summaryrefslogtreecommitdiff
path: root/build-aux/gen-linkedin-loader
diff options
context:
space:
mode:
Diffstat (limited to 'build-aux/gen-linkedin-loader')
-rwxr-xr-xbuild-aux/gen-linkedin-loader163
1 files changed, 163 insertions, 0 deletions
diff --git a/build-aux/gen-linkedin-loader b/build-aux/gen-linkedin-loader
new file mode 100755
index 0000000..3bb4ed5
--- /dev/null
+++ b/build-aux/gen-linkedin-loader
@@ -0,0 +1,163 @@
+#!/bin/bash
+
+######################################################################
+# Generate helper code for making builtin DSO plugins available.
+#
+# Sometimes it is necessary to split a plugin to several source
+# files. Usually this is the case when the functionality provided
+# by the plugin is complex enough to require subdividing the plugin
+# into internal modules for the best maintainability.
+#
+# In these cases we cannot avoid making several functions and
+# variables globally available within the plugin so we cannot just
+# limit the scope of visibility by making them static. Still, we do
+# want to avoid conflicts between these symbols of different plugins.
+# To accomplish this we compile and link such plugins into shared
+# libraries (with our normal symbol visibility conventions) and then
+# link the murphy daemon against them.
+#
+# Since none of the code linked into murphy proper references
+# any of the symbols in any of these plugins without any further
+# special arrangements these plugins wouldn't be demand-loaded
+# and consequently would be unavailable when the daemon starts up.
+#
+# To overcome this every such plugin gets automatically augmented
+# by a plugin-specifig globally visible symbol and the murphy daemon
+# gets augmented by a symbol that references these plugin-specific
+# symbols. This forces the dynamic loader to load the plugins and
+# the normal builtin-plugin autoregistration mechanism takes care of
+# the rest.
+#
+# A bit too spaceship-ish, I admit... but nevertheless necessary
+# unless we want to give up the idea of builtin/linkedin plugins...
+#
+
+
+error () {
+ echo "error: $*" 1>&2
+}
+
+info () {
+ echo "$*" 1>&2
+}
+
+warning () {
+ echo "warning: $*" 1>&2
+}
+
+usage () {
+ info "usage: $0 -p <plugin> -o <output-file>, or"
+ info "usage: $0 -o <output-file> -d <plugin-list>"
+ exit ${1:-1}
+}
+
+emit () {
+ echo "$*" >> $OUTPUT
+}
+
+emit_plugin_loader () {
+ case $OUTPUT in
+ *.c) emit "int mrp_linkedin_plugin_${1//-/_}_symbol = 0;"
+ ;;
+ *.h) emit "extern int mrp_linkedin_plugin_${1//-/_}_symbol;"
+ ;;
+ esac
+}
+
+emit_murphy_loader () {
+ local _p
+
+ for _p in $*; do
+ emit "#include \"linkedin-$_p-loader.h\""
+ done
+ emit ""
+ emit "int mrp_load_linkedin_plugins(void)"
+ emit "{"
+ emit " return \\"
+ for _p in $*; do
+ emit " mrp_linkedin_plugin_${_p//-/_}_symbol + \\"
+ done
+ emit " 0;"
+ emit "}"
+}
+
+
+OUTPUT=""
+PLUGIN=""
+PLUGIN_LIST=""
+daemon=no
+
+#echo "*** $0 $* ***"
+
+# parse command line
+while [ -n "${1#-}" ]; do
+ case $1 in
+ -o)
+ if [ -z "$OUTPUT" ]; then
+ shift
+ OUTPUT="$1"
+ else
+ error "Multiple output files requested."
+ usage
+ fi
+ ;;
+ -p)
+ if [ -z "$PLUGIN" -a "$daemon" = "no" ]; then
+ shift
+ PLUGIN="$1"
+ else
+ if [ -n "$PLUGIN" ]; then
+ error "Multiple builtin plugins specified."
+ else
+ error "Both builtin plugin and plugin list specified."
+ fi
+ usage
+ fi
+ ;;
+
+ -h)
+ usage 0
+ ;;
+ -q)
+ QUIET="yes"
+ ;;
+ -d)
+ daemon=yes
+ ;;
+
+ -*)
+ error "Unknown option '$1'."
+ usage
+ ;;
+
+ *)
+ if [ "$daemon" = "yes" ]; then
+ PLUGIN_LIST="$PLUGIN_LIST $1"
+ else
+ error "Unexpected argument '$1'."
+ usage
+ fi
+ ;;
+ esac
+ shift
+done
+
+# check that we've got everything mandatory
+if [ -z "$OUTPUT" ]; then
+ error "No output file specified (use the -o option)."
+ usage
+fi
+
+if [ -z "$PLUGIN" -a "$daemon" = "no" ]; then
+ error "Neither builtin plugin nor plugin list is specified."
+ usage
+fi
+
+# generate the output
+rm -f $OUTPUT
+touch $OUTPUT
+if [ "$daemon" = "no" ]; then
+ emit_plugin_loader $PLUGIN
+else
+ emit_murphy_loader $PLUGIN_LIST
+fi