diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/driver/slbt_driver_ctx.c | 54 | ||||
-rw-r--r-- | src/internal/slibtool_driver_impl.h | 2 | ||||
-rw-r--r-- | src/internal/slibtool_mkvars_impl.c | 226 | ||||
-rw-r--r-- | src/internal/slibtool_mkvars_impl.h | 13 | ||||
-rw-r--r-- | src/skin/slbt_skin_default.c | 4 |
5 files changed, 299 insertions, 0 deletions
diff --git a/src/driver/slbt_driver_ctx.c b/src/driver/slbt_driver_ctx.c index 85c75d2..00e1998 100644 --- a/src/driver/slbt_driver_ctx.c +++ b/src/driver/slbt_driver_ctx.c @@ -22,6 +22,7 @@ #include "slibtool_objlist_impl.h" #include "slibtool_errinfo_impl.h" #include "slibtool_lconf_impl.h" +#include "slibtool_mkvars_impl.h" #include "slibtool_txtline_impl.h" #include "slibtool_stoolie_impl.h" #include "slibtool_ar_impl.h" @@ -32,6 +33,7 @@ extern char ** environ; /* annotation strings */ static const char cfgexplicit[] = "command-line argument"; static const char cfglconf[] = "derived from <libtool>"; +static const char cfgmkvars[] = "derived from <makefile>"; /* package info */ static const struct slbt_source_version slbt_src_version = { @@ -407,6 +409,7 @@ int slbt_lib_get_driver_ctx( struct argv_entry * cmdnoshared; const char * program; const char * lconf; + const char * mkvars; uint64_t lflags; size_t ndlopen; struct argv_entry ** dlopenv; @@ -455,6 +458,7 @@ int slbt_lib_get_driver_ctx( return slbt_free_argv_buffer(&sargv,objlistv); lconf = 0; + mkvars = 0; program = argv_program_name(argv[0]); memset(&cctx,0,sizeof(cctx)); @@ -519,6 +523,10 @@ int slbt_lib_get_driver_ctx( lconf = entry->arg; break; + case TAG_MKVARS: + mkvars = entry->arg; + break; + case TAG_MODE: if (!strcmp("clean",entry->arg)) cctx.mode = SLBT_MODE_CLEAN; @@ -930,6 +938,49 @@ int slbt_lib_get_driver_ctx( ctx->cctx.cargv = sargv.cargv; ctx->meta = meta; + /* mkvars */ + if (mkvars) { + if (slbt_get_mkvars_flags(&ctx->ctx,mkvars,&lflags) < 0) + return slbt_lib_get_driver_ctx_fail(&ctx->ctx,0); + + if (ctx->cctx.host.host && !cfgmeta_host) + cfgmeta_host = cfgmkvars; + + if (ctx->cctx.host.ar && !cfgmeta_ar) + cfgmeta_ar = cfgmkvars; + + if (ctx->cctx.host.as && !cfgmeta_as) + cfgmeta_as = cfgmkvars; + + if (ctx->cctx.host.nm && !cfgmeta_nm) + cfgmeta_nm = cfgmkvars; + + if (ctx->cctx.host.ranlib && !cfgmeta_ranlib) + cfgmeta_ranlib = cfgmkvars; + + if (ctx->cctx.host.dlltool && !cfgmeta_dlltool) + cfgmeta_dlltool = cfgmkvars; + + if (cmdnoshared) + lflags &= ~(uint64_t)SLBT_DRIVER_DISABLE_STATIC; + + if (cmdnostatic) + if (lflags & SLBT_DRIVER_DISABLE_SHARED) + cctx.drvflags &= ~(uint64_t)SLBT_DRIVER_DISABLE_STATIC; + + cctx.drvflags |= lflags; + + /* -disable-static? */ + if (cctx.drvflags & SLBT_DRIVER_DISABLE_STATIC) + cctx.drvflags &= ~(uint64_t)SLBT_DRIVER_STATIC; + + /* -disable-shared? */ + if (cctx.drvflags & SLBT_DRIVER_DISABLE_SHARED) + cctx.drvflags &= ~(uint64_t)SLBT_DRIVER_SHARED; + + ctx->cctx.drvflags = cctx.drvflags; + } + /* heuristics */ if (cctx.drvflags & SLBT_DRIVER_HEURISTICS) { if (slbt_get_lconf_flags(&ctx->ctx,lconf,&lflags) < 0) @@ -1113,6 +1164,9 @@ static void slbt_lib_free_driver_ctx_impl(struct slbt_driver_ctx_alloc * ictx) if (ictx->ctx.lconfctx) slbt_lib_free_txtfile_ctx(ictx->ctx.lconfctx); + if (ictx->ctx.mkvarsctx) + slbt_lib_free_txtfile_ctx(ictx->ctx.mkvarsctx); + for (objlistp=ictx->ctx.objlistv; objlistp->name; objlistp++) { free(objlistp->objv); free(objlistp->addr); diff --git a/src/internal/slibtool_driver_impl.h b/src/internal/slibtool_driver_impl.h index 65e5f96..41c7e0b 100644 --- a/src/internal/slibtool_driver_impl.h +++ b/src/internal/slibtool_driver_impl.h @@ -28,6 +28,7 @@ enum app_tags { TAG_VERSION, TAG_INFO, TAG_CONFIG, + TAG_MKVARS, TAG_DUMPMACHINE, TAG_DEBUG, TAG_DRY_RUN, @@ -160,6 +161,7 @@ struct slbt_driver_ctx_impl { struct slbt_fd_ctx fdctx; struct slbt_map_info lconf; struct slbt_txtfile_ctx * lconfctx; + struct slbt_txtfile_ctx * mkvarsctx; struct slbt_obj_list * objlistv; struct argv_entry ** dlopenv; diff --git a/src/internal/slibtool_mkvars_impl.c b/src/internal/slibtool_mkvars_impl.c new file mode 100644 index 0000000..a18dbfe --- /dev/null +++ b/src/internal/slibtool_mkvars_impl.c @@ -0,0 +1,226 @@ +/*******************************************************************/ +/* 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 <ctype.h> +#include <stdio.h> +#include <stdint.h> +#include <stdbool.h> + +#include "slibtool_mkvars_impl.h" +#include "slibtool_driver_impl.h" +#include "slibtool_errinfo_impl.h" +#include "slibtool_symlink_impl.h" +#include "slibtool_readlink_impl.h" +#include "slibtool_realpath_impl.h" +#include "slibtool_visibility_impl.h" + +static int slbt_get_mkvars_var( + const struct slbt_driver_ctx * dctx, + const struct slbt_txtfile_ctx * tctx, + const char * var, + const char space, + char (*val)[PATH_MAX]) +{ + const char ** pline; + const char * mark; + const char * match; + ssize_t len; + int cint; + + /* init */ + match = 0; + len = strlen(var); + + /* search for ^var= */ + for (pline=tctx->txtlinev; !match && *pline; pline++) { + if (!strncmp(*pline,var,len)) { + if (isspace((*pline)[len]) || ((*pline)[len] == '=')) { + mark = &(*pline)[len]; + + for (; isspace(cint = *mark); ) + mark++; + + if (mark[0] != '=') + return SLBT_CUSTOM_ERROR( + dctx, + SLBT_ERR_MKVARS_PARSE); + + mark++; + + for (; isspace(cint = *mark); ) + mark++; + + match = mark; + } + } + } + + /* not found? */ + if (!match) { + (*val)[0] = '\0'; + return 0; + } + + /* validate */ + for (mark=match; *mark; mark++) { + if ((*mark >= 'a') && (*mark <= 'z')) + (void)0; + + else if ((*mark >= 'A') && (*mark <= 'Z')) + (void)0; + + else if ((*mark >= '0') && (*mark <= '9')) + (void)0; + + else if ((*mark == '+') || (*mark == '-')) + (void)0; + + else if ((*mark == '/') || (*mark == '@')) + (void)0; + + else if ((*mark == '.') || (*mark == '_')) + (void)0; + + else if ((*mark == ':') || (*mark == space)) + (void)0; + + else + return SLBT_CUSTOM_ERROR( + dctx, + SLBT_ERR_MKVARS_PARSE); + } + + /* all done */ + strcpy(*val,match); + + return 0; +} + +slbt_hidden int slbt_get_mkvars_flags( + struct slbt_driver_ctx * dctx, + const char * mkvars, + uint64_t * flags) +{ + struct slbt_driver_ctx_impl * ctx; + struct slbt_txtfile_ctx * confctx; + char * dash; + uint64_t optshared; + uint64_t optstatic; + char val[PATH_MAX]; + + /* driver context (ar, ranlib, cc) */ + ctx = slbt_get_driver_ictx(dctx); + + /* cache the makefile in library friendly form) */ + if (slbt_lib_get_txtfile_ctx(dctx,mkvars,&ctx->mkvarsctx) < 0) + return SLBT_NESTED_ERROR(dctx); + + confctx = ctx->mkvarsctx; + + /* scan */ + optshared = 0; + optstatic = 0; + + /* slibtool */ + if (slbt_get_mkvars_var(dctx,confctx,"SLIBTOOL",0,&val) < 0) + return SLBT_NESTED_ERROR(dctx); + + if ((dash = strrchr(val,'-'))) { + if (!strcmp(dash,"-shared")) { + optshared = SLBT_DRIVER_SHARED; + optstatic = SLBT_DRIVER_DISABLE_STATIC; + + } else if (!strcmp(dash,"-static")) { + optshared = SLBT_DRIVER_DISABLE_SHARED; + optstatic = SLBT_DRIVER_STATIC; + } else { + return SLBT_CUSTOM_ERROR( + dctx, + SLBT_ERR_MKVARS_PARSE); + } + } else { + optshared = SLBT_DRIVER_SHARED; + optstatic = SLBT_DRIVER_STATIC; + } + + *flags = optshared | optstatic; + + /* host */ + if (!ctx->cctx.host.host) { + if (slbt_get_mkvars_var(dctx,confctx,"host",0,&val) < 0) + return SLBT_NESTED_ERROR(dctx); + + if (val[0] && !(ctx->host.host = strdup(val))) + return SLBT_SYSTEM_ERROR(dctx,0); + + ctx->cctx.host.host = ctx->host.host; + } + + + /* ar tool */ + if (!ctx->cctx.host.ar) { + if (slbt_get_mkvars_var(dctx,confctx,"AR",0x20,&val) < 0) + return SLBT_NESTED_ERROR(dctx); + + if (val[0] && !(ctx->host.ar = strdup(val))) + return SLBT_SYSTEM_ERROR(dctx,0); + + ctx->cctx.host.ar = ctx->host.ar; + } + + + /* nm tool */ + if (!ctx->cctx.host.nm) { + if (slbt_get_mkvars_var(dctx,confctx,"NM",0x20,&val) < 0) + return SLBT_NESTED_ERROR(dctx); + + if (val[0] && !(ctx->host.nm = strdup(val))) + return SLBT_SYSTEM_ERROR(dctx,0); + + ctx->cctx.host.nm = ctx->host.nm; + } + + + /* ranlib tool */ + if (!ctx->cctx.host.ranlib) { + if (slbt_get_mkvars_var(dctx,confctx,"RANLIB",0x20,&val) < 0) + return SLBT_NESTED_ERROR(dctx); + + if (val[0] && !(ctx->host.ranlib = strdup(val))) + return SLBT_SYSTEM_ERROR(dctx,0); + + ctx->cctx.host.ranlib = ctx->host.ranlib; + } + + + /* as tool (optional) */ + if (!ctx->cctx.host.as) { + if (slbt_get_mkvars_var(dctx,confctx,"AS",0x20,&val) < 0) + return SLBT_NESTED_ERROR(dctx); + + if (val[0] && !(ctx->host.as = strdup(val))) + return SLBT_SYSTEM_ERROR(dctx,0); + + + ctx->cctx.host.as = ctx->host.as; + } + + + /* dlltool tool (optional) */ + if (!ctx->cctx.host.dlltool) { + if (slbt_get_mkvars_var(dctx,confctx,"DLLTOOL",0x20,&val) < 0) + return SLBT_NESTED_ERROR(dctx); + + if (val[0] && !(ctx->host.dlltool = strdup(val))) + return SLBT_SYSTEM_ERROR(dctx,0); + + ctx->cctx.host.dlltool = ctx->host.dlltool; + } + + + /* all done */ + return 0; +} diff --git a/src/internal/slibtool_mkvars_impl.h b/src/internal/slibtool_mkvars_impl.h new file mode 100644 index 0000000..00ebd99 --- /dev/null +++ b/src/internal/slibtool_mkvars_impl.h @@ -0,0 +1,13 @@ +#ifndef SLIBTOOL_MKVARS_IMPL_H +#define SLIBTOOL_MKVARS_IMPL_H + +#include <stdint.h> + +struct slbt_driver_ctx; + +int slbt_get_mkvars_flags( + struct slbt_driver_ctx * dctx, + const char * mkvars, + uint64_t * flags); + +#endif diff --git a/src/skin/slbt_skin_default.c b/src/skin/slbt_skin_default.c index 7c54f76..476e36e 100644 --- a/src/skin/slbt_skin_default.c +++ b/src/skin/slbt_skin_default.c @@ -18,6 +18,10 @@ const slbt_hidden struct argv_option slbt_default_options[] = { "the %s of which is either provided via this " "command-line argument, or detected by the program."}, + {"mkvars", 0,TAG_MKVARS,ARGV_OPTARG_REQUIRED,0,0,"<makefile>", + "obtain information about the current build project " + "from the specified %s."}, + {"mode", 0,TAG_MODE,ARGV_OPTARG_REQUIRED,0, "clean|compile|execute|finish" "|install|link|uninstall|ar" |