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