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 $ROOT src/dcpomatic/build/src/lib/libdcpomatic2.dylib "$dest"
126 copy $ROOT src/dcpomatic/build/src/wx/libdcpomatic2-wx.dylib "$dest"
127 copy_lib_env libboost_system "$dest"
128 copy_lib_env libboost_filesystem "$dest"
129 copy_lib_env libboost_thread "$dest"
130 copy_lib_env libboost_date_time "$dest"
131 copy_lib_env libboost_locale "$dest"
132 copy_lib_env libboost_regex "$dest"
133 copy_lib_env libxml++ "$dest"
134 copy_lib_env libxslt "$dest"
135 copy_lib_env libxml2 "$dest"
136 copy_lib_env libglibmm-2.4 "$dest"
137 copy_lib_env libgobject "$dest"
138 copy_lib_env libgthread "$dest"
139 copy_lib_env libgmodule "$dest"
140 copy_lib_env libsigc "$dest"
141 copy_lib_env libglib-2 "$dest"
142 copy_lib_env libintl "$dest"
143 copy_lib_env libsndfile "$dest"
144 copy_lib_env libssh "$dest"
145 copy_lib_env libwx "$dest"
146 copy_lib_env libfontconfig "$dest"
147 copy_lib_env libfreetype "$dest"
148 copy_lib_env libexpat "$dest"
149 copy_lib_env libltdl "$dest"
150 copy_lib_env libxmlsec1 "$dest"
151 copy_lib_env libcurl "$dest"
152 copy_lib_env libffi "$dest"
153 copy_lib_env libpango "$dest"
154 copy_lib_env libcairo "$dest"
155 copy_lib_env libpixman "$dest"
156 copy_lib_env libharfbuzz "$dest"
157 copy_lib_env libsamplerate "$dest"
158 copy_lib_env libicui18n "$dest"
159 copy_lib_env libicudata "$dest"
160 copy_lib_env libicuio "$dest"
161 copy_lib_env libicule "$dest"
162 copy_lib_env libiculx "$dest"
163 copy_lib_env libicutest "$dest"
164 copy_lib_env libicutu "$dest"
165 copy_lib_env libicuuc "$dest"
166 copy_lib_env libFLAC "$dest"
167 copy_lib_env libvorbis "$dest"
168 copy_lib_env libogg "$dest"
169 copy_lib_env libxerces-c "$dest"
172 # @param #1 directory to copy to
173 function copy_resources {
177 local prefix=$ROOT/32
183 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic_small.png "$dest"
184 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2.icns "$dest"
185 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_kdm.icns "$dest"
186 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_server.icns "$dest"
187 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_player.icns "$dest"
188 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_batch.icns "$dest"
189 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_playlist.icns "$dest"
190 cp $prefix/src/dcpomatic/graphics/osx/preferences/colour_conversions.png "$dest"
191 cp $prefix/src/dcpomatic/graphics/osx/preferences/defaults.png "$dest"
192 cp $prefix/src/dcpomatic/graphics/osx/preferences/kdm_email.png "$dest"
193 cp $prefix/src/dcpomatic/graphics/osx/preferences/email.png "$dest"
194 cp $prefix/src/dcpomatic/graphics/osx/preferences/servers.png "$dest"
195 cp $prefix/src/dcpomatic/graphics/osx/preferences/tms.png "$dest"
196 cp $prefix/src/dcpomatic/graphics/osx/preferences/keys.png "$dest"
197 cp $prefix/src/dcpomatic/graphics/osx/preferences/cover_sheet.png "$dest"
198 cp $prefix/src/dcpomatic/graphics/osx/preferences/notifications.png "$dest"
199 cp $prefix/src/dcpomatic/graphics/osx/preferences/locations.png "$dest"
200 cp $prefix/src/dcpomatic/graphics/osx/preferences/sound.png "$dest"
201 cp $prefix/src/dcpomatic/fonts/LiberationSans-Regular.ttf "$dest"
202 cp $prefix/src/dcpomatic/fonts/LiberationSans-Italic.ttf "$dest"
203 cp $prefix/src/dcpomatic/fonts/LiberationSans-Bold.ttf "$dest"
204 cp $prefix/src/dcpomatic/fonts/fonts.conf.osx "$dest"/fonts.conf
205 cp $prefix/src/dcpomatic/graphics/splash.png "$dest"
206 cp $prefix/src/dcpomatic/graphics/zoom.png "$dest"
207 cp $prefix/src/dcpomatic/graphics/zoom_all.png "$dest"
208 cp $prefix/src/dcpomatic/graphics/select.png "$dest"
209 cp $prefix/src/dcpomatic/graphics/snap.png "$dest"
210 cp $prefix/src/dcpomatic/graphics/sequence.png "$dest"
211 cp $prefix/src/dcpomatic/graphics/me.jpg "$dest"
212 cp -r $prefix/share/libdcp/xsd "$dest"
214 # i18n: DCP-o-matic .mo files
215 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
216 mkdir -p "$dest/$lang/LC_MESSAGES"
217 cp $prefix/src/dcpomatic/build/src/lib/mo/$lang/*.mo "$dest/$lang/LC_MESSAGES"
218 cp $prefix/src/dcpomatic/build/src/wx/mo/$lang/*.mo "$dest/$lang/LC_MESSAGES"
219 cp $prefix/src/dcpomatic/build/src/tools/mo/$lang/*.mo "$dest/$lang/LC_MESSAGES"
222 # i18n: wxWidgets .mo files
223 for lang in de es fr it sv nl ru pl da cs; do
225 cp $ENV/64/share/locale/$lang/LC_MESSAGES/wxstd.mo "$dest/$lang"
229 # param $1 list of things that link to other things
231 to_relink=`echo $to_relink | sed -e "s/\+//g"`
234 for obj in "${linkers[@]}"; do
235 deps=`otool -L "$obj" | awk '{print $1}' | egrep "($to_relink)" | egrep "($ENV|$ROOT|boost|libicu)"`
239 if [ "$TYPE" == "universal" ]; then
240 # $dep will be a path within 64/; make a 32/ path too
241 dep32=`echo $dep | sed -e "s/\/64\//\/32\//g"`
242 changes="$changes -change $dep @executable_path/../Frameworks/$base -change $dep32 @executable_path/../Frameworks/$base"
244 changes="$changes -change $dep @executable_path/../Frameworks/$base"
247 if test "x$changes" != "x"; then
248 install_name_tool $changes -id `basename "$obj"` "$obj"
253 # @param #1 .app directory
254 # @param #2 full name e.g. DCP-o-matic Batch Converter
255 # @param #3 bundle id e.g. com.dcpomatic.batch
260 tmp_dmg=dcpomatic_tmp.dmg
261 dmg="$full_name $version.dmg"
262 vol_name=DCP-o-matic-$version
264 codesign --deep --force --verify --verbose --options runtime --sign "Developer ID Application: Carl Hetherington (R82DXSR997)" "$appdir"
265 if [ "$?" != "0" ]; then
266 echo "Failed to sign .app"
271 cp -a "$appdir" $vol_name
272 ln -s /Applications "$vol_name/Applications"
273 cat<<EOF > "$vol_name/READ ME.txt"
274 Welcome to DCP-o-matic! The first time you run the program there may be
275 a long (several-minute) delay while OS X checks the code for viruses and
276 other malware. Please be patient!
278 cat<<EOF > "$vol_name/READ ME.de_DE.txt"
279 Beim erstmaligen Start der DCP-o-matic Anwendungen kann ein längerer
280 Verifikationsvorgang auftreten. Dies ist von der OS X Sicherheitsumgebung
281 'Gatekeeper' verursacht. Dieser je nach Rechner teils minutenlange
282 Verifikationsvorgang ist gegenwärtig normal und nicht zu umgehen,
283 es ist kein Programmfehler. Warten sie die Verifikation für jede der
284 DCP-o-matic Anwendungen ab, bei weiteren Programmstarts wird sie nicht
288 rm -f $tmp_dmg "$dmg"
289 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
290 attach=$(hdiutil attach -readwrite -noverify -noautoopen $tmp_dmg)
291 device=`echo $attach | egrep '^/dev/' | sed 1q | awk '{print $5}'`
295 tell application "Finder"
296 tell disk "'$vol_name'"
298 set current view of container window to icon view
299 set toolbar visible of container window to false
300 set statusbar visible of container window to false
301 set the bounds of container window to {400, 200, 940, 300}
302 set theViewOptions to the icon view options of container window
303 set arrangement of theViewOptions to not arranged
304 set icon size of theViewOptions to 64
305 set position of item "'$appdir'" of container window to {90, 80}
306 set position of item "Applications" of container window to {265, 80}
307 set position of item "READ ME.txt" of container window to {430, 80}
308 set position of item "READ ME.de_DE.txt" of container window to {595, 80}
311 update without registering applications
317 chmod -Rf go-w /Volumes/"$vol_name"/"$appdir"
320 hdiutil eject $device
321 hdiutil convert -format UDZO $tmp_dmg -imagekey zlib-level=9 -o "$dmg"
322 sips -i "$appdir/Contents/Resources/dcpomatic2.icns"
323 DeRez -only icns "$appdir/Contents/Resources/dcpomatic2.icns" > "$appdir/Contents/Resources/DCP-o-matic.rsrc"
324 Rez -append "$appdir/Contents/Resources/DCP-o-matic.rsrc" -o "$dmg"
329 codesign --verify --verbose --options runtime --sign "Developer ID Application: Carl Hetherington (R82DXSR997)" "$dmg"
331 # We only notarize thin builds, as if we're building universal binaries we must be on an OS
332 # sufficiently old that it can't notarize anyway
333 if [ "$TYPE" == "thin" ]; then
335 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")
338 echo "Checking up on $id"
339 status=$(xcrun altool --notarization-info $id -u $APPLE_ID -p $APPLE_PASSWORD --output-format xml)
340 summary=$(echo "$status" | grep -C1 "<key>Status</key>" | tail -n 1 | sed -e "s/ .//g")
342 if [ "$summary" == "<string>invalid</string>" ]; then
343 echo "Notarization failed."
347 if [ "$summary" == "<string>success</string>" ]; then
352 if [ "$N" == "30" ]; then
353 echo "Timed out waiting for notarization"
358 xcrun stapler staple "$dmg"
369 approot="$appdir/Contents"
371 mkdir -p "$approot/MacOS"
372 mkdir -p "$approot/Frameworks"
373 mkdir -p "$approot/Resources"
375 to_relink="dcpomatic"
376 copy_libs "$approot/Frameworks"
377 copy_resources "$approot/Resources"
390 setup "DCP-o-matic 2.app"
391 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2 "$approot/MacOS"
392 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_cli "$approot/MacOS"
393 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_create "$approot/MacOS"
394 copy $ROOT bin/ffprobe "$approot/MacOS"
395 copy $ROOT src/openssl/apps/openssl "$approot/MacOS"
396 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2.Info.plist "$approot/Info.plist"
397 rl=("$approot/MacOS/dcpomatic2" "$approot/MacOS/dcpomatic2_cli" "$approot/MacOS/dcpomatic2_create" "$approot/MacOS/ffprobe" "$approot/Frameworks/"*.dylib)
399 make_dmg "$appdir" "DCP-o-matic" com.dcpomatic
401 # DCP-o-matic KDM Creator
402 setup "DCP-o-matic 2 KDM Creator.app"
403 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_kdm "$approot/MacOS"
404 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_kdm_cli "$approot/MacOS"
405 copy $ROOT src/openssl/apps/openssl "$approot/MacOS"
406 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_kdm.Info.plist "$approot/Info.plist"
407 rl=("$approot/MacOS/dcpomatic2_kdm" "$approot/MacOS/dcpomatic2_kdm_cli" "$approot/Frameworks/"*.dylib)
409 make_dmg "$appdir" "DCP-o-matic KDM Creator" com.dcpomatic.kdm
411 # DCP-o-matic Encode Server
412 setup "DCP-o-matic 2 Encode Server.app"
413 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_server "$approot/MacOS"
414 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_server_cli "$approot/MacOS"
415 copy $ROOT src/openssl/apps/openssl "$approot/MacOS"
416 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_server.Info.plist "$approot/Info.plist"
417 rl=("$approot/MacOS/dcpomatic2_server" "$approot/MacOS/dcpomatic2_server_cli" "$approot/Frameworks/"*.dylib)
419 make_dmg "$appdir" "DCP-o-matic Encode Server" com.dcpomatic.server
421 # DCP-o-matic Batch Converter
422 setup "DCP-o-matic 2 Batch converter.app"
423 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_batch "$approot/MacOS"
424 copy $ROOT src/openssl/apps/openssl "$approot/MacOS"
425 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_batch.Info.plist "$approot/Info.plist"
426 rl=("$approot/MacOS/dcpomatic2_batch" "$approot/Frameworks/"*.dylib)
428 make_dmg "$appdir" "DCP-o-matic Batch Converter" com.dcpomatic.batch
431 setup "DCP-o-matic 2 Player.app"
432 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_player "$approot/MacOS"
433 copy $ROOT src/openssl/apps/openssl "$approot/MacOS"
434 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_player.Info.plist "$approot/Info.plist"
435 rl=("$approot/MacOS/dcpomatic2_player" "$approot/Frameworks/"*.dylib)
437 make_dmg "$appdir" "DCP-o-matic Player" com.dcpomatic.player
439 # DCP-o-matic Playlist Editor
440 setup "DCP-o-matic 2 Playlist Editor.app"
441 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_playlist "$approot/MacOS"
442 copy $ROOT src/openssl/apps/openssl "$approot/MacOS"
443 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_playlist.Info.plist "$approot/Info.plist"
444 rl=("$approot/MacOS/dcpomatic2_playlist" "$approot/Frameworks/"*.dylib)
446 make_dmg "$appdir" "DCP-o-matic Playlist Editor" com.dcpomatic.playlist