5 # script for pulling together a MacOSX app bundle.
7 GTKSTACK_ROOT=$HOME/gtk/inst
8 ARDOURSTACK_ROOT=$HOME/a3/inst
11 # where harvid and xjadeo binaries are cached
12 if test -z "$CACHEDIR" -o ! -d "$CACHEDIR"; then
25 while [ $# -gt 0 ] ; do
30 # top level build targets
37 PRODUCT_PKG_DIR=ArdourSAE ;
45 PRODUCT_PKG_DIR=MixBus;
51 PRODUCT_PKG_DIR=Ardour;
58 PRODUCT_PKG_DIR=Ardour ;
60 --test) SAE= ; WITH_LADSPA=; STRIP= ; shift ;;
63 # specific build flags
66 --noharvid) WITH_HARVID= ; shift ;;
67 --noladspa) WITH_LADSPA= ; shift ;;
68 --nostrip) STRIP= ; shift ;;
69 --sysdeps) PRINT_SYSDEPS=1; shift ;;
70 --nls) WITH_NLS=1 ; shift ;;
74 if test -z "$PRODUCT_PKG_DIR" -o -z "$APPNAME"; then
75 echo "application or product-name was not specified"
79 . ../define_versions.sh
80 echo "Version is $release_version"
81 if [ "x$commit" != "x" ] ; then
82 info_string="$release_version ($commit) built on `hostname` by `whoami` on `date`"
84 info_string="$release_version built on `hostname` by `whoami` on `date`"
86 echo "Info string is $info_string"
88 if [ x$DEBUG = xT ]; then
90 echo "Debug build, strip disabled"
92 if test x$STRIP != x ; then
93 echo "No debug build, strip enabled"
95 echo "No debug build, but strip disabled."
99 # setup directory structure
101 APPDIR=${APPNAME}.app
102 APPROOT=$APPDIR/Contents
103 Frameworks=$APPROOT/lib
104 Resources=$APPROOT/Resources
106 # Since this is OS X, don't try to distinguish between etc and shared
107 # (machine dependent and independent data) - just put everything
112 Locale=$Resources/locale
114 # Bundled Plugins live in a top level folder
116 Plugins=$APPROOT/Plugins
117 Surfaces=$Frameworks/surfaces
118 Panners=$Frameworks/panners
119 Backends=$Frameworks/backends
120 MidiMaps=$Shared/midi_maps
121 ExportFormats=$Shared/export
122 Templates=$Shared/templates
123 PatchFiles=$Shared/patchfiles
124 MackieControl=$Shared/mcp
126 if [ x$PRINT_SYSDEPS != x ] ; then
128 # print system dependencies
131 for file in $APPROOT/MacOS/* $Frameworks/* $Frameworks/modules/* $Plugins/*.so ; do
132 if ! file $file | grep -qs Mach-O ; then
135 otool -L $file | awk '{print $1}' | egrep -v "(^@executable_path|^Ardour[0-9][.0-9]*.app)"
140 echo "Removing old $APPDIR tree ..."
144 echo "Building new app directory structure ..."
146 # only bother to make the longest paths
148 mkdir -p $APPROOT/MacOS
149 mkdir -p $APPROOT/Resources
155 mkdir -p $ExportFormats
157 mkdir -p $Frameworks/modules
159 mkdir -p $MackieControl
162 # maybe set variables
164 if test x$SAE != x ; then
165 appname="Ardour3/SAE"
166 env="$env<key>ARDOUR_SAE</key><string>true</string>"
168 # current default for SAE version is German keyboard layout without a keypad
170 env="$env<key>ARDOUR_KEYBOARD_LAYOUT</key><string>de-nokeypad</string>"
171 env="$env<key>ARDOUR_UI_CONF</key><string>ardour3_ui_sae.conf</string>"
172 elif test x$MIXBUS != x ; then
173 appname="Ardour3/Mixbus"
174 env="$env<key>ARDOUR_MIXBUS</key><string>true</string>"
176 # current default for MIXBUS version is US keyboard layout without a keypad
178 env="$env<key>ARDOUR_KEYBOARD_LAYOUT</key><string>us-nokeypad</string>"
179 env="$env<key>ARDOUR_UI_CONF</key><string>ardour3_ui.conf</string>"
185 # if we're not going to bundle JACK, make sure we can find
186 # jack in the places where it might be
189 env="$env<key>PATH</key><string>/usr/local/bin:/opt/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>"
190 env="$env<key>DYLIB_FALLBACK_LIBRARY_PATH</key><string>/usr/local/lib:/opt/lib</string>"
192 env="<key>LSEnvironment</key><dict>$env<key>ARDOUR_BUNDLED</key><string>true</string></dict>"
195 sed -e "s?@ENV@?$env?g" \
196 -e "s?@VERSION@?$release_version?g" \
197 -e "s?@INFOSTRING@?$info_string?g" < Info.plist.in > Info.plist
199 sed -e "s?@APPNAME@?$appname?" \
200 -e "s?@ENV@?$env?g" \
201 -e "s?@VERSION@?$release_version?g" \
202 -e "s?@INFOSTRING@?$info_string?g" < InfoPlist.strings.in > Resources/InfoPlist.strings || exit 1
206 cp Info.plist $APPROOT
207 cp -R Resources $APPROOT
211 rm -f Resources/InfoPlist.strings
214 # if we build a bundle without jack, then
215 # make the Ardour3 executable a helper
216 # script that checks to see if JACK is
220 cp startup_script $APPROOT/MacOS/Ardour3
221 chmod 775 $APPROOT/MacOS/Ardour3
222 MAIN_EXECUTABLE=Ardour3.bin
224 echo "Copying ardour executable ...."
225 cp $BUILD_ROOT/gtk2_ardour/ardour-$release_version $APPROOT/MacOS/$MAIN_EXECUTABLE
226 if test x$SAE != x ; then
227 # cp $BUILD_ROOT/gtk2_ardour/evtest $APPROOT/MacOS/gtkevents
228 cp Ardour3-SAE.icns $Resources/appIcon.icns
229 elif test x$MIXBUS != x ; then
230 cp Mixbus.icns $Resources/appIcon.icns
232 cp Ardour3.icns $Resources/appIcon.icns
234 cp typeArdour.icns $Resources/
236 set +e # things below are not error-free (optional files etc) :(
239 if test x$WITH_NLS != x ; then
240 echo "NLS support ..."
241 echo "I hope you remembered to run waf i18n"
244 for pkg in gtk2_ardour libs/ardour libs/gtkmm2ext ; do
245 files=`find ../../$pkg -name "*.mo"`
248 # the package name is appended with a number so that
249 # it can be parallel installed during a regular install
250 # with older (and newer) versions. it is just the major
251 # number of the release (i.e. leading digits)
254 vsuffix=`echo $release_version | sed 's/^\([0-9][0-9]*\).*/\1/'`
256 if [ -z "$files" ]; then
258 echo "!!!! WARNING !!!! - Did not find any .mo files in ../../$pkg"
265 lang=`basename $file | sed 's/\.mo//'`
266 mkdir -p $Locale/$lang/LC_MESSAGES
267 cp $file $Locale/$lang/LC_MESSAGES/`basename $pkg`$vsuffix.mo
268 echo copy $file to $Locale/$lang/LC_MESSAGES/`basename $pkg`$vsuffix.mo
269 if echo $LINGUAS | grep $lang >/dev/null 2>&1 ; then
272 LINGUAS="$LINGUAS $lang"
279 if [ -d $GTKSTACK_ROOT/share/locale/$l ] ; then
280 echo "Copying GTK i18n files for $l..."
281 cp -r $GTKSTACK_ROOT/share/locale/$l $Locale
283 # try with just the language spec
284 just_lang=`echo $l | sed 's/_[A-Z][A-Z]$//'`
285 if [ -d $GTKSTACK_ROOT/share/locale/$just_lang ] ; then
286 echo "Copying GTK i18n files for $l..."
287 cp -r $GTKSTACK_ROOT/share/locale/$just_lang $Locale
292 echo "Skipping NLS support"
296 # Copy stuff that may be dynamically loaded
299 cp -R $GTKSTACK_ROOT/etc/* $Etc
300 echo "Copying all Pango modules ..."
301 cp -R $GTKSTACK_ROOT/lib/pango/1.8.0/modules/*.so $Frameworks/modules
302 echo "Copying all GDK Pixbuf loaders ..."
303 cp -R $GTKSTACK_ROOT/lib/gdk-pixbuf-2.0/2.10.0/loaders/*.so $Frameworks/modules
305 cp -R $GTKSTACK_ROOT/lib/charset.alias $Resources
307 # generate new Pango module file
310 ModulesPath=$GTKSTACK_ROOT/lib/pango/1.8.0/modules
312 env PANGO_RC_FILE=pangorc $GTKSTACK_ROOT/bin/pango-querymodules | sed "s?$GTKSTACK_ROOT/lib/pango/1.8.0/modules/?@executable_path/../lib/modules/?" > $Resources/pango.modules
315 # generate a new GDK pixbufs loaders file
316 gdk-pixbuf-query-loaders | sed "s?$GTKSTACK_ROOT/lib/gdk-pixbuf-2.0/2.10.0/loaders/?@executable_path/../lib/modules/?" > $Resources/gdk-pixbuf.loaders
318 # We rely on clearlooks, so include a version from our own build tree
319 # this one is special - we will set GTK_PATH to $Frameworks/gtkengines
321 GTK_ENGINE_DIR=$Frameworks/gtkengines/engines
322 mkdir -p $GTK_ENGINE_DIR
324 echo "Copying GTK engines ..."
325 cp $BUILD_ROOT/libs/clearlooks-newer/libclearlooks.dylib $Frameworks
326 (cd $GTK_ENGINE_DIR && ln -s ../../libclearlooks.dylib . && ln -s ../../libclearlooks.dylib libclearlooks.so)
328 cp $GTKSTACK_ROOT/lib/gtk-2.0/2.10.0/engines/libpixmap.so $Frameworks
329 (cd $GTK_ENGINE_DIR && ln -s ../../libpixmap.so)
332 if test x$WITH_LADSPA != x ; then
333 if test x$SAE != x ; then
335 elif test x$MIXBUS != x ; then
336 plugdir=mixbus_ladspa
340 if [ -d $plugdir -a "x$(ls $plugdir)" != x ] ; then
341 echo "Copying `ls $plugdir | wc -l` plugins ..."
342 cp -r $plugdir/* $Plugins
346 # Control Surface shared libraries
347 cp $BUILD_ROOT/libs/surfaces/*/libardour_*.dylib $Surfaces
348 cp $BUILD_ROOT/libs/surfaces/control_protocol/libardourcp*.dylib $Frameworks
351 cp $BUILD_ROOT/libs/panners/*/lib*.dylib $Panners
354 for backend in jack wavesaudio dummy; do
355 cp $BUILD_ROOT/libs/backends/$backend/lib*.dylib $Backends
358 # Export Formats/Presets
359 for f in $BUILD_ROOT/../export/*.preset $BUILD_ROOT/../export/*.format ; do
360 cp "$f" $ExportFormats ;
363 # Session and Route templates
364 #for f in $BUILD_ROOT/../templates/* ; do
365 # if [ -d "$f" ] ; then
366 # cp -r "$f" $Templates ;
371 # got to be careful with names here
372 for x in $BUILD_ROOT/../midi_maps/*.map ; do
377 # got to be careful with names here
378 for x in $BUILD_ROOT/../patchfiles/*.midnam ; do
383 # got to be careful with names here
384 for x in $BUILD_ROOT/../mcp/*.device $BUILD_ROOT/../mcp/*.profile ; do
385 cp "$x" $MackieControl
388 # VAMP plugins that we use
389 cp $BUILD_ROOT/libs/vamp-plugins/libardourvampplugins.dylib $Frameworks
391 # Suil modules (new dir 'build-stack')
392 if test -d $GTKSTACK_ROOT/lib/suil-0/ ; then
393 cp $GTKSTACK_ROOT/lib/suil-0/lib* $Frameworks
396 # Suil modules (old dir 'build-ardour-stack')
397 if test -d $ARDOURSTACK_ROOT/lib/suil-0/ ; then
398 cp $ARDOURSTACK_ROOT/lib/suil-0/lib* $Frameworks
401 # VST scanner app and wrapper script, if they exist
402 if test -d $BUILD_ROOT/libs/fst ; then
403 cp $BUILD_ROOT/libs/fst/ardour-vst-scanner* $Frameworks/
407 if test -f $BUILD_ROOT/libs/vfork/ardour-exec-wrapper ; then
408 mkdir -p $Frameworks/vfork
409 cp $BUILD_ROOT/libs/vfork/ardour-exec-wrapper $Frameworks/
415 for file in $APPROOT/MacOS/* $Frameworks/* $Frameworks/modules/* $Panners/*.dylib $Backends/*.dylib $Surfaces/*.dylib $Plugins/*.so ; do
416 if ! file $file | grep -qs Mach-O ; then
420 if test x$STRIP != x ; then
421 strip -u -r -arch all $file &>/dev/null
424 deps=`otool -L $file | awk '{print $1}' | egrep "($GTKSTACK_ROOT|$ARDOURSTACK_ROOT|/opt/|/local/|libs/)" | grep -v 'libjack\.'`
426 for dep in $deps ; do
428 if ! test -f $Frameworks/$base; then
429 if echo $dep | grep -sq '^libs' ; then
430 cp $BUILD_ROOT/$dep $Frameworks
438 if test x$missing = xfalse ; then
439 # everything has been found
445 echo "Copying other stuff to $APPDIR ..."
447 #cp $BUILD_ROOT/gtk2_ardour/ergonomic-us.bindings $Resources
449 cp $BUILD_ROOT/gtk2_ardour/mnemonic-us.bindings $Resources
450 cp $BUILD_ROOT/gtk2_ardour/ardour.menus $Resources
451 cp $BUILD_ROOT/gtk2_ardour/default_ui_config $Resources
452 cp $BUILD_ROOT/gtk2_ardour/clearlooks.rc $Resources
454 # Copied directly from source tree
456 cp ../../system_config $Resources/system_config
457 cp ../../instant.xml $Resources/instant.xml
458 cp ../../gtk2_ardour/step_editing.bindings $Resources
459 cp ../../gtk2_ardour/mixer.bindings $Resources
460 cp -r ../../gtk2_ardour/icons $Resources
461 cp -r ../../gtk2_ardour/pixmaps $Resources
462 cp ../../gtk2_ardour/dark.colors $Resources
463 cp -R ../../gtk2_ardour/splash.png $Shared
464 cp -R ../../gtk2_ardour/small-splash.png $Shared
465 cp -R ../../gtk2_ardour/ArdourMono.ttf $Shared
467 # go through and recursively remove any .svn dirs in the bundle
468 for svndir in `find $APPDIR -name .svn -type dir`; do
472 # install bundled LV2s to <app>/Contents/lib/LV2/
473 cp -R $BUILD_ROOT/libs/LV2 $Frameworks/
475 # lv2 core, classifications etc - TODO check if we need the complete LV2 ontology
476 if test -d $ARDOURSTACK_ROOT/lib/lv2/lv2core.lv2 ; then
477 cp -R $ARDOURSTACK_ROOT/lib/lv2/lv2core.lv2 $Frameworks/LV2/
478 elif test -d $GTKSTACK_ROOT/lib/lv2/lv2core.lv2 ; then
479 cp -R $GTKSTACK_ROOT/lib/lv2/lv2core.lv2 $Frameworks/LV2/
483 # now fix up the executables
484 echo "Fixing up executable dependency names ..."
485 executables=$MAIN_EXECUTABLE
486 if test x$SAE != x ; then
487 executables="$executables"
490 for exe in $executables; do
491 EXE=$APPROOT/MacOS/$exe
493 for lib in `otool -L $EXE | egrep "($GTKSTACK_ROOT|$ARDOURSTACK_ROOT|/opt/|/local/|libs/)" | awk '{print $1}' | grep -v 'libjack\.'` ; do
495 changes="$changes -change $lib @executable_path/../lib/$base"
497 if test "x$changes" != "x" ; then
498 install_name_tool $changes $EXE
502 echo "Fixing up library names ..."
503 # now do the same for all the libraries we include
504 for libdir in $Frameworks $Frameworks/modules $Surfaces $Panners $Backends ; do
506 libbase=`basename $libdir`
508 for dylib in $libdir/*.dylib $libdir/*.so ; do
512 if test -L $dylib ; then
516 # change all the dependencies
519 for lib in `otool -L $dylib | egrep "($GTKSTACK_ROOT|$ARDOURSTACK_ROOT|/opt/|/local/|libs/)" | awk '{print $1}' | grep -v 'libjack\.'` ; do
521 if echo $lib | grep -s libbase; then
522 changes="$changes -change $lib @executable_path/../$libbase/$base"
524 changes="$changes -change $lib @executable_path/../lib/$base"
528 if test "x$changes" != x ; then
529 if install_name_tool $changes $dylib ; then
536 # now the change what the library thinks its own name is
538 base=`basename $dylib`
539 install_name_tool -id @executable_path/../$libbase/$base $dylib
544 # and now ... the DMG
547 rm -rf $PRODUCT_PKG_DIR
548 mkdir $PRODUCT_PKG_DIR
553 if [ x$SAE != x ] ; then
557 echo "Creating SAE packaging directory"
558 mv $APPDIR $PRODUCT_PKG_DIR/Ardour3-SAE.app
559 cp HowToInstallArdourSAE.pdf "$PRODUCT_PKG_DIR/How To Install Ardour SAE.pdf"
560 cp SAE-de-keypad.pdf "$PRODUCT_PKG_DIR/Ardour SAE Shortcuts (keypad).pdf"
561 cp SAE-de-nokeypad.pdf "$PRODUCT_PKG_DIR/Ardour SAE Shortcuts.pdf"
563 elif [ x$MIXBUS != x ] ; then
567 echo "Creating Mixbus packaging directory"
568 mv $APPDIR $PRODUCT_PKG_DIR/
569 DMGBACKGROUND=dmgbgMB
572 echo "Creating $APPNAME packaging directory"
573 mv $APPDIR $PRODUCT_PKG_DIR/
577 if test x$WITH_HARVID != x ; then
578 echo "installing video tools.."
579 HARVID_VERSION=$(curl -s -S http://ardour.org/files/video-tools/harvid_version.txt)
580 XJADEO_VERSION=$(curl -s -S http://ardour.org/files/video-tools/xjadeo_version.txt)
582 echo "copying harvid and xjadeo ..."
585 rsync://ardour.org/video-tools/harvid-osx-${HARVID_VERSION}.tgz \
586 "$CACHEDIR/harvid-${MULTIARCH}-${HARVID_VERSION}.tgz"
589 rsync://ardour.org/video-tools/jadeo-${XJADEO_VERSION:1}.dmg \
590 "$CACHEDIR/jadeo-${XJADEO_VERSION:1}.dmg"
593 -C $PRODUCT_PKG_DIR/$APPROOT \
594 -f "$CACHEDIR/harvid-${MULTIARCH}-${HARVID_VERSION}.tgz" || exit 1
596 JADEO=$(hdiutil attach "$CACHEDIR/jadeo-${XJADEO_VERSION:1}.dmg" | grep Apple_HFS | grep dev/ | cut -f 3)
597 cp -r "${JADEO}/Jadeo.app" "$PRODUCT_PKG_DIR/"
598 hdiutil detach "${JADEO}"
601 YPOS=$[ $DMGWINBOTTOM - 300 ]
602 XJADEOPOS="set position of item \"Jadeo.app\" of container window to {310, ${YPOS}}"
604 DMGBACKGROUND=${DMGBACKGROUND}xj
607 echo "Building DMG ..."
609 # UC_DMG=$APPNAME-${release_version}-UC.dmg
610 # FINAL_DMG=$APPNAME-${release_version}.dmg
612 if [ x$DEBUG = xT ]; then
613 UC_DMG=$APPNAME-$release_version-dbg.dmg
615 UC_DMG=$APPNAME-$release_version.dmg
617 VOLNAME=$APPNAME-$release_version
619 MNTPATH=`mktemp -d -t ardourimg`
620 TMPDMG=`mktemp -t ardour`
621 ICNSTMP=`mktemp -t ardouricon`
623 DMGMEGABYTES=$[ `du -sk "$PRODUCT_PKG_DIR" | cut -f 1` * 1024 / 1048576 + $EXTRA_SPACE_MB ]
625 echo "DMG MB = " $DMGMEGABYTES
627 rm -f $UC_DMG "$TMPDMG" "${TMPDMG}.dmg" "$ICNSTMP"
631 TMPDMG="${TMPDMG}.dmg"
633 trap "rm -rf $MNTPATH $TMPDMG ${TMPDMG}.dmg $ICNSTMP" EXIT
635 hdiutil create -megabytes $DMGMEGABYTES "$TMPDMG"
636 DiskDevice=$(hdid -nomount "$TMPDMG" | grep Apple_HFS | cut -f 1 -d ' ')
637 newfs_hfs -v "${VOLNAME}" "${DiskDevice}"
638 mount -t hfs "${DiskDevice}" "${MNTPATH}"
640 cp -r ${PRODUCT_PKG_DIR}/* "${MNTPATH}" || exit
641 mkdir "${MNTPATH}/.background"
642 cp -vi ${DMGBACKGROUND}.png "${MNTPATH}/.background/dmgbg.png"
644 echo "setting DMG background ..."
646 if test $(sw_vers -productVersion | cut -d '.' -f 2) -lt 9; then
650 # OSX 10.9.X and later
651 DISKNAME=`basename "${MNTPATH}"`
655 tell application "Finder"
657 tell disk "${DISKNAME}"
659 set current view of container window to icon view
660 set toolbar visible of container window to false
661 set statusbar visible of container window to false
662 set the bounds of container window to {400, 200, 800, ${DMGWINBOTTOM}}
663 set theViewOptions to the icon view options of container window
664 set arrangement of theViewOptions to not arranged
665 set icon size of theViewOptions to 64
666 set background picture of theViewOptions to file ".background:dmgbg.png"
667 make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"}
668 set position of item "${APPDIR}" of container window to {90, 100}
669 set position of item "Applications" of container window to {310, 100}
675 update without registering applications
682 chmod -Rf go-w "${MNTPATH}"
686 echo "compressing Image ..."
689 umount "${DiskDevice}"
690 hdiutil eject "${DiskDevice}"
691 # Create a read-only version, use zlib compression
692 hdiutil convert -format UDZO "${TMPDMG}" -imagekey zlib-level=9 -o "${UC_DMG}"
694 echo "setting file icon ..."
696 cp ${PRODUCT_PKG_DIR}/$Resources/appIcon.icns ${ICNSTMP}.icns
697 sips -i ${ICNSTMP}.icns
698 DeRez -only icns ${ICNSTMP}.icns > ${ICNSTMP}.rsrc
699 Rez -append ${ICNSTMP}.rsrc -o "$UC_DMG"
700 SetFile -a C "$UC_DMG"
702 rm ${ICNSTMP}.icns ${ICNSTMP}.rsrc
705 echo "packaging suceeded."