summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2024-03-30 16:51:17 +0000
committermidipix <writeonce@midipix.org>2024-03-30 16:51:17 +0000
commitc6ecfc312fa1e2d3b128240ce41345ff7c1367d4 (patch)
tree9c10d421d5343eb232b9606c243260d015263afe
parent637ac5ddf9088246d0753dda010ebd303586871c (diff)
downloadslibtool-c6ecfc312fa1e2d3b128240ce41345ff7c1367d4.tar.bz2
slibtool-c6ecfc312fa1e2d3b128240ce41345ff7c1367d4.tar.xz
driver: --mkvars, slbt_get_mkvars_flags(): implementation and integration.
-rw-r--r--include/slibtool/slibtool.h3
-rw-r--r--project/common.mk1
-rw-r--r--project/headers.mk1
-rw-r--r--src/driver/slbt_driver_ctx.c54
-rw-r--r--src/internal/slibtool_driver_impl.h2
-rw-r--r--src/internal/slibtool_mkvars_impl.c226
-rw-r--r--src/internal/slibtool_mkvars_impl.h13
-rw-r--r--src/skin/slbt_skin_default.c4
8 files changed, 304 insertions, 0 deletions
diff --git a/include/slibtool/slibtool.h b/include/slibtool/slibtool.h
index d428e54..3be95e5 100644
--- a/include/slibtool/slibtool.h
+++ b/include/slibtool/slibtool.h
@@ -125,6 +125,9 @@ enum slbt_custom_error {
SLBT_ERR_LCONF_OPEN,
SLBT_ERR_LCONF_MAP,
SLBT_ERR_LCONF_PARSE,
+ SLBT_ERR_MKVARS_OPEN,
+ SLBT_ERR_MKVARS_MAP,
+ SLBT_ERR_MKVARS_PARSE,
SLBT_ERR_AR_FAIL,
SLBT_ERR_AR_EMPTY_FILE,
SLBT_ERR_AR_INVALID_SIGNATURE,
diff --git a/project/common.mk b/project/common.mk
index ace734f..d35b34f 100644
--- a/project/common.mk
+++ b/project/common.mk
@@ -74,6 +74,7 @@ INTERNAL_SRCS = \
src/internal/$(PACKAGE)_libmeta_impl.c \
src/internal/$(PACKAGE)_m4fake_impl.c \
src/internal/$(PACKAGE)_mapfile_impl.c \
+ src/internal/$(PACKAGE)_mkvars_impl.c \
src/internal/$(PACKAGE)_objlist_impl.c \
src/internal/$(PACKAGE)_objmeta_impl.c \
src/internal/$(PACKAGE)_pecoff_impl.c \
diff --git a/project/headers.mk b/project/headers.mk
index 1b77743..56c0a6a 100644
--- a/project/headers.mk
+++ b/project/headers.mk
@@ -18,6 +18,7 @@ INTERNAL_HEADERS = \
$(PROJECT_DIR)/src/internal/$(PACKAGE)_mapfile_impl.h \
$(PROJECT_DIR)/src/internal/$(PACKAGE)_metafile_impl.h \
$(PROJECT_DIR)/src/internal/$(PACKAGE)_mkdir_impl.h \
+ $(PROJECT_DIR)/src/internal/$(PACKAGE)_mkvars_impl.h \
$(PROJECT_DIR)/src/internal/$(PACKAGE)_objlist_impl.h \
$(PROJECT_DIR)/src/internal/$(PACKAGE)_pecoff_impl.h \
$(PROJECT_DIR)/src/internal/$(PACKAGE)_readlink_impl.h \
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"