merge with master
[ardour.git] / tools / osx_packaging / osx_build
1 #!/bin/bash
2
3 # script for pulling together a MacOSX app bundle.
4
5 GTKSTACK_ROOT=$HOME/gtk/inst
6 ARDOURSTACK_ROOT=$HOME/a3/inst
7 BUILD_ROOT=../../build
8
9 SAE=
10 MIXBUS=
11 WITH_LADSPA=1
12 STRIP=1
13 PRINT_SYSDEPS=
14 WITH_NLS=
15
16 while [ $# -gt 0 ] ; do
17     echo "arg = $1"
18     case $1 in
19
20         #
21         # top level build targets
22         #
23
24         --sae) WITH_NLS= ; 
25                SAE=1 ; 
26                WITH_LADSPA=1; 
27                STRIP= ; 
28                PRODUCT_PKG_DIR=ArdourSAE ; 
29                APPNAME=Ardour ;
30                shift ;;
31         --mixbus) MIXBUS=1; 
32                   WITH_NLS=1 ; 
33                   SAE= ; 
34                   WITH_LADSPA=; 
35                   STRIP= ; 
36                   PRODUCT_PKG_DIR=MixBus;
37                   APPNAME=Mixbus ;
38                   shift ;;
39         --public) WITH_NLS= ; 
40                   SAE= ; 
41                   WITH_LADSPA=1; 
42                   STRIP= ; 
43                   PRODUCT_PKG_DIR=Ardour;
44                   APPNAME=Ardour ;
45                   shift ;;
46         --allinone) SAE= ; 
47                     WITH_NLS= ; 
48                     WITH_LADSPA=1; 
49                     STRIP= ; 
50                     PRODUCT_PKG_DIR=Ardour ;
51                     shift ;;
52         --test) SAE= ; WITH_LADSPA=; STRIP= ; shift ;;
53
54         #
55         # specific build flags
56         #
57
58         --noladspa) WITH_LADSPA= ; shift ;;
59         --nostrip) STRIP= ; shift ;;
60         --sysdeps) PRINT_SYSDEPS=1; shift ;;
61         --nls) WITH_NLS=1 ; shift ;;
62     esac
63 done
64
65 if test -z "$PRODUCT_PKG_DIR" -o -z "$APPNAME"; then
66         echo "application or product-name was not specified"
67         exit 1
68 fi
69
70 . ../define_versions.sh
71 echo "Version is $release_version / $revision"
72 info_string="$version built on `hostname` by `whoami` on `date`"
73 echo "Info string is $info_string"
74
75 # setup directory structure
76
77 APPDIR=${APPNAME}.app
78 APPROOT=$APPDIR/Contents
79 Frameworks=$APPROOT/lib
80 Resources=$APPROOT/Resources
81 #
82 # Since this is OS X, don't try to distinguish between etc and shared
83 # (machine dependent and independent data) - just put everything
84 # into Resources.
85
86 Shared=$Resources
87 Etc=$Resources
88 Locale=$Resources/locale
89 #
90 # Bundled Plugins live in a top level folder
91
92 Plugins=$APPROOT/Plugins
93 Surfaces=$Frameworks/surfaces
94 Panners=$Frameworks/panners
95 MidiMaps=$Shared/midi_maps
96 ExportFormats=$Shared/export
97 Templates=$Shared/templates
98 PatchFiles=$Shared/patchfiles
99 MackieControl=$Shared/mcp
100
101 if [ x$PRINT_SYSDEPS != x ] ; then
102 #
103 # print system dependencies
104 #
105
106     for file in $APPROOT/MacOS/* $Frameworks/* $Frameworks/modules/* $Plugins/*.so ; do 
107         if ! file $file | grep -qs Mach-O ; then
108             continue
109         fi
110         otool -L $file | awk '{print $1}' | egrep -v "(^@executable_path|^Ardour[0-9][.0-9]*.app)" 
111     done | sort | uniq
112     exit 0
113 fi
114
115 echo "Removing old $APPDIR tree ..."
116
117 rm -rf $APPDIR
118
119 echo "Building new app directory structure ..."
120
121 # only bother to make the longest paths
122
123 mkdir -p $APPROOT/MacOS
124 mkdir -p $APPROOT/Resources
125 mkdir -p $Plugins
126 mkdir -p $Surfaces
127 mkdir -p $Panners
128 mkdir -p $MidiMaps
129 mkdir -p $ExportFormats
130 mkdir -p $Templates
131 mkdir -p $Frameworks/modules
132 mkdir -p $Etc
133 mkdir -p $MackieControl
134
135 # maybe set variables
136 env=""
137 if test x$SAE != x ; then
138     appname="Ardour3/SAE"
139     env="$env<key>ARDOUR_SAE</key><string>true</string>"
140     #
141     # current default for SAE version is German keyboard layout without a keypad
142     #
143     env="$env<key>ARDOUR_KEYBOARD_LAYOUT</key><string>de-nokeypad</string>"
144     env="$env<key>ARDOUR_UI_CONF</key><string>ardour3_ui_sae.conf</string>"
145     env="$env<key>ARDOUR3_UI_RC</key><string>ardour3_ui_dark_sae.rc</string>"
146 elif test x$MIXBUS != x ; then
147     appname="Ardour3/Mixbus"
148     env="$env<key>ARDOUR_MIXBUS</key><string>true</string>"
149     #
150     # current default for MIXBUS version is US keyboard layout without a keypad
151     #
152     env="$env<key>ARDOUR_KEYBOARD_LAYOUT</key><string>us-nokeypad</string>"
153     env="$env<key>ARDOUR_UI_CONF</key><string>ardour3_ui.conf</string>"
154     env="$env<key>ARDOUR3_UI_RC</key><string>ardour3_ui_dark.rc</string>"
155 else
156     appname="Ardour3"
157 fi
158
159 #
160 # if we're not going to bundle JACK, make sure we can find
161 # jack in the places where it might be
162 #
163
164 env="$env<key>PATH</key><string>/usr/local/bin:/opt/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>"
165 env="$env<key>DYLIB_FALLBACK_LIBRARY_PATH</key><string>/usr/local/lib:/opt/lib</string>"
166
167 env="<key>LSEnvironment</key><dict>$env<key>ARDOUR_BUNDLED</key><string>true</string></dict>"
168
169 # edit plist
170 sed -e "s?@ENV@?$env?g" \
171     -e "s?@VERSION@?$release_version/$revision?g" \
172     -e "s?@INFOSTRING@?$info_string?g" < Info.plist.in > Info.plist
173 # and plist strings
174 sed -e "s?@APPNAME@?$appname?" \
175     -e "s?@ENV@?$env?g" \
176     -e "s?@VERSION@?$release_version/$revision?g" \
177     -e "s?@INFOSTRING@?$info_string?g" < InfoPlist.strings.in > Resources/InfoPlist.strings || exit 1
178
179 # copy static files
180
181 cp Info.plist $APPROOT
182 cp -R Resources $APPROOT
183
184 #
185 # if we build a bundle without jack, then
186 # make the Ardour3 executable a helper
187 # script that checks to see if JACK is
188 # installed.
189 #
190
191 cp startup_script $APPROOT/MacOS/Ardour3
192 chmod 775 $APPROOT/MacOS/Ardour3
193 MAIN_EXECUTABLE=Ardour3.bin
194
195 echo "Copying ardour executable ...."
196 cp $BUILD_ROOT/gtk2_ardour/ardour-$release_version $APPROOT/MacOS/$MAIN_EXECUTABLE
197 if test x$SAE != x ; then
198     # cp $BUILD_ROOT/gtk2_ardour/evtest $APPROOT/MacOS/gtkevents
199     cp  Ardour3-SAE.icns $Resources/appIcon.icns
200 elif test x$MIXBUS != x ; then
201     cp  Mixbus.icns $Resources/appIcon.icns
202 else
203     cp  Ardour3.icns $Resources/appIcon.icns
204 fi
205 cp  typeArdour.icns $Resources/
206 if test x$STRIP != x ; then
207     strip $APPROOT/MacOS/Ardour3
208 fi
209
210 # copy locale files
211 if test x$WITH_NLS != x ; then
212     echo "NLS support ..."
213     echo "I hope you remembered to run scons msgupdate!"
214     LINGUAS=
215     for file in $BUILD_ROOT/gtk2_ardour/*.mo 
216     do
217         lang=`basename $file | sed 's/\.mo//'`
218         mkdir -p $Locale/$lang/LC_MESSAGES
219         cp $file $Locale/$lang/LC_MESSAGES/gtk2_ardour.mo
220         LINGUAS="$LINGUAS $lang"
221     done
222     for file in $BUILD_ROOT/libs/ardour/*.mo 
223     do
224         lang=`basename $file | sed 's/\.mo//'`
225         mkdir -p $Locale/$lang/LC_MESSAGES
226         cp $file $Locale/$lang/LC_MESSAGES/libardour.mo
227     done
228     for l in $LINGUAS
229     do
230       if [ -d $GTKSTACK_ROOT/share/locale/$l ] ; then
231           echo "Copying GTK i18n files for $l..."
232           cp -r $GTKSTACK_ROOT/share/locale/$l $Locale
233       else
234           # try with just the language spec
235           just_lang=`echo $l | sed 's/_[A-Z][A-Z]$//'`
236           if [ -d $GTKSTACK_ROOT/share/locale/$just_lang ] ; then
237               echo "Copying GTK i18n files for $l..."
238               cp -r $GTKSTACK_ROOT/share/locale/$just_lang $Locale
239           fi
240       fi
241     done
242 else
243     echo "Skipping NLS support"
244 fi
245
246 #
247 # Copy stuff that may be dynamically loaded
248
249
250 cp -R $GTKSTACK_ROOT/etc/* $Etc
251 echo "Copying all Pango modules ..."
252 cp -R $GTKSTACK_ROOT/lib/pango/1.6.0/modules/*.so $Frameworks/modules
253 echo "Copying all GDK Pixbuf loaders ..."
254 cp -R $GTKSTACK_ROOT/lib/gdk-pixbuf-2.0/2.10.0/loaders/*.so $Frameworks/modules
255 # charset alias file
256 cp -R $GTKSTACK_ROOT/lib/charset.alias $Resources
257
258 # generate new Pango module file
259 cat > pangorc <<EOF 
260 [Pango]
261 ModulesPath=$GTKSTACK_ROOT/lib/pango/1.6.0/modules
262 EOF
263 env PANGO_RC_FILE=pangorc $GTKSTACK_ROOT/bin/pango-querymodules | sed "s?$GTKSTACK_ROOT/lib/pango/1.6.0/modules/?@executable_path/../lib/modules/?" > $Resources/pango.modules
264 rm pangorc
265
266 # generate a new GDK pixbufs loaders file
267 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
268
269 # We rely on clearlooks, so include a version from our own build tree
270 # this one is special - we will set GTK_PATH to $Frameworks/gtkengines
271
272 GTK_ENGINE_DIR=$Frameworks/gtkengines/engines
273 mkdir -p $GTK_ENGINE_DIR
274
275 echo "Copying GTK engines ..."
276 cp $BUILD_ROOT/libs/clearlooks-newer/libclearlooks.dylib $Frameworks
277 (cd $GTK_ENGINE_DIR && ln -s ../../libclearlooks.dylib . && ln -s ../../libclearlooks.dylib libclearlooks.so)
278
279 cp $GTKSTACK_ROOT/lib/gtk-2.0/2.10.0/engines/libpixmap.so $Frameworks
280 (cd $GTK_ENGINE_DIR && ln -s ../../libpixmap.so)
281
282
283 if test x$WITH_LADSPA != x ; then
284     if test x$SAE != x ; then
285         plugdir=sae_ladspa
286     elif test x$MIXBUS != x ; then
287         plugdir=mixbus_ladspa
288     else
289         plugdir=ladspa
290     fi
291     if [ -d $plugdir -a "x$(ls $plugdir)" != x ] ; then 
292         echo "Copying `ls $plugdir | wc -l` plugins ..."
293         cp -r $plugdir/* $Plugins
294     fi
295 fi
296
297 # Control Surface shared libraries
298 cp $BUILD_ROOT/libs/surfaces/*/libardour_*.dylib $Surfaces
299 cp $BUILD_ROOT/libs/surfaces/control_protocol/libardourcp*.dylib $Frameworks
300
301 # Panners
302 cp $BUILD_ROOT/libs/panners/*/lib*.dylib $Panners
303
304
305 # Export Formats/Presets
306 for f in $BUILD_ROOT/../export/*.preset $BUILD_ROOT/../export/*.format ; do 
307     cp "$f" $ExportFormats ; 
308 done
309
310 # Session and Route templates
311 #for f in $BUILD_ROOT/../templates/* ; do 
312 #    if [ -d "$f" ] ; then
313 #        cp -r "$f" $Templates ; 
314 #    fi
315 #done
316
317 # MidiMaps
318 # got to be careful with names here
319 for x in $BUILD_ROOT/../midi_maps/*.map ; do
320     cp "$x" $MidiMaps
321 done
322
323 # MIDNAM Patch Files
324 # got to be careful with names here
325 for x in $BUILD_ROOT/../patchfiles/*.midnam ; do
326     cp "$x" $PatchFiles
327 done
328
329 # MackieControl data
330 # got to be careful with names here
331 for x in $BUILD_ROOT/../mcp/*.device $BUILD_ROOT/../mcp/*.profile ; do
332     cp "$x" $MackieControl
333 done
334
335 # VAMP plugins that we use
336 cp $BUILD_ROOT/libs/vamp-plugins/libardourvampplugins.dylib $Frameworks
337
338 # Suil modules
339 cp $ARDOURSTACK_ROOT/lib/suil-0/lib* $Frameworks
340
341 while [ true ] ; do 
342     missing=false
343     for file in $APPROOT/MacOS/* $Frameworks/* $Frameworks/modules/* $Panners/*.dylib $Surfaces/*.dylib $Plugins/*.so ; do 
344         if ! file $file | grep -qs Mach-O ; then
345             continue
346         fi
347         deps=`otool -L $file | awk '{print $1}' | egrep "($GTKSTACK_ROOT|$ARDOURSTACK_ROOT|/opt/|/local/|libs/)" | grep -v 'libjack\.'`
348         # echo -n "."
349         for dep in $deps ; do
350             base=`basename $dep`
351             if ! test -f $Frameworks/$base; then
352                 if echo $dep | grep -sq '^libs' ; then
353                     cp $BUILD_ROOT/$dep $Frameworks
354                 else
355                     cp $dep $Frameworks
356                 fi
357                 missing=true
358             fi
359         done
360     done
361     if test x$missing = xfalse ; then
362         # everything has been found
363         break
364     fi
365 done
366 echo
367
368 echo "Copying other stuff to $APPDIR  ..."
369
370 #cp $BUILD_ROOT/gtk2_ardour/ergonomic-us.bindings  $Resources
371
372 cp $BUILD_ROOT/gtk2_ardour/mnemonic-us.bindings  $Resources
373 cp ../../gtk2_ardour/mixer.bindings $Resources
374 cp ../../gtk2_ardour/step_editing.bindings $Resources
375 cp $BUILD_ROOT/gtk2_ardour/ardour.menus $Resources
376
377 if test x$SAE != x ; then
378     cp $BUILD_ROOT/gtk2_ardour/SAE-de-keypad.bindings  $Resources
379     cp $BUILD_ROOT/gtk2_ardour/SAE-de-nokeypad.bindings  $Resources
380     cp $BUILD_ROOT/gtk2_ardour/SAE-us-keypad.bindings  $Resources
381     cp $BUILD_ROOT/gtk2_ardour/SAE-us-nokeypad.bindings  $Resources
382     cp $BUILD_ROOT/ardour_system_sae.rc $Resources/ardour_system.rc
383     echo cp $BUILD_ROOT/ardour_system_sae.rc $Resources/ardour_system.rc
384     cp $BUILD_ROOT/instant.xml.sae $Resources/instant.xml
385     echo cp $BUILD_ROOT/instant.xml.sae $Resources/instant.xml
386 else
387     cp ../../ardour_system.rc $Resources/ardour_system.rc
388     cp ../../instant.xml $Resources/instant.xml
389     echo cp ../../instant.xml $Resources/instant.xml
390 fi
391 cp ../../gtk2_ardour/ardour3_ui_default.conf $Resources
392 cp ../../gtk2_ardour/ardour3_ui_default.conf $Resources/ardour3_ui.conf
393 cp $BUILD_ROOT/gtk2_ardour/ardour3_ui_light.rc $Resources
394 cp $BUILD_ROOT/gtk2_ardour/ardour3_ui_dark.rc $Resources
395
396 cp -r ../../gtk2_ardour/icons $Resources
397 cp -r ../../gtk2_ardour/pixmaps $Resources
398
399 # shared stuff
400 cp -R ../../gtk2_ardour/splash.png $Shared
401 cp -R ../../gtk2_ardour/ArdourMono.ttf $Shared
402
403 # go through and recursively remove any .svn dirs in the bundle
404 for svndir in `find $APPDIR -name .svn -type dir`; do
405     rm -rf $svndir
406 done
407
408 # now fix up the executables
409 echo "Fixing up executable dependency names ..."
410 executables=$MAIN_EXECUTABLE
411 if test x$SAE != x ; then
412     executables="$executables"
413 fi
414
415 for exe in $executables; do
416     EXE=$APPROOT/MacOS/$exe
417     changes=""
418     for lib in `otool -L $EXE | egrep "($GTKSTACK_ROOT|$ARDOURSTACK_ROOT|/opt/|/local/|libs/)" | awk '{print $1}' | grep -v 'libjack\.'` ; do
419       base=`basename $lib`
420       changes="$changes -change $lib @executable_path/../lib/$base"
421     done
422     if test "x$changes" != "x" ; then
423         install_name_tool $changes $EXE
424     fi
425 done
426
427 echo "Fixing up library names ..."
428 # now do the same for all the libraries we include
429 for libdir in $Frameworks $Frameworks/modules $Surfaces $Panners ; do
430
431     libbase=`basename $libdir`
432     
433     for dylib in $libdir/*.dylib $libdir/*.so ; do
434         
435        # skip symlinks
436         
437         if test -L $dylib ; then
438             continue
439         fi
440         
441         # change all the dependencies
442         
443         changes=""
444         for lib in `otool -L $dylib | egrep "($GTKSTACK_ROOT|$ARDOURSTACK_ROOT|/opt/|/local/|libs/)" | awk '{print $1}' | grep -v 'libjack\.'` ; do
445             base=`basename $lib`
446             if echo $lib | grep -s libbase; then
447                 changes="$changes -change $lib @executable_path/../$libbase/$base"
448             else
449                 changes="$changes -change $lib @executable_path/../lib/$base"
450             fi
451         done
452         
453         if test "x$changes" != x ; then
454             if  install_name_tool $changes $dylib ; then
455                 :
456             else
457                 exit 1
458             fi
459         fi
460         
461         # now the change what the library thinks its own name is
462         
463         base=`basename $dylib`
464         install_name_tool -id @executable_path/../$libbase/$base $dylib
465     done
466 done
467
468 #
469 # and now ... the DMG
470
471
472 rm -rf $PRODUCT_PKG_DIR
473 mkdir $PRODUCT_PKG_DIR
474
475 if [ x$SAE != x ] ; then
476         
477     # SAE packaging
478     
479     echo "Creating SAE packaging directory"
480     mv $APPDIR $PRODUCT_PKG_DIR/Ardour3-SAE.app
481     cp HowToInstallArdourSAE.pdf "$PRODUCT_PKG_DIR/How To Install Ardour SAE.pdf"
482     cp SAE-de-keypad.pdf "$PRODUCT_PKG_DIR/Ardour SAE Shortcuts (keypad).pdf"
483     cp SAE-de-nokeypad.pdf "$PRODUCT_PKG_DIR/Ardour SAE Shortcuts.pdf"
484     
485 elif [ x$MIXBUS != x ] ; then
486
487      # Mixbus packaging
488
489     echo "Creating Mixbus packaging directory"
490     mv $APPDIR $PRODUCT_PKG_DIR/
491     cp MixBus_Install_QuickStart.pdf "$PRODUCT_PKG_DIR/Mixbus Install & Quick Start Guide.pdf"
492
493 else 
494
495     echo "Creating $APPNAME packaging directory"
496     mv $APPDIR $PRODUCT_PKG_DIR/
497
498 fi
499
500 echo "Building DMG ..."
501
502 # UC_DMG=$APPNAME-${release_version}-${revision}-UC.dmg
503 # FINAL_DMG=$APPNAME-${release_version}-${revision}.dmg
504 UC_DMG=$APPNAME-$version.dmg
505 VOLNAME=$APPNAME-$version
506
507 # TODO use mktemp
508 export TMPDIR=`pwd`
509 MNTPATH=`mktemp -d -t /ardourimg`
510 TMPDMG=`mktemp -t ardour`
511 ICNSTMP=`mktemp -t ardouricon`
512 EXTRA_SPACE_MB=30
513 DMGMEGABYTES=$[ `du -sk "$PRODUCT_PKG_DIR" | cut -f 1` * 1024 / 1048576 + $EXTRA_SPACE_MB ]
514
515 echo "DMG MB = " $DMGMEGABYTES
516
517 rm -f $UC_DMG "$TMPDMG" "${TMPDMG}.dmg" "$ICNSTMP"
518 rm -rf "$MNTPATH"
519 mkdir -p "$MNTPATH"
520
521 TMPDMG="${TMPDMG}.dmg"
522
523 hdiutil create -megabytes $DMGMEGABYTES "$TMPDMG"
524 DiskDevice=$(hdid -nomount "$TMPDMG" | grep Apple_HFS | cut -f 1 -d ' ')
525 newfs_hfs -v "${VOLNAME}" "${DiskDevice}"
526 mount -t hfs "${DiskDevice}" "${MNTPATH}"
527
528 cp -r ${PRODUCT_PKG_DIR}/${APPDIR} "${MNTPATH}" || exit
529 mkdir "${MNTPATH}/.background"
530 cp -vi dmgbg.png "${MNTPATH}/.background/dmgbg.png"
531
532 echo "setting DMG background ..."
533
534 echo '
535    tell application "Finder"
536      tell disk "'${VOLNAME}'"
537            open
538            set current view of container window to icon view
539            set toolbar visible of container window to false
540            set statusbar visible of container window to false
541            set the bounds of container window to {400, 200, 800, 440}
542            set theViewOptions to the icon view options of container window
543            set arrangement of theViewOptions to not arranged
544            set icon size of theViewOptions to 64
545            set background picture of theViewOptions to file ".background:dmgbg.png"
546            make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"}
547            set position of item "'${APPDIR}'" of container window to {90, 100}
548            set position of item "Applications" of container window to {310, 100}
549            close
550            open
551            update without registering applications
552            delay 5
553            eject
554      end tell
555    end tell
556 ' | osascript
557
558 chmod -Rf go-w "${MNTPATH}"
559 sync
560
561 echo "compressing Image ..."
562
563 # Umount the image
564 umount "${DiskDevice}"
565 hdiutil eject "${DiskDevice}"
566 # Create a read-only version, use zlib compression
567 hdiutil convert -format UDZO "${TMPDMG}" -imagekey zlib-level=9 -o "${UC_DMG}"
568 # Delete the temporary files
569 rm "$TMPDMG"
570 rmdir "$MNTPATH"
571
572 echo "setting file icon ..."
573
574 cp ${PRODUCT_PKG_DIR}/$Resources/appIcon.icns ${ICNSTMP}.icns
575 /usr/bin/sips -i ${ICNSTMP}.icns
576 /Developer/Tools/DeRez -only icns ${ICNSTMP}.icns > ${ICNSTMP}.rsrc
577 /Developer/Tools/Rez -append ${ICNSTMP}.rsrc -o "$UC_DMG"
578 /Developer/Tools/SetFile -a C "$UC_DMG"
579
580 rm ${ICNSTMP}.icns ${ICNSTMP}.rsrc
581
582 echo
583 echo "packaging suceeded."
584 ls -l "$UC_DMG"
585
586 echo "Done."
587 exit