From 80dd9390de6321ef094c213bdfa8d2835612976a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vivek=20Das=C2=A0Mohapatra?= <vivek@collabora.co.uk> Date: Mon, 17 Jul 2017 16:24:32 +0100 Subject: [PATCH] Script to automatically initialise a capsule proxy library project Also include an automake stub to make bootstrapping the project easier. --- data/capsule-init-project | 120 ++++++++++++++++++++++++++++++++++++++ data/capsule-shim.mk.in | 46 +++++++++++++++ 2 files changed, 166 insertions(+) create mode 100755 data/capsule-init-project create mode 100644 data/capsule-shim.mk.in diff --git a/data/capsule-init-project b/data/capsule-init-project new file mode 100755 index 000000000..179066d6d --- /dev/null +++ b/data/capsule-init-project @@ -0,0 +1,120 @@ +#!/bin/bash + +set -e; +set -u; + +libexec=$(dirname $0); + +target=$1; +tree=${2:-/host}; + +base=${target%%.so.*}; +base=${base%.so}; +name=${base#lib}; +lcbase=${base,,}; + +dest=${3:-$base-proxy}; +ver=0; + +read x x ver x < <($libexec/capsule-version $target $tree); + +echo Generating project for $tree : $target $ver proxy; + +echo Creating project directory $dest; + +mkdir -p "$dest"; +cd $dest; +mkdir -p shim; + +echo Working in $PWD; + +cat - <<EOF > README +This is a libcapsule based proxy library. + +Its purpose is to allow a library ($target) to be loaded from a +foreign filesystem tree ($tree) without exposing any other libraries +from that tree to the program using it. + +You can export the symbols of more than one library via the proxy: +To do so, add a line containing the bare (libFOO.so.X format) name +of each extra library to shim/lib@LIB@.so.c.shared and rebuild. + +You can also prevent a library from the foreign tree from being loaded +at all (at least as a result of being a dependency of lib@LIB@): +To achieve this, add a line containing the bare (libFOO.so.X) name +of the excluded library to shim/lib@LIB@.so.c.excluded and rebuild. + +The generated library will have the same name as the main proxy target +($target). You can control the exact version number (cf libfoo.x.y.z) +by setting CAPSULE_VERSION in Makefile.am +EOF + +echo Extracting dynamic symbols from $tree : $target; + +$libexec/capsule-symbols $target $tree > shim/$base.so.symbols; + +echo Preparing proxy source files +touch shim/$base.so.c.{shared,excluded}; + +cat - <<EOF > shim/$base.so.c.dlopen +static void *_dlopen (const char *filename, int flag) +{ + if( flag & RTLD_GLOBAL ) + { + fprintf( stderr, "Warning: libcapsule dlopen wrapper cannot pass " + "RTLD_GLOBAL to underlying dlmopen(%s...) call\\n", + filename ); + flag = (flag & ~RTLD_GLOBAL) & 0xfffff; + } + return capsule_shim_dlopen( symbol_ns, prefix, exclude, filename, flag ); +} +EOF + +echo Initialising configure.ac; + +cat - <<EOF > configure.ac +AC_INIT($lcbase-proxy, $ver) +AC_CONFIG_MACRO_DIR([m4]) + +dnl basename of the main library we are proxying for: +AC_SUBST([LIB],[$name]) + +dnl don't kvetch about gnu makefile syntax +dnl and don't require ChangeLog &co if they don't exist +AM_INIT_AUTOMAKE([-Wno-portability foreign]) +AM_SILENT_RULES([yes]) +LT_INIT + +PKG_CHECK_MODULES([CAPSULE], [capsule]) +PKG_CHECK_VAR([CAPSULE_MKINC], [capsule], [makeinc]) + +AC_CONFIG_FILES([capsule-shim.mk:\$CAPSULE_MKINC/capsule-shim.mk.in Makefile]) +AC_OUTPUT() +EOF + +echo Initialising Makefile.am; + +cat - <<EOF > Makefile.am +CAPSULE_LIBRARY := $name +CAPSULE_VERSION := $ver +CAPSULE_TREE := $tree + +include @CAPSULE_MKINC@/disabled.mk +##include capsule-shim.mk## +EOF + +echo Bootstrapping autoconf templates for $target; + +############################################################################ +# this stage generates the capsule-shim.mk from a template, which +# we need to be in place before we generate the _real_ Makefile.in: +(autoreconf -if; + ./configure; + sed -i -re 's@##(include .*)##@\1@' Makefile.am) > preconfigure.log 2>&1 +############################################################################ + +echo Running initial configuration; +autoreconf -ivf + +echo $PWD is ready for ./configure, see README for details; + diff --git a/data/capsule-shim.mk.in b/data/capsule-shim.mk.in new file mode 100644 index 000000000..f2b18454b --- /dev/null +++ b/data/capsule-shim.mk.in @@ -0,0 +1,46 @@ +V ?= 0 +AUTOMAKE_OPTIONS = subdir-objects +ACLOCAL_AMFLAGS = -I m4 +AM_CFLAGS = --std=c99 -D_GNU_SOURCE -Wall -Werror + +# locations of capsule helper files: +libexecd = $(shell pkg-config --variable=libexecdir capsule) +mkstub = $(libexecd)/capsule-mkstublib + +# capsule proxy library specific values: +symvermap = -Wl,--version-script=shim/lib@LIB@.so.map +ltver = $(subst .,:,$(CAPSULE_VERSION)) + +shim_srcs = shim/lib@LIB@.so.c +shim_base = $(basename $(shim_srcs)) +shim_once = $(foreach y,map symbols,$(foreach x,$(shim_base),$x.$y)) + +# the main target +lib_LTLIBRARIES = lib@LIB@.la + +# don't clean up the shim_once built files, we don't want to be tied to +# them at build time, we only care at project init time: +CLEANFILES = $(shim_srcs) +BUILT_SOURCES = $(shim_srcs) + +# allow stub file generation to be quiet or verbose per the value of V +GENSTUB_V1 = +GENSTUB_V0 = @echo " GENSTUB " $(subst $(word 1, $(basename $(filter shim/lib%,$^))),,$(filter shim/lib%,$^)) : $@; +GENSTUB = $(GENSTUB_V$(V)) + +# regenerate if any dependencies get updated: +shim/lib%.so.c: shim/lib%.so.c.excluded shim/lib%.so.c.dlopen shim/lib%.so.symbols + $(GENSTUB)V=$V $(mkstub) $$(basename $@ .c) $@.excluded $@.shared $@ $(ltver) + +# regenerate the exportable symbols list +shim/lib%.so.symbols: shim/lib%.so.c.shared + @(ht=$(CAPSULE_TREE); \ + (for dso in lib@LIB@.so $$(cat $<); \ + do $(libexecd)/capsule-symbols $$dso $${ht:-/host}; done > $@.tmp) && \ + mv $@.tmp $@) + +# the settings that control out actual build: +lib@LIB@_la_SOURCES = $(shim_srcs) +lib@LIB@_la_LDFLAGS = $(CAPSULE_LIBS) -version-number $(ltver) \ + $(if $(wildcard shim/lib@LIB@.so.map),$(symvermap)) +lib@LIB@_la_CFLAGS = $(AM_CFLAGS) $(CAPSULE_CFLAGS) -- GitLab