orbea / cross / slibtool

Forked from cross/slibtool 3 years ago
Clone

Blame src/logic/slbt_exec_compile.c

36de3e
/*******************************************************************/
36de3e
/*  slibtool: a skinny libtool implementation, written in C        */
36de3e
/*  Copyright (C) 2016  Z. Gilboa                                  */
36de3e
/*  Released under the Standard MIT License; see COPYING.SLIBTOOL. */
36de3e
/*******************************************************************/
36de3e
36de3e
#include <string.h>
36de3e
#include <stdbool.h>
36de3e
#include <fcntl.h>
36de3e
#include <errno.h>
36de3e
#include <sys/stat.h>
36de3e
36de3e
#include <slibtool/slibtool.h>
36de3e
#include "slibtool_spawn_impl.h"
36de3e
d117fc
static int slbt_exec_compile_remove_file(
d117fc
	const struct slbt_driver_ctx *	dctx,
d117fc
	struct slbt_exec_ctx *		ectx,
d117fc
	const char *			target)
d117fc
{
d117fc
	/* remove target (if any) */
d117fc
	if (!(unlink(target)) || (errno == ENOENT))
d117fc
		return 0;
d117fc
d117fc
	if (!(dctx->cctx->drvflags & SLBT_DRIVER_SILENT))
d117fc
		strerror(errno);
d117fc
d117fc
	return -1;
d117fc
}
d117fc
36de3e
int  slbt_exec_compile(
36de3e
	const struct slbt_driver_ctx *	dctx,
36de3e
	struct slbt_exec_ctx *		ectx)
36de3e
{
36de3e
	int			ret;
36de3e
	int			fdlibs;
36de3e
	FILE *			fout;
36de3e
	struct slbt_exec_ctx *	actx = 0;
ff55c4
	const struct slbt_source_version * verinfo;
36de3e
36de3e
	/* context */
36de3e
	if (ectx)
36de3e
		slbt_reset_placeholders(ectx);
36de3e
	else if ((ret = slbt_get_exec_ctx(dctx,&ectx)))
36de3e
		return ret;
36de3e
	else
36de3e
		actx = ectx;
36de3e
d117fc
	/* remove old .lo wrapper */
d117fc
	if (slbt_exec_compile_remove_file(dctx,ectx,ectx->ltobjname))
d117fc
		return -1;
d117fc
36de3e
	/* .libs directory */
36de3e
	if (dctx->cctx->drvflags & SLBT_DRIVER_SHARED) {
36de3e
		if ((fdlibs = open(ectx->ldirname,O_DIRECTORY)) >= 0)
36de3e
			close(fdlibs);
36de3e
		else if ((errno != ENOENT) || mkdir(ectx->ldirname,0777)) {
36de3e
			slbt_free_exec_ctx(actx);
36de3e
			return -1;
36de3e
		}
36de3e
	}
36de3e
27a8e1
	/* compile mode */
27a8e1
	ectx->program = ectx->compiler;
27a8e1
	ectx->argv    = ectx->cargv;
27a8e1
36de3e
	/* shared library object */
36de3e
	if (dctx->cctx->drvflags & SLBT_DRIVER_SHARED) {
36de3e
		if (!(dctx->cctx->drvflags & SLBT_DRIVER_ANTI_PIC)) {
36de3e
			*ectx->dpic = "-DPIC";
36de3e
			*ectx->fpic = "-fPIC";
36de3e
		}
36de3e
8b1ca1
		switch (dctx->cctx->tag) {
8b1ca1
			case SLBT_TAG_NASM:
8b1ca1
				break;
8b1ca1
8b1ca1
			default:
8b1ca1
				*ectx->cass = "-c";
8b1ca1
				break;
8b1ca1
		}
8b1ca1
36de3e
		*ectx->lout[0] = "-o";
36de3e
		*ectx->lout[1] = ectx->lobjname;
36de3e
db30c2
		if (!(dctx->cctx->drvflags & SLBT_DRIVER_SILENT)) {
db30c2
			if (slbt_output_compile(dctx,ectx)) {
db30c2
				slbt_free_exec_ctx(actx);
db30c2
				return -1;
db30c2
			}
db30c2
		}
db30c2
36de3e
		if (((ret = slbt_spawn(ectx,true)) < 0) || ectx->exitcode) {
36de3e
			slbt_free_exec_ctx(actx);
36de3e
			return -1;
36de3e
		}
36de3e
	}
36de3e
36de3e
	/* static archive object */
36de3e
	if (dctx->cctx->drvflags & SLBT_DRIVER_STATIC) {
36de3e
		slbt_reset_placeholders(ectx);
36de3e
36de3e
		if (dctx->cctx->drvflags & SLBT_DRIVER_PRO_PIC) {
36de3e
			*ectx->dpic = "-DPIC";
36de3e
			*ectx->fpic = "-fPIC";
36de3e
		}
36de3e
8b1ca1
		switch (dctx->cctx->tag) {
8b1ca1
			case SLBT_TAG_NASM:
8b1ca1
				break;
8b1ca1
8b1ca1
			default:
8b1ca1
				*ectx->cass = "-c";
8b1ca1
				break;
8b1ca1
		}
8b1ca1
36de3e
		*ectx->lout[0] = "-o";
55c95a
		*ectx->lout[1] = ectx->aobjname;
36de3e
db30c2
		if (!(dctx->cctx->drvflags & SLBT_DRIVER_SILENT)) {
db30c2
			if (slbt_output_compile(dctx,ectx)) {
db30c2
				slbt_free_exec_ctx(actx);
db30c2
				return -1;
db30c2
			}
db30c2
		}
db30c2
36de3e
		if (((ret = slbt_spawn(ectx,true)) < 0) || ectx->exitcode) {
36de3e
			slbt_free_exec_ctx(actx);
36de3e
			return -1;
36de3e
		}
36de3e
	}
36de3e
36de3e
	/* libtool object */
36de3e
	if (!(fout = fopen(ectx->ltobjname,"w"))) {
36de3e
		slbt_free_exec_ctx(actx);
36de3e
		return -1;
36de3e
	}
36de3e
ff55c4
	verinfo = slbt_source_version();
ff55c4
36de3e
	ret = fprintf(fout,
534879
		"# libtool compatible object wrapper\n"
ff55c4
		"# Generated by %s (slibtool %d.%d.%d)\n"
ff55c4
		"# [commit reference: %s]\n\n"
825728
36de3e
		"pic_object='%s'\n"
36de3e
		"non_pic_object='%s'\n",
825728
825728
		dctx->program,
ff55c4
		verinfo->major,verinfo->minor,verinfo->revision,
ff55c4
		verinfo->commit,
825728
36de3e
		(dctx->cctx->drvflags & SLBT_DRIVER_SHARED)
36de3e
			? ectx->lobjname
36de3e
			: "none",
36de3e
		(dctx->cctx->drvflags & SLBT_DRIVER_STATIC)
36de3e
			? ectx->aobjname
36de3e
			: "none");
36de3e
36de3e
	fclose(fout);
36de3e
	slbt_free_exec_ctx(actx);
36de3e
fa3d12
	return (ret > 0) ? 0 : -1;
36de3e
}