| OLD | NEW |
| 1 # Copyright (c) 2012 Google Inc. All rights reserved. | 1 # Copyright (c) 2012 Google Inc. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """ | 5 """ |
| 6 This module contains classes that help to emulate xcodebuild behavior on top of | 6 This module contains classes that help to emulate xcodebuild behavior on top of |
| 7 other build systems, such as make and ninja. | 7 other build systems, such as make and ninja. |
| 8 """ | 8 """ |
| 9 | 9 |
| 10 import copy | 10 import copy |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 _sdk_path_cache = {} | 24 _sdk_path_cache = {} |
| 25 | 25 |
| 26 # Populated lazily by GetExtraPlistItems(). Shared by all XcodeSettings, so | 26 # Populated lazily by GetExtraPlistItems(). Shared by all XcodeSettings, so |
| 27 # cached at class-level for efficiency. | 27 # cached at class-level for efficiency. |
| 28 _plist_cache = {} | 28 _plist_cache = {} |
| 29 | 29 |
| 30 # Populated lazily by GetIOSPostbuilds. Shared by all XcodeSettings, so | 30 # Populated lazily by GetIOSPostbuilds. Shared by all XcodeSettings, so |
| 31 # cached at class-level for efficiency. | 31 # cached at class-level for efficiency. |
| 32 _codesigning_key_cache = {} | 32 _codesigning_key_cache = {} |
| 33 | 33 |
| 34 # Populated lazily by _XcodeVersion. Shared by all XcodeSettings, so cached |
| 35 # at class-level for efficiency. |
| 36 _xcode_version_cache = () |
| 37 |
| 34 def __init__(self, spec): | 38 def __init__(self, spec): |
| 35 self.spec = spec | 39 self.spec = spec |
| 36 | 40 |
| 37 self.isIOS = False | 41 self.isIOS = False |
| 38 | 42 |
| 39 # Per-target 'xcode_settings' are pushed down into configs earlier by gyp. | 43 # Per-target 'xcode_settings' are pushed down into configs earlier by gyp. |
| 40 # This means self.xcode_settings[config] always contains all settings | 44 # This means self.xcode_settings[config] always contains all settings |
| 41 # for that config -- the per-target settings as well. Settings that are | 45 # for that config -- the per-target settings as well. Settings that are |
| 42 # the same for all configs are implicitly per-target settings. | 46 # the same for all configs are implicitly per-target settings. |
| 43 self.xcode_settings = {} | 47 self.xcode_settings = {} |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 Chromium.app/Contents/MacOS/Chromium.""" | 259 Chromium.app/Contents/MacOS/Chromium.""" |
| 256 if self._IsBundle(): | 260 if self._IsBundle(): |
| 257 return self._GetBundleBinaryPath() | 261 return self._GetBundleBinaryPath() |
| 258 else: | 262 else: |
| 259 return self._GetStandaloneBinaryPath() | 263 return self._GetStandaloneBinaryPath() |
| 260 | 264 |
| 261 def GetActiveArchs(self, configname): | 265 def GetActiveArchs(self, configname): |
| 262 """Returns the architectures this target should be built for.""" | 266 """Returns the architectures this target should be built for.""" |
| 263 # TODO: Look at VALID_ARCHS, ONLY_ACTIVE_ARCH; possibly set | 267 # TODO: Look at VALID_ARCHS, ONLY_ACTIVE_ARCH; possibly set |
| 264 # CURRENT_ARCH / NATIVE_ARCH env vars? | 268 # CURRENT_ARCH / NATIVE_ARCH env vars? |
| 265 return self.xcode_settings[configname].get('ARCHS', ['i386']) | 269 return self.xcode_settings[configname].get('ARCHS', [self._DefaultArch()]) |
| 266 | 270 |
| 267 def _GetStdout(self, cmdlist): | 271 def _GetStdout(self, cmdlist): |
| 268 job = subprocess.Popen(cmdlist, stdout=subprocess.PIPE) | 272 job = subprocess.Popen(cmdlist, stdout=subprocess.PIPE) |
| 269 out = job.communicate()[0] | 273 out = job.communicate()[0] |
| 270 if job.returncode != 0: | 274 if job.returncode != 0: |
| 271 sys.stderr.write(out + '\n') | 275 sys.stderr.write(out + '\n') |
| 272 raise GypError('Error %d running %s' % (job.returncode, cmdlist[0])) | 276 raise GypError('Error %d running %s' % (job.returncode, cmdlist[0])) |
| 273 return out.rstrip('\n') | 277 return out.rstrip('\n') |
| 274 | 278 |
| 275 def _GetSdkVersionInfoItem(self, sdk, infoitem): | 279 def _GetSdkVersionInfoItem(self, sdk, infoitem): |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 self._WarnUnimplemented('GCC_DEBUGGING_SYMBOLS') | 374 self._WarnUnimplemented('GCC_DEBUGGING_SYMBOLS') |
| 371 self._WarnUnimplemented('GCC_ENABLE_OBJC_EXCEPTIONS') | 375 self._WarnUnimplemented('GCC_ENABLE_OBJC_EXCEPTIONS') |
| 372 | 376 |
| 373 # TODO: This is exported correctly, but assigning to it is not supported. | 377 # TODO: This is exported correctly, but assigning to it is not supported. |
| 374 self._WarnUnimplemented('MACH_O_TYPE') | 378 self._WarnUnimplemented('MACH_O_TYPE') |
| 375 self._WarnUnimplemented('PRODUCT_TYPE') | 379 self._WarnUnimplemented('PRODUCT_TYPE') |
| 376 | 380 |
| 377 if arch is not None: | 381 if arch is not None: |
| 378 archs = [arch] | 382 archs = [arch] |
| 379 else: | 383 else: |
| 380 archs = self._Settings().get('ARCHS', ['i386']) | 384 archs = self._Settings().get('ARCHS', [self._DefaultArch()]) |
| 381 if len(archs) != 1: | 385 if len(archs) != 1: |
| 382 # TODO: Supporting fat binaries will be annoying. | 386 # TODO: Supporting fat binaries will be annoying. |
| 383 self._WarnUnimplemented('ARCHS') | 387 self._WarnUnimplemented('ARCHS') |
| 384 archs = ['i386'] | 388 archs = ['i386'] |
| 385 cflags.append('-arch ' + archs[0]) | 389 cflags.append('-arch ' + archs[0]) |
| 386 | 390 |
| 387 if archs[0] in ('i386', 'x86_64'): | 391 if archs[0] in ('i386', 'x86_64'): |
| 388 if self._Test('GCC_ENABLE_SSE3_EXTENSIONS', 'YES', default='NO'): | 392 if self._Test('GCC_ENABLE_SSE3_EXTENSIONS', 'YES', default='NO'): |
| 389 cflags.append('-msse3') | 393 cflags.append('-msse3') |
| 390 if self._Test('GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS', 'YES', | 394 if self._Test('GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS', 'YES', |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 ldflags.append('-L' + gyp_to_build_path(library_path)) | 627 ldflags.append('-L' + gyp_to_build_path(library_path)) |
| 624 | 628 |
| 625 if 'ORDER_FILE' in self._Settings(): | 629 if 'ORDER_FILE' in self._Settings(): |
| 626 ldflags.append('-Wl,-order_file ' + | 630 ldflags.append('-Wl,-order_file ' + |
| 627 '-Wl,' + gyp_to_build_path( | 631 '-Wl,' + gyp_to_build_path( |
| 628 self._Settings()['ORDER_FILE'])) | 632 self._Settings()['ORDER_FILE'])) |
| 629 | 633 |
| 630 if arch is not None: | 634 if arch is not None: |
| 631 archs = [arch] | 635 archs = [arch] |
| 632 else: | 636 else: |
| 633 archs = self._Settings().get('ARCHS', ['i386']) | 637 archs = self._Settings().get('ARCHS', [self._DefaultArch()]) |
| 634 if len(archs) != 1: | 638 if len(archs) != 1: |
| 635 # TODO: Supporting fat binaries will be annoying. | 639 # TODO: Supporting fat binaries will be annoying. |
| 636 self._WarnUnimplemented('ARCHS') | 640 self._WarnUnimplemented('ARCHS') |
| 637 archs = ['i386'] | 641 archs = ['i386'] |
| 638 ldflags.append('-arch ' + archs[0]) | 642 ldflags.append('-arch ' + archs[0]) |
| 639 | 643 |
| 640 # Xcode adds the product directory by default. | 644 # Xcode adds the product directory by default. |
| 641 ldflags.append('-L' + product_dir) | 645 ldflags.append('-L' + product_dir) |
| 642 | 646 |
| 643 install_name = self.GetInstallName() | 647 install_name = self.GetInstallName() |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 841 | 845 |
| 842 def _XcodeVersion(self): | 846 def _XcodeVersion(self): |
| 843 # `xcodebuild -version` output looks like | 847 # `xcodebuild -version` output looks like |
| 844 # Xcode 4.6.3 | 848 # Xcode 4.6.3 |
| 845 # Build version 4H1503 | 849 # Build version 4H1503 |
| 846 # or like | 850 # or like |
| 847 # Xcode 3.2.6 | 851 # Xcode 3.2.6 |
| 848 # Component versions: DevToolsCore-1809.0; DevToolsSupport-1806.0 | 852 # Component versions: DevToolsCore-1809.0; DevToolsSupport-1806.0 |
| 849 # BuildVersion: 10M2518 | 853 # BuildVersion: 10M2518 |
| 850 # Convert that to '0463', '4H1503'. | 854 # Convert that to '0463', '4H1503'. |
| 851 version_list = self._GetStdout(['xcodebuild', '-version']).splitlines() | 855 if len(XcodeSettings._xcode_version_cache) == 0: |
| 852 version = version_list[0] | 856 version_list = self._GetStdout(['xcodebuild', '-version']).splitlines() |
| 853 build = version_list[-1] | 857 version = version_list[0] |
| 854 # Be careful to convert "4.2" to "0420": | 858 build = version_list[-1] |
| 855 version = version.split()[-1].replace('.', '') | 859 # Be careful to convert "4.2" to "0420": |
| 856 version = (version + '0' * (3 - len(version))).zfill(4) | 860 version = version.split()[-1].replace('.', '') |
| 857 build = build.split()[-1] | 861 version = (version + '0' * (3 - len(version))).zfill(4) |
| 858 return version, build | 862 build = build.split()[-1] |
| 863 XcodeSettings._xcode_version_cache = (version, build) |
| 864 return XcodeSettings._xcode_version_cache |
| 859 | 865 |
| 860 def _XcodeIOSDeviceFamily(self, configname): | 866 def _XcodeIOSDeviceFamily(self, configname): |
| 861 family = self.xcode_settings[configname].get('TARGETED_DEVICE_FAMILY', '1') | 867 family = self.xcode_settings[configname].get('TARGETED_DEVICE_FAMILY', '1') |
| 862 return [int(x) for x in family.split(',')] | 868 return [int(x) for x in family.split(',')] |
| 863 | 869 |
| 864 def GetExtraPlistItems(self, configname=None): | 870 def GetExtraPlistItems(self, configname=None): |
| 865 """Returns a dictionary with extra items to insert into Info.plist.""" | 871 """Returns a dictionary with extra items to insert into Info.plist.""" |
| 866 if configname not in XcodeSettings._plist_cache: | 872 if configname not in XcodeSettings._plist_cache: |
| 867 cache = {} | 873 cache = {} |
| 868 cache['BuildMachineOSBuild'] = self._BuildMachineOSBuild() | 874 cache['BuildMachineOSBuild'] = self._BuildMachineOSBuild() |
| (...skipping 20 matching lines...) Expand all Loading... |
| 889 cache['CFBundleSupportedPlatforms'] = ['iPhoneSimulator'] | 895 cache['CFBundleSupportedPlatforms'] = ['iPhoneSimulator'] |
| 890 XcodeSettings._plist_cache[configname] = cache | 896 XcodeSettings._plist_cache[configname] = cache |
| 891 | 897 |
| 892 # Include extra plist items that are per-target, not per global | 898 # Include extra plist items that are per-target, not per global |
| 893 # XcodeSettings. | 899 # XcodeSettings. |
| 894 items = dict(XcodeSettings._plist_cache[configname]) | 900 items = dict(XcodeSettings._plist_cache[configname]) |
| 895 if self.isIOS: | 901 if self.isIOS: |
| 896 items['UIDeviceFamily'] = self._XcodeIOSDeviceFamily(configname) | 902 items['UIDeviceFamily'] = self._XcodeIOSDeviceFamily(configname) |
| 897 return items | 903 return items |
| 898 | 904 |
| 905 def _DefaultArch(self): |
| 906 # The default value for ARCHS changed from ['i386'] to ['x86_64'] in |
| 907 # Xcode 5. |
| 908 version, build = self._XcodeVersion() |
| 909 if version >= '0500': |
| 910 return 'x86_64' |
| 911 return 'i386' |
| 899 | 912 |
| 900 class MacPrefixHeader(object): | 913 class MacPrefixHeader(object): |
| 901 """A class that helps with emulating Xcode's GCC_PREFIX_HEADER feature. | 914 """A class that helps with emulating Xcode's GCC_PREFIX_HEADER feature. |
| 902 | 915 |
| 903 This feature consists of several pieces: | 916 This feature consists of several pieces: |
| 904 * If GCC_PREFIX_HEADER is present, all compilations in that project get an | 917 * If GCC_PREFIX_HEADER is present, all compilations in that project get an |
| 905 additional |-include path_to_prefix_header| cflag. | 918 additional |-include path_to_prefix_header| cflag. |
| 906 * If GCC_PRECOMPILE_PREFIX_HEADER is present too, then the prefix header is | 919 * If GCC_PRECOMPILE_PREFIX_HEADER is present too, then the prefix header is |
| 907 instead compiled, and all other compilations in the project get an | 920 instead compiled, and all other compilations in the project get an |
| 908 additional |-include path_to_compiled_header| instead. | 921 additional |-include path_to_compiled_header| instead. |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1303 new_config_dict['xcode_settings']['SDKROOT'] = 'iphoneos' | 1316 new_config_dict['xcode_settings']['SDKROOT'] = 'iphoneos' |
| 1304 target_dict['configurations'][new_config_name] = new_config_dict | 1317 target_dict['configurations'][new_config_name] = new_config_dict |
| 1305 return targets | 1318 return targets |
| 1306 | 1319 |
| 1307 def CloneConfigurationForDeviceAndEmulator(target_dicts): | 1320 def CloneConfigurationForDeviceAndEmulator(target_dicts): |
| 1308 """If |target_dicts| contains any iOS targets, automatically create -iphoneos | 1321 """If |target_dicts| contains any iOS targets, automatically create -iphoneos |
| 1309 targets for iOS device builds.""" | 1322 targets for iOS device builds.""" |
| 1310 if _HasIOSTarget(target_dicts): | 1323 if _HasIOSTarget(target_dicts): |
| 1311 return _AddIOSDeviceConfigurations(target_dicts) | 1324 return _AddIOSDeviceConfigurations(target_dicts) |
| 1312 return target_dicts | 1325 return target_dicts |
| OLD | NEW |