summaryrefslogtreecommitdiff
path: root/src/logic/slbt_exec_compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/logic/slbt_exec_compile.c')
-rw-r--r--src/logic/slbt_exec_compile.c108
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;
}