From 5cc3b3bc6d95bbe4ca3e13b84d43b9d32a64eda1 Mon Sep 17 00:00:00 2001
From: midipix <writeonce@midipix.org>
Date: Sun, 20 Mar 2016 12:57:34 -0400
Subject: link mode: static archive generation: initial implementation.

---
 src/logic/slbt_exec_link.c | 111 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 110 insertions(+), 1 deletion(-)

(limited to 'src/logic')

diff --git a/src/logic/slbt_exec_link.c b/src/logic/slbt_exec_link.c
index 4da33c6..7a86d5e 100644
--- a/src/logic/slbt_exec_link.c
+++ b/src/logic/slbt_exec_link.c
@@ -14,6 +14,105 @@
 #include "slibtool_spawn_impl.h"
 
 
+/*******************************************************************/
+/*                                                                 */
+/* -o <ltlib>  switches              input   result                */
+/* ----------  --------------------- -----   ------                */
+/* libfoo.a    -static               bar.lo  libfoo.a              */
+/*                                                                 */
+/* ar cru libfoo.a bar.lo                                          */
+/* ranlib libfoo.a                                                 */
+/*                                                                 */
+/*******************************************************************/
+
+static bool slbt_adjust_input_argument(char * arg, bool fpic)
+{
+	char *	dot;
+
+	if (*arg == '-')
+		return false;
+
+	if (!(dot = strrchr(arg,'.')))
+		return false;
+
+	if (strcmp(dot,".lo"))
+		return false;
+
+	if (fpic) {
+		/* to do */
+		return false;
+	} else {
+		dot[1] = 'o';
+		dot[2] = '\0';
+		return true;
+	}
+}
+
+static int slbt_exec_link_static_archive(
+	const struct slbt_driver_ctx *	dctx,
+	struct slbt_exec_ctx *		ectx)
+{
+	char ** 	aarg;
+	char ** 	parg;
+	char *		ranlib[3];
+	char		program[2048];
+
+	/* placeholders */
+	slbt_reset_placeholders(ectx);
+
+	/* alternate program (ar, ranlib) */
+	ectx->program = program;
+
+	/* ar alternate argument vector */
+	if ((size_t)snprintf(program,sizeof(program),"%s",
+			dctx->cctx->host.ar) >= sizeof(program))
+		return -1;
+
+	aarg    = ectx->altv;
+	*aarg++ = program;
+	*aarg++ = "cru";
+	*aarg++ = ectx->arfilename;
+
+	/* input argument adjustment */
+	for (parg=ectx->cargv; *parg; parg++)
+		if (slbt_adjust_input_argument(*parg,false))
+			*aarg++ = *parg;
+
+	*aarg = 0;
+	ectx->argv = ectx->altv;
+
+	/* step output */
+	if (!(dctx->cctx->drvflags & SLBT_DRIVER_SILENT))
+		if (slbt_output_link(dctx,ectx))
+			return -1;
+
+	/* ar spawn */
+	if ((slbt_spawn(ectx,true) < 0) || ectx->exitcode)
+		return -1;
+
+	/* ranlib argv */
+	if ((size_t)snprintf(program,sizeof(program),"%s",
+			dctx->cctx->host.ranlib) >= sizeof(program))
+		return -1;
+
+	ranlib[0] = program;
+	ranlib[1] = ectx->arfilename;
+	ranlib[2] = 0;
+	ectx->argv = ranlib;
+
+	/* step output */
+	if (!(dctx->cctx->drvflags & SLBT_DRIVER_SILENT))
+		if (slbt_output_link(dctx,ectx))
+			return -1;
+
+	/* ranlib spawn */
+	if ((slbt_spawn(ectx,true) < 0) || ectx->exitcode)
+		return -1;
+
+	return 0;
+}
+
+
 int slbt_exec_link(
 	const struct slbt_driver_ctx *	dctx,
 	struct slbt_exec_ctx *		ectx)
@@ -32,6 +131,9 @@ int slbt_exec_link(
 	else
 		actx = ectx;
 
+	/* output suffix */
+	dot = strrchr(dctx->cctx->output,'.');
+
 	/* .libs directory */
 	if (dctx->cctx->drvflags & SLBT_DRIVER_SHARED) {
 		if ((fdlibs = open(ectx->ldirname,O_DIRECTORY)) >= 0)
@@ -42,8 +144,15 @@ int slbt_exec_link(
 		}
 	}
 
+	/* non-pic libfoo.a */
+	if (dot && !strcmp(dot,".a"))
+		if (slbt_exec_link_static_archive(dctx,ectx)) {
+			slbt_free_exec_ctx(actx);
+			return -1;
+		}
+
 	/* no wrapper? */
-	if (!(dot = strrchr(dctx->cctx->output,'.')) || strcmp(dot,".la")) {
+	if (!dot || strcmp(dot,".la")) {
 		slbt_free_exec_ctx(actx);
 		return 0;
 	}
-- 
cgit v1.2.3