Blame src/internal/slibtool_libmeta_impl.c

a9cfe4
/*******************************************************************/
a9cfe4
/*  slibtool: a skinny libtool implementation, written in C        */
49181b
/*  Copyright (C) 2016--2024  SysDeer Technologies, LLC            */
a9cfe4
/*  Released under the Standard MIT License; see COPYING.SLIBTOOL. */
a9cfe4
/*******************************************************************/
a9cfe4
a53a8b
#include <fcntl.h>
a9cfe4
#include <stdio.h>
Sebastian Wiedenroth ec296a
#include <string.h>
a9cfe4
#include <stdbool.h>
a9cfe4
#include <slibtool/slibtool.h>
5fac6c
#include "slibtool_driver_impl.h"
a53a8b
#include "slibtool_dprintf_impl.h"
08246d
#include "slibtool_errinfo_impl.h"
a9cfe4
#include "slibtool_metafile_impl.h"
4b56de
#include "slibtool_visibility_impl.h"
a9cfe4
a9cfe4
static int  slbt_create_default_library_wrapper(
a9cfe4
	const struct slbt_driver_ctx *	dctx,
a9cfe4
	struct slbt_exec_ctx *		ectx,
a9cfe4
	char *				arname,
a9cfe4
	char *				soname,
a9cfe4
	char *				soxyz,
a9cfe4
	char *				solnk)
