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

Side by Side 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: Created 5 years, 6 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
« no previous file with comments | « pylib/gyp/mac_tool.py ('k') | test/ios/gyptest-swift.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 Chromium.app/Contents/Resources. Only valid for bundles.""" 295 Chromium.app/Contents/Resources. Only valid for bundles."""
296 assert self._IsBundle() 296 assert self._IsBundle()
297 if self.isIOS: 297 if self.isIOS:
298 return self.GetBundleContentsFolderPath() 298 return self.GetBundleContentsFolderPath()
299 return os.path.join(self.GetBundleContentsFolderPath(), 'Resources') 299 return os.path.join(self.GetBundleContentsFolderPath(), 'Resources')
300 300
301 def GetBundlePlistPath(self): 301 def GetBundlePlistPath(self):
302 """Returns the qualified path to the bundle's plist file. E.g. 302 """Returns the qualified path to the bundle's plist file. E.g.
303 Chromium.app/Contents/Info.plist. Only valid for bundles.""" 303 Chromium.app/Contents/Info.plist. Only valid for bundles."""
304 assert self._IsBundle() 304 assert self._IsBundle()
305 if self.spec['type'] in ('executable', 'loadable_module'): 305 if self.isIOS or self.spec['type'] in ('executable', 'loadable_module'):
306 return os.path.join(self.GetBundleContentsFolderPath(), 'Info.plist') 306 return os.path.join(self.GetBundleContentsFolderPath(), 'Info.plist')
307 else: 307 else:
308 return os.path.join(self.GetBundleContentsFolderPath(), 308 return os.path.join(self.GetBundleContentsFolderPath(),
309 'Resources', 'Info.plist') 309 'Resources', 'Info.plist')
310 310
311 def GetProductType(self): 311 def GetProductType(self):
312 """Returns the PRODUCT_TYPE of this target.""" 312 """Returns the PRODUCT_TYPE of this target."""
313 if self._IsIosAppExtension(): 313 if self._IsIosAppExtension():
314 assert self._IsBundle(), ('ios_app_extension flag requires mac_bundle ' 314 assert self._IsBundle(), ('ios_app_extension flag requires mac_bundle '
315 '(target %s)' % self.spec['target_name']) 315 '(target %s)' % self.spec['target_name'])
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 self.configname = configname 473 self.configname = configname
474 cflags = [] 474 cflags = []
475 475
476 sdk_root = self._SdkPath() 476 sdk_root = self._SdkPath()
477 if 'SDKROOT' in self._Settings() and sdk_root: 477 if 'SDKROOT' in self._Settings() and sdk_root:
478 cflags.append('-isysroot %s' % sdk_root) 478 cflags.append('-isysroot %s' % sdk_root)
479 479
480 if self._Test('CLANG_WARN_CONSTANT_CONVERSION', 'YES', default='NO'): 480 if self._Test('CLANG_WARN_CONSTANT_CONVERSION', 'YES', default='NO'):
481 cflags.append('-Wconstant-conversion') 481 cflags.append('-Wconstant-conversion')
482 482
483 if self._AreModulesEnabled():
484 cflags.append('-fmodules')
485 self._Appendf(cflags,
486 'CLANG_MODULE_CACHE_PATH',
487 '-fmodules-cache-path=\'%s\'',
488 self._GetDefaultClangModuleCachePath())
489 if self._IsModuleDefined():
490 cflags.append('-Xclang -fmodule-implementation-of -Xclang ' +
Nico 2015/06/10 01:09:18 -Xclang flags are considered clang-internal flags
efimovmichael 2015/07/22 14:46:05 I tried to copy all flags, which Xcode uses itself
491 self._GetProductModuleName())
492 cflags.append('-F.')
493
483 if self._Test('GCC_CHAR_IS_UNSIGNED_CHAR', 'YES', default='NO'): 494 if self._Test('GCC_CHAR_IS_UNSIGNED_CHAR', 'YES', default='NO'):
484 cflags.append('-funsigned-char') 495 cflags.append('-funsigned-char')
485 496
486 if self._Test('GCC_CW_ASM_SYNTAX', 'YES', default='YES'): 497 if self._Test('GCC_CW_ASM_SYNTAX', 'YES', default='YES'):
487 cflags.append('-fasm-blocks') 498 cflags.append('-fasm-blocks')
488 499
489 if 'GCC_DYNAMIC_NO_PIC' in self._Settings(): 500 if 'GCC_DYNAMIC_NO_PIC' in self._Settings():
490 if self._Settings()['GCC_DYNAMIC_NO_PIC'] == 'YES': 501 if self._Settings()['GCC_DYNAMIC_NO_PIC'] == 'YES':
491 cflags.append('-mdynamic-no-pic') 502 cflags.append('-mdynamic-no-pic')
492 else: 503 else:
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 579
569 cflags += self._Settings().get('WARNING_CFLAGS', []) 580 cflags += self._Settings().get('WARNING_CFLAGS', [])
570 581
571 if sdk_root: 582 if sdk_root:
572 framework_root = sdk_root 583 framework_root = sdk_root
573 else: 584 else:
574 framework_root = '' 585 framework_root = ''
575 config = self.spec['configurations'][self.configname] 586 config = self.spec['configurations'][self.configname]
576 framework_dirs = config.get('mac_framework_dirs', []) 587 framework_dirs = config.get('mac_framework_dirs', [])
577 for directory in framework_dirs: 588 for directory in framework_dirs:
578 cflags.append('-F' + directory.replace('$(SDKROOT)', framework_root)) 589 cflags.append('-F' + os.path.normpath(
590 directory.replace('$(SDKROOT)', framework_root)))
579 591
580 self.configname = None 592 self.configname = None
581 return cflags 593 return cflags
582 594
595 def AreModulesEnabled(self, configname):
596 self.configname = configname
597 res = self._AreModulesEnabled()
598 self.configname = None
599 return res
600
601 def _AreModulesEnabled(self):
602 res = self._Test('CLANG_ENABLE_MODULES', 'YES', default='NO')
603 return res
604
605 def IsModuleDefined(self, configname):
606 self.configname = configname
607 res = self._IsModuleDefined()
608 self.configname = None
609 return res
610
611 def _IsModuleDefined(self):
612 res = self._Test('DEFINES_MODULE', 'YES', default='NO')
613 return res
614
615 def GetProductModuleName(self, configname):
616 self.configname = configname
617 swift_module_name = self._GetProductModuleName()
618 self.configname = None
619 return swift_module_name
620
621 def _GetProductModuleName(self):
622 default_module_name = self.spec['target_name'].replace('-', '_')
623 return self._Settings().get(
624 'PRODUCT_MODULE_NAME', default_module_name)
625
626 def GetSwiftHeaderPath(self, configname, gyp_path_to_build_path, arch=None):
627 self.configname = configname
628 swift_header_path = self._GetSwiftHeaderPath(gyp_path_to_build_path, arch)
629 self.configname = None
630 return swift_header_path
631
632 def _GetSwiftHeaderPath(self, gyp_path_to_build_path, arch):
633 swift_header_name = self._Settings().get(
634 'SWIFT_OBJC_INTERFACE_HEADER_NAME',
635 self._GetProductModuleName() + '-Swift.h')
636 # SWIFT_OBJC_INTERFACE_HEADER_NAME must just a file name without path
637 assert(not os.path.dirname(swift_header_name))
638 if arch:
639 swift_header_name = re.sub(r'\.h$', '.' + arch + '.h', swift_header_name)
640 swift_header_path = os.path.join('$!INTERMEDIATE_DIR', swift_header_name)
641 swift_header_path = gyp_path_to_build_path(swift_header_path)
642 return swift_header_path
643
644 def GetSwiftLibsPath(self, configname):
645 developer_dir = subprocess.check_output(['xcode-select', '-p']).strip()
646 base_toolchain_path = os.path.join(
647 developer_dir, 'Toolchains/XcodeDefault.xctoolchain')
648 base_toolchain_path = os.path.normpath(base_toolchain_path)
649
650 sdk_path_basename = os.path.basename(self._SdkPath(configname))
651 if sdk_path_basename.lower().startswith('iphonesimulator'):
652 platform = 'iphonesimulator'
653 elif sdk_path_basename.lower().startswith('iphoneos'):
654 platform = 'iphoneos'
655 elif sdk_path_basename.lower().startswith('macosx'):
656 platform = 'macosx'
657 else:
658 assert(False)
659
660 swift_toolchain_path = os.path.join(
661 base_toolchain_path, 'usr/lib/swift', platform)
662 assert(os.path.exists(swift_toolchain_path))
663 return swift_toolchain_path
664
665 def _GetDefaultClangModuleCachePath(self):
666 return os.path.join(os.path.expanduser('~'),
667 'Library/Developer/Xcode/DerivedData/ModuleCache')
668
669 def _GetSwiftCommonFlags(self, gyp_path_to_build_path, arch):
670 assert(arch)
671
672 swift_flags = []
673 swift_flags.append('-enable-objc-interop')
674
675 if self._IsModuleDefined():
676 swift_flags.append('-import-underlying-module')
677
678 self._Appendf(swift_flags, 'IPHONEOS_DEPLOYMENT_TARGET',
679 '-target ' + arch + '-apple-ios%s')
680 self._Appendf(swift_flags, 'MACOSX_DEPLOYMENT_TARGET',
681 '-target ' + arch + '-apple-macosx%s')
682
683 swift_flags.append('-sdk ' + self._SdkPath())
684
685 swift_flags.append('-g')
686
687 swift_flags.append('-parse-as-library')
688
689 self._Appendf(swift_flags,
690 'CLANG_MODULE_CACHE_PATH',
691 '-module-cache-path \'%s\'',
692 self._GetDefaultClangModuleCachePath())
693
694 swift_flags.append('-module-name ' + self._GetProductModuleName())
695
696 if self._Settings().get('SWIFT_OBJC_BRIDGING_HEADER'):
697 import_header = self._Settings().get('SWIFT_OBJC_BRIDGING_HEADER')
698 import_header = gyp_path_to_build_path(import_header)
699 swift_flags.append('-import-objc-header \'' + import_header + '\'')
700
701 config = self.spec['configurations'][self.configname]
702 framework_dirs = config.get('mac_framework_dirs', [])
703 sdk_root = self._SdkPath()
704 for directory in framework_dirs:
705 swift_flags.append('-F ' + os.path.normpath(
706 directory.replace('$(SDKROOT)', sdk_root)))
707
708 swift_flags.append('-F .')
709 swift_flags.append('-I .')
710
711 return swift_flags
712
713 def GetBundleFrameworksFolderPath(self):
714 return os.path.join(self.GetBundleContentsFolderPath(), 'Frameworks')
715
716 def GetBundlePublicHeadersFolderPath(self):
717 return os.path.join(self.GetBundleContentsFolderPath(), 'Headers')
718
719 def GetBundlePrivateHeadersFolderPath(self):
720 return os.path.join(self.GetBundleContentsFolderPath(), 'PrivateHeaders')
721
722 def GetBundleModulesFolderPath(self):
723 return os.path.join(self.GetBundleContentsFolderPath(), 'Modules')
724
725 def GetSwiftCompileFlags(self, configname, gyp_path_to_build_path, arch):
726 self.configname = configname
727
728 swift_flags = self._GetSwiftCommonFlags(gyp_path_to_build_path, arch)
729
730 self._Appendf(swift_flags, 'SWIFT_OPTIMIZATION_LEVEL', '%s', '-O')
731
732 self.configname = None
733 return swift_flags
734
735 def GetSwiftMergeFlags(self, configname, gyp_path_to_build_path, arch):
736 self.configname = configname
737
738 swift_flags = self._GetSwiftCommonFlags(gyp_path_to_build_path, arch)
739
740 self.configname = None
741 return swift_flags
742
743 def GetSwiftLdflags(self, configname, arch_module_path):
744 ldflags = []
745 ldflags.append('-Xlinker -add_ast_path -Xlinker ' + arch_module_path)
746 ldflags.append('-L' + self.GetSwiftLibsPath(configname))
747 return ldflags
748
583 def GetCflagsC(self, configname): 749 def GetCflagsC(self, configname):
584 """Returns flags that need to be added to .c, and .m compilations.""" 750 """Returns flags that need to be added to .c, and .m compilations."""
585 self.configname = configname 751 self.configname = configname
586 cflags_c = [] 752 cflags_c = []
587 if self._Settings().get('GCC_C_LANGUAGE_STANDARD', '') == 'ansi': 753 if self._Settings().get('GCC_C_LANGUAGE_STANDARD', '') == 'ansi':
588 cflags_c.append('-ansi') 754 cflags_c.append('-ansi')
589 else: 755 else:
590 self._Appendf(cflags_c, 'GCC_C_LANGUAGE_STANDARD', '-std=%s') 756 self._Appendf(cflags_c, 'GCC_C_LANGUAGE_STANDARD', '-std=%s')
591 cflags_c += self._Settings().get('OTHER_CFLAGS', []) 757 cflags_c += self._Settings().get('OTHER_CFLAGS', [])
592 self.configname = None 758 self.configname = None
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 ldflags.append('-isysroot ' + self._SdkPath()) 961 ldflags.append('-isysroot ' + self._SdkPath())
796 962
797 for library_path in self._Settings().get('LIBRARY_SEARCH_PATHS', []): 963 for library_path in self._Settings().get('LIBRARY_SEARCH_PATHS', []):
798 ldflags.append('-L' + gyp_to_build_path(library_path)) 964 ldflags.append('-L' + gyp_to_build_path(library_path))
799 965
800 if 'ORDER_FILE' in self._Settings(): 966 if 'ORDER_FILE' in self._Settings():
801 ldflags.append('-Wl,-order_file ' + 967 ldflags.append('-Wl,-order_file ' +
802 '-Wl,' + gyp_to_build_path( 968 '-Wl,' + gyp_to_build_path(
803 self._Settings()['ORDER_FILE'])) 969 self._Settings()['ORDER_FILE']))
804 970
971 if 'BUNDLE_LOADER' in self._Settings():
972 bundle_loader_path = gyp_to_build_path(self._Settings()['BUNDLE_LOADER'])
973 ldflags.append('-bundle_loader ' + bundle_loader_path)
974
805 if arch is not None: 975 if arch is not None:
806 archs = [arch] 976 archs = [arch]
807 else: 977 else:
808 assert self.configname 978 assert self.configname
809 archs = self.GetActiveArchs(self.configname) 979 archs = self.GetActiveArchs(self.configname)
810 if len(archs) != 1: 980 if len(archs) != 1:
811 # TODO: Supporting fat binaries will be annoying. 981 # TODO: Supporting fat binaries will be annoying.
812 self._WarnUnimplemented('ARCHS') 982 self._WarnUnimplemented('ARCHS')
813 archs = ['i386'] 983 archs = ['i386']
814 ldflags.append('-arch ' + archs[0]) 984 ldflags.append('-arch ' + archs[0])
815 985
816 # Xcode adds the product directory by default. 986 # Xcode adds the product directory by default.
817 ldflags.append('-L' + product_dir) 987 ldflags.append('-L' + product_dir)
818 988
819 install_name = self.GetInstallName() 989 install_name = self.GetInstallName()
820 if install_name and self.spec['type'] != 'loadable_module': 990 if install_name and self.spec['type'] != 'loadable_module':
821 ldflags.append('-install_name ' + install_name.replace(' ', r'\ ')) 991 ldflags.append('-install_name ' + install_name.replace(' ', r'\ '))
822 992
823 for rpath in self._Settings().get('LD_RUNPATH_SEARCH_PATHS', []): 993 for rpath in self._Settings().get('LD_RUNPATH_SEARCH_PATHS', []):
824 ldflags.append('-Wl,-rpath,' + rpath) 994 ldflags.append('-Xlinker -rpath -Xlinker ' + rpath)
825 995
826 sdk_root = self._SdkPath() 996 sdk_root = self._SdkPath()
827 if not sdk_root: 997 if not sdk_root:
828 sdk_root = '' 998 sdk_root = ''
829 config = self.spec['configurations'][self.configname] 999 config = self.spec['configurations'][self.configname]
830 framework_dirs = config.get('mac_framework_dirs', []) 1000 framework_dirs = config.get('mac_framework_dirs', [])
831 for directory in framework_dirs: 1001 for directory in framework_dirs:
832 ldflags.append('-F' + directory.replace('$(SDKROOT)', sdk_root)) 1002 ldflags.append('-F' + os.path.normpath(
1003 directory.replace('$(SDKROOT)', sdk_root)))
1004
1005 ldflags.append('-F.')
833 1006
834 is_extension = self._IsIosAppExtension() or self._IsIosWatchKitExtension() 1007 is_extension = self._IsIosAppExtension() or self._IsIosWatchKitExtension()
835 if sdk_root and is_extension: 1008 if sdk_root and is_extension:
836 # Adds the link flags for extensions. These flags are common for all 1009 # Adds the link flags for extensions. These flags are common for all
837 # extensions and provide loader and main function. 1010 # extensions and provide loader and main function.
838 # These flags reflect the compilation options used by xcode to compile 1011 # These flags reflect the compilation options used by xcode to compile
839 # extensions. 1012 # extensions.
840 ldflags.append('-lpkstart') 1013 ldflags.append('-lpkstart')
841 ldflags.append(sdk_root + 1014 ldflags.append(sdk_root +
842 '/System/Library/PrivateFrameworks/PlugInKit.framework/PlugInKit') 1015 '/System/Library/PrivateFrameworks/PlugInKit.framework/PlugInKit')
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after
1405 'INFOPLIST_PREPROCESSOR_DEFINITIONS', default='')) 1578 'INFOPLIST_PREPROCESSOR_DEFINITIONS', default=''))
1406 else: 1579 else:
1407 defines = [] 1580 defines = []
1408 1581
1409 dest_plist = os.path.join(product_dir, xcode_settings.GetBundlePlistPath()) 1582 dest_plist = os.path.join(product_dir, xcode_settings.GetBundlePlistPath())
1410 extra_env = xcode_settings.GetPerTargetSettings() 1583 extra_env = xcode_settings.GetPerTargetSettings()
1411 1584
1412 return info_plist, dest_plist, defines, extra_env 1585 return info_plist, dest_plist, defines, extra_env
1413 1586
1414 1587
1588 def IsSwiftSupported():
1589 xcode_version, _ = XcodeVersion()
1590 return xcode_version >= '0600'
1591
1592
1415 def _GetXcodeEnv(xcode_settings, built_products_dir, srcroot, configuration, 1593 def _GetXcodeEnv(xcode_settings, built_products_dir, srcroot, configuration,
1416 additional_settings=None): 1594 additional_settings=None):
1417 """Return the environment variables that Xcode would set. See 1595 """Return the environment variables that Xcode would set. See
1418 http://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference /XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_r ef/doc/uid/TP40003931-CH3-SW153 1596 http://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference /XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_r ef/doc/uid/TP40003931-CH3-SW153
1419 for a full list. 1597 for a full list.
1420 1598
1421 Args: 1599 Args:
1422 xcode_settings: An XcodeSettings object. If this is None, this function 1600 xcode_settings: An XcodeSettings object. If this is None, this function
1423 returns an empty dict. 1601 returns an empty dict.
1424 built_products_dir: Absolute path to the built products dir. 1602 built_products_dir: Absolute path to the built products dir.
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1600 if toolset == 'target': 1778 if toolset == 'target':
1601 iphoneos_config_dict['xcode_settings']['SDKROOT'] = 'iphoneos' 1779 iphoneos_config_dict['xcode_settings']['SDKROOT'] = 'iphoneos'
1602 return targets 1780 return targets
1603 1781
1604 def CloneConfigurationForDeviceAndEmulator(target_dicts): 1782 def CloneConfigurationForDeviceAndEmulator(target_dicts):
1605 """If |target_dicts| contains any iOS targets, automatically create -iphoneos 1783 """If |target_dicts| contains any iOS targets, automatically create -iphoneos
1606 targets for iOS device builds.""" 1784 targets for iOS device builds."""
1607 if _HasIOSTarget(target_dicts): 1785 if _HasIOSTarget(target_dicts):
1608 return _AddIOSDeviceConfigurations(target_dicts) 1786 return _AddIOSDeviceConfigurations(target_dicts)
1609 return target_dicts 1787 return target_dicts
OLDNEW
« 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