Skip to content

Commit

Permalink
Bug 1197325 -- Set volume icon for DMG in Linux->Mac cross compiles. …
Browse files Browse the repository at this point in the history
…r=ted

MozReview-Commit-ID: C4LFZB6msmL

--HG--
extra : rebase_source : 18d4e2fa3af4a387bf5e08f987d44a0a658ac1d3
  • Loading branch information
Callek committed Jan 30, 2017
1 parent 8cf804e commit 9feb800
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,13 @@
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true
},
{
"size": 281576,
"visibility": "public",
"digest": "71616564533d138fb12f08e761c2638d054814fdf9c9439638ec57b201e100445c364d73d8d7a4f0e3b784898d5fe6264e8242863fc5ac40163f1791468bbc46",
"algorithm": "sha512",
"filename": "hfsplus-tools.tar.xz",
"unpack": true
}
]
2 changes: 2 additions & 0 deletions build/macosx/cross-mozconfig.common
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ export LDFLAGS="-Wl,-syslibroot,$CROSS_SYSROOT -Wl,-dead_strip"
export TOOLCHAIN_PREFIX=$CROSS_CCTOOLS_PATH/bin/x86_64-apple-darwin10-
export DSYMUTIL=$topsrcdir/clang/bin/llvm-dsymutil
export GENISOIMAGE=$topsrcdir/genisoimage/genisoimage
export MKFSHFS=$topsrcdir/hfsplus-tools/newfs_hfs
export DMG_TOOL=$topsrcdir/dmg/dmg
export HFS_TOOL=$topsrcdir/dmg/hfsplus

export HOST_CC="$topsrcdir/clang/bin/clang"
export HOST_CXX="$topsrcdir/clang/bin/clang++"
Expand Down
6 changes: 6 additions & 0 deletions moz.configure
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ def extra_programs(target):
return namespace(
DSYMUTIL=('dsymutil', 'llvm-dsymutil'),
GENISOIMAGE=('genisoimage',),
MKFSHFS=('newfs_hfs', 'mkfs.hfsplus'),
HFS_TOOL=('hfsplus',)
)
if target.os == 'GNU' and target.kernel == 'Linux':
return namespace(RPMBUILD=('rpmbuild',))
Expand All @@ -273,6 +275,10 @@ check_prog('DSYMUTIL', delayed_getattr(extra_programs, 'DSYMUTIL'),
allow_missing=True)
check_prog('GENISOIMAGE', delayed_getattr(extra_programs, 'GENISOIMAGE'),
allow_missing=True)
check_prog('MKFSHFS', delayed_getattr(extra_programs, 'MKFSHFS'),
allow_missing=True)
check_prog('HFS_TOOL', delayed_getattr(extra_programs, 'HFS_TOOL'),
allow_missing=True)
check_prog('RPMBUILD', delayed_getattr(extra_programs, 'RPMBUILD'),
allow_missing=True)

Expand Down
69 changes: 50 additions & 19 deletions python/mozbuild/mozpack/dmg.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import buildconfig
import errno
import mozfile
import os
Expand All @@ -11,6 +12,7 @@

is_linux = platform.system() == 'Linux'


def mkdir(dir):
if not os.path.isdir(dir):
try:
Expand All @@ -34,11 +36,48 @@ def rsync(source, dest):
source, dest])


def set_folder_icon(dir):
def set_folder_icon(dir, tmpdir):
'Set HFS attributes of dir to use a custom icon'
if not is_linux:
#TODO: bug 1197325 - figure out how to support this on Linux
subprocess.check_call(['SetFile', '-a', 'C', dir])
else:
hfs = os.path.join(tmpdir, 'staged.hfs')
subprocess.check_call([
buildconfig.substs['HFS_TOOL'], hfs, 'attr', '/', 'C'])


def generate_hfs_file(stagedir, tmpdir, volume_name):
'''
When cross compiling, we zero fill an hfs file, that we will turn into
a DMG. To do so we test the size of the staged dir, and add some slight
padding to that.
'''
if is_linux:
hfs = os.path.join(tmpdir, 'staged.hfs')
output = subprocess.check_output(['du', '-s', stagedir])
size = (int(output.split()[0]) / 1000) # Get in MB
size = int(size * 1.02) # Bump the used size slightly larger.
# Setup a proper file sized out with zero's
subprocess.check_call(['dd', 'if=/dev/zero', 'of={}'.format(hfs),
'bs=1M', 'count={}'.format(size)])
subprocess.check_call([
buildconfig.substs['MKFSHFS'], '-v', volume_name,
hfs])


def create_app_symlink(stagedir, tmpdir):
'''
Make a symlink to /Applications. The symlink name is a space
so we don't have to localize it. The Applications folder icon
will be shown in Finder, which should be clear enough for users.
'''
if is_linux:
hfs = os.path.join(tmpdir, 'staged.hfs')
subprocess.check_call([
buildconfig.substs['HFS_TOOL'], hfs, 'symlink',
'/ ', '/Applications'])
else:
os.symlink('/Applications', os.path.join(stagedir, ' '))


def create_dmg_from_staged(stagedir, output_dmg, tmpdir, volume_name):
Expand All @@ -55,29 +94,23 @@ def create_dmg_from_staged(stagedir, output_dmg, tmpdir, volume_name):
'-imagekey', 'bzip2-level=9',
'-ov', hybrid, '-o', output_dmg])
else:
import buildconfig
uncompressed = os.path.join(tmpdir, 'uncompressed.dmg')
hfs = os.path.join(tmpdir, 'staged.hfs')
subprocess.check_call([
buildconfig.substs['GENISOIMAGE'],
'-V', volume_name,
'-D', '-R', '-apple', '-no-pad',
'-o', uncompressed,
stagedir
])
buildconfig.substs['HFS_TOOL'], hfs, 'addall', stagedir])
subprocess.check_call([
buildconfig.substs['DMG_TOOL'],
'dmg',
uncompressed,
'build',
hfs,
output_dmg
],
# dmg is seriously chatty
stdout=open(os.devnull, 'wb'))


def check_tools(*tools):
'''
Check that each tool named in tools exists in SUBSTS and is executable.
'''
import buildconfig
for tool in tools:
path = buildconfig.substs[tool]
if not path:
Expand All @@ -100,7 +133,7 @@ def create_dmg(source_directory, output_dmg, volume_name, extra_files):
raise Exception("Don't know how to build a DMG on '%s'" % platform.system())

if is_linux:
check_tools('DMG_TOOL', 'GENISOIMAGE')
check_tools('DMG_TOOL', 'GENISOIMAGE', 'MKFSHFS', 'HFS_TOOL')
with mozfile.TemporaryDirectory() as tmpdir:
stagedir = os.path.join(tmpdir, 'stage')
os.mkdir(stagedir)
Expand All @@ -111,11 +144,9 @@ def create_dmg(source_directory, output_dmg, volume_name, extra_files):
full_target = os.path.join(stagedir, target)
mkdir(os.path.dirname(full_target))
shutil.copyfile(source, full_target)
# Make a symlink to /Applications. The symlink name is a space
# so we don't have to localize it. The Applications folder icon
# will be shown in Finder, which should be clear enough for users.
os.symlink('/Applications', os.path.join(stagedir, ' '))
generate_hfs_file(stagedir, tmpdir, volume_name)
create_app_symlink(stagedir, tmpdir)
# Set the folder attributes to use a custom icon
set_folder_icon(stagedir)
set_folder_icon(stagedir, tmpdir)
chmod(stagedir)
create_dmg_from_staged(stagedir, output_dmg, tmpdir, volume_name)

0 comments on commit 9feb800

Please sign in to comment.