Chromium Code Reviews| Index: pylib/gyp/mac_tool.py |
| diff --git a/pylib/gyp/mac_tool.py b/pylib/gyp/mac_tool.py |
| index 60d4058208b98484bbfa4ce1913f8c460926bd50..fb7e55ad1f1eca9af64ed13f67fcc247f81e9e84 100755 |
| --- a/pylib/gyp/mac_tool.py |
| +++ b/pylib/gyp/mac_tool.py |
| @@ -17,6 +17,7 @@ import plistlib |
| import re |
| import shutil |
| import string |
| +import struct |
| import subprocess |
| import sys |
| import tempfile |
| @@ -272,6 +273,24 @@ class MacTool(object): |
| break |
| return libtoolout.returncode |
| + def ExecPackageIosFramework(self, framework): |
| + # Find the name of the binary based on the part before the ".framework". |
| + binary = os.path.basename(framework).split('.')[0] |
| + module_path = os.path.join(framework, 'Modules'); |
| + if not os.path.exists(module_path): |
| + os.mkdir(module_path) |
| + module_template = 'framework module %s {\n' \ |
| + ' umbrella header "%s.h"\n' \ |
| + '\n' \ |
| + ' export *\n' \ |
| + ' module * { export * }\n' \ |
| + '}\n' % (binary, binary) |
| + |
| + module_file = open(os.path.join(module_path, 'module.modulemap'), "w") |
| + module_file.write(module_template) |
| + module_file.close() |
| + |
| + |
| def ExecPackageFramework(self, framework, version): |
| """Takes a path to Something.framework and the Current version of that and |
| sets up all the symlinks.""" |
| @@ -308,6 +327,23 @@ class MacTool(object): |
| os.remove(link) |
| os.symlink(dest, link) |
| + def ExecCompileIosFrameworkHeaderMap(self, out, framework, *all_headers): |
| + framework_name = os.path.basename(framework).split('.')[0] |
| + all_headers = map(os.path.abspath, all_headers) |
| + filelist = {} |
| + for header in all_headers: |
| + filename = os.path.basename(header) |
| + filelist[filename] = header |
| + filelist[os.path.join(framework_name, filename)] = header |
| + self._writeHmap(out, filelist) |
| + |
| + def ExecCopyIosFrameworkHeaders(self, framework, *copy_headers): |
| + header_path = os.path.join(framework, 'Headers'); |
| + if not os.path.exists(header_path): |
| + os.makedirs(header_path) |
| + for header in copy_headers: |
| + shutil.copy2(header, os.path.join(header_path, os.path.basename(header))) |
| + |
| def ExecCompileXcassets(self, keys, *inputs): |
| """Compiles multiple .xcassets files into a single .car file. |
| @@ -601,5 +637,60 @@ class MacTool(object): |
| return {k: self._ExpandVariables(data[k], substitutions) for k in data} |
| return data |
| + def _next_greater_power_of_2(self, x): |
|
sdefresne
2016/03/15 14:14:33
This does not need to be an instance method, can b
justincohen
2016/03/17 02:49:05
Done.
|
| + return 2**(x-1).bit_length() |
| + |
| + def _writeHmap(self, output_name, filelist): |
|
sdefresne
2016/03/15 14:14:33
This does not need to be an instance method, can b
justincohen
2016/03/17 02:49:05
Done.
|
| + magic = 1751998832 |
| + version = 1 |
| + _reserved = 0 |
| + count = len(filelist) |
| + capacity = self._next_greater_power_of_2(count) |
| + strings_offset = 24 + (12 * capacity) |
| + max_value_length = len(max(filelist.items(), key=lambda (k,v):len(v))[1]) |
| + |
| + out = open(output_name, "wb") |
| + out.write(struct.pack('<LHHLLLL', magic, version, _reserved, strings_offset, |
| + count, capacity, max_value_length)) |
| + |
| + # Create empty hashmap buckets. |
| + buckets = [None] * capacity |
| + for file, path in filelist.items(): |
| + key = 0 |
| + for c in file: |
| + key += ord(c.lower()) * 13 |
| + |
| + # Fill next empty bucket. |
| + while buckets[key & capacity - 1] is not None: |
| + key = key + 1 |
| + buckets[key & capacity - 1] = (file, path) |
| + |
| + next_offset = 1 |
| + for bucket in buckets: |
| + if bucket is None: |
| + out.write(struct.pack('<LLL', 0, 0, 0)) |
| + else: |
| + (file, path) = bucket |
| + key_offset = next_offset |
| + prefix_offset = key_offset + len(file) + 1 |
| + suffix_offset = prefix_offset + len(os.path.dirname(path) + os.sep) + 1 |
| + next_offset = suffix_offset + len(os.path.basename(path)) + 1 |
| + out.write(struct.pack('<LLL', key_offset, prefix_offset, suffix_offset)) |
| + |
| + # Pad byte since next offset starts at 1. |
| + out.write(struct.pack('<x')) |
| + |
| + for bucket in buckets: |
| + if bucket is not None: |
| + (file, path) = bucket |
| + out.write(struct.pack('<%ds' % len(file), file)) |
| + out.write(struct.pack('<s', '\0')) |
| + base = os.path.dirname(path) + os.sep |
| + out.write(struct.pack('<%ds' % len(base), base)) |
| + out.write(struct.pack('<s', '\0')) |
| + path = os.path.basename(path) |
| + out.write(struct.pack('<%ds' % len(path), path)) |
| + out.write(struct.pack('<s', '\0')) |
| + |
| if __name__ == '__main__': |
| sys.exit(main(sys.argv[1:])) |