22# License, v. 2.0. If a copy of the MPL was not distributed with this
33# file, You can obtain one at http://mozilla.org/MPL/2.0/.
44
5+ import buildconfig
56import errno
67import mozfile
78import os
1112
1213is_linux = platform .system () == 'Linux'
1314
15+
1416def mkdir (dir ):
1517 if not os .path .isdir (dir ):
1618 try :
@@ -34,11 +36,48 @@ def rsync(source, dest):
3436 source , dest ])
3537
3638
37- def set_folder_icon (dir ):
39+ def set_folder_icon (dir , tmpdir ):
3840 'Set HFS attributes of dir to use a custom icon'
3941 if not is_linux :
40- #TODO: bug 1197325 - figure out how to support this on Linux
4142 subprocess .check_call (['SetFile' , '-a' , 'C' , dir ])
43+ else :
44+ hfs = os .path .join (tmpdir , 'staged.hfs' )
45+ subprocess .check_call ([
46+ buildconfig .substs ['HFS_TOOL' ], hfs , 'attr' , '/' , 'C' ])
47+
48+
49+ def generate_hfs_file (stagedir , tmpdir , volume_name ):
50+ '''
51+ When cross compiling, we zero fill an hfs file, that we will turn into
52+ a DMG. To do so we test the size of the staged dir, and add some slight
53+ padding to that.
54+ '''
55+ if is_linux :
56+ hfs = os .path .join (tmpdir , 'staged.hfs' )
57+ output = subprocess .check_output (['du' , '-s' , stagedir ])
58+ size = (int (output .split ()[0 ]) / 1000 ) # Get in MB
59+ size = int (size * 1.02 ) # Bump the used size slightly larger.
60+ # Setup a proper file sized out with zero's
61+ subprocess .check_call (['dd' , 'if=/dev/zero' , 'of={}' .format (hfs ),
62+ 'bs=1M' , 'count={}' .format (size )])
63+ subprocess .check_call ([
64+ buildconfig .substs ['MKFSHFS' ], '-v' , volume_name ,
65+ hfs ])
66+
67+
68+ def create_app_symlink (stagedir , tmpdir ):
69+ '''
70+ Make a symlink to /Applications. The symlink name is a space
71+ so we don't have to localize it. The Applications folder icon
72+ will be shown in Finder, which should be clear enough for users.
73+ '''
74+ if is_linux :
75+ hfs = os .path .join (tmpdir , 'staged.hfs' )
76+ subprocess .check_call ([
77+ buildconfig .substs ['HFS_TOOL' ], hfs , 'symlink' ,
78+ '/ ' , '/Applications' ])
79+ else :
80+ os .symlink ('/Applications' , os .path .join (stagedir , ' ' ))
4281
4382
4483def create_dmg_from_staged (stagedir , output_dmg , tmpdir , volume_name ):
@@ -55,29 +94,23 @@ def create_dmg_from_staged(stagedir, output_dmg, tmpdir, volume_name):
5594 '-imagekey' , 'bzip2-level=9' ,
5695 '-ov' , hybrid , '-o' , output_dmg ])
5796 else :
58- import buildconfig
59- uncompressed = os .path .join (tmpdir , 'uncompressed.dmg' )
97+ hfs = os .path .join (tmpdir , 'staged.hfs' )
6098 subprocess .check_call ([
61- buildconfig .substs ['GENISOIMAGE' ],
62- '-V' , volume_name ,
63- '-D' , '-R' , '-apple' , '-no-pad' ,
64- '-o' , uncompressed ,
65- stagedir
66- ])
99+ buildconfig .substs ['HFS_TOOL' ], hfs , 'addall' , stagedir ])
67100 subprocess .check_call ([
68101 buildconfig .substs ['DMG_TOOL' ],
69- 'dmg ' ,
70- uncompressed ,
102+ 'build ' ,
103+ hfs ,
71104 output_dmg
72105 ],
73106 # dmg is seriously chatty
74107 stdout = open (os .devnull , 'wb' ))
75108
109+
76110def check_tools (* tools ):
77111 '''
78112 Check that each tool named in tools exists in SUBSTS and is executable.
79113 '''
80- import buildconfig
81114 for tool in tools :
82115 path = buildconfig .substs [tool ]
83116 if not path :
@@ -100,7 +133,7 @@ def create_dmg(source_directory, output_dmg, volume_name, extra_files):
100133 raise Exception ("Don't know how to build a DMG on '%s'" % platform .system ())
101134
102135 if is_linux :
103- check_tools ('DMG_TOOL' , 'GENISOIMAGE' )
136+ check_tools ('DMG_TOOL' , 'GENISOIMAGE' , 'MKFSHFS' , 'HFS_TOOL' )
104137 with mozfile .TemporaryDirectory () as tmpdir :
105138 stagedir = os .path .join (tmpdir , 'stage' )
106139 os .mkdir (stagedir )
@@ -111,11 +144,9 @@ def create_dmg(source_directory, output_dmg, volume_name, extra_files):
111144 full_target = os .path .join (stagedir , target )
112145 mkdir (os .path .dirname (full_target ))
113146 shutil .copyfile (source , full_target )
114- # Make a symlink to /Applications. The symlink name is a space
115- # so we don't have to localize it. The Applications folder icon
116- # will be shown in Finder, which should be clear enough for users.
117- os .symlink ('/Applications' , os .path .join (stagedir , ' ' ))
147+ generate_hfs_file (stagedir , tmpdir , volume_name )
148+ create_app_symlink (stagedir , tmpdir )
118149 # Set the folder attributes to use a custom icon
119- set_folder_icon (stagedir )
150+ set_folder_icon (stagedir , tmpdir )
120151 chmod (stagedir )
121152 create_dmg_from_staged (stagedir , output_dmg , tmpdir , volume_name )
0 commit comments