summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--project/common.mk1
-rw-r--r--project/headers.mk1
-rw-r--r--project/tree.mk1
-rw-r--r--src/internal/slibtool_linkcmd_impl.h24
-rw-r--r--src/logic/linkcmd/slbt_linkcmd_deps.c329
-rw-r--r--src/logic/slbt_exec_link.c316
6 files changed, 357 insertions, 315 deletions
diff --git a/project/common.mk b/project/common.mk
index 8ebd33d..971173d 100644
--- a/project/common.mk
+++ b/project/common.mk
@@ -28,6 +28,7 @@ API_SRCS = \
src/logic/slbt_exec_install.c \
src/logic/slbt_exec_link.c \
src/logic/slbt_exec_uninstall.c \
+ src/logic/linkcmd/slbt_linkcmd_deps.c \
src/output/slbt_output_config.c \
src/output/slbt_output_error.c \
src/output/slbt_output_exec.c \
diff --git a/project/headers.mk b/project/headers.mk
index f847b60..bb2628f 100644
--- a/project/headers.mk
+++ b/project/headers.mk
@@ -12,6 +12,7 @@ INTERNAL_HEADERS = \
$(PROJECT_DIR)/src/internal/$(PACKAGE)_errinfo_impl.h \
$(PROJECT_DIR)/src/internal/$(PACKAGE)_install_impl.h \
$(PROJECT_DIR)/src/internal/$(PACKAGE)_lconf_impl.h \
+ $(PROJECT_DIR)/src/internal/$(PACKAGE)_linkcmd_impl.h \
$(PROJECT_DIR)/src/internal/$(PACKAGE)_mapfile_impl.h \
$(PROJECT_DIR)/src/internal/$(PACKAGE)_metafile_impl.h \
$(PROJECT_DIR)/src/internal/$(PACKAGE)_mkdir_impl.h \
diff --git a/project/tree.mk b/project/tree.mk
index 978e313..c06d62c 100644
--- a/project/tree.mk
+++ b/project/tree.mk
@@ -9,4 +9,5 @@ tree.tag:
mkdir -p src/output
mkdir -p src/skin
mkdir -p src/arbits/output
+ mkdir -p src/logic/linkcmd
touch tree.tag
diff --git a/src/internal/slibtool_linkcmd_impl.h b/src/internal/slibtool_linkcmd_impl.h
new file mode 100644
index 0000000..c2598f3
--- /dev/null
+++ b/src/internal/slibtool_linkcmd_impl.h
@@ -0,0 +1,24 @@
+#ifndef SLIBTOOL_LINKCMD_IMPL_H
+#define SLIBTOOL_LINKCMD_IMPL_H
+
+struct slbt_deps_meta {
+ char ** altv;
+ char * args;
+ int depscnt;
+ int infolen;
+};
+
+int slbt_get_deps_meta(
+ const struct slbt_driver_ctx * dctx,
+ char * libfilename,
+ int fexternal,
+ struct slbt_deps_meta * depsmeta);
+
+int slbt_exec_link_create_dep_file(
+ const struct slbt_driver_ctx * dctx,
+ struct slbt_exec_ctx * ectx,
+ char ** altv,
+ const char * libfilename,
+ bool farchive);
+
+#endif
diff --git a/src/logic/linkcmd/slbt_linkcmd_deps.c b/src/logic/linkcmd/slbt_linkcmd_deps.c
new file mode 100644
index 0000000..2b50ff8
--- /dev/null
+++ b/src/logic/linkcmd/slbt_linkcmd_deps.c
@@ -0,0 +1,329 @@
+/*******************************************************************/
+/* slibtool: a skinny libtool implementation, written in C */
+/* Copyright (C) 2016--2021 SysDeer Technologies, LLC */
+/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
+/*******************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include <slibtool/slibtool.h>
+#include "slibtool_driver_impl.h"
+#include "slibtool_errinfo_impl.h"
+#include "slibtool_linkcmd_impl.h"
+#include "slibtool_mapfile_impl.h"
+#include "slibtool_metafile_impl.h"
+#include "slibtool_snprintf_impl.h"
+
+int slbt_get_deps_meta(
+ const struct slbt_driver_ctx * dctx,
+ char * libfilename,
+ int fexternal,
+ struct slbt_deps_meta * depsmeta)
+{
+ int fdcwd;
+ char * ch;
+ char * cap;
+ char * base;
+ size_t libexlen;
+ struct stat st;
+ struct slbt_map_info * mapinfo;
+ char depfile[PATH_MAX];
+
+ /* fdcwd */
+ fdcwd = slbt_driver_fdcwd(dctx);
+
+ /* -rpath */
+ if (slbt_snprintf(depfile,sizeof(depfile),
+ "%s.slibtool.rpath",
+ libfilename) < 0)
+ return SLBT_BUFFER_ERROR(dctx);
+
+ /* -Wl,%s */
+ if (!fstatat(fdcwd,depfile,&st,AT_SYMLINK_NOFOLLOW)) {
+ depsmeta->infolen += st.st_size + 4;
+ depsmeta->infolen++;
+ }
+
+ /* .deps */
+ if (slbt_snprintf(depfile,sizeof(depfile),
+ "%s.slibtool.deps",
+ libfilename) < 0)
+ return SLBT_BUFFER_ERROR(dctx);
+
+ /* mapinfo */
+ if (!(mapinfo = slbt_map_file(fdcwd,depfile,SLBT_MAP_INPUT)))
+ return (fexternal && (errno == ENOENT))
+ ? 0 : SLBT_SYSTEM_ERROR(dctx,depfile);
+
+ /* copied length */
+ depsmeta->infolen += mapinfo->size;
+ depsmeta->infolen++;
+
+ /* libexlen */
+ libexlen = (base = strrchr(libfilename,'/'))
+ ? strlen(depfile) + 2 + (base - libfilename)
+ : strlen(depfile) + 2;
+
+ /* iterate */
+ ch = mapinfo->addr;
+ cap = mapinfo->cap;
+
+ for (; ch<cap; ) {
+ if (*ch++ == '\n') {
+ depsmeta->infolen += libexlen;
+ depsmeta->depscnt++;
+ }
+ }
+
+ slbt_unmap_file(mapinfo);
+
+ return 0;
+}
+
+
+int slbt_exec_link_create_dep_file(
+ const struct slbt_driver_ctx * dctx,
+ struct slbt_exec_ctx * ectx,
+ char ** altv,
+ const char * libfilename,
+ bool farchive)
+{
+ int ret;
+ int deps;
+ int slen;
+ int fdcwd;
+ char ** parg;
+ char * popt;
+ char * plib;
+ char * path;
+ char * mark;
+ char * base;
+ size_t size;
+ char deplib [PATH_MAX];
+ bool is_reladir;
+ char reladir[PATH_MAX];
+ char depfile[PATH_MAX];
+ struct stat st;
+ int ldepth;
+ int fdyndep;
+ struct slbt_map_info * mapinfo;
+
+ /* fdcwd */
+ fdcwd = slbt_driver_fdcwd(dctx);
+
+ /* depfile */
+ if (slbt_snprintf(depfile,sizeof(depfile),
+ "%s.slibtool.deps",
+ libfilename) < 0)
+ return SLBT_BUFFER_ERROR(dctx);
+
+ /* deps */
+ if ((deps = openat(fdcwd,depfile,O_RDWR|O_CREAT|O_TRUNC,0644)) < 0)
+ return SLBT_SYSTEM_ERROR(dctx,depfile);
+
+ /* iterate */
+ for (parg=altv; *parg; parg++) {
+ popt = 0;
+ plib = 0;
+ path = 0;
+ mapinfo = 0;
+
+ if (!strncmp(*parg,"-l",2)) {
+ popt = *parg;
+ plib = popt + 2;
+
+ } else if (!strncmp(*parg,"-L",2)) {
+ popt = *parg;
+ path = popt + 2;
+
+ } else if (!strncmp(*parg,"-f",2)) {
+ (void)0;
+
+ } else if ((popt = strrchr(*parg,'.')) && !strcmp(popt,".la")) {
+ /* import dependency list */
+ if ((base = strrchr(*parg,'/')))
+ base++;
+ else
+ base = *parg;
+
+ /* [relative .la directory] */
+ if (base > *parg) {
+ slen = slbt_snprintf(
+ reladir,
+ sizeof(reladir),
+ "%s",*parg);
+
+ if (slen < 0) {
+ close(deps);
+ return SLBT_BUFFER_ERROR(dctx);
+ }
+
+ is_reladir = true;
+ reladir[base - *parg - 1] = 0;
+ } else {
+ is_reladir = false;
+ reladir[0] = '.';
+ reladir[1] = 0;
+ }
+
+
+ /* dynamic library dependency? */
+ strcpy(depfile,*parg);
+ mark = depfile + (base - *parg);
+ size = sizeof(depfile) - (base - *parg);
+ slen = slbt_snprintf(mark,size,".libs/%s",base);
+
+ if (slen < 0) {
+ close(deps);
+ return SLBT_BUFFER_ERROR(dctx);
+ }
+
+ mark = strrchr(mark,'.');
+ strcpy(mark,dctx->cctx->settings.dsosuffix);
+
+ fdyndep = !fstatat(fdcwd,depfile,&st,0);
+
+ /* [-L... as needed] */
+ if (fdyndep && (ectx->ldirdepth >= 0)) {
+ if (slbt_dprintf(deps,"-L") < 0) {
+ close(deps);
+ return SLBT_SYSTEM_ERROR(dctx,0);
+ }
+
+ for (ldepth=ectx->ldirdepth; ldepth; ldepth--) {
+ if (slbt_dprintf(deps,"../") < 0) {
+ close(deps);
+ return SLBT_SYSTEM_ERROR(dctx,0);
+ }
+ }
+
+ if (slbt_dprintf(deps,"%s%s.libs\n",
+ (is_reladir ? reladir : ""),
+ (is_reladir ? "/" : "")) < 0) {
+ close(deps);
+ return SLBT_SYSTEM_ERROR(dctx,0);
+ }
+ }
+
+ /* -ldeplib */
+ if (fdyndep) {
+ *popt = 0;
+ mark = base;
+ mark += strlen(dctx->cctx->settings.dsoprefix);
+
+ if (slbt_dprintf(deps,"-l%s\n",mark) < 0) {
+ close(deps);
+ return SLBT_SYSTEM_ERROR(dctx,0);
+ }
+
+ *popt = '.';
+ }
+
+ /* [open dependency list] */
+ strcpy(depfile,*parg);
+ mark = depfile + (base - *parg);
+ size = sizeof(depfile) - (base - *parg);
+ slen = slbt_snprintf(mark,size,".libs/%s",base);
+
+ if (slen < 0) {
+ close(deps);
+ return SLBT_BUFFER_ERROR(dctx);
+ }
+
+ mapinfo = 0;
+
+ mark = strrchr(mark,'.');
+ size = sizeof(depfile) - (mark - depfile);
+
+ if (!farchive) {
+ slen = slbt_snprintf(mark,size,
+ "%s.slibtool.deps",
+ dctx->cctx->settings.dsosuffix);
+
+ if (slen < 0) {
+ close(deps);
+ return SLBT_BUFFER_ERROR(dctx);
+ }
+
+ mapinfo = slbt_map_file(
+ fdcwd,depfile,
+ SLBT_MAP_INPUT);
+
+ if (!mapinfo && (errno != ENOENT)) {
+ close(deps);
+ return SLBT_SYSTEM_ERROR(dctx,0);
+ }
+ }
+
+ if (!mapinfo) {
+ slen = slbt_snprintf(mark,size,
+ ".a.slibtool.deps");
+
+ if (slen < 0) {
+ close(deps);
+ return SLBT_BUFFER_ERROR(dctx);
+ }
+
+ mapinfo = slbt_map_file(
+ fdcwd,depfile,
+ SLBT_MAP_INPUT);
+
+ if (!mapinfo) {
+ strcpy(mark,".a.disabled");
+
+ if (fstatat(fdcwd,depfile,&st,AT_SYMLINK_NOFOLLOW)) {
+ close(deps);
+ return SLBT_SYSTEM_ERROR(dctx,depfile);
+ }
+ }
+ }
+
+ /* [-l... as needed] */
+ while (mapinfo && (mapinfo->mark < mapinfo->cap)) {
+ ret = slbt_mapped_readline(
+ dctx,mapinfo,
+ deplib,sizeof(deplib));
+
+ if (ret) {
+ close(deps);
+ return SLBT_NESTED_ERROR(dctx);
+ }
+
+ ret = ((deplib[0] == '-')
+ && (deplib[1] == 'L')
+ && (deplib[2] != '/'))
+ ? slbt_dprintf(
+ deps,"-L%s/%s",
+ reladir,&deplib[2])
+ : slbt_dprintf(
+ deps,"%s",
+ deplib);
+
+ if (ret < 0) {
+ close(deps);
+ return SLBT_SYSTEM_ERROR(dctx,0);
+ }
+ }
+
+ if (mapinfo)
+ slbt_unmap_file(mapinfo);
+ }
+
+ if (plib && (slbt_dprintf(deps,"-l%s\n",plib) < 0)) {
+ close(deps);
+ return SLBT_SYSTEM_ERROR(dctx,0);
+ }
+
+ if (path && (slbt_dprintf(deps,"-L%s\n",path) < 0)) {
+ close(deps);
+ return SLBT_SYSTEM_ERROR(dctx,0);
+ }
+ }
+
+ return 0;
+}
diff --git a/src/logic/slbt_exec_link.c b/src/logic/slbt_exec_link.c
index 6eb9e8d..cacbe44 100644
--- a/src/logic/slbt_exec_link.c
+++ b/src/logic/slbt_exec_link.c
@@ -19,19 +19,13 @@
#include "slibtool_driver_impl.h"
#include "slibtool_dprintf_impl.h"
#include "slibtool_errinfo_impl.h"
+#include "slibtool_linkcmd_impl.h"
#include "slibtool_mapfile_impl.h"
#include "slibtool_metafile_impl.h"
#include "slibtool_readlink_impl.h"
#include "slibtool_snprintf_impl.h"
#include "slibtool_symlink_impl.h"
-struct slbt_deps_meta {
- char ** altv;
- char * args;
- int depscnt;
- int infolen;
-};
-
/*******************************************************************/
/* */
/* -o <ltlib> switches input result */
@@ -83,72 +77,6 @@ static int slbt_exec_link_exit(
return ret;
}
-static int slbt_get_deps_meta(
- const struct slbt_driver_ctx * dctx,
- char * libfilename,
- int fexternal,
- struct slbt_deps_meta * depsmeta)
-{
- int fdcwd;
- char * ch;
- char * cap;
- char * base;
- size_t libexlen;
- struct stat st;
- struct slbt_map_info * mapinfo;
- char depfile[PATH_MAX];
-
- /* fdcwd */
- fdcwd = slbt_driver_fdcwd(dctx);
-
- /* -rpath */
- if (slbt_snprintf(depfile,sizeof(depfile),
- "%s.slibtool.rpath",
- libfilename) < 0)
- return SLBT_BUFFER_ERROR(dctx);
-
- /* -Wl,%s */
- if (!fstatat(fdcwd,depfile,&st,AT_SYMLINK_NOFOLLOW)) {
- depsmeta->infolen += st.st_size + 4;
- depsmeta->infolen++;
- }
-
- /* .deps */
- if (slbt_snprintf(depfile,sizeof(depfile),
- "%s.slibtool.deps",
- libfilename) < 0)
- return SLBT_BUFFER_ERROR(dctx);
-
- /* mapinfo */
- if (!(mapinfo = slbt_map_file(fdcwd,depfile,SLBT_MAP_INPUT)))
- return (fexternal && (errno == ENOENT))
- ? 0 : SLBT_SYSTEM_ERROR(dctx,depfile);
-
- /* copied length */
- depsmeta->infolen += mapinfo->size;
- depsmeta->infolen++;
-
- /* libexlen */
- libexlen = (base = strrchr(libfilename,'/'))
- ? strlen(depfile) + 2 + (base - libfilename)
- : strlen(depfile) + 2;
-
- /* iterate */
- ch = mapinfo->addr;
- cap = mapinfo->cap;
-
- for (; ch<cap; ) {
- if (*ch++ == '\n') {
- depsmeta->infolen += libexlen;
- depsmeta->depscnt++;
- }
- }
-
- slbt_unmap_file(mapinfo);
-
- return 0;
-}
-
static bool slbt_adjust_object_argument(
char * arg,
bool fpic,
@@ -895,248 +823,6 @@ static int slbt_exec_link_remove_file(
return SLBT_SYSTEM_ERROR(dctx,0);
}
-static int slbt_exec_link_create_dep_file(
- const struct slbt_driver_ctx * dctx,
- struct slbt_exec_ctx * ectx,
- char ** altv,
- const char * libfilename,
- bool farchive)
-{
- int ret;
- int deps;
- int slen;
- int fdcwd;
- char ** parg;
- char * popt;
- char * plib;
- char * path;
- char * mark;
- char * base;
- size_t size;
- char deplib [PATH_MAX];
- bool is_reladir;
- char reladir[PATH_MAX];
- char depfile[PATH_MAX];
- struct stat st;
- int ldepth;
- int fdyndep;
- struct slbt_map_info * mapinfo;
-
- /* fdcwd */
- fdcwd = slbt_driver_fdcwd(dctx);
-
- /* depfile */
- if (slbt_snprintf(depfile,sizeof(depfile),
- "%s.slibtool.deps",
- libfilename) < 0)
- return SLBT_BUFFER_ERROR(dctx);
-
- /* deps */
- if ((deps = openat(fdcwd,depfile,O_RDWR|O_CREAT|O_TRUNC,0644)) < 0)
- return SLBT_SYSTEM_ERROR(dctx,depfile);
-
- /* iterate */
- for (parg=altv; *parg; parg++) {
- popt = 0;
- plib = 0;
- path = 0;
- mapinfo = 0;
-
- if (!strncmp(*parg,"-l",2)) {
- popt = *parg;
- plib = popt + 2;
-
- } else if (!strncmp(*parg,"-L",2)) {
- popt = *parg;
- path = popt + 2;
-
- } else if (!strncmp(*parg,"-f",2)) {
- (void)0;
-
- } else if ((popt = strrchr(*parg,'.')) && !strcmp(popt,".la")) {
- /* import dependency list */
- if ((base = strrchr(*parg,'/')))
- base++;
- else
- base = *parg;
-
- /* [relative .la directory] */
- if (base > *parg) {
- slen = slbt_snprintf(
- reladir,
- sizeof(reladir),
- "%s",*parg);
-
- if (slen < 0) {
- close(deps);
- return SLBT_BUFFER_ERROR(dctx);
- }
-
- is_reladir = true;
- reladir[base - *parg - 1] = 0;
- } else {
- is_reladir = false;
- reladir[0] = '.';
- reladir[1] = 0;
- }
-
-
- /* dynamic library dependency? */
- strcpy(depfile,*parg);
- mark = depfile + (base - *parg);
- size = sizeof(depfile) - (base - *parg);
- slen = slbt_snprintf(mark,size,".libs/%s",base);
-
- if (slen < 0) {
- close(deps);
- return SLBT_BUFFER_ERROR(dctx);
- }
-
- mark = strrchr(mark,'.');
- strcpy(mark,dctx->cctx->settings.dsosuffix);
-
- fdyndep = !fstatat(fdcwd,depfile,&st,0);
-
- /* [-L... as needed] */
- if (fdyndep && (ectx->ldirdepth >= 0)) {
- if (slbt_dprintf(deps,"-L") < 0) {
- close(deps);
- return SLBT_SYSTEM_ERROR(dctx,0);
- }
-
- for (ldepth=ectx->ldirdepth; ldepth; ldepth--) {
- if (slbt_dprintf(deps,"../") < 0) {
- close(deps);
- return SLBT_SYSTEM_ERROR(dctx,0);
- }
- }
-
- if (slbt_dprintf(deps,"%s%s.libs\n",
- (is_reladir ? reladir : ""),
- (is_reladir ? "/" : "")) < 0) {
- close(deps);
- return SLBT_SYSTEM_ERROR(dctx,0);
- }
- }
-
- /* -ldeplib */
- if (fdyndep) {
- *popt = 0;
- mark = base;
- mark += strlen(dctx->cctx->settings.dsoprefix);
-
- if (slbt_dprintf(deps,"-l%s\n",mark) < 0) {
- close(deps);
- return SLBT_SYSTEM_ERROR(dctx,0);
- }
-
- *popt = '.';
- }
-
- /* [open dependency list] */
- strcpy(depfile,*parg);
- mark = depfile + (base - *parg);
- size = sizeof(depfile) - (base - *parg);
- slen = slbt_snprintf(mark,size,".libs/%s",base);
-
- if (slen < 0) {
- close(deps);
- return SLBT_BUFFER_ERROR(dctx);
- }
-
- mapinfo = 0;
-
- mark = strrchr(mark,'.');
- size = sizeof(depfile) - (mark - depfile);
-
- if (!farchive) {
- slen = slbt_snprintf(mark,size,
- "%s.slibtool.deps",
- dctx->cctx->settings.dsosuffix);
-
- if (slen < 0) {
- close(deps);
- return SLBT_BUFFER_ERROR(dctx);
- }
-
- mapinfo = slbt_map_file(
- fdcwd,depfile,
- SLBT_MAP_INPUT);
-
- if (!mapinfo && (errno != ENOENT)) {
- close(deps);
- return SLBT_SYSTEM_ERROR(dctx,0);
- }
- }
-
- if (!mapinfo) {
- slen = slbt_snprintf(mark,size,
- ".a.slibtool.deps");
-
- if (slen < 0) {
- close(deps);
- return SLBT_BUFFER_ERROR(dctx);
- }
-
- mapinfo = slbt_map_file(
- fdcwd,depfile,
- SLBT_MAP_INPUT);
-
- if (!mapinfo) {
- strcpy(mark,".a.disabled");
-
- if (fstatat(fdcwd,depfile,&st,AT_SYMLINK_NOFOLLOW)) {
- close(deps);
- return SLBT_SYSTEM_ERROR(dctx,depfile);
- }
- }
- }
-
- /* [-l... as needed] */
- while (mapinfo && (mapinfo->mark < mapinfo->cap)) {
- ret = slbt_mapped_readline(
- dctx,mapinfo,
- deplib,sizeof(deplib));
-
- if (ret) {
- close(deps);
- return SLBT_NESTED_ERROR(dctx);
- }
-
- ret = ((deplib[0] == '-')
- && (deplib[1] == 'L')
- && (deplib[2] != '/'))
- ? slbt_dprintf(
- deps,"-L%s/%s",
- reladir,&deplib[2])
- : slbt_dprintf(
- deps,"%s",
- deplib);
-
- if (ret < 0) {
- close(deps);
- return SLBT_SYSTEM_ERROR(dctx,0);
- }
- }
-
- if (mapinfo)
- slbt_unmap_file(mapinfo);
- }
-
- if (plib && (slbt_dprintf(deps,"-l%s\n",plib) < 0)) {
- close(deps);
- return SLBT_SYSTEM_ERROR(dctx,0);
- }
-
- if (path && (slbt_dprintf(deps,"-L%s\n",path) < 0)) {
- close(deps);
- return SLBT_SYSTEM_ERROR(dctx,0);
- }
- }
-
- return 0;
-}
-
static int slbt_exec_link_create_host_tag(
const struct slbt_driver_ctx * dctx,
struct slbt_exec_ctx * ectx,