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 |
| 11 import errno |
11 import fcntl | 12 import fcntl |
12 import fnmatch | 13 import fnmatch |
13 import glob | 14 import glob |
14 import json | 15 import json |
15 import os | 16 import os |
16 import plistlib | 17 import plistlib |
17 import re | 18 import re |
18 import shutil | 19 import shutil |
19 import string | 20 import string |
20 import subprocess | 21 import subprocess |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 fd.close() | 147 fd.close() |
147 | 148 |
148 # Insert synthesized key/value pairs (e.g. BuildMachineOSBuild). | 149 # Insert synthesized key/value pairs (e.g. BuildMachineOSBuild). |
149 plist = plistlib.readPlistFromString(lines) | 150 plist = plistlib.readPlistFromString(lines) |
150 if keys: | 151 if keys: |
151 plist = dict(plist.items() + json.loads(keys[0]).items()) | 152 plist = dict(plist.items() + json.loads(keys[0]).items()) |
152 lines = plistlib.writePlistToString(plist) | 153 lines = plistlib.writePlistToString(plist) |
153 | 154 |
154 # Go through all the environment variables and replace them as variables in | 155 # Go through all the environment variables and replace them as variables in |
155 # the file. | 156 # the file. |
156 IDENT_RE = re.compile(r'[/\s]') | 157 IDENT_RE = re.compile(r'[/\s_-]') |
157 for key in os.environ: | 158 for key in os.environ: |
158 if key.startswith('_'): | 159 if key.startswith('_'): |
159 continue | 160 continue |
160 evar = '${%s}' % key | 161 evar = '${%s}' % key |
161 evalue = os.environ[key] | 162 evalue = os.environ[key] |
162 lines = string.replace(lines, evar, evalue) | 163 lines = string.replace(lines, evar, evalue) |
163 | 164 |
164 # Xcode supports various suffices on environment variables, which are | 165 # Xcode supports various suffices on environment variables, which are |
165 # all undocumented. :rfc1034identifier is used in the standard project | 166 # all undocumented. :rfc1034identifier is used in the standard project |
166 # template these days, and :identifier was used earlier. They are used to | 167 # 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) | 335 command_line.append(arg_name) |
335 command_line.append(str(v)) | 336 command_line.append(str(v)) |
336 else: | 337 else: |
337 command_line.append(arg_name) | 338 command_line.append(arg_name) |
338 command_line.append(str(value)) | 339 command_line.append(str(value)) |
339 # Note: actool crashes if inputs path are relative, so use os.path.abspath | 340 # Note: actool crashes if inputs path are relative, so use os.path.abspath |
340 # to get absolute path name for inputs. | 341 # to get absolute path name for inputs. |
341 command_line.extend(map(os.path.abspath, inputs)) | 342 command_line.extend(map(os.path.abspath, inputs)) |
342 subprocess.check_call(command_line) | 343 subprocess.check_call(command_line) |
343 | 344 |
| 345 def _EnsureDirExists(self, dir_path): |
| 346 if not os.path.exists(dir_path): |
| 347 try: |
| 348 os.makedirs(dir_path) |
| 349 except OSError as exc: |
| 350 if exc.errno != errno.EEXIST: |
| 351 raise |
| 352 |
| 353 def _MakeStamp(self, stamp): |
| 354 self._EnsureDirExists(os.path.dirname(stamp)) |
| 355 subprocess.check_call(['touch', stamp]) |
| 356 |
| 357 def ExecCopySwiftLibs(self, executable_path, platform, dst_path, codesign_key, |
| 358 stamp): |
| 359 args = [ |
| 360 'xcrun', 'swift-stdlib-tool', '--copy', |
| 361 '--scan-executable', executable_path, |
| 362 '--platform', platform, |
| 363 '--destination', dst_path, |
| 364 ] |
| 365 if codesign_key: |
| 366 args.extend(['--sign', codesign_key]) |
| 367 |
| 368 # Using only PATH variable from environment, |
| 369 # to prevent swift-stdlib-tool from using variables like |
| 370 # CODE_SIGNING_REQUIRED which may be set by Xcode |
| 371 env = {'PATH' : os.environ.get('PATH', '')} |
| 372 p = subprocess.Popen(args, env=env) |
| 373 retcode = p.wait() |
| 374 if retcode != 0: |
| 375 raise subprocess.CalledProcessError(retcode, args) |
| 376 |
| 377 self._MakeStamp(stamp) |
| 378 |
| 379 def ExecBuildModuleMapFile(self, module_name, umbrella_header, map_file, |
| 380 stamp): |
| 381 self._EnsureDirExists(os.path.dirname(map_file)) |
| 382 with open(map_file, 'w') as f: |
| 383 f.write( |
| 384 'framework module %s {\n' |
| 385 ' umbrella header \"%s\"\n' |
| 386 ' export *\n' |
| 387 ' module * { export * }\n' |
| 388 '}\n' % (module_name, umbrella_header)) |
| 389 |
| 390 self._MakeStamp(stamp) |
| 391 |
| 392 def ExecAppendSwiftToModuleMapFile(self, module_name, swift_header, map_file, |
| 393 stamp): |
| 394 self._EnsureDirExists(os.path.dirname(map_file)) |
| 395 with open(map_file, 'a') as f: |
| 396 f.write( |
| 397 'module %s.Swift {\n' |
| 398 ' header \"%s\"\n' |
| 399 '}\n' % (module_name, swift_header)) |
| 400 |
| 401 self._MakeStamp(stamp) |
| 402 |
344 def ExecMergeInfoPlist(self, output, *inputs): | 403 def ExecMergeInfoPlist(self, output, *inputs): |
345 """Merge multiple .plist files into a single .plist file.""" | 404 """Merge multiple .plist files into a single .plist file.""" |
346 merged_plist = {} | 405 merged_plist = {} |
347 for path in inputs: | 406 for path in inputs: |
348 plist = self._LoadPlistMaybeBinary(path) | 407 plist = self._LoadPlistMaybeBinary(path) |
349 self._MergePlist(merged_plist, plist) | 408 self._MergePlist(merged_plist, plist) |
350 plistlib.writePlist(merged_plist, output) | 409 plistlib.writePlist(merged_plist, output) |
351 | 410 |
352 def ExecCodeSignBundle(self, key, resource_rules, entitlements, provisioning): | 411 def ExecCodeSignBundle(self, key, resource_rules, entitlements, provisioning): |
353 """Code sign a bundle. | 412 """Code sign a bundle. |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 data = data.replace('$(%s)' % key, value) | 660 data = data.replace('$(%s)' % key, value) |
602 return data | 661 return data |
603 if isinstance(data, list): | 662 if isinstance(data, list): |
604 return [self._ExpandVariables(v, substitutions) for v in data] | 663 return [self._ExpandVariables(v, substitutions) for v in data] |
605 if isinstance(data, dict): | 664 if isinstance(data, dict): |
606 return {k: self._ExpandVariables(data[k], substitutions) for k in data} | 665 return {k: self._ExpandVariables(data[k], substitutions) for k in data} |
607 return data | 666 return data |
608 | 667 |
609 if __name__ == '__main__': | 668 if __name__ == '__main__': |
610 sys.exit(main(sys.argv[1:])) | 669 sys.exit(main(sys.argv[1:])) |
OLD | NEW |