Allow thin builds (target name osx-64).
[dcpomatic.git] / platform / osx / make_dmg.sh
1 #!/bin/bash
2 #
3 # Syntax: make_dmg.sh <builddir> <type>
4 # where <type> is universal or thin
5 #
6 # e.g. make_dmg.sh /Users/carl/cdist
7
8 # Don't set -e here as egrep (used a few times) returns 1 if no matches
9 # were found.
10
11 version=`git describe --tags --abbrev=0 | sed -e "s/v//"`
12
13 # DMG size in megabytes
14 DMG_SIZE=256
15 ENV=/Users/carl/Environments/dcpomatic
16 ROOT=$1
17 TYPE=$2
18
19 if [ "$TYPE" != "universal" -a "$TYPE" != "thin" ]; then
20     echo "Syntax: $0 <builddir> <type>"
21     echo "where <type> is universal or thin"
22     exit 1
23 fi
24
25 # This is our work area for making up the .dmgs
26 mkdir -p build/platform/osx
27 cd build/platform/osx
28
29 function copy {
30     case $TYPE in
31         universal)
32             for f in $1/32/$2; do
33                 if [ -h $f ]; then
34                     ln -s $(readlink $f) "$3/`basename $f`"
35                 else
36                     g=`echo $f | sed -e "s/\/32\//\/64\//g"`
37                     mkdir -p "$3"
38                     lipo -create $f $g -output "$3/`basename $f`"
39                 fi
40             done
41             ;;
42         thin)
43             if [ -h $1/$2 ]; then
44                 ln -s $(readlink $1/$2) "$3/`basename $f`"
45             else
46                 cp $1/$2 "$3"
47             fi
48             ;;
49     esac
50 }
51
52 function copy_lib_root {
53     case $TYPE in
54         universal)
55             for f in $ROOT/32/lib/$1*.dylib; do
56                 if [ -h $f ]; then
57                     ln -s $(readlink $f) "$2/`basename $f`"
58                 else
59                     g=`echo $f | sed -e "s/\/32\//\/64\//g"`
60                     mkdir -p "$2"
61                     lipo -create $f $g -output "$2/`basename $f`"
62                 fi
63             done
64             ;;
65         thin)
66             for f in $ROOT/lib/$1*.dylib; do
67                 if [ -h $f ]; then
68                     ln -s $(readlink $f) "$2/`basename $f`"
69                 else
70                     mkdir -p "$2"
71                     cp $f "$2"
72                 fi
73             done
74             ;;
75     esac
76     to_relink="$to_relink|$1"
77 }
78
79 function copy_lib_env {
80     case $TYPE in
81         universal)
82             for f in $ENV/32/lib/$1*.dylib; do
83                 if [ -h $f ]; then
84                     ln -s $(readlink $f) "$2/`basename $f`"
85                 else
86                     g=`echo $f | sed -e "s/\/32\//\/64\//g"`
87                     mkdir -p "$2"
88                     lipo -create $f $g -output "$2/`basename $f`"
89                 fi
90             done
91             ;;
92         thin)
93             for f in $ENV/64/lib/$1*.dylib; do
94                 if [ -h $f ]; then
95                     ln -s $(readlink $f) "$2/`basename $f`"
96                 else
97                     mkdir -p "$2"
98                     cp $f "$2"
99                 fi
100             done
101             ;;
102     esac
103     to_relink="$to_relink|$1"
104 }
105
106 # @param #1 directory to copy to
107 function copy_libs {
108     local dest="$1"
109     copy_lib_root libcxml "$dest"
110     copy_lib_root libdcp-1.0 "$dest"
111     copy_lib_root libasdcp-cth "$dest"
112     copy_lib_root libkumu-cth "$dest"
113     copy_lib_root libsub "$dest"
114     copy_lib_root libopenjp2 "$dest"
115     copy_lib_root libavdevice "$dest"
116     copy_lib_root libavformat "$dest"
117     copy_lib_root libavfilter "$dest"
118     copy_lib_root libavutil "$dest"
119     copy_lib_root libavcodec "$dest"
120     copy_lib_root libswscale "$dest"
121     copy_lib_root libpostproc "$dest"
122     copy_lib_root libswresample "$dest"
123     copy $ROOT src/dcpomatic/build/src/lib/libdcpomatic2.dylib "$dest"
124     copy $ROOT src/dcpomatic/build/src/wx/libdcpomatic2-wx.dylib "$dest"
125     copy_lib_env libboost_system "$dest"
126     copy_lib_env libboost_filesystem "$dest"
127     copy_lib_env libboost_thread "$dest"
128     copy_lib_env libboost_date_time "$dest"
129     copy_lib_env libboost_locale "$dest"
130     copy_lib_env libboost_regex "$dest"
131     copy_lib_env libxml++ "$dest"
132     copy_lib_env libxslt "$dest"
133     copy_lib_env libxml2 "$dest"
134     copy_lib_env libglibmm-2.4 "$dest"
135     copy_lib_env libgobject "$dest"
136     copy_lib_env libgthread "$dest"
137     copy_lib_env libgmodule "$dest"
138     copy_lib_env libsigc "$dest"
139     copy_lib_env libglib-2 "$dest"
140     copy_lib_env libintl "$dest"
141     copy_lib_env libsndfile "$dest"
142     copy_lib_env libssh "$dest"
143     copy_lib_env libwx "$dest"
144     copy_lib_env libfontconfig "$dest"
145     copy_lib_env libfreetype "$dest"
146     copy_lib_env libexpat "$dest"
147     copy_lib_env libltdl "$dest"
148     copy_lib_env libxmlsec1 "$dest"
149     copy_lib_env libcurl "$dest"
150     copy_lib_env libffi "$dest"
151     copy_lib_env libpango "$dest"
152     copy_lib_env libcairo "$dest"
153     copy_lib_env libpixman "$dest"
154     copy_lib_env libharfbuzz "$dest"
155     copy_lib_env libsamplerate "$dest"
156     copy_lib_env libicui18n "$dest"
157     copy_lib_env libicudata "$dest"
158     copy_lib_env libicuio "$dest"
159     copy_lib_env libicule "$dest"
160     copy_lib_env libiculx "$dest"
161     copy_lib_env libicutest "$dest"
162     copy_lib_env libicutu "$dest"
163     copy_lib_env libicuuc "$dest"
164     copy_lib_env libFLAC "$dest"
165     copy_lib_env libvorbis "$dest"
166     copy_lib_env libogg "$dest"
167 }
168
169 # @param #1 directory to copy to
170 function copy_resources {
171     local dest="$1"
172     case $TYPE in
173         universal)
174             local prefix=$ROOT/32
175             ;;
176         thin)
177             local prefix=$ROOT
178             ;;
179     esac
180     cp $prefix/src/dcpomatic/graphics/osx/dcpomatic_small.png "$dest"
181     cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2.icns "$dest"
182     cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_kdm.icns "$dest"
183     cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_server.icns "$dest"
184     cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_player.icns "$dest"
185     cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_batch.icns "$dest"
186     cp $prefix/src/dcpomatic/graphics/osx/preferences/colour_conversions.png "$dest"
187     cp $prefix/src/dcpomatic/graphics/osx/preferences/defaults.png "$dest"
188     cp $prefix/src/dcpomatic/graphics/osx/preferences/kdm_email.png "$dest"
189     cp $prefix/src/dcpomatic/graphics/osx/preferences/email.png "$dest"
190     cp $prefix/src/dcpomatic/graphics/osx/preferences/servers.png "$dest"
191     cp $prefix/src/dcpomatic/graphics/osx/preferences/tms.png "$dest"
192     cp $prefix/src/dcpomatic/graphics/osx/preferences/keys.png "$dest"
193     cp $prefix/src/dcpomatic/graphics/osx/preferences/cover_sheet.png "$dest"
194     cp $prefix/src/dcpomatic/graphics/osx/preferences/notifications.png "$dest"
195     cp $prefix/src/dcpomatic/graphics/osx/preferences/accounts.png "$dest"
196     cp $prefix/src/dcpomatic/graphics/osx/preferences/locations.png "$dest"
197     cp $prefix/src/dcpomatic/fonts/LiberationSans-Regular.ttf "$dest"
198     cp $prefix/src/dcpomatic/fonts/LiberationSans-Italic.ttf "$dest"
199     cp $prefix/src/dcpomatic/fonts/LiberationSans-Bold.ttf "$dest"
200     cp $prefix/src/dcpomatic/fonts/fonts.conf.osx "$dest"/fonts.conf
201     cp $prefix/src/dcpomatic/graphics/splash.png "$dest"
202     cp $prefix/src/dcpomatic/graphics/zoom.png "$dest"
203     cp $prefix/src/dcpomatic/graphics/zoom_all.png "$dest"
204     cp $prefix/src/dcpomatic/graphics/select.png "$dest"
205     cp $prefix/src/dcpomatic/graphics/snap.png "$dest"
206     cp $prefix/src/dcpomatic/graphics/sequence.png "$dest"
207     cp $prefix/src/dcpomatic/graphics/me.jpg "$dest"
208
209     # i18n: DCP-o-matic .mo files
210     for lang in de_DE es_ES fr_FR it_IT sv_SE nl_NL ru_RU pl_PL da_DK pt_PT pt_BR sk_SK cs_CZ uk_UA zh_CN tr_TR; do
211         mkdir -p "$dest/$lang/LC_MESSAGES"
212         cp $prefix/src/dcpomatic/build/src/lib/mo/$lang/*.mo "$dest/$lang/LC_MESSAGES"
213         cp $prefix/src/dcpomatic/build/src/wx/mo/$lang/*.mo "$dest/$lang/LC_MESSAGES"
214         cp $prefix/src/dcpomatic/build/src/tools/mo/$lang/*.mo "$dest/$lang/LC_MESSAGES"
215     done
216
217     # i18n: wxWidgets .mo files
218     for lang in de es fr it sv nl ru pl da cs; do
219         mkdir "$dest/$lang"
220         cp $ENV/64/share/locale/$lang/LC_MESSAGES/wxstd.mo "$dest/$lang"
221     done
222 }
223
224 # param $1 list of things that link to other things
225 function relink {
226     to_relink=`echo $to_relink | sed -e "s/\+//g"`
227     local linkers=("$@")
228
229     for obj in "${linkers[@]}"; do
230         deps=`otool -L "$obj" | awk '{print $1}' | egrep "($to_relink)" | egrep "($ENV|$ROOT|boost|libicu)"`
231         changes=""
232         for dep in $deps; do
233             base=`basename $dep`
234             if [ "$TYPE" == "universal" ]; then
235                 # $dep will be a path within 64/; make a 32/ path too
236                 dep32=`echo $dep | sed -e "s/\/64\//\/32\//g"`
237                 changes="$changes -change $dep @executable_path/../Frameworks/$base -change $dep32 @executable_path/../Frameworks/$base"
238             else
239                 changes="$changes -change $dep @executable_path/../Frameworks/$base"
240             fi
241         done
242         if test "x$changes" != "x"; then
243             install_name_tool $changes -id `basename "$obj"` "$obj"
244         fi
245     done
246 }
247
248 # @param #1 .app directory
249 # @param #2 full name e.g. DCP-o-matic Batch Converter
250 function make_dmg {
251     local appdir="$1"
252     local full_name="$2"
253     tmp_dmg=dcpomatic_tmp.dmg
254     dmg="$full_name $version.dmg"
255     vol_name=DCP-o-matic-$version
256
257     codesign --deep --force --verify --verbose --sign "Developer ID Application: Carl Hetherington (R82DXSR997)" "$appdir"
258     if [ "$?" != "0" ]; then
259         echo "Failed to sign .app"
260         exit 1
261     fi
262
263     mkdir -p $vol_name
264     cp -a "$appdir" $vol_name
265     ln -s /Applications "$vol_name/Applications"
266     cat<<EOF > "$vol_name/READ ME.txt"
267 Welcome to DCP-o-matic!  The first time you run the program there may be
268 a long (several-minute) delay while OS X checks the code for viruses and
269 other malware.  Please be patient!
270 EOF
271     cat<<EOF > "$vol_name/READ ME.de_DE.txt"
272 Beim erstmaligen Start der DCP-o-matic Anwendungen kann ein längerer
273 Verifikationsvorgang auftreten.  Dies ist von der OS X Sicherheitsumgebung
274 'Gatekeeper' verursacht.  Dieser je nach Rechner teils minutenlange
275 Verifikationsvorgang ist gegenwärtig normal und nicht zu umgehen,
276 es ist kein Programmfehler.  Warten sie die Verifikation für jede der
277 DCP-o-matic Anwendungen ab, bei weiteren Programmstarts wird sie nicht
278 mehr auftreten.
279 EOF
280
281     rm -f $tmp_dmg "$dmg"
282     hdiutil create -srcfolder $vol_name -volname $vol_name -fs HFS+ -fsargs "-c c=64,a=16,e=16" -format UDRW -size $DMG_SIZE $tmp_dmg
283     attach=$(hdiutil attach -readwrite -noverify -noautoopen $tmp_dmg)
284     device=`echo $attach | egrep '^/dev/' | sed 1q | awk '{print $5}'`
285     sleep 5
286
287     echo '
288   tell application "Finder"
289     tell disk "'$vol_name'"
290            open
291            set current view of container window to icon view
292            set toolbar visible of container window to false
293            set statusbar visible of container window to false
294            set the bounds of container window to {400, 200, 940, 300}
295            set theViewOptions to the icon view options of container window
296            set arrangement of theViewOptions to not arranged
297            set icon size of theViewOptions to 64
298            set position of item "'$appdir'" of container window to {90, 80}
299            set position of item "Applications" of container window to {265, 80}
300            set position of item "READ ME.txt" of container window to {430, 80}
301            set position of item "READ ME.de_DE.txt" of container window to {595, 80}
302            close
303            open
304            update without registering applications
305            delay 5
306      end tell
307    end tell
308 ' | osascript
309
310     chmod -Rf go-w /Volumes/"$vol_name"/"$appdir"
311     sync
312
313     hdiutil eject $device
314     hdiutil convert -format UDZO $tmp_dmg -imagekey zlib-level=9 -o "$dmg"
315     sips -i "$appdir/Contents/Resources/dcpomatic2.icns"
316     DeRez -only icns "$appdir/Contents/Resources/dcpomatic2.icns" > "$appdir/Contents/Resources/DCP-o-matic.rsrc"
317     Rez -append "$appdir/Contents/Resources/DCP-o-matic.rsrc" -o "$dmg"
318     SetFile -a C "$dmg"
319     xattr -c "$dmg"
320     codesign --verify --verbose --sign "Developer ID Application: Carl Hetherington (R82DXSR997)" "$dmg"
321     if [ "$?" != "0" ]; then
322         echo "Failed to sign .dmg"
323         exit 1
324     fi
325     rm $tmp_dmg
326     rm -rf $vol_name
327 }
328
329 # @param #1 appdir
330 function setup {
331     appdir="$1"
332     approot="$appdir/Contents"
333     rm -rf "$appdir"
334     mkdir -p "$approot/MacOS"
335     mkdir -p "$approot/Frameworks"
336     mkdir -p "$approot/Resources"
337
338     to_relink="dcpomatic"
339     copy_libs "$approot/Frameworks"
340     copy_resources "$approot/Resources"
341 }
342
343 case $TYPE in
344     universal)
345         prefix=$ROOT/32
346         ;;
347     thin)
348         prefix=$ROOT
349         ;;
350 esac
351
352 # DCP-o-matic main
353 setup "DCP-o-matic 2.app"
354 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2 "$approot/MacOS"
355 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_cli "$approot/MacOS"
356 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_create "$approot/MacOS"
357 copy $ROOT bin/ffprobe "$approot/MacOS"
358 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2.Info.plist "$approot/Info.plist"
359 rl=("$approot/MacOS/dcpomatic2" "$approot/MacOS/dcpomatic2_cli" "$approot/MacOS/dcpomatic2_create" "$approot/MacOS/ffprobe" "$approot/Frameworks/"*.dylib)
360 relink "${rl[@]}"
361 make_dmg "$appdir" "DCP-o-matic"
362
363 # DCP-o-matic KDM Creator
364 setup "DCP-o-matic 2 KDM Creator.app"
365 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_kdm "$approot/MacOS"
366 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_kdm_cli "$approot/MacOS"
367 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_kdm.Info.plist "$approot/Info.plist"
368 rl=("$approot/MacOS/dcpomatic2_kdm" "$approot/MacOS/dcpomatic2_kdm_cli" "$approot/Frameworks/"*.dylib)
369 relink "${rl[@]}"
370 make_dmg "$appdir" "DCP-o-matic KDM Creator"
371
372 # DCP-o-matic Encode Server
373 setup "DCP-o-matic 2 Encode Server.app"
374 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_server "$approot/MacOS"
375 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_server_cli "$approot/MacOS"
376 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_server.Info.plist "$approot/Info.plist"
377 rl=("$approot/MacOS/dcpomatic2_server" "$approot/MacOS/dcpomatic2_server_cli" "$approot/Frameworks/"*.dylib)
378 relink "${rl[@]}"
379 make_dmg "$appdir" "DCP-o-matic Encode Server"
380
381 # DCP-o-matic Batch Converter
382 setup "DCP-o-matic 2 Batch converter.app"
383 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_batch "$approot/MacOS"
384 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_batch.Info.plist "$approot/Info.plist"
385 rl=("$approot/MacOS/dcpomatic2_batch" "$approot/Frameworks/"*.dylib)
386 relink "${rl[@]}"
387 make_dmg "$appdir" "DCP-o-matic Batch Converter"
388
389 # DCP-o-matic Player
390 setup "DCP-o-matic 2 Player.app"
391 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_player "$approot/MacOS"
392 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_player.Info.plist "$approot/Info.plist"
393 rl=("$approot/MacOS/dcpomatic2_player" "$approot/Frameworks/"*.dylib)
394 relink "${rl[@]}"
395 make_dmg "$appdir" "DCP-o-matic Player"