ardour/tools/linux_packaging/build
Paul Davis 72decf24cd use patchelf to reset RPATH within bundled libraries so that the runtime linker will not go looking in places set by parts of the GTK build stack
git-svn-id: svn://localhost/ardour2/branches/3.0@12521 d708f5d6-7413-0410-9779-e7cbd77b26cf
2012-06-01 13:27:38 +00:00

546 lines
14 KiB
Bash
Executable file

#!/bin/bash
# script for pulling together a Linux app bundle.
#
# This will create a bundle for a single architecture.
# Execute this scirpt on both x86 and x86_64 and then use
# package to merge the 2 bundles into a final package with the
# installer. See "noderun" for a complete build script.
# where the GTK stack is installed
GTKSTACK_ROOT=$HOME/gtk/inst
# where the Ardour dependencies are installed
ARDOURSTACK_ROOT=$HOME/a3/inst
# the waf build tree to use when copying built/generated files
BUILD_ROOT=../../build
MIXBUS=
WITH_LADSPA=0
STRIP=all
PRINT_SYSDEPS=
WITH_NLS=
EXTERNAL_JACK=
VENDOR=Ardour ;
BUILDTYPE=""
if [ $# -eq 0 ] ; then
echo ""
echo "ERROR - Please specify build type"
echo " --public"
echo " --mixbus"
echo ""
exit 1
fi
while [ $# -gt 0 ] ; do
echo "arg = $1"
case $1 in
#
# top level build targets
#
--mixbus)
MIXBUS=1;
WITH_NLS=1 ;
WITH_LADSPA=;
STRIP=all
APPNAME=Mixbus ;
VENDOR=Harrison ;
shift ;;
--public)
WITH_NLS=1 ;
WITH_LADSPA=;
STRIP=all ;
APPNAME=Ardour ;
shift ;;
--allinone)
WITH_NLS= ;
WITH_LADSPA=1;
STRIP=all;
shift ;;
--test) WITH_LADSPA=; STRIP= ; shift ;;
#
# specific build flags
#
--nojack) INTERNAL_JACK= ; shift ;;
--noladspa) WITH_LADSPA= ; shift ;;
--strip) STRIP=$2 ; shift ; shift ;;
--sysdeps) PRINT_SYSDEPS=1; shift ;;
--nls) WITH_NLS=1 ; shift ;;
*)
#catch all for unknown arguments
echo ""
echo "!!! ERROR !!! - Unknown argument $1"
echo ""
exit 1
;;
esac
done
if test x$STRIP != xall -a x$STRIP != xnone -a x$STRIP != xsome ; then
echo "Unknown strip option \"$STRIP\""
echo "Legal values are: all, none, some"
exit 1
fi
# Error out whenever possible
set -e
release_version=`grep -m 1 '^VERSION' ../../wscript | awk '{print $3}' | sed "s/'//g"`
svn_version=`grep -m 1 'svn_revision =' ../../libs/ardour/svn_revision.cc | cut -d"'" -f 2`
echo "Version is $release_version / $svn_version"
info_string="$release_version/$svn_version built on `hostname` by `whoami` on `date`"
echo "Info string is $info_string"
# Figure out our CPU type
case `uname -m` in
i[3456789]86|x86|i86pc)
echo "Architecture is x86"
ARCH='x86'
ARCH_BITS='32-bit'
;;
x86_64|amd64|AMD64)
echo "Architecture is x86_64"
ARCH='x86_64'
ARCH_BITS='64-bit'
;;
*)
echo ""
echo "ERROR - Unknown architecture `uname -m`"
echo ""
exit 1
;;
esac
# Figure out the Build Type
if grep -q "DEBUG = True" ../../build/c4che/default.cache.py; then
DEBUG="T"
else
DEBUG="F"
fi
if [ x$DEBUG = xT ]; then
BUILDTYPE="dbg"
if [ x$STRIP = xall ] ; then
echo "A debug build with --strip all makes no sense - STRIP reset to \"some\""
STRIP=some
fi
fi
# setup directory structure
if [ -z "${BUILDTYPE}" ]; then
APPDIR=${APPNAME}_${ARCH}-${release_version}_${svn_version}
APP_VER_NAME=${APPNAME}-${release_version}_${svn_version}
else
APPDIR=${APPNAME}_${ARCH}-${release_version}_${svn_version}-${BUILDTYPE}
APP_VER_NAME=${APPNAME}-${release_version}_${svn_version}-${BUILDTYPE}
fi
APPBIN=$APPDIR/bin
APPLIB=$APPDIR/lib
Libraries=$APPLIB
Etc=$APPDIR/etc
Shared=$APPDIR/share
Plugins=$APPLIB/plugins
Surfaces=$APPLIB/surfaces
Panners=$APPLIB/panners
Modules=$Libraries/modules
Loaders=$Libraries/loaders
Templates=$Shared/templates
ExportFormats=$Shared/export
Locale=$Shared/locale
MidiMaps=$Shared/midi_maps
PatchFiles=$Shared/patchfiles
MackieControl=$Shared/mcp
if [ x$PRINT_SYSDEPS != x ] ; then
#
# print system dependencies
#
for file in $APPBIN/* $Libraries/* $Modules/* $Plugins/*.so ; do
if ! file $file | grep -qs Mach-O ; then
continue
fi
otool -L $file | awk '{print $1}' | egrep -v "(^@executable_path|^Ardour[0-9][.0-9]*.app)"
done | sort | uniq
exit 0
fi
echo "Removing old $APPDIR tree ..."
rm -rf $APPDIR/
echo "Building new app directory structure ..."
# only bother to make the longest paths
mkdir -p $APPDIR
mkdir -p $APPBIN
mkdir -p $APPLIB
mkdir -p $Etc
mkdir -p $Plugins
mkdir -p $Modules
mkdir -p $Loaders
mkdir -p $Shared
mkdir -p $Locale
mkdir -p $Surfaces
mkdir -p $MidiMaps
mkdir -p $PatchFiles
mkdir -p $MackieControl
mkdir -p $ExportFormats
mkdir -p $Panners
mkdir -p $Templates
mkdir -p $Shared/templates
mkdir -p $Shared/doc
# maybe set variables
ENVIRONMENT=environment
rm -f $ENVIRONMENT
touch $ENVIRONMENT
if test x$MIXBUS != x ; then
echo export ARDOUR_MIXBUS=true >> $ENVIRONMENT
#
# current default for MIXBUS version is US keyboard layout without a keypad
#
echo export ARDOUR_KEYBOARD_LAYOUT=us-nokeypad >> $ENVIRONMENT
echo export ARDOUR_UI_CONF=ardour3_ui.conf >> $ENVIRONMENT
echo export ARDOUR3_UI_RC=ardour3_ui_dark.rc >> $ENVIRONMENT
fi
#
# if we're not going to bundle JACK, make sure we can find
# jack in the places where it might be
#
echo export 'PATH=/usr/local/bin:/opt/bin:$PATH' >> $ENVIRONMENT
# create startup helper script
sed -e "/^%ENV%/r $ENVIRONMENT" -e '/^%ENV%/d' -e 's/%VER%/'"${release_version}"'/' < ardour.sh.in > $APPBIN/ardour3
rm $ENVIRONMENT && chmod 775 $APPBIN/ardour3
# the 3.0 here is not the same as "release-version" because the latter may include "-betaN" etc.
MAIN_EXECUTABLE=ardour-3.0
echo "Copying ardour executable ...."
cp $BUILD_ROOT/gtk2_ardour/$MAIN_EXECUTABLE $APPBIN
if test x$STRIP = xall ; then
strip $APPBIN/$MAIN_EXECUTABLE
fi
# copy locale files
# note that at present(feb 2011), the .mo files end up in the source tree which is
# not really as it should be.
if test x$WITH_NLS != x ; then
echo "NLS support ..."
echo "I hope you remembered to run scons msgupdate!"
LINGUAS=
for dl in gtk2_ardour libs/ardour libs/gtkmm2ext ; do
files=`find ../../$dl -name "*.mo"`
if [ -z "$files" ]; then
echo ""
echo "!!!! WARNING !!!! - Did not find any .mo files in ../../$dl"
echo ""
fi
for file in $files
do
echo $file
lang=`basename $file | sed 's/\.mo//'`
mkdir -p $Locale/$lang/LC_MESSAGES
cp $file $Locale/$lang/LC_MESSAGES/`basename $dl`
if echo $LINGUAS | grep $lang >/dev/null 2>&1 ; then
:
else
LINGUAS="$LINGUAS $lang"
fi
done
done
GTK_MESSAGES="atk10.mo gdk-pixbuf.mo gtk20-properties.mo gtk20.mo atk10.mo glib20.mo"
LOCALEROOT=/usr/share/locale
for l in $LINGUAS ; do
echo "Copying GTK i18n files for $l..."
for MO in $GTK_MESSAGES ; do
if [ -f $LOCALEROOT/$l/LC_MESSAGES/$MO ] ; then
cp $LOCALEROOT/$l/LC_MESSAGES/$MO $Locale/$l/LC_MESSAGES
else
# try with just the language spec
just_lang=`echo $l | sed 's/_[A-Z][A-Z]$//'`
if [ -f $LOCALEROOT/$just_lang/LC_MESSAGES/$MO ] ; then
cp $LOCALEROOT/$just_lang/LC_MESSAGES/$MO $Locale/$just_lang/LC_MESSAGES
fi
fi
done
done
else
echo "Skipping NLS support"
fi
#
# Copy stuff that may be dynamically loaded
#
cp -R $GTKSTACK_ROOT/etc/* $Etc
echo "Copying all Pango modules ..."
cp -R $GTKSTACK_ROOT/lib/pango/1.6.0/modules/*.so $Modules
echo "Copying all GDK Pixbuf loaders ..."
cp -R $GTKSTACK_ROOT/lib/gdk-pixbuf-2.0/2.10.0/loaders/*.so $Loaders
# Generate a pango module file using the actual Pango that we're going to bundle
cat > pangorc <<EOF
[Pango]
ModulesPath=$GTKSTACK_ROOT/lib/pango/1.6.0/modules
EOF
env PANGO_RC_FILE=pangorc $GTKSTACK_ROOT/bin/pango-querymodules | sed "s?$GTKSTACK_ROOT/lib/pango/1.6.0/?@ROOTDIR@/?" > $Etc/pango.modules.in
rm pangorc
# Ditto for gdk-pixbuf loaders
gdk-pixbuf-query-loaders | sed "s?$GTKSTACK_ROOT/lib/gdk-pixbuf-2.0/2.10.0/?@ROOTDIR@/?" > $Etc/gdk-pixbuf.loaders.in
# We rely on clearlooks, so include a version from our own build tree
# this one is special - we will set GTK_PATH to $Libraries/clearlooks
echo "Copying clearlooks ..."
cp $BUILD_ROOT/libs/clearlooks-newer/libclearlooks.so $Libraries
mkdir -p $Libraries/clearlooks/engines
(cd $Libraries/clearlooks/engines && ln -s ../../libclearlooks.so . )
# LADSPA
if test x$WITH_LADSPA != x ; then
if test x$MIXBUS != x ; then
plugdir=mixbus_ladspa
else
plugdir=ladspa
fi
echo "Copying `ls $plugdir | wc -l` plugins ..."
if [ -d $plugdir ] ; then
cp -r $plugdir/* $Plugins
fi
fi
# Control Surfaces
cp $BUILD_ROOT/libs/surfaces/*/libardour_*.so* $Surfaces
cp $BUILD_ROOT/libs/surfaces/control_protocol/libardourcp.so* $Libraries
# MidiMaps
# got to be careful with names here
for x in $BUILD_ROOT/../midi_maps/*.map ; do
cp "$x" $MidiMaps
done
# MIDNAM Patch Files
# got to be careful with names here
for x in $BUILD_ROOT/../patchfiles/*.midnam ; do
cp "$x" $PatchFiles
done
# MackieControl data
# got to be careful with names here
for x in $BUILD_ROOT/../mcp/*.device $BUILD_ROOT/../mcp/*.profile ; do
cp "$x" $MackieControl
done
# Templates
for f in $BUILD_ROOT/../templates/* ; do
if [ -d "$f" ] ; then
echo Template: $f ; cp -r "$f" $Templates ;
fi
done
# ExportFormats
# got to be careful with names here
for x in $BUILD_ROOT/../export/*.preset $BUILD_ROOT/../export/*.format ; do
cp "$x" $ExportFormats
done
# Panners
cp $BUILD_ROOT/libs/panners/*/lib*.so* $Panners
# VAMP plugins that we use
cp $BUILD_ROOT/libs/vamp-plugins/libardourvampplugins.so* $Libraries
# Suil modules
cp $ARDOURSTACK_ROOT/lib/suil-0/lib* $Libraries
OURLIBDIR=$BUILD_ROOT/libs
OURLIBS=$OURLIBDIR/vamp-sdk:$OURLIBDIR/surfaces/control_protocol:$OURLIBDIR/ardour:$OURLIBDIR/midi++2:$OURLIBDIR/pbd:$OURLIBDIR/rubberband:$OURLIBDIR/soundtouch:$OURLIBDIR/gtkmm2ext:$OURLIBDIR/sigc++2:$OURLIBDIR/glibmm2:$OURLIBDIR/gtkmm2/atk:$OURLIBDIR/gtkmm2/pango:$OURLIBDIR/gtkmm2/gdk:$OURLIBDIR/gtkmm2/gtk:$OURLIBDIR/libgnomecanvasmm:$OURLIBDIR/libsndfile:$OURLIBDIR/evoral:$OURLIBDIR/evoral/src/libsmf:$OURLIBDIR/audiographer:$OURLIBDIR/timecode:$OURLIBDIR/taglib:$OURLIBDIR/qm-dsp
echo $OURLIBS${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
checkedIdx=0
deplibs=
while [ true ] ; do
missing=false
filelist=`find $APPLIB/ -type f`
filelist="$APPBIN/$MAIN_EXECUTABLE $filelist"
for file in $filelist ; do
if ! file $file | grep -qs ELF ; then
continue
fi
# speed this up a bit by not checking things multiple times.
for i in "${depCheckedList[@]}"; do
if [ $i == $file ]; then
continue 2
fi
done
depCheckedList[$checkIdx]=$file
checkIdx=$(($checkIdx + 1))
# do not include libjack
deps=`LD_LIBRARY_PATH=$OURLIBS${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} ldd $file | awk '{print $3}'`
echo -n "."
for dep in $deps ; do
if test "not" = ${dep}; then
echo ""
echo "!!! ERROR !!! - Missing dependant library for $file."
echo ""
(LD_LIBRARY_PATH=$OURLIBS${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} ldd $file)
echo ""
echo "!!! ERROR !!! - See Above"
exit 1
fi
# don't use anything mapped at a specific address
if echo $dep | grep -qs '0x' ; then continue; fi
# don't include /lib
if echo $dep | grep -qs "^/lib/" ; then continue; fi
# don't include jack
if echo $dep | grep -qs libjack ; then continue; fi
# don't include ALSA
if echo $dep | grep -qs libasound ; then continue; fi
# don't include any X Window libraries
if echo $dep | grep -qs libX\. ; then continue; fi
if echo $dep | grep -qs libxcb ; then continue; fi
if echo $dep | grep -qs libICE\. ; then continue; fi
if echo $dep | grep -qs libSM\. ; then continue; fi
# don't include libc
if echo $dep | grep -qs 'libc\.' ; then continue; fi
# don't include libstdc++
if echo $dep | grep -qs libstdc++ ; then continue; fi
base=`basename $dep`
if ! test -f $Libraries/$base; then
parent=$(basename ${file})
if echo $dep | grep -sq '^libs' ; then
echo "Copying dependant lib $BUILD_ROOT/$dep (required by ${parent})"
cp $BUILD_ROOT/$dep $Libraries
else
echo "Copying dependant lib $dep (required by ${parent})"
cp $dep $Libraries
fi
#
# reset RPATH so that the runtime linker never looks
# in places we don't want it to
#
patchelf --set-rpath $Libraries $Libraries/`basename $dep`
if echo $dep | grep -sq '^/' ; then
# absolute path, candidate for stripping
deplibs="$deplibs $base"
fi
missing=true
fi
done
done
if test x$missing = xfalse ; then
# everything has been found
break
fi
done
echo
# strip libraries
if test x$STRIP = xall ; then
echo Stripping all libraries
# Must be writable so that we can strip
find $APPLIB/ -name "*.so*" | xargs chmod u+w
# and strip ...
find $APPLIB/ -name "*.so*" | xargs strip
elif test x$STRIP = xsome ; then
echo Stripping dependent libraries
for l in $deplibs ; do
chmod u+w $APPLIB/$l
strip $APPLIB/$l
done
fi
find $APPLIB/ -name "*.so*" | xargs chmod a+rx
echo "Copying other stuff to $APPDIR ..."
# these are all generated by waf
#cp $BUILD_ROOT/gtk2_ardour/ergonomic-us.bindings $Etc
cp $BUILD_ROOT/gtk2_ardour/mnemonic-us.bindings $Etc
cp $BUILD_ROOT/gtk2_ardour/ardour.menus $Etc
cp $BUILD_ROOT/ardour_system.rc $Etc/ardour_system.rc
cp $BUILD_ROOT/gtk2_ardour/ardour3*.rc $Etc
# these are copied straight from the source tree
cp ../../gtk2_ardour/ardour3_ui_default.conf $Etc/ardour3_ui_default.conf
cp ../../gtk2_ardour/ardour3_ui_default.conf $Etc/ardour3_ui.conf
cp ../../instant.xml $Etc/instant.xml
cp ../../gtk2_ardour/step_editing.bindings $Etc
cp ../../gtk2_ardour/mixer.bindings $Etc
cp -r ../../gtk2_ardour/icons $Shared
cp -r ../../gtk2_ardour/pixmaps $Shared
#
# put sooper sekrit ingredients here and they will be copied
#
if [ -d specialSauce ] ; then
cp -r specialSauce $Etc
fi
# share stuff
cp -R ../../gtk2_ardour/splash.png $Shared
# go through and recursively remove any .svn dirs in the bundle
for svndir in `find $APPDIR -name .svn -type d`; do
rm -rf $svndir
done
#
# Add the uninstaller
#
sed -e "s/%REPLACE_PGM%/${APPNAME}/" -e "s/%REPLACE_VENDOR%/${VENDOR}/" -e "s/%REPLACE_VERSION%/${release_version}/" -e "s/%REPLACE_BUILD%/${svn_version}/" -e "s/%REPLACE_TYPE%/${BUILDTYPE}/" < uninstall.sh.in > $APPBIN/${APP_VER_NAME}.uninstall.sh
chmod a+x $APPBIN/${APP_VER_NAME}.uninstall.sh
#Sanity Check file
if [ -e $BUILD_ROOT/tools/sanity_check/sanityCheck ]; then
cp $BUILD_ROOT/tools/sanity_check/sanityCheck $APPBIN
else
echo "!!!ERROR !!! sanityCheck program is missing. packager will exit without being complete"
exit 1
fi
echo "Building tarball ..."
rm -f $APPDIR.tar.bz2
tar -cjf $APPDIR.tar.bz2 $APPDIR
echo "Calculating bundle size"
du -sb $APPDIR/ | awk '{print $1}' > $APPDIR.size
rm -rf $APPDIR/
echo "Done."