Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(419)

Side by Side Diff: pylib/gyp/xcode_emulation.py

Issue 26895006: ninja/mac: Support iOS codesign for ninja builds. (Closed) Base URL: http://gyp.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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.path 12 import os.path
13 import re 13 import re
14 import shlex 14 import shlex
15 import subprocess 15 import subprocess
16 import sys 16 import sys
17 from gyp.common import GypError 17 from gyp.common import GypError
18 18
19 class XcodeSettings(object): 19 class XcodeSettings(object):
20 """A class that understands the gyp 'xcode_settings' object.""" 20 """A class that understands the gyp 'xcode_settings' object."""
21 21
22 # Populated lazily by _SdkPath(). Shared by all XcodeSettings, so cached 22 # Populated lazily by _SdkPath(). Shared by all XcodeSettings, so cached
23 # at class-level for efficiency. 23 # at class-level for efficiency.
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
31 # cached at class-level for efficiency.
32 _codesigning_key_cache = {}
33
30 def __init__(self, spec): 34 def __init__(self, spec):
31 self.spec = spec 35 self.spec = spec
32 36
33 self.isIOS = False 37 self.isIOS = False
34 38
35 # Per-target 'xcode_settings' are pushed down into configs earlier by gyp. 39 # Per-target 'xcode_settings' are pushed down into configs earlier by gyp.
36 # This means self.xcode_settings[config] always contains all settings 40 # This means self.xcode_settings[config] always contains all settings
37 # for that config -- the per-target settings as well. Settings that are 41 # for that config -- the per-target settings as well. Settings that are
38 # the same for all configs are implicitly per-target settings. 42 # the same for all configs are implicitly per-target settings.
39 self.xcode_settings = {} 43 self.xcode_settings = {}
40 configs = spec['configurations'] 44 configs = spec['configurations']
41 for configname, config in configs.iteritems(): 45 for configname, config in configs.iteritems():
42 self.xcode_settings[configname] = config.get('xcode_settings', {}) 46 self.xcode_settings[configname] = config.get('xcode_settings', {})
47 self._ConvertConditionalKeys(configname)
43 if self.xcode_settings[configname].get('IPHONEOS_DEPLOYMENT_TARGET', 48 if self.xcode_settings[configname].get('IPHONEOS_DEPLOYMENT_TARGET',
44 None): 49 None):
45 self.isIOS = True 50 self.isIOS = True
46 51
47 # If you need this, speak up at http://crbug.com/122592
48 conditional_keys = [key for key in self.xcode_settings[configname]
49 if key.endswith(']')]
50 if conditional_keys:
51 print 'Warning: Conditional keys not implemented, ignoring:', \
52 ' '.join(conditional_keys)
53 for key in conditional_keys:
54 del self.xcode_settings[configname][key]
55
56 # This is only non-None temporarily during the execution of some methods. 52 # This is only non-None temporarily during the execution of some methods.
57 self.configname = None 53 self.configname = None
58 54
59 # Used by _AdjustLibrary to match .a and .dylib entries in libraries. 55 # Used by _AdjustLibrary to match .a and .dylib entries in libraries.
60 self.library_re = re.compile(r'^lib([^/]+)\.(a|dylib)$') 56 self.library_re = re.compile(r'^lib([^/]+)\.(a|dylib)$')
61 57
58 def _ConvertConditionalKeys(self, configname):
Nico 2013/10/15 02:12:57 docstring
justincohen 2013/10/15 16:47:33 Done.
59 settings = self.xcode_settings[configname]
60 conditional_keys = [key for key in settings if key.endswith(']')]
61 for key in conditional_keys:
62 # If you need more, speak up at http://crbug.com/122592
Nico 2013/10/15 02:12:57 indented too far
justincohen 2013/10/15 16:47:33 Done.
63 if key.endswith("[sdk=iphoneos*]"):
64 if configname.endswith("iphoneos"):
65 new_key = key.split("[")[0]
66 settings[new_key] = settings[key]
67 else:
68 print 'Warning: Conditional keys not implemented, ignoring:', \
69 ' '.join(conditional_keys)
70 del settings[key]
71
62 def _Settings(self): 72 def _Settings(self):
63 assert self.configname 73 assert self.configname
64 return self.xcode_settings[self.configname] 74 return self.xcode_settings[self.configname]
65 75
66 def _Test(self, test_key, cond_key, default): 76 def _Test(self, test_key, cond_key, default):
67 return self._Settings().get(test_key, default) == cond_key 77 return self._Settings().get(test_key, default) == cond_key
68 78
69 def _Appendf(self, lst, test_key, format_str, default=None): 79 def _Appendf(self, lst, test_key, format_str, default=None):
70 if test_key in self._Settings(): 80 if test_key in self._Settings():
71 lst.append(format_str % str(self._Settings()[test_key])) 81 lst.append(format_str % str(self._Settings()[test_key]))
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 self._Test( 747 self._Test(
738 'DEBUG_INFORMATION_FORMAT', 'dwarf-with-dsym', default='dwarf') and 748 'DEBUG_INFORMATION_FORMAT', 'dwarf-with-dsym', default='dwarf') and
739 self.spec['type'] != 'static_library'): 749 self.spec['type'] != 'static_library'):
740 if not quiet: 750 if not quiet:
741 result.append('echo DSYMUTIL\\(%s\\)' % self.spec['target_name']) 751 result.append('echo DSYMUTIL\\(%s\\)' % self.spec['target_name'])
742 result.append('dsymutil %s -o %s' % (output_binary, output + '.dSYM')) 752 result.append('dsymutil %s -o %s' % (output_binary, output + '.dSYM'))
743 753
744 self.configname = None 754 self.configname = None
745 return result 755 return result
746 756
747 def GetTargetPostbuilds(self, configname, output, output_binary, quiet=False): 757 def GetTargetPostbuilds(self, configname, output, output_binary, quiet=False):
Nico 2013/10/15 02:12:57 Can you change make.py to call AddImplicitPostbui
justincohen 2013/10/15 16:47:33 Done.
748 """Returns a list of shell commands that contain the shell commands 758 """Returns a list of shell commands that contain the shell commands
749 to run as postbuilds for this target, before the actual postbuilds.""" 759 to run as postbuilds for this target, before the actual postbuilds."""
750 # dSYMs need to build before stripping happens. 760 # dSYMs need to build before stripping happens.
751 return ( 761 return (
752 self._GetDebugInfoPostbuilds(configname, output, output_binary, quiet) + 762 self._GetDebugInfoPostbuilds(configname, output, output_binary, quiet) +
753 self._GetStripPostbuilds(configname, output_binary, quiet)) 763 self._GetStripPostbuilds(configname, output_binary, quiet))
754 764
765 def _GetIOSPostbuilds(self, configname, is_app, output_binary):
766 """Return a shell command to codesign the iOS output binary so it can
767 be deployed to a device. This should be run as the very last step of the
768 build."""
769 if not (self.isIOS and is_app):
Nico 2013/10/15 02:12:57 this can read self.spec['type'], no need to for th
justincohen 2013/10/15 16:47:33 Done.
770 return []
771
772 self.configname = configname
773 identity = self._Settings().get('CODE_SIGN_IDENTITY')
774 if identity == None:
775 return []
Nico 2013/10/15 02:12:57 now self.configname is wrong
Nico 2013/10/15 02:33:27 Also, setting this to "" (the empty string) appare
justincohen 2013/10/15 16:47:33 Done.
justincohen 2013/10/15 16:47:33 Done On 2013/10/15 02:33:27, Nico wrote:
776 if identity not in XcodeSettings._codesigning_key_cache:
777 proc = subprocess.Popen(['security', 'find-identity', '-p', 'codesigning',
778 '-v'], stdout=subprocess.PIPE)
Nico 2013/10/15 02:19:29 why -v here?
Nico 2013/10/15 02:22:28 Ignore this, I misread the man page for `security`
justincohen 2013/10/15 16:47:33 Done.
justincohen 2013/10/15 16:47:33 Done.
779 output = proc.communicate()[0].strip()
780 key = None
781 for item in output.split("\n"):
782 if identity in item:
783 assert key == None, (
784 "Multiple codesigning identities for identity: %s" %
785 identity)
786 key = item.split(' ')[1]
787 XcodeSettings._codesigning_key_cache[identity] = key
788 self.configname = None
789 key = XcodeSettings._codesigning_key_cache[identity]
790 if key:
791 return ["/usr/bin/codesign -v --force --sign %s %s" %
Nico 2013/10/15 02:12:57 the rest of this file uses ' quotes why "/usr/bin
justincohen 2013/10/15 16:47:33 Yeah, it was as verbose. I removed it. On 2013/1
792 (key, output_binary)]
793 return []
794
795 def AddImplicitPostbuilds(self, configname, is_app, output, output_binary,
796 postbuilds, quiet=False):
Nico 2013/10/15 02:12:57 docstring
justincohen 2013/10/15 16:47:33 Done.
797 assert output_binary is not None
798 pre = self.GetTargetPostbuilds(configname, output, output_binary, quiet)
799 post = self._GetIOSPostbuilds(configname, is_app, output_binary)
800 return (pre + postbuilds + post)
Nico 2013/10/15 02:12:57 no parens
justincohen 2013/10/15 16:47:33 Done.
801
755 def _AdjustLibrary(self, library, config_name=None): 802 def _AdjustLibrary(self, library, config_name=None):
756 if library.endswith('.framework'): 803 if library.endswith('.framework'):
757 l = '-framework ' + os.path.splitext(os.path.basename(library))[0] 804 l = '-framework ' + os.path.splitext(os.path.basename(library))[0]
758 else: 805 else:
759 m = self.library_re.match(library) 806 m = self.library_re.match(library)
760 if m: 807 if m:
761 l = '-l' + m.group(1) 808 l = '-l' + m.group(1)
762 else: 809 else:
763 l = library 810 l = library
764 return l.replace('$(SDKROOT)', self._SdkPath(config_name)) 811 return l.replace('$(SDKROOT)', self._SdkPath(config_name))
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 new_config_dict['xcode_settings']['SDKROOT'] = 'iphoneos' 1274 new_config_dict['xcode_settings']['SDKROOT'] = 'iphoneos'
1228 target_dict['configurations'][new_config_name] = new_config_dict 1275 target_dict['configurations'][new_config_name] = new_config_dict
1229 return targets 1276 return targets
1230 1277
1231 def CloneConfigurationForDeviceAndEmulator(target_dicts): 1278 def CloneConfigurationForDeviceAndEmulator(target_dicts):
1232 """If |target_dicts| contains any iOS targets, automatically create -iphoneos 1279 """If |target_dicts| contains any iOS targets, automatically create -iphoneos
1233 targets for iOS device builds.""" 1280 targets for iOS device builds."""
1234 if _HasIOSTarget(target_dicts): 1281 if _HasIOSTarget(target_dicts):
1235 return _AddIOSDeviceConfigurations(target_dicts) 1282 return _AddIOSDeviceConfigurations(target_dicts)
1236 return target_dicts 1283 return target_dicts
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698