and more packaging changes for GTK engines on OS X
[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 $Frameworks/gtkengines
269
270 GTK_ENGINE_DIR=$Frameworks/gtkengines/engines
271 mkdir -p $GTK_ENGINE_DIR
272
273 echo "Copying GTK engines ..."
274 cp $BUILD_ROOT/libs/clearlooks-newer/libclearlooks.dylib $Frameworks
275 (cd $GTK_ENGINE_DIR && ln -s ../../libclearlooks.dylib . && ln -s ../../libclearlooks.dylib libclearlooks.so)
276
277 cp $GTKSTACK_ROOT/lib/gtk-2.0/2.10.0/engines/libpixmap.dylib $Frameworks
278 (cd $GTK_ENGINE_DIR && ln -s ../../libpixmap.dylib . && ln -s ../../libpixmap.dylib libpixmap.so)
279
280
281 if test x$WITH_LADSPA != x ; then
282     if test x$SAE != x ; then
283         plugdir=sae_ladspa
284     elif test x$MIXBUS != x ; then
285         plugdir=mixbus_ladspa
286     else
287         plugdir=ladspa
288     fi
289     if [ -d $plugdir -a "x$(ls $plugdir)" != x ] ; then 
290         echo "Copying `ls $plugdir | wc -l` plugins ..."
291         cp -r $plugdir/* $Plugins
292     fi
293 fi
294
295 # Control Surface shared libraries
296 cp $BUILD_ROOT/libs/surfaces/*/libardour_*.dylib $Surfaces
297 cp $BUILD_ROOT/libs/surfaces/control_protocol/libardourcp*.dylib $Frameworks
298
299 # Panners
300 cp $BUILD_ROOT/libs/panners/*/lib*.dylib $Panners
301
302
303 # Export Formats/Presets
304 for f in $BUILD_ROOT/../export/*.preset $BUILD_ROOT/../export/*.format ; do 
305     cp "$f" $ExportFormats ; 
306 done
307
308 # Session and Route templates
309 for f in $BUILD_ROOT/../templates/* ; do 
310     if [ -d "$f" ] ; then
311         cp -r "$f" $Templates ; 
312     fi
313 done
314
315 # MidiMaps
316 # got to be careful with names here
317 for x in $BUILD_ROOT/../midi_maps/*.map ; do
318     cp "$x" $MidiMaps
319 done
320
321 # MIDNAM Patch Files
322 # got to be careful with names here
323 for x in $BUILD_ROOT/../patchfiles/*.midnam ; do
324     cp "$x" $PatchFiles
325 done
326
327 # MackieControl data
328 # got to be careful with names here
329 for x in $BUILD_ROOT/../mcp/*.device $BUILD_ROOT/../mcp/*.profile ; do
330     cp "$x" $MackieControl
331 done
332
333 # VAMP plugins that we use
334 cp $BUILD_ROOT/libs/vamp-plugins/libardourvampplugins.dylib $Frameworks
335
336 # Suil modules
337 cp $ARDOURSTACK_ROOT/lib/suil-0/lib* $Frameworks
338
339 while [ true ] ; do 
340     missing=false
341     for file in $APPROOT/MacOS/* $Frameworks/* $Frameworks/modules/* $Panners/*.dylib $Surfaces/*.dylib $Plugins/*.so ; do 
342         if ! file $file | grep -qs Mach-O ; then
343             continue
344         fi
345         deps=`otool -L $file | awk '{print $1}' | egrep "($GTKSTACK_ROOT|$ARDOURSTACK_ROOT|/opt/|/local/|libs/)" | grep -v 'libjack\.'`
346         # echo -n "."
347         for dep in $deps ; do
348             base=`basename $dep`
349             if ! test -f $Frameworks/$base; then
350                 if echo $dep | grep -sq '^libs' ; then
351                     cp $BUILD_ROOT/$dep $Frameworks
352                 else
353                     cp $dep $Frameworks
354                 fi
355                 missing=true
356             fi
357         done
358     done
359     if test x$missing = xfalse ; then
360         # everything has been found
361         break
362     fi
363 done
364 echo
365
366 echo "Copying other stuff to $APPDIR  ..."
367
368 #cp $BUILD_ROOT/gtk2_ardour/ergonomic-us.bindings  $Resources
369
370 cp $BUILD_ROOT/gtk2_ardour/mnemonic-us.bindings  $Resources
371 cp ../../gtk2_ardour/mixer.bindings $Resources
372 cp ../../gtk2_ardour/step_editing.bindings $Resources
373 cp $BUILD_ROOT/gtk2_ardour/ardour.menus $Resources
374
375 if test x$SAE != x ; then
376     cp $BUILD_ROOT/gtk2_ardour/SAE-de-keypad.bindings  $Resources
377     cp $BUILD_ROOT/gtk2_ardour/SAE-de-nokeypad.bindings  $Resources
378     cp $BUILD_ROOT/gtk2_ardour/SAE-us-keypad.bindings  $Resources
379     cp $BUILD_ROOT/gtk2_ardour/SAE-us-nokeypad.bindings  $Resources
380     cp $BUILD_ROOT/ardour_system_sae.rc $Resources/ardour_system.rc
381     echo cp $BUILD_ROOT/ardour_system_sae.rc $Resources/ardour_system.rc
382     cp $BUILD_ROOT/instant.xml.sae $Resources/instant.xml
383     echo cp $BUILD_ROOT/instant.xml.sae $Resources/instant.xml
384 else
385     cp ../../ardour_system.rc $Resources/ardour_system.rc
386     cp ../../instant.xml $Resources/instant.xml
387     echo cp ../../instant.xml $Resources/instant.xml
388 fi
389 cp ../../gtk2_ardour/ardour3_ui_default.conf $Resources
390 cp ../../gtk2_ardour/ardour3_ui_default.conf $Resources/ardour3_ui.conf
391 cp $BUILD_ROOT/gtk2_ardour/ardour3_ui_light.rc $Resources
392 cp $BUILD_ROOT/gtk2_ardour/ardour3_ui_dark.rc $Resources
393
394 cp -r ../../gtk2_ardour/icons $Resources
395 cp -r ../../gtk2_ardour/pixmaps $Resources
396
397 # shared stuff
398 cp -R ../../gtk2_ardour/splash.png $Shared
399 cp -R ../../gtk2_ardour/ArdourMono.ttf $Shared
400
401 # go through and recursively remove any .svn dirs in the bundle
402 for svndir in `find $APPDIR -name .svn -type dir`; do
403     rm -rf $svndir
404 done
405
406 # now fix up the executables
407 echo "Fixing up executable dependency names ..."
408 executables=$MAIN_EXECUTABLE
409 if test x$SAE != x ; then
410     executables="$executables"
411 fi
412
413 for exe in $executables; do
414     EXE=$APPROOT/MacOS/$exe
415     changes=""
416     for lib in `otool -L $EXE | egrep "($GTKSTACK_ROOT|$ARDOURSTACK_ROOT|/opt/|/local/|libs/)" | awk '{print $1}' | grep -v 'libjack\.'` ; do
417       base=`basename $lib`
418       changes="$changes -change $lib @executable_path/../lib/$base"
419     done
420     if test "x$changes" != "x" ; then
421         install_name_tool $changes $EXE
422     fi
423 done
424
425 echo "Fixing up library names ..."
426 # now do the same for all the libraries we include
427 for libdir in $Frameworks $Frameworks/modules $Surfaces $Panners ; do
428
429     libbase=`basename $libdir`
430     
431     for dylib in $libdir/*.dylib $libdir/*.so ; do
432         
433        # skip symlinks
434         
435         if test -L $dylib ; then
436             continue
437         fi
438         
439         # change all the dependencies
440         
441         changes=""
442         for lib in `otool -L $dylib | egrep "($GTKSTACK_ROOT|$ARDOURSTACK_ROOT|/opt/|/local/|libs/)" | awk '{print $1}' | grep -v 'libjack\.'` ; do
443             base=`basename $lib`
444             if echo $lib | grep -s libbase; then
445                 changes="$changes -change $lib @executable_path/../$libbase/$base"
446             else
447                 changes="$changes -change $lib @executable_path/../lib/$base"
448             fi
449         done
450         
451         if test "x$changes" != x ; then
452             if  install_name_tool $changes $dylib ; then
453                 :
454             else
455                 exit 1
456             fi
457         fi
458         
459         # now the change what the library thinks its own name is
460         
461         base=`basename $dylib`
462         install_name_tool -id @executable_path/../$libbase/$base $dylib
463     done
464 done
465
466 #
467 # and now ... the DMG
468
469
470 rm -rf $PRODUCT_PKG_DIR
471 mkdir $PRODUCT_PKG_DIR
472
473 if [ x$SAE != x ] ; then
474         
475     # SAE packaging
476     
477     echo "Creating SAE packaging directory"
478     mv $APPDIR $PRODUCT_PKG_DIR/Ardour3-SAE.app
479     cp HowToInstallArdourSAE.pdf "$PRODUCT_PKG_DIR/How To Install Ardour SAE.pdf"
480     cp SAE-de-keypad.pdf "$PRODUCT_PKG_DIR/Ardour SAE Shortcuts (keypad).pdf"
481     cp SAE-de-nokeypad.pdf "$PRODUCT_PKG_DIR/Ardour SAE Shortcuts.pdf"
482     
483 elif [ x$MIXBUS != x ] ; then
484
485      # Mixbus packaging
486
487     echo "Creating Mixbus packaging directory"
488     mv $APPDIR $PRODUCT_PKG_DIR/
489     cp MixBus_Install_QuickStart.pdf "$PRODUCT_PKG_DIR/Mixbus Install & Quick Start Guide.pdf"
490
491 else 
492
493     echo "Creating $APPNAME packaging directory"
494     mv $APPDIR $PRODUCT_PKG_DIR/
495
496 fi
497
498 echo "Building DMG ..."
499
500 # UC_DMG=$APPNAME-${release_version}-${svn_version}-UC.dmg
501 # FINAL_DMG=$APPNAME-${release_version}-${svn_version}.dmg
502 UC_DMG=$APPNAME-${release_version}-${svn_version}.dmg
503 VOLNAME=$APPNAME-$release_version
504
505 # TODO use mktemp
506 MNTPATH=`mktemp -d -t ardourimg`
507 TMPDMG=`mktemp -t ardour`
508 ICNSTMP=`mktemp -t ardouricon`
509 DMGSIZE=$[ `du -sm "$PRODUCT_PKG_DIR" | cut -f 1` * 1049 / 1000 + 3 ]
510
511 rm -f $UC_DMG "$TMPDMG" "${TMPDMG}.dmg" "$ICNSTMP"
512 rm -rf "$MNTPATH"
513 mkdir -p "$MNTPATH"
514
515 TMPDMG="${TMPDMG}.dmg"
516
517 hdiutil create -megabytes $DMGSIZE "$TMPDMG"
518 DiskDevice=$(hdid -nomount "$TMPDMG" | grep Apple_HFS | cut -f 1 -d ' ')
519 newfs_hfs -v "${VOLNAME}" "${DiskDevice}"
520 mount -t hfs "${DiskDevice}" "${MNTPATH}"
521
522 cp -r ${PRODUCT_PKG_DIR}/${APPDIR} "${MNTPATH}" || exit
523 mkdir "${MNTPATH}/.background"
524 cp -vi dmgbg.png "${MNTPATH}/.background/dmgbg.png"
525
526 echo "setting DMG background ..."
527
528 echo '
529    tell application "Finder"
530      tell disk "'${VOLNAME}'"
531            open
532            set current view of container window to icon view
533            set toolbar visible of container window to false
534            set statusbar visible of container window to false
535            set the bounds of container window to {400, 200, 800, 440}
536            set theViewOptions to the icon view options of container window
537            set arrangement of theViewOptions to not arranged
538            set icon size of theViewOptions to 64
539            set background picture of theViewOptions to file ".background:dmgbg.png"
540            make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"}
541            set position of item "'${APPDIR}'" of container window to {90, 100}
542            set position of item "Applications" of container window to {310, 100}
543            close
544            open
545            update without registering applications
546            delay 5
547            eject
548      end tell
549    end tell
550 ' | osascript
551
552 chmod -Rf go-w "${MNTPATH}"
553 sync
554
555 echo "compressing Image ..."
556
557 # Umount the image
558 umount "${DiskDevice}"
559 hdiutil eject "${DiskDevice}"
560 # Create a read-only version, use zlib compression
561 hdiutil convert -format UDZO "${TMPDMG}" -imagekey zlib-level=9 -o "${UC_DMG}"
562 # Delete the temporary files
563 rm "$TMPDMG"
564 rmdir "$MNTPATH"
565
566 echo "setting file icon ..."
567
568 cp ${PRODUCT_PKG_DIR}/$Resources/appIcon.icns ${ICNSTMP}.icns
569 /usr/bin/sips -i ${ICNSTMP}.icns
570 /Developer/Tools/DeRez -only icns ${ICNSTMP}.icns > ${ICNSTMP}.rsrc
571 /Developer/Tools/Rez -append ${ICNSTMP}.rsrc -o "$UC_DMG"
572 /Developer/Tools/SetFile -a C "$UC_DMG"
573
574 rm ${ICNSTMP}.icns ${ICNSTMP}.rsrc
575
576 echo
577 echo "packaging suceeded."
578 ls -l "$UC_DMG"
579
580 echo "Done."
581 exit