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 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |