|
|
9ca8c4 |
/*******************************************************************/
|
|
|
9ca8c4 |
/* slibtool: a skinny libtool implementation, written in C */
|
|
|
9ca8c4 |
/* Copyright (C) 2016 Z. Gilboa */
|
|
|
9ca8c4 |
/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
|
|
|
9ca8c4 |
/*******************************************************************/
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
#include <stdint.h>
|
|
|
9ca8c4 |
#include <unistd.h>
|
|
|
9ca8c4 |
#include <fcntl.h>
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
#define ARGV_DRIVER
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
#include <slibtool/slibtool.h>
|
|
|
9f24d2 |
#include "slibtool_version.h"
|
|
|
9ca8c4 |
#include "slibtool_driver_impl.h"
|
|
|
9ca8c4 |
#include "argv/argv.h"
|
|
|
9ca8c4 |
|
|
|
9f24d2 |
/* package info */
|
|
|
9f24d2 |
static const struct slbt_source_version slbt_src_version = {
|
|
|
9f24d2 |
SLBT_TAG_VER_MAJOR,
|
|
|
9f24d2 |
SLBT_TAG_VER_MINOR,
|
|
|
9f24d2 |
SLBT_TAG_VER_PATCH,
|
|
|
9f24d2 |
SLIBTOOL_GIT_VERSION
|
|
|
9f24d2 |
};
|
|
|
5a9161 |
|
|
|
a66d34 |
/* flavor settings */
|
|
|
bcd5af |
#define SLBT_FLAVOR_SETTINGS(flavor,bfmt,arp,ars,dsop,dsos,exep,exes,impp,imps,ldenv) \
|
|
|
a66d34 |
static const struct slbt_flavor_settings flavor = { \
|
|
|
bcd5af |
bfmt,arp,ars,dsop,dsos,exep,exes,impp,imps,ldenv}
|
|
|
a66d34 |
|
|
|
bcd5af |
SLBT_FLAVOR_SETTINGS(host_flavor_default, "elf", "lib",".a", "lib",".so", "","", "", "", "LD_LIBRARY_PATH");
|
|
|
bcd5af |
SLBT_FLAVOR_SETTINGS(host_flavor_midipix, "pe", "lib",".a", "lib",".so", "","", "lib",".lib.a", "PATH");
|
|
|
bcd5af |
SLBT_FLAVOR_SETTINGS(host_flavor_mingw, "pe", "lib",".a", "lib",".dll", "",".exe", "lib",".dll.a", "PATH");
|
|
|
bcd5af |
SLBT_FLAVOR_SETTINGS(host_flavor_cygwin, "pe", "lib",".a", "lib",".dll", "",".exe", "lib",".dll.a", "PATH");
|
|
|
bcd5af |
SLBT_FLAVOR_SETTINGS(host_flavor_darwin, "macho","lib",".a", "lib",".dylib", "","", "", "", "DYLD_LIBRARY_PATH");
|
|
|
a66d34 |
|
|
|
a66d34 |
|
|
|
f10958 |
/* annotation strings */
|
|
|
46ea99 |
static const char cfgexplicit[] = "command-line argument";
|
|
|
46ea99 |
static const char cfghost[] = "derived from <host>";
|
|
|
46ea99 |
static const char cfgtarget[] = "derived from <target>";
|
|
|
46ea99 |
static const char cfgcompiler[] = "derived from <compiler>";
|
|
|
c7857f |
static const char cfgnmachine[] = "native (derived from -dumpmachine)";
|
|
|
c7857f |
static const char cfgxmachine[] = "foreign (derived from -dumpmachine)";
|
|
|
46ea99 |
static const char cfgnative[] = "native";
|
|
|
46ea99 |
|
|
|
af7db9 |
/* elf rpath */
|
|
|
af7db9 |
static const char*ldrpath_elf[] = {
|
|
|
af7db9 |
"/lib",
|
|
|
af7db9 |
"/lib/64",
|
|
|
af7db9 |
"/usr/lib",
|
|
|
af7db9 |
"/usr/lib64",
|
|
|
af7db9 |
"/usr/local/lib",
|
|
|
af7db9 |
"usr/local/lib64",
|
|
|
af7db9 |
0};
|
|
|
af7db9 |
|
|
|
56cab3 |
struct slbt_split_vector {
|
|
|
56cab3 |
char ** targv;
|
|
|
56cab3 |
char ** cargv;
|
|
|
56cab3 |
};
|
|
|
56cab3 |
|
|
|
9ca8c4 |
struct slbt_driver_ctx_alloc {
|
|
|
9ca8c4 |
struct argv_meta * meta;
|
|
|
9ca8c4 |
struct slbt_driver_ctx_impl ctx;
|
|
|
9ca8c4 |
uint64_t guard;
|
|
|
9ca8c4 |
const char * units[];
|
|
|
9ca8c4 |
};
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
static uint32_t slbt_argv_flags(uint32_t flags)
|
|
|
9ca8c4 |
{
|
|
|
9ca8c4 |
uint32_t ret = 0;
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
if (flags & SLBT_DRIVER_VERBOSITY_NONE)
|
|
|
9ca8c4 |
ret |= ARGV_VERBOSITY_NONE;
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
if (flags & SLBT_DRIVER_VERBOSITY_ERRORS)
|
|
|
9ca8c4 |
ret |= ARGV_VERBOSITY_ERRORS;
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
if (flags & SLBT_DRIVER_VERBOSITY_STATUS)
|
|
|
9ca8c4 |
ret |= ARGV_VERBOSITY_STATUS;
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
return ret;
|
|
|
9ca8c4 |
}
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
static int slbt_driver_usage(
|
|
|
9ca8c4 |
const char * program,
|
|
|
9ca8c4 |
const char * arg,
|
|
|
9ca8c4 |
const struct argv_option * options,
|
|
|
9ca8c4 |
struct argv_meta * meta)
|
|
|
9ca8c4 |
{
|
|
|
9ca8c4 |
char header[512];
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
snprintf(header,sizeof(header),
|
|
|
9ca8c4 |
"Usage: %s [options] <file>...\n" "Options:\n",
|
|
|
9ca8c4 |
program);
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
argv_usage(stdout,header,options,arg);
|
|
|
9ca8c4 |
argv_free(meta);
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
return SLBT_USAGE;
|
|
|
9ca8c4 |
}
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
static struct slbt_driver_ctx_impl * slbt_driver_ctx_alloc(
|
|
|
9ca8c4 |
struct argv_meta * meta,
|
|
|
9ca8c4 |
const struct slbt_common_ctx * cctx,
|
|
|
9ca8c4 |
size_t nunits)
|
|
|
9ca8c4 |
{
|
|
|
9ca8c4 |
struct slbt_driver_ctx_alloc * ictx;
|
|
|
9ca8c4 |
size_t size;
|
|
|
9ca8c4 |
struct argv_entry * entry;
|
|
|
9ca8c4 |
const char ** units;
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
size = sizeof(struct slbt_driver_ctx_alloc);
|
|
|
9ca8c4 |
size += (nunits+1)*sizeof(const char *);
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
if (!(ictx = calloc(1,size)))
|
|
|
9ca8c4 |
return 0;
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
if (cctx)
|
|
|
9ca8c4 |
memcpy(&ictx->ctx.cctx,cctx,sizeof(*cctx));
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
for (entry=meta->entries,units=ictx->units; entry->fopt || entry->arg; entry++)
|
|
|
9ca8c4 |
if (!entry->fopt)
|
|
|
9ca8c4 |
*units++ = entry->arg;
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
ictx->meta = meta;
|
|
|
9ca8c4 |
ictx->ctx.ctx.units = ictx->units;
|
|
|
9ca8c4 |
return &ictx->ctx;
|
|
|
9ca8c4 |
}
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
static int slbt_get_driver_ctx_fail(struct argv_meta * meta)
|
|
|
9ca8c4 |
{
|
|
|
9ca8c4 |
argv_free(meta);
|
|
|
9ca8c4 |
return -1;
|
|
|
9ca8c4 |
}
|
|
|
9ca8c4 |
|
|
|
56cab3 |
static int slbt_split_argv(
|
|
|
56cab3 |
char ** argv,
|
|
|
56cab3 |
uint32_t flags,
|
|
|
56cab3 |
struct slbt_split_vector * sargv)
|
|
|
56cab3 |
{
|
|
|
56cab3 |
int i;
|
|
|
56cab3 |
int argc;
|
|
|
56cab3 |
const char * program;
|
|
|
56cab3 |
char * compiler;
|
|
|
56cab3 |
char ** targv;
|
|
|
56cab3 |
char ** cargv;
|
|
|
56cab3 |
struct argv_meta * meta;
|
|
|
56cab3 |
struct argv_entry * entry;
|
|
|
56cab3 |
struct argv_entry * mode;
|
|
|
37ff4a |
struct argv_entry * config;
|
|
|
56cab3 |
const struct argv_option * option;
|
|
|
56cab3 |
const struct argv_option * options = slbt_default_options;
|
|
|
56cab3 |
struct argv_ctx ctx = {ARGV_VERBOSITY_NONE,
|
|
|
56cab3 |
ARGV_MODE_SCAN,
|
|
|
56cab3 |
0,0,0,0,0,0,0};
|
|
|
56cab3 |
|
|
|
56cab3 |
program = argv_program_name(argv[0]);
|
|
|
56cab3 |
|
|
|
56cab3 |
/* missing arguments? */
|
|
|
56cab3 |
if (!argv[1] && (flags & SLBT_DRIVER_VERBOSITY_USAGE))
|
|
|
56cab3 |
return slbt_driver_usage(program,0,options,0);
|
|
|
56cab3 |
|
|
|
56cab3 |
/* initial argv scan: ... --mode=xxx ... <compiler> ... */
|
|
|
56cab3 |
argv_scan(argv,options,&ctx,0);
|
|
|
56cab3 |
|
|
|
56cab3 |
/* invalid slibtool arguments? */
|
|
|
56cab3 |
if (ctx.erridx && !ctx.unitidx) {
|
|
|
56cab3 |
if (flags & SLBT_DRIVER_VERBOSITY_ERRORS)
|
|
|
56cab3 |
argv_get(
|
|
|
56cab3 |
argv,options,
|
|
|
56cab3 |
slbt_argv_flags(flags));
|
|
|
56cab3 |
return -1;
|
|
|
56cab3 |
}
|
|
|
56cab3 |
|
|
|
56cab3 |
/* missing compiler? */
|
|
|
56cab3 |
if (!ctx.unitidx) {
|
|
|
56cab3 |
if (flags & SLBT_DRIVER_VERBOSITY_ERRORS)
|
|
|
56cab3 |
fprintf(stderr,
|
|
|
56cab3 |
"%s: error: <compiler> is missing.\n",
|
|
|
56cab3 |
program);
|
|
|
56cab3 |
return -1;
|
|
|
56cab3 |
}
|
|
|
56cab3 |
|
|
|
56cab3 |
/* obtain slibtool's own arguments */
|
|
|
56cab3 |
compiler = argv[ctx.unitidx];
|
|
|
56cab3 |
argv[ctx.unitidx] = 0;
|
|
|
56cab3 |
|
|
|
56cab3 |
meta = argv_get(argv,options,ARGV_VERBOSITY_NONE);
|
|
|
56cab3 |
argv[ctx.unitidx] = compiler;
|
|
|
56cab3 |
|
|
|
37ff4a |
/* missing both --mode and --config? */
|
|
|
94d109 |
for (mode=0, config=0, entry=meta->entries; entry->fopt; entry++)
|
|
|
56cab3 |
if (entry->tag == TAG_MODE)
|
|
|
56cab3 |
mode = entry;
|
|
|
37ff4a |
else if (entry->tag == TAG_CONFIG)
|
|
|
37ff4a |
config = entry;
|
|
|
56cab3 |
|
|
|
56cab3 |
argv_free(meta);
|
|
|
56cab3 |
|
|
|
37ff4a |
if (!mode && !config) {
|
|
|
56cab3 |
fprintf(stderr,
|
|
|
56cab3 |
"%s: error: --mode must be specified.\n",
|
|
|
56cab3 |
program);
|
|
|
56cab3 |
return -1;
|
|
|
56cab3 |
}
|
|
|
56cab3 |
|
|
|
56cab3 |
/* allocate split vectors */
|
|
|
56cab3 |
for (argc=0, targv=argv; *targv; targv++)
|
|
|
56cab3 |
argc++;
|
|
|
56cab3 |
|
|
|
56cab3 |
if ((sargv->targv = calloc(2*(argc+1),sizeof(char *))))
|
|
|
56cab3 |
sargv->cargv = sargv->targv + argc + 1;
|
|
|
56cab3 |
else
|
|
|
56cab3 |
return -1;
|
|
|
56cab3 |
|
|
|
56cab3 |
/* split vectors: slibtool's own options */
|
|
|
56cab3 |
for (i=0; i
|
|
|
56cab3 |
sargv->targv[i] = argv[i];
|
|
|
56cab3 |
|
|
|
56cab3 |
/* split vectors: legacy mixture */
|
|
|
56cab3 |
options = option_from_tag(
|
|
|
56cab3 |
slbt_default_options,
|
|
|
56cab3 |
TAG_OUTPUT);
|
|
|
56cab3 |
|
|
|
56cab3 |
targv = sargv->targv + i;
|
|
|
56cab3 |
cargv = sargv->cargv;
|
|
|
56cab3 |
|
|
|
56cab3 |
for (; i
|
|
|
70c446 |
if (argv[i][0] != '-') {
|
|
|
70c446 |
if (argv[i+1] && (argv[i+1][0] == '+')
|
|
|
70c446 |
&& (argv[i+1][1] == '=')
|
|
|
70c446 |
&& (argv[i+1][2] == 0)
|
|
|
70c446 |
&& !(strrchr(argv[i],'.')))
|
|
|
70c446 |
/* libfoo_la_LDFLAGS += -Wl,.... */
|
|
|
70c446 |
i++;
|
|
|
70c446 |
else
|
|
|
70c446 |
*cargv++ = argv[i];
|
|
|
70c446 |
|
|
|
70c446 |
} else if (argv[i][1] == 'o') {
|
|
|
56cab3 |
*targv++ = argv[i];
|
|
|
56cab3 |
|
|
|
a87fd1 |
if (argv[i][2] == 0)
|
|
|
a288c4 |
*targv++ = argv[++i];
|
|
|
a288c4 |
}
|
|
|
a288c4 |
|
|
|
56cab3 |
else if ((argv[i][1] == 'W') && (argv[i][2] == 'c'))
|
|
|
56cab3 |
*cargv++ = argv[i];
|
|
|
56cab3 |
|
|
|
56cab3 |
else if (!(strcmp("Xcompiler",&argv[i][1])))
|
|
|
56cab3 |
*cargv++ = argv[++i];
|
|
|
56cab3 |
|
|
|
411564 |
else if (!(strncmp("-target=",&argv[i][1],strlen("-target="))))
|
|
|
666296 |
*targv++ = argv[i];
|
|
|
411564 |
|
|
|
411564 |
else if (!(strcmp("-target",&argv[i][1]))) {
|
|
|
411564 |
*targv++ = argv[i++];
|
|
|
666296 |
*targv++ = argv[i];
|
|
|
411564 |
|
|
|
a87fd1 |
} else if ((argv[i][1] == 'R') && (argv[i][2] == 0)) {
|
|
|
523027 |
*targv++ = argv[i++];
|
|
|
523027 |
*targv++ = argv[i];
|
|
|
523027 |
|
|
|
523027 |
} else if (argv[i][1] == 'R') {
|
|
|
523027 |
*targv++ = argv[i];
|
|
|
523027 |
|
|
|
63a1b4 |
} else if (!(strcmp("bindir",&argv[i][1]))) {
|
|
|
63a1b4 |
*targv++ = argv[i++];
|
|
|
63a1b4 |
*targv++ = argv[i];
|
|
|
63a1b4 |
|
|
|
bfa8ca |
} else if (!(strcmp("shrext",&argv[i][1]))) {
|
|
|
bfa8ca |
*targv++ = argv[i++];
|
|
|
bfa8ca |
*targv++ = argv[i];
|
|
|
bfa8ca |
|
|
|
9c664d |
} else if (!(strcmp("rpath",&argv[i][1]))) {
|
|
|
9c664d |
*targv++ = argv[i++];
|
|
|
666296 |
*targv++ = argv[i];
|
|
|
5a9161 |
|
|
|
9aa1f4 |
} else if (!(strcmp("release",&argv[i][1]))) {
|
|
|
9aa1f4 |
*targv++ = argv[i++];
|
|
|
9aa1f4 |
*targv++ = argv[i];
|
|
|
9aa1f4 |
|
|
|
873ecb |
} else if (!(strcmp("export-symbols",&argv[i][1]))) {
|
|
|
873ecb |
*targv++ = argv[i++];
|
|
|
873ecb |
*targv++ = argv[i];
|
|
|
873ecb |
|
|
|
73ca78 |
} else if (!(strcmp("export-symbols-regex",&argv[i][1]))) {
|
|
|
73ca78 |
*targv++ = argv[i++];
|
|
|
73ca78 |
*targv++ = argv[i];
|
|
|
73ca78 |
|
|
|
5a9161 |
} else if (!(strcmp("version-info",&argv[i][1]))) {
|
|
|
5a9161 |
*targv++ = argv[i++];
|
|
|
5a9161 |
*targv++ = argv[i];
|
|
|
5a9161 |
|
|
|
cd3d41 |
} else if (!(strcmp("version-number",&argv[i][1]))) {
|
|
|
cd3d41 |
*targv++ = argv[i++];
|
|
|
cd3d41 |
*targv++ = argv[i];
|
|
|
cd3d41 |
|
|
|
411564 |
} else {
|
|
|
56cab3 |
for (option=options; option->long_name; option++)
|
|
|
56cab3 |
if (!(strcmp(option->long_name,&argv[i][1])))
|
|
|
56cab3 |
break;
|
|
|
56cab3 |
|
|
|
56cab3 |
if (option->long_name)
|
|
|
56cab3 |
*targv++ = argv[i];
|
|
|
56cab3 |
else
|
|
|
56cab3 |
*cargv++ = argv[i];
|
|
|
56cab3 |
}
|
|
|
56cab3 |
}
|
|
|
56cab3 |
|
|
|
56cab3 |
return 0;
|
|
|
56cab3 |
}
|
|
|
56cab3 |
|
|
|
f0921b |
static int slbt_init_host_params(
|
|
|
46ea99 |
const struct slbt_common_ctx * cctx,
|
|
|
46ea99 |
struct slbt_host_strs * drvhost,
|
|
|
46ea99 |
struct slbt_host_params * host,
|
|
|
46ea99 |
struct slbt_host_params * cfgmeta)
|
|
|
46ea99 |
{
|
|
|
46ea99 |
size_t toollen;
|
|
|
a07c9b |
char * dash;
|
|
|
a21ac1 |
char * base;
|
|
|
46ea99 |
const char * machine;
|
|
|
46ea99 |
bool ftarget = false;
|
|
|
46ea99 |
bool fhost = false;
|
|
|
46ea99 |
bool fcompiler = false;
|
|
|
46ea99 |
bool fnative = false;
|
|
|
663ef2 |
bool fdumpmachine = false;
|
|
|
663ef2 |
char buf[256];
|
|
|
46ea99 |
|
|
|
a21ac1 |
/* base */
|
|
|
a21ac1 |
if ((base = strrchr(cctx->cargv[0],'/')))
|
|
|
a21ac1 |
base++;
|
|
|
a21ac1 |
else
|
|
|
a21ac1 |
base = cctx->cargv[0];
|
|
|
a21ac1 |
|
|
|
663ef2 |
if ((cctx->mode == SLBT_MODE_COMPILE) || (cctx->mode == SLBT_MODE_LINK))
|
|
|
663ef2 |
fdumpmachine = true;
|
|
|
663ef2 |
|
|
|
46ea99 |
/* host */
|
|
|
46ea99 |
if (host->host) {
|
|
|
46ea99 |
cfgmeta->host = cfgexplicit;
|
|
|
46ea99 |
fhost = true;
|
|
|
46ea99 |
} else if (cctx->target) {
|
|
|
46ea99 |
host->host = cctx->target;
|
|
|
46ea99 |
cfgmeta->host = cfgtarget;
|
|
|
46ea99 |
ftarget = true;
|
|
|
a21ac1 |
} else if (strrchr(base,'-')) {
|
|
|
46ea99 |
if (!(drvhost->host = strdup(cctx->cargv[0])))
|
|
|
46ea99 |
return -1;
|
|
|
46ea99 |
|
|
|
a07c9b |
dash = strrchr(drvhost->host,'-');
|
|
|
a07c9b |
*dash = 0;
|
|
|
46ea99 |
host->host = drvhost->host;
|
|
|
46ea99 |
cfgmeta->host = cfgcompiler;
|
|
|
46ea99 |
fcompiler = true;
|
|
|
663ef2 |
} else if (fdumpmachine && !(slbt_dump_machine(
|
|
|
663ef2 |
cctx->cargv[0],
|
|
|
663ef2 |
buf,sizeof(buf)))) {
|
|
|
663ef2 |
if (!(drvhost->host = strdup(buf)))
|
|
|
663ef2 |
return -1;
|
|
|
663ef2 |
|
|
|
663ef2 |
host->host = drvhost->host;
|
|
|
663ef2 |
fcompiler = true;
|
|
|
663ef2 |
fnative = (!(strcmp(host->host,SLBT_MACHINE)));
|
|
|
c7857f |
cfgmeta->host = fnative ? cfgnmachine : cfgxmachine;
|
|
|
46ea99 |
} else {
|
|
|
46ea99 |
host->host = SLBT_MACHINE;
|
|
|
c7857f |
cfgmeta->host = cfgnmachine;
|
|
|
46ea99 |
fnative = true;
|
|
|
46ea99 |
}
|
|
|
46ea99 |
|
|
|
46ea99 |
/* flavor */
|
|
|
46ea99 |
if (host->flavor) {
|
|
|
46ea99 |
cfgmeta->flavor = cfgexplicit;
|
|
|
46ea99 |
} else {
|
|
|
46ea99 |
if (fhost) {
|
|
|
46ea99 |
machine = host->host;
|
|
|
46ea99 |
cfgmeta->flavor = cfghost;
|
|
|
46ea99 |
} else if (ftarget) {
|
|
|
46ea99 |
machine = cctx->target;
|
|
|
46ea99 |
cfgmeta->flavor = cfgtarget;
|
|
|
46ea99 |
} else if (fcompiler) {
|
|
|
46ea99 |
machine = drvhost->host;
|
|
|
46ea99 |
cfgmeta->flavor = cfgcompiler;
|
|
|
46ea99 |
} else {
|
|
|
46ea99 |
machine = SLBT_MACHINE;
|
|
|
c7857f |
cfgmeta->flavor = cfgnmachine;
|
|
|
46ea99 |
}
|
|
|
46ea99 |
|
|
|
a07c9b |
dash = strrchr(machine,'-');
|
|
|
46ea99 |
cfgmeta->flavor = cfghost;
|
|
|
46ea99 |
|
|
|
a07c9b |
if ((dash && !strcmp(dash,"-bsd")) || strstr(machine,"-bsd-"))
|
|
|
46ea99 |
host->flavor = "bsd";
|
|
|
a07c9b |
else if ((dash && !strcmp(dash,"-cygwin")) || strstr(machine,"-cygwin-"))
|
|
|
46ea99 |
host->flavor = "cygwin";
|
|
|
9ff9ad |
else if ((dash && !strcmp(dash,"-darwin")) || strstr(machine,"-darwin"))
|
|
|
46ea99 |
host->flavor = "darwin";
|
|
|
a07c9b |
else if ((dash && !strcmp(dash,"-linux")) || strstr(machine,"-linux-"))
|
|
|
46ea99 |
host->flavor = "linux";
|
|
|
a07c9b |
else if ((dash && !strcmp(dash,"-midipix")) || strstr(machine,"-midipix-"))
|
|
|
46ea99 |
host->flavor = "midipix";
|
|
|
a07c9b |
else if ((dash && !strcmp(dash,"-mingw")) || strstr(machine,"-mingw-"))
|
|
|
46ea99 |
host->flavor = "mingw";
|
|
|
a07c9b |
else if ((dash && !strcmp(dash,"-mingw32")) || strstr(machine,"-mingw32-"))
|
|
|
46ea99 |
host->flavor = "mingw";
|
|
|
a07c9b |
else if ((dash && !strcmp(dash,"-mingw64")) || strstr(machine,"-mingw64-"))
|
|
|
46ea99 |
host->flavor = "mingw";
|
|
|
46ea99 |
else {
|
|
|
46ea99 |
host->flavor = "default";
|
|
|
46ea99 |
cfgmeta->flavor = "fallback, unverified";
|
|
|
46ea99 |
}
|
|
|
46ea99 |
}
|
|
|
46ea99 |
|
|
|
46ea99 |
/* toollen */
|
|
|
46ea99 |
toollen = fnative ? 0 : strlen(host->host);
|
|
|
46ea99 |
toollen += strlen("-utility-name");
|
|
|
46ea99 |
|
|
|
46ea99 |
/* ar */
|
|
|
46ea99 |
if (host->ar)
|
|
|
46ea99 |
cfgmeta->ar = cfgexplicit;
|
|
|
46ea99 |
else {
|
|
|
46ea99 |
if (!(drvhost->ar = calloc(1,toollen)))
|
|
|
46ea99 |
return -1;
|
|
|
46ea99 |
|
|
|
46ea99 |
if (fnative) {
|
|
|
46ea99 |
strcpy(drvhost->ar,"ar");
|
|
|
46ea99 |
cfgmeta->ar = cfgnative;
|
|
|
46ea99 |
} else {
|
|
|
46ea99 |
sprintf(drvhost->ar,"%s-ar",host->host);
|
|
|
46ea99 |
cfgmeta->ar = cfghost;
|
|
|
46ea99 |
}
|
|
|
46ea99 |
|
|
|
46ea99 |
host->ar = drvhost->ar;
|
|
|
46ea99 |
}
|
|
|
46ea99 |
|
|
|
46ea99 |
/* ranlib */
|
|
|
46ea99 |
if (host->ranlib)
|
|
|
46ea99 |
cfgmeta->ranlib = cfgexplicit;
|
|
|
46ea99 |
else {
|
|
|
46ea99 |
if (!(drvhost->ranlib = calloc(1,toollen)))
|
|
|
46ea99 |
return -1;
|
|
|
46ea99 |
|
|
|
46ea99 |
if (fnative) {
|
|
|
46ea99 |
strcpy(drvhost->ranlib,"ranlib");
|
|
|
46ea99 |
cfgmeta->ranlib = cfgnative;
|
|
|
46ea99 |
} else {
|
|
|
46ea99 |
sprintf(drvhost->ranlib,"%s-ranlib",host->host);
|
|
|
46ea99 |
cfgmeta->ranlib = cfghost;
|
|
|
46ea99 |
}
|
|
|
46ea99 |
|
|
|
46ea99 |
host->ranlib = drvhost->ranlib;
|
|
|
46ea99 |
}
|
|
|
46ea99 |
|
|
|
46ea99 |
/* dlltool */
|
|
|
46ea99 |
if (host->dlltool)
|
|
|
46ea99 |
cfgmeta->dlltool = cfgexplicit;
|
|
|
46ea99 |
|
|
|
46ea99 |
else if (strcmp(host->flavor,"cygwin")
|
|
|
46ea99 |
&& strcmp(host->flavor,"midipix")
|
|
|
46ea99 |
&& strcmp(host->flavor,"mingw")) {
|
|
|
46ea99 |
host->dlltool = "";
|
|
|
46ea99 |
cfgmeta->dlltool = "not applicable";
|
|
|
46ea99 |
|
|
|
46ea99 |
} else {
|
|
|
46ea99 |
if (!(drvhost->dlltool = calloc(1,toollen)))
|
|
|
46ea99 |
return -1;
|
|
|
46ea99 |
|
|
|
46ea99 |
if (fnative) {
|
|
|
46ea99 |
strcpy(drvhost->dlltool,"dlltool");
|
|
|
46ea99 |
cfgmeta->dlltool = cfgnative;
|
|
|
46ea99 |
} else {
|
|
|
46ea99 |
sprintf(drvhost->dlltool,"%s-dlltool",host->host);
|
|
|
46ea99 |
cfgmeta->dlltool = cfghost;
|
|
|
46ea99 |
}
|
|
|
46ea99 |
|
|
|
46ea99 |
host->dlltool = drvhost->dlltool;
|
|
|
46ea99 |
}
|
|
|
46ea99 |
|
|
|
46ea99 |
return 0;
|
|
|
46ea99 |
}
|
|
|
46ea99 |
|
|
|
52556c |
static void slbt_free_host_params(struct slbt_host_strs * host)
|
|
|
52556c |
{
|
|
|
52556c |
if (host->host)
|
|
|
52556c |
free(host->host);
|
|
|
52556c |
|
|
|
52556c |
if (host->flavor)
|
|
|
52556c |
free(host->flavor);
|
|
|
52556c |
|
|
|
52556c |
if (host->ar)
|
|
|
52556c |
free(host->ar);
|
|
|
52556c |
|
|
|
52556c |
if (host->ranlib)
|
|
|
52556c |
free(host->ranlib);
|
|
|
52556c |
|
|
|
52556c |
if (host->dlltool)
|
|
|
52556c |
free(host->dlltool);
|
|
|
a313a4 |
|
|
|
a313a4 |
memset(host,0,sizeof(*host));
|
|
|
52556c |
}
|
|
|
52556c |
|
|
|
0b68ad |
static void slbt_init_flavor_settings(
|
|
|
0b68ad |
struct slbt_common_ctx * cctx,
|
|
|
1f442f |
const struct slbt_host_params * ahost,
|
|
|
0b68ad |
struct slbt_flavor_settings * psettings)
|
|
|
a66d34 |
{
|
|
|
1f442f |
const struct slbt_host_params * host;
|
|
|
a66d34 |
const struct slbt_flavor_settings * settings;
|
|
|
a66d34 |
|
|
|
1f442f |
host = ahost ? ahost : &cctx->host;
|
|
|
1f442f |
|
|
|
1f442f |
if (!strcmp(host->flavor,"midipix"))
|
|
|
a66d34 |
settings = &host_flavor_midipix;
|
|
|
1f442f |
else if (!strcmp(host->flavor,"mingw"))
|
|
|
a66d34 |
settings = &host_flavor_mingw;
|
|
|
1f442f |
else if (!strcmp(host->flavor,"cygwin"))
|
|
|
a66d34 |
settings = &host_flavor_cygwin;
|
|
|
1f442f |
else if (!strcmp(host->flavor,"darwin"))
|
|
|
a66d34 |
settings = &host_flavor_darwin;
|
|
|
a66d34 |
else
|
|
|
a66d34 |
settings = &host_flavor_default;
|
|
|
a66d34 |
|
|
|
1f442f |
if (!ahost) {
|
|
|
1f442f |
if (!strcmp(settings->imagefmt,"elf"))
|
|
|
1f442f |
cctx->drvflags |= SLBT_DRIVER_IMAGE_ELF;
|
|
|
1f442f |
else if (!strcmp(settings->imagefmt,"pe"))
|
|
|
1f442f |
cctx->drvflags |= SLBT_DRIVER_IMAGE_PE;
|
|
|
1f442f |
else if (!strcmp(settings->imagefmt,"macho"))
|
|
|
1573d0 |
cctx->drvflags |= SLBT_DRIVER_IMAGE_MACHO;
|
|
|
1f442f |
}
|
|
|
bcd5af |
|
|
|
0b68ad |
memcpy(psettings,settings,sizeof(*settings));
|
|
|
bfa8ca |
|
|
|
bfa8ca |
if (cctx->shrext)
|
|
|
bfa8ca |
psettings->dsosuffix = cctx->shrext;
|
|
|
a66d34 |
}
|
|
|
a66d34 |
|
|
|
af7db9 |
static int slbt_init_ldrpath(
|
|
|
af7db9 |
struct slbt_common_ctx * cctx,
|
|
|
af7db9 |
struct slbt_host_params * host)
|
|
|
af7db9 |
{
|
|
|
af7db9 |
char * buf;
|
|
|
af7db9 |
const char ** ldrpath;
|
|
|
af7db9 |
|
|
|
af7db9 |
if (!cctx->rpath || !(cctx->drvflags & SLBT_DRIVER_IMAGE_ELF)) {
|
|
|
af7db9 |
host->ldrpath = 0;
|
|
|
af7db9 |
return 0;
|
|
|
af7db9 |
}
|
|
|
af7db9 |
|
|
|
af7db9 |
/* common? */
|
|
|
af7db9 |
for (ldrpath=ldrpath_elf; *ldrpath; ldrpath ++)
|
|
|
af7db9 |
if (!(strcmp(cctx->rpath,*ldrpath))) {
|
|
|
af7db9 |
host->ldrpath = 0;
|
|
|
af7db9 |
return 0;
|
|
|
af7db9 |
}
|
|
|
af7db9 |
|
|
|
af7db9 |
/* buf */
|
|
|
af7db9 |
if (!(buf = malloc(12 + strlen(cctx->host.host))))
|
|
|
af7db9 |
return -1;
|
|
|
af7db9 |
|
|
|
af7db9 |
/* /usr/{host}/lib */
|
|
|
af7db9 |
sprintf(buf,"/usr/%s/lib",cctx->host.host);
|
|
|
af7db9 |
|
|
|
af7db9 |
if (!(strcmp(cctx->rpath,buf))) {
|
|
|
af7db9 |
host->ldrpath = 0;
|
|
|
af7db9 |
free(buf);
|
|
|
af7db9 |
return 0;
|
|
|
af7db9 |
}
|
|
|
af7db9 |
|
|
|
af7db9 |
/* /usr/{host}/lib64 */
|
|
|
af7db9 |
sprintf(buf,"/usr/%s/lib64",cctx->host.host);
|
|
|
af7db9 |
|
|
|
af7db9 |
if (!(strcmp(cctx->rpath,buf))) {
|
|
|
af7db9 |
host->ldrpath = 0;
|
|
|
af7db9 |
free(buf);
|
|
|
af7db9 |
return 0;
|
|
|
af7db9 |
}
|
|
|
af7db9 |
|
|
|
af7db9 |
host->ldrpath = cctx->rpath;
|
|
|
af7db9 |
|
|
|
af7db9 |
free(buf);
|
|
|
af7db9 |
return 0;
|
|
|
af7db9 |
}
|
|
|
af7db9 |
|
|
|
5a9161 |
static int slbt_init_version_info(
|
|
|
5a9161 |
struct slbt_driver_ctx_impl * ictx,
|
|
|
5a9161 |
struct slbt_version_info * verinfo)
|
|
|
5a9161 |
{
|
|
|
5a9161 |
int current;
|
|
|
5a9161 |
int revision;
|
|
|
5a9161 |
int age;
|
|
|
5a9161 |
|
|
|
dcb453 |
if (!verinfo->verinfo && !verinfo->vernumber)
|
|
|
dcb453 |
return 0;
|
|
|
dcb453 |
|
|
|
cd3d41 |
if (verinfo->vernumber) {
|
|
|
cd3d41 |
sscanf(verinfo->vernumber,"%d:%d:%d",
|
|
|
cd3d41 |
&verinfo->major,
|
|
|
cd3d41 |
&verinfo->minor,
|
|
|
cd3d41 |
&verinfo->revision);
|
|
|
cd3d41 |
return 0;
|
|
|
cd3d41 |
}
|
|
|
cd3d41 |
|
|
|
f22545 |
current = revision = age = 0;
|
|
|
f22545 |
|
|
|
5a9161 |
sscanf(verinfo->verinfo,"%d:%d:%d",
|
|
|
5a9161 |
¤t,&revision,&age;;
|
|
|
5a9161 |
|
|
|
5a9161 |
if (current < age) {
|
|
|
5a9161 |
if (ictx->cctx.drvflags & SLBT_DRIVER_VERBOSITY_ERRORS)
|
|
|
5a9161 |
fprintf(stderr,
|
|
|
5a9161 |
"%s: error: invalid version info: "
|
|
|
5a9161 |
"<current> may not be smaller than <age>.\n",
|
|
|
5a9161 |
argv_program_name(ictx->cctx.targv[0]));
|
|
|
5a9161 |
return -1;
|
|
|
5a9161 |
}
|
|
|
5a9161 |
|
|
|
5a9161 |
verinfo->major = current - age;
|
|
|
5a9161 |
verinfo->minor = age;
|
|
|
5a9161 |
verinfo->revision = revision;
|
|
|
5a9161 |
|
|
|
5a9161 |
return 0;
|
|
|
5a9161 |
}
|
|
|
5a9161 |
|
|
|
f8e27e |
static int slbt_init_link_params(struct slbt_driver_ctx_impl * ctx)
|
|
|
f8e27e |
{
|
|
|
f8e27e |
const char * program;
|
|
|
f8e27e |
const char * libname;
|
|
|
f8e27e |
const char * prefix;
|
|
|
965661 |
const char * base;
|
|
|
f8e27e |
char * dot;
|
|
|
a943fc |
bool fmodule;
|
|
|
f8e27e |
|
|
|
f8e27e |
program = argv_program_name(ctx->cctx.targv[0]);
|
|
|
f8e27e |
libname = 0;
|
|
|
146916 |
prefix = 0;
|
|
|
a943fc |
fmodule = false;
|
|
|
f8e27e |
|
|
|
f8e27e |
/* output */
|
|
|
f8e27e |
if (!(ctx->cctx.output)) {
|
|
|
f8e27e |
if (ctx->cctx.drvflags & SLBT_DRIVER_VERBOSITY_ERRORS)
|
|
|
f8e27e |
fprintf(stderr,
|
|
|
f8e27e |
"%s: error: output file must be "
|
|
|
f8e27e |
"specified in link mode.\n",
|
|
|
f8e27e |
program);
|
|
|
f8e27e |
return -1;
|
|
|
f8e27e |
}
|
|
|
f8e27e |
|
|
|
f8e27e |
/* executable? */
|
|
|
f8e27e |
if (!(dot = strrchr(ctx->cctx.output,'.')))
|
|
|
f8e27e |
return 0;
|
|
|
f8e27e |
|
|
|
f8e27e |
/* todo: archive? library? wrapper? inlined function, avoid repetition */
|
|
|
965661 |
if ((base = strrchr(ctx->cctx.output,'/')))
|
|
|
965661 |
base++;
|
|
|
965661 |
else
|
|
|
965661 |
base = ctx->cctx.output;
|
|
|
f8e27e |
|
|
|
f8e27e |
/* archive? */
|
|
|
f8e27e |
if (!strcmp(dot,ctx->cctx.settings.arsuffix)) {
|
|
|
f8e27e |
prefix = ctx->cctx.settings.arprefix;
|
|
|
f8e27e |
|
|
|
965661 |
if (!strncmp(prefix,base,strlen(prefix)))
|
|
|
4f7984 |
libname = base;
|
|
|
f8e27e |
else {
|
|
|
f8e27e |
if (ctx->cctx.drvflags & SLBT_DRIVER_VERBOSITY_ERRORS)
|
|
|
f8e27e |
fprintf(stderr,
|
|
|
f8e27e |
"%s: error: output file prefix does "
|
|
|
f8e27e |
"not match its (archive) suffix; "
|
|
|
f8e27e |
"the expected prefix was '%s'\n",
|
|
|
f8e27e |
program,prefix);
|
|
|
f8e27e |
return -1;
|
|
|
f8e27e |
}
|
|
|
f8e27e |
}
|
|
|
f8e27e |
|
|
|
f8e27e |
/* library? */
|
|
|
f8e27e |
else if (!strcmp(dot,ctx->cctx.settings.dsosuffix)) {
|
|
|
f8e27e |
prefix = ctx->cctx.settings.dsoprefix;
|
|
|
f8e27e |
|
|
|
965661 |
if (!strncmp(prefix,base,strlen(prefix)))
|
|
|
4f7984 |
libname = base;
|
|
|
f8e27e |
else {
|
|
|
f8e27e |
if (ctx->cctx.drvflags & SLBT_DRIVER_VERBOSITY_ERRORS)
|
|
|
f8e27e |
fprintf(stderr,
|
|
|
f8e27e |
"%s: error: output file prefix does "
|
|
|
f8e27e |
"not match its (shared library) suffix; "
|
|
|
f8e27e |
"the expected prefix was '%s'\n",
|
|
|
f8e27e |
program,prefix);
|
|
|
f8e27e |
return -1;
|
|
|
f8e27e |
}
|
|
|
f8e27e |
}
|
|
|
f8e27e |
|
|
|
f8e27e |
/* wrapper? */
|
|
|
f8e27e |
else if (!strcmp(dot,".la")) {
|
|
|
f8e27e |
prefix = ctx->cctx.settings.dsoprefix;
|
|
|
f8e27e |
|
|
|
f9dfdb |
if (!strncmp(prefix,base,strlen(prefix))) {
|
|
|
4f7984 |
libname = base;
|
|
|
f9dfdb |
fmodule = !!(ctx->cctx.drvflags & SLBT_DRIVER_MODULE);
|
|
|
f9dfdb |
} else if (ctx->cctx.drvflags & SLBT_DRIVER_MODULE) {
|
|
|
a943fc |
libname = base;
|
|
|
a943fc |
fmodule = true;
|
|
|
a943fc |
} else {
|
|
|
f8e27e |
if (ctx->cctx.drvflags & SLBT_DRIVER_VERBOSITY_ERRORS)
|
|
|
f8e27e |
fprintf(stderr,
|
|
|
f8e27e |
"%s: error: output file prefix does "
|
|
|
f8e27e |
"not match its (libtool wrapper) suffix; "
|
|
|
f8e27e |
"the expected prefix was '%s'\n",
|
|
|
f8e27e |
program,prefix);
|
|
|
f8e27e |
return -1;
|
|
|
f8e27e |
}
|
|
|
82142f |
} else
|
|
|
f8e27e |
return 0;
|
|
|
f8e27e |
|
|
|
f8e27e |
/* libname alloc */
|
|
|
a943fc |
if (!fmodule)
|
|
|
a943fc |
libname += strlen(prefix);
|
|
|
a943fc |
|
|
|
a943fc |
if (!(ctx->libname = strdup(libname)))
|
|
|
f8e27e |
return -1;
|
|
|
f8e27e |
|
|
|
f8e27e |
dot = strrchr(ctx->libname,'.');
|
|
|
a87fd1 |
*dot = 0;
|
|
|
f8e27e |
|
|
|
f8e27e |
ctx->cctx.libname = ctx->libname;
|
|
|
f8e27e |
|
|
|
f8e27e |
return 0;
|
|
|
f8e27e |
}
|
|
|
f8e27e |
|
|
|
9ca8c4 |
int slbt_get_driver_ctx(
|
|
|
9ca8c4 |
char ** argv,
|
|
|
9ca8c4 |
char ** envp,
|
|
|
9ca8c4 |
uint32_t flags,
|
|
|
9ca8c4 |
struct slbt_driver_ctx ** pctx)
|
|
|
9ca8c4 |
{
|
|
|
56cab3 |
struct slbt_split_vector sargv;
|
|
|
9ca8c4 |
struct slbt_driver_ctx_impl * ctx;
|
|
|
9ca8c4 |
struct slbt_common_ctx cctx;
|
|
|
9ca8c4 |
const struct argv_option * options;
|
|
|
9ca8c4 |
struct argv_meta * meta;
|
|
|
9ca8c4 |
struct argv_entry * entry;
|
|
|
9ca8c4 |
size_t nunits;
|
|
|
9ca8c4 |
const char * program;
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
options = slbt_default_options;
|
|
|
9ca8c4 |
|
|
|
56cab3 |
if (slbt_split_argv(argv,flags,&sargv))
|
|
|
56cab3 |
return -1;
|
|
|
56cab3 |
|
|
|
56cab3 |
if (!(meta = argv_get(sargv.targv,options,slbt_argv_flags(flags))))
|
|
|
9ca8c4 |
return -1;
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
nunits = 0;
|
|
|
9ca8c4 |
program = argv_program_name(argv[0]);
|
|
|
9ca8c4 |
memset(&cctx,0,sizeof(cctx));
|
|
|
9ca8c4 |
|
|
|
341c87 |
/* shared and static objects: enable by default, disable by ~switch */
|
|
|
340eda |
cctx.drvflags = flags | SLBT_DRIVER_SHARED | SLBT_DRIVER_STATIC;
|
|
|
341c87 |
|
|
|
2bc175 |
/* full annotation when annotation is on; */
|
|
|
2bc175 |
cctx.drvflags |= SLBT_DRIVER_ANNOTATE_FULL;
|
|
|
2bc175 |
|
|
|
9ca8c4 |
/* get options, count units */
|
|
|
9ca8c4 |
for (entry=meta->entries; entry->fopt || entry->arg; entry++) {
|
|
|
9ca8c4 |
if (entry->fopt) {
|
|
|
9ca8c4 |
switch (entry->tag) {
|
|
|
9ca8c4 |
case TAG_HELP:
|
|
|
949677 |
case TAG_HELP_ALL:
|
|
|
9ca8c4 |
if (flags & SLBT_DRIVER_VERBOSITY_USAGE)
|
|
|
9ca8c4 |
return slbt_driver_usage(program,entry->arg,options,meta);
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
case TAG_VERSION:
|
|
|
9ca8c4 |
cctx.drvflags |= SLBT_DRIVER_VERSION;
|
|
|
9ca8c4 |
break;
|
|
|
667ce2 |
|
|
|
667ce2 |
case TAG_MODE:
|
|
|
667ce2 |
if (!strcmp("clean",entry->arg))
|
|
|
667ce2 |
cctx.mode = SLBT_MODE_CLEAN;
|
|
|
667ce2 |
|
|
|
667ce2 |
else if (!strcmp("compile",entry->arg))
|
|
|
667ce2 |
cctx.mode = SLBT_MODE_COMPILE;
|
|
|
667ce2 |
|
|
|
667ce2 |
else if (!strcmp("execute",entry->arg))
|
|
|
667ce2 |
cctx.mode = SLBT_MODE_EXECUTE;
|
|
|
667ce2 |
|
|
|
667ce2 |
else if (!strcmp("finish",entry->arg))
|
|
|
667ce2 |
cctx.mode = SLBT_MODE_FINISH;
|
|
|
667ce2 |
|
|
|
667ce2 |
else if (!strcmp("install",entry->arg))
|
|
|
667ce2 |
cctx.mode = SLBT_MODE_INSTALL;
|
|
|
667ce2 |
|
|
|
667ce2 |
else if (!strcmp("link",entry->arg))
|
|
|
667ce2 |
cctx.mode = SLBT_MODE_LINK;
|
|
|
667ce2 |
|
|
|
667ce2 |
else if (!strcmp("uninstall",entry->arg))
|
|
|
667ce2 |
cctx.mode = SLBT_MODE_UNINSTALL;
|
|
|
667ce2 |
break;
|
|
|
071d14 |
|
|
|
071d14 |
case TAG_DRY_RUN:
|
|
|
071d14 |
cctx.drvflags |= SLBT_DRIVER_DRY_RUN;
|
|
|
071d14 |
break;
|
|
|
53f4ec |
|
|
|
53f4ec |
case TAG_TAG:
|
|
|
53f4ec |
if (!strcmp("CC",entry->arg))
|
|
|
53f4ec |
cctx.tag = SLBT_TAG_CC;
|
|
|
53f4ec |
|
|
|
53f4ec |
else if (!strcmp("CXX",entry->arg))
|
|
|
53f4ec |
cctx.tag = SLBT_TAG_CXX;
|
|
|
62b4bb |
|
|
|
62b4bb |
else if (!strcmp("NASM",entry->arg))
|
|
|
62b4bb |
cctx.tag = SLBT_TAG_NASM;
|
|
|
0e609b |
|
|
|
0e609b |
else if (!strcmp("disable-static",entry->arg))
|
|
|
0e609b |
cctx.drvflags |= SLBT_DRIVER_DISABLE_STATIC;
|
|
|
f5fa4c |
|
|
|
f5fa4c |
else if (!strcmp("disable-shared",entry->arg))
|
|
|
f5fa4c |
cctx.drvflags |= SLBT_DRIVER_DISABLE_SHARED;
|
|
|
53f4ec |
break;
|
|
|
173b54 |
|
|
|
173b54 |
case TAG_CONFIG:
|
|
|
173b54 |
cctx.drvflags |= SLBT_DRIVER_CONFIG;
|
|
|
173b54 |
break;
|
|
|
173b54 |
|
|
|
fea1b8 |
case TAG_DEBUG:
|
|
|
fea1b8 |
cctx.drvflags |= SLBT_DRIVER_DEBUG;
|
|
|
fea1b8 |
break;
|
|
|
d03fbc |
|
|
|
d03fbc |
case TAG_FEATURES:
|
|
|
d03fbc |
cctx.drvflags |= SLBT_DRIVER_FEATURES;
|
|
|
d03fbc |
break;
|
|
|
6376f0 |
|
|
|
6376f0 |
case TAG_WARNINGS:
|
|
|
6376f0 |
if (!strcmp("all",entry->arg))
|
|
|
1142bf |
cctx.warnings = SLBT_WARNING_LEVEL_ALL;
|
|
|
6376f0 |
|
|
|
6376f0 |
else if (!strcmp("error",entry->arg))
|
|
|
1142bf |
cctx.warnings = SLBT_WARNING_LEVEL_ERROR;
|
|
|
6376f0 |
|
|
|
6376f0 |
else if (!strcmp("none",entry->arg))
|
|
|
1142bf |
cctx.warnings = SLBT_WARNING_LEVEL_NONE;
|
|
|
6376f0 |
break;
|
|
|
40fabb |
|
|
|
2bc175 |
case TAG_ANNOTATE:
|
|
|
2bc175 |
if (!strcmp("always",entry->arg)) {
|
|
|
2bc175 |
cctx.drvflags |= SLBT_DRIVER_ANNOTATE_ALWAYS;
|
|
|
2bc175 |
cctx.drvflags &= ~(uint64_t)SLBT_DRIVER_ANNOTATE_NEVER;
|
|
|
2bc175 |
|
|
|
2bc175 |
} else if (!strcmp("never",entry->arg)) {
|
|
|
2bc175 |
cctx.drvflags |= SLBT_DRIVER_ANNOTATE_NEVER;
|
|
|
2bc175 |
cctx.drvflags &= ~(uint64_t)SLBT_DRIVER_ANNOTATE_ALWAYS;
|
|
|
2bc175 |
|
|
|
2bc175 |
} else if (!strcmp("minimal",entry->arg)) {
|
|
|
2bc175 |
cctx.drvflags &= ~(uint64_t)SLBT_DRIVER_ANNOTATE_FULL;
|
|
|
2bc175 |
|
|
|
2bc175 |
} else if (!strcmp("full",entry->arg)) {
|
|
|
2bc175 |
cctx.drvflags |= SLBT_DRIVER_ANNOTATE_FULL;
|
|
|
2bc175 |
}
|
|
|
2bc175 |
|
|
|
2bc175 |
break;
|
|
|
2bc175 |
|
|
|
40fabb |
case TAG_DEPS:
|
|
|
40fabb |
cctx.drvflags |= SLBT_DRIVER_DEPS;
|
|
|
40fabb |
break;
|
|
|
40fabb |
|
|
|
398419 |
case TAG_SILENT:
|
|
|
398419 |
cctx.drvflags |= SLBT_DRIVER_SILENT;
|
|
|
398419 |
break;
|
|
|
25956b |
|
|
|
25956b |
case TAG_VERBOSE:
|
|
|
25956b |
cctx.drvflags |= SLBT_DRIVER_VERBOSE;
|
|
|
25956b |
break;
|
|
|
b83b64 |
|
|
|
db67ad |
case TAG_HOST:
|
|
|
db67ad |
cctx.host.host = entry->arg;
|
|
|
db67ad |
break;
|
|
|
db67ad |
|
|
|
db67ad |
case TAG_FLAVOR:
|
|
|
db67ad |
cctx.host.flavor = entry->arg;
|
|
|
db67ad |
break;
|
|
|
db67ad |
|
|
|
db67ad |
case TAG_AR:
|
|
|
db67ad |
cctx.host.ar = entry->arg;
|
|
|
db67ad |
break;
|
|
|
db67ad |
|
|
|
db67ad |
case TAG_RANLIB:
|
|
|
db67ad |
cctx.host.ranlib = entry->arg;
|
|
|
db67ad |
break;
|
|
|
db67ad |
|
|
|
db67ad |
case TAG_DLLTOOL:
|
|
|
db67ad |
cctx.host.dlltool = entry->arg;
|
|
|
db67ad |
break;
|
|
|
db67ad |
|
|
|
b83b64 |
case TAG_OUTPUT:
|
|
|
b83b64 |
cctx.output = entry->arg;
|
|
|
b83b64 |
break;
|
|
|
4f1b20 |
|
|
|
bfa8ca |
case TAG_SHREXT:
|
|
|
bfa8ca |
cctx.shrext = entry->arg;
|
|
|
bfa8ca |
break;
|
|
|
bfa8ca |
|
|
|
9c664d |
case TAG_RPATH:
|
|
|
9c664d |
cctx.rpath = entry->arg;
|
|
|
9c664d |
break;
|
|
|
9c664d |
|
|
|
9aa1f4 |
case TAG_RELEASE:
|
|
|
9aa1f4 |
cctx.release = entry->arg;
|
|
|
112a2b |
cctx.drvflags |= SLBT_DRIVER_AVOID_VERSION;
|
|
|
9aa1f4 |
break;
|
|
|
9aa1f4 |
|
|
|
873ecb |
case TAG_EXPSYM_FILE:
|
|
|
873ecb |
cctx.symfile = entry->arg;
|
|
|
873ecb |
break;
|
|
|
873ecb |
|
|
|
73ca78 |
case TAG_EXPSYM_REGEX:
|
|
|
73ca78 |
cctx.regex = entry->arg;
|
|
|
73ca78 |
break;
|
|
|
73ca78 |
|
|
|
5a9161 |
case TAG_VERSION_INFO:
|
|
|
5a9161 |
cctx.verinfo.verinfo = entry->arg;
|
|
|
5a9161 |
break;
|
|
|
5a9161 |
|
|
|
cd3d41 |
case TAG_VERSION_NUMBER:
|
|
|
cd3d41 |
cctx.verinfo.vernumber = entry->arg;
|
|
|
cd3d41 |
break;
|
|
|
cd3d41 |
|
|
|
4df790 |
case TAG_TARGET:
|
|
|
4df790 |
cctx.target = entry->arg;
|
|
|
4df790 |
break;
|
|
|
4df790 |
|
|
|
4f1b20 |
case TAG_PREFER_PIC:
|
|
|
4f1b20 |
cctx.drvflags |= SLBT_DRIVER_PRO_PIC;
|
|
|
4f1b20 |
break;
|
|
|
4f1b20 |
|
|
|
4f1b20 |
case TAG_PREFER_NON_PIC:
|
|
|
4f1b20 |
cctx.drvflags |= SLBT_DRIVER_ANTI_PIC;
|
|
|
4f1b20 |
break;
|
|
|
9c25c7 |
|
|
|
93b62c |
case TAG_NO_UNDEFINED:
|
|
|
93b62c |
cctx.drvflags |= SLBT_DRIVER_NO_UNDEFINED;
|
|
|
93b62c |
break;
|
|
|
93b62c |
|
|
|
a943fc |
case TAG_MODULE:
|
|
|
a943fc |
cctx.drvflags |= SLBT_DRIVER_MODULE;
|
|
|
a943fc |
break;
|
|
|
a943fc |
|
|
|
f7645c |
case TAG_ALL_STATIC:
|
|
|
f7645c |
cctx.drvflags |= SLBT_DRIVER_ALL_STATIC;
|
|
|
f7645c |
break;
|
|
|
f7645c |
|
|
|
0e609b |
case TAG_DISABLE_STATIC:
|
|
|
0e609b |
cctx.drvflags |= SLBT_DRIVER_DISABLE_STATIC;
|
|
|
0e609b |
break;
|
|
|
0e609b |
|
|
|
f5fa4c |
case TAG_DISABLE_SHARED:
|
|
|
f5fa4c |
cctx.drvflags |= SLBT_DRIVER_DISABLE_SHARED;
|
|
|
f5fa4c |
break;
|
|
|
f5fa4c |
|
|
|
68f313 |
case TAG_AVOID_VERSION:
|
|
|
68f313 |
cctx.drvflags |= SLBT_DRIVER_AVOID_VERSION;
|
|
|
68f313 |
break;
|
|
|
68f313 |
|
|
|
9c25c7 |
case TAG_SHARED:
|
|
|
341c87 |
cctx.drvflags &= ~(uint64_t)SLBT_DRIVER_STATIC;
|
|
|
9c25c7 |
break;
|
|
|
9c25c7 |
|
|
|
9c25c7 |
case TAG_STATIC:
|
|
|
341c87 |
cctx.drvflags &= ~(uint64_t)SLBT_DRIVER_SHARED;
|
|
|
9c25c7 |
break;
|
|
|
9ca8c4 |
}
|
|
|
9ca8c4 |
} else
|
|
|
9ca8c4 |
nunits++;
|
|
|
9ca8c4 |
}
|
|
|
9ca8c4 |
|
|
|
9b5eec |
/* -o in install mode means USER */
|
|
|
9b5eec |
if ((cctx.mode == SLBT_MODE_INSTALL) && cctx.output) {
|
|
|
9b5eec |
cctx.user = cctx.output;
|
|
|
9b5eec |
cctx.output = 0;
|
|
|
9b5eec |
}
|
|
|
9b5eec |
|
|
|
c778cc |
/* driver context */
|
|
|
9ca8c4 |
if (!(ctx = slbt_driver_ctx_alloc(meta,&cctx,nunits)))
|
|
|
9ca8c4 |
return slbt_get_driver_ctx_fail(meta);
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
ctx->ctx.program = program;
|
|
|
9ca8c4 |
ctx->ctx.cctx = &ctx->cctx;
|
|
|
56cab3 |
ctx->targv = sargv.targv;
|
|
|
56cab3 |
ctx->cargv = sargv.cargv;
|
|
|
9ca8c4 |
|
|
|
a288c4 |
ctx->cctx.targv = sargv.targv;
|
|
|
a288c4 |
ctx->cctx.cargv = sargv.cargv;
|
|
|
a288c4 |
|
|
|
46ea99 |
/* host params */
|
|
|
46ea99 |
if ((cctx.drvflags & SLBT_DRIVER_HEURISTICS)
|
|
|
24efc6 |
|| (cctx.drvflags & SLBT_DRIVER_CONFIG)
|
|
|
a66d34 |
|| (cctx.mode != SLBT_MODE_COMPILE)) {
|
|
|
46ea99 |
if (slbt_init_host_params(
|
|
|
46ea99 |
&ctx->cctx,
|
|
|
46ea99 |
&ctx->host,
|
|
|
46ea99 |
&ctx->cctx.host,
|
|
|
46ea99 |
&ctx->cctx.cfgmeta)) {
|
|
|
46ea99 |
slbt_free_driver_ctx(&ctx->ctx);
|
|
|
46ea99 |
return -1;
|
|
|
a66d34 |
} else
|
|
|
0b68ad |
slbt_init_flavor_settings(
|
|
|
1f442f |
&ctx->cctx,0,
|
|
|
0b68ad |
&ctx->cctx.settings);
|
|
|
a66d34 |
}
|
|
|
46ea99 |
|
|
|
af7db9 |
/* ldpath */
|
|
|
af7db9 |
if (slbt_init_ldrpath(&ctx->cctx,&ctx->cctx.host)) {
|
|
|
af7db9 |
slbt_free_driver_ctx(&ctx->ctx);
|
|
|
af7db9 |
return -1;
|
|
|
af7db9 |
}
|
|
|
af7db9 |
|
|
|
5a9161 |
/* version info */
|
|
|
dcb453 |
if (slbt_init_version_info(ctx,&ctx->cctx.verinfo)) {
|
|
|
dcb453 |
slbt_free_driver_ctx(&ctx->ctx);
|
|
|
dcb453 |
return -1;
|
|
|
dcb453 |
}
|
|
|
5a9161 |
|
|
|
f8e27e |
/* link params */
|
|
|
f8e27e |
if (cctx.mode == SLBT_MODE_LINK)
|
|
|
f8e27e |
if (slbt_init_link_params(ctx)) {
|
|
|
f8e27e |
slbt_free_driver_ctx(&ctx->ctx);
|
|
|
f8e27e |
return -1;
|
|
|
f8e27e |
}
|
|
|
f8e27e |
|
|
|
9ca8c4 |
*pctx = &ctx->ctx;
|
|
|
9ca8c4 |
return SLBT_OK;
|
|
|
9ca8c4 |
}
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
int slbt_create_driver_ctx(
|
|
|
9ca8c4 |
const struct slbt_common_ctx * cctx,
|
|
|
9ca8c4 |
struct slbt_driver_ctx ** pctx)
|
|
|
9ca8c4 |
{
|
|
|
9ca8c4 |
struct argv_meta * meta;
|
|
|
9ca8c4 |
struct slbt_driver_ctx_impl * ctx;
|
|
|
9ca8c4 |
char * argv[] = {"slibtool_driver",0};
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
if (!(meta = argv_get(argv,slbt_default_options,0)))
|
|
|
9ca8c4 |
return -1;
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
if (!(ctx = slbt_driver_ctx_alloc(meta,cctx,0)))
|
|
|
9ca8c4 |
return slbt_get_driver_ctx_fail(0);
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
ctx->ctx.cctx = &ctx->cctx;
|
|
|
9ca8c4 |
memcpy(&ctx->cctx,cctx,sizeof(*cctx));
|
|
|
9ca8c4 |
*pctx = &ctx->ctx;
|
|
|
9ca8c4 |
return SLBT_OK;
|
|
|
9ca8c4 |
}
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
static void slbt_free_driver_ctx_impl(struct slbt_driver_ctx_alloc * ictx)
|
|
|
9ca8c4 |
{
|
|
|
56cab3 |
if (ictx->ctx.targv)
|
|
|
56cab3 |
free(ictx->ctx.targv);
|
|
|
56cab3 |
|
|
|
f8e27e |
if (ictx->ctx.libname)
|
|
|
f8e27e |
free(ictx->ctx.libname);
|
|
|
f8e27e |
|
|
|
52556c |
slbt_free_host_params(&ictx->ctx.host);
|
|
|
77b97b |
slbt_free_host_params(&ictx->ctx.ahost);
|
|
|
9ca8c4 |
argv_free(ictx->meta);
|
|
|
9ca8c4 |
free(ictx);
|
|
|
9ca8c4 |
}
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
void slbt_free_driver_ctx(struct slbt_driver_ctx * ctx)
|
|
|
9ca8c4 |
{
|
|
|
9ca8c4 |
struct slbt_driver_ctx_alloc * ictx;
|
|
|
9ca8c4 |
uintptr_t addr;
|
|
|
9ca8c4 |
|
|
|
9ca8c4 |
if (ctx) {
|
|
|
9ca8c4 |
addr = (uintptr_t)ctx - offsetof(struct slbt_driver_ctx_alloc,ctx);
|
|
|
9ca8c4 |
addr = addr - offsetof(struct slbt_driver_ctx_impl,ctx);
|
|
|
9ca8c4 |
ictx = (struct slbt_driver_ctx_alloc *)addr;
|
|
|
9ca8c4 |
slbt_free_driver_ctx_impl(ictx);
|
|
|
9ca8c4 |
}
|
|
|
9ca8c4 |
}
|
|
|
a313a4 |
|
|
|
a313a4 |
void slbt_reset_alternate_host(const struct slbt_driver_ctx * ctx)
|
|
|
a313a4 |
{
|
|
|
a313a4 |
struct slbt_driver_ctx_alloc * ictx;
|
|
|
a313a4 |
uintptr_t addr;
|
|
|
a313a4 |
|
|
|
a313a4 |
addr = (uintptr_t)ctx - offsetof(struct slbt_driver_ctx_alloc,ctx);
|
|
|
a313a4 |
addr = addr - offsetof(struct slbt_driver_ctx_impl,ctx);
|
|
|
a313a4 |
ictx = (struct slbt_driver_ctx_alloc *)addr;
|
|
|
a313a4 |
|
|
|
a313a4 |
slbt_free_host_params(&ictx->ctx.ahost);
|
|
|
a313a4 |
}
|
|
|
a313a4 |
|
|
|
a313a4 |
int slbt_set_alternate_host(
|
|
|
a313a4 |
const struct slbt_driver_ctx * ctx,
|
|
|
a313a4 |
const char * host,
|
|
|
a313a4 |
const char * flavor)
|
|
|
a313a4 |
{
|
|
|
a313a4 |
struct slbt_driver_ctx_alloc * ictx;
|
|
|
a313a4 |
uintptr_t addr;
|
|
|
a313a4 |
|
|
|
a313a4 |
addr = (uintptr_t)ctx - offsetof(struct slbt_driver_ctx_alloc,ctx);
|
|
|
a313a4 |
addr = addr - offsetof(struct slbt_driver_ctx_impl,ctx);
|
|
|
a313a4 |
ictx = (struct slbt_driver_ctx_alloc *)addr;
|
|
|
a313a4 |
slbt_free_host_params(&ictx->ctx.ahost);
|
|
|
a313a4 |
|
|
|
a313a4 |
if (!(ictx->ctx.ahost.host = strdup(host)))
|
|
|
a313a4 |
return -1;
|
|
|
a313a4 |
|
|
|
a313a4 |
if (!(ictx->ctx.ahost.flavor = strdup(flavor))) {
|
|
|
a313a4 |
slbt_free_host_params(&ictx->ctx.ahost);
|
|
|
a313a4 |
return -1;
|
|
|
a313a4 |
}
|
|
|
a313a4 |
|
|
|
a313a4 |
ictx->ctx.cctx.ahost.host = ictx->ctx.ahost.host;
|
|
|
a313a4 |
ictx->ctx.cctx.ahost.flavor = ictx->ctx.ahost.flavor;
|
|
|
a313a4 |
|
|
|
a313a4 |
if (slbt_init_host_params(
|
|
|
a313a4 |
ctx->cctx,
|
|
|
a313a4 |
&ictx->ctx.ahost,
|
|
|
a313a4 |
&ictx->ctx.cctx.ahost,
|
|
|
a313a4 |
&ictx->ctx.cctx.acfgmeta)) {
|
|
|
a313a4 |
slbt_free_host_params(&ictx->ctx.ahost);
|
|
|
a313a4 |
return -1;
|
|
|
a313a4 |
}
|
|
|
a313a4 |
|
|
|
a313a4 |
slbt_init_flavor_settings(
|
|
|
a313a4 |
&ictx->ctx.cctx,
|
|
|
a313a4 |
&ictx->ctx.cctx.ahost,
|
|
|
a313a4 |
&ictx->ctx.cctx.asettings);
|
|
|
a313a4 |
|
|
|
af7db9 |
if (slbt_init_ldrpath(
|
|
|
af7db9 |
&ictx->ctx.cctx,
|
|
|
af7db9 |
&ictx->ctx.cctx.ahost)) {
|
|
|
af7db9 |
slbt_free_host_params(&ictx->ctx.ahost);
|
|
|
af7db9 |
return -1;
|
|
|
af7db9 |
}
|
|
|
af7db9 |
|
|
|
a313a4 |
return 0;
|
|
|
a313a4 |
}
|
|
|
9f24d2 |
|
|
|
9f24d2 |
const struct slbt_source_version * slbt_source_version(void)
|
|
|
9f24d2 |
{
|
|
|
9f24d2 |
return &slbt_src_version;
|
|
|
9f24d2 |
}
|