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 libMagick++ "$dest"
83     universal_copy_lib $ENV libMagickCore "$dest"
84     universal_copy_lib $ENV libMagickWand "$dest"
85     universal_copy_lib $ENV libssh "$dest"
86     universal_copy_lib $ENV libwx "$dest"
87     universal_copy_lib $ENV libfontconfig "$dest"
88     universal_copy_lib $ENV libfreetype "$dest"
89     universal_copy_lib $ENV libexpat "$dest"
90     universal_copy_lib $ENV libltdl "$dest"
91     universal_copy_lib $ENV libxmlsec1 "$dest"
92     universal_copy_lib $ENV libcurl "$dest"
93     universal_copy_lib $ENV libffi "$dest"
94     universal_copy_lib $ENV libpango "$dest"
95     universal_copy_lib $ENV libcairo "$dest"
96     universal_copy_lib $ENV libpixman "$dest"
97     universal_copy_lib $ENV libharfbuzz "$dest"
98     universal_copy_lib $ENV libsamplerate "$dest"
99     universal_copy_lib $ENV libicui18n "$dest"
100     universal_copy_lib $ENV libicudata "$dest"
101     universal_copy_lib $ENV libicuio "$dest"
102     universal_copy_lib $ENV libicule "$dest"
103     universal_copy_lib $ENV libiculx "$dest"
104     universal_copy_lib $ENV libicutest "$dest"
105     universal_copy_lib $ENV libicutu "$dest"
106     universal_copy_lib $ENV libicuuc "$dest"
107     universal_copy_lib $ENV libFLAC "$dest"
108     universal_copy_lib $ENV libvorbis "$dest"
109     universal_copy_lib $ENV libogg "$dest"
110 }
111
112 # @param #1 directory to copy to
113 function copy_resources {
114     local dest="$1"
115     cp $ROOT/32/src/dcpomatic/graphics/osx/dcpomatic_small.png "$dest"
116     cp $ROOT/32/src/dcpomatic/graphics/osx/dcpomatic2.icns "$dest"
117     cp $ROOT/32/src/dcpomatic/graphics/osx/dcpomatic2_kdm.icns "$dest"
118     cp $ROOT/32/src/dcpomatic/graphics/osx/dcpomatic2_server.icns "$dest"
119     cp $ROOT/32/src/dcpomatic/graphics/osx/dcpomatic2_player.icns "$dest"
120     cp $ROOT/32/src/dcpomatic/graphics/osx/dcpomatic2_batch.icns "$dest"
121     cp $ROOT/32/src/dcpomatic/graphics/osx/preferences/colour_conversions.png "$dest"
122     cp $ROOT/32/src/dcpomatic/graphics/osx/preferences/defaults.png "$dest"
123     cp $ROOT/32/src/dcpomatic/graphics/osx/preferences/kdm_email.png "$dest"
124     cp $ROOT/32/src/dcpomatic/graphics/osx/preferences/email.png "$dest"
125     cp $ROOT/32/src/dcpomatic/graphics/osx/preferences/servers.png "$dest"
126     cp $ROOT/32/src/dcpomatic/graphics/osx/preferences/tms.png "$dest"
127     cp $ROOT/32/src/dcpomatic/graphics/osx/preferences/keys.png "$dest"
128     cp $ROOT/32/src/dcpomatic/graphics/osx/preferences/cover_sheet.png "$dest"
129     cp $ROOT/32/src/dcpomatic/graphics/osx/preferences/notifications.png "$dest"
130     cp $ROOT/32/src/dcpomatic/fonts/LiberationSans-Regular.ttf "$dest"
131     cp $ROOT/32/src/dcpomatic/fonts/LiberationSans-Italic.ttf "$dest"
132     cp $ROOT/32/src/dcpomatic/fonts/LiberationSans-Bold.ttf "$dest"
133     cp $ROOT/32/src/dcpomatic/graphics/splash.png "$dest"
134
135     # i18n: DCP-o-matic .mo files
136     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 ar_LB fi_FI el_GR; do
137         mkdir -p "$dest/$lang/LC_MESSAGES"
138         cp $ROOT/32/src/dcpomatic/build/src/lib/mo/$lang/*.mo "$dest/$lang/LC_MESSAGES"
139         cp $ROOT/32/src/dcpomatic/build/src/wx/mo/$lang/*.mo "$dest/$lang/LC_MESSAGES"
140         cp $ROOT/32/src/dcpomatic/build/src/tools/mo/$lang/*.mo "$dest/$lang/LC_MESSAGES"
141     done
142
143     # i18n: wxWidgets .mo files
144     for lang in de es fr it sv nl ru pl da cs; do
145         mkdir "$dest/$lang"
146         cp $ENV/64/share/locale/$lang/LC_MESSAGES/wxstd.mo "$dest/$lang"
147     done
148 }
149
150 # param $1 list of things that link to other things
151 function relink {
152     to_relink=`echo $to_relink | sed -e "s/\+//g"`
153     local linkers=("$@")
154
155     for obj in "${linkers[@]}"; do
156         deps=`otool -L "$obj" | awk '{print $1}' | egrep "($to_relink)" | egrep "($ENV|$ROOT|boost|libicu)"`
157         changes=""
158         for dep in $deps; do
159             base=`basename $dep`
160             # $dep will be a path within 64/; make a 32/ path too
161             dep32=`echo $dep | sed -e "s/\/64\//\/32\//g"`
162             changes="$changes -change $dep @executable_path/../Frameworks/$base -change $dep32 @executable_path/../Frameworks/$base"
163         done
164         if test "x$changes" != "x"; then
165             install_name_tool $changes -id `basename "$obj"` "$obj"
166         fi
167     done
168 }
169
170 # @param #1 .app directory
171 # @param #2 full name e.g. DCP-o-matic Batch Converter
172 function make_dmg {
173     local appdir="$1"
174     local full_name="$2"
175     tmp_dmg=dcpomatic_tmp.dmg
176     dmg="$full_name $version.dmg"
177     vol_name=DCP-o-matic-$version
178
179     codesign --deep --force --verify --verbose --sign "Developer ID Application: Carl Hetherington (R82DXSR997)" "$appdir"
180     if [ "$?" != "0" ]; then
181         echo "Failed to sign .app"
182         exit 1
183     fi
184
185     mkdir -p $vol_name
186     cp -a "$appdir" $vol_name
187     ln -s /Applications "$vol_name/Applications"
188     cat<<EOF > "$vol_name/READ ME.txt"
189 Welcome to DCP-o-matic!  The first time you run the program there may be
190 a long (several-minute) delay while OS X checks the code for viruses and
191 other malware.  Please be patient!
192 EOF
193     cat<<EOF > "$vol_name/READ ME.de_DE.txt"
194 Beim erstmaligen Start der DCP-o-matic Anwendungen kann ein längerer
195 Verifikationsvorgang auftreten.  Dies ist von der OS X Sicherheitsumgebung
196 'Gatekeeper' verursacht.  Dieser je nach Rechner teils minutenlange
197 Verifikationsvorgang ist gegenwärtig normal und nicht zu umgehen,
198 es ist kein Programmfehler.  Warten sie die Verifikation für jede der
199 DCP-o-matic Anwendungen ab, bei weiteren Programmstarts wird sie nicht
200 mehr auftreten.
201 EOF
202
203     rm -f $tmp_dmg "$dmg"
204     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
205     attach=$(hdiutil attach -readwrite -noverify -noautoopen $tmp_dmg)
206     device=`echo $attach | egrep '^/dev/' | sed 1q | awk '{print $5}'`
207     sleep 5
208
209     echo '
210   tell application "Finder"
211     tell disk "'$vol_name'"
212            open
213            set current view of container window to icon view
214            set toolbar visible of container window to false
215            set statusbar visible of container window to false
216            set the bounds of container window to {400, 200, 940, 300}
217            set theViewOptions to the icon view options of container window
218            set arrangement of theViewOptions to not arranged
219            set icon size of theViewOptions to 64
220            set position of item "'$appdir'" of container window to {90, 80}
221            set position of item "Applications" of container window to {265, 80}
222            set position of item "READ ME.txt" of container window to {430, 80}
223            set position of item "READ ME.de_DE.txt" of container window to {595, 80}
224            close
225            open
226            update without registering applications
227            delay 5
228      end tell
229    end tell
230 ' | osascript
231
232     chmod -Rf go-w /Volumes/"$vol_name"/"$appdir"
233     sync
234
235     hdiutil eject $device
236     hdiutil convert -format UDZO $tmp_dmg -imagekey zlib-level=9 -o "$dmg"
237     sips -i "$appdir/Contents/Resources/dcpomatic2.icns"
238     DeRez -only icns "$appdir/Contents/Resources/dcpomatic2.icns" > "$appdir/Contents/Resources/DCP-o-matic.rsrc"
239     Rez -append "$appdir/Contents/Resources/DCP-o-matic.rsrc" -o "$dmg"
240     SetFile -a C "$dmg"
241     codesign --verify --verbose --sign "Developer ID Application: Carl Hetherington (R82DXSR997)" "$dmg"
242     if [ "$?" != "0" ]; then
243         echo "Failed to sign .dmg"
244         exit 1
245     fi
246     rm $tmp_dmg
247     rm -rf $vol_name
248 }
249
250 # @param #1 appdir
251 function setup {
252     appdir="$1"
253     approot="$appdir/Contents"
254     rm -rf "$appdir"
255     mkdir -p "$approot/MacOS"
256     mkdir -p "$approot/Frameworks"
257     mkdir -p "$approot/Resources"
258
259     to_relink="dcpomatic"
260     copy_libs "$approot/Frameworks"
261     copy_resources "$approot/Resources"
262 }
263
264 # DCP-o-matic main
265 setup "DCP-o-matic 2.app"
266 universal_copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2 "$approot/MacOS"
267 universal_copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_cli "$approot/MacOS"
268 universal_copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_create "$approot/MacOS"
269 universal_copy $ROOT bin/ffprobe "$approot/MacOS"
270 cp $ROOT/32/src/dcpomatic/build/platform/osx/dcpomatic2.Info.plist "$approot/Info.plist"
271 rl=("$approot/MacOS/dcpomatic2" "$approot/MacOS/dcpomatic2_cli" "$approot/MacOS/dcpomatic2_create" "$approot/MacOS/ffprobe" "$approot/Frameworks/"*.dylib)
272 relink "${rl[@]}"
273 make_dmg "$appdir" "DCP-o-matic"
274
275 # DCP-o-matic KDM Creator
276 setup "DCP-o-matic 2 KDM Creator.app"
277 universal_copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_kdm "$approot/MacOS"
278 universal_copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_kdm_cli "$approot/MacOS"
279 cp $ROOT/32/src/dcpomatic/build/platform/osx/dcpomatic2_kdm.Info.plist "$approot/Info.plist"
280 rl=("$approot/MacOS/dcpomatic2_kdm" "$approot/MacOS/dcpomatic2_kdm_cli" "$approot/Frameworks/"*.dylib)
281 relink "${rl[@]}"
282 make_dmg "$appdir" "DCP-o-matic KDM Creator"
283
284 # DCP-o-matic Encode Server
285 setup "DCP-o-matic 2 Encode Server.app"
286 universal_copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_server "$approot/MacOS"
287 universal_copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_server_cli "$approot/MacOS"
288 cp $ROOT/32/src/dcpomatic/build/platform/osx/dcpomatic2_server.Info.plist "$approot/Info.plist"
289 rl=("$approot/MacOS/dcpomatic2_server" "$approot/MacOS/dcpomatic2_server_cli" "$approot/Frameworks/"*.dylib)
290 relink "${rl[@]}"
291 make_dmg "$appdir" "DCP-o-matic Encode Server"
292
293 # DCP-o-matic Batch Converter
294 setup "DCP-o-matic 2 Batch converter.app"
295 universal_copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_batch "$approot/MacOS"
296 cp $ROOT/32/src/dcpomatic/build/platform/osx/dcpomatic2_batch.Info.plist "$approot/Info.plist"
297 rl=("$approot/MacOS/dcpomatic2_batch" "$approot/Frameworks/"*.dylib)
298 relink "${rl[@]}"
299 make_dmg "$appdir" "DCP-o-matic Batch Converter"
300
301 # DCP-o-matic Player
302 setup "DCP-o-matic 2 Player.app"
303 universal_copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_player "$approot/MacOS"
304 cp $ROOT/32/src/dcpomatic/build/platform/osx/dcpomatic2_player.Info.plist "$approot/Info.plist"
305 rl=("$approot/MacOS/dcpomatic2_player" "$approot/Frameworks/"*.dylib)
306 relink "${rl[@]}"
307 make_dmg "$appdir" "DCP-o-matic Player"