#!/bin/bash # Software License : # # Copyright (c) 2003-2015, The Open Effects Association Ltd. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # * Neither the name The Open Effects Association Ltd, nor the names of its # contributors may be used to endorse or promote products derived from this # software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Package all local libraries into an application or plugin bundle on OSX # # Author: Frederic Devernay # # This script copies the .so, .la and .xml files needed to redistribute a mac application # This file is strongly inspired from the osx-app.sh script from the Inkscape source code # # In the XCode project, the "Runtime search paths" of your binaries should be set to # "@loader_path/../Frameworks @loader_path/../Libraries" so that it finds libraries # and frameworks at runtime. # If using a Makefile, you should add the following flags at link time: # -Wl,-rpath,@loader_path/../Frameworks -Wl,-rpath,@loader_path/../Libraries # # References: # http://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html # http://www.dribin.org/dave/blog/archives/2009/11/15/rpath/ # env LANG=C is necessary so that sed doesn't try to interpret the binary file with a specific encoding LANG=C export LANG if [ $# != 2 ]; then echo "Usage: $0 AppName.app|Bundle.bundle Executablename" echo "moves macports and local libraries into AppName.app" exit 1 fi MACPORTS=/opt/local HOMEBREW=/brew2/local LOCAL=/usr/local # add to PATH PATH="$MACPORTS/bin:$HOMEBREW/bin:$LOCAL/bin:$PATH" if ! port help > /dev/null 2>&1; then echo "Please make sure that MacPorts is installed in /opt/local" exit 1 fi package="$1" binary="$package/Contents/MacOS/$2" libdir="Libraries" pkglib="$package/Contents/$libdir" if [ ! -x "$binary" ]; then echo "Error: $binary does not exist or is not an executable" exit 1 fi rpath=`otool -l $binary | grep -A 3 LC_RPATH |grep path|awk '{ print $2 }'` if [[ ! ("$rpath" == *"@loader_path/../Libraries"*) ]]; then echo "Error:: The runtime search path in $binary does not contain \"@loader_path/../Libraries\". Please set it in your Xcode project, or link the binary with the flags -Xlinker -rpath -Xlinker \"@loader_path/../Libraries\"" exit 1 fi # Test dirs test -d "$pkglib" || mkdir "$pkglib" test -d "$pkglib/share/" || mkdir "$pkglib/share/" LIBADD= ############################# # test if ImageMagick is used if otool -L "$binary" | fgrep libMagick > /dev/null; then # Check that ImageMagick is properly installed if ! pkg-config --modversion ImageMagick >/dev/null 2>&1; then echo "Missing ImageMagick -- please install ImageMagick ('sudo port install ImageMagick +no_x11 +universal') and try again." >&2 exit 1 fi # Update the ImageMagick path in startup script. IMAGEMAGICKVER=`pkg-config --modversion ImageMagick` IMAGEMAGICKMAJ=${IMAGEMAGICKVER%.*.*} IMAGEMAGICKLIB=`pkg-config --variable=libdir ImageMagick` IMAGEMAGICKSHARE=`pkg-config --variable=prefix ImageMagick`/share # if I get this right, sed substitutes in the exe the occurences of IMAGEMAGICKVER # into the actual value retrieved from the package. # We don't need this because we use MAGICKCORE_PACKAGE_VERSION declared in the # sed -e "s,IMAGEMAGICKVER,$IMAGEMAGICKVER,g" -i "" $pkgbin/DisparityKillerM # copy the ImageMagick libraries (.la and .so) cp -r "$IMAGEMAGICKLIB/ImageMagick-$IMAGEMAGICKVER" "$pkglib/" cp -r "$IMAGEMAGICKSHARE/ImageMagick-$IMAGEMAGICKMAJ" "$pkglib/share/" LIBADD="$LIBADD $pkglib/ImageMagick-$IMAGEMAGICKVER/modules-*/*/*.so" WITH_IMAGEMAGICK=yes fi # expand glob patterns in LIBADD LIBADD=`echo $LIBADD` # Find out the library dependencies # (i.e. $LOCAL or $MACPORTS), then loop until no changes. a=1 nfiles=0 alllibs="" endl=true while $endl; do #echo -e "\033[1mLooking for dependencies.\033[0m Round" $a libs="`otool -L $pkglib/* $LIBADD $binary 2>/dev/null | fgrep compatibility | cut -d\( -f1 | grep -e $LOCAL'\\|'$HOMEBREW'\\|'$MACPORTS | sort | uniq`" if [ -n "$libs" ]; then cp -f $libs $pkglib alllibs="`ls $alllibs $libs | sort | uniq`" fi let "a+=1" nnfiles=`ls $pkglib | wc -l` if [ $nnfiles = $nfiles ]; then endl=false else nfiles=$nnfiles fi done # all the libraries were copied, now change the names... ## We use @rpath instead of @executable_path/../$libdir because it's shorter ## than /opt/local, so it always works. The downside is that the XCode project ## has to link the binary with "Runtime search paths" set correctly ## (e.g. to "@loader_path/../Frameworks @loader_path/../Libraries" ). if [ -n "$alllibs" ]; then changes="" for l in $alllibs; do changes="$changes -change $l @rpath/`basename $l`" done for f in $pkglib/* $LIBADD "$binary"; do # avoid directories if [ -f $f ]; then if ! install_name_tool $changes $f; then echo "Error: 'install_name_tool $changes $f' failed" exit 1 fi fi done fi #if [ "$WITH_IMAGEMAGICK" = "yes" ]; then # and now, obfuscate all the default paths in dynamic libraries # and ImageMagick modules and config files # generate a pseudo-random string which has the same length as $MACPORTS RANDSTR="R7bUU6jiFvqrPy6zLVPwIC3b93R2b1RG2qD3567t8hC3b93R2b1RG2qD3567t8h" MACRAND=${RANDSTR:0:${#MACPORTS}} HOMEBREWRAND=${RANDSTR:0:${#HOMEBREW}} LOCALRAND=${RANDSTR:0:${#LOCAL}} find $pkglib -type f -exec sed -e "s@$MACPORTS@$MACRAND@g" -e "s@$HOMEBREW@$HOMEBREWRAND@g" -e "s@$LOCAL@$LOCALRAND@g" -i "" {} \; sed -e "s@$MACPORTS@$MACRAND@g" -e "s@$HOMEBREW@$HOMEBREWRAND@g" -e "s@$LOCAL@$LOCALRAND@g" -i "" "$binary" #fi