diff options
-rw-r--r-- | project/common.mk | 1 | ||||
-rw-r--r-- | src/driver/slbt_driver_ctx.c | 493 | ||||
-rw-r--r-- | src/driver/slbt_split_argv.c | 509 | ||||
-rw-r--r-- | src/internal/slibtool_driver_impl.h | 23 |
4 files changed, 535 insertions, 491 deletions
diff --git a/project/common.mk b/project/common.mk index 1fa7ca9..cebaef7 100644 --- a/project/common.mk +++ b/project/common.mk @@ -12,6 +12,7 @@ API_SRCS = \ src/driver/slbt_amain.c \ src/driver/slbt_driver_ctx.c \ src/driver/slbt_host_params.c \ + src/driver/slbt_split_argv.c \ src/fallback/slbt_archive_import_mri.c \ src/helper/slbt_archive_import.c \ src/helper/slbt_copy_file.c \ diff --git a/src/driver/slbt_driver_ctx.c b/src/driver/slbt_driver_ctx.c index ec468a2..2eee876 100644 --- a/src/driver/slbt_driver_ctx.c +++ b/src/driver/slbt_driver_ctx.c @@ -48,9 +48,6 @@ static const struct slbt_fd_ctx slbt_default_fdctx = { .fdlog = (-1), }; -/* default compiler argv */ -static char * slbt_default_cargv[] = {"cc",0}; - static const char aclr_reset [] = "\x1b[0m"; static const char aclr_bold [] = "\x1b[1m"; static const char aclr_red [] = "\x1b[31m"; @@ -94,7 +91,7 @@ static void slbt_output_raw_vector(int fderr, char ** argv, char ** envp, bool f slbt_dprintf(fderr,"%s\n\n",fcolor ? aclr_reset : ""); } -static uint64_t slbt_argv_flags(uint64_t flags) +uint64_t slbt_argv_flags(uint64_t flags) { uint32_t ret = 0; @@ -137,7 +134,7 @@ static int slbt_free_argv_buffer( return -1; } -static int slbt_driver_usage( +int slbt_driver_usage( int fdout, const char * program, const char * arg, @@ -224,492 +221,6 @@ static int slbt_get_driver_ctx_fail( return -1; } -static int slbt_split_argv( - char ** argv, - uint64_t flags, - struct slbt_split_vector * sargv, - struct slbt_obj_list ** aobjlistv, - int fderr, - int fdcwd) -{ - int i; - int argc; - int objc; - const char * program; - char * compiler; - char * csysroot; - char ** dargv; - char ** targv; - char ** cargv; - char ** objp; - struct slbt_obj_list * objlistv; - struct slbt_obj_list * objlistp; - char * dst; - bool flast; - bool fcopy; - bool altmode; - size_t size; - const char * base; - struct argv_meta * meta; - struct argv_entry * entry; - struct argv_entry * mode; - struct argv_entry * help; - struct argv_entry * version; - struct argv_entry * config; - struct argv_entry * finish; - struct argv_entry * features; - struct argv_entry * ccwrap; - struct argv_entry * dumpmachine; - struct argv_entry * aropt; - const struct argv_option ** popt; - const struct argv_option ** optout; - const struct argv_option * optv[SLBT_OPTV_ELEMENTS]; - struct argv_ctx ctx = {ARGV_VERBOSITY_NONE, - ARGV_MODE_SCAN, - 0,0,0,0,0,0,0}; - - program = argv_program_name(argv[0]); - - /* missing arguments? */ - if ((altmode = (flags & SLBT_DRIVER_MODE_AR))) { - argv_optv_init(slbt_ar_options,optv); - } else { - argv_optv_init(slbt_default_options,optv); - } - - - if (!argv[1] && !altmode && (flags & SLBT_DRIVER_VERBOSITY_USAGE)) - return slbt_driver_usage( - fderr,program, - 0,optv,0,sargv,0, - !!getenv("NO_COLOR")); - - /* initial argv scan: ... --mode=xxx ... <compiler> ... */ - argv_scan(argv,optv,&ctx,0); - - /* invalid slibtool arguments? */ - if (ctx.erridx && !ctx.unitidx && altmode) { - if (flags & SLBT_DRIVER_VERBOSITY_ERRORS) - argv_get( - argv,optv, - slbt_argv_flags(flags), - fderr); - return -1; - } - - /* error possibly due to an altmode argument? */ - if (ctx.erridx && !ctx.unitidx) - ctx.unitidx = ctx.erridx; - - /* obtain slibtool's own arguments */ - if (ctx.unitidx) { - compiler = argv[ctx.unitidx]; - argv[ctx.unitidx] = 0; - - meta = argv_get(argv,optv,ARGV_VERBOSITY_NONE,fderr); - argv[ctx.unitidx] = compiler; - } else { - meta = argv_get(argv,optv,ARGV_VERBOSITY_NONE,fderr); - } - - if (!meta) { - if (flags & SLBT_DRIVER_VERBOSITY_ERRORS) - argv_get( - argv,optv, - slbt_argv_flags(flags), - fderr); - return -1; - } - - /* missing all of --mode, --help, --version, --config, --dumpmachine, --features, and --finish? */ - mode = help = version = config = finish = features = ccwrap = dumpmachine = aropt = 0; - - for (entry=meta->entries; entry->fopt; entry++) - if (entry->tag == TAG_MODE) - mode = entry; - else if (entry->tag == TAG_HELP) - help = entry; - else if (entry->tag == TAG_VERSION) - version = entry; - else if (entry->tag == TAG_CONFIG) - config = entry; - else if (entry->tag == TAG_FINISH) - finish = entry; - else if (entry->tag == TAG_FEATURES) - features = entry; - else if (entry->tag == TAG_CCWRAP) - ccwrap = entry; - else if (entry->tag == TAG_DUMPMACHINE) - dumpmachine = entry; - - /* alternate execusion mode? */ - if (!altmode && mode && !strcmp(mode->arg,"ar")) - aropt = mode; - - /* release temporary argv meta context */ - argv_free(meta); - - /* error not due to an altmode argument? */ - if (!aropt && ctx.erridx && (ctx.erridx == ctx.unitidx)) { - if (flags & SLBT_DRIVER_VERBOSITY_ERRORS) - argv_get( - argv,optv, - slbt_argv_flags(flags), - fderr); - return -1; - } - - if (!mode && !help && !version && !config && !finish && !features && !dumpmachine && !altmode) { - slbt_dprintf(fderr, - "%s: error: --mode must be specified.\n", - program); - return -1; - } - - /* missing compiler? */ - if (!ctx.unitidx && !help && !version && !finish && !features && !dumpmachine && !altmode && !aropt) { - if (flags & SLBT_DRIVER_VERBOSITY_ERRORS) - slbt_dprintf(fderr, - "%s: error: <compiler> is missing.\n", - program); - return -1; - } - - /* clone and normalize the argv vector (-l, --library) */ - for (argc=0,size=0,dargv=argv; *dargv; argc++,dargv++) - size += strlen(*dargv) + 1; - - if (!(sargv->dargv = calloc(argc+1,sizeof(char *)))) - return -1; - - else if (!(sargv->dargs = calloc(1,size+1))) - return -1; - - else if (!(*aobjlistv = calloc(argc,sizeof(**aobjlistv)))) { - free(sargv->dargv); - free(sargv->dargs); - return -1; - } - - objlistv = *aobjlistv; - objlistp = objlistv; - csysroot = 0; - - for (i=0,flast=false,dargv=sargv->dargv,dst=sargv->dargs; i<argc; i++) { - if ((fcopy = (flast || altmode || aropt))) { - (void)0; - - } else if (!strcmp(argv[i],"--")) { - flast = true; - fcopy = true; - - } else if (!strcmp(argv[i],"-l")) { - *dargv++ = dst; - *dst++ = '-'; - *dst++ = 'l'; - strcpy(dst,argv[++i]); - dst += strlen(dst)+1; - - } else if (!strncmp(argv[i],"-l",2)) { - fcopy = true; - - } else if (!strcmp(argv[i],"--library")) { - *dargv++ = dst; - *dst++ = '-'; - *dst++ = 'l'; - strcpy(dst,argv[++i]); - dst += strlen(dst)+1; - - } else if (!strncmp(argv[i],"--library=",10)) { - *dargv++ = dst; - *dst++ = '-'; - *dst++ = 'l'; - strcpy(dst,&argv[++i][10]); - dst += strlen(dst)+1; - - } else if (!strcmp(argv[i],"-L")) { - *dargv++ = dst; - *dst++ = '-'; - *dst++ = 'L'; - strcpy(dst,argv[++i]); - dst += strlen(dst)+1; - - } else if (!strncmp(argv[i],"-L",2)) { - fcopy = true; - - } else if (!strcmp(argv[i],"-Xlinker")) { - *dargv++ = dst; - *dst++ = '-'; - *dst++ = 'W'; - *dst++ = 'l'; - *dst++ = ','; - strcpy(dst,argv[++i]); - dst += strlen(dst)+1; - - } else if (!strcmp(argv[i],"--library-path")) { - *dargv++ = dst; - *dst++ = '-'; - *dst++ = 'L'; - strcpy(dst,argv[++i]); - dst += strlen(dst)+1; - - } else if (!strncmp(argv[i],"--library-path=",15)) { - *dargv++ = dst; - *dst++ = '-'; - *dst++ = 'L'; - strcpy(dst,&argv[i][15]); - dst += strlen(dst)+1; - - } else if (!strcmp(argv[i],"--sysroot") && (i<ctx.unitidx)) { - *dargv++ = dst; - csysroot = dst; - strcpy(dst,argv[i]); - dst[9] = '='; - strcpy(&dst[10],argv[++i]); - dst += strlen(dst)+1; - ctx.unitidx--; - - } else if (!strncmp(argv[i],"--sysroot=",10) && (i<ctx.unitidx)) { - *dargv++ = dst; - csysroot = dst; - strcpy(dst,argv[i]); - dst += strlen(dst)+1; - - } else if (!strcmp(argv[i],"-objectlist")) { - *dargv++ = dst; - strcpy(dst,argv[i++]); - dst += strlen(dst)+1; - - objlistp->name = dst; - objlistp++; - fcopy = true; - - } else { - fcopy = true; - } - - if (fcopy) { - *dargv++ = dst; - strcpy(dst,argv[i]); - dst += strlen(dst)+1; - } - } - - /* update argc,argv */ - argc = dargv - sargv->dargv; - argv = sargv->dargv; - - /* iterate through the object list vector: map, parse, store */ - for (objlistp=objlistv; objlistp->name; objlistp++) - if (slbt_objlist_read(fdcwd,objlistp) < 0) - return -1; - - for (objc=0,objlistp=objlistv; objlistp->name; objlistp++) - objc += objlistp->objc; - - /* allocate split vectors, account for cargv's added sysroot */ - if ((sargv->targv = calloc(objc + 2*(argc+3),sizeof(char *)))) - sargv->cargv = sargv->targv + argc + 2; - else - return -1; - - /* --features and no <compiler>? */ - if (ctx.unitidx) { - (void)0; - - } else if (help || version || features || dumpmachine || altmode) { - for (i=0; i<argc; i++) - sargv->targv[i] = argv[i]; - - sargv->cargv = altmode ? sargv->targv : slbt_default_cargv; - - return 0; - } - - /* --mode=ar and no ar-specific arguments? */ - if (aropt && !ctx.unitidx) - ctx.unitidx = argc; - - /* split vectors: slibtool's own options */ - for (i=0; i<ctx.unitidx; i++) - sargv->targv[i] = argv[i]; - - /* split vector marks */ - targv = sargv->targv + i; - cargv = sargv->cargv; - - /* known wrappers */ - if (ctx.unitidx && !ccwrap && !aropt) { - if ((base = strrchr(argv[i],'/'))) - base++; - else if ((base = strrchr(argv[i],'\\'))) - base++; - else - base = argv[i]; - - if (!strcmp(base,"ccache") - || !strcmp(base,"distcc") - || !strcmp(base,"compiler") - || !strcmp(base,"purify")) { - *targv++ = "--ccwrap"; - *targv++ = argv[i++]; - } - } - - /* split vectors: legacy mixture */ - for (optout=optv; optout[0] && (optout[0]->tag != TAG_OUTPUT); optout++) - (void)0; - - /* compiler, archiver, etc. */ - if (altmode) { - i = 0; - } else if (aropt) { - *cargv++ = argv[0]; - } else { - *cargv++ = argv[i++]; - } - - /* sysroot */ - if (csysroot) - *cargv++ = csysroot; - - /* remaining vector */ - for (objlistp=objlistv; i<argc; i++) { - if (aropt && (i >= ctx.unitidx)) { - *cargv++ = argv[i]; - - } else if (argv[i][0] != '-') { - if (argv[i+1] && (argv[i+1][0] == '+') - && (argv[i+1][1] == '=') - && (argv[i+1][2] == 0) - && !(strrchr(argv[i],'.'))) - /* libfoo_la_LDFLAGS += -Wl,.... */ - i++; - else - *cargv++ = argv[i]; - - /* must capture -objectlist prior to -o */ - } else if (!(strcmp("objectlist",&argv[i][1]))) { - for (objp=objlistp->objv; *objp; objp++) - *cargv++ = *objp; - - i++; - objlistp++; - - } else if (argv[i][1] == 'o') { - *targv++ = argv[i]; - - if (argv[i][2] == 0) - *targv++ = argv[++i]; - } else if ((argv[i][1] == 'W') && (argv[i][2] == 'c')) { - *cargv++ = argv[i]; - - } else if (!(strcmp("Xcompiler",&argv[i][1]))) { - *cargv++ = argv[++i]; - - } else if (!(strcmp("XCClinker",&argv[i][1]))) { - *cargv++ = argv[++i]; - - } else if ((argv[i][1] == 'R') && (argv[i][2] == 0)) { - *targv++ = argv[i++]; - *targv++ = argv[i]; - - } else if (argv[i][1] == 'R') { - *targv++ = argv[i]; - - } else if (!(strncmp("-target=",&argv[i][1],8))) { - *cargv++ = argv[i]; - *targv++ = argv[i]; - - } else if (!(strcmp("-target",&argv[i][1]))) { - *cargv++ = argv[i]; - *targv++ = argv[i++]; - - *cargv++ = argv[i]; - *targv++ = argv[i]; - - } else if (!(strcmp("target",&argv[i][1]))) { - *cargv++ = argv[i]; - *targv++ = argv[i++]; - - *cargv++ = argv[i]; - *targv++ = argv[i]; - - } else if (!(strncmp("-sysroot=",&argv[i][1],9))) { - *cargv++ = argv[i]; - *targv++ = argv[i]; - - } else if (!(strcmp("-sysroot",&argv[i][1]))) { - *cargv++ = argv[i]; - *targv++ = argv[i++]; - - *cargv++ = argv[i]; - *targv++ = argv[i]; - - } else if (!(strcmp("bindir",&argv[i][1]))) { - *targv++ = argv[i++]; - *targv++ = argv[i]; - - } else if (!(strcmp("shrext",&argv[i][1]))) { - *targv++ = argv[i++]; - *targv++ = argv[i]; - - } else if (!(strcmp("rpath",&argv[i][1]))) { - *targv++ = argv[i++]; - *targv++ = argv[i]; - - } else if (!(strcmp("release",&argv[i][1]))) { - *targv++ = argv[i++]; - *targv++ = argv[i]; - - } else if (!(strcmp("dlopen",&argv[i][1]))) { - *targv++ = argv[i++]; - *targv++ = argv[i]; - - } else if (!(strcmp("weak",&argv[i][1]))) { - *targv++ = argv[i++]; - *targv++ = argv[i]; - - } else if (!(strcmp("static-libtool-libs",&argv[i][1]))) { - *targv++ = argv[i]; - - } else if (!(strcmp("export-dynamic",&argv[i][1]))) { - *targv++ = argv[i]; - - } else if (!(strcmp("export-symbols",&argv[i][1]))) { - *targv++ = argv[i++]; - *targv++ = argv[i]; - - } else if (!(strcmp("export-symbols-regex",&argv[i][1]))) { - *targv++ = argv[i++]; - *targv++ = argv[i]; - - } else if (!(strcmp("version-info",&argv[i][1]))) { - *targv++ = argv[i++]; - *targv++ = argv[i]; - - } else if (!(strcmp("version-number",&argv[i][1]))) { - *targv++ = argv[i++]; - *targv++ = argv[i]; - - } else if (!(strcmp("dlpreopen",&argv[i][1]))) { - (void)0; - - } else { - for (popt=optout; popt[0] && popt[0]->long_name; popt++) - if (!(strcmp(popt[0]->long_name,&argv[i][1]))) - break; - - if (popt[0] && popt[0]->long_name) - *targv++ = argv[i]; - else - *cargv++ = argv[i]; - } - } - - return 0; -} - static int slbt_init_version_info( struct slbt_driver_ctx_impl * ictx, diff --git a/src/driver/slbt_split_argv.c b/src/driver/slbt_split_argv.c new file mode 100644 index 0000000..8ec189b --- /dev/null +++ b/src/driver/slbt_split_argv.c @@ -0,0 +1,509 @@ +/*******************************************************************/ +/* slibtool: a skinny libtool implementation, written in C */ +/* Copyright (C) 2016--2021 SysDeer Technologies, LLC */ +/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ +/*******************************************************************/ + +#include <stdint.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdbool.h> + +#define ARGV_DRIVER + +#include <slibtool/slibtool.h> +#include "slibtool_version.h" +#include "slibtool_driver_impl.h" +#include "slibtool_objlist_impl.h" +#include "slibtool_errinfo_impl.h" +#include "slibtool_ar_impl.h" +#include "argv/argv.h" + +static char * slbt_default_cargv[] = {"cc",0}; + +int slbt_split_argv( + char ** argv, + uint64_t flags, + struct slbt_split_vector * sargv, + struct slbt_obj_list ** aobjlistv, + int fderr, + int fdcwd) +{ + int i; + int argc; + int objc; + const char * program; + char * compiler; + char * csysroot; + char ** dargv; + char ** targv; + char ** cargv; + char ** objp; + struct slbt_obj_list * objlistv; + struct slbt_obj_list * objlistp; + char * dst; + bool flast; + bool fcopy; + bool altmode; + size_t size; + const char * base; + struct argv_meta * meta; + struct argv_entry * entry; + struct argv_entry * mode; + struct argv_entry * help; + struct argv_entry * version; + struct argv_entry * config; + struct argv_entry * finish; + struct argv_entry * features; + struct argv_entry * ccwrap; + struct argv_entry * dumpmachine; + struct argv_entry * aropt; + const struct argv_option ** popt; + const struct argv_option ** optout; + const struct argv_option * optv[SLBT_OPTV_ELEMENTS]; + struct argv_ctx ctx = {ARGV_VERBOSITY_NONE, + ARGV_MODE_SCAN, + 0,0,0,0,0,0,0}; + + program = argv_program_name(argv[0]); + + /* missing arguments? */ + if ((altmode = (flags & SLBT_DRIVER_MODE_AR))) { + argv_optv_init(slbt_ar_options,optv); + } else { + argv_optv_init(slbt_default_options,optv); + } + + + if (!argv[1] && !altmode && (flags & SLBT_DRIVER_VERBOSITY_USAGE)) + return slbt_driver_usage( + fderr,program, + 0,optv,0,sargv,0, + !!getenv("NO_COLOR")); + + /* initial argv scan: ... --mode=xxx ... <compiler> ... */ + argv_scan(argv,optv,&ctx,0); + + /* invalid slibtool arguments? */ + if (ctx.erridx && !ctx.unitidx && altmode) { + if (flags & SLBT_DRIVER_VERBOSITY_ERRORS) + argv_get( + argv,optv, + slbt_argv_flags(flags), + fderr); + return -1; + } + + /* error possibly due to an altmode argument? */ + if (ctx.erridx && !ctx.unitidx) + ctx.unitidx = ctx.erridx; + + /* obtain slibtool's own arguments */ + if (ctx.unitidx) { + compiler = argv[ctx.unitidx]; + argv[ctx.unitidx] = 0; + + meta = argv_get(argv,optv,ARGV_VERBOSITY_NONE,fderr); + argv[ctx.unitidx] = compiler; + } else { + meta = argv_get(argv,optv,ARGV_VERBOSITY_NONE,fderr); + } + + if (!meta) { + if (flags & SLBT_DRIVER_VERBOSITY_ERRORS) + argv_get( + argv,optv, + slbt_argv_flags(flags), + fderr); + return -1; + } + + /* missing all of --mode, --help, --version, --config, --dumpmachine, --features, and --finish? */ + mode = help = version = config = finish = features = ccwrap = dumpmachine = aropt = 0; + + for (entry=meta->entries; entry->fopt; entry++) + if (entry->tag == TAG_MODE) + mode = entry; + else if (entry->tag == TAG_HELP) + help = entry; + else if (entry->tag == TAG_VERSION) + version = entry; + else if (entry->tag == TAG_CONFIG) + config = entry; + else if (entry->tag == TAG_FINISH) + finish = entry; + else if (entry->tag == TAG_FEATURES) + features = entry; + else if (entry->tag == TAG_CCWRAP) + ccwrap = entry; + else if (entry->tag == TAG_DUMPMACHINE) + dumpmachine = entry; + + /* alternate execusion mode? */ + if (!altmode && mode && !strcmp(mode->arg,"ar")) + aropt = mode; + + /* release temporary argv meta context */ + argv_free(meta); + + /* error not due to an altmode argument? */ + if (!aropt && ctx.erridx && (ctx.erridx == ctx.unitidx)) { + if (flags & SLBT_DRIVER_VERBOSITY_ERRORS) + argv_get( + argv,optv, + slbt_argv_flags(flags), + fderr); + return -1; + } + + if (!mode && !help && !version && !config && !finish && !features && !dumpmachine && !altmode) { + slbt_dprintf(fderr, + "%s: error: --mode must be specified.\n", + program); + return -1; + } + + /* missing compiler? */ + if (!ctx.unitidx && !help && !version && !finish && !features && !dumpmachine && !altmode && !aropt) { + if (flags & SLBT_DRIVER_VERBOSITY_ERRORS) + slbt_dprintf(fderr, + "%s: error: <compiler> is missing.\n", + program); + return -1; + } + + /* clone and normalize the argv vector (-l, --library) */ + for (argc=0,size=0,dargv=argv; *dargv; argc++,dargv++) + size += strlen(*dargv) + 1; + + if (!(sargv->dargv = calloc(argc+1,sizeof(char *)))) + return -1; + + else if (!(sargv->dargs = calloc(1,size+1))) + return -1; + + else if (!(*aobjlistv = calloc(argc,sizeof(**aobjlistv)))) { + free(sargv->dargv); + free(sargv->dargs); + return -1; + } + + objlistv = *aobjlistv; + objlistp = objlistv; + csysroot = 0; + + for (i=0,flast=false,dargv=sargv->dargv,dst=sargv->dargs; i<argc; i++) { + if ((fcopy = (flast || altmode || aropt))) { + (void)0; + + } else if (!strcmp(argv[i],"--")) { + flast = true; + fcopy = true; + + } else if (!strcmp(argv[i],"-l")) { + *dargv++ = dst; + *dst++ = '-'; + *dst++ = 'l'; + strcpy(dst,argv[++i]); + dst += strlen(dst)+1; + + } else if (!strncmp(argv[i],"-l",2)) { + fcopy = true; + + } else if (!strcmp(argv[i],"--library")) { + *dargv++ = dst; + *dst++ = '-'; + *dst++ = 'l'; + strcpy(dst,argv[++i]); + dst += strlen(dst)+1; + + } else if (!strncmp(argv[i],"--library=",10)) { + *dargv++ = dst; + *dst++ = '-'; + *dst++ = 'l'; + strcpy(dst,&argv[++i][10]); + dst += strlen(dst)+1; + + } else if (!strcmp(argv[i],"-L")) { + *dargv++ = dst; + *dst++ = '-'; + *dst++ = 'L'; + strcpy(dst,argv[++i]); + dst += strlen(dst)+1; + + } else if (!strncmp(argv[i],"-L",2)) { + fcopy = true; + + } else if (!strcmp(argv[i],"-Xlinker")) { + *dargv++ = dst; + *dst++ = '-'; + *dst++ = 'W'; + *dst++ = 'l'; + *dst++ = ','; + strcpy(dst,argv[++i]); + dst += strlen(dst)+1; + + } else if (!strcmp(argv[i],"--library-path")) { + *dargv++ = dst; + *dst++ = '-'; + *dst++ = 'L'; + strcpy(dst,argv[++i]); + dst += strlen(dst)+1; + + } else if (!strncmp(argv[i],"--library-path=",15)) { + *dargv++ = dst; + *dst++ = '-'; + *dst++ = 'L'; + strcpy(dst,&argv[i][15]); + dst += strlen(dst)+1; + + } else if (!strcmp(argv[i],"--sysroot") && (i<ctx.unitidx)) { + *dargv++ = dst; + csysroot = dst; + strcpy(dst,argv[i]); + dst[9] = '='; + strcpy(&dst[10],argv[++i]); + dst += strlen(dst)+1; + ctx.unitidx--; + + } else if (!strncmp(argv[i],"--sysroot=",10) && (i<ctx.unitidx)) { + *dargv++ = dst; + csysroot = dst; + strcpy(dst,argv[i]); + dst += strlen(dst)+1; + + } else if (!strcmp(argv[i],"-objectlist")) { + *dargv++ = dst; + strcpy(dst,argv[i++]); + dst += strlen(dst)+1; + + objlistp->name = dst; + objlistp++; + fcopy = true; + + } else { + fcopy = true; + } + + if (fcopy) { + *dargv++ = dst; + strcpy(dst,argv[i]); + dst += strlen(dst)+1; + } + } + + /* update argc,argv */ + argc = dargv - sargv->dargv; + argv = sargv->dargv; + + /* iterate through the object list vector: map, parse, store */ + for (objlistp=objlistv; objlistp->name; objlistp++) + if (slbt_objlist_read(fdcwd,objlistp) < 0) + return -1; + + for (objc=0,objlistp=objlistv; objlistp->name; objlistp++) + objc += objlistp->objc; + + /* allocate split vectors, account for cargv's added sysroot */ + if ((sargv->targv = calloc(objc + 2*(argc+3),sizeof(char *)))) + sargv->cargv = sargv->targv + argc + 2; + else + return -1; + + /* --features and no <compiler>? */ + if (ctx.unitidx) { + (void)0; + + } else if (help || version || features || dumpmachine || altmode) { + for (i=0; i<argc; i++) + sargv->targv[i] = argv[i]; + + sargv->cargv = altmode ? sargv->targv : slbt_default_cargv; + + return 0; + } + + /* --mode=ar and no ar-specific arguments? */ + if (aropt && !ctx.unitidx) + ctx.unitidx = argc; + + /* split vectors: slibtool's own options */ + for (i=0; i<ctx.unitidx; i++) + sargv->targv[i] = argv[i]; + + /* split vector marks */ + targv = sargv->targv + i; + cargv = sargv->cargv; + + /* known wrappers */ + if (ctx.unitidx && !ccwrap && !aropt) { + if ((base = strrchr(argv[i],'/'))) + base++; + else if ((base = strrchr(argv[i],'\\'))) + base++; + else + base = argv[i]; + + if (!strcmp(base,"ccache") + || !strcmp(base,"distcc") + || !strcmp(base,"compiler") + || !strcmp(base,"purify")) { + *targv++ = "--ccwrap"; + *targv++ = argv[i++]; + } + } + + /* split vectors: legacy mixture */ + for (optout=optv; optout[0] && (optout[0]->tag != TAG_OUTPUT); optout++) + (void)0; + + /* compiler, archiver, etc. */ + if (altmode) { + i = 0; + } else if (aropt) { + *cargv++ = argv[0]; + } else { + *cargv++ = argv[i++]; + } + + /* sysroot */ + if (csysroot) + *cargv++ = csysroot; + + /* remaining vector */ + for (objlistp=objlistv; i<argc; i++) { + if (aropt && (i >= ctx.unitidx)) { + *cargv++ = argv[i]; + + } else if (argv[i][0] != '-') { + if (argv[i+1] && (argv[i+1][0] == '+') + && (argv[i+1][1] == '=') + && (argv[i+1][2] == 0) + && !(strrchr(argv[i],'.'))) + /* libfoo_la_LDFLAGS += -Wl,.... */ + i++; + else + *cargv++ = argv[i]; + + /* must capture -objectlist prior to -o */ + } else if (!(strcmp("objectlist",&argv[i][1]))) { + for (objp=objlistp->objv; *objp; objp++) + *cargv++ = *objp; + + i++; + objlistp++; + + } else if (argv[i][1] == 'o') { + *targv++ = argv[i]; + + if (argv[i][2] == 0) + *targv++ = argv[++i]; + } else if ((argv[i][1] == 'W') && (argv[i][2] == 'c')) { + *cargv++ = argv[i]; + + } else if (!(strcmp("Xcompiler",&argv[i][1]))) { + *cargv++ = argv[++i]; + + } else if (!(strcmp("XCClinker",&argv[i][1]))) { + *cargv++ = argv[++i]; + + } else if ((argv[i][1] == 'R') && (argv[i][2] == 0)) { + *targv++ = argv[i++]; + *targv++ = argv[i]; + + } else if (argv[i][1] == 'R') { + *targv++ = argv[i]; + + } else if (!(strncmp("-target=",&argv[i][1],8))) { + *cargv++ = argv[i]; + *targv++ = argv[i]; + + } else if (!(strcmp("-target",&argv[i][1]))) { + *cargv++ = argv[i]; + *targv++ = argv[i++]; + + *cargv++ = argv[i]; + *targv++ = argv[i]; + + } else if (!(strcmp("target",&argv[i][1]))) { + *cargv++ = argv[i]; + *targv++ = argv[i++]; + + *cargv++ = argv[i]; + *targv++ = argv[i]; + + } else if (!(strncmp("-sysroot=",&argv[i][1],9))) { + *cargv++ = argv[i]; + *targv++ = argv[i]; + + } else if (!(strcmp("-sysroot",&argv[i][1]))) { + *cargv++ = argv[i]; + *targv++ = argv[i++]; + + *cargv++ = argv[i]; + *targv++ = argv[i]; + + } else if (!(strcmp("bindir",&argv[i][1]))) { + *targv++ = argv[i++]; + *targv++ = argv[i]; + + } else if (!(strcmp("shrext",&argv[i][1]))) { + *targv++ = argv[i++]; + *targv++ = argv[i]; + + } else if (!(strcmp("rpath",&argv[i][1]))) { + *targv++ = argv[i++]; + *targv++ = argv[i]; + + } else if (!(strcmp("release",&argv[i][1]))) { + *targv++ = argv[i++]; + *targv++ = argv[i]; + + } else if (!(strcmp("dlopen",&argv[i][1]))) { + *targv++ = argv[i++]; + *targv++ = argv[i]; + + } else if (!(strcmp("weak",&argv[i][1]))) { + *targv++ = argv[i++]; + *targv++ = argv[i]; + + } else if (!(strcmp("static-libtool-libs",&argv[i][1]))) { + *targv++ = argv[i]; + + } else if (!(strcmp("export-dynamic",&argv[i][1]))) { + *targv++ = argv[i]; + + } else if (!(strcmp("export-symbols",&argv[i][1]))) { + *targv++ = argv[i++]; + *targv++ = argv[i]; + + } else if (!(strcmp("export-symbols-regex",&argv[i][1]))) { + *targv++ = argv[i++]; + *targv++ = argv[i]; + + } else if (!(strcmp("version-info",&argv[i][1]))) { + *targv++ = argv[i++]; + *targv++ = argv[i]; + + } else if (!(strcmp("version-number",&argv[i][1]))) { + *targv++ = argv[i++]; + *targv++ = argv[i]; + + } else if (!(strcmp("dlpreopen",&argv[i][1]))) { + (void)0; + + } else { + for (popt=optout; popt[0] && popt[0]->long_name; popt++) + if (!(strcmp(popt[0]->long_name,&argv[i][1]))) + break; + + if (popt[0] && popt[0]->long_name) + *targv++ = argv[i]; + else + *cargv++ = argv[i]; + } + } + + return 0; +} diff --git a/src/internal/slibtool_driver_impl.h b/src/internal/slibtool_driver_impl.h index 32ae6c8..9a32c9b 100644 --- a/src/internal/slibtool_driver_impl.h +++ b/src/internal/slibtool_driver_impl.h @@ -169,6 +169,29 @@ struct slbt_archive_ctx_impl { }; +uint64_t slbt_argv_flags(uint64_t flags); + + +int slbt_driver_usage( + int fdout, + const char * program, + const char * arg, + const struct argv_option ** optv, + struct argv_meta * meta, + struct slbt_split_vector * sargv, + struct slbt_obj_list * objlistv, + int noclr); + + +int slbt_split_argv( + char ** argv, + uint64_t flags, + struct slbt_split_vector * sargv, + struct slbt_obj_list ** aobjlistv, + int fderr, + int fdcwd); + + int slbt_init_host_params( const struct slbt_driver_ctx * dctx, const struct slbt_common_ctx * cctx, |