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