|
|
b08054 |
/*******************************************************************/
|
|
|
eac61a |
/* slibtool: a strong libtool implementation, written in C */
|
|
|
49181b |
/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */
|
|
|
b08054 |
/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
|
|
|
b08054 |
/*******************************************************************/
|
|
|
b08054 |
|
|
|
b08054 |
#include <stdlib.h>
|
|
|
b08054 |
#include <stdio.h>
|
|
|
b08054 |
#include <string.h>
|
|
|
b08054 |
#include <fcntl.h>
|
|
|
b08054 |
#include <errno.h>
|
|
|
b08054 |
#include <sys/stat.h>
|
|
|
b08054 |
|
|
|
b08054 |
#include <slibtool/slibtool.h>
|
|
|
b08054 |
#include "slibtool_driver_impl.h"
|
|
|
b08054 |
#include "slibtool_errinfo_impl.h"
|
|
|
b08054 |
#include "slibtool_linkcmd_impl.h"
|
|
|
b08054 |
#include "slibtool_mapfile_impl.h"
|
|
|
b08054 |
#include "slibtool_metafile_impl.h"
|
|
|
43ee04 |
#include "slibtool_realpath_impl.h"
|
|
|
b08054 |
#include "slibtool_snprintf_impl.h"
|
|
|
4b56de |
#include "slibtool_visibility_impl.h"
|
|
|
b08054 |
|
|
|
4b56de |
slbt_hidden int slbt_get_deps_meta(
|
|
|
b08054 |
const struct slbt_driver_ctx * dctx,
|
|
|
b08054 |
char * libfilename,
|
|
|
b08054 |
int fexternal,
|
|
|
b08054 |
struct slbt_deps_meta * depsmeta)
|
|
|
b08054 |
{
|
|
|
b08054 |
int fdcwd;
|
|
|
b08054 |
char * ch;
|
|
|
b08054 |
char * cap;
|
|
|
b08054 |
char * base;
|
|
|
b08054 |
size_t libexlen;
|
|
|
b08054 |
struct stat st;
|
|
|
b08054 |
struct slbt_map_info * mapinfo;
|
|
|
b08054 |
char depfile[PATH_MAX];
|
|
|
b08054 |
|
|
|
b08054 |
/* fdcwd */
|
|
|
b08054 |
fdcwd = slbt_driver_fdcwd(dctx);
|
|
|
b08054 |
|
|
|
b08054 |
/* -rpath */
|
|
|
b08054 |
if (slbt_snprintf(depfile,sizeof(depfile),
|
|
|
b08054 |
"%s.slibtool.rpath",
|
|
|
b08054 |
libfilename) < 0)
|
|
|
b08054 |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
b08054 |
|
|
|
b08054 |
/* -Wl,%s */
|
|
|
b08054 |
if (!fstatat(fdcwd,depfile,&st,AT_SYMLINK_NOFOLLOW)) {
|
|
|
b08054 |
depsmeta->infolen += st.st_size + 4;
|
|
|
b08054 |
depsmeta->infolen++;
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
b08054 |
/* .deps */
|
|
|
b08054 |
if (slbt_snprintf(depfile,sizeof(depfile),
|
|
|
b08054 |
"%s.slibtool.deps",
|
|
|
b08054 |
libfilename) < 0)
|
|
|
b08054 |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
b08054 |
|
|
|
b08054 |
/* mapinfo */
|
|
|
b08054 |
if (!(mapinfo = slbt_map_file(fdcwd,depfile,SLBT_MAP_INPUT)))
|
|
|
b08054 |
return (fexternal && (errno == ENOENT))
|
|
|
b08054 |
? 0 : SLBT_SYSTEM_ERROR(dctx,depfile);
|
|
|
b08054 |
|
|
|
b08054 |
/* copied length */
|
|
|
b08054 |
depsmeta->infolen += mapinfo->size;
|
|
|
b08054 |
depsmeta->infolen++;
|
|
|
b08054 |
|
|
|
b08054 |
/* libexlen */
|
|
|
b08054 |
libexlen = (base = strrchr(libfilename,'/'))
|
|
|
b08054 |
? strlen(depfile) + 2 + (base - libfilename)
|
|
|
b08054 |
: strlen(depfile) + 2;
|
|
|
b08054 |
|
|
|
b08054 |
/* iterate */
|
|
|
b08054 |
ch = mapinfo->addr;
|
|
|
b08054 |
cap = mapinfo->cap;
|
|
|
b08054 |
|
|
|
b08054 |
for (; ch
|
|
|
b08054 |
if (*ch++ == '\n') {
|
|
|
b08054 |
depsmeta->infolen += libexlen;
|
|
|
b08054 |
depsmeta->depscnt++;
|
|
|
b08054 |
}
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
b08054 |
slbt_unmap_file(mapinfo);
|
|
|
b08054 |
|
|
|
b08054 |
return 0;
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
b08054 |
|
|
|
43ee04 |
static int slbt_exec_link_normalize_dep_file(
|
|
|
43ee04 |
const struct slbt_driver_ctx * dctx,
|
|
|
43ee04 |
int deps,
|
|
|
43ee04 |
char (*depfile)[PATH_MAX])
|
|
|
43ee04 |
{
|
|
|
43ee04 |
int ret;
|
|
|
43ee04 |
int fdcwd;
|
|
|
43ee04 |
int fdtgt;
|
|
|
43ee04 |
char * dot;
|
|
|
43ee04 |
char * slash;
|
|
|
198205 |
const char * base;
|
|
|
43ee04 |
const char * mark;
|
|
|
43ee04 |
struct slbt_txtfile_ctx * tctx;
|
|
|
43ee04 |
const char ** pline;
|
|
|
43ee04 |
char * tgtmark;
|
|
|
43ee04 |
char * depmark;
|
|
|
43ee04 |
char * relmark;
|
|
|
43ee04 |
char * tgtnext;
|
|
|
43ee04 |
char * depnext;
|
|
|
43ee04 |
char tgtdir [PATH_MAX];
|
|
|
43ee04 |
char tgtpath [PATH_MAX];
|
|
|
43ee04 |
char deppath [PATH_MAX];
|
|
|
43ee04 |
char pathbuf [PATH_MAX];
|
|
|
43ee04 |
char depsbuf [PATH_MAX];
|
|
|
198205 |
char basebuf [PATH_MAX];
|
|
|
43ee04 |
char relapath[PATH_MAX];
|
|
|
43ee04 |
|
|
|
43ee04 |
/* fdcwd */
|
|
|
43ee04 |
fdcwd = slbt_driver_fdcwd(dctx);
|
|
|
43ee04 |
|
|
|
43ee04 |
/* first-pass dependency file */
|
|
|
43ee04 |
if (slbt_impl_get_txtfile_ctx(dctx,*depfile,deps,&tctx) < 0)
|
|
|
43ee04 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
43ee04 |
|
|
|
43ee04 |
/* second-pass dependency file */
|
|
|
43ee04 |
dot = strrchr(*depfile,'.');
|
|
|
43ee04 |
strcpy(dot,".tmp2");
|
|
|
43ee04 |
|
|
|
43ee04 |
if ((deps = openat(fdcwd,*depfile,O_RDWR|O_CREAT|O_TRUNC,0644)) < 0) {
|
|
|
43ee04 |
slbt_lib_free_txtfile_ctx(tctx);
|
|
|
43ee04 |
return SLBT_SYSTEM_ERROR(dctx,depfile);
|
|
|
43ee04 |
}
|
|
|
43ee04 |
|
|
|
43ee04 |
/* fdtgt */
|
|
|
43ee04 |
strcpy(tgtdir,*depfile);
|
|
|
43ee04 |
|
|
|
43ee04 |
if (!(slash = strrchr(tgtdir,'/')))
|
|
|
43ee04 |
slash = tgtdir;
|
|
|
43ee04 |
|
|
|
43ee04 |
slash[0] = '\0';
|
|
|
43ee04 |
|
|
|
43ee04 |
if ((slash = strrchr(tgtdir,'/'))) {
|
|
|
43ee04 |
slash[0] = '\0';
|
|
|
43ee04 |
slash++;
|
|
|
43ee04 |
} else {
|
|
|
43ee04 |
slash = tgtdir;
|
|
|
43ee04 |
slash[0] = '.';
|
|
|
43ee04 |
slash[1] = '/';
|
|
|
43ee04 |
slash[2] = '\0';
|
|
|
43ee04 |
}
|
|
|
43ee04 |
|
|
|
43ee04 |
if ((slash > tgtdir) && strcmp(slash,".libs")) {
|
|
|
43ee04 |
close(deps);
|
|
|
43ee04 |
slbt_lib_free_txtfile_ctx(tctx);
|
|
|
43ee04 |
|
|
|
43ee04 |
return SLBT_CUSTOM_ERROR(
|
|
|
43ee04 |
dctx,
|
|
|
43ee04 |
SLBT_ERR_FLOW_ERROR);
|
|
|
43ee04 |
}
|
|
|
43ee04 |
|
|
|
43ee04 |
if ((fdtgt = openat(fdcwd,tgtdir,O_DIRECTORY|O_CLOEXEC,0)) < 0) {
|
|
|
43ee04 |
close(deps);
|
|
|
43ee04 |
slbt_lib_free_txtfile_ctx(tctx);
|
|
|
43ee04 |
|
|
|
43ee04 |
return SLBT_CUSTOM_ERROR(
|
|
|
43ee04 |
dctx,
|
|
|
43ee04 |
SLBT_ERR_FLOW_ERROR);
|
|
|
43ee04 |
}
|
|
|
43ee04 |
|
|
|
43ee04 |
if (slbt_realpath(fdcwd,tgtdir,0,tgtpath,sizeof(tgtpath)) < 0) {
|
|
|
43ee04 |
close(fdtgt);
|
|
|
43ee04 |
close(deps);
|
|
|
43ee04 |
slbt_lib_free_txtfile_ctx(tctx);
|
|
|
43ee04 |
|
|
|
43ee04 |
return SLBT_CUSTOM_ERROR(
|
|
|
43ee04 |
dctx,
|
|
|
43ee04 |
SLBT_ERR_FLOW_ERROR);
|
|
|
43ee04 |
}
|
|
|
43ee04 |
|
|
|
43ee04 |
strcpy(pathbuf,tgtpath);
|
|
|
43ee04 |
|
|
|
43ee04 |
/* normalize dependency lines as needed */
|
|
|
43ee04 |
for (pline=tctx->txtlinev; *pline; pline++) {
|
|
|
43ee04 |
if ((mark = *pline)) {
|
|
|
198205 |
if ((mark[0] == '-') && (mark[1] == 'L')) {
|
|
|
43ee04 |
mark = &mark[2];
|
|
|
198205 |
base = 0;
|
|
|
198205 |
|
|
|
198205 |
} else if ((mark[0] == ':') && (mark[1] == ':')) {
|
|
|
198205 |
mark = &mark[2];
|
|
|
198205 |
base = mark;
|
|
|
198205 |
}
|
|
|
43ee04 |
|
|
|
43ee04 |
if ((mark > *pline) && (mark[0] == '/'))
|
|
|
43ee04 |
mark = *pline;
|
|
|
43ee04 |
}
|
|
|
43ee04 |
|
|
|
43ee04 |
if (mark > *pline) {
|
|
|
43ee04 |
if (slbt_realpath(
|
|
|
43ee04 |
fdtgt,mark,0,deppath,
|
|
|
43ee04 |
sizeof(deppath)) < 0)
|
|
|
43ee04 |
mark = *pline;
|
|
|
43ee04 |
|
|
|
43ee04 |
else if ((tgtpath[0] != '/') || (deppath[0] != '/'))
|
|
|
43ee04 |
mark = 0;
|
|
|
43ee04 |
|
|
|
43ee04 |
else
|
|
|
43ee04 |
strcpy(depsbuf,deppath);
|
|
|
198205 |
|
|
|
198205 |
if ((mark > *pline) && base) {
|
|
|
198205 |
slash = strrchr(deppath,'/');
|
|
|
198205 |
*slash = '\0';
|
|
|
198205 |
|
|
|
198205 |
slash = strrchr(deppath,'/');
|
|
|
198205 |
*slash = '\0';
|
|
|
198205 |
|
|
|
198205 |
base = basebuf;
|
|
|
198205 |
slash = &depsbuf[slash - deppath];
|
|
|
198205 |
|
|
|
198205 |
strcpy(basebuf,++slash);
|
|
|
198205 |
strcpy(depsbuf,deppath);
|
|
|
198205 |
}
|
|
|
43ee04 |
}
|
|
|
43ee04 |
|
|
|
198205 |
if (mark > *pline) {
|
|
|
43ee04 |
tgtmark = tgtpath;
|
|
|
43ee04 |
depmark = deppath;
|
|
|
43ee04 |
|
|
|
43ee04 |
tgtnext = strchr(tgtmark,'/');
|
|
|
43ee04 |
depnext = strchr(depmark,'/');
|
|
|
43ee04 |
|
|
|
43ee04 |
while (tgtnext && depnext) {
|
|
|
43ee04 |
*tgtnext = '\0';
|
|
|
43ee04 |
*depnext = '\0';
|
|
|
43ee04 |
|
|
|
43ee04 |
if (strcmp(tgtmark,depmark)) {
|
|
|
43ee04 |
tgtnext = 0;
|
|
|
43ee04 |
depnext = 0;
|
|
|
43ee04 |
} else {
|
|
|
43ee04 |
tgtmark = &tgtnext[1];
|
|
|
43ee04 |
depmark = &depnext[1];
|
|
|
43ee04 |
|
|
|
43ee04 |
if (*tgtmark && *depmark) {
|
|
|
43ee04 |
tgtnext = strchr(tgtmark,'/');
|
|
|
43ee04 |
depnext = strchr(depmark,'/');
|
|
|
43ee04 |
} else {
|
|
|
43ee04 |
tgtnext = 0;
|
|
|
43ee04 |
depnext = 0;
|
|
|
43ee04 |
}
|
|
|
43ee04 |
}
|
|
|
43ee04 |
}
|
|
|
43ee04 |
|
|
|
43ee04 |
strcpy(tgtmark,&pathbuf[tgtmark-tgtpath]);
|
|
|
43ee04 |
strcpy(depmark,&depsbuf[depmark-deppath]);
|
|
|
43ee04 |
|
|
|
43ee04 |
if ((tgtmark - tgtpath) == (depmark - deppath)) {
|
|
|
43ee04 |
mark = &depmark[strlen(tgtmark)];
|
|
|
43ee04 |
|
|
|
43ee04 |
if ((mark[0] == '/') && !strncmp(tgtmark,depmark,mark-depmark))
|
|
|
43ee04 |
sprintf(relapath,"-L.%s",mark);
|
|
|
43ee04 |
else
|
|
|
43ee04 |
mark = relapath;
|
|
|
43ee04 |
} else {
|
|
|
43ee04 |
mark = relapath;
|
|
|
43ee04 |
}
|
|
|
43ee04 |
|
|
|
43ee04 |
if (mark == relapath) {
|
|
|
43ee04 |
relmark = relapath;
|
|
|
43ee04 |
relmark += sprintf(relapath,"-L../");
|
|
|
43ee04 |
|
|
|
43ee04 |
while ((tgtnext = strchr(tgtmark,'/'))) {
|
|
|
43ee04 |
tgtmark = &tgtnext[1];
|
|
|
43ee04 |
relmark += sprintf(relmark,"../");
|
|
|
43ee04 |
}
|
|
|
43ee04 |
|
|
|
43ee04 |
strcpy(relmark,depmark);
|
|
|
43ee04 |
}
|
|
|
43ee04 |
|
|
|
198205 |
if (base) {
|
|
|
198205 |
relapath[0] = ':';
|
|
|
198205 |
relapath[1] = ':';
|
|
|
198205 |
}
|
|
|
43ee04 |
|
|
|
43ee04 |
mark = relapath;
|
|
|
43ee04 |
}
|
|
|
43ee04 |
|
|
|
198205 |
if ((mark == relapath) && base) {
|
|
|
198205 |
ret = slbt_dprintf(deps,"%s/%s\n",mark,base);
|
|
|
198205 |
|
|
|
198205 |
} else if (mark) {
|
|
|
198205 |
ret = slbt_dprintf(deps,"%s\n",mark);
|
|
|
198205 |
|
|
|
198205 |
} else {
|
|
|
198205 |
ret = (-1);
|
|
|
198205 |
}
|
|
|
43ee04 |
|
|
|
43ee04 |
if (ret < 0) {
|
|
|
43ee04 |
close(deps);
|
|
|
43ee04 |
close(fdtgt);
|
|
|
43ee04 |
slbt_lib_free_txtfile_ctx(tctx);
|
|
|
43ee04 |
|
|
|
43ee04 |
return mark
|
|
|
43ee04 |
? SLBT_SYSTEM_ERROR(dctx,0)
|
|
|
43ee04 |
: SLBT_NESTED_ERROR(dctx);
|
|
|
43ee04 |
}
|
|
|
43ee04 |
|
|
|
43ee04 |
if (mark == relapath)
|
|
|
43ee04 |
strcpy(tgtpath,pathbuf);
|
|
|
43ee04 |
}
|
|
|
43ee04 |
|
|
|
43ee04 |
close(fdtgt);
|
|
|
43ee04 |
slbt_lib_free_txtfile_ctx(tctx);
|
|
|
43ee04 |
|
|
|
43ee04 |
return deps;
|
|
|
43ee04 |
}
|
|
|
43ee04 |
|
|
|
43ee04 |
|
|
|
43ee04 |
static int slbt_exec_link_compact_dep_file(
|
|
|
43ee04 |
const struct slbt_driver_ctx * dctx,
|
|
|
43ee04 |
int deps,
|
|
|
43ee04 |
char (*depfile)[PATH_MAX])
|
|
|
43ee04 |
{
|
|
|
43ee04 |
int fdcwd;
|
|
|
43ee04 |
struct slbt_txtfile_ctx * tctx;
|
|
|
43ee04 |
const char ** pline;
|
|
|
43ee04 |
const char ** pcomp;
|
|
|
43ee04 |
const char * depline;
|
|
|
43ee04 |
char * dot;
|
|
|
43ee04 |
|
|
|
43ee04 |
/* fdcwd */
|
|
|
43ee04 |
fdcwd = slbt_driver_fdcwd(dctx);
|
|
|
43ee04 |
|
|
|
43ee04 |
/* second-pass dependency file */
|
|
|
43ee04 |
if (slbt_impl_get_txtfile_ctx(dctx,*depfile,deps,&tctx) < 0)
|
|
|
43ee04 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
43ee04 |
|
|
|
43ee04 |
/* second-pass dependency file */
|
|
|
43ee04 |
dot = strrchr(*depfile,'.');
|
|
|
43ee04 |
dot[0] = '\0';
|
|
|
43ee04 |
|
|
|
43ee04 |
if ((deps = openat(fdcwd,*depfile,O_RDWR|O_CREAT|O_TRUNC,0644)) < 0) {
|
|
|
43ee04 |
slbt_lib_free_txtfile_ctx(tctx);
|
|
|
43ee04 |
return SLBT_SYSTEM_ERROR(dctx,depfile);
|
|
|
43ee04 |
}
|
|
|
43ee04 |
|
|
|
43ee04 |
/* iterate, only write unique entries */
|
|
|
43ee04 |
for (pline=tctx->txtlinev; *pline; pline++) {
|
|
|
43ee04 |
depline = *pline;
|
|
|
43ee04 |
|
|
|
43ee04 |
if ((depline[0] == '-') && (depline[1] == 'L'))
|
|
|
43ee04 |
for (pcomp=tctx->txtlinev; depline && pcomp
|
|
|
43ee04 |
if (!strcmp(*pcomp,depline))
|
|
|
43ee04 |
depline = 0;
|
|
|
43ee04 |
|
|
|
43ee04 |
if (depline && (slbt_dprintf(deps,"%s\n",depline) < 0)) {
|
|
|
43ee04 |
close(deps);
|
|
|
43ee04 |
slbt_lib_free_txtfile_ctx(tctx);
|
|
|
43ee04 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
43ee04 |
}
|
|
|
43ee04 |
}
|
|
|
43ee04 |
|
|
|
43ee04 |
slbt_lib_free_txtfile_ctx(tctx);
|
|
|
43ee04 |
|
|
|
43ee04 |
return deps;
|
|
|
43ee04 |
}
|
|
|
43ee04 |
|
|
|
43ee04 |
|
|
|
198205 |
static bool slbt_archive_is_convenience_library(int fdcwd, const char * arpath)
|
|
|
198205 |
{
|
|
|
198205 |
int fd;
|
|
|
198205 |
char laipath[PATH_MAX];
|
|
|
198205 |
char * dot;
|
|
|
198205 |
|
|
|
198205 |
strcpy(laipath,arpath);
|
|
|
198205 |
dot = strrchr(laipath,'.');
|
|
|
198205 |
strcpy(dot,".lai");
|
|
|
198205 |
|
|
|
198205 |
if ((fd = openat(fdcwd,laipath,O_RDONLY,0)) >= 0) {
|
|
|
198205 |
close(fd);
|
|
|
198205 |
return false;
|
|
|
198205 |
}
|
|
|
198205 |
|
|
|
198205 |
return true;
|
|
|
198205 |
}
|
|
|
198205 |
|
|
|
198205 |
|
|
|
4b56de |
slbt_hidden int slbt_exec_link_create_dep_file(
|
|
|
b08054 |
const struct slbt_driver_ctx * dctx,
|
|
|
b08054 |
struct slbt_exec_ctx * ectx,
|
|
|
b08054 |
char ** altv,
|
|
|
b08054 |
const char * libfilename,
|
|
|
b08054 |
bool farchive)
|
|
|
b08054 |
{
|
|
|
b08054 |
int ret;
|
|
|
b08054 |
int deps;
|
|
|
43ee04 |
int fdtmp;
|
|
|
b08054 |
int slen;
|
|
|
b08054 |
int fdcwd;
|
|
|
b08054 |
char ** parg;
|
|
|
b08054 |
char * popt;
|
|
|
b08054 |
char * plib;
|
|
|
b08054 |
char * path;
|
|
|
b08054 |
char * mark;
|
|
|
b08054 |
char * base;
|
|
|
b08054 |
size_t size;
|
|
|
6ccc20 |
bool fdep;
|
|
|
b08054 |
char deplib [PATH_MAX];
|
|
|
62a007 |
char deppref[PATH_MAX];
|
|
|
b08054 |
char reladir[PATH_MAX];
|
|
|
b08054 |
char depfile[PATH_MAX];
|
|
|
43ee04 |
char pathbuf[PATH_MAX];
|
|
|
b08054 |
struct stat st;
|
|
|
b08054 |
int ldepth;
|
|
|
198205 |
int fardep;
|
|
|
b08054 |
int fdyndep;
|
|
|
b08054 |
struct slbt_map_info * mapinfo;
|
|
|
62a007 |
bool is_reladir;
|
|
|
b08054 |
|
|
|
b08054 |
/* fdcwd */
|
|
|
b08054 |
fdcwd = slbt_driver_fdcwd(dctx);
|
|
|
b08054 |
|
|
|
b08054 |
/* depfile */
|
|
|
b08054 |
if (slbt_snprintf(depfile,sizeof(depfile),
|
|
|
43ee04 |
"%s.slibtool.deps.tmp1",
|
|
|
b08054 |
libfilename) < 0)
|
|
|
b08054 |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
b08054 |
|
|
|
43ee04 |
strcpy(pathbuf,depfile);
|
|
|
43ee04 |
|
|
|
62a007 |
/* dependency prefix */
|
|
|
62a007 |
if (depfile[0] == '/') {
|
|
|
62a007 |
deppref[0] = '\0';
|
|
|
62a007 |
} else {
|
|
|
62a007 |
if ((mark = strrchr(depfile,'/')))
|
|
|
62a007 |
*mark = 0;
|
|
|
62a007 |
|
|
|
62a007 |
if (!mark)
|
|
|
62a007 |
mark = depfile;
|
|
|
62a007 |
|
|
|
62a007 |
if (slbt_realpath(fdcwd,depfile,0,reladir,sizeof(reladir)) < 0)
|
|
|
62a007 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
62a007 |
|
|
|
62a007 |
if (slbt_realpath(fdcwd,"./",0,deppref,sizeof(deppref)) < 0)
|
|
|
62a007 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
62a007 |
|
|
|
62a007 |
if (mark > depfile)
|
|
|
62a007 |
*mark = '/';
|
|
|
62a007 |
|
|
|
62a007 |
mark = &reladir[strlen(deppref)];
|
|
|
62a007 |
*mark++ = '\0';
|
|
|
62a007 |
|
|
|
62a007 |
if (strcmp(reladir,deppref))
|
|
|
62a007 |
return SLBT_CUSTOM_ERROR(
|
|
|
62a007 |
dctx,
|
|
|
62a007 |
SLBT_ERR_FLOW_ERROR);
|
|
|
62a007 |
|
|
|
62a007 |
if ((base = strrchr(mark,'/')))
|
|
|
62a007 |
base++;
|
|
|
62a007 |
|
|
|
62a007 |
if (!base)
|
|
|
62a007 |
base = mark;
|
|
|
62a007 |
|
|
|
62a007 |
if (strcmp(base,".libs"))
|
|
|
62a007 |
return SLBT_CUSTOM_ERROR(
|
|
|
62a007 |
dctx,
|
|
|
62a007 |
SLBT_ERR_FLOW_ERROR);
|
|
|
62a007 |
|
|
|
62a007 |
base = mark;
|
|
|
62a007 |
mark = deppref;
|
|
|
62a007 |
|
|
|
62a007 |
for (; base; ) {
|
|
|
62a007 |
if ((base = strchr(base,'/'))) {
|
|
|
62a007 |
mark += sprintf(mark,"../");
|
|
|
62a007 |
base++;
|
|
|
62a007 |
}
|
|
|
62a007 |
}
|
|
|
97cd9f |
|
|
|
97cd9f |
*mark = '\0';
|
|
|
62a007 |
}
|
|
|
62a007 |
|
|
|
b08054 |
/* deps */
|
|
|
b08054 |
if ((deps = openat(fdcwd,depfile,O_RDWR|O_CREAT|O_TRUNC,0644)) < 0)
|
|
|
b08054 |
return SLBT_SYSTEM_ERROR(dctx,depfile);
|
|
|
b08054 |
|
|
|
6ccc20 |
/* informational header */
|
|
|
6ccc20 |
if (slbt_realpath(fdcwd,"./",0,reladir,sizeof(reladir)) < 0)
|
|
|
6ccc20 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
6ccc20 |
|
|
|
6ccc20 |
if (slbt_dprintf(deps,
|
|
|
6ccc20 |
"# makefile target: %s\n"
|
|
|
6ccc20 |
"# slibtool target: %s\n"
|
|
|
6ccc20 |
"# cprocess fdcwd: %s\n",
|
|
|
6ccc20 |
dctx->cctx->output,
|
|
|
6ccc20 |
libfilename,
|
|
|
6ccc20 |
reladir) < 0)
|
|
|
6ccc20 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
6ccc20 |
|
|
|
6ccc20 |
fdep = 0;
|
|
|
6ccc20 |
|
|
|
b08054 |
/* iterate */
|
|
|
b08054 |
for (parg=altv; *parg; parg++) {
|
|
|
b08054 |
popt = 0;
|
|
|
b08054 |
plib = 0;
|
|
|
b08054 |
path = 0;
|
|
|
b08054 |
mapinfo = 0;
|
|
|
b08054 |
|
|
|
b08054 |
if (!strncmp(*parg,"-l",2)) {
|
|
|
6ccc20 |
if (fdep) {
|
|
|
6ccc20 |
if (slbt_dprintf(
|
|
|
6ccc20 |
deps,
|
|
|
6ccc20 |
"#\n# makefile target: %s\n",
|
|
|
6ccc20 |
dctx->cctx->output) < 0)
|
|
|
6ccc20 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
6ccc20 |
|
|
|
6ccc20 |
fdep = false;
|
|
|
6ccc20 |
}
|
|
|
6ccc20 |
|
|
|
b08054 |
popt = *parg;
|
|
|
b08054 |
plib = popt + 2;
|
|
|
b08054 |
|
|
|
b08054 |
} else if (!strncmp(*parg,"-L",2)) {
|
|
|
6ccc20 |
if (fdep) {
|
|
|
6ccc20 |
if (slbt_dprintf(
|
|
|
6ccc20 |
deps,
|
|
|
6ccc20 |
"#\n# makefile target: %s\n",
|
|
|
6ccc20 |
dctx->cctx->output) < 0)
|
|
|
6ccc20 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
6ccc20 |
|
|
|
6ccc20 |
fdep = false;
|
|
|
6ccc20 |
}
|
|
|
6ccc20 |
|
|
|
b08054 |
popt = *parg;
|
|
|
b08054 |
path = popt + 2;
|
|
|
b08054 |
|
|
|
b08054 |
} else if (!strncmp(*parg,"-f",2)) {
|
|
|
b08054 |
(void)0;
|
|
|
b08054 |
|
|
|
b08054 |
} else if ((popt = strrchr(*parg,'.')) && !strcmp(popt,".la")) {
|
|
|
b08054 |
/* import dependency list */
|
|
|
6ccc20 |
fdep = true;
|
|
|
6ccc20 |
|
|
|
b08054 |
if ((base = strrchr(*parg,'/')))
|
|
|
b08054 |
base++;
|
|
|
b08054 |
else
|
|
|
b08054 |
base = *parg;
|
|
|
b08054 |
|
|
|
b08054 |
/* [relative .la directory] */
|
|
|
b08054 |
if (base > *parg) {
|
|
|
b08054 |
slen = slbt_snprintf(
|
|
|
b08054 |
reladir,
|
|
|
b08054 |
sizeof(reladir),
|
|
|
b08054 |
"%s",*parg);
|
|
|
b08054 |
|
|
|
b08054 |
if (slen < 0) {
|
|
|
b08054 |
close(deps);
|
|
|
b08054 |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
b08054 |
is_reladir = true;
|
|
|
b08054 |
reladir[base - *parg - 1] = 0;
|
|
|
b08054 |
} else {
|
|
|
b08054 |
is_reladir = false;
|
|
|
b08054 |
reladir[0] = '.';
|
|
|
b08054 |
reladir[1] = 0;
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
b08054 |
|
|
|
b08054 |
/* dynamic library dependency? */
|
|
|
b08054 |
strcpy(depfile,*parg);
|
|
|
b08054 |
mark = depfile + (base - *parg);
|
|
|
b08054 |
size = sizeof(depfile) - (base - *parg);
|
|
|
b08054 |
slen = slbt_snprintf(mark,size,".libs/%s",base);
|
|
|
b08054 |
|
|
|
b08054 |
if (slen < 0) {
|
|
|
b08054 |
close(deps);
|
|
|
b08054 |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
b08054 |
mark = strrchr(mark,'.');
|
|
|
b08054 |
strcpy(mark,dctx->cctx->settings.dsosuffix);
|
|
|
b08054 |
|
|
|
198205 |
fardep = 0;
|
|
|
b08054 |
fdyndep = !fstatat(fdcwd,depfile,&st,0);
|
|
|
b08054 |
|
|
|
198205 |
if (fdyndep && farchive) {
|
|
|
198205 |
mark = strrchr(mark,'.');
|
|
|
198205 |
strcpy(mark,dctx->cctx->settings.arsuffix);
|
|
|
198205 |
|
|
|
198205 |
if (fstatat(fdcwd,depfile,&st,0) < 0) {
|
|
|
198205 |
strcpy(mark,dctx->cctx->settings.dsosuffix);
|
|
|
198205 |
} else {
|
|
|
198205 |
fdyndep = 0;
|
|
|
198205 |
}
|
|
|
198205 |
}
|
|
|
198205 |
|
|
|
b08054 |
/* [-L... as needed] */
|
|
|
b08054 |
if (fdyndep && (ectx->ldirdepth >= 0)) {
|
|
|
b08054 |
if (slbt_dprintf(deps,"-L") < 0) {
|
|
|
b08054 |
close(deps);
|
|
|
b08054 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
b08054 |
for (ldepth=ectx->ldirdepth; ldepth; ldepth--) {
|
|
|
b08054 |
if (slbt_dprintf(deps,"../") < 0) {
|
|
|
b08054 |
close(deps);
|
|
|
b08054 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
b08054 |
}
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
b08054 |
if (slbt_dprintf(deps,"%s%s.libs\n",
|
|
|
b08054 |
(is_reladir ? reladir : ""),
|
|
|
b08054 |
(is_reladir ? "/" : "")) < 0) {
|
|
|
b08054 |
close(deps);
|
|
|
b08054 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
b08054 |
}
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
b08054 |
/* -ldeplib */
|
|
|
b08054 |
if (fdyndep) {
|
|
|
b08054 |
*popt = 0;
|
|
|
b08054 |
mark = base;
|
|
|
b08054 |
mark += strlen(dctx->cctx->settings.dsoprefix);
|
|
|
b08054 |
|
|
|
b08054 |
if (slbt_dprintf(deps,"-l%s\n",mark) < 0) {
|
|
|
b08054 |
close(deps);
|
|
|
b08054 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
b08054 |
*popt = '.';
|
|
|
198205 |
} else {
|
|
|
198205 |
strcpy(depfile,*parg);
|
|
|
198205 |
|
|
|
198205 |
slbt_adjust_wrapper_argument(
|
|
|
198205 |
depfile,true,
|
|
|
198205 |
dctx->cctx->settings.arsuffix);
|
|
|
198205 |
|
|
|
198205 |
|
|
|
198205 |
fardep = farchive;
|
|
|
198205 |
fardep |= !slbt_archive_is_convenience_library(fdcwd,depfile);
|
|
|
198205 |
}
|
|
|
198205 |
|
|
|
198205 |
if (fardep) {
|
|
|
198205 |
if (slbt_dprintf(deps,"::") < 0) {
|
|
|
198205 |
close(deps);
|
|
|
198205 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
198205 |
}
|
|
|
198205 |
|
|
|
198205 |
for (ldepth=ectx->ldirdepth; ldepth; ldepth--) {
|
|
|
198205 |
if (slbt_dprintf(deps,"../") < 0) {
|
|
|
198205 |
close(deps);
|
|
|
198205 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
198205 |
}
|
|
|
198205 |
}
|
|
|
198205 |
|
|
|
198205 |
|
|
|
198205 |
if (ectx->ldirdepth >= 0) {
|
|
|
198205 |
if (slbt_dprintf(deps,"%s\n",depfile) < 0) {
|
|
|
198205 |
close(deps);
|
|
|
198205 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
198205 |
}
|
|
|
198205 |
} else {
|
|
|
198205 |
if (slbt_dprintf(deps,"::./%s\n",depfile) < 0) {
|
|
|
198205 |
close(deps);
|
|
|
198205 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
198205 |
}
|
|
|
198205 |
}
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
b08054 |
/* [open dependency list] */
|
|
|
b08054 |
strcpy(depfile,*parg);
|
|
|
b08054 |
mark = depfile + (base - *parg);
|
|
|
b08054 |
size = sizeof(depfile) - (base - *parg);
|
|
|
b08054 |
slen = slbt_snprintf(mark,size,".libs/%s",base);
|
|
|
b08054 |
|
|
|
b08054 |
if (slen < 0) {
|
|
|
b08054 |
close(deps);
|
|
|
b08054 |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
b08054 |
mapinfo = 0;
|
|
|
b08054 |
|
|
|
b08054 |
mark = strrchr(mark,'.');
|
|
|
b08054 |
size = sizeof(depfile) - (mark - depfile);
|
|
|
b08054 |
|
|
|
198205 |
if (!fardep) {
|
|
|
b08054 |
slen = slbt_snprintf(mark,size,
|
|
|
b08054 |
"%s.slibtool.deps",
|
|
|
b08054 |
dctx->cctx->settings.dsosuffix);
|
|
|
b08054 |
|
|
|
b08054 |
if (slen < 0) {
|
|
|
b08054 |
close(deps);
|
|
|
b08054 |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
b08054 |
mapinfo = slbt_map_file(
|
|
|
b08054 |
fdcwd,depfile,
|
|
|
b08054 |
SLBT_MAP_INPUT);
|
|
|
b08054 |
|
|
|
b08054 |
if (!mapinfo && (errno != ENOENT)) {
|
|
|
b08054 |
close(deps);
|
|
|
b08054 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
b08054 |
}
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
b08054 |
if (!mapinfo) {
|
|
|
b08054 |
slen = slbt_snprintf(mark,size,
|
|
|
b08054 |
".a.slibtool.deps");
|
|
|
b08054 |
|
|
|
b08054 |
if (slen < 0) {
|
|
|
b08054 |
close(deps);
|
|
|
b08054 |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
b08054 |
mapinfo = slbt_map_file(
|
|
|
b08054 |
fdcwd,depfile,
|
|
|
b08054 |
SLBT_MAP_INPUT);
|
|
|
b08054 |
|
|
|
b08054 |
if (!mapinfo) {
|
|
|
b08054 |
strcpy(mark,".a.disabled");
|
|
|
b08054 |
|
|
|
b08054 |
if (fstatat(fdcwd,depfile,&st,AT_SYMLINK_NOFOLLOW)) {
|
|
|
b08054 |
close(deps);
|
|
|
b08054 |
return SLBT_SYSTEM_ERROR(dctx,depfile);
|
|
|
b08054 |
}
|
|
|
b08054 |
}
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
b08054 |
/* [-l... as needed] */
|
|
|
b08054 |
while (mapinfo && (mapinfo->mark < mapinfo->cap)) {
|
|
|
b08054 |
ret = slbt_mapped_readline(
|
|
|
b08054 |
dctx,mapinfo,
|
|
|
b08054 |
deplib,sizeof(deplib));
|
|
|
b08054 |
|
|
|
b08054 |
if (ret) {
|
|
|
b08054 |
close(deps);
|
|
|
b08054 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
198205 |
if ((deplib[0] == '-') && (deplib[1] == 'L') && (deplib[2] != '/')) {
|
|
|
198205 |
ret = slbt_dprintf(
|
|
|
62a007 |
deps,"-L%s%s/%s",
|
|
|
198205 |
deppref,reladir,&deplib[2]);
|
|
|
198205 |
|
|
|
198205 |
} else if ((deplib[0] == ':') && (deplib[1] == ':') && (deplib[2] != '/')) {
|
|
|
198205 |
ret = slbt_dprintf(
|
|
|
198205 |
deps,"::%s%s/%s",
|
|
|
198205 |
deppref,reladir,&deplib[2]);
|
|
|
198205 |
|
|
|
198205 |
} else {
|
|
|
198205 |
ret = slbt_dprintf(
|
|
|
b08054 |
deps,"%s",
|
|
|
b08054 |
deplib);
|
|
|
198205 |
}
|
|
|
b08054 |
|
|
|
b08054 |
if (ret < 0) {
|
|
|
b08054 |
close(deps);
|
|
|
b08054 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
b08054 |
}
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
b08054 |
if (mapinfo)
|
|
|
b08054 |
slbt_unmap_file(mapinfo);
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
b08054 |
if (plib && (slbt_dprintf(deps,"-l%s\n",plib) < 0)) {
|
|
|
b08054 |
close(deps);
|
|
|
b08054 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
b08054 |
if (path && (slbt_dprintf(deps,"-L%s\n",path) < 0)) {
|
|
|
b08054 |
close(deps);
|
|
|
b08054 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
b08054 |
}
|
|
|
b08054 |
}
|
|
|
b08054 |
|
|
|
43ee04 |
if ((fdtmp = slbt_exec_link_normalize_dep_file(dctx,deps,&pathbuf)) < 0)
|
|
|
43ee04 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
43ee04 |
|
|
|
43ee04 |
close(deps);
|
|
|
43ee04 |
|
|
|
43ee04 |
if ((deps = slbt_exec_link_compact_dep_file(dctx,fdtmp,&pathbuf)) < 0)
|
|
|
43ee04 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
43ee04 |
|
|
|
43ee04 |
close(deps);
|
|
|
43ee04 |
close(fdtmp);
|
|
|
43ee04 |
|
|
|
b08054 |
return 0;
|
|
|
b08054 |
}
|