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 |
11 import gyp.common | 11 import gyp.common |
12 import os | 12 import os |
13 import os.path | 13 import os.path |
14 import re | 14 import re |
15 import shlex | 15 import shlex |
16 import subprocess | 16 import subprocess |
17 import sys | 17 import sys |
18 import tempfile | 18 import tempfile |
19 from gyp.common import GypError | 19 from gyp.common import GypError |
20 | 20 |
21 class XcodeSettings(object): | 21 class XcodeSettings(object): |
22 """A class that understands the gyp 'xcode_settings' object.""" | 22 """A class that understands the gyp 'xcode_settings' object.""" |
23 | 23 |
24 # Populated lazily by _SdkPath(). Shared by all XcodeSettings, so cached | 24 # Populated lazily by _SdkPath(). Shared by all XcodeSettings, so cached |
25 # at class-level for efficiency. | 25 # at class-level for efficiency. |
26 _sdk_path_cache = {} | 26 _sdk_path_cache = {} |
| 27 _sdk_root_cache = {} |
27 | 28 |
28 # Populated lazily by GetExtraPlistItems(). Shared by all XcodeSettings, so | 29 # Populated lazily by GetExtraPlistItems(). Shared by all XcodeSettings, so |
29 # cached at class-level for efficiency. | 30 # cached at class-level for efficiency. |
30 _plist_cache = {} | 31 _plist_cache = {} |
31 | 32 |
32 # Populated lazily by GetIOSPostbuilds. Shared by all XcodeSettings, so | 33 # Populated lazily by GetIOSPostbuilds. Shared by all XcodeSettings, so |
33 # cached at class-level for efficiency. | 34 # cached at class-level for efficiency. |
34 _codesigning_key_cache = {} | 35 _codesigning_key_cache = {} |
35 | 36 |
36 # Populated lazily by _XcodeVersion. Shared by all XcodeSettings, so cached | 37 # Populated lazily by _XcodeVersion. Shared by all XcodeSettings, so cached |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 | 284 |
284 def _SdkRoot(self, configname): | 285 def _SdkRoot(self, configname): |
285 if configname is None: | 286 if configname is None: |
286 configname = self.configname | 287 configname = self.configname |
287 return self.GetPerConfigSetting('SDKROOT', configname, default='') | 288 return self.GetPerConfigSetting('SDKROOT', configname, default='') |
288 | 289 |
289 def _SdkPath(self, configname=None): | 290 def _SdkPath(self, configname=None): |
290 sdk_root = self._SdkRoot(configname) | 291 sdk_root = self._SdkRoot(configname) |
291 if sdk_root.startswith('/'): | 292 if sdk_root.startswith('/'): |
292 return sdk_root | 293 return sdk_root |
| 294 return self._XcodeSdkPath(sdk_root) |
| 295 |
| 296 def _XcodeSdkPath(self, sdk_root): |
293 if sdk_root not in XcodeSettings._sdk_path_cache: | 297 if sdk_root not in XcodeSettings._sdk_path_cache: |
294 XcodeSettings._sdk_path_cache[sdk_root] = self._GetSdkVersionInfoItem( | 298 sdk_path = self._GetSdkVersionInfoItem(sdk_root, 'Path') |
295 sdk_root, 'Path') | 299 XcodeSettings._sdk_path_cache[sdk_root] = sdk_path |
| 300 if sdk_root: |
| 301 XcodeSettings._sdk_root_cache[sdk_path] = sdk_root |
296 return XcodeSettings._sdk_path_cache[sdk_root] | 302 return XcodeSettings._sdk_path_cache[sdk_root] |
297 | 303 |
298 def _AppendPlatformVersionMinFlags(self, lst): | 304 def _AppendPlatformVersionMinFlags(self, lst): |
299 self._Appendf(lst, 'MACOSX_DEPLOYMENT_TARGET', '-mmacosx-version-min=%s') | 305 self._Appendf(lst, 'MACOSX_DEPLOYMENT_TARGET', '-mmacosx-version-min=%s') |
300 if 'IPHONEOS_DEPLOYMENT_TARGET' in self._Settings(): | 306 if 'IPHONEOS_DEPLOYMENT_TARGET' in self._Settings(): |
301 # TODO: Implement this better? | 307 # TODO: Implement this better? |
302 sdk_path_basename = os.path.basename(self._SdkPath()) | 308 sdk_path_basename = os.path.basename(self._SdkPath()) |
303 if sdk_path_basename.lower().startswith('iphonesimulator'): | 309 if sdk_path_basename.lower().startswith('iphonesimulator'): |
304 self._Appendf(lst, 'IPHONEOS_DEPLOYMENT_TARGET', | 310 self._Appendf(lst, 'IPHONEOS_DEPLOYMENT_TARGET', |
305 '-mios-simulator-version-min=%s') | 311 '-mios-simulator-version-min=%s') |
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
878 """Returns a dictionary with extra items to insert into Info.plist.""" | 884 """Returns a dictionary with extra items to insert into Info.plist.""" |
879 if configname not in XcodeSettings._plist_cache: | 885 if configname not in XcodeSettings._plist_cache: |
880 cache = {} | 886 cache = {} |
881 cache['BuildMachineOSBuild'] = self._BuildMachineOSBuild() | 887 cache['BuildMachineOSBuild'] = self._BuildMachineOSBuild() |
882 | 888 |
883 xcode, xcode_build = self._XcodeVersion() | 889 xcode, xcode_build = self._XcodeVersion() |
884 cache['DTXcode'] = xcode | 890 cache['DTXcode'] = xcode |
885 cache['DTXcodeBuild'] = xcode_build | 891 cache['DTXcodeBuild'] = xcode_build |
886 | 892 |
887 sdk_root = self._SdkRoot(configname) | 893 sdk_root = self._SdkRoot(configname) |
| 894 if not sdk_root: |
| 895 sdk_root = self._DefaultSdkRoot() |
888 cache['DTSDKName'] = sdk_root | 896 cache['DTSDKName'] = sdk_root |
889 if xcode >= '0430': | 897 if xcode >= '0430': |
890 cache['DTSDKBuild'] = self._GetSdkVersionInfoItem( | 898 cache['DTSDKBuild'] = self._GetSdkVersionInfoItem( |
891 sdk_root, 'ProductBuildVersion') | 899 sdk_root, 'ProductBuildVersion') |
892 else: | 900 else: |
893 cache['DTSDKBuild'] = cache['BuildMachineOSBuild'] | 901 cache['DTSDKBuild'] = cache['BuildMachineOSBuild'] |
894 | 902 |
895 if self.isIOS: | 903 if self.isIOS: |
896 cache['DTPlatformName'] = cache['DTSDKName'] | 904 cache['DTPlatformName'] = cache['DTSDKName'] |
897 if configname.endswith("iphoneos"): | 905 if configname.endswith("iphoneos"): |
898 cache['DTPlatformVersion'] = self._GetSdkVersionInfoItem( | 906 cache['DTPlatformVersion'] = self._GetSdkVersionInfoItem( |
899 sdk_root, 'ProductVersion') | 907 sdk_root, 'ProductVersion') |
900 cache['CFBundleSupportedPlatforms'] = ['iPhoneOS'] | 908 cache['CFBundleSupportedPlatforms'] = ['iPhoneOS'] |
901 else: | 909 else: |
902 cache['CFBundleSupportedPlatforms'] = ['iPhoneSimulator'] | 910 cache['CFBundleSupportedPlatforms'] = ['iPhoneSimulator'] |
903 XcodeSettings._plist_cache[configname] = cache | 911 XcodeSettings._plist_cache[configname] = cache |
904 | 912 |
905 # Include extra plist items that are per-target, not per global | 913 # Include extra plist items that are per-target, not per global |
906 # XcodeSettings. | 914 # XcodeSettings. |
907 items = dict(XcodeSettings._plist_cache[configname]) | 915 items = dict(XcodeSettings._plist_cache[configname]) |
908 if self.isIOS: | 916 if self.isIOS: |
909 items['UIDeviceFamily'] = self._XcodeIOSDeviceFamily(configname) | 917 items['UIDeviceFamily'] = self._XcodeIOSDeviceFamily(configname) |
910 return items | 918 return items |
911 | 919 |
| 920 def _DefaultSdkRoot(self): |
| 921 """Returns the default SDKROOT to use. |
| 922 |
| 923 Prior to version 5.0.0, if SDKROOT was not explicitly set in the Xcode |
| 924 project, then the environment variable was empty. Starting with this |
| 925 version, Xcode uses the name of the newest SDK installed. |
| 926 """ |
| 927 if self._XcodeVersion() < '0500': |
| 928 return '' |
| 929 default_sdk_path = self._XcodeSdkPath('') |
| 930 default_sdk_root = XcodeSettings._sdk_root_cache.get(default_sdk_path) |
| 931 if default_sdk_root: |
| 932 return default_sdk_root |
| 933 all_sdks = self._GetStdout(['xcodebuild', '-showsdks']) |
| 934 for line in all_sdks.splitlines(): |
| 935 items = line.split() |
| 936 if len(items) >= 3 and items[-2] == '-sdk': |
| 937 sdk_root = items[-1] |
| 938 sdk_path = self._XcodeSdkPath(sdk_root) |
| 939 if sdk_path == default_sdk_path: |
| 940 return sdk_root |
| 941 return '' |
| 942 |
912 def _DefaultArch(self): | 943 def _DefaultArch(self): |
913 # For Mac projects, Xcode changed the default value used when ARCHS is not | 944 # For Mac projects, Xcode changed the default value used when ARCHS is not |
914 # set from "i386" to "x86_64". | 945 # set from "i386" to "x86_64". |
915 # | 946 # |
916 # For iOS projects, if ARCHS is unset, it defaults to "armv7 armv7s" when | 947 # For iOS projects, if ARCHS is unset, it defaults to "armv7 armv7s" when |
917 # building for a device, and the simulator binaries are always build for | 948 # building for a device, and the simulator binaries are always build for |
918 # "i386". | 949 # "i386". |
919 # | 950 # |
920 # For new projects, ARCHS is set to $(ARCHS_STANDARD_INCLUDING_64_BIT), | 951 # For new projects, ARCHS is set to $(ARCHS_STANDARD_INCLUDING_64_BIT), |
921 # which correspond to "armv7 armv7s arm64", and when building the simulator | 952 # which correspond to "armv7 armv7s arm64", and when building the simulator |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1338 new_config_dict['xcode_settings']['SDKROOT'] = 'iphoneos' | 1369 new_config_dict['xcode_settings']['SDKROOT'] = 'iphoneos' |
1339 target_dict['configurations'][new_config_name] = new_config_dict | 1370 target_dict['configurations'][new_config_name] = new_config_dict |
1340 return targets | 1371 return targets |
1341 | 1372 |
1342 def CloneConfigurationForDeviceAndEmulator(target_dicts): | 1373 def CloneConfigurationForDeviceAndEmulator(target_dicts): |
1343 """If |target_dicts| contains any iOS targets, automatically create -iphoneos | 1374 """If |target_dicts| contains any iOS targets, automatically create -iphoneos |
1344 targets for iOS device builds.""" | 1375 targets for iOS device builds.""" |
1345 if _HasIOSTarget(target_dicts): | 1376 if _HasIOSTarget(target_dicts): |
1346 return _AddIOSDeviceConfigurations(target_dicts) | 1377 return _AddIOSDeviceConfigurations(target_dicts) |
1347 return target_dicts | 1378 return target_dicts |
OLD | NEW |