|
|
2bd749 |
/*******************************************************************/
|
|
|
2bd749 |
/* slibtool: a skinny libtool implementation, written in C */
|
|
|
2bd749 |
/* Copyright (C) 2016 Z. Gilboa */
|
|
|
2bd749 |
/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
|
|
|
2bd749 |
/*******************************************************************/
|
|
|
2bd749 |
|
|
|
2bd749 |
#include <string.h>
|
|
|
2bd749 |
#include <stdbool.h>
|
|
|
2bd749 |
#include <fcntl.h>
|
|
|
3c594d |
#include <limits.h>
|
|
|
2bd749 |
#include <errno.h>
|
|
|
2bd749 |
#include <sys/stat.h>
|
|
|
2bd749 |
|
|
|
2bd749 |
#include <slibtool/slibtool.h>
|
|
|
2bd749 |
#include "slibtool_spawn_impl.h"
|
|
|
2bd749 |
|
|
|
5cc3b3 |
/*******************************************************************/
|
|
|
5cc3b3 |
/* */
|
|
|
5cc3b3 |
/* -o <ltlib> switches input result */
|
|
|
5cc3b3 |
/* ---------- --------------------- ----- ------ */
|
|
|
5cc3b3 |
/* libfoo.a -static bar.lo libfoo.a */
|
|
|
5cc3b3 |
/* */
|
|
|
5cc3b3 |
/* ar cru libfoo.a bar.lo */
|
|
|
5cc3b3 |
/* ranlib libfoo.a */
|
|
|
5cc3b3 |
/* */
|
|
|
5cc3b3 |
/*******************************************************************/
|
|
|
5cc3b3 |
|
|
|
3c594d |
#ifndef PATH_MAX
|
|
|
3c594d |
#define PATH_MAX _XOPEN_PATH_MAX
|
|
|
3c594d |
#endif
|
|
|
3c594d |
|
|
|
5cc3b3 |
static bool slbt_adjust_input_argument(char * arg, bool fpic)
|
|
|
5cc3b3 |
{
|
|
|
5cc3b3 |
char * dot;
|
|
|
5cc3b3 |
|
|
|
5cc3b3 |
if (*arg == '-')
|
|
|
5cc3b3 |
return false;
|
|
|
5cc3b3 |
|
|
|
5cc3b3 |
if (!(dot = strrchr(arg,'.')))
|
|
|
5cc3b3 |
return false;
|
|
|
5cc3b3 |
|
|
|
5cc3b3 |
if (strcmp(dot,".lo"))
|
|
|
5cc3b3 |
return false;
|
|
|
5cc3b3 |
|
|
|
5cc3b3 |
if (fpic) {
|
|
|
5cc3b3 |
/* to do */
|
|
|
5cc3b3 |
return false;
|
|
|
5cc3b3 |
} else {
|
|
|
5cc3b3 |
dot[1] = 'o';
|
|
|
5cc3b3 |
dot[2] = '\0';
|
|
|
5cc3b3 |
return true;
|
|
|
5cc3b3 |
}
|
|
|
5cc3b3 |
}
|
|
|
5cc3b3 |
|
|
|
5cc3b3 |
static int slbt_exec_link_static_archive(
|
|
|
5cc3b3 |
const struct slbt_driver_ctx * dctx,
|
|
|
a51ace |
struct slbt_exec_ctx * ectx,
|
|
|
a51ace |
const char * arfilename)
|
|
|
5cc3b3 |
{
|
|
|
5cc3b3 |
char ** aarg;
|
|
|
5cc3b3 |
char ** parg;
|
|
|
5cc3b3 |
char * ranlib[3];
|
|
|
3c594d |
char program[PATH_MAX];
|
|
|
3c594d |
char output [PATH_MAX];
|
|
|
5cc3b3 |
|
|
|
5cc3b3 |
/* placeholders */
|
|
|
5cc3b3 |
slbt_reset_placeholders(ectx);
|
|
|
5cc3b3 |
|
|
|
5cc3b3 |
/* alternate program (ar, ranlib) */
|
|
|
5cc3b3 |
ectx->program = program;
|
|
|
5cc3b3 |
|
|
|
a51ace |
/* output */
|
|
|
a51ace |
if ((size_t)snprintf(output,sizeof(output),"%s",
|
|
|
a51ace |
arfilename) >= sizeof(output))
|
|
|
a51ace |
return -1;
|
|
|
a51ace |
|
|
|
5cc3b3 |
/* ar alternate argument vector */
|
|
|
5cc3b3 |
if ((size_t)snprintf(program,sizeof(program),"%s",
|
|
|
5cc3b3 |
dctx->cctx->host.ar) >= sizeof(program))
|
|
|
5cc3b3 |
return -1;
|
|
|
5cc3b3 |
|
|
|
5cc3b3 |
aarg = ectx->altv;
|
|
|
5cc3b3 |
*aarg++ = program;
|
|
|
5cc3b3 |
*aarg++ = "cru";
|
|
|
a51ace |
*aarg++ = output;
|
|
|
5cc3b3 |
|
|
|
5cc3b3 |
/* input argument adjustment */
|
|
|
5cc3b3 |
for (parg=ectx->cargv; *parg; parg++)
|
|
|
5cc3b3 |
if (slbt_adjust_input_argument(*parg,false))
|
|
|
5cc3b3 |
*aarg++ = *parg;
|
|
|
5cc3b3 |
|
|
|
5cc3b3 |
*aarg = 0;
|
|
|
5cc3b3 |
ectx->argv = ectx->altv;
|
|
|
5cc3b3 |
|
|
|
5cc3b3 |
/* step output */
|
|
|
5cc3b3 |
if (!(dctx->cctx->drvflags & SLBT_DRIVER_SILENT))
|
|
|
5cc3b3 |
if (slbt_output_link(dctx,ectx))
|
|
|
5cc3b3 |
return -1;
|
|
|
5cc3b3 |
|
|
|
5cc3b3 |
/* ar spawn */
|
|
|
5cc3b3 |
if ((slbt_spawn(ectx,true) < 0) || ectx->exitcode)
|
|
|
5cc3b3 |
return -1;
|
|
|
5cc3b3 |
|
|
|
5cc3b3 |
/* ranlib argv */
|
|
|
5cc3b3 |
if ((size_t)snprintf(program,sizeof(program),"%s",
|
|
|
5cc3b3 |
dctx->cctx->host.ranlib) >= sizeof(program))
|
|
|
5cc3b3 |
return -1;
|
|
|
5cc3b3 |
|
|
|
5cc3b3 |
ranlib[0] = program;
|
|
|
a51ace |
ranlib[1] = output;
|
|
|
5cc3b3 |
ranlib[2] = 0;
|
|
|
5cc3b3 |
ectx->argv = ranlib;
|
|
|
5cc3b3 |
|
|
|
5cc3b3 |
/* step output */
|
|
|
5cc3b3 |
if (!(dctx->cctx->drvflags & SLBT_DRIVER_SILENT))
|
|
|
5cc3b3 |
if (slbt_output_link(dctx,ectx))
|
|
|
5cc3b3 |
return -1;
|
|
|
5cc3b3 |
|
|
|
5cc3b3 |
/* ranlib spawn */
|
|
|
5cc3b3 |
if ((slbt_spawn(ectx,true) < 0) || ectx->exitcode)
|
|
|
5cc3b3 |
return -1;
|
|
|
5cc3b3 |
|
|
|
5cc3b3 |
return 0;
|
|
|
5cc3b3 |
}
|
|
|
5cc3b3 |
|
|
|
5cc3b3 |
|
|
|
2bd749 |
int slbt_exec_link(
|
|
|
2bd749 |
const struct slbt_driver_ctx * dctx,
|
|
|
2bd749 |
struct slbt_exec_ctx * ectx)
|
|
|
2bd749 |
{
|
|
|
2bd749 |
int ret;
|
|
|
2bd749 |
int fdlibs;
|
|
|
a51ace |
const char * output;
|
|
|
2bd749 |
char * dot;
|
|
|
2bd749 |
FILE * fout;
|
|
|
2bd749 |
struct slbt_exec_ctx * actx;
|
|
|
2bd749 |
|
|
|
2bd749 |
/* context */
|
|
|
2bd749 |
if (ectx)
|
|
|
2bd749 |
actx = 0;
|
|
|
2bd749 |
else if ((ret = slbt_get_exec_ctx(dctx,&ectx)))
|
|
|
2bd749 |
return ret;
|
|
|
2bd749 |
else
|
|
|
2bd749 |
actx = ectx;
|
|
|
2bd749 |
|
|
|
5cc3b3 |
/* output suffix */
|
|
|
a51ace |
output = dctx->cctx->output;
|
|
|
a51ace |
dot = strrchr(output,'.');
|
|
|
5cc3b3 |
|
|
|
2bd749 |
/* .libs directory */
|
|
|
2bd749 |
if (dctx->cctx->drvflags & SLBT_DRIVER_SHARED) {
|
|
|
2bd749 |
if ((fdlibs = open(ectx->ldirname,O_DIRECTORY)) >= 0)
|
|
|
2bd749 |
close(fdlibs);
|
|
|
2bd749 |
else if ((errno != ENOENT) || mkdir(ectx->ldirname,0777)) {
|
|
|
2bd749 |
slbt_free_exec_ctx(actx);
|
|
|
2bd749 |
return -1;
|
|
|
2bd749 |
}
|
|
|
2bd749 |
}
|
|
|
2bd749 |
|
|
|
5cc3b3 |
/* non-pic libfoo.a */
|
|
|
5cc3b3 |
if (dot && !strcmp(dot,".a"))
|
|
|
a51ace |
if (slbt_exec_link_static_archive(dctx,ectx,output)) {
|
|
|
5cc3b3 |
slbt_free_exec_ctx(actx);
|
|
|
5cc3b3 |
return -1;
|
|
|
5cc3b3 |
}
|
|
|
5cc3b3 |
|
|
|
2bd749 |
/* no wrapper? */
|
|
|
5cc3b3 |
if (!dot || strcmp(dot,".la")) {
|
|
|
2bd749 |
slbt_free_exec_ctx(actx);
|
|
|
2bd749 |
return 0;
|
|
|
2bd749 |
}
|
|
|
2bd749 |
|
|
|
2bd749 |
/* hey, yo, let's rap it up */
|
|
|
2bd749 |
if (!(fout = fopen(ectx->ltobjname,"w"))) {
|
|
|
2bd749 |
slbt_free_exec_ctx(actx);
|
|
|
2bd749 |
return -1;
|
|
|
2bd749 |
}
|
|
|
2bd749 |
|
|
|
2bd749 |
ret = fprintf(fout,
|
|
|
2bd749 |
"# slibtool (pre-alphe) generated file\n\n");
|
|
|
2bd749 |
|
|
|
2bd749 |
/* all done */
|
|
|
2bd749 |
fclose(fout);
|
|
|
2bd749 |
slbt_free_exec_ctx(actx);
|
|
|
2bd749 |
|
|
|
2bd749 |
return (ret > 0) ? 0 : -1;
|
|
|
2bd749 |
}
|