| 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 from __future__ import print_function |
| 11 |
| 10 import copy | 12 import copy |
| 11 import gyp.common | 13 import gyp.common |
| 12 import os | 14 import os |
| 13 import os.path | 15 import os.path |
| 14 import re | 16 import re |
| 15 import shlex | 17 import shlex |
| 16 import subprocess | 18 import subprocess |
| 17 import sys | 19 import sys |
| 18 import tempfile | 20 import tempfile |
| 19 from gyp.common import GypError | 21 from gyp.common import GypError |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 expanded_archs = [] | 68 expanded_archs = [] |
| 67 for arch in archs: | 69 for arch in archs: |
| 68 if self.variable_pattern.match(arch): | 70 if self.variable_pattern.match(arch): |
| 69 variable = arch | 71 variable = arch |
| 70 try: | 72 try: |
| 71 variable_expansion = variable_mapping[variable] | 73 variable_expansion = variable_mapping[variable] |
| 72 for arch in variable_expansion: | 74 for arch in variable_expansion: |
| 73 if arch not in expanded_archs: | 75 if arch not in expanded_archs: |
| 74 expanded_archs.append(arch) | 76 expanded_archs.append(arch) |
| 75 except KeyError as e: | 77 except KeyError as e: |
| 76 print 'Warning: Ignoring unsupported variable "%s".' % variable | 78 print('Warning: Ignoring unsupported variable "%s".' % variable) |
| 77 elif arch not in expanded_archs: | 79 elif arch not in expanded_archs: |
| 78 expanded_archs.append(arch) | 80 expanded_archs.append(arch) |
| 79 return expanded_archs | 81 return expanded_archs |
| 80 | 82 |
| 81 def ActiveArchs(self, archs, valid_archs, sdkroot): | 83 def ActiveArchs(self, archs, valid_archs, sdkroot): |
| 82 """Expands variables references in ARCHS, and filter by VALID_ARCHS if it | 84 """Expands variables references in ARCHS, and filter by VALID_ARCHS if it |
| 83 is defined (if not set, Xcode accept any value in ARCHS, otherwise, only | 85 is defined (if not set, Xcode accept any value in ARCHS, otherwise, only |
| 84 values present in VALID_ARCHS are kept).""" | 86 values present in VALID_ARCHS are kept).""" |
| 85 expanded_archs = self._ExpandArchs(archs or self._default, sdkroot or '') | 87 expanded_archs = self._ExpandArchs(archs or self._default, sdkroot or '') |
| 86 if valid_archs: | 88 if valid_archs: |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 self.isIOS = False | 166 self.isIOS = False |
| 165 self.mac_toolchain_dir = None | 167 self.mac_toolchain_dir = None |
| 166 self.header_map_path = None | 168 self.header_map_path = None |
| 167 | 169 |
| 168 # Per-target 'xcode_settings' are pushed down into configs earlier by gyp. | 170 # Per-target 'xcode_settings' are pushed down into configs earlier by gyp. |
| 169 # This means self.xcode_settings[config] always contains all settings | 171 # This means self.xcode_settings[config] always contains all settings |
| 170 # for that config -- the per-target settings as well. Settings that are | 172 # for that config -- the per-target settings as well. Settings that are |
| 171 # the same for all configs are implicitly per-target settings. | 173 # the same for all configs are implicitly per-target settings. |
| 172 self.xcode_settings = {} | 174 self.xcode_settings = {} |
| 173 configs = spec['configurations'] | 175 configs = spec['configurations'] |
| 174 for configname, config in configs.iteritems(): | 176 for configname, config in configs.items(): |
| 175 self.xcode_settings[configname] = config.get('xcode_settings', {}) | 177 self.xcode_settings[configname] = config.get('xcode_settings', {}) |
| 176 self._ConvertConditionalKeys(configname) | 178 self._ConvertConditionalKeys(configname) |
| 177 if self.xcode_settings[configname].get('IPHONEOS_DEPLOYMENT_TARGET', | 179 if self.xcode_settings[configname].get('IPHONEOS_DEPLOYMENT_TARGET', |
| 178 None): | 180 None): |
| 179 self.isIOS = True | 181 self.isIOS = True |
| 180 | 182 |
| 181 # This is only non-None temporarily during the execution of some methods. | 183 # This is only non-None temporarily during the execution of some methods. |
| 182 self.configname = None | 184 self.configname = None |
| 183 | 185 |
| 184 # Used by _AdjustLibrary to match .a and .dylib entries in libraries. | 186 # Used by _AdjustLibrary to match .a and .dylib entries in libraries. |
| 185 self.library_re = re.compile(r'^lib([^/]+)\.(a|dylib)$') | 187 self.library_re = re.compile(r'^lib([^/]+)\.(a|dylib)$') |
| 186 | 188 |
| 187 def _ConvertConditionalKeys(self, configname): | 189 def _ConvertConditionalKeys(self, configname): |
| 188 """Converts or warns on conditional keys. Xcode supports conditional keys, | 190 """Converts or warns on conditional keys. Xcode supports conditional keys, |
| 189 such as CODE_SIGN_IDENTITY[sdk=iphoneos*]. This is a partial implementation | 191 such as CODE_SIGN_IDENTITY[sdk=iphoneos*]. This is a partial implementation |
| 190 with some keys converted while the rest force a warning.""" | 192 with some keys converted while the rest force a warning.""" |
| 191 settings = self.xcode_settings[configname] | 193 settings = self.xcode_settings[configname] |
| 192 conditional_keys = [key for key in settings if key.endswith(']')] | 194 conditional_keys = [key for key in settings if key.endswith(']')] |
| 193 for key in conditional_keys: | 195 for key in conditional_keys: |
| 194 # If you need more, speak up at http://crbug.com/122592 | 196 # If you need more, speak up at http://crbug.com/122592 |
| 195 if key.endswith("[sdk=iphoneos*]"): | 197 if key.endswith("[sdk=iphoneos*]"): |
| 196 if configname.endswith("iphoneos"): | 198 if configname.endswith("iphoneos"): |
| 197 new_key = key.split("[")[0] | 199 new_key = key.split("[")[0] |
| 198 settings[new_key] = settings[key] | 200 settings[new_key] = settings[key] |
| 199 else: | 201 else: |
| 200 print 'Warning: Conditional keys not implemented, ignoring:', \ | 202 print('Warning: Conditional keys not implemented, ignoring:', \ |
| 201 ' '.join(conditional_keys) | 203 ' '.join(conditional_keys)) |
| 202 del settings[key] | 204 del settings[key] |
| 203 | 205 |
| 204 def _Settings(self): | 206 def _Settings(self): |
| 205 assert self.configname | 207 assert self.configname |
| 206 return self.xcode_settings[self.configname] | 208 return self.xcode_settings[self.configname] |
| 207 | 209 |
| 208 def _Test(self, test_key, cond_key, default): | 210 def _Test(self, test_key, cond_key, default): |
| 209 return self._Settings().get(test_key, default) == cond_key | 211 return self._Settings().get(test_key, default) == cond_key |
| 210 | 212 |
| 211 def _Appendf(self, lst, test_key, format_str, default=None): | 213 def _Appendf(self, lst, test_key, format_str, default=None): |
| 212 if test_key in self._Settings(): | 214 if test_key in self._Settings(): |
| 213 lst.append(format_str % str(self._Settings()[test_key])) | 215 lst.append(format_str % str(self._Settings()[test_key])) |
| 214 elif default: | 216 elif default: |
| 215 lst.append(format_str % str(default)) | 217 lst.append(format_str % str(default)) |
| 216 | 218 |
| 217 def _WarnUnimplemented(self, test_key): | 219 def _WarnUnimplemented(self, test_key): |
| 218 if test_key in self._Settings(): | 220 if test_key in self._Settings(): |
| 219 print 'Warning: Ignoring not yet implemented key "%s".' % test_key | 221 print('Warning: Ignoring not yet implemented key "%s".' % test_key) |
| 220 | 222 |
| 221 def IsBinaryOutputFormat(self, configname): | 223 def IsBinaryOutputFormat(self, configname): |
| 222 default = "binary" if self.isIOS else "xml" | 224 default = "binary" if self.isIOS else "xml" |
| 223 format = self.xcode_settings[configname].get('INFOPLIST_OUTPUT_FORMAT', | 225 format = self.xcode_settings[configname].get('INFOPLIST_OUTPUT_FORMAT', |
| 224 default) | 226 default) |
| 225 return format == "binary" | 227 return format == "binary" |
| 226 | 228 |
| 227 def IsIosFramework(self): | 229 def IsIosFramework(self): |
| 228 return self.spec['type'] == 'shared_library' and self._IsBundle() and \ | 230 return self.spec['type'] == 'shared_library' and self._IsBundle() and \ |
| 229 self.isIOS | 231 self.isIOS |
| (...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 899 def GetPerTargetSettings(self): | 901 def GetPerTargetSettings(self): |
| 900 """Gets a list of all the per-target settings. This will only fetch keys | 902 """Gets a list of all the per-target settings. This will only fetch keys |
| 901 whose values are the same across all configurations.""" | 903 whose values are the same across all configurations.""" |
| 902 first_pass = True | 904 first_pass = True |
| 903 result = {} | 905 result = {} |
| 904 for configname in sorted(self.xcode_settings.keys()): | 906 for configname in sorted(self.xcode_settings.keys()): |
| 905 if first_pass: | 907 if first_pass: |
| 906 result = dict(self.xcode_settings[configname]) | 908 result = dict(self.xcode_settings[configname]) |
| 907 first_pass = False | 909 first_pass = False |
| 908 else: | 910 else: |
| 909 for key, value in self.xcode_settings[configname].iteritems(): | 911 for key, value in self.xcode_settings[configname].items(): |
| 910 if key not in result: | 912 if key not in result: |
| 911 continue | 913 continue |
| 912 elif result[key] != value: | 914 elif result[key] != value: |
| 913 del result[key] | 915 del result[key] |
| 914 return result | 916 return result |
| 915 | 917 |
| 916 def GetPerConfigSetting(self, setting, configname, default=None): | 918 def GetPerConfigSetting(self, setting, configname, default=None): |
| 917 if configname in self.xcode_settings: | 919 if configname in self.xcode_settings: |
| 918 return self.xcode_settings[configname].get(setting, default) | 920 return self.xcode_settings[configname].get(setting, default) |
| 919 else: | 921 else: |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1010 | 1012 |
| 1011 settings = self.xcode_settings[configname] | 1013 settings = self.xcode_settings[configname] |
| 1012 key = self._GetIOSCodeSignIdentityKey(settings) | 1014 key = self._GetIOSCodeSignIdentityKey(settings) |
| 1013 if not key: | 1015 if not key: |
| 1014 return [] | 1016 return [] |
| 1015 | 1017 |
| 1016 # Warn for any unimplemented signing xcode keys. | 1018 # Warn for any unimplemented signing xcode keys. |
| 1017 unimpl = ['OTHER_CODE_SIGN_FLAGS'] | 1019 unimpl = ['OTHER_CODE_SIGN_FLAGS'] |
| 1018 unimpl = set(unimpl) & set(self.xcode_settings[configname].keys()) | 1020 unimpl = set(unimpl) & set(self.xcode_settings[configname].keys()) |
| 1019 if unimpl: | 1021 if unimpl: |
| 1020 print 'Warning: Some codesign keys not implemented, ignoring: %s' % ( | 1022 print('Warning: Some codesign keys not implemented, ignoring: %s' % ( |
| 1021 ', '.join(sorted(unimpl))) | 1023 ', '.join(sorted(unimpl)))) |
| 1022 | 1024 |
| 1023 return ['%s code-sign-bundle "%s" "%s" "%s"' % ( | 1025 return ['%s code-sign-bundle "%s" "%s" "%s"' % ( |
| 1024 os.path.join('${TARGET_BUILD_DIR}', 'gyp-mac-tool'), key, | 1026 os.path.join('${TARGET_BUILD_DIR}', 'gyp-mac-tool'), key, |
| 1025 settings.get('CODE_SIGN_ENTITLEMENTS', ''), | 1027 settings.get('CODE_SIGN_ENTITLEMENTS', ''), |
| 1026 settings.get('PROVISIONING_PROFILE', '')) | 1028 settings.get('PROVISIONING_PROFILE', '')) |
| 1027 ] | 1029 ] |
| 1028 | 1030 |
| 1029 def _GetIOSCodeSignIdentityKey(self, settings): | 1031 def _GetIOSCodeSignIdentityKey(self, settings): |
| 1030 identity = settings.get('CODE_SIGN_IDENTITY') | 1032 identity = settings.get('CODE_SIGN_IDENTITY') |
| 1031 if not identity: | 1033 if not identity: |
| (...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1614 assert '${' not in dependee, 'Nested variables not supported: ' + dependee | 1616 assert '${' not in dependee, 'Nested variables not supported: ' + dependee |
| 1615 return matches | 1617 return matches |
| 1616 | 1618 |
| 1617 try: | 1619 try: |
| 1618 # Topologically sort, and then reverse, because we used an edge definition | 1620 # Topologically sort, and then reverse, because we used an edge definition |
| 1619 # that's inverted from the expected result of this function (see comment | 1621 # that's inverted from the expected result of this function (see comment |
| 1620 # above). | 1622 # above). |
| 1621 order = gyp.common.TopologicallySorted(env.keys(), GetEdges) | 1623 order = gyp.common.TopologicallySorted(env.keys(), GetEdges) |
| 1622 order.reverse() | 1624 order.reverse() |
| 1623 return order | 1625 return order |
| 1624 except gyp.common.CycleError, e: | 1626 except gyp.common.CycleError as e: |
| 1625 raise GypError( | 1627 raise GypError( |
| 1626 'Xcode environment variables are cyclically dependent: ' + str(e.nodes)) | 1628 'Xcode environment variables are cyclically dependent: ' + str(e.nodes)) |
| 1627 | 1629 |
| 1628 | 1630 |
| 1629 def GetSortedXcodeEnv(xcode_settings, built_products_dir, srcroot, | 1631 def GetSortedXcodeEnv(xcode_settings, built_products_dir, srcroot, |
| 1630 configuration, additional_settings=None): | 1632 configuration, additional_settings=None): |
| 1631 env = _GetXcodeEnv(xcode_settings, built_products_dir, srcroot, configuration, | 1633 env = _GetXcodeEnv(xcode_settings, built_products_dir, srcroot, configuration, |
| 1632 additional_settings) | 1634 additional_settings) |
| 1633 return [(key, env[key]) for key in _TopologicallySortedEnvVarKeys(env)] | 1635 return [(key, env[key]) for key in _TopologicallySortedEnvVarKeys(env)] |
| 1634 | 1636 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1651 for target_dict in targets.values(): | 1653 for target_dict in targets.values(): |
| 1652 for config in target_dict['configurations'].values(): | 1654 for config in target_dict['configurations'].values(): |
| 1653 if config.get('xcode_settings', {}).get('IPHONEOS_DEPLOYMENT_TARGET'): | 1655 if config.get('xcode_settings', {}).get('IPHONEOS_DEPLOYMENT_TARGET'): |
| 1654 return True | 1656 return True |
| 1655 return False | 1657 return False |
| 1656 | 1658 |
| 1657 | 1659 |
| 1658 def _AddIOSDeviceConfigurations(targets): | 1660 def _AddIOSDeviceConfigurations(targets): |
| 1659 """Clone all targets and append -iphoneos to the name. Configure these targets | 1661 """Clone all targets and append -iphoneos to the name. Configure these targets |
| 1660 to build for iOS devices and use correct architectures for those builds.""" | 1662 to build for iOS devices and use correct architectures for those builds.""" |
| 1661 for target_dict in targets.itervalues(): | 1663 for target_dict in targets.values(): |
| 1662 toolset = target_dict['toolset'] | 1664 toolset = target_dict['toolset'] |
| 1663 configs = target_dict['configurations'] | 1665 configs = target_dict['configurations'] |
| 1664 for config_name, config_dict in dict(configs).iteritems(): | 1666 for config_name, config_dict in dict(configs).items(): |
| 1665 iphoneos_config_dict = copy.deepcopy(config_dict) | 1667 iphoneos_config_dict = copy.deepcopy(config_dict) |
| 1666 configs[config_name + '-iphoneos'] = iphoneos_config_dict | 1668 configs[config_name + '-iphoneos'] = iphoneos_config_dict |
| 1667 configs[config_name + '-iphonesimulator'] = config_dict | 1669 configs[config_name + '-iphonesimulator'] = config_dict |
| 1668 if toolset == 'target': | 1670 if toolset == 'target': |
| 1669 iphoneos_config_dict['xcode_settings']['SDKROOT'] = 'iphoneos' | 1671 iphoneos_config_dict['xcode_settings']['SDKROOT'] = 'iphoneos' |
| 1670 return targets | 1672 return targets |
| 1671 | 1673 |
| 1672 def CloneConfigurationForDeviceAndEmulator(target_dicts): | 1674 def CloneConfigurationForDeviceAndEmulator(target_dicts): |
| 1673 """If |target_dicts| contains any iOS targets, automatically create -iphoneos | 1675 """If |target_dicts| contains any iOS targets, automatically create -iphoneos |
| 1674 targets for iOS device builds.""" | 1676 targets for iOS device builds.""" |
| 1675 if _HasIOSTarget(target_dicts): | 1677 if _HasIOSTarget(target_dicts): |
| 1676 return _AddIOSDeviceConfigurations(target_dicts) | 1678 return _AddIOSDeviceConfigurations(target_dicts) |
| 1677 return target_dicts | 1679 return target_dicts |
| OLD | NEW |