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