|
|
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>
|
|
|
9ca8c4 |
#include "slibtool_driver_impl.h"
|
|
|
9ca8c4 |
#include "argv/argv.h"
|
|
|
9ca8c4 |
|
|
|
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>";
|
|
|
46ea99 |
static const char cfgmachine[] = "native (derived from -dumpmachine)";
|
|
|
46ea99 |
static const char cfgnative[] = "native";
|
|
|
46ea99 |
|
|
|
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? */
|
|
|
56cab3 |
for (mode=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
|
|
|
56cab3 |
if (argv[i][0] != '-')
|
|
|
56cab3 |
*cargv++ = argv[i];
|
|
|
56cab3 |
|
|
|
a288c4 |
else if (argv[i][1] == 'o') {
|
|
|
56cab3 |
*targv++ = argv[i];
|
|
|
56cab3 |
|
|
|
a288c4 |
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="))))
|
|
|
411564 |
*targv++ = argv[i++];
|
|
|
411564 |
|
|
|
411564 |
else if (!(strcmp("-target",&argv[i][1]))) {
|
|
|
411564 |
*targv++ = argv[i++];
|
|
|
411564 |
*targv++ = argv[i++];
|
|
|
411564 |
|
|
|
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 |
|
|
|
46ea99 |
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;
|
|
|
46ea99 |
char * slash;
|
|
|
46ea99 |
const char * machine;
|
|
|
46ea99 |
bool ftarget = false;
|
|
|
46ea99 |
bool fhost = false;
|
|
|
46ea99 |
bool fcompiler = false;
|
|
|
46ea99 |
bool fnative = false;
|
|
|
46ea99 |
|
|
|
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;
|
|
|
46ea99 |
} else if (strrchr(cctx->cargv[0],'-')) {
|
|
|
46ea99 |
if (!(drvhost->host = strdup(cctx->cargv[0])))
|
|
|
46ea99 |
return -1;
|
|
|
46ea99 |
|
|
|
46ea99 |
slash = strrchr(drvhost->host,'-');
|
|
|
46ea99 |
*slash = '\0';
|
|
|
46ea99 |
host->host = drvhost->host;
|
|
|
46ea99 |
cfgmeta->host = cfgcompiler;
|
|
|
46ea99 |
fcompiler = true;
|
|
|
46ea99 |
} else {
|
|
|
46ea99 |
host->host = SLBT_MACHINE;
|
|
|
46ea99 |
cfgmeta->host = cfgmachine;
|
|
|
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;
|
|
|
46ea99 |
cfgmeta->flavor = cfgmachine;
|
|
|
46ea99 |
}
|
|
|
46ea99 |
|
|
|
46ea99 |
slash = strrchr(machine,'-');
|
|
|
46ea99 |
cfgmeta->flavor = cfghost;
|
|
|
46ea99 |
|
|
|
46ea99 |
if ((slash && !strcmp(slash,"-bsd")) || strstr(machine,"-bsd-"))
|
|
|
46ea99 |
host->flavor = "bsd";
|
|
|
46ea99 |
else if ((slash && !strcmp(slash,"-cygwin")) || strstr(machine,"-cygwin-"))
|
|
|
46ea99 |
host->flavor = "cygwin";
|
|
|
46ea99 |
else if ((slash && !strcmp(slash,"-darwin")) || strstr(machine,"-darwin-"))
|
|
|
46ea99 |
host->flavor = "darwin";
|
|
|
46ea99 |
else if ((slash && !strcmp(slash,"-linux")) || strstr(machine,"-linux-"))
|
|
|
46ea99 |
host->flavor = "linux";
|
|
|
46ea99 |
else if ((slash && !strcmp(slash,"-midipix")) || strstr(machine,"-midipix-"))
|
|
|
46ea99 |
host->flavor = "midipix";
|
|
|
46ea99 |
else if ((slash && !strcmp(slash,"-mingw")) || strstr(machine,"-mingw-"))
|
|
|
46ea99 |
host->flavor = "mingw";
|
|
|
46ea99 |
else if ((slash && !strcmp(slash,"-mingw32")) || strstr(machine,"-mingw32-"))
|
|
|
46ea99 |
host->flavor = "mingw";
|
|
|
46ea99 |
else if ((slash && !strcmp(slash,"-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 |
|
|
|
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 */
|
|
|
341c87 |
cctx.drvflags = SLBT_DRIVER_SHARED | SLBT_DRIVER_STATIC;
|
|
|
341c87 |
|
|
|
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;
|
|
|
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))
|
|
|
6376f0 |
cctx.tag = SLBT_WARNING_LEVEL_ALL;
|
|
|
6376f0 |
|
|
|
6376f0 |
else if (!strcmp("error",entry->arg))
|
|
|
6376f0 |
cctx.tag = SLBT_WARNING_LEVEL_ERROR;
|
|
|
6376f0 |
|
|
|
6376f0 |
else if (!strcmp("none",entry->arg))
|
|
|
6376f0 |
cctx.tag = SLBT_WARNING_LEVEL_NONE;
|
|
|
6376f0 |
break;
|
|
|
40fabb |
|
|
|
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 |
|
|
|
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 |
|
|
|
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 |
|
|
|
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)
|
|
|
46ea99 |
|| (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;
|
|
|
46ea99 |
}
|
|
|
46ea99 |
|
|
|
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 |
|
|
|
46ea99 |
if (ictx->ctx.host.host)
|
|
|
46ea99 |
free(ictx->ctx.host.host);
|
|
|
46ea99 |
|
|
|
46ea99 |
if (ictx->ctx.host.flavor)
|
|
|
46ea99 |
free(ictx->ctx.host.flavor);
|
|
|
46ea99 |
|
|
|
46ea99 |
if (ictx->ctx.host.ar)
|
|
|
46ea99 |
free(ictx->ctx.host.ar);
|
|
|
46ea99 |
|
|
|
46ea99 |
if (ictx->ctx.host.ranlib)
|
|
|
46ea99 |
free(ictx->ctx.host.ranlib);
|
|
|
46ea99 |
|
|
|
46ea99 |
if (ictx->ctx.host.dlltool)
|
|
|
46ea99 |
free(ictx->ctx.host.dlltool);
|
|
|
46ea99 |
|
|
|
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 |
}
|