build-sys: gen-linkedin-loader helper script.
authorKrisztian Litkey <krisztian.litkey@intel.com>
Thu, 4 Oct 2012 06:38:56 +0000 (09:38 +0300)
committerKrisztian Litkey <krisztian.litkey@intel.com>
Fri, 26 Oct 2012 16:03:51 +0000 (19:03 +0300)
build-aux/gen-linkedin-loader [new file with mode: 0755]

diff --git a/build-aux/gen-linkedin-loader b/build-aux/gen-linkedin-loader
new file mode 100755 (executable)
index 0000000..1719dd4
--- /dev/null
@@ -0,0 +1,157 @@
+#!/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>] [-l <plugin-list>] -o <output-file>"
+    info "usage: $0 -p <plugin> -o <output-file>, or"
+    info "usage: $0 -o <output-file> <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 "void 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=""
+
+#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 -z "$PLUGIN_LIST" ]; 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"
+           ;;
+        -*)
+            error "Unknown option '$1'."
+            usage
+            ;;
+        *)
+            PLUGIN_LIST="$PLUGIN_LIST $1"
+            ;;
+    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 -z "$PLUGIN_LIST" ]; then
+    error "Neither builtin plugin nor plugin list is specified."
+    usage
+fi
+
+if [ -n "$PLUGIN" -a -n "$PLUGIN_LIST" ]; then
+    error "Both builtin plugin and plugin list are specified."
+    usage
+fi
+
+# generate the output
+rm -f $OUTPUT
+touch $OUTPUT
+if [ -n "$PLUGIN" ]; then
+    emit_plugin_loader $PLUGIN
+else
+    emit_murphy_loader $PLUGIN_LIST
+fi