Index: pylib/gyp/xcode_emulation.py |
diff --git a/pylib/gyp/xcode_emulation.py b/pylib/gyp/xcode_emulation.py |
index 47f9d520e10e0206be9cc7d32df2eedc61db57ea..2fb7febdf203f5e86ae69660a63be4e69945ab29 100644 |
--- a/pylib/gyp/xcode_emulation.py |
+++ b/pylib/gyp/xcode_emulation.py |
@@ -302,7 +302,7 @@ class XcodeSettings(object): |
"""Returns the qualified path to the bundle's plist file. E.g. |
Chromium.app/Contents/Info.plist. Only valid for bundles.""" |
assert self._IsBundle() |
- if self.spec['type'] in ('executable', 'loadable_module'): |
+ if self.isIOS or self.spec['type'] in ('executable', 'loadable_module'): |
return os.path.join(self.GetBundleContentsFolderPath(), 'Info.plist') |
else: |
return os.path.join(self.GetBundleContentsFolderPath(), |
@@ -464,7 +464,7 @@ class XcodeSettings(object): |
self._Appendf(lst, 'IPHONEOS_DEPLOYMENT_TARGET', |
'-miphoneos-version-min=%s') |
- def GetCflags(self, configname, arch=None): |
+ def GetCflags(self, configname, gyp_to_build_path, arch=None): |
"""Returns flags that need to be added to .c, .cc, .m, and .mm |
compilations.""" |
# This functions (and the similar ones below) do not offer complete |
@@ -480,6 +480,18 @@ class XcodeSettings(object): |
if self._Test('CLANG_WARN_CONSTANT_CONVERSION', 'YES', default='NO'): |
cflags.append('-Wconstant-conversion') |
+ if self._AreModulesEnabled(): |
+ cflags.append('-fmodules') |
+ module_cache_path = self._Settings().get( |
+ 'CLANG_MODULE_CACHE_PATH', self._GetDefaultClangModuleCachePath()) |
+ if arch: |
+ module_cache_path = os.path.join(module_cache_path, arch) |
+ cflags.append('-fmodules-cache-path=\'%s\'' % module_cache_path) |
+ if self._IsModuleDefined(): |
+ cflags.append('-Xclang -fmodule-implementation-of -Xclang ' + |
+ self._GetProductModuleName()) |
+ cflags.append('-F.') |
+ |
if self._Test('GCC_CHAR_IS_UNSIGNED_CHAR', 'YES', default='NO'): |
cflags.append('-funsigned-char') |
@@ -575,11 +587,192 @@ class XcodeSettings(object): |
config = self.spec['configurations'][self.configname] |
framework_dirs = config.get('mac_framework_dirs', []) |
for directory in framework_dirs: |
- cflags.append('-F' + directory.replace('$(SDKROOT)', framework_root)) |
+ cflags.append('-F' + gyp_to_build_path(directory)) |
self.configname = None |
return cflags |
+ def AreModulesEnabled(self, configname): |
+ self.configname = configname |
+ res = self._AreModulesEnabled() |
+ self.configname = None |
+ return res |
+ |
+ def _AreModulesEnabled(self): |
+ res = self._Test('CLANG_ENABLE_MODULES', 'YES', default='NO') |
+ return res |
+ |
+ def IsModuleDefined(self, configname): |
+ self.configname = configname |
+ res = self._IsModuleDefined() |
+ self.configname = None |
+ return res |
+ |
+ def _IsModuleDefined(self): |
+ res = self._Test('DEFINES_MODULE', 'YES', default='NO') |
+ return res |
+ |
+ def IsSwiftWMOEnabled(self, configname): |
+ self.configname = configname |
+ res = self._IsSwiftWMOEnabled() |
+ self.configname = None |
+ return res |
+ |
+ def _IsSwiftWMOEnabled(self): |
+ return self._Test('SWIFT_OPTIMIZATION_LEVEL', '-Owholemodule', default='-O') |
+ |
+ def GetProductModuleName(self, configname): |
+ self.configname = configname |
+ swift_module_name = self._GetProductModuleName() |
+ self.configname = None |
+ return swift_module_name |
+ |
+ def _GetProductModuleName(self): |
+ default_module_name = self.spec['target_name'].replace('-', '_') |
+ return self._Settings().get( |
+ 'PRODUCT_MODULE_NAME', default_module_name) |
+ |
+ def GetSwiftHeaderPath(self, configname, gyp_path_to_build_path, arch=None): |
+ self.configname = configname |
+ swift_header_path = self._GetSwiftHeaderPath(gyp_path_to_build_path, arch) |
+ self.configname = None |
+ return swift_header_path |
+ |
+ def _GetSwiftHeaderPath(self, gyp_path_to_build_path, arch): |
+ swift_header_name = self._Settings().get( |
+ 'SWIFT_OBJC_INTERFACE_HEADER_NAME', |
+ self._GetProductModuleName() + '-Swift.h') |
+ # SWIFT_OBJC_INTERFACE_HEADER_NAME must just a file name without path |
+ assert not os.path.dirname(swift_header_name) |
+ if arch: |
+ swift_header_name = re.sub(r'\.h$', '.' + arch + '.h', swift_header_name) |
+ swift_header_path = os.path.join('$!INTERMEDIATE_DIR', swift_header_name) |
+ swift_header_path = gyp_path_to_build_path(swift_header_path) |
+ return swift_header_path |
+ |
+ def _GetCommonLibsPath(self): |
+ developer_dir = subprocess.check_output(['xcode-select', '-p']).strip() |
+ base_toolchain_path = os.path.join( |
+ developer_dir, 'Toolchains/XcodeDefault.xctoolchain') |
+ base_toolchain_path = os.path.normpath(base_toolchain_path) |
+ |
+ libs_path = os.path.join(base_toolchain_path, 'usr', 'lib') |
+ assert os.path.exists(libs_path) |
+ return libs_path |
+ |
+ def GetPlatform(self, configname): |
+ sdk_path_basename = os.path.basename(self._SdkPath(configname)) |
+ if sdk_path_basename.lower().startswith('iphonesimulator'): |
+ platform = 'iphonesimulator' |
+ elif sdk_path_basename.lower().startswith('iphoneos'): |
+ platform = 'iphoneos' |
+ elif sdk_path_basename.lower().startswith('macosx'): |
+ platform = 'macosx' |
+ else: |
+ assert False, 'Unexpected platform' |
+ |
+ return platform |
+ |
+ def _GetDefaultClangModuleCachePath(self): |
+ return os.path.join(os.path.expanduser('~'), |
+ 'Library/Developer/Xcode/DerivedData/ModuleCache') |
+ |
+ def _GetSwiftCommonFlags(self, gyp_path_to_build_path, arch): |
+ assert arch |
+ |
+ swift_flags = [] |
+ swift_flags.append('-enable-objc-interop') |
+ |
+ if self._IsModuleDefined(): |
+ swift_flags.append('-import-underlying-module') |
+ |
+ self._Appendf(swift_flags, 'IPHONEOS_DEPLOYMENT_TARGET', |
+ '-target ' + arch + '-apple-ios%s') |
+ self._Appendf(swift_flags, 'MACOSX_DEPLOYMENT_TARGET', |
+ '-target ' + arch + '-apple-macosx%s') |
+ |
+ swift_flags.append('-sdk ' + self._SdkPath()) |
+ |
+ swift_flags.append('-g') |
+ |
+ swift_flags.append('-parse-as-library') |
+ |
+ self._Appendf(swift_flags, |
+ 'CLANG_MODULE_CACHE_PATH', |
+ '-module-cache-path \'%s\'', |
+ self._GetDefaultClangModuleCachePath()) |
+ |
+ swift_flags.append('-module-name ' + self._GetProductModuleName()) |
+ |
+ if self._Settings().get('SWIFT_OBJC_BRIDGING_HEADER'): |
+ import_header = self._Settings().get('SWIFT_OBJC_BRIDGING_HEADER') |
+ import_header = gyp_path_to_build_path(import_header) |
+ swift_flags.append('-import-objc-header \'' + import_header + '\'') |
+ |
+ config = self.spec['configurations'][self.configname] |
+ framework_dirs = config.get('mac_framework_dirs', []) |
+ sdk_root = self._SdkPath() |
+ for directory in framework_dirs: |
+ swift_flags.append('-F' + gyp_path_to_build_path(directory)) |
+ |
+ swift_flags.append('-F.') |
+ |
+ swift_flags.append('-I.') |
+ for i in config.get('include_dirs', []): |
+ swift_flags.append('-I' + gyp_path_to_build_path(i)) |
+ |
+ return swift_flags |
+ |
+ def GetBundleFrameworksFolderPath(self): |
+ return os.path.join(self.GetBundleContentsFolderPath(), 'Frameworks') |
+ |
+ def GetBundlePublicHeadersFolderPath(self): |
+ return os.path.join(self.GetBundleContentsFolderPath(), 'Headers') |
+ |
+ def GetBundlePrivateHeadersFolderPath(self): |
+ return os.path.join(self.GetBundleContentsFolderPath(), 'PrivateHeaders') |
+ |
+ def GetBundleModulesFolderPath(self): |
+ return os.path.join(self.GetBundleContentsFolderPath(), 'Modules') |
+ |
+ def GetSwiftCompileFlags(self, configname, gyp_path_to_build_path, arch): |
+ self.configname = configname |
+ |
+ swift_flags = self._GetSwiftCommonFlags(gyp_path_to_build_path, arch) |
+ |
+ if self._IsSwiftWMOEnabled(): |
+ swift_flags.append('-O') |
+ else: |
+ self._Appendf(swift_flags, 'SWIFT_OPTIMIZATION_LEVEL', '%s', '-O') |
+ |
+ self.configname = None |
+ return swift_flags |
+ |
+ def GetSwiftMergeFlags(self, configname, gyp_path_to_build_path, arch): |
+ self.configname = configname |
+ |
+ swift_flags = self._GetSwiftCommonFlags(gyp_path_to_build_path, arch) |
+ |
+ self.configname = None |
+ return swift_flags |
+ |
+ def GetSwiftLdflags(self, configname, arch_module_path): |
+ ldflags = [] |
+ platform = self.GetPlatform(configname) |
+ libs_path = self._GetCommonLibsPath() |
+ if self.isIOS: |
+ # Some crazy hack by Xcode for iOS7 Swift support |
+ arclib_path = os.path.join( |
+ libs_path, 'arc', 'libarclite_' + platform + '.a') |
+ assert os.path.isfile(arclib_path) |
+ ldflags.append('-Xlinker -force_load -Xlinker ' + arclib_path) |
+ |
+ swift_libs_path = os.path.join(libs_path, 'swift', platform) |
+ assert os.path.isdir(swift_libs_path) |
+ ldflags.append('-Xlinker -add_ast_path -Xlinker ' + arch_module_path) |
+ ldflags.append('-L' + swift_libs_path) |
+ return ldflags |
+ |
def GetCflagsC(self, configname): |
"""Returns flags that need to be added to .c, and .m compilations.""" |
self.configname = configname |
@@ -802,6 +995,10 @@ class XcodeSettings(object): |
'-Wl,' + gyp_to_build_path( |
self._Settings()['ORDER_FILE'])) |
+ if 'BUNDLE_LOADER' in self._Settings(): |
+ bundle_loader_path = gyp_to_build_path(self._Settings()['BUNDLE_LOADER']) |
+ ldflags.append('-bundle_loader ' + bundle_loader_path) |
+ |
if arch is not None: |
archs = [arch] |
else: |
@@ -821,7 +1018,7 @@ class XcodeSettings(object): |
ldflags.append('-install_name ' + install_name.replace(' ', r'\ ')) |
for rpath in self._Settings().get('LD_RUNPATH_SEARCH_PATHS', []): |
- ldflags.append('-Wl,-rpath,' + rpath) |
+ ldflags.append('-Xlinker -rpath -Xlinker ' + rpath) |
sdk_root = self._SdkPath() |
if not sdk_root: |
@@ -829,7 +1026,9 @@ class XcodeSettings(object): |
config = self.spec['configurations'][self.configname] |
framework_dirs = config.get('mac_framework_dirs', []) |
for directory in framework_dirs: |
- ldflags.append('-F' + directory.replace('$(SDKROOT)', sdk_root)) |
+ ldflags.append('-F' + gyp_to_build_path(directory)) |
+ |
+ ldflags.append('-F.') |
is_extension = self._IsIosAppExtension() or self._IsIosWatchKitExtension() |
if sdk_root and is_extension: |
@@ -994,6 +1193,13 @@ class XcodeSettings(object): |
settings.get('PROVISIONING_PROFILE', '')) |
] |
+ def GetCodeSignIdentityKey(self, configname): |
+ if not self.isIOS: |
+ return None |
+ |
+ settings = self.xcode_settings[configname] |
+ return self._GetIOSCodeSignIdentityKey(settings) |
+ |
def _GetIOSCodeSignIdentityKey(self, settings): |
identity = settings.get('CODE_SIGN_IDENTITY') |
if not identity: |
@@ -1413,6 +1619,14 @@ def GetMacInfoPlist(product_dir, xcode_settings, gyp_path_to_build_path): |
return info_plist, dest_plist, defines, extra_env |
+def IsSwiftSupported(): |
+ xcode_version, _ = XcodeVersion() |
+ # Xcode actually supports Swift since 0600, |
+ # but here is least version supported by this script. |
+ # You should not try compiling Swift with Xcode less than 6.3 at all. |
+ return xcode_version >= '0630' |
+ |
+ |
def _GetXcodeEnv(xcode_settings, built_products_dir, srcroot, configuration, |
additional_settings=None): |
"""Return the environment variables that Xcode would set. See |