| 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 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 elif default: | 211 elif default: |
| 212 lst.append(format_str % str(default)) | 212 lst.append(format_str % str(default)) |
| 213 | 213 |
| 214 def _WarnUnimplemented(self, test_key): | 214 def _WarnUnimplemented(self, test_key): |
| 215 if test_key in self._Settings(): | 215 if test_key in self._Settings(): |
| 216 print 'Warning: Ignoring not yet implemented key "%s".' % test_key | 216 print 'Warning: Ignoring not yet implemented key "%s".' % test_key |
| 217 | 217 |
| 218 def _IsBundle(self): | 218 def _IsBundle(self): |
| 219 return int(self.spec.get('mac_bundle', 0)) != 0 | 219 return int(self.spec.get('mac_bundle', 0)) != 0 |
| 220 | 220 |
| 221 def _IsIosAppExtension(self): |
| 222 return int(self.spec.get('ios_app_extension', 0)) != 0 |
| 223 |
| 221 def GetFrameworkVersion(self): | 224 def GetFrameworkVersion(self): |
| 222 """Returns the framework version of the current target. Only valid for | 225 """Returns the framework version of the current target. Only valid for |
| 223 bundles.""" | 226 bundles.""" |
| 224 assert self._IsBundle() | 227 assert self._IsBundle() |
| 225 return self.GetPerTargetSetting('FRAMEWORK_VERSION', default='A') | 228 return self.GetPerTargetSetting('FRAMEWORK_VERSION', default='A') |
| 226 | 229 |
| 227 def GetWrapperExtension(self): | 230 def GetWrapperExtension(self): |
| 228 """Returns the bundle extension (.app, .framework, .plugin, etc). Only | 231 """Returns the bundle extension (.app, .framework, .plugin, etc). Only |
| 229 valid for bundles.""" | 232 valid for bundles.""" |
| 230 assert self._IsBundle() | 233 assert self._IsBundle() |
| 231 if self.spec['type'] in ('loadable_module', 'shared_library'): | 234 if self.spec['type'] in ('loadable_module', 'shared_library'): |
| 232 default_wrapper_extension = { | 235 default_wrapper_extension = { |
| 233 'loadable_module': 'bundle', | 236 'loadable_module': 'bundle', |
| 234 'shared_library': 'framework', | 237 'shared_library': 'framework', |
| 235 }[self.spec['type']] | 238 }[self.spec['type']] |
| 236 wrapper_extension = self.GetPerTargetSetting( | 239 wrapper_extension = self.GetPerTargetSetting( |
| 237 'WRAPPER_EXTENSION', default=default_wrapper_extension) | 240 'WRAPPER_EXTENSION', default=default_wrapper_extension) |
| 238 return '.' + self.spec.get('product_extension', wrapper_extension) | 241 return '.' + self.spec.get('product_extension', wrapper_extension) |
| 239 elif self.spec['type'] == 'executable': | 242 elif self.spec['type'] == 'executable': |
| 240 return '.' + self.spec.get('product_extension', 'app') | 243 if self._IsIosAppExtension(): |
| 244 return '.' + self.spec.get('product_extension', 'appex') |
| 245 else: |
| 246 return '.' + self.spec.get('product_extension', 'app') |
| 241 else: | 247 else: |
| 242 assert False, "Don't know extension for '%s', target '%s'" % ( | 248 assert False, "Don't know extension for '%s', target '%s'" % ( |
| 243 self.spec['type'], self.spec['target_name']) | 249 self.spec['type'], self.spec['target_name']) |
| 244 | 250 |
| 245 def GetProductName(self): | 251 def GetProductName(self): |
| 246 """Returns PRODUCT_NAME.""" | 252 """Returns PRODUCT_NAME.""" |
| 247 return self.spec.get('product_name', self.spec['target_name']) | 253 return self.spec.get('product_name', self.spec['target_name']) |
| 248 | 254 |
| 249 def GetFullProductName(self): | 255 def GetFullProductName(self): |
| 250 """Returns FULL_PRODUCT_NAME.""" | 256 """Returns FULL_PRODUCT_NAME.""" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 Chromium.app/Contents/Info.plist. Only valid for bundles.""" | 291 Chromium.app/Contents/Info.plist. Only valid for bundles.""" |
| 286 assert self._IsBundle() | 292 assert self._IsBundle() |
| 287 if self.spec['type'] in ('executable', 'loadable_module'): | 293 if self.spec['type'] in ('executable', 'loadable_module'): |
| 288 return os.path.join(self.GetBundleContentsFolderPath(), 'Info.plist') | 294 return os.path.join(self.GetBundleContentsFolderPath(), 'Info.plist') |
| 289 else: | 295 else: |
| 290 return os.path.join(self.GetBundleContentsFolderPath(), | 296 return os.path.join(self.GetBundleContentsFolderPath(), |
| 291 'Resources', 'Info.plist') | 297 'Resources', 'Info.plist') |
| 292 | 298 |
| 293 def GetProductType(self): | 299 def GetProductType(self): |
| 294 """Returns the PRODUCT_TYPE of this target.""" | 300 """Returns the PRODUCT_TYPE of this target.""" |
| 301 if self._IsIosAppExtension(): |
| 302 assert self._IsBundle(), ('ios_app_extension flag requires mac_bundle ' |
| 303 '(target %s)' % self.spec['target_name']) |
| 304 return 'com.apple.product-type.app-extension' |
| 295 if self._IsBundle(): | 305 if self._IsBundle(): |
| 296 return { | 306 return { |
| 297 'executable': 'com.apple.product-type.application', | 307 'executable': 'com.apple.product-type.application', |
| 298 'loadable_module': 'com.apple.product-type.bundle', | 308 'loadable_module': 'com.apple.product-type.bundle', |
| 299 'shared_library': 'com.apple.product-type.framework', | 309 'shared_library': 'com.apple.product-type.framework', |
| 300 }[self.spec['type']] | 310 }[self.spec['type']] |
| 301 else: | 311 else: |
| 302 return { | 312 return { |
| 303 'executable': 'com.apple.product-type.tool', | 313 'executable': 'com.apple.product-type.tool', |
| 304 'loadable_module': 'com.apple.product-type.library.dynamic', | 314 'loadable_module': 'com.apple.product-type.library.dynamic', |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 787 ldflags.append('-Wl,-rpath,' + rpath) | 797 ldflags.append('-Wl,-rpath,' + rpath) |
| 788 | 798 |
| 789 sdk_root = self._SdkPath() | 799 sdk_root = self._SdkPath() |
| 790 if not sdk_root: | 800 if not sdk_root: |
| 791 sdk_root = '' | 801 sdk_root = '' |
| 792 config = self.spec['configurations'][self.configname] | 802 config = self.spec['configurations'][self.configname] |
| 793 framework_dirs = config.get('mac_framework_dirs', []) | 803 framework_dirs = config.get('mac_framework_dirs', []) |
| 794 for directory in framework_dirs: | 804 for directory in framework_dirs: |
| 795 ldflags.append('-F' + directory.replace('$(SDKROOT)', sdk_root)) | 805 ldflags.append('-F' + directory.replace('$(SDKROOT)', sdk_root)) |
| 796 | 806 |
| 807 if sdk_root and self._IsIosAppExtension(): |
| 808 # Adds the link flags for extensions. These flags are common for all |
| 809 # extensions and provide loader and main function. |
| 810 # These flags reflect the compilation options used by xcode to compile |
| 811 # extensions. |
| 812 ldflags.append('-lpkstart') |
| 813 ldflags.append(sdk_root + |
| 814 '/System/Library/PrivateFrameworks/PlugInKit.framework/PlugInKit') |
| 815 ldflags.append('-fapplication-extension') |
| 816 ldflags.append('-Xlinker -rpath ' |
| 817 '-Xlinker @executable_path/../../Frameworks') |
| 818 |
| 797 self._Appendf(ldflags, 'CLANG_CXX_LIBRARY', '-stdlib=%s') | 819 self._Appendf(ldflags, 'CLANG_CXX_LIBRARY', '-stdlib=%s') |
| 798 | 820 |
| 799 self.configname = None | 821 self.configname = None |
| 800 return ldflags | 822 return ldflags |
| 801 | 823 |
| 802 def GetLibtoolflags(self, configname): | 824 def GetLibtoolflags(self, configname): |
| 803 """Returns flags that need to be passed to the static linker. | 825 """Returns flags that need to be passed to the static linker. |
| 804 | 826 |
| 805 Args: | 827 Args: |
| 806 configname: The name of the configuration to get ld flags for. | 828 configname: The name of the configuration to get ld flags for. |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 to run as postbuilds for this target, before the actual postbuilds.""" | 936 to run as postbuilds for this target, before the actual postbuilds.""" |
| 915 # dSYMs need to build before stripping happens. | 937 # dSYMs need to build before stripping happens. |
| 916 return ( | 938 return ( |
| 917 self._GetDebugInfoPostbuilds(configname, output, output_binary, quiet) + | 939 self._GetDebugInfoPostbuilds(configname, output, output_binary, quiet) + |
| 918 self._GetStripPostbuilds(configname, output_binary, quiet)) | 940 self._GetStripPostbuilds(configname, output_binary, quiet)) |
| 919 | 941 |
| 920 def _GetIOSPostbuilds(self, configname, output_binary): | 942 def _GetIOSPostbuilds(self, configname, output_binary): |
| 921 """Return a shell command to codesign the iOS output binary so it can | 943 """Return a shell command to codesign the iOS output binary so it can |
| 922 be deployed to a device. This should be run as the very last step of the | 944 be deployed to a device. This should be run as the very last step of the |
| 923 build.""" | 945 build.""" |
| 924 if not (self.isIOS and self.spec['type'] == "executable"): | 946 if not (self.isIOS and self.spec['type'] == 'executable'): |
| 925 return [] | 947 return [] |
| 926 | 948 |
| 927 settings = self.xcode_settings[configname] | 949 settings = self.xcode_settings[configname] |
| 928 key = self._GetIOSCodeSignIdentityKey(settings) | 950 key = self._GetIOSCodeSignIdentityKey(settings) |
| 929 if not key: | 951 if not key: |
| 930 return [] | 952 return [] |
| 931 | 953 |
| 932 # Warn for any unimplemented signing xcode keys. | 954 # Warn for any unimplemented signing xcode keys. |
| 933 unimpl = ['OTHER_CODE_SIGN_FLAGS'] | 955 unimpl = ['OTHER_CODE_SIGN_FLAGS'] |
| 934 unimpl = set(unimpl) & set(self.xcode_settings[configname].keys()) | 956 unimpl = set(unimpl) & set(self.xcode_settings[configname].keys()) |
| (...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1550 if toolset == 'target': | 1572 if toolset == 'target': |
| 1551 iphoneos_config_dict['xcode_settings']['SDKROOT'] = 'iphoneos' | 1573 iphoneos_config_dict['xcode_settings']['SDKROOT'] = 'iphoneos' |
| 1552 return targets | 1574 return targets |
| 1553 | 1575 |
| 1554 def CloneConfigurationForDeviceAndEmulator(target_dicts): | 1576 def CloneConfigurationForDeviceAndEmulator(target_dicts): |
| 1555 """If |target_dicts| contains any iOS targets, automatically create -iphoneos | 1577 """If |target_dicts| contains any iOS targets, automatically create -iphoneos |
| 1556 targets for iOS device builds.""" | 1578 targets for iOS device builds.""" |
| 1557 if _HasIOSTarget(target_dicts): | 1579 if _HasIOSTarget(target_dicts): |
| 1558 return _AddIOSDeviceConfigurations(target_dicts) | 1580 return _AddIOSDeviceConfigurations(target_dicts) |
| 1559 return target_dicts | 1581 return target_dicts |
| OLD | NEW |