OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 Google Inc. All rights reserved. | 2 # Copyright (c) 2012 Google Inc. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Utility functions to perform Xcode-style build steps. | 6 """Utility functions to perform Xcode-style build steps. |
7 | 7 |
8 These functions are executed via gyp-mac-tool when using the Makefile generator. | 8 These functions are executed via gyp-mac-tool when using the Makefile generator. |
9 """ | 9 """ |
10 | 10 |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 fd.close() | 146 fd.close() |
147 | 147 |
148 # Insert synthesized key/value pairs (e.g. BuildMachineOSBuild). | 148 # Insert synthesized key/value pairs (e.g. BuildMachineOSBuild). |
149 plist = plistlib.readPlistFromString(lines) | 149 plist = plistlib.readPlistFromString(lines) |
150 if keys: | 150 if keys: |
151 plist = dict(plist.items() + json.loads(keys[0]).items()) | 151 plist = dict(plist.items() + json.loads(keys[0]).items()) |
152 lines = plistlib.writePlistToString(plist) | 152 lines = plistlib.writePlistToString(plist) |
153 | 153 |
154 # Go through all the environment variables and replace them as variables in | 154 # Go through all the environment variables and replace them as variables in |
155 # the file. | 155 # the file. |
156 IDENT_RE = re.compile(r'[/\s]') | 156 IDENT_RE = re.compile(r'[/\s_-]') |
157 for key in os.environ: | 157 for key in os.environ: |
158 if key.startswith('_'): | 158 if key.startswith('_'): |
159 continue | 159 continue |
160 evar = '${%s}' % key | 160 evar = '${%s}' % key |
161 evalue = os.environ[key] | 161 evalue = os.environ[key] |
162 lines = string.replace(lines, evar, evalue) | 162 lines = string.replace(lines, evar, evalue) |
163 | 163 |
164 # Xcode supports various suffices on environment variables, which are | 164 # Xcode supports various suffices on environment variables, which are |
165 # all undocumented. :rfc1034identifier is used in the standard project | 165 # all undocumented. :rfc1034identifier is used in the standard project |
166 # template these days, and :identifier was used earlier. They are used to | 166 # template these days, and :identifier was used earlier. They are used to |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 command_line.append(arg_name) | 334 command_line.append(arg_name) |
335 command_line.append(str(v)) | 335 command_line.append(str(v)) |
336 else: | 336 else: |
337 command_line.append(arg_name) | 337 command_line.append(arg_name) |
338 command_line.append(str(value)) | 338 command_line.append(str(value)) |
339 # Note: actool crashes if inputs path are relative, so use os.path.abspath | 339 # Note: actool crashes if inputs path are relative, so use os.path.abspath |
340 # to get absolute path name for inputs. | 340 # to get absolute path name for inputs. |
341 command_line.extend(map(os.path.abspath, inputs)) | 341 command_line.extend(map(os.path.abspath, inputs)) |
342 subprocess.check_call(command_line) | 342 subprocess.check_call(command_line) |
343 | 343 |
| 344 def ExecCopySwiftLibs(self, swift_libs_dir, app_framework_dir, *inputs): |
| 345 libs = set() |
| 346 inputs = set(inputs) |
| 347 while inputs: |
| 348 input_file = inputs.pop() |
| 349 symbols = subprocess.check_output(['nm', input_file]) |
| 350 for m in re.finditer(r'__swift_FORCE_LOAD_\$_(\w+)$', symbols, |
| 351 re.MULTILINE): |
| 352 lib_name = 'lib' + m.group(1) + '.dylib' |
| 353 if not lib_name in libs: |
| 354 lib_path = os.path.join(swift_libs_dir, lib_name) |
| 355 inputs.add(lib_path) |
| 356 libs.add(lib_name) |
| 357 if not os.path.exists(app_framework_dir): |
| 358 os.makedirs(app_framework_dir) |
| 359 |
| 360 if libs: |
| 361 # This lib is not linked from anywhere directly, |
| 362 # but is needed for the app to run with Swift |
| 363 libs.add('libswiftCore.dylib') |
| 364 |
| 365 for lib in libs: |
| 366 src = os.path.join(swift_libs_dir, lib) |
| 367 dst = os.path.join(app_framework_dir, lib) |
| 368 shutil.copyfile(src, dst) |
| 369 |
| 370 def ExecBuildModuleMapFile(self, module_name, umbrella_header, map_file, |
| 371 stamp): |
| 372 if not os.path.exists(os.path.dirname(map_file)): |
| 373 os.makedirs(os.path.dirname(map_file)) |
| 374 with open(map_file, 'w') as f: |
| 375 f.write( |
| 376 'framework module %s {\n' |
| 377 ' umbrella header \"%s\"\n' |
| 378 ' export *\n' |
| 379 ' module * { export * }\n' |
| 380 '}\n' % (module_name, umbrella_header)) |
| 381 subprocess.check_call(['touch', stamp]) |
| 382 |
| 383 def ExecAppendSwiftToModuleMapFile(self, module_name, swift_header, map_file, |
| 384 stamp): |
| 385 if not os.path.exists(os.path.dirname(map_file)): |
| 386 os.makedirs(os.path.dirname(map_file)) |
| 387 with open(map_file, 'a') as f: |
| 388 f.write( |
| 389 'module %s.Swift {\n' |
| 390 ' header \"%s\"\n' |
| 391 '}\n' % (module_name, swift_header)) |
| 392 subprocess.check_call(['touch', stamp]) |
| 393 |
344 def ExecMergeInfoPlist(self, output, *inputs): | 394 def ExecMergeInfoPlist(self, output, *inputs): |
345 """Merge multiple .plist files into a single .plist file.""" | 395 """Merge multiple .plist files into a single .plist file.""" |
346 merged_plist = {} | 396 merged_plist = {} |
347 for path in inputs: | 397 for path in inputs: |
348 plist = self._LoadPlistMaybeBinary(path) | 398 plist = self._LoadPlistMaybeBinary(path) |
349 self._MergePlist(merged_plist, plist) | 399 self._MergePlist(merged_plist, plist) |
350 plistlib.writePlist(merged_plist, output) | 400 plistlib.writePlist(merged_plist, output) |
351 | 401 |
352 def ExecCodeSignBundle(self, key, resource_rules, entitlements, provisioning): | 402 def ExecCodeSignBundle(self, key, resource_rules, entitlements, provisioning): |
353 """Code sign a bundle. | 403 """Code sign a bundle. |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 data = data.replace('$(%s)' % key, value) | 651 data = data.replace('$(%s)' % key, value) |
602 return data | 652 return data |
603 if isinstance(data, list): | 653 if isinstance(data, list): |
604 return [self._ExpandVariables(v, substitutions) for v in data] | 654 return [self._ExpandVariables(v, substitutions) for v in data] |
605 if isinstance(data, dict): | 655 if isinstance(data, dict): |
606 return {k: self._ExpandVariables(data[k], substitutions) for k in data} | 656 return {k: self._ExpandVariables(data[k], substitutions) for k in data} |
607 return data | 657 return data |
608 | 658 |
609 if __name__ == '__main__': | 659 if __name__ == '__main__': |
610 sys.exit(main(sys.argv[1:])) | 660 sys.exit(main(sys.argv[1:])) |
OLD | NEW |