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