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

Unified Diff: pylib/gyp/xcode_emulation.py

Issue 1160773005: Support for Swift language and Clang modules for ninja generator. Base URL: https://chromium.googlesource.com/external/gyp@master
Patch Set: Fixed rare build failure when compiling with modules for multiple archs Created 5 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pylib/gyp/mac_tool.py ('k') | test/ios/gyptest-swift.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « pylib/gyp/mac_tool.py ('k') | test/ios/gyptest-swift.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698