diff --git a/include/slibtool/slibtool.h b/include/slibtool/slibtool.h index bb1fc84..153a202 100644 --- a/include/slibtool/slibtool.h +++ b/include/slibtool/slibtool.h @@ -78,6 +78,9 @@ extern "C" { #define SLBT_DRIVER_MODE_AR_CHECK SLBT_DRIVER_XFLAG(0x020000) #define SLBT_DRIVER_MODE_AR_MERGE SLBT_DRIVER_XFLAG(0x040000) +#define SLBT_DRIVER_MODE_STOOLIE SLBT_DRIVER_XFLAG(0x080000) +#define SLBT_DRIVER_MODE_SLIBTOOLIZE SLBT_DRIVER_XFLAG(0x080000) + #define SLBT_DRIVER_PREFER_SHARED SLBT_DRIVER_XFLAG(0x100000) #define SLBT_DRIVER_PREFER_STATIC SLBT_DRIVER_XFLAG(0x200000) @@ -154,6 +157,7 @@ enum slbt_mode { SLBT_MODE_LINK, SLBT_MODE_UNINSTALL, SLBT_MODE_AR, + SLBT_MODE_STOOLIE, }; enum slbt_tag { @@ -422,6 +426,8 @@ slbt_api int slbt_exec_install (const struct slbt_driver_ctx *); slbt_api int slbt_exec_link (const struct slbt_driver_ctx *); slbt_api int slbt_exec_uninstall (const struct slbt_driver_ctx *); slbt_api int slbt_exec_ar (const struct slbt_driver_ctx *); +slbt_api int slbt_exec_stoolie (const struct slbt_driver_ctx *); +slbt_api int slbt_exec_slibtoolize (const struct slbt_driver_ctx *); /* host and flavor interfaces */ slbt_api int slbt_host_set_althost (const struct slbt_driver_ctx *, const char * host, const char * flavor); diff --git a/project/common.mk b/project/common.mk index e7d687a..a87d577 100644 --- a/project/common.mk +++ b/project/common.mk @@ -39,6 +39,7 @@ API_SRCS = \ src/logic/slbt_exec_execute.c \ src/logic/slbt_exec_install.c \ src/logic/slbt_exec_link.c \ + src/logic/slbt_exec_stoolie.c \ src/logic/slbt_exec_uninstall.c \ src/logic/linkcmd/slbt_linkcmd_archive.c \ src/logic/linkcmd/slbt_linkcmd_argv.c \ @@ -58,6 +59,7 @@ API_SRCS = \ src/skin/slbt_skin_ar.c \ src/skin/slbt_skin_default.c \ src/skin/slbt_skin_install.c \ + src/skin/slbt_skin_stoolie.c \ src/skin/slbt_skin_uninstall.c \ FALLBACK_SRCS = \ diff --git a/project/extras.mk b/project/extras.mk index da2faaf..5118914 100644 --- a/project/extras.mk +++ b/project/extras.mk @@ -15,6 +15,7 @@ RAPUNZEL = rlibtool RAPUNCEL = rclibtool RAPUNDEL = rdlibtool RAPUNJEL = rdclibtool +STOOLIE = slibtoolize install-app-extras: mkdir -p $(DESTDIR)$(BINDIR) @@ -38,6 +39,8 @@ install-app-extras: rm -f bin/$(RAPUNDEL)$(OS_APP_SUFFIX).tmp rm -f bin/$(RAPUNJEL)$(OS_APP_SUFFIX).tmp + rm -f bin/$(STOOLIE)$(OS_APP_SUFFIX).tmp + ln -s ./$(NICKNAME)$(OS_APP_SUFFIX) bin/$(NICKNAME)-shared$(OS_APP_SUFFIX).tmp ln -s ./$(NICKNAME)$(OS_APP_SUFFIX) bin/$(NICKNAME)-static$(OS_APP_SUFFIX).tmp ln -s ./$(NICKNAME)$(OS_APP_SUFFIX) bin/$(NICKNAME)-ar$(OS_APP_SUFFIX).tmp @@ -57,6 +60,8 @@ install-app-extras: ln -s ./$(NICKNAME)$(OS_APP_SUFFIX) bin/$(RAPUNDEL)$(OS_APP_SUFFIX).tmp ln -s ./$(NICKNAME)$(OS_APP_SUFFIX) bin/$(RAPUNJEL)$(OS_APP_SUFFIX).tmp + ln -s ./$(NICKNAME)$(OS_APP_SUFFIX) bin/$(STOOLIE)$(OS_APP_SUFFIX).tmp + mv bin/$(NICKNAME)-shared$(OS_APP_SUFFIX).tmp $(DESTDIR)$(BINDIR)/$(NICKNAME)-shared$(OS_APP_SUFFIX) mv bin/$(NICKNAME)-static$(OS_APP_SUFFIX).tmp $(DESTDIR)$(BINDIR)/$(NICKNAME)-static$(OS_APP_SUFFIX) mv bin/$(NICKNAME)-ar$(OS_APP_SUFFIX).tmp $(DESTDIR)$(BINDIR)/$(NICKNAME)-ar$(OS_APP_SUFFIX) @@ -75,3 +80,5 @@ install-app-extras: mv bin/$(RAPUNCEL)$(OS_APP_SUFFIX).tmp $(DESTDIR)$(BINDIR)/$(RAPUNCEL)$(OS_APP_SUFFIX) mv bin/$(RAPUNDEL)$(OS_APP_SUFFIX).tmp $(DESTDIR)$(BINDIR)/$(RAPUNDEL)$(OS_APP_SUFFIX) mv bin/$(RAPUNJEL)$(OS_APP_SUFFIX).tmp $(DESTDIR)$(BINDIR)/$(RAPUNJEL)$(OS_APP_SUFFIX) + + mv bin/$(STOOLIE)$(OS_APP_SUFFIX).tmp $(DESTDIR)$(BINDIR)/$(STOOLIE)$(OS_APP_SUFFIX) diff --git a/project/headers.mk b/project/headers.mk index b986ec2..f57eaae 100644 --- a/project/headers.mk +++ b/project/headers.mk @@ -23,6 +23,7 @@ INTERNAL_HEADERS = \ $(PROJECT_DIR)/src/internal/$(PACKAGE)_realpath_impl.h \ $(PROJECT_DIR)/src/internal/$(PACKAGE)_snprintf_impl.h \ $(PROJECT_DIR)/src/internal/$(PACKAGE)_spawn_impl.h \ + $(PROJECT_DIR)/src/internal/$(PACKAGE)_stoolie_impl.h \ $(PROJECT_DIR)/src/internal/$(PACKAGE)_symlink_impl.h \ $(PROJECT_DIR)/src/internal/$(PACKAGE)_uninstall_impl.h \ $(PROJECT_DIR)/src/internal/$(PACKAGE)_visibility_impl.h \ diff --git a/src/driver/slbt_amain.c b/src/driver/slbt_amain.c index 3b21500..73d1462 100644 --- a/src/driver/slbt_amain.c +++ b/src/driver/slbt_amain.c @@ -85,6 +85,9 @@ static void slbt_perform_driver_actions(struct slbt_driver_ctx * dctx) if (dctx->cctx->mode == SLBT_MODE_AR) slbt_exec_ar(dctx); + + if (dctx->cctx->mode == SLBT_MODE_STOOLIE) + slbt_exec_stoolie(dctx); } static int slbt_exit(struct slbt_driver_ctx * dctx, int ret) @@ -132,6 +135,13 @@ int slbt_main(char ** argv, char ** envp, const struct slbt_fd_ctx * fdctx) else if (!(strcmp(dash,"ar"))) flags |= SLBT_DRIVER_MODE_AR; + /* slibtoolize (stoolie) mode */ + if (!(strcmp(program,"stoolie"))) + flags |= SLBT_DRIVER_MODE_STOOLIE; + + else if (!(strcmp(program,"slibtoolize"))) + flags |= SLBT_DRIVER_MODE_STOOLIE; + /* debug */ if (!(strcmp(program,"dlibtool"))) flags |= SLBT_DRIVER_DEBUG; @@ -182,9 +192,10 @@ int slbt_main(char ** argv, char ** envp, const struct slbt_fd_ctx * fdctx) /* --version must be the first (and only) action */ if (dctx->cctx->drvflags & SLBT_DRIVER_VERSION) if (dctx->cctx->mode != SLBT_MODE_AR) - return (slbt_version(dctx,fdout) < 0) - ? slbt_exit(dctx,SLBT_ERROR) - : slbt_exit(dctx,SLBT_OK); + if (dctx->cctx->mode != SLBT_MODE_STOOLIE) + return (slbt_version(dctx,fdout) < 0) + ? slbt_exit(dctx,SLBT_ERROR) + : slbt_exit(dctx,SLBT_OK); /* perform all other actions */ slbt_perform_driver_actions(dctx); diff --git a/src/driver/slbt_driver_ctx.c b/src/driver/slbt_driver_ctx.c index a5b3861..3bb0e58 100644 --- a/src/driver/slbt_driver_ctx.c +++ b/src/driver/slbt_driver_ctx.c @@ -454,6 +454,9 @@ int slbt_lib_get_driver_ctx( if (flags & SLBT_DRIVER_MODE_AR) cctx.mode = SLBT_MODE_AR; + else if (flags & SLBT_DRIVER_MODE_STOOLIE) + cctx.mode = SLBT_MODE_STOOLIE; + /* default flags (set at compile time and derived from symlink) */ cctx.drvflags = flags; @@ -484,6 +487,7 @@ int slbt_lib_get_driver_ctx( case SLBT_MODE_INSTALL: case SLBT_MODE_UNINSTALL: case SLBT_MODE_AR: + case SLBT_MODE_STOOLIE: break; default: @@ -531,6 +535,12 @@ int slbt_lib_get_driver_ctx( else if (!strcmp("ar",entry->arg)) cctx.mode = SLBT_MODE_AR; + + else if (!strcmp("stoolie",entry->arg)) + cctx.mode = SLBT_MODE_STOOLIE; + + else if (!strcmp("slibtoolize",entry->arg)) + cctx.mode = SLBT_MODE_STOOLIE; break; case TAG_FINISH: diff --git a/src/driver/slbt_split_argv.c b/src/driver/slbt_split_argv.c index 43af9f8..7ad20a3 100644 --- a/src/driver/slbt_split_argv.c +++ b/src/driver/slbt_split_argv.c @@ -16,6 +16,7 @@ #include "slibtool_objlist_impl.h" #include "slibtool_errinfo_impl.h" #include "slibtool_visibility_impl.h" +#include "slibtool_stoolie_impl.h" #include "slibtool_ar_impl.h" #include "argv/argv.h" @@ -59,6 +60,7 @@ slbt_hidden int slbt_split_argv( struct argv_entry * ccwrap; struct argv_entry * dumpmachine; struct argv_entry * aropt; + struct argv_entry * stoolieopt; const struct argv_option ** popt; const struct argv_option ** optout; const struct argv_option * optv[SLBT_OPTV_ELEMENTS]; @@ -71,6 +73,8 @@ slbt_hidden int slbt_split_argv( /* missing arguments? */ if ((altmode = (flags & SLBT_DRIVER_MODE_AR))) { slbt_optv_init(slbt_ar_options,optv); + } else if ((altmode = (flags & SLBT_DRIVER_MODE_STOOLIE))) { + slbt_optv_init(slbt_stoolie_options,optv); } else { slbt_optv_init(slbt_default_options,optv); } @@ -120,7 +124,7 @@ slbt_hidden int slbt_split_argv( } /* missing all of --mode, --help, --version, --info, --config, --dumpmachine, --features, and --finish? */ - mode = help = version = info = config = finish = features = ccwrap = dumpmachine = aropt = 0; + mode = help = version = info = config = finish = features = ccwrap = dumpmachine = aropt = stoolieopt = 0; for (entry=meta->entries; entry->fopt; entry++) if (entry->tag == TAG_MODE) @@ -146,11 +150,17 @@ slbt_hidden int slbt_split_argv( if (!altmode && mode && !strcmp(mode->arg,"ar")) aropt = mode; + if (!altmode && mode && !strcmp(mode->arg,"stoolie")) + stoolieopt = mode; + + if (!altmode && mode && !strcmp(mode->arg,"slibtoolize")) + stoolieopt = mode; + /* release temporary argv meta context */ slbt_argv_free(meta); /* error not due to an altmode argument? */ - if (!aropt && ctx.erridx && (ctx.erridx == ctx.unitidx)) { + if (!aropt && !stoolieopt && ctx.erridx && (ctx.erridx == ctx.unitidx)) { if (flags & SLBT_DRIVER_VERBOSITY_ERRORS) slbt_argv_get( argv,optv, @@ -167,12 +177,14 @@ slbt_hidden int slbt_split_argv( } /* missing compiler? */ - if (!ctx.unitidx && !help && !info && !config && !version && !finish && !features && !dumpmachine && !altmode && !aropt) { - if (flags & SLBT_DRIVER_VERBOSITY_ERRORS) - slbt_dprintf(fderr, - "%s: error: is missing.\n", - program); - return -1; + if (!ctx.unitidx && !help && !info && !config && !version && !finish && !features && !dumpmachine) { + if (!altmode && !aropt && !stoolieopt) { + if (flags & SLBT_DRIVER_VERBOSITY_ERRORS) + slbt_dprintf(fderr, + "%s: error: is missing.\n", + program); + return -1; + } } /* clone and normalize the argv vector */ @@ -196,7 +208,7 @@ slbt_hidden int slbt_split_argv( csysroot = 0; for (i=0,flast=false,dargv=sargv->dargv,dst=sargv->dargs; itargv[i] = argv[i]; @@ -349,7 +365,7 @@ slbt_hidden int slbt_split_argv( cargv = sargv->cargv; /* known wrappers */ - if (ctx.unitidx && !ccwrap && !aropt) { + if (ctx.unitidx && !ccwrap && !aropt && !stoolieopt) { if ((base = strrchr(argv[i],'/'))) base++; else if ((base = strrchr(argv[i],'\\'))) @@ -375,6 +391,8 @@ slbt_hidden int slbt_split_argv( i = 0; } else if (aropt) { *cargv++ = argv[0]; + } else if (stoolieopt) { + *cargv++ = argv[0]; } else { *cargv++ = argv[i++]; } @@ -388,6 +406,9 @@ slbt_hidden int slbt_split_argv( if (aropt && (i >= ctx.unitidx)) { *cargv++ = argv[i]; + } else if (stoolieopt && (i >= ctx.unitidx)) { + *cargv++ = argv[i]; + } else if (argv[i][0] != '-') { if (argv[i+1] && (argv[i+1][0] == '+') && (argv[i+1][1] == '=') diff --git a/src/internal/slibtool_driver_impl.h b/src/internal/slibtool_driver_impl.h index 047a69b..458f74f 100644 --- a/src/internal/slibtool_driver_impl.h +++ b/src/internal/slibtool_driver_impl.h @@ -102,6 +102,9 @@ enum app_tags { TAG_AR_MERGE, TAG_AR_OUTPUT, TAG_AR_VERBOSE, + /* slibtoolize (stoolie) mode */ + TAG_STLE_VERSION, + TAG_STLE_HELP, }; struct slbt_split_vector { diff --git a/src/internal/slibtool_stoolie_impl.h b/src/internal/slibtool_stoolie_impl.h new file mode 100644 index 0000000..43d70a5 --- /dev/null +++ b/src/internal/slibtool_stoolie_impl.h @@ -0,0 +1,15 @@ +/*******************************************************************/ +/* slibtool: a strong libtool implementation, written in C */ +/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */ +/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ +/*******************************************************************/ + +#ifndef SLIBTOOL_STOOLIE_IMPL_H +#define SLIBTOOL_STOOLIE_IMPL_H + +#include "argv/argv.h" +#include + +extern const struct argv_option slbt_stoolie_options[]; + +#endif diff --git a/src/logic/slbt_exec_stoolie.c b/src/logic/slbt_exec_stoolie.c new file mode 100644 index 0000000..6b2f883 --- /dev/null +++ b/src/logic/slbt_exec_stoolie.c @@ -0,0 +1,178 @@ +/*******************************************************************/ +/* slibtool: a strong libtool implementation, written in C */ +/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */ +/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ +/*******************************************************************/ + +#include +#include +#include "slibtool_driver_impl.h" +#include "slibtool_stoolie_impl.h" +#include "slibtool_errinfo_impl.h" +#include "argv/argv.h" + +static int slbt_stoolie_usage( + int fdout, + const char * program, + const char * arg, + const struct argv_option ** optv, + struct argv_meta * meta, + struct slbt_exec_ctx * ectx, + int noclr) +{ + char header[512]; + bool stooliemode; + + stooliemode = !strcmp(program,"slibtoolize"); + + snprintf(header,sizeof(header), + "Usage: %s%s [options] ...\n" + "Options:\n", + program, + stooliemode ? "" : " --mode=slibtoolize"); + + switch (noclr) { + case 0: + slbt_argv_usage(fdout,header,optv,arg); + break; + + default: + slbt_argv_usage_plain(fdout,header,optv,arg); + break; + } + + if (ectx) + slbt_ectx_free_exec_ctx(ectx); + + slbt_argv_free(meta); + + return SLBT_USAGE; +} + +static int slbt_exec_stoolie_fail( + struct slbt_exec_ctx * ectx, + struct argv_meta * meta, + int ret) +{ + slbt_argv_free(meta); + slbt_ectx_free_exec_ctx(ectx); + return ret; +} + +static int slbt_exec_stoolie_perform_actions( + const struct slbt_driver_ctx * dctx) +{ + (void)dctx; + return 0; +} + +int slbt_exec_stoolie(const struct slbt_driver_ctx * dctx) +{ + int ret; + int fdout; + int fderr; + char ** argv; + char ** iargv; + struct slbt_exec_ctx * ectx; + struct slbt_driver_ctx_impl * ictx; + const struct slbt_common_ctx * cctx; + struct argv_meta * meta; + struct argv_entry * entry; + size_t nunits; + const struct argv_option * optv[SLBT_OPTV_ELEMENTS]; + + /* context */ + if (slbt_ectx_get_exec_ctx(dctx,&ectx) < 0) + return SLBT_NESTED_ERROR(dctx); + + /* initial state, slibtoolize (stoolie) mode skin */ + slbt_ectx_reset_arguments(ectx); + slbt_disable_placeholders(ectx); + + ictx = slbt_get_driver_ictx(dctx); + cctx = dctx->cctx; + iargv = ectx->cargv; + + fdout = slbt_driver_fdout(dctx); + fderr = slbt_driver_fderr(dctx); + + (void)fderr; + + /* missing arguments? */ + slbt_optv_init(slbt_stoolie_options,optv); + + if (!iargv[1] && (dctx->cctx->drvflags & SLBT_DRIVER_VERBOSITY_USAGE)) + return slbt_stoolie_usage( + fdout, + dctx->program, + 0,optv,0,ectx, + dctx->cctx->drvflags & SLBT_DRIVER_ANNOTATE_NEVER); + + /* argv meta */ + if (!(meta = slbt_argv_get( + iargv,optv, + dctx->cctx->drvflags & SLBT_DRIVER_VERBOSITY_ERRORS + ? ARGV_VERBOSITY_ERRORS + : ARGV_VERBOSITY_NONE, + fdout))) + return slbt_exec_stoolie_fail( + ectx,meta, + SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_AR_FAIL)); + + /* dest, alternate argument vector options */ + argv = ectx->altv; + *argv++ = iargv[0]; + nunits = 0; + + for (entry=meta->entries; entry->fopt || entry->arg; entry++) { + if (entry->fopt) { + switch (entry->tag) { + case TAG_STLE_HELP: + slbt_stoolie_usage( + fdout, + dctx->program, + 0,optv,0,ectx, + dctx->cctx->drvflags + & SLBT_DRIVER_ANNOTATE_NEVER); + + ictx->cctx.drvflags |= SLBT_DRIVER_VERSION; + ictx->cctx.drvflags ^= SLBT_DRIVER_VERSION; + + slbt_argv_free(meta); + + return SLBT_OK; + + case TAG_STLE_VERSION: + ictx->cctx.drvflags |= SLBT_DRIVER_VERSION; + break; + } + + if (entry->fval) { + *argv++ = (char *)entry->arg; + } + } else { + nunits++; + }; + } + + /* defer --version printing to slbt_main() as needed */ + if (cctx->drvflags & SLBT_DRIVER_VERSION) { + slbt_argv_free(meta); + slbt_ectx_free_exec_ctx(ectx); + return SLBT_OK; + } + + /* slibtoolize operations */ + ret = slbt_exec_stoolie_perform_actions(dctx); + + /* all done */ + slbt_argv_free(meta); + slbt_ectx_free_exec_ctx(ectx); + + return ret; +} + +int slbt_exec_slibtoolize(const struct slbt_driver_ctx * dctx) +{ + return slbt_exec_stoolie(dctx); +} diff --git a/src/skin/slbt_skin_default.c b/src/skin/slbt_skin_default.c index 630afc1..7c54f76 100644 --- a/src/skin/slbt_skin_default.c +++ b/src/skin/slbt_skin_default.c @@ -20,7 +20,8 @@ const slbt_hidden struct argv_option slbt_default_options[] = { {"mode", 0,TAG_MODE,ARGV_OPTARG_REQUIRED,0, "clean|compile|execute|finish" - "|install|link|uninstall|ar",0, + "|install|link|uninstall|ar" + "|stoolie|slibtoolize",0, "set the execution mode, where " "is one of {%s}. of the above modes, " "'finish' is not needed and is therefore " diff --git a/src/skin/slbt_skin_stoolie.c b/src/skin/slbt_skin_stoolie.c new file mode 100644 index 0000000..c4a10b8 --- /dev/null +++ b/src/skin/slbt_skin_stoolie.c @@ -0,0 +1,13 @@ +#include "slibtool_driver_impl.h" +#include "slibtool_visibility_impl.h" +#include "argv/argv.h" + +const slbt_hidden struct argv_option slbt_stoolie_options[] = { + {"version", 0,TAG_STLE_VERSION,ARGV_OPTARG_NONE,0,0,0, + "show version information"}, + + {"help", 'h',TAG_STLE_HELP,ARGV_OPTARG_NONE,0,0,0, + "display slibtoolize (stoolie) mode help"}, + + {0,0,0,0,0,0,0,0} +};