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