| Index: pylib/gyp/xcode_emulation.py
|
| ===================================================================
|
| --- pylib/gyp/xcode_emulation.py (revision 1755)
|
| +++ pylib/gyp/xcode_emulation.py (working copy)
|
| @@ -27,6 +27,10 @@
|
| # cached at class-level for efficiency.
|
| _plist_cache = {}
|
|
|
| + # Populated lazily by GetIOSPostbuilds. Shared by all XcodeSettings, so
|
| + # cached at class-level for efficiency.
|
| + _codesigning_key_cache = {}
|
| +
|
| def __init__(self, spec):
|
| self.spec = spec
|
|
|
| @@ -40,25 +44,34 @@
|
| configs = spec['configurations']
|
| for configname, config in configs.iteritems():
|
| self.xcode_settings[configname] = config.get('xcode_settings', {})
|
| + self._ConvertConditionalKeys(configname)
|
| if self.xcode_settings[configname].get('IPHONEOS_DEPLOYMENT_TARGET',
|
| None):
|
| self.isIOS = True
|
|
|
| - # If you need this, speak up at http://crbug.com/122592
|
| - conditional_keys = [key for key in self.xcode_settings[configname]
|
| - if key.endswith(']')]
|
| - if conditional_keys:
|
| - print 'Warning: Conditional keys not implemented, ignoring:', \
|
| - ' '.join(conditional_keys)
|
| - for key in conditional_keys:
|
| - del self.xcode_settings[configname][key]
|
| -
|
| # This is only non-None temporarily during the execution of some methods.
|
| self.configname = None
|
|
|
| # Used by _AdjustLibrary to match .a and .dylib entries in libraries.
|
| self.library_re = re.compile(r'^lib([^/]+)\.(a|dylib)$')
|
|
|
| + def _ConvertConditionalKeys(self, configname):
|
| + """Converts or warns on conditional keys. Xcode supports conditional keys,
|
| + such as CODE_SIGN_IDENTITY[sdk=iphoneos*]. This is a partial implementation
|
| + with some keys converted while the rest force a warning."""
|
| + settings = self.xcode_settings[configname]
|
| + conditional_keys = [key for key in settings if key.endswith(']')]
|
| + for key in conditional_keys:
|
| + # If you need more, speak up at http://crbug.com/122592
|
| + if key.endswith("[sdk=iphoneos*]"):
|
| + if configname.endswith("iphoneos"):
|
| + new_key = key.split("[")[0]
|
| + settings[new_key] = settings[key]
|
| + else:
|
| + print 'Warning: Conditional keys not implemented, ignoring:', \
|
| + ' '.join(conditional_keys)
|
| + del settings[key]
|
| +
|
| def _Settings(self):
|
| assert self.configname
|
| return self.xcode_settings[self.configname]
|
| @@ -744,7 +757,8 @@
|
| self.configname = None
|
| return result
|
|
|
| - def GetTargetPostbuilds(self, configname, output, output_binary, quiet=False):
|
| + def _GetTargetPostbuilds(self, configname, output, output_binary,
|
| + quiet=False):
|
| """Returns a list of shell commands that contain the shell commands
|
| to run as postbuilds for this target, before the actual postbuilds."""
|
| # dSYMs need to build before stripping happens.
|
| @@ -752,6 +766,50 @@
|
| self._GetDebugInfoPostbuilds(configname, output, output_binary, quiet) +
|
| self._GetStripPostbuilds(configname, output_binary, quiet))
|
|
|
| + def _GetIOSPostbuilds(self, configname, output_binary):
|
| + """Return a shell command to codesign the iOS output binary so it can
|
| + be deployed to a device. This should be run as the very last step of the
|
| + build."""
|
| + if not (self.isIOS and self.spec['type'] == "executable"):
|
| + return []
|
| +
|
| + identity = self.xcode_settings[configname].get('CODE_SIGN_IDENTITY', '')
|
| + if identity == '':
|
| + return []
|
| + if identity not in XcodeSettings._codesigning_key_cache:
|
| + proc = subprocess.Popen(['security', 'find-identity', '-p', 'codesigning',
|
| + '-v'], stdout=subprocess.PIPE)
|
| + output = proc.communicate()[0].strip()
|
| + key = None
|
| + for item in output.split("\n"):
|
| + if identity in item:
|
| + assert key == None, (
|
| + "Multiple codesigning identities for identity: %s" %
|
| + identity)
|
| + key = item.split(' ')[1]
|
| + XcodeSettings._codesigning_key_cache[identity] = key
|
| + key = XcodeSettings._codesigning_key_cache[identity]
|
| + if key:
|
| + # Warn for any unimplemented signing xcode keys.
|
| + unimpl = ['CODE_SIGN_RESOURCE_RULES_PATH', 'OTHER_CODE_SIGN_FLAGS',
|
| + 'CODE_SIGN_ENTITLEMENTS']
|
| + keys = set(self.xcode_settings[configname].keys())
|
| + unimpl = set(unimpl) & keys
|
| + if unimpl:
|
| + print 'Warning: Some codesign keys not implemented, ignoring:', \
|
| + ' '.join(unimpl)
|
| + return ['codesign --force --sign %s %s' % (key, output_binary)]
|
| + return []
|
| +
|
| + def AddImplicitPostbuilds(self, configname, output, output_binary,
|
| + postbuilds=[], quiet=False):
|
| + """Returns a list of shell commands that should run before and after
|
| + |postbuilds|."""
|
| + assert output_binary is not None
|
| + pre = self._GetTargetPostbuilds(configname, output, output_binary, quiet)
|
| + post = self._GetIOSPostbuilds(configname, output_binary)
|
| + return pre + postbuilds + post
|
| +
|
| def _AdjustLibrary(self, library, config_name=None):
|
| if library.endswith('.framework'):
|
| l = '-framework ' + os.path.splitext(os.path.basename(library))[0]
|
| @@ -815,15 +873,20 @@
|
| cache['DTSDKBuild'] = cache['BuildMachineOSBuild']
|
|
|
| if self.isIOS:
|
| - cache['UIDeviceFamily'] = self._XcodeIOSDeviceFamily(configname)
|
| if configname.endswith("iphoneos"):
|
| cache['CFBundleSupportedPlatforms'] = ['iPhoneOS']
|
| else:
|
| cache['CFBundleSupportedPlatforms'] = ['iPhoneSimulator']
|
| XcodeSettings._plist_cache[configname] = cache
|
| - return XcodeSettings._plist_cache[configname]
|
|
|
| + # Include extra plist items that are per-target, not per global
|
| + # XcodeSettings.
|
| + items = dict(XcodeSettings._plist_cache[configname])
|
| + if self.isIOS:
|
| + items['UIDeviceFamily'] = self._XcodeIOSDeviceFamily(configname)
|
| + return items
|
|
|
| +
|
| class MacPrefixHeader(object):
|
| """A class that helps with emulating Xcode's GCC_PREFIX_HEADER feature.
|
|
|
|
|