|
|
528799 |
/*******************************************************************/
|
|
|
528799 |
/* slibtool: a skinny libtool implementation, written in C */
|
|
|
528799 |
/* Copyright (C) 2016 Z. Gilboa */
|
|
|
528799 |
/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
|
|
|
528799 |
/*******************************************************************/
|
|
|
528799 |
|
|
|
528799 |
#include <stdint.h>
|
|
|
528799 |
#include <unistd.h>
|
|
|
528799 |
#include <stdlib.h>
|
|
|
528799 |
#include <string.h>
|
|
|
528799 |
|
|
|
528799 |
#include <slibtool/slibtool.h>
|
|
|
528799 |
|
|
|
528799 |
#define SLBT_ARGV_SPARE_PTRS 16
|
|
|
528799 |
|
|
|
528799 |
struct slbt_exec_ctx_impl {
|
|
|
528799 |
int argc;
|
|
|
528799 |
char * args;
|
|
|
528799 |
struct slbt_exec_ctx ctx;
|
|
|
528799 |
char * buffer[];
|
|
|
528799 |
};
|
|
|
528799 |
|
|
|
528799 |
|
|
|
528799 |
static size_t slbt_parse_comma_separated_flags(
|
|
|
528799 |
const char * str,
|
|
|
528799 |
int * argc)
|
|
|
528799 |
{
|
|
|
528799 |
const char * ch;
|
|
|
528799 |
|
|
|
528799 |
for (ch=str; *ch; ch++)
|
|
|
528799 |
if (*ch == ',')
|
|
|
528799 |
(*argc)++;
|
|
|
528799 |
|
|
|
528799 |
return ch - str;
|
|
|
528799 |
}
|
|
|
528799 |
|
|
|
528799 |
|
|
|
528799 |
static struct slbt_exec_ctx_impl * slbt_exec_ctx_alloc(
|
|
|
528799 |
const struct slbt_driver_ctx * dctx)
|
|
|
528799 |
{
|
|
|
528799 |
struct slbt_exec_ctx_impl * ictx;
|
|
|
528799 |
size_t size;
|
|
|
528799 |
int argc;
|
|
|
528799 |
char * args;
|
|
|
528799 |
char ** parg;
|
|
|
528799 |
|
|
|
528799 |
size = argc = 0;
|
|
|
528799 |
|
|
|
528799 |
/* buffer size (cargv, -Wc) */
|
|
|
528799 |
for (parg=dctx->cctx->cargv; *parg; parg++, argc++)
|
|
|
528799 |
if (!(strncmp("-Wc,",*parg,4)))
|
|
|
528799 |
size += sizeof('\0') + slbt_parse_comma_separated_flags(
|
|
|
528799 |
parg[4],&argc);
|
|
|
528799 |
else
|
|
|
528799 |
size += sizeof('\0') + strlen(*parg);
|
|
|
528799 |
|
|
|
528799 |
/* alloc */
|
|
|
528799 |
if (!(args = malloc(size + strlen(".libs/")
|
|
|
528799 |
+ strlen(".lo")
|
|
|
528799 |
+ strlen(dctx->cctx->output))))
|
|
|
528799 |
return 0;
|
|
|
528799 |
|
|
|
528799 |
size = sizeof(*ictx) + (argc+SLBT_ARGV_SPARE_PTRS)*sizeof(char *);
|
|
|
528799 |
|
|
|
528799 |
if (!(ictx = calloc(1,size))) {
|
|
|
528799 |
free(args);
|
|
|
528799 |
return 0;
|
|
|
528799 |
}
|
|
|
528799 |
|
|
|
528799 |
ictx->args = args;
|
|
|
528799 |
ictx->argc = argc;
|
|
|
528799 |
|
|
|
528799 |
return ictx;
|
|
|
528799 |
}
|
|
|
528799 |
|
|
|
528799 |
|
|
|
528799 |
int slbt_get_exec_ctx(
|
|
|
528799 |
const struct slbt_driver_ctx * dctx,
|
|
|
528799 |
struct slbt_exec_ctx ** ectx)
|
|
|
528799 |
{
|
|
|
528799 |
struct slbt_exec_ctx_impl * ictx;
|
|
|
528799 |
char ** parg;
|
|
|
528799 |
char * ch;
|
|
|
528799 |
char * slash;
|
|
|
528799 |
int i;
|
|
|
528799 |
|
|
|
528799 |
/* alloc */
|
|
|
528799 |
if (!(ictx = slbt_exec_ctx_alloc(dctx)))
|
|
|
528799 |
return -1;
|
|
|
528799 |
|
|
|
528799 |
/* init with guard for later .lo check */
|
|
|
528799 |
ch = ictx->args + strlen(".lo");
|
|
|
528799 |
ictx->ctx.argv = ictx->buffer;
|
|
|
528799 |
|
|
|
528799 |
/* <compiler> */
|
|
|
528799 |
ictx->ctx.program = dctx->cctx->cargv[0];
|
|
|
528799 |
|
|
|
528799 |
/* cargv, -Wc */
|
|
|
528799 |
for (i=0, parg=dctx->cctx->cargv; *parg; parg++, ch++) {
|
|
|
528799 |
if (!(strncmp("-Wc,",*parg,4))) {
|
|
|
528799 |
strcpy(ch,parg[4]);
|
|
|
528799 |
ictx->ctx.argv[i++] = ch;
|
|
|
528799 |
|
|
|
528799 |
for (; *ch; ch++)
|
|
|
528799 |
if (*ch == ',') {
|
|
|
528799 |
*ch = '\0';
|
|
|
528799 |
ictx->ctx.argv[i++] = ch+1;
|
|
|
528799 |
}
|
|
|
528799 |
} else {
|
|
|
528799 |
ictx->ctx.argv[i++] = ch;
|
|
|
528799 |
ch += sprintf(ch,"%s",*parg);
|
|
|
528799 |
}
|
|
|
528799 |
}
|
|
|
528799 |
|
|
|
528799 |
if (dctx->cctx->mode == SLBT_MODE_COMPILE) {
|
|
|
528799 |
if (dctx->cctx->drvflags & SLBT_DRIVER_SHARED) {
|
|
|
528799 |
ictx->ctx.argv[i++] = "-DPIC";
|
|
|
528799 |
ictx->ctx.argv[i++] = "-fPIC";
|
|
|
528799 |
}
|
|
|
528799 |
|
|
|
528799 |
ictx->ctx.argv[i++] = "-c";
|
|
|
528799 |
ictx->ctx.argv[i++] = "-o";
|
|
|
528799 |
ictx->ctx.argv[i++] = ch;
|
|
|
528799 |
|
|
|
528799 |
if ((slash = strrchr(dctx->cctx->output,'/'))) {
|
|
|
528799 |
sprintf(ch,"%s",dctx->cctx->output);
|
|
|
528799 |
ch += slash - dctx->cctx->output;
|
|
|
528799 |
ch += sprintf(ch,"/.libs%s",slash);
|
|
|
528799 |
} else
|
|
|
528799 |
ch += sprintf(ch,".libs/%s",dctx->cctx->output);
|
|
|
528799 |
|
|
|
528799 |
if ((ch[-3] == '.') && (ch[-2] == 'l') && (ch[-1] == 'o')) {
|
|
|
528799 |
ch[-2] = 'o';
|
|
|
528799 |
ch[-1] = '\0';
|
|
|
528799 |
ch--;
|
|
|
528799 |
}
|
|
|
528799 |
}
|
|
|
528799 |
|
|
|
528799 |
*ectx = &ictx->ctx;
|
|
|
528799 |
return 0;
|
|
|
528799 |
}
|
|
|
528799 |
|
|
|
528799 |
|
|
|
528799 |
static int slbt_free_exec_ctx_impl(
|
|
|
528799 |
struct slbt_exec_ctx_impl * ictx,
|
|
|
528799 |
int status)
|
|
|
528799 |
{
|
|
|
528799 |
free(ictx->args);
|
|
|
528799 |
free (ictx);
|
|
|
528799 |
return status;
|
|
|
528799 |
}
|
|
|
528799 |
|
|
|
528799 |
|
|
|
528799 |
void slbt_free_exec_ctx(struct slbt_exec_ctx * ctx)
|
|
|
528799 |
{
|
|
|
528799 |
struct slbt_exec_ctx_impl * ictx;
|
|
|
528799 |
uintptr_t addr;
|
|
|
528799 |
|
|
|
528799 |
if (ctx) {
|
|
|
528799 |
addr = (uintptr_t)ctx - offsetof(struct slbt_exec_ctx_impl,ctx);
|
|
|
528799 |
ictx = (struct slbt_exec_ctx_impl *)addr;
|
|
|
528799 |
slbt_free_exec_ctx_impl(ictx,0);
|
|
|
528799 |
}
|
|
|
528799 |
}
|