1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
#!/bin/bash
# ************************************************************************** #
# BornAgain: simulate and fit reflection and scattering
#
# @file adjust_pkg_linux.sh
# @brief Extract the dependencies of shared libraries (Linux only)
#
# @homepage http://apps.jcns.fz-juelich.de/BornAgain
# @license GNU General Public License v3 or higher (see COPYING)
# @copyright Forschungszentrum Juelich GmbH 2016
# @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
# ************************************************************************** #
# usage:
# % bash adjust_pkg_linux.sh <pkg-root-dir>
# Requires `ldd` and `bash` >= 4.0.
# externally given variables
pkg_root_dir="$1"
main_exe="@LINUXPKG_MAIN_EXE@"
framework_dir="$pkg_root_dir/@LINUXPKG_FRAMEWORK_DEST@"
qt_root_dir="@Qt_DIR@"
qt_plugins_dir="@Qt_PLUGINS_DIR@"
qt_libs_dir="@Qt_LIBS_DIR@"
# constants
TITLE="Linux Package"
HELP="$TITLE: Usage: bash adjust_pkg_linux.sh <pkg-root-dir>"
# shell commands
COPY="cp -nf"
MKDIR="mkdir -p"
if [ -z $pkg_root_dir ]
then
echo "$TITLE: Error: Provide the root directory for the package."
echo "$HELP"
exit 1
fi
if [ -z $framework_dir ]
then
echo "$TITLE: Error: Provide the directory for the framework libraries."
echo "$HELP"
exit 1
fi
if [ -z $main_exe ]
then
echo "$TITLE: Error: Provide the path to the main executable."
echo "$HELP"
exit 1
fi
echo "$TITLE: package root = '$pkg_root_dir', " \
"framework dir = '$framework_dir', " \
"main executable = '$main_exe'"
# libraries allowed to be included in the package
libs_inc_re='cerf|formfactor|gsl|fftw|boost|tiff|jpeg|jbig|Qt'
# compression libraries
libs_inc_re=${libs_inc_re}'|zstd|lzma|deflate|bz2|Lerc|b2'
# secondary dependencies
# X11 interface (libQt5XcbQpa):
libs_inc_re=${libs_inc_re}'|XcbQpa|xcb-xinerama|xcb-xinput'
libs_inc_re=${libs_inc_re}'|double-conversion|icu|md4c|pcre2|svg|webp'
# extract dependency names and locations from the raw output of `ldd`
# NOTE: ldd returns all dependencies recursively.
# ldd output example:
# ```
# libgsl.so.25 => /lib/x86_64-linux-gnu/libgsl.so.25 (0x7f764fd5b)
# ```
libname_re='[[:alnum:]_.-]+'
libpath_re='[[:alnum:]_./-]+'
ldd_re='.*lib('$libs_inc_re')('$libname_re')\s*=>\s*('$libpath_re')\s.*'
declare -r KVFS='<~>' # separator token for key and value
# associated array to hold the dependencies {library so-name => full path}
declare -A deps_all
deps_kv_re='s/'$ldd_re'/lib\1\2'$KVFS'\3/p'
# extract all the dependencies from the main executable
deps=$(ldd $main_exe)
#-- Qt extra dependencies
# obtain Qt major version
# eg. `/lib/x86_64-linux-gnu/libQt5Core.so.5.1.12` => `5`
qt_version=$(echo "$deps" | sed -nE 's;.+ =>[[:blank:]]*.+/libQt.+\.so\.([1-9]).+;\1;p' | head -n1)
#-- Qt for X11 requirements
# see <https://doc.qt.io/qt-5/linux-requirements.html>
# NOTE: xcb Qt platform abstraction: provides the basic functionality needed by
# Qt GUI and Qt Widgets to run against X11
# NOTE: Run the GUI with flag `QT_DEBUG_PLUGINS=1` to obtain the plugins
platforms="libqxcb.so"
imageformats="libqgif.so libqico.so libqjpeg.so libqsvg.so"
xcbglintegrations="libqxcb-egl-integration.so libqxcb-glx-integration.so"
# add extra dependencies from the Qt platforms plugin
deps="$deps\n"$(ldd "$qt_plugins_dir/platforms/libqxcb.so")
for plg in $imageformats; do
deps="$deps\n"$(ldd "$qt_plugins_dir/imageformats/$plg")
done
echo "$TITLE: Qt root dir = '$qt_root_dir'"
echo "$TITLE: Qt major version = '$qt_version'"
echo "$TITLE: Qt plugins dir = '$qt_plugins_dir'"
# collect all the package dependencies (discard duplicates)
deps=$(echo "$deps" | sed -nE $deps_kv_re)
for key_val in $deps; do
# use 'parameter expansion' to extract the key and value
# strip the given pattern from back of the variable (longest match);
# eg. `K;V` => `K`
key="${key_val%%$KVFS*}"
# strip the given pattern from front of the variable (longest match);
# eg. `K;V` => `V`
value="${key_val##*$KVFS}"
deps_all[$key]="$value"
done
echo "$TITLE: External dependencies:"
for xlib in ${!deps_all[@]}; do
xlibpath=${deps_all[$xlib]}
echo " + $xlib => $xlibpath"
done
# copy external libraries to the corresponding directory
echo "$TITLE: Copying external libraries to '$xlibdir'..."
$MKDIR $framework_dir
for xlib in "${!deps_all[@]}"; do
xlibpath="${deps_all[$xlib]}"
# NOTE: The final name must be the so-name of the library
$COPY "$xlibpath" "$framework_dir/$xlib"
done
echo "$TITLE: External libraries in '$framework_dir':"
for lib in $framework_dir/*.so*; do
echo " + ${lib##*/}"
done
# copy required Qt plugins to the corresponding directory
pkg_plugins_dir="$pkg_root_dir/plugins"
echo "$TITLE: Copying Qt plugins from '$qt_plugins_dir' to '$pkg_plugins_dir'..."
# platform plugins
dst="$pkg_plugins_dir/platforms"
$MKDIR "$dst"
for plg in $platforms; do
$COPY "$qt_plugins_dir/platforms/$plg" "$dst/$plg"
done
# xcb-GL integrations
dst="$pkg_plugins_dir/xcbglintegrations"
$MKDIR "$dst"
for plg in $xcbglintegrations; do
$COPY "$qt_plugins_dir/xcbglintegrations/$plg" "$dst/$plg"
done
# image formats
dst="$pkg_plugins_dir/imageformats"
$MKDIR "$dst"
for plg in $imageformats; do
$COPY "$qt_plugins_dir/imageformats/$plg" "$dst/$plg"
done
# final message
echo "$TITLE: Done."
|