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
202 # if we build a bundle without jack, then
203 # make the Ardour3 executable a helper
204 # script that checks to see if JACK is
208 cp startup_script $APPROOT/MacOS/Ardour3
209 chmod 775 $APPROOT/MacOS/Ardour3
210 MAIN_EXECUTABLE=Ardour3.bin
212 echo "Copying ardour executable ...."
213 cp $BUILD_ROOT/gtk2_ardour/ardour-$release_version $APPROOT/MacOS/$MAIN_EXECUTABLE
214 if test x$SAE != x ; then
215 # cp $BUILD_ROOT/gtk2_ardour/evtest $APPROOT/MacOS/gtkevents
216 cp Ardour3-SAE.icns $Resources/appIcon.icns
217 elif test x$MIXBUS != x ; then
218 cp Mixbus.icns $Resources/appIcon.icns
220 cp Ardour3.icns $Resources/appIcon.icns
222 cp typeArdour.icns $Resources/
223 if test x$STRIP != x ; then
224 strip $APPROOT/MacOS/Ardour3
228 if test x$WITH_NLS != x ; then
229 echo "NLS support ..."
230 echo "I hope you remembered to run waf i18n"
233 for pkg in gtk2_ardour libs/ardour libs/gtkmm2ext ; do
234 files=`find ../../$pkg -name "*.mo"`
237 # the package name is appended with a number so that
238 # it can be parallel installed during a regular install
239 # with older (and newer) versions. it is just the major
240 # number of the release (i.e. leading digits)
243 vsuffix=`echo $release_version | sed 's/^\([0-9][0-9]*\).*/\1/'`
245 if [ -z "$files" ]; then
247 echo "!!!! WARNING !!!! - Did not find any .mo files in ../../$pkg"
254 lang=`basename $file | sed 's/\.mo//'`
255 mkdir -p $Locale/$lang/LC_MESSAGES
256 cp $file $Locale/$lang/LC_MESSAGES/`basename $pkg`$vsuffix.mo
257 echo copy $file to $Locale/$lang/LC_MESSAGES/`basename $pkg`$vsuffix.mo
258 if echo $LINGUAS | grep $lang >/dev/null 2>&1 ; then
261 LINGUAS="$LINGUAS $lang"
268 if [ -d $GTKSTACK_ROOT/share/locale/$l ] ; then
269 echo "Copying GTK i18n files for $l..."
270 cp -r $GTKSTACK_ROOT/share/locale/$l $Locale
272 # try with just the language spec
273 just_lang=`echo $l | sed 's/_[A-Z][A-Z]$//'`
274 if [ -d $GTKSTACK_ROOT/share/locale/$just_lang ] ; then
275 echo "Copying GTK i18n files for $l..."
276 cp -r $GTKSTACK_ROOT/share/locale/$just_lang $Locale
281 echo "Skipping NLS support"
285 # Copy stuff that may be dynamically loaded
288 cp -R $GTKSTACK_ROOT/etc/* $Etc
289 echo "Copying all Pango modules ..."
290 cp -R $GTKSTACK_ROOT/lib/pango/1.8.0/modules/*.so $Frameworks/modules
291 echo "Copying all GDK Pixbuf loaders ..."
292 cp -R $GTKSTACK_ROOT/lib/gdk-pixbuf-2.0/2.10.0/loaders/*.so $Frameworks/modules
294 cp -R $GTKSTACK_ROOT/lib/charset.alias $Resources
296 # generate new Pango module file
299 ModulesPath=$GTKSTACK_ROOT/lib/pango/1.8.0/modules
301 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
304 # generate a new GDK pixbufs loaders file
305 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
307 # We rely on clearlooks, so include a version from our own build tree
308 # this one is special - we will set GTK_PATH to $Frameworks/gtkengines
310 GTK_ENGINE_DIR=$Frameworks/gtkengines/engines
311 mkdir -p $GTK_ENGINE_DIR
313 echo "Copying GTK engines ..."
314 cp $BUILD_ROOT/libs/clearlooks-newer/libclearlooks.dylib $Frameworks
315 (cd $GTK_ENGINE_DIR && ln -s ../../libclearlooks.dylib . && ln -s ../../libclearlooks.dylib libclearlooks.so)
317 cp $GTKSTACK_ROOT/lib/gtk-2.0/2.10.0/engines/libpixmap.so $Frameworks
318 (cd $GTK_ENGINE_DIR && ln -s ../../libpixmap.so)
321 if test x$WITH_LADSPA != x ; then
322 if test x$SAE != x ; then
324 elif test x$MIXBUS != x ; then
325 plugdir=mixbus_ladspa
329 if [ -d $plugdir -a "x$(ls $plugdir)" != x ] ; then
330 echo "Copying `ls $plugdir | wc -l` plugins ..."
331 cp -r $plugdir/* $Plugins
335 # Control Surface shared libraries
336 cp $BUILD_ROOT/libs/surfaces/*/libardour_*.dylib $Surfaces
337 cp $BUILD_ROOT/libs/surfaces/control_protocol/libardourcp*.dylib $Frameworks
340 cp $BUILD_ROOT/libs/panners/*/lib*.dylib $Panners
343 for backend in jack wavesaudio dummy; do
344 cp $BUILD_ROOT/libs/backends/$backend/lib*.dylib $Backends
347 # Export Formats/Presets
348 for f in $BUILD_ROOT/../export/*.preset $BUILD_ROOT/../export/*.format ; do
349 cp "$f" $ExportFormats ;
352 # Session and Route templates
353 #for f in $BUILD_ROOT/../templates/* ; do
354 # if [ -d "$f" ] ; then
355 # cp -r "$f" $Templates ;
360 # got to be careful with names here
361 for x in $BUILD_ROOT/../midi_maps/*.map ; do
366 # got to be careful with names here
367 for x in $BUILD_ROOT/../patchfiles/*.midnam ; do
372 # got to be careful with names here
373 for x in $BUILD_ROOT/../mcp/*.device $BUILD_ROOT/../mcp/*.profile ; do
374 cp "$x" $MackieControl
377 # VAMP plugins that we use
378 cp $BUILD_ROOT/libs/vamp-plugins/libardourvampplugins.dylib $Frameworks
380 # Suil modules (new dir 'build-stack')
381 if test -d $GTKSTACK_ROOT/lib/suil-0/ ; then
382 cp $GTKSTACK_ROOT/lib/suil-0/lib* $Frameworks
385 # Suil modules (old dir 'build-ardour-stack')
386 if test -d $ARDOURSTACK_ROOT/lib/suil-0/ ; then
387 cp $ARDOURSTACK_ROOT/lib/suil-0/lib* $Frameworks
390 # VST scanner app and wrapper script, if they exist
391 if test -d $BUILD_ROOT/libs/fst ; then
392 cp $BUILD_ROOT/libs/fst/ardour-vst-scanner* $Frameworks/ || true
396 if test -f $BUILD_ROOT/libs/vfork/ardour-exec-wrapper ; then
397 mkdir -p $Frameworks/vfork
398 cp $BUILD_ROOT/libs/vfork/ardour-exec-wrapper $VFork
404 for file in $APPROOT/MacOS/* $Frameworks/* $Frameworks/modules/* $Panners/*.dylib $Backends/*.dylib $Surfaces/*.dylib $Plugins/*.so ; do
405 if ! file $file | grep -qs Mach-O ; then
408 deps=`otool -L $file | awk '{print $1}' | egrep "($GTKSTACK_ROOT|$ARDOURSTACK_ROOT|/opt/|/local/|libs/)" | grep -v 'libjack\.'`
410 for dep in $deps ; do
412 if ! test -f $Frameworks/$base; then
413 if echo $dep | grep -sq '^libs' ; then
414 cp $BUILD_ROOT/$dep $Frameworks
422 if test x$missing = xfalse ; then
423 # everything has been found
429 echo "Copying other stuff to $APPDIR ..."
431 #cp $BUILD_ROOT/gtk2_ardour/ergonomic-us.bindings $Resources
433 cp $BUILD_ROOT/gtk2_ardour/mnemonic-us.bindings $Resources
434 cp ../../gtk2_ardour/mixer.bindings $Resources
435 cp ../../gtk2_ardour/step_editing.bindings $Resources
436 cp $BUILD_ROOT/gtk2_ardour/ardour.menus $Resources
438 if test x$SAE != x ; then
439 cp $BUILD_ROOT/gtk2_ardour/SAE-de-keypad.bindings $Resources
440 cp $BUILD_ROOT/gtk2_ardour/SAE-de-nokeypad.bindings $Resources
441 cp $BUILD_ROOT/gtk2_ardour/SAE-us-keypad.bindings $Resources
442 cp $BUILD_ROOT/gtk2_ardour/SAE-us-nokeypad.bindings $Resources
443 cp $BUILD_ROOT/instant.xml.sae $Resources/instant.xml
444 echo cp $BUILD_ROOT/instant.xml.sae $Resources/instant.xml
446 cp ../../system_config $Resources/system_config
447 cp ../../instant.xml $Resources/instant.xml
448 echo cp ../../instant.xml $Resources/instant.xml
450 cp $BUILD_ROOT/gtk2_ardour/default_ui_config $Resources
451 cp $BUILD_ROOT/gtk2_ardour/dark_fonts.rc $Resources
452 cp $BUILD_ROOT/gtk2_ardour/dark_styles.rc $Resources
453 cp $BUILD_ROOT/gtk2_ardour/light_fonts.rc $Resources
454 cp $BUILD_ROOT/gtk2_ardour/light_styles.rc $Resources
455 cp $BUILD_ROOT/gtk2_ardour/ui_dark.rc $Resources
456 cp $BUILD_ROOT/gtk2_ardour/ui_light.rc $Resources
457 cp $BUILD_ROOT/gtk2_ardour/widgets.rc $Resources
459 cp -r ../../gtk2_ardour/icons $Resources
460 cp -r ../../gtk2_ardour/pixmaps $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 # now fix up the executables
476 echo "Fixing up executable dependency names ..."
477 executables=$MAIN_EXECUTABLE
478 if test x$SAE != x ; then
479 executables="$executables"
482 for exe in $executables; do
483 EXE=$APPROOT/MacOS/$exe
485 for lib in `otool -L $EXE | egrep "($GTKSTACK_ROOT|$ARDOURSTACK_ROOT|/opt/|/local/|libs/)" | awk '{print $1}' | grep -v 'libjack\.'` ; do
487 changes="$changes -change $lib @executable_path/../lib/$base"
489 if test "x$changes" != "x" ; then
490 install_name_tool $changes $EXE
494 echo "Fixing up library names ..."
495 # now do the same for all the libraries we include
496 for libdir in $Frameworks $Frameworks/modules $Surfaces $Panners $Backends ; do
498 libbase=`basename $libdir`
500 for dylib in $libdir/*.dylib $libdir/*.so ; do
504 if test -L $dylib ; then
508 # change all the dependencies
511 for lib in `otool -L $dylib | egrep "($GTKSTACK_ROOT|$ARDOURSTACK_ROOT|/opt/|/local/|libs/)" | awk '{print $1}' | grep -v 'libjack\.'` ; do
513 if echo $lib | grep -s libbase; then
514 changes="$changes -change $lib @executable_path/../$libbase/$base"
516 changes="$changes -change $lib @executable_path/../lib/$base"
520 if test "x$changes" != x ; then
521 if install_name_tool $changes $dylib ; then
528 # now the change what the library thinks its own name is
530 base=`basename $dylib`
531 install_name_tool -id @executable_path/../$libbase/$base $dylib
536 # and now ... the DMG
539 rm -rf $PRODUCT_PKG_DIR
540 mkdir $PRODUCT_PKG_DIR
543 DMGBACKGROUND=dmgbg.png
545 if [ x$SAE != x ] ; then
549 echo "Creating SAE packaging directory"
550 mv $APPDIR $PRODUCT_PKG_DIR/Ardour3-SAE.app
551 cp HowToInstallArdourSAE.pdf "$PRODUCT_PKG_DIR/How To Install Ardour SAE.pdf"
552 cp SAE-de-keypad.pdf "$PRODUCT_PKG_DIR/Ardour SAE Shortcuts (keypad).pdf"
553 cp SAE-de-nokeypad.pdf "$PRODUCT_PKG_DIR/Ardour SAE Shortcuts.pdf"
555 elif [ x$MIXBUS != x ] ; then
559 echo "Creating Mixbus packaging directory"
560 mv $APPDIR $PRODUCT_PKG_DIR/
561 cp MixBus_Install_QuickStart.pdf "$PRODUCT_PKG_DIR/Mixbus Install & Quick Start Guide.pdf"
563 YPOS=$[ $DMGWINBOTTOM - 300 ]
564 MIXBUSPOS="set position of item \"MixBus_Install_QuickStart.pdf\" of container window to {90, ${YPOS}}"
567 echo "Creating $APPNAME packaging directory"
568 mv $APPDIR $PRODUCT_PKG_DIR/
572 if test x$WITH_HARVID != x ; then
573 echo "installing video tools.."
574 HARVID_VERSION=$(curl -s -S http://ardour.org/files/video-tools/harvid_version.txt)
575 XJADEO_VERSION=$(curl -s -S http://ardour.org/files/video-tools/xjadeo_version.txt)
577 echo "copying harvid and xjadeo ..."
580 rsync://ardour.org/video-tools/harvid-osx-${HARVID_VERSION}.tgz \
581 "$CACHEDIR/harvid-${MULTIARCH}-${HARVID_VERSION}.tgz"
584 rsync://ardour.org/video-tools/jadeo-${XJADEO_VERSION:1}.dmg \
585 "$CACHEDIR/jadeo-${XJADEO_VERSION:1}.dmg"
588 -C $PRODUCT_PKG_DIR/$APPROOT \
589 -f "$CACHEDIR/harvid-${MULTIARCH}-${HARVID_VERSION}.tgz" || exit 1
591 JADEO=$(hdiutil attach "$CACHEDIR/jadeo-${XJADEO_VERSION:1}.dmg" | grep Apple_HFS | grep dev/ | cut -f 3)
592 cp -r "${JADEO}/Jadeo.app" "$PRODUCT_PKG_DIR/"
593 hdiutil detach "${JADEO}"
596 YPOS=$[ $DMGWINBOTTOM - 300 ]
597 XJADEOPOS="set position of item \"Jadeo.app\" of container window to {310, ${YPOS}}"
599 DMGBACKGROUND=dmgbgxj.png
602 echo "Building DMG ..."
604 # UC_DMG=$APPNAME-${release_version}-UC.dmg
605 # FINAL_DMG=$APPNAME-${release_version}.dmg
606 UC_DMG=$APPNAME-$release_version.dmg
607 VOLNAME=$APPNAME-$release_version
611 MNTPATH=`mktemp -d -t ardourimg`
612 TMPDMG=`mktemp -t ardour`
613 ICNSTMP=`mktemp -t ardouricon`
615 DMGMEGABYTES=$[ `du -sk "$PRODUCT_PKG_DIR" | cut -f 1` * 1024 / 1048576 + $EXTRA_SPACE_MB ]
617 echo "DMG MB = " $DMGMEGABYTES
619 rm -f $UC_DMG "$TMPDMG" "${TMPDMG}.dmg" "$ICNSTMP"
623 TMPDMG="${TMPDMG}.dmg"
625 hdiutil create -megabytes $DMGMEGABYTES "$TMPDMG"
626 DiskDevice=$(hdid -nomount "$TMPDMG" | grep Apple_HFS | cut -f 1 -d ' ')
627 newfs_hfs -v "${VOLNAME}" "${DiskDevice}"
628 mount -t hfs "${DiskDevice}" "${MNTPATH}"
630 cp -r ${PRODUCT_PKG_DIR}/* "${MNTPATH}" || exit
631 mkdir "${MNTPATH}/.background"
632 cp -vi ${DMGBACKGROUND} "${MNTPATH}/.background/dmgbg.png"
634 echo "setting DMG background ..."
636 if test $(sw_vers -productVersion | cut -d '.' -f 2) -lt 9; then
640 # OSX 10.9.X and later
641 DISKNAME=`basename "${MNTPATH}"`
645 tell application "Finder"
647 tell disk "${DISKNAME}"
649 set current view of container window to icon view
650 set toolbar visible of container window to false
651 set statusbar visible of container window to false
652 set the bounds of container window to {400, 200, 800, ${DMGWINBOTTOM}}
653 set theViewOptions to the icon view options of container window
654 set arrangement of theViewOptions to not arranged
655 set icon size of theViewOptions to 64
656 set background picture of theViewOptions to file ".background:dmgbg.png"
657 make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"}
658 set position of item "${APPDIR}" of container window to {90, 100}
659 set position of item "Applications" of container window to {310, 100}
665 update without registering applications
672 chmod -Rf go-w "${MNTPATH}"
675 echo "compressing Image ..."
678 umount "${DiskDevice}"
679 hdiutil eject "${DiskDevice}"
680 # Create a read-only version, use zlib compression
681 hdiutil convert -format UDZO "${TMPDMG}" -imagekey zlib-level=9 -o "${UC_DMG}"
682 # Delete the temporary files
686 echo "setting file icon ..."
688 cp ${PRODUCT_PKG_DIR}/$Resources/appIcon.icns ${ICNSTMP}.icns
689 sips -i ${ICNSTMP}.icns
690 DeRez -only icns ${ICNSTMP}.icns > ${ICNSTMP}.rsrc
691 Rez -append ${ICNSTMP}.rsrc -o "$UC_DMG"
692 SetFile -a C "$UC_DMG"
694 rm ${ICNSTMP}.icns ${ICNSTMP}.rsrc
697 echo "packaging suceeded."