diff options
Diffstat (limited to 'src/logic/slbt_exec_compile.c')
-rw-r--r-- | src/logic/slbt_exec_compile.c | 108 |
1 files changed, 78 insertions, 30 deletions
diff --git a/src/logic/slbt_exec_compile.c b/src/logic/slbt_exec_compile.c index f9cd1d2..47d8e72 100644 --- a/src/logic/slbt_exec_compile.c +++ b/src/logic/slbt_exec_compile.c @@ -1,6 +1,6 @@ /*******************************************************************/ -/* slibtool: a skinny libtool implementation, written in C */ -/* Copyright (C) 2016--2021 SysDeer Technologies, LLC */ +/* slibtool: a strong libtool implementation, written in C */ +/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */ /* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ /*******************************************************************/ @@ -48,7 +48,9 @@ static int slbt_exec_compile_finalize_argument_vector( char ** cap; char ** src; char ** dst; + char ** cmp; char * ccwrap; + char * custom; /* vector size */ base = ectx->argv; @@ -74,6 +76,9 @@ static int slbt_exec_compile_finalize_argument_vector( /* (program name) */ parg = &base[1]; + /* avoid -I deduplication with project specific drivers */ + custom = strchr(ectx->program,'/'); + /* split object args from all other args, record output */ /* annotation, and remove redundant -l arguments */ for (; *parg; ) { @@ -102,13 +107,47 @@ static int slbt_exec_compile_finalize_argument_vector( base++; } - /* join all other args */ + /* join all other args, starting with de-duplicated -I arguments, */ + /* and filter out all -f switches when compiling in --tag=RC mode */ src = aargv; cap = aarg; dst = &base[1]; - for (; src<cap; ) - *dst++ = *src++; + for (; !custom && src<cap; ) { + if (((*src)[0] == '-') && ((*src)[1] == 'I')) { + cmp = &base[1]; + + for (; cmp && cmp<dst; ) { + if (!strcmp(*src,*cmp)) { + cmp = 0; + } else { + cmp++; + } + } + + if (cmp) + *dst++ = *src; + } + + src++; + } + + src = aargv; + + for (; src<cap; ) { + if ((dctx->cctx->tag == SLBT_TAG_RC) + && ((*src)[0] == '-') + && ((*src)[1] == 'f')) + (void)0; + + else if (((*src)[0] != '-') || ((*src)[1] != 'I')) + *dst++ = *src; + + else if (custom) + *dst++ = *src; + + src++; + } /* properly null-terminate argv, accounting for redundant arguments */ *dst = 0; @@ -131,14 +170,14 @@ static int slbt_exec_compile_finalize_argument_vector( return 0; } -int slbt_exec_compile( - const struct slbt_driver_ctx * dctx, - struct slbt_exec_ctx * ectx) +int slbt_exec_compile(const struct slbt_driver_ctx * dctx) { int ret; char * fpic; char * ccwrap; - struct slbt_exec_ctx * actx = 0; + bool fshared; + bool fstatic; + struct slbt_exec_ctx * ectx; const struct slbt_common_ctx * cctx = dctx->cctx; /* dry run */ @@ -146,22 +185,22 @@ int slbt_exec_compile( return 0; /* context */ - if (ectx) - slbt_reset_placeholders(ectx); - else if ((ret = slbt_get_exec_ctx(dctx,&ectx))) - return ret; - else - actx = ectx; + if (slbt_ectx_get_exec_ctx(dctx,&ectx) < 0) + return SLBT_NESTED_ERROR(dctx); /* remove old .lo wrapper */ if (slbt_exec_compile_remove_file(dctx,ectx,ectx->ltobjname)) return SLBT_NESTED_ERROR(dctx); + /* fshared, fstatic */ + fshared = (cctx->drvflags & (SLBT_DRIVER_SHARED | SLBT_DRIVER_PREFER_SHARED)); + fstatic = (cctx->drvflags & (SLBT_DRIVER_STATIC | SLBT_DRIVER_PREFER_STATIC)); + /* .libs directory */ - if (cctx->drvflags & SLBT_DRIVER_SHARED) + if (fshared) if (slbt_mkdir(dctx,ectx->ldirname)) { ret = SLBT_SYSTEM_ERROR(dctx,ectx->ldirname); - slbt_free_exec_ctx(actx); + slbt_ectx_free_exec_ctx(ectx); return ret; } @@ -175,6 +214,7 @@ int slbt_exec_compile( case SLBT_TAG_CC: case SLBT_TAG_CXX: case SLBT_TAG_F77: + case SLBT_TAG_FC: fpic = cctx->settings.picswitch ? cctx->settings.picswitch : *ectx->fpic; @@ -185,7 +225,7 @@ int slbt_exec_compile( } /* shared library object */ - if (cctx->drvflags & SLBT_DRIVER_SHARED) { + if (fshared) { if (!(cctx->drvflags & SLBT_DRIVER_ANTI_PIC)) { *ectx->dpic = "-DPIC"; *ectx->fpic = fpic; @@ -198,23 +238,27 @@ int slbt_exec_compile( return SLBT_NESTED_ERROR(dctx); if (!(cctx->drvflags & SLBT_DRIVER_SILENT)) { - if (slbt_output_compile(dctx,ectx)) { - slbt_free_exec_ctx(actx); + if (slbt_output_compile(ectx)) { + slbt_ectx_free_exec_ctx(ectx); return SLBT_NESTED_ERROR(dctx); } } - if (((ret = slbt_spawn(ectx,true)) < 0) || ectx->exitcode) { - slbt_free_exec_ctx(actx); + if ((slbt_spawn(ectx,true) < 0) && (ectx->pid < 0)) { + slbt_ectx_free_exec_ctx(ectx); return SLBT_SYSTEM_ERROR(dctx,0); + + } else if (ectx->exitcode) { + slbt_ectx_free_exec_ctx(ectx); + return SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_COMPILE_ERROR); } - if (cctx->drvflags & SLBT_DRIVER_STATIC) - slbt_reset_argvector(ectx); + if (fstatic) + slbt_ectx_reset_argvector(ectx); } /* static archive object */ - if (cctx->drvflags & SLBT_DRIVER_STATIC) { + if (fstatic) { slbt_reset_placeholders(ectx); if (cctx->drvflags & SLBT_DRIVER_PRO_PIC) { @@ -229,20 +273,24 @@ int slbt_exec_compile( return SLBT_NESTED_ERROR(dctx); if (!(cctx->drvflags & SLBT_DRIVER_SILENT)) { - if (slbt_output_compile(dctx,ectx)) { - slbt_free_exec_ctx(actx); + if (slbt_output_compile(ectx)) { + slbt_ectx_free_exec_ctx(ectx); return SLBT_NESTED_ERROR(dctx); } } - if (((ret = slbt_spawn(ectx,true)) < 0) || ectx->exitcode) { - slbt_free_exec_ctx(actx); + if ((slbt_spawn(ectx,true) < 0) && (ectx->pid < 0)) { + slbt_ectx_free_exec_ctx(ectx); return SLBT_SYSTEM_ERROR(dctx,0); + + } else if (ectx->exitcode) { + slbt_ectx_free_exec_ctx(ectx); + return SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_COMPILE_ERROR); } } ret = slbt_create_object_wrapper(dctx,ectx); - slbt_free_exec_ctx(actx); + slbt_ectx_free_exec_ctx(ectx); return ret ? SLBT_NESTED_ERROR(dctx) : 0; } |