3 # Syntax: make_dmg.sh <environment> <builddir> <type> <apple-id> <apple-password>
4 # where <type> is universal or thin
6 # e.g. make_dmg.sh /Users/carl/osx-environment /Users/carl/cdist universal foo@bar.net opensesame
8 # Don't set -e here as egrep (used a few times) returns 1 if no matches
11 version=`git describe --tags --abbrev=0 | sed -e "s/v//"`
13 # DMG size in megabytes
21 if [ "$TYPE" != "universal" -a "$TYPE" != "thin" ]; then
22 echo "Syntax: $0 <builddir> <type>"
23 echo "where <type> is universal or thin"
27 # This is our work area for making up the .dmgs
28 mkdir -p build/platform/osx
36 ln -s $(readlink $f) "$3/`basename $f`"
38 g=`echo $f | sed -e "s/\/32\//\/64\//g"`
40 lipo -create $f $g -output "$3/`basename $f`"
46 ln -s $(readlink $1/$2) "$3/`basename $f`"
54 function copy_lib_root {
57 for f in $ROOT/32/lib/$1*.dylib; do
59 ln -s $(readlink $f) "$2/`basename $f`"
61 g=`echo $f | sed -e "s/\/32\//\/64\//g"`
63 lipo -create $f $g -output "$2/`basename $f`"
68 for f in $ROOT/lib/$1*.dylib; do
70 ln -s $(readlink $f) "$2/`basename $f`"
78 to_relink="$to_relink|$1"
81 function copy_lib_env {
84 for f in $ENV/32/lib/$1*.dylib; do
86 ln -s $(readlink $f) "$2/`basename $f`"
88 g=`echo $f | sed -e "s/\/32\//\/64\//g"`
90 lipo -create $f $g -output "$2/`basename $f`"
95 for f in $ENV/64/lib/$1*.dylib; do
97 ln -s $(readlink $f) "$2/`basename $f`"
105 to_relink="$to_relink|$1"
108 # @param #1 directory to copy to
111 copy_lib_root libcxml "$dest"
112 copy_lib_root libdcp-1.0 "$dest"
113 copy_lib_root libasdcp-carl "$dest"
114 copy_lib_root libkumu-carl "$dest"
115 copy_lib_root libsub "$dest"
116 copy_lib_root libopenjp2 "$dest"
117 copy_lib_root libavdevice "$dest"
118 copy_lib_root libavformat "$dest"
119 copy_lib_root libavfilter "$dest"
120 copy_lib_root libavutil "$dest"
121 copy_lib_root libavcodec "$dest"
122 copy_lib_root libswscale "$dest"
123 copy_lib_root libpostproc "$dest"
124 copy_lib_root libswresample "$dest"
125 copy_lib_root liblwext4 "$dest"
126 copy_lib_root libblockdev "$dest"
127 copy $ROOT src/dcpomatic/build/src/lib/libdcpomatic2.dylib "$dest"
128 copy $ROOT src/dcpomatic/build/src/wx/libdcpomatic2-wx.dylib "$dest"
129 copy_lib_env libboost_system "$dest"
130 copy_lib_env libboost_filesystem "$dest"
131 copy_lib_env libboost_thread "$dest"
132 copy_lib_env libboost_date_time "$dest"
133 copy_lib_env libboost_locale "$dest"
134 copy_lib_env libboost_regex "$dest"
135 copy_lib_env libxml++ "$dest"
136 copy_lib_env libxslt "$dest"
137 copy_lib_env libxml2 "$dest"
138 copy_lib_env libglibmm-2.4 "$dest"
139 copy_lib_env libgobject "$dest"
140 copy_lib_env libgthread "$dest"
141 copy_lib_env libgmodule "$dest"
142 copy_lib_env libsigc "$dest"
143 copy_lib_env libglib-2 "$dest"
144 copy_lib_env libintl "$dest"
145 copy_lib_env libsndfile "$dest"
146 copy_lib_env libssh "$dest"
147 copy_lib_env libwx "$dest"
148 copy_lib_env libfontconfig "$dest"
149 copy_lib_env libfreetype "$dest"
150 copy_lib_env libexpat "$dest"
151 copy_lib_env libltdl "$dest"
152 copy_lib_env libxmlsec1 "$dest"
153 copy_lib_env libcurl "$dest"
154 copy_lib_env libffi "$dest"
155 copy_lib_env libpango "$dest"
156 copy_lib_env libcairo "$dest"
157 copy_lib_env libpixman "$dest"
158 copy_lib_env libharfbuzz "$dest"
159 copy_lib_env libsamplerate "$dest"
160 copy_lib_env libicui18n "$dest"
161 copy_lib_env libicudata "$dest"
162 copy_lib_env libicuio "$dest"
163 copy_lib_env libicule "$dest"
164 copy_lib_env libiculx "$dest"
165 copy_lib_env libicutest "$dest"
166 copy_lib_env libicutu "$dest"
167 copy_lib_env libicuuc "$dest"
168 copy_lib_env libFLAC "$dest"
169 copy_lib_env libvorbis "$dest"
170 copy_lib_env libogg "$dest"
171 copy_lib_env libxerces-c "$dest"
174 # @param #1 directory to copy to
175 function copy_resources {
179 local prefix=$ROOT/32
185 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic_small.png "$dest"
186 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2.icns "$dest"
187 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_kdm.icns "$dest"
188 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_server.icns "$dest"
189 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_player.icns "$dest"
190 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_batch.icns "$dest"
191 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_playlist.icns "$dest"
192 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_disk.icns "$dest"
193 cp $prefix/src/dcpomatic/graphics/osx/preferences/colour_conversions.png "$dest"
194 cp $prefix/src/dcpomatic/graphics/osx/preferences/defaults.png "$dest"
195 cp $prefix/src/dcpomatic/graphics/osx/preferences/kdm_email.png "$dest"
196 cp $prefix/src/dcpomatic/graphics/osx/preferences/email.png "$dest"
197 cp $prefix/src/dcpomatic/graphics/osx/preferences/servers.png "$dest"
198 cp $prefix/src/dcpomatic/graphics/osx/preferences/tms.png "$dest"
199 cp $prefix/src/dcpomatic/graphics/osx/preferences/keys.png "$dest"
200 cp $prefix/src/dcpomatic/graphics/osx/preferences/cover_sheet.png "$dest"
201 cp $prefix/src/dcpomatic/graphics/osx/preferences/notifications.png "$dest"
202 cp $prefix/src/dcpomatic/graphics/osx/preferences/locations.png "$dest"
203 cp $prefix/src/dcpomatic/graphics/osx/preferences/sound.png "$dest"
204 cp $prefix/src/dcpomatic/fonts/LiberationSans-Regular.ttf "$dest"
205 cp $prefix/src/dcpomatic/fonts/LiberationSans-Italic.ttf "$dest"
206 cp $prefix/src/dcpomatic/fonts/LiberationSans-Bold.ttf "$dest"
207 cp $prefix/src/dcpomatic/fonts/fonts.conf.osx "$dest"/fonts.conf
208 cp $prefix/src/dcpomatic/graphics/splash.png "$dest"
209 cp $prefix/src/dcpomatic/graphics/zoom.png "$dest"
210 cp $prefix/src/dcpomatic/graphics/zoom_all.png "$dest"
211 cp $prefix/src/dcpomatic/graphics/select.png "$dest"
212 cp $prefix/src/dcpomatic/graphics/snap.png "$dest"
213 cp $prefix/src/dcpomatic/graphics/sequence.png "$dest"
214 cp $prefix/src/dcpomatic/graphics/me.jpg "$dest"
215 cp -r $prefix/share/libdcp/xsd "$dest"
217 # i18n: DCP-o-matic .mo files
218 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
219 mkdir -p "$dest/$lang/LC_MESSAGES"
220 cp $prefix/src/dcpomatic/build/src/lib/mo/$lang/*.mo "$dest/$lang/LC_MESSAGES"
221 cp $prefix/src/dcpomatic/build/src/wx/mo/$lang/*.mo "$dest/$lang/LC_MESSAGES"
222 cp $prefix/src/dcpomatic/build/src/tools/mo/$lang/*.mo "$dest/$lang/LC_MESSAGES"
225 # i18n: wxWidgets .mo files
226 for lang in de es fr it sv nl ru pl da cs; do
228 cp $ENV/64/share/locale/$lang/LC_MESSAGES/wxstd.mo "$dest/$lang"
232 # param $1 list of things that link to other things
234 to_relink=`echo $to_relink | sed -e "s/\+//g"`
237 for obj in "${linkers[@]}"; do
238 deps=`otool -L "$obj" | awk '{print $1}' | egrep "($to_relink)" | egrep "($ENV|$ROOT|boost|libicu)"`
242 if [ "$TYPE" == "universal" ]; then
243 # $dep will be a path within 64/; make a 32/ path too
244 dep32=`echo $dep | sed -e "s/\/64\//\/32\//g"`
245 changes="$changes -change $dep @executable_path/../Frameworks/$base -change $dep32 @executable_path/../Frameworks/$base"
247 changes="$changes -change $dep @executable_path/../Frameworks/$base"
250 if test "x$changes" != "x"; then
251 install_name_tool $changes -id `basename "$obj"` "$obj"
256 # @param #1 .app directory
257 # @param #2 full name e.g. DCP-o-matic Batch Converter
258 # @param #3 bundle id e.g. com.dcpomatic.batch
263 tmp_dmg=dcpomatic_tmp.dmg
264 dmg="$full_name $version.dmg"
265 vol_name=DCP-o-matic-$version
267 codesign --deep --force --verify --verbose --options runtime --sign "Developer ID Application: Carl Hetherington (R82DXSR997)" "$appdir"
268 if [ "$?" != "0" ]; then
269 echo "Failed to sign .app"
274 cp -a "$appdir" $vol_name
275 ln -s /Applications "$vol_name/Applications"
276 cat<<EOF > "$vol_name/READ ME.txt"
277 Welcome to DCP-o-matic! The first time you run the program there may be
278 a long (several-minute) delay while OS X checks the code for viruses and
279 other malware. Please be patient!
281 cat<<EOF > "$vol_name/READ ME.de_DE.txt"
282 Beim erstmaligen Start der DCP-o-matic Anwendungen kann ein längerer
283 Verifikationsvorgang auftreten. Dies ist von der OS X Sicherheitsumgebung
284 'Gatekeeper' verursacht. Dieser je nach Rechner teils minutenlange
285 Verifikationsvorgang ist gegenwärtig normal und nicht zu umgehen,
286 es ist kein Programmfehler. Warten sie die Verifikation für jede der
287 DCP-o-matic Anwendungen ab, bei weiteren Programmstarts wird sie nicht
291 rm -f $tmp_dmg "$dmg"
292 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
293 attach=$(hdiutil attach -readwrite -noverify -noautoopen $tmp_dmg)
294 device=`echo $attach | egrep '^/dev/' | sed 1q | awk '{print $5}'`
298 tell application "Finder"
299 tell disk "'$vol_name'"
301 set current view of container window to icon view
302 set toolbar visible of container window to false
303 set statusbar visible of container window to false
304 set the bounds of container window to {400, 200, 940, 300}
305 set theViewOptions to the icon view options of container window
306 set arrangement of theViewOptions to not arranged
307 set icon size of theViewOptions to 64
308 set position of item "'$appdir'" of container window to {90, 80}
309 set position of item "Applications" of container window to {265, 80}
310 set position of item "READ ME.txt" of container window to {430, 80}
311 set position of item "READ ME.de_DE.txt" of container window to {595, 80}
314 update without registering applications
320 chmod -Rf go-w /Volumes/"$vol_name"/"$appdir"
323 hdiutil eject $device
324 hdiutil convert -format UDZO $tmp_dmg -imagekey zlib-level=9 -o "$dmg"
325 sips -i "$appdir/Contents/Resources/dcpomatic2.icns"
326 DeRez -only icns "$appdir/Contents/Resources/dcpomatic2.icns" > "$appdir/Contents/Resources/DCP-o-matic.rsrc"
327 Rez -append "$appdir/Contents/Resources/DCP-o-matic.rsrc" -o "$dmg"
332 codesign --verify --verbose --options runtime --sign "Developer ID Application: Carl Hetherington (R82DXSR997)" "$dmg"
334 # We only notarize thin builds, as if we're building universal binaries we must be on an OS
335 # sufficiently old that it can't notarize anyway
336 if [ "$TYPE" == "thin" ]; then
338 id=$(xcrun altool --notarize-app -t osx -f "$dmg" --primary-bundle-id $bundle_id -u $APPLE_ID -p $APPLE_PASSWORD --output-format xml | grep -C1 RequestUUID | tail -n 1 | sed -e "s/<string>//g" | sed -e "s/<\/string>//g")
341 echo "Checking up on $id"
342 status=$(xcrun altool --notarization-info $id -u $APPLE_ID -p $APPLE_PASSWORD --output-format xml)
343 summary=$(echo "$status" | grep -C1 "<key>Status</key>" | tail -n 1 | sed -e "s/ .//g")
345 if [ "$summary" == "<string>invalid</string>" ]; then
346 echo "Notarization failed."
350 if [ "$summary" == "<string>success</string>" ]; then
355 if [ "$N" == "30" ]; then
356 echo "Timed out waiting for notarization"
361 xcrun stapler staple "$dmg"
372 approot="$appdir/Contents"
374 mkdir -p "$approot/MacOS"
375 mkdir -p "$approot/Frameworks"
376 mkdir -p "$approot/Resources"
378 to_relink="dcpomatic"
379 copy_libs "$approot/Frameworks"
380 copy_resources "$approot/Resources"
393 setup "DCP-o-matic 2.app"
394 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2 "$approot/MacOS"
395 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_cli "$approot/MacOS"
396 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_create "$approot/MacOS"
397 copy $ROOT bin/ffprobe "$approot/MacOS"
398 copy $ROOT src/openssl/apps/openssl "$approot/MacOS"
399 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2.Info.plist "$approot/Info.plist"
400 rl=("$approot/MacOS/dcpomatic2" "$approot/MacOS/dcpomatic2_cli" "$approot/MacOS/dcpomatic2_create" "$approot/MacOS/ffprobe" "$approot/Frameworks/"*.dylib)
402 make_dmg "$appdir" "DCP-o-matic" com.dcpomatic
404 # DCP-o-matic KDM Creator
405 setup "DCP-o-matic 2 KDM Creator.app"
406 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_kdm "$approot/MacOS"
407 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_kdm_cli "$approot/MacOS"
408 copy $ROOT src/openssl/apps/openssl "$approot/MacOS"
409 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_kdm.Info.plist "$approot/Info.plist"
410 rl=("$approot/MacOS/dcpomatic2_kdm" "$approot/MacOS/dcpomatic2_kdm_cli" "$approot/Frameworks/"*.dylib)
412 make_dmg "$appdir" "DCP-o-matic KDM Creator" com.dcpomatic.kdm
414 # DCP-o-matic Encode Server
415 setup "DCP-o-matic 2 Encode Server.app"
416 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_server "$approot/MacOS"
417 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_server_cli "$approot/MacOS"
418 copy $ROOT src/openssl/apps/openssl "$approot/MacOS"
419 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_server.Info.plist "$approot/Info.plist"
420 rl=("$approot/MacOS/dcpomatic2_server" "$approot/MacOS/dcpomatic2_server_cli" "$approot/Frameworks/"*.dylib)
422 make_dmg "$appdir" "DCP-o-matic Encode Server" com.dcpomatic.server
424 # DCP-o-matic Batch Converter
425 setup "DCP-o-matic 2 Batch converter.app"
426 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_batch "$approot/MacOS"
427 copy $ROOT src/openssl/apps/openssl "$approot/MacOS"
428 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_batch.Info.plist "$approot/Info.plist"
429 rl=("$approot/MacOS/dcpomatic2_batch" "$approot/Frameworks/"*.dylib)
431 make_dmg "$appdir" "DCP-o-matic Batch Converter" com.dcpomatic.batch
434 setup "DCP-o-matic 2 Player.app"
435 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_player "$approot/MacOS"
436 copy $ROOT src/openssl/apps/openssl "$approot/MacOS"
437 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_player.Info.plist "$approot/Info.plist"
438 rl=("$approot/MacOS/dcpomatic2_player" "$approot/Frameworks/"*.dylib)
440 make_dmg "$appdir" "DCP-o-matic Player" com.dcpomatic.player
442 # DCP-o-matic Playlist Editor
443 setup "DCP-o-matic 2 Playlist Editor.app"
444 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_playlist "$approot/MacOS"
445 copy $ROOT src/openssl/apps/openssl "$approot/MacOS"
446 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_playlist.Info.plist "$approot/Info.plist"
447 rl=("$approot/MacOS/dcpomatic2_playlist" "$approot/Frameworks/"*.dylib)
449 make_dmg "$appdir" "DCP-o-matic Playlist Editor" com.dcpomatic.playlist
451 # DCP-o-matic Disk Writer
452 setup "DCP-o-matic 2 Disk Writer.app"
453 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_disk "$approot/MacOS"
454 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_disk_writer "$approot/MacOS"
455 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_disk.Info.plist "$approot/Info.plist"
456 rl=("$approot/MacOS/dcpomatic2_disk" "$approot/Frameworks/"*.dylib)
458 rl=("$approot/MacOS/dcpomatic2_disk_writer" "$approot/Frameworks/"*.dylib)
460 make_dmg "$appdir" "DCP-o-matic Disk Writer" com.dcpomatic.disk