3 # script for pulling together a MacOSX app bundle.
5 GTKSTACK_ROOT=$HOME/gtk/inst
6 ARDOURSTACK_ROOT=$HOME/a3/inst
9 # where harvid and xjadeo binaries are cached
10 if test -z "$CACHEDIR" -o ! -d "$CACHEDIR"; then
23 while [ $# -gt 0 ] ; do
28 # top level build targets
35 PRODUCT_PKG_DIR=ArdourSAE ;
43 PRODUCT_PKG_DIR=MixBus;
50 PRODUCT_PKG_DIR=Ardour;
57 PRODUCT_PKG_DIR=Ardour ;
59 --test) SAE= ; WITH_LADSPA=; STRIP= ; shift ;;
62 # specific build flags
65 --noharvid) WITH_HARVID= ; shift ;;
66 --noladspa) WITH_LADSPA= ; shift ;;
67 --nostrip) STRIP= ; shift ;;
68 --sysdeps) PRINT_SYSDEPS=1; shift ;;
69 --nls) WITH_NLS=1 ; shift ;;
73 if test -z "$PRODUCT_PKG_DIR" -o -z "$APPNAME"; then
74 echo "application or product-name was not specified"
78 . ../define_versions.sh
79 echo "Version is $release_version"
80 if [ "x$commit" != "x" ] ; then
81 info_string="$release_version ($commit) built on `hostname` by `whoami` on `date`"
83 info_string="$release_version built on `hostname` by `whoami` on `date`"
85 echo "Info string is $info_string"
87 # setup directory structure
90 APPROOT=$APPDIR/Contents
91 Frameworks=$APPROOT/lib
92 Resources=$APPROOT/Resources
94 # Since this is OS X, don't try to distinguish between etc and shared
95 # (machine dependent and independent data) - just put everything
100 Locale=$Resources/locale
102 # Bundled Plugins live in a top level folder
104 Plugins=$APPROOT/Plugins
105 Surfaces=$Frameworks/surfaces
106 Panners=$Frameworks/panners
107 Backends=$Frameworks/backends
108 MidiMaps=$Shared/midi_maps
109 ExportFormats=$Shared/export
110 Templates=$Shared/templates
111 PatchFiles=$Shared/patchfiles
112 MackieControl=$Shared/mcp
113 VFork=$Frameworks/vfork
115 if [ x$PRINT_SYSDEPS != x ] ; then
117 # print system dependencies
120 for file in $APPROOT/MacOS/* $Frameworks/* $Frameworks/modules/* $Plugins/*.so ; do
121 if ! file $file | grep -qs Mach-O ; then
124 otool -L $file | awk '{print $1}' | egrep -v "(^@executable_path|^Ardour[0-9][.0-9]*.app)"
129 echo "Removing old $APPDIR tree ..."
133 echo "Building new app directory structure ..."
135 # only bother to make the longest paths
137 mkdir -p $APPROOT/MacOS
138 mkdir -p $APPROOT/Resources
144 mkdir -p $ExportFormats
146 mkdir -p $Frameworks/modules
148 mkdir -p $MackieControl
152 # maybe set variables
154 if test x$SAE != x ; then
155 appname="Ardour3/SAE"
156 env="$env<key>ARDOUR_SAE</key><string>true</string>"
158 # current default for SAE version is German keyboard layout without a keypad
160 env="$env<key>ARDOUR_KEYBOARD_LAYOUT</key><string>de-nokeypad</string>"
161 env="$env<key>ARDOUR_UI_CONF</key><string>ardour3_ui_sae.conf</string>"
162 env="$env<key>ARDOUR3_UI_RC</key><string>ardour3_ui_dark_sae.rc</string>"
163 elif test x$MIXBUS != x ; then
164 appname="Ardour3/Mixbus"
165 env="$env<key>ARDOUR_MIXBUS</key><string>true</string>"
167 # current default for MIXBUS version is US keyboard layout without a keypad
169 env="$env<key>ARDOUR_KEYBOARD_LAYOUT</key><string>us-nokeypad</string>"
170 env="$env<key>ARDOUR_UI_CONF</key><string>ardour3_ui.conf</string>"
171 env="$env<key>ARDOUR3_UI_RC</key><string>ardour3_ui_dark.rc</string>"
177 # if we're not going to bundle JACK, make sure we can find
178 # jack in the places where it might be
181 env="$env<key>PATH</key><string>/usr/local/bin:/opt/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>"
182 env="$env<key>DYLIB_FALLBACK_LIBRARY_PATH</key><string>/usr/local/lib:/opt/lib</string>"
184 env="<key>LSEnvironment</key><dict>$env<key>ARDOUR_BUNDLED</key><string>true</string></dict>"
187 sed -e "s?@ENV@?$env?g" \
188 -e "s?@VERSION@?$release_version?g" \
189 -e "s?@INFOSTRING@?$info_string?g" < Info.plist.in > Info.plist
191 sed -e "s?@APPNAME@?$appname?" \
192 -e "s?@ENV@?$env?g" \
193 -e "s?@VERSION@?$release_version?g" \
194 -e "s?@INFOSTRING@?$info_string?g" < InfoPlist.strings.in > Resources/InfoPlist.strings || exit 1
198 cp Info.plist $APPROOT
199 cp -R Resources $APPROOT
203 rm -f Resources/InfoPlist.strings
206 # if we build a bundle without jack, then
207 # make the Ardour3 executable a helper
208 # script that checks to see if JACK is
212 cp startup_script $APPROOT/MacOS/Ardour3
213 chmod 775 $APPROOT/MacOS/Ardour3
214 MAIN_EXECUTABLE=Ardour3.bin
216 echo "Copying ardour executable ...."
217 cp $BUILD_ROOT/gtk2_ardour/ardour-$release_version $APPROOT/MacOS/$MAIN_EXECUTABLE
218 if test x$SAE != x ; then
219 # cp $BUILD_ROOT/gtk2_ardour/evtest $APPROOT/MacOS/gtkevents
220 cp Ardour3-SAE.icns $Resources/appIcon.icns
221 elif test x$MIXBUS != x ; then
222 cp Mixbus.icns $Resources/appIcon.icns
224 cp Ardour3.icns $Resources/appIcon.icns
226 cp typeArdour.icns $Resources/
227 if test x$STRIP != x ; then
228 strip $APPROOT/MacOS/Ardour3
232 if test x$WITH_NLS != x ; then
233 echo "NLS support ..."
234 echo "I hope you remembered to run waf i18n"
237 for pkg in gtk2_ardour libs/ardour libs/gtkmm2ext ; do
238 files=`find ../../$pkg -name "*.mo"`
241 # the package name is appended with a number so that
242 # it can be parallel installed during a regular install
243 # with older (and newer) versions. it is just the major
244 # number of the release (i.e. leading digits)
247 vsuffix=`echo $release_version | sed 's/^\([0-9][0-9]*\).*/\1/'`
249 if [ -z "$files" ]; then
251 echo "!!!! WARNING !!!! - Did not find any .mo files in ../../$pkg"
258 lang=`basename $file | sed 's/\.mo//'`
259 mkdir -p $Locale/$lang/LC_MESSAGES
260 cp $file $Locale/$lang/LC_MESSAGES/`basename $pkg`$vsuffix.mo
261 echo copy $file to $Locale/$lang/LC_MESSAGES/`basename $pkg`$vsuffix.mo
262 if echo $LINGUAS | grep $lang >/dev/null 2>&1 ; then
265 LINGUAS="$LINGUAS $lang"
272 if [ -d $GTKSTACK_ROOT/share/locale/$l ] ; then
273 echo "Copying GTK i18n files for $l..."
274 cp -r $GTKSTACK_ROOT/share/locale/$l $Locale
276 # try with just the language spec
277 just_lang=`echo $l | sed 's/_[A-Z][A-Z]$//'`
278 if [ -d $GTKSTACK_ROOT/share/locale/$just_lang ] ; then
279 echo "Copying GTK i18n files for $l..."
280 cp -r $GTKSTACK_ROOT/share/locale/$just_lang $Locale
285 echo "Skipping NLS support"
289 # Copy stuff that may be dynamically loaded
292 cp -R $GTKSTACK_ROOT/etc/* $Etc
293 echo "Copying all Pango modules ..."
294 cp -R $GTKSTACK_ROOT/lib/pango/1.8.0/modules/*.so $Frameworks/modules
295 echo "Copying all GDK Pixbuf loaders ..."
296 cp -R $GTKSTACK_ROOT/lib/gdk-pixbuf-2.0/2.10.0/loaders/*.so $Frameworks/modules
298 cp -R $GTKSTACK_ROOT/lib/charset.alias $Resources
300 # generate new Pango module file
303 ModulesPath=$GTKSTACK_ROOT/lib/pango/1.8.0/modules
305 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
308 # generate a new GDK pixbufs loaders file
309 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
311 # We rely on clearlooks, so include a version from our own build tree
312 # this one is special - we will set GTK_PATH to $Frameworks/gtkengines
314 GTK_ENGINE_DIR=$Frameworks/gtkengines/engines
315 mkdir -p $GTK_ENGINE_DIR
317 echo "Copying GTK engines ..."
318 cp $BUILD_ROOT/libs/clearlooks-newer/libclearlooks.dylib $Frameworks
319 (cd $GTK_ENGINE_DIR && ln -s ../../libclearlooks.dylib . && ln -s ../../libclearlooks.dylib libclearlooks.so)
321 cp $GTKSTACK_ROOT/lib/gtk-2.0/2.10.0/engines/libpixmap.so $Frameworks
322 (cd $GTK_ENGINE_DIR && ln -s ../../libpixmap.so)
325 if test x$WITH_LADSPA != x ; then
326 if test x$SAE != x ; then
328 elif test x$MIXBUS != x ; then
329 plugdir=mixbus_ladspa
333 if [ -d $plugdir -a "x$(ls $plugdir)" != x ] ; then
334 echo "Copying `ls $plugdir | wc -l` plugins ..."
335 cp -r $plugdir/* $Plugins
339 # Control Surface shared libraries
340 cp $BUILD_ROOT/libs/surfaces/*/libardour_*.dylib $Surfaces
341 cp $BUILD_ROOT/libs/surfaces/control_protocol/libardourcp*.dylib $Frameworks
344 cp $BUILD_ROOT/libs/panners/*/lib*.dylib $Panners
347 for backend in jack wavesaudio dummy; do
348 cp $BUILD_ROOT/libs/backends/$backend/lib*.dylib $Backends
351 # Export Formats/Presets
352 for f in $BUILD_ROOT/../export/*.preset $BUILD_ROOT/../export/*.format ; do
353 cp "$f" $ExportFormats ;
356 # Session and Route templates
357 #for f in $BUILD_ROOT/../templates/* ; do
358 # if [ -d "$f" ] ; then
359 # cp -r "$f" $Templates ;
364 # got to be careful with names here
365 for x in $BUILD_ROOT/../midi_maps/*.map ; do
370 # got to be careful with names here
371 for x in $BUILD_ROOT/../patchfiles/*.midnam ; do
376 # got to be careful with names here
377 for x in $BUILD_ROOT/../mcp/*.device $BUILD_ROOT/../mcp/*.profile ; do
378 cp "$x" $MackieControl
381 # VAMP plugins that we use
382 cp $BUILD_ROOT/libs/vamp-plugins/libardourvampplugins.dylib $Frameworks
384 # Suil modules (new dir 'build-stack')
385 if test -d $GTKSTACK_ROOT/lib/suil-0/ ; then
386 cp $GTKSTACK_ROOT/lib/suil-0/lib* $Frameworks
389 # Suil modules (old dir 'build-ardour-stack')
390 if test -d $ARDOURSTACK_ROOT/lib/suil-0/ ; then
391 cp $ARDOURSTACK_ROOT/lib/suil-0/lib* $Frameworks
394 # VST scanner app and wrapper script, if they exist
395 if test -d $BUILD_ROOT/libs/fst ; then
396 cp $BUILD_ROOT/libs/fst/ardour-vst-scanner* $Frameworks/ || true
400 if test -f $BUILD_ROOT/libs/vfork/ardour-exec-wrapper ; then
401 mkdir -p $Frameworks/vfork
402 cp $BUILD_ROOT/libs/vfork/ardour-exec-wrapper $VFork
408 for file in $APPROOT/MacOS/* $Frameworks/* $Frameworks/modules/* $Panners/*.dylib $Backends/*.dylib $Surfaces/*.dylib $Plugins/*.so ; do
409 if ! file $file | grep -qs Mach-O ; then
412 deps=`otool -L $file | awk '{print $1}' | egrep "($GTKSTACK_ROOT|$ARDOURSTACK_ROOT|/opt/|/local/|libs/)" | grep -v 'libjack\.'`
414 for dep in $deps ; do
416 if ! test -f $Frameworks/$base; then
417 if echo $dep | grep -sq '^libs' ; then
418 cp $BUILD_ROOT/$dep $Frameworks
426 if test x$missing = xfalse ; then
427 # everything has been found
433 echo "Copying other stuff to $APPDIR ..."
435 #cp $BUILD_ROOT/gtk2_ardour/ergonomic-us.bindings $Resources
437 cp $BUILD_ROOT/gtk2_ardour/mnemonic-us.bindings $Resources
438 cp ../../gtk2_ardour/mixer.bindings $Resources
439 cp ../../gtk2_ardour/step_editing.bindings $Resources
440 cp $BUILD_ROOT/gtk2_ardour/ardour.menus $Resources
442 if test x$SAE != x ; then
443 cp $BUILD_ROOT/gtk2_ardour/SAE-de-keypad.bindings $Resources
444 cp $BUILD_ROOT/gtk2_ardour/SAE-de-nokeypad.bindings $Resources
445 cp $BUILD_ROOT/gtk2_ardour/SAE-us-keypad.bindings $Resources
446 cp $BUILD_ROOT/gtk2_ardour/SAE-us-nokeypad.bindings $Resources
447 cp $BUILD_ROOT/instant.xml.sae $Resources/instant.xml
448 echo cp $BUILD_ROOT/instant.xml.sae $Resources/instant.xml
450 cp ../../system_config $Resources/system_config
451 cp ../../instant.xml $Resources/instant.xml
452 echo cp ../../instant.xml $Resources/instant.xml
454 cp $BUILD_ROOT/gtk2_ardour/default_ui_config $Resources
455 cp $BUILD_ROOT/gtk2_ardour/dark_fonts.rc $Resources
456 cp $BUILD_ROOT/gtk2_ardour/dark_styles.rc $Resources
457 cp $BUILD_ROOT/gtk2_ardour/light_fonts.rc $Resources
458 cp $BUILD_ROOT/gtk2_ardour/light_styles.rc $Resources
459 cp $BUILD_ROOT/gtk2_ardour/ui_dark.rc $Resources
460 cp $BUILD_ROOT/gtk2_ardour/ui_light.rc $Resources
461 cp $BUILD_ROOT/gtk2_ardour/widgets.rc $Resources
463 cp -r ../../gtk2_ardour/icons $Resources
464 cp -r ../../gtk2_ardour/pixmaps $Resources
467 cp -R ../../gtk2_ardour/splash.png $Shared
468 cp -R ../../gtk2_ardour/small-splash.png $Shared
469 cp -R ../../gtk2_ardour/ArdourMono.ttf $Shared
471 # go through and recursively remove any .svn dirs in the bundle
472 for svndir in `find $APPDIR -name .svn -type dir`; do
476 # install bundled LV2s to <app>/Contents/lib/LV2/
477 cp -R $BUILD_ROOT/libs/LV2 $Frameworks/
479 # now fix up the executables
480 echo "Fixing up executable dependency names ..."
481 executables=$MAIN_EXECUTABLE
482 if test x$SAE != x ; then
483 executables="$executables"
486 for exe in $executables; do
487 EXE=$APPROOT/MacOS/$exe
489 for lib in `otool -L $EXE | egrep "($GTKSTACK_ROOT|$ARDOURSTACK_ROOT|/opt/|/local/|libs/)" | awk '{print $1}' | grep -v 'libjack\.'` ; do
491 changes="$changes -change $lib @executable_path/../lib/$base"
493 if test "x$changes" != "x" ; then
494 install_name_tool $changes $EXE
498 echo "Fixing up library names ..."
499 # now do the same for all the libraries we include
500 for libdir in $Frameworks $Frameworks/modules $Surfaces $Panners $Backends ; do
502 libbase=`basename $libdir`
504 for dylib in $libdir/*.dylib $libdir/*.so ; do
508 if test -L $dylib ; then
512 # change all the dependencies
515 for lib in `otool -L $dylib | egrep "($GTKSTACK_ROOT|$ARDOURSTACK_ROOT|/opt/|/local/|libs/)" | awk '{print $1}' | grep -v 'libjack\.'` ; do
517 if echo $lib | grep -s libbase; then
518 changes="$changes -change $lib @executable_path/../$libbase/$base"
520 changes="$changes -change $lib @executable_path/../lib/$base"
524 if test "x$changes" != x ; then
525 if install_name_tool $changes $dylib ; then
532 # now the change what the library thinks its own name is
534 base=`basename $dylib`
535 install_name_tool -id @executable_path/../$libbase/$base $dylib
540 # and now ... the DMG
543 rm -rf $PRODUCT_PKG_DIR
544 mkdir $PRODUCT_PKG_DIR
547 DMGBACKGROUND=dmgbg.png
549 if [ x$SAE != x ] ; then
553 echo "Creating SAE packaging directory"
554 mv $APPDIR $PRODUCT_PKG_DIR/Ardour3-SAE.app
555 cp HowToInstallArdourSAE.pdf "$PRODUCT_PKG_DIR/How To Install Ardour SAE.pdf"
556 cp SAE-de-keypad.pdf "$PRODUCT_PKG_DIR/Ardour SAE Shortcuts (keypad).pdf"
557 cp SAE-de-nokeypad.pdf "$PRODUCT_PKG_DIR/Ardour SAE Shortcuts.pdf"
559 elif [ x$MIXBUS != x ] ; then
563 echo "Creating Mixbus packaging directory"
564 mv $APPDIR $PRODUCT_PKG_DIR/
565 cp MixBus_Install_QuickStart.pdf "$PRODUCT_PKG_DIR/Mixbus Install & Quick Start Guide.pdf"
567 YPOS=$[ $DMGWINBOTTOM - 300 ]
568 MIXBUSPOS="set position of item \"MixBus_Install_QuickStart.pdf\" of container window to {90, ${YPOS}}"
571 echo "Creating $APPNAME packaging directory"
572 mv $APPDIR $PRODUCT_PKG_DIR/
576 if test x$WITH_HARVID != x ; then
577 echo "installing video tools.."
578 HARVID_VERSION=$(curl -s -S http://ardour.org/files/video-tools/harvid_version.txt)
579 XJADEO_VERSION=$(curl -s -S http://ardour.org/files/video-tools/xjadeo_version.txt)
581 echo "copying harvid and xjadeo ..."
584 rsync://ardour.org/video-tools/harvid-osx-${HARVID_VERSION}.tgz \
585 "$CACHEDIR/harvid-${MULTIARCH}-${HARVID_VERSION}.tgz"
588 rsync://ardour.org/video-tools/jadeo-${XJADEO_VERSION:1}.dmg \
589 "$CACHEDIR/jadeo-${XJADEO_VERSION:1}.dmg"
592 -C $PRODUCT_PKG_DIR/$APPROOT \
593 -f "$CACHEDIR/harvid-${MULTIARCH}-${HARVID_VERSION}.tgz" || exit 1
595 JADEO=$(hdiutil attach "$CACHEDIR/jadeo-${XJADEO_VERSION:1}.dmg" | grep Apple_HFS | grep dev/ | cut -f 3)
596 cp -r "${JADEO}/Jadeo.app" "$PRODUCT_PKG_DIR/"
597 hdiutil detach "${JADEO}"
600 YPOS=$[ $DMGWINBOTTOM - 300 ]
601 XJADEOPOS="set position of item \"Jadeo.app\" of container window to {310, ${YPOS}}"
603 DMGBACKGROUND=dmgbgxj.png
606 echo "Building DMG ..."
608 # UC_DMG=$APPNAME-${release_version}-UC.dmg
609 # FINAL_DMG=$APPNAME-${release_version}.dmg
610 UC_DMG=$APPNAME-$release_version.dmg
611 VOLNAME=$APPNAME-$release_version
615 MNTPATH=`mktemp -d -t ardourimg`
616 TMPDMG=`mktemp -t ardour`
617 ICNSTMP=`mktemp -t ardouricon`
619 DMGMEGABYTES=$[ `du -sk "$PRODUCT_PKG_DIR" | cut -f 1` * 1024 / 1048576 + $EXTRA_SPACE_MB ]
621 echo "DMG MB = " $DMGMEGABYTES
623 rm -f $UC_DMG "$TMPDMG" "${TMPDMG}.dmg" "$ICNSTMP"
627 TMPDMG="${TMPDMG}.dmg"
629 hdiutil create -megabytes $DMGMEGABYTES "$TMPDMG"
630 DiskDevice=$(hdid -nomount "$TMPDMG" | grep Apple_HFS | cut -f 1 -d ' ')
631 newfs_hfs -v "${VOLNAME}" "${DiskDevice}"
632 mount -t hfs "${DiskDevice}" "${MNTPATH}"
634 cp -r ${PRODUCT_PKG_DIR}/* "${MNTPATH}" || exit
635 mkdir "${MNTPATH}/.background"
636 cp -vi ${DMGBACKGROUND} "${MNTPATH}/.background/dmgbg.png"
638 echo "setting DMG background ..."
640 if test $(sw_vers -productVersion | cut -d '.' -f 2) -lt 9; then
644 # OSX 10.9.X and later
645 DISKNAME=`basename "${MNTPATH}"`
649 tell application "Finder"
651 tell disk "${DISKNAME}"
653 set current view of container window to icon view
654 set toolbar visible of container window to false
655 set statusbar visible of container window to false
656 set the bounds of container window to {400, 200, 800, ${DMGWINBOTTOM}}
657 set theViewOptions to the icon view options of container window
658 set arrangement of theViewOptions to not arranged
659 set icon size of theViewOptions to 64
660 set background picture of theViewOptions to file ".background:dmgbg.png"
661 make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"}
662 set position of item "${APPDIR}" of container window to {90, 100}
663 set position of item "Applications" of container window to {310, 100}
669 update without registering applications
676 chmod -Rf go-w "${MNTPATH}"
679 echo "compressing Image ..."
682 umount "${DiskDevice}"
683 hdiutil eject "${DiskDevice}"
684 # Create a read-only version, use zlib compression
685 hdiutil convert -format UDZO "${TMPDMG}" -imagekey zlib-level=9 -o "${UC_DMG}"
686 # Delete the temporary files
690 echo "setting file icon ..."
692 cp ${PRODUCT_PKG_DIR}/$Resources/appIcon.icns ${ICNSTMP}.icns
693 sips -i ${ICNSTMP}.icns
694 DeRez -only icns ${ICNSTMP}.icns > ${ICNSTMP}.rsrc
695 Rez -append ${ICNSTMP}.rsrc -o "$UC_DMG"
696 SetFile -a C "$UC_DMG"
698 rm ${ICNSTMP}.icns ${ICNSTMP}.rsrc
701 echo "packaging suceeded."