summaryrefslogtreecommitdiff
path: root/src/logic/slbt_exec_link.c
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2016-04-03 19:22:46 -0400
committermidipix <writeonce@midipix.org>2016-04-04 18:05:05 -0400
commitb3940afbd36d80909adf04e2e1e6545d0870ce3d (patch)
treee2ab20a22061d394648772b6debcb2acc7d83281 /src/logic/slbt_exec_link.c
parentd1091b4e9ef0ae62fe95189e49f08ba048544f27 (diff)
downloadslibtool-b3940afbd36d80909adf04e2e1e6545d0870ce3d.tar.bz2
slibtool-b3940afbd36d80909adf04e2e1e6545d0870ce3d.tar.xz
link mode: slbt_exec_link_create_library(): initial implementation.
Diffstat (limited to 'src/logic/slbt_exec_link.c')
-rw-r--r--src/logic/slbt_exec_link.c167
1 files changed, 167 insertions, 0 deletions
diff --git a/src/logic/slbt_exec_link.c b/src/logic/slbt_exec_link.c
index c025a97..7327cb6 100644
--- a/src/logic/slbt_exec_link.c
+++ b/src/logic/slbt_exec_link.c
@@ -88,6 +88,57 @@ static bool slbt_adjust_input_argument(char * arg, bool fpic)
return true;
}
+static bool slbt_adjust_linker_argument(
+ char * arg,
+ bool fpic,
+ const char * dsosuffix,
+ const char * arsuffix)
+{
+ int fdlib;
+ char * slash;
+ char * dot;
+ char base[PATH_MAX];
+
+ if (*arg == '-')
+ return false;
+
+ if (!(dot = strrchr(arg,'.')))
+ return false;
+
+ if (strcmp(dot,".la"))
+ return false;
+
+ if (fpic) {
+ if ((slash = strrchr(arg,'/')))
+ slash++;
+ else
+ slash = arg;
+
+ if ((size_t)snprintf(base,sizeof(base),"%s",
+ slash) >= sizeof(base))
+ return false;
+
+ sprintf(slash,".libs/%s",base);
+ dot = strrchr(arg,'.');
+ }
+
+ /* shared library dependency? */
+ if (fpic) {
+ sprintf(dot,"%s",dsosuffix);
+
+ if ((fdlib = open(arg,O_RDONLY)) >= 0)
+ close(fdlib);
+ else
+ sprintf(dot,"%s",arsuffix);
+
+ return true;
+ }
+
+ /* input archive */
+ sprintf(dot,"%s",arsuffix);
+ return true;
+}
+
static int slbt_exec_link_remove_file(
const struct slbt_driver_ctx * dctx,
struct slbt_exec_ctx * ectx,
@@ -182,6 +233,67 @@ static int slbt_exec_link_create_archive(
return 0;
}
+static int slbt_exec_link_create_library(
+ const struct slbt_driver_ctx * dctx,
+ struct slbt_exec_ctx * ectx,
+ const char * dsofilename)
+{
+ char ** parg;
+ char output [PATH_MAX];
+
+ /* initial state */
+ slbt_reset_arguments(ectx);
+
+ /* placeholders */
+ slbt_reset_placeholders(ectx);
+
+ /* using default argument vector */
+ ectx->argv = ectx->cargv;
+ ectx->program = ectx->cargv[0];
+
+ /* input argument adjustment */
+ for (parg=ectx->cargv; *parg; parg++)
+ slbt_adjust_input_argument(*parg,true);
+
+ /* linker argument adjustment */
+ for (parg=ectx->cargv; *parg; parg++)
+ slbt_adjust_linker_argument(
+ *parg,true,
+ dctx->cctx->settings.dsosuffix,
+ dctx->cctx->settings.arsuffix);
+
+ /* --no-undefined */
+ if (dctx->cctx->drvflags & SLBT_DRIVER_NO_UNDEFINED)
+ *ectx->noundef = "-Wl,--no-undefined";
+
+ /* shared object */
+ *ectx->dpic = "-shared";
+ *ectx->fpic = "-fPIC";
+
+ /* output */
+ if ((size_t)snprintf(output,sizeof(output),"%s.%d.%d.%d",
+ dsofilename,
+ dctx->cctx->verinfo.major,
+ dctx->cctx->verinfo.minor,
+ dctx->cctx->verinfo.revision)
+ >= sizeof(output))
+ return -1;
+
+ *ectx->lout[0] = "-o";
+ *ectx->lout[1] = output;
+
+ /* step output */
+ if (!(dctx->cctx->drvflags & SLBT_DRIVER_SILENT))
+ if (slbt_output_link(dctx,ectx))
+ return -1;
+
+ /* spawn */
+ if ((slbt_spawn(ectx,true) < 0) || ectx->exitcode)
+ return -1;
+
+ return 0;
+}
+
static int slbt_exec_link_create_symlink(
const struct slbt_driver_ctx * dctx,
struct slbt_exec_ctx * ectx,
@@ -227,6 +339,34 @@ static int slbt_exec_link_create_symlink(
return symlink(atarget,lnkname);
}
+static int slbt_exec_link_create_library_symlink(
+ const struct slbt_driver_ctx * dctx,
+ struct slbt_exec_ctx * ectx,
+ bool fmajor)
+{
+ char target[PATH_MAX];
+ char lnkname[PATH_MAX];
+
+ sprintf(target,"%s.%d.%d.%d",
+ ectx->dsofilename,
+ dctx->cctx->verinfo.major,
+ dctx->cctx->verinfo.minor,
+ dctx->cctx->verinfo.revision);
+
+ if (fmajor)
+ sprintf(lnkname,"%s.%d",
+ ectx->dsofilename,
+ dctx->cctx->verinfo.major);
+
+ else
+ strcpy(lnkname,ectx->dsofilename);
+
+ return slbt_exec_link_create_symlink(
+ dctx,ectx,
+ target,lnkname,
+ false);
+}
+
int slbt_exec_link(
const struct slbt_driver_ctx * dctx,
struct slbt_exec_ctx * ectx)
@@ -277,6 +417,33 @@ int slbt_exec_link(
return -1;
}
+ /* dynamic library */
+ if (dot && !strcmp(dot,".la") && dctx->cctx->rpath) {
+ /* linking: libfoo.so.x.y.z */
+ if (slbt_exec_link_create_library(
+ dctx,ectx,
+ ectx->dsofilename)) {
+ slbt_free_exec_ctx(actx);
+ return -1;
+ }
+
+ /* symlink: libfoo.so.x --> libfoo.so.x.y.z */
+ if (slbt_exec_link_create_library_symlink(
+ dctx,ectx,
+ true)) {
+ slbt_free_exec_ctx(actx);
+ return -1;
+ }
+
+ /* symlink: libfoo.so --> libfoo.so.x.y.z */
+ if (slbt_exec_link_create_library_symlink(
+ dctx,ectx,
+ false)) {
+ slbt_free_exec_ctx(actx);
+ return -1;
+ }
+ }
+
/* no wrapper? */
if (!dot || strcmp(dot,".la")) {
slbt_free_exec_ctx(actx);