a9cfe4
{
a9cfe4
	int					ret;
a53a8b
	int					fdout;
a9cfe4
	const char *				header;
a9cfe4
	const char *				base;
a9cfe4
	bool					fnover;
a9cfe4
	bool					fvernum;
a9cfe4
	int					current;
a9cfe4
	int					revision;
a9cfe4
	int					age;
a9cfe4
	const struct slbt_source_version *	verinfo;
a9cfe4
a9cfe4
	(void)ectx;
a9cfe4
a9cfe4
	/* create */
a53a8b
	if ((fdout = openat(
5fac6c
			slbt_driver_fdcwd(dctx),
a53a8b
			dctx->cctx->output,
a53a8b
			O_RDWR|O_CREAT|O_TRUNC,
a53a8b
			0644)) < 0)
6beda1
		return SLBT_SYSTEM_ERROR(dctx,dctx->cctx->output);
a9cfe4
a9cfe4
	/* version info */
a9cfe4
	current  = 0;
a9cfe4
	age      = 0;
a9cfe4
	revision = 0;
a9cfe4
a9cfe4
	if (dctx->cctx->verinfo.verinfo)
a9cfe4
		sscanf(dctx->cctx->verinfo.verinfo,"%d:%d:%d",
a9cfe4
			&current,&revision,&age;;
a9cfe4
a9cfe4
	fnover  = !!(dctx->cctx->drvflags & SLBT_DRIVER_AVOID_VERSION);
a9cfe4
	fvernum = !!(dctx->cctx->verinfo.vernumber);
a9cfe4
	verinfo = slbt_source_version();
a9cfe4
a9cfe4
	/* wrapper header */
a9cfe4
	header = "libtool compatible library wrapper\n";
a9cfe4
	base   = "";
a9cfe4
a9cfe4
	/* wrapper content */
a53a8b
	ret = slbt_dprintf(fdout,
a9cfe4
		"# %s%s"
a9cfe4
		"# Generated by %s (slibtool %d.%d.%d)\n"
a9cfe4
		"# [commit reference: %s]\n\n"
a9cfe4
a9cfe4
		"dlname='%s'\n"
a9cfe4
		"library_names='%s %s %s'\n"
a9cfe4
		"old_library='%s'\n\n"
a9cfe4
a9cfe4
		"inherited_linker_flags='%s'\n"
a9cfe4
		"dependency_libs='%s'\n"
a9cfe4
		"weak_library_names='%s'\n\n"
a9cfe4
a9cfe4
		"current=%d\n"
a9cfe4
		"age=%d\n"
a9cfe4
		"revision=%d\n\n"
a9cfe4
a9cfe4
		"installed=%s\n"
a9cfe4
		"shouldnotlink=%s\n\n"
a9cfe4
a9cfe4
		"dlopen='%s'\n"
a9cfe4
		"dlpreopen='%s'\n\n"
a9cfe4
a9cfe4
		"libdir='%s'\n",
a9cfe4
a9cfe4
		/* wrapper header */
a9cfe4
		base,header,
a9cfe4
a9cfe4
		/* nickname, verinfo */
a9cfe4
		dctx->program,
a9cfe4
		verinfo->major,verinfo->minor,verinfo->revision,
a9cfe4
		verinfo->commit,
a9cfe4
a9cfe4
		/* dlname */
a9cfe4
		fnover ? solnk : soxyz,
a9cfe4
a9cfe4
		/* library_names */
a9cfe4
		fnover ? solnk : soxyz,
a9cfe4
		fnover ? solnk : soname,
a9cfe4
		solnk,
a9cfe4
a9cfe4
		/* old_library */
a9cfe4
		arname,
a9cfe4
a9cfe4
		/* inherited_linker_flags, dependency_libs, weak_library_names */
a9cfe4
		"","","",
a9cfe4
a9cfe4
		/* current, age, revision */
a9cfe4
		fvernum ? dctx->cctx->verinfo.major : current,
a9cfe4
		fvernum ? dctx->cctx->verinfo.minor : age,
a9cfe4
		fvernum ? dctx->cctx->verinfo.major : revision,
a9cfe4
a9cfe4
		/* installed, shouldnotlink */
a9cfe4
		"no","no",
a9cfe4
a9cfe4
		/* dlopen, dlpreopen */
a9cfe4
		"","",
a9cfe4
a9cfe4
		/* libdir */
a9cfe4
		dctx->cctx->rpath ? dctx->cctx->rpath : "");
a9cfe4
a53a8b
	close(fdout);
a53a8b
6beda1
	return (ret < 0) ? SLBT_SYSTEM_ERROR(dctx,0) : 0;
a9cfe4
}
a9cfe4
a9cfe4
static int  slbt_create_compatible_library_wrapper(
a9cfe4
	const struct slbt_driver_ctx *	dctx,
a9cfe4
	struct slbt_exec_ctx *		ectx,
a9cfe4
	char *				arname,
a9cfe4
	char *				soname,
a9cfe4
	char *				soxyz,
a9cfe4
	char *				solnk)
a9cfe4
{
Sebastian Wiedenroth ec296a
	int					ret;
45a19f
	int					fdout;
Sebastian Wiedenroth ec296a
	const char *				base;
Sebastian Wiedenroth ec296a
	bool					fnover;
Sebastian Wiedenroth ec296a
	bool					fvernum;
Sebastian Wiedenroth ec296a
	int					current;
Sebastian Wiedenroth ec296a
	int					revision;
Sebastian Wiedenroth ec296a
	int					age;
Sebastian Wiedenroth ec296a
	const struct slbt_source_version *	verinfo;
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
	(void)ectx;
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
	/* create */
45a19f
	if ((fdout = openat(
5fac6c
			slbt_driver_fdcwd(dctx),
45a19f
			dctx->cctx->output,
45a19f
			O_RDWR|O_CREAT|O_TRUNC,
45a19f
			0644)) < 0)
6beda1
		return SLBT_SYSTEM_ERROR(dctx,dctx->cctx->output);
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
	/* version info */
Sebastian Wiedenroth ec296a
	current  = 0;
Sebastian Wiedenroth ec296a
	age      = 0;
Sebastian Wiedenroth ec296a
	revision = 0;
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
	/* wrapper header */
Sebastian Wiedenroth ec296a
	if ((base = strrchr(dctx->cctx->output,'/'))) {
Sebastian Wiedenroth ec296a
		base++;
Sebastian Wiedenroth ec296a
	} else {
Sebastian Wiedenroth ec296a
		base = dctx->cctx->output;
Sebastian Wiedenroth ec296a
	}
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
	if (dctx->cctx->verinfo.verinfo)
Sebastian Wiedenroth ec296a
		sscanf(dctx->cctx->verinfo.verinfo,"%d:%d:%d",
Sebastian Wiedenroth ec296a
			&current,&revision,&age;;
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
	fnover  = !!(dctx->cctx->drvflags & SLBT_DRIVER_AVOID_VERSION);
Sebastian Wiedenroth ec296a
	fvernum = !!(dctx->cctx->verinfo.vernumber);
Sebastian Wiedenroth ec296a
	verinfo = slbt_source_version();
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
	/* wrapper content */
45a19f
	ret = slbt_dprintf(fdout,
Sebastian Wiedenroth ec296a
		"# %s - a libtool library file\n"
Sebastian Wiedenroth ec296a
		"# Generated by %s (slibtool %d.%d.%d)\n"
Sebastian Wiedenroth ec296a
		"# [commit reference: %s]\n"
Sebastian Wiedenroth ec296a
		"#\n"
Sebastian Wiedenroth ec296a
		"# Please DO NOT delete this file!\n"
Sebastian Wiedenroth ec296a
		"# It is necessary for linking the library.\n\n"
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		"# The name that we can dlopen(3).\n"
Sebastian Wiedenroth ec296a
		"dlname='%s'\n\n"
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		"# Names of this library.\n"
Sebastian Wiedenroth ec296a
		"library_names='%s %s %s'\n\n"
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		"# The name of the static archive.\n"
Sebastian Wiedenroth ec296a
		"old_library='%s'\n\n"
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		"# Linker flags that can not go in dependency_libs.\n"
Sebastian Wiedenroth ec296a
		"inherited_linker_flags='%s'\n\n"
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		"# Libraries that this one depends upon.\n"
Sebastian Wiedenroth ec296a
		"dependency_libs='%s'\n\n"
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		"# Names of additional weak libraries provided by this library\n"
Sebastian Wiedenroth ec296a
		"weak_library_names='%s'\n\n"
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		"# Version information for %s%s.\n"
Sebastian Wiedenroth ec296a
		"current=%d\n"
Sebastian Wiedenroth ec296a
		"age=%d\n"
Sebastian Wiedenroth ec296a
		"revision=%d\n\n"
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		"# Is this an already installed library?\n"
Sebastian Wiedenroth ec296a
		"installed=%s\n\n"
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		"# Should we warn about portability when linking against -modules?\n"
Sebastian Wiedenroth ec296a
		"shouldnotlink=%s\n\n"
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		"# Files to dlopen/dlpreopen\n"
Sebastian Wiedenroth ec296a
		"dlopen='%s'\n"
Sebastian Wiedenroth ec296a
		"dlpreopen='%s'\n\n"
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		"# Directory that this library needs to be installed in:\n"
Sebastian Wiedenroth ec296a
		"libdir='%s'\n",
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		/* wrapper header */
Sebastian Wiedenroth ec296a
		base,
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		/* nickname, verinfo */
Sebastian Wiedenroth ec296a
		dctx->program,
Sebastian Wiedenroth ec296a
		verinfo->major,verinfo->minor,verinfo->revision,
Sebastian Wiedenroth ec296a
		verinfo->commit,
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		/* dlname */
Sebastian Wiedenroth ec296a
		fnover ? solnk : soxyz,
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		/* library_names */
Sebastian Wiedenroth ec296a
		fnover ? solnk : soxyz,
Sebastian Wiedenroth ec296a
		fnover ? solnk : soname,
Sebastian Wiedenroth ec296a
		solnk,
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		/* old_library */
Sebastian Wiedenroth ec296a
		arname,
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		/* inherited_linker_flags, dependency_libs, weak_library_names */
Sebastian Wiedenroth ec296a
		"","","",
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		/* version information for */
Sebastian Wiedenroth ec296a
		(dctx->cctx->drvflags & SLBT_DRIVER_MODULE)
Sebastian Wiedenroth ec296a
		    ? "" : dctx->cctx->settings.dsoprefix,
Sebastian Wiedenroth ec296a
		dctx->cctx->libname,
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		/* current, age, revision */
Sebastian Wiedenroth ec296a
		fvernum ? dctx->cctx->verinfo.major : current,
Sebastian Wiedenroth ec296a
		fvernum ? dctx->cctx->verinfo.minor : age,
Sebastian Wiedenroth ec296a
		fvernum ? dctx->cctx->verinfo.major : revision,
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		/* installed, shouldnotlink */
Sebastian Wiedenroth ec296a
		"no","no",
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		/* dlopen, dlpreopen */
Sebastian Wiedenroth ec296a
		"","",
Sebastian Wiedenroth ec296a
Sebastian Wiedenroth ec296a
		/* libdir */
Sebastian Wiedenroth ec296a
		dctx->cctx->rpath ? dctx->cctx->rpath : "");
Sebastian Wiedenroth ec296a
45a19f
	close(fdout);
45a19f
6beda1
	return (ret < 0) ? SLBT_SYSTEM_ERROR(dctx,0) : 0;
a9cfe4
}
a9cfe4
4b56de
slbt_hidden int slbt_create_library_wrapper(
a9cfe4
	const struct slbt_driver_ctx *	dctx,
a9cfe4
	struct slbt_exec_ctx *		ectx,
a9cfe4
	char *				arname,
a9cfe4
	char *				soname,
a9cfe4
	char *				soxyz,
a9cfe4
	char *				solnk)
a9cfe4
{
a9cfe4
	if (dctx->cctx->drvflags & SLBT_DRIVER_LEGABITS)
a9cfe4
		return slbt_create_compatible_library_wrapper(
a9cfe4
			dctx,ectx,arname,soxyz,soname,solnk);
a9cfe4
	else
a9cfe4
		return slbt_create_default_library_wrapper(
a9cfe4
			dctx,ectx,arname,soxyz,soname,solnk);
a9cfe4
}