Blame src/driver/slbt_link_params.c

741c4d
/*******************************************************************/
eac61a
/*  slibtool: a strong libtool implementation, written in C        */
49181b
/*  Copyright (C) 2016--2024  SysDeer Technologies, LLC            */
741c4d
/*  Released under the Standard MIT License; see COPYING.SLIBTOOL. */
741c4d
/*******************************************************************/
741c4d
741c4d
#include <stdint.h>
741c4d
#include <string.h>
741c4d
#include <unistd.h>
741c4d
#include <stdlib.h>
741c4d
#include <stdbool.h>
741c4d
741c4d
#include <slibtool/slibtool.h>
741c4d
#include "slibtool_version.h"
741c4d
#include "slibtool_driver_impl.h"
741c4d
#include "slibtool_errinfo_impl.h"
4b56de
#include "slibtool_visibility_impl.h"
741c4d
741c4d
4b56de
slbt_hidden int slbt_init_link_params(struct slbt_driver_ctx_impl * ctx)
741c4d
{
741c4d
	const char * program;
741c4d
	const char * libname;
741c4d
	const char * prefix;
741c4d
	const char * base;
741c4d
	char *       dot;
741c4d
	bool         fmodule;
741c4d
	int          fderr;
741c4d
741c4d
	fderr   = ctx->fdctx.fderr;
741c4d
	program = slbt_program_name(ctx->cctx.targv[0]);
741c4d
	libname = 0;
741c4d
	prefix  = 0;
741c4d
	fmodule = false;
741c4d
741c4d
	/* output */
741c4d
	if (!(ctx->cctx.output)) {
741c4d
		if (ctx->cctx.drvflags & SLBT_DRIVER_VERBOSITY_ERRORS)
741c4d
			slbt_dprintf(fderr,
741c4d
				"%s: error: output file must be "
741c4d
				"specified in link mode.\n",
741c4d
				program);
741c4d
		return -1;
741c4d
	}
741c4d
741c4d
	/* executable? */
741c4d
	if (!(dot = strrchr(ctx->cctx.output,'.')))
741c4d
		if (!(ctx->cctx.drvflags & SLBT_DRIVER_MODULE))
741c4d
			return 0;
741c4d
741c4d
	/* todo: archive? library? wrapper? inlined function, avoid repetition */
741c4d
	if ((base = strrchr(ctx->cctx.output,'/')))
741c4d
		base++;
741c4d
	else
741c4d
		base = ctx->cctx.output;
741c4d
741c4d
	/* archive? */
741c4d
	if (dot && !strcmp(dot,ctx->cctx.settings.arsuffix)) {
741c4d
		prefix = ctx->cctx.settings.arprefix;
741c4d
741c4d
		if (!strncmp(prefix,base,strlen(prefix)))
741c4d
			libname = base;
741c4d
		else {
741c4d
			if (ctx->cctx.drvflags & SLBT_DRIVER_VERBOSITY_ERRORS)
741c4d
				slbt_dprintf(fderr,
741c4d
					"%s: error: output file prefix does "
741c4d
					"not match its (archive) suffix; "
741c4d
					"the expected prefix was '%s'\n",
741c4d
					program,prefix);
741c4d
			return -1;
741c4d
		}
741c4d
	}
741c4d
741c4d
	/* library? */
741c4d
	else if (dot && !strcmp(dot,ctx->cctx.settings.dsosuffix)) {
741c4d
		prefix = ctx->cctx.settings.dsoprefix;
741c4d
741c4d
		if (!strncmp(prefix,base,strlen(prefix))) {
741c4d
			libname = base;
741c4d
741c4d
		} else if (ctx->cctx.drvflags & SLBT_DRIVER_MODULE) {
741c4d
			libname = base;
741c4d
			fmodule = true;
741c4d
741c4d
		} else {
741c4d
			if (ctx->cctx.drvflags & SLBT_DRIVER_VERBOSITY_ERRORS)
741c4d
				slbt_dprintf(fderr,
741c4d
					"%s: error: output file prefix does "
741c4d
					"not match its (shared library) suffix; "
741c4d
					"the expected prefix was '%s'\n",
741c4d
					program,prefix);
741c4d
			return -1;
741c4d
		}
741c4d
	}
741c4d
741c4d
	/* wrapper? */
741c4d
	else if (dot && !strcmp(dot,".la")) {
741c4d
		prefix = ctx->cctx.settings.dsoprefix;
741c4d
741c4d
		if (!strncmp(prefix,base,strlen(prefix))) {
741c4d
			libname = base;
741c4d
			fmodule = !!(ctx->cctx.drvflags & SLBT_DRIVER_MODULE);
741c4d
		} else if (ctx->cctx.drvflags & SLBT_DRIVER_MODULE) {
741c4d
			libname = base;
741c4d
			fmodule = true;
741c4d
		} else {
741c4d
			if (ctx->cctx.drvflags & SLBT_DRIVER_VERBOSITY_ERRORS)
741c4d
				slbt_dprintf(fderr,
741c4d
					"%s: error: output file prefix does "
741c4d
					"not match its (libtool wrapper) suffix; "
741c4d
					"the expected prefix was '%s'\n",
741c4d
					program,prefix);
741c4d
			return -1;
741c4d
		}
741c4d
	} else
741c4d
		return 0;
741c4d
741c4d
	/* libname alloc */
741c4d
	if (!fmodule)
741c4d
		libname += strlen(prefix);
741c4d
741c4d
	if (!(ctx->libname = strdup(libname)))
741c4d
		return -1;
741c4d
741c4d
	if ((dot  = strrchr(ctx->libname,'.')))
741c4d
		*dot = 0;
741c4d
741c4d
	ctx->cctx.libname = ctx->libname;
741c4d
741c4d
	return 0;
741c4d
}