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

Side by Side Diff: pylib/gyp/generator/ninja.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 unified diff | Download patch
« no previous file with comments | « no previous file | pylib/gyp/mac_tool.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) 2013 Google Inc. All rights reserved. 1 # Copyright (c) 2013 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 import collections 5 import collections
6 import copy 6 import copy
7 import hashlib 7 import hashlib
8 import json 8 import json
9 import multiprocessing 9 import multiprocessing
10 import os.path 10 import os.path
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 # File representing the completion of actions/rules/copies, if any. 133 # File representing the completion of actions/rules/copies, if any.
134 self.actions_stamp = None 134 self.actions_stamp = None
135 # Path to the output of the link step, if any. 135 # Path to the output of the link step, if any.
136 self.binary = None 136 self.binary = None
137 # Path to the file representing the completion of building the bundle, 137 # Path to the file representing the completion of building the bundle,
138 # if any. 138 # if any.
139 self.bundle = None 139 self.bundle = None
140 # On Windows, incremental linking requires linking against all the .objs 140 # On Windows, incremental linking requires linking against all the .objs
141 # that compose a .lib (rather than the .lib itself). That list is stored 141 # that compose a .lib (rather than the .lib itself). That list is stored
142 # here. 142 # here.
143
144 # Path to the file representing completion of building module, if any.
145 self.module_stamp = None
146
143 self.component_objs = None 147 self.component_objs = None
144 # Windows only. The import .lib is the output of a build step, but 148 # Windows only. The import .lib is the output of a build step, but
145 # because dependents only link against the lib (not both the lib and the 149 # because dependents only link against the lib (not both the lib and the
146 # dll) we keep track of the import library here. 150 # dll) we keep track of the import library here.
147 self.import_lib = None 151 self.import_lib = None
148 152
149 def Linkable(self): 153 def Linkable(self):
150 """Return true if this is a target that can be linked against.""" 154 """Return true if this is a target that can be linked against."""
151 return self.type in ('static_library', 'shared_library') 155 return self.type in ('static_library', 'shared_library')
152 156
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 if path.startswith('$!'): 299 if path.startswith('$!'):
296 expanded = self.ExpandSpecial(path) 300 expanded = self.ExpandSpecial(path)
297 if self.flavor == 'win': 301 if self.flavor == 'win':
298 expanded = os.path.normpath(expanded) 302 expanded = os.path.normpath(expanded)
299 return expanded 303 return expanded
300 if '$|' in path: 304 if '$|' in path:
301 path = self.ExpandSpecial(path) 305 path = self.ExpandSpecial(path)
302 assert '$' not in path, path 306 assert '$' not in path, path
303 return os.path.normpath(os.path.join(self.build_to_base, path)) 307 return os.path.normpath(os.path.join(self.build_to_base, path))
304 308
309 def GypPathToNinjaWithToolchain(self, path):
310 return self.GypPathToNinja(path, self.GetToolchainEnv())
311
305 def GypPathToUniqueOutput(self, path, qualified=True): 312 def GypPathToUniqueOutput(self, path, qualified=True):
306 """Translate a gyp path to a ninja path for writing output. 313 """Translate a gyp path to a ninja path for writing output.
307 314
308 If qualified is True, qualify the resulting filename with the name 315 If qualified is True, qualify the resulting filename with the name
309 of the target. This is necessary when e.g. compiling the same 316 of the target. This is necessary when e.g. compiling the same
310 path twice for two separate output targets. 317 path twice for two separate output targets.
311 318
312 See the above discourse on path conversions.""" 319 See the above discourse on path conversions."""
313 320
314 path = self.ExpandSpecial(path) 321 path = self.ExpandSpecial(path)
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 self.name = spec['target_name'] 376 self.name = spec['target_name']
370 self.toolset = spec['toolset'] 377 self.toolset = spec['toolset']
371 config = spec['configurations'][config_name] 378 config = spec['configurations'][config_name]
372 self.target = Target(spec['type']) 379 self.target = Target(spec['type'])
373 self.is_standalone_static_library = bool( 380 self.is_standalone_static_library = bool(
374 spec.get('standalone_static_library', 0)) 381 spec.get('standalone_static_library', 0))
375 # Track if this target contains any C++ files, to decide if gcc or g++ 382 # Track if this target contains any C++ files, to decide if gcc or g++
376 # should be used for linking. 383 # should be used for linking.
377 self.uses_cpp = False 384 self.uses_cpp = False
378 385
386 # Track if there are any swift sources
387 self.uses_swift = False
388
379 self.is_mac_bundle = gyp.xcode_emulation.IsMacBundle(self.flavor, spec) 389 self.is_mac_bundle = gyp.xcode_emulation.IsMacBundle(self.flavor, spec)
380 self.xcode_settings = self.msvs_settings = None 390 self.xcode_settings = self.msvs_settings = None
381 if self.flavor == 'mac': 391 if self.flavor == 'mac':
382 self.xcode_settings = gyp.xcode_emulation.XcodeSettings(spec) 392 self.xcode_settings = gyp.xcode_emulation.XcodeSettings(spec)
383 if self.flavor == 'win': 393 if self.flavor == 'win':
384 self.msvs_settings = gyp.msvs_emulation.MsvsSettings(spec, 394 self.msvs_settings = gyp.msvs_emulation.MsvsSettings(spec,
385 generator_flags) 395 generator_flags)
386 arch = self.msvs_settings.GetArch(config_name) 396 arch = self.msvs_settings.GetArch(config_name)
387 self.ninja.variable('arch', self.win_env[arch]) 397 self.ninja.variable('arch', self.win_env[arch])
388 self.ninja.variable('cc', '$cl_' + arch) 398 self.ninja.variable('cc', '$cl_' + arch)
(...skipping 12 matching lines...) Expand all
401 'w'))) 411 'w')))
402 for arch in self.archs) 412 for arch in self.archs)
403 413
404 # Compute predepends for all rules. 414 # Compute predepends for all rules.
405 # actions_depends is the dependencies this target depends on before running 415 # actions_depends is the dependencies this target depends on before running
406 # any of its action/rule/copy steps. 416 # any of its action/rule/copy steps.
407 # compile_depends is the dependencies this target depends on before running 417 # compile_depends is the dependencies this target depends on before running
408 # any of its compile steps. 418 # any of its compile steps.
409 actions_depends = [] 419 actions_depends = []
410 compile_depends = [] 420 compile_depends = []
421 module_depends = []
411 # TODO(evan): it is rather confusing which things are lists and which 422 # TODO(evan): it is rather confusing which things are lists and which
412 # are strings. Fix these. 423 # are strings. Fix these.
413 if 'dependencies' in spec: 424 if 'dependencies' in spec:
414 for dep in spec['dependencies']: 425 for dep in spec['dependencies']:
415 if dep in self.target_outputs: 426 if dep in self.target_outputs:
416 target = self.target_outputs[dep] 427 target = self.target_outputs[dep]
417 actions_depends.append(target.PreActionInput(self.flavor)) 428 actions_depends.append(target.PreActionInput(self.flavor))
418 compile_depends.append(target.PreCompileInput()) 429 compile_depends.append(target.PreCompileInput())
430 module_depends.append(target.module_stamp)
419 actions_depends = filter(None, actions_depends) 431 actions_depends = filter(None, actions_depends)
420 compile_depends = filter(None, compile_depends) 432 compile_depends = filter(None, compile_depends)
433 module_depends = filter(None, module_depends)
434 if (self.flavor == 'mac' and
435 self.xcode_settings.AreModulesEnabled(config_name)):
436 compile_depends += module_depends
437
421 actions_depends = self.WriteCollapsedDependencies('actions_depends', 438 actions_depends = self.WriteCollapsedDependencies('actions_depends',
422 actions_depends) 439 actions_depends)
423 compile_depends = self.WriteCollapsedDependencies('compile_depends', 440 compile_depends = self.WriteCollapsedDependencies('compile_depends',
424 compile_depends) 441 compile_depends)
425 self.target.preaction_stamp = actions_depends 442 self.target.preaction_stamp = actions_depends
426 self.target.precompile_stamp = compile_depends 443 self.target.precompile_stamp = compile_depends
427 444
428 # Write out actions, rules, and copies. These must happen before we 445 # Write out actions, rules, and copies. These must happen before we
429 # compile any sources, so compute a list of predependencies for sources 446 # compile any sources, so compute a list of predependencies for sources
430 # while we do it. 447 # while we do it.
431 extra_sources = [] 448 extra_sources = []
432 mac_bundle_depends = [] 449 mac_bundle_depends = []
433 self.target.actions_stamp = self.WriteActionsRulesCopies( 450 self.target.actions_stamp = self.WriteActionsRulesCopies(
434 spec, extra_sources, actions_depends, mac_bundle_depends) 451 spec, extra_sources, actions_depends, mac_bundle_depends)
435 452
436 # If we have actions/rules/copies, we depend directly on those, but 453 # If we have actions/rules/copies, we depend directly on those, but
437 # otherwise we depend on dependent target's actions/rules/copies etc. 454 # otherwise we depend on dependent target's actions/rules/copies etc.
438 # We never need to explicitly depend on previous target's link steps, 455 # We never need to explicitly depend on previous target's link steps,
439 # because no compile ever depends on them. 456 # because no compile ever depends on them.
440 compile_depends_stamp = (self.target.actions_stamp or compile_depends) 457 compile_depends_stamp = (self.target.actions_stamp or compile_depends)
441 458
459 if self.flavor == 'mac':
460 # Module should be written before compilaton, because Swift compiler
461 # use it
462 module_stamp = self.WriteModule(self.ninja, compile_depends_stamp,
463 config_name, spec)
464 if module_stamp:
465 compile_depends_stamp = module_stamp
466
442 # Write out the compilation steps, if any. 467 # Write out the compilation steps, if any.
443 link_deps = [] 468 link_deps = []
444 sources = extra_sources + spec.get('sources', []) 469 sources = extra_sources + spec.get('sources', [])
445 if sources: 470 if sources:
446 if self.flavor == 'mac' and len(self.archs) > 1: 471 if self.flavor == 'mac' and len(self.archs) > 1:
447 # Write subninja file containing compile and link commands scoped to 472 # Write subninja file containing compile and link commands scoped to
448 # a single arch if a fat binary is being built. 473 # a single arch if a fat binary is being built.
449 for arch in self.archs: 474 for arch in self.archs:
450 self.ninja.subninja(self._SubninjaNameForArch(arch)) 475 self.ninja.subninja(self._SubninjaNameForArch(arch))
451 476
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 [partial_info_plist, info_plist]) 873 [partial_info_plist, info_plist])
849 874
850 keys = self.xcode_settings.GetExtraPlistItems(self.config_name) 875 keys = self.xcode_settings.GetExtraPlistItems(self.config_name)
851 keys = QuoteShellArgument(json.dumps(keys), self.flavor) 876 keys = QuoteShellArgument(json.dumps(keys), self.flavor)
852 isBinary = self.xcode_settings.IsBinaryOutputFormat(self.config_name) 877 isBinary = self.xcode_settings.IsBinaryOutputFormat(self.config_name)
853 self.ninja.build(out, 'copy_infoplist', info_plist, 878 self.ninja.build(out, 'copy_infoplist', info_plist,
854 variables=[('env', env), ('keys', keys), 879 variables=[('env', env), ('keys', keys),
855 ('binary', isBinary)]) 880 ('binary', isBinary)])
856 bundle_depends.append(out) 881 bundle_depends.append(out)
857 882
883 def _AddSwiftModuleExt(self, module):
884 return module + '.swiftmodule'
885
886 def _GetSwiftModulePath(self, config_name, spec, arch=None):
887 module_path = self._AddSwiftModuleExt(
888 self.xcode_settings.GetProductModuleName(config_name))
889 if self._IsFramework(spec):
890 module_path = os.path.join(
891 self.xcode_settings.GetBundleModulesFolderPath(), module_path)
892 if arch:
893 # Fixing path for armv7, since Xcode expects it to have 'arm' name instead
894 if arch == 'armv7':
895 arch = 'arm'
896 module_path = os.path.join(module_path, self._AddSwiftModuleExt(arch))
897 return module_path
898
899 def WriteFrameworkHeaders(self, ninja_file, headers, headers_dir):
900 outputs = []
901 for header in headers:
902 out_path = os.path.join(headers_dir, os.path.basename(header))
903 outputs.append(out_path)
904 self.ninja.build(out_path, 'mac_tool', header,
905 variables=[('mactool_cmd', 'copy-bundle-resource'), \
906 ('binary', False)])
907 return outputs
908
909 def _GetModuleMapFilePath(self):
910 return os.path.join(self.xcode_settings.GetBundleModulesFolderPath(),
911 'module.modulemap')
912
913 def _IsFramework(self, spec):
914 is_framework = (spec['type'] == 'shared_library') and self.is_mac_bundle
915 return is_framework
916
917 def WriteModule(self, ninja_file, predepends, config_name, spec):
918 """Write build rules to build Clang module."""
919 if not self.xcode_settings.IsModuleDefined(config_name):
920 return None
921 if not self._IsFramework(spec):
922 # There are no any actions by Xcode for non-framework targets
923 return None
924
925 assert self.xcode_settings.AreModulesEnabled(config_name)
926
927 ninja_file.newline()
928
929 module_inputs = []
930 # Copying headers to framework
931 public_headers = map(self.GypPathToNinja,
932 list(spec.get('mac_framework_headers', [])))
933 module_inputs += self.WriteFrameworkHeaders(
934 ninja_file, public_headers,
935 self.xcode_settings.GetBundlePublicHeadersFolderPath())
936
937 private_headers = map(self.GypPathToNinja,
938 list(spec.get('mac_framework_private_headers', [])))
939 module_inputs += self.WriteFrameworkHeaders(
940 ninja_file, private_headers,
941 self.xcode_settings.GetBundlePrivateHeadersFolderPath())
942
943 module_name = self.xcode_settings.GetProductModuleName(config_name)
944 umbrella_header = None
945 for header in public_headers:
946 filename, _ = os.path.splitext(os.path.basename(header))
947 if filename == module_name:
948 umbrella_header = header
949 break
950
951 assert umbrella_header
952
953 # Building module map file in the /Modules folder
954 module_map_path = self._GetModuleMapFilePath()
955 variables = {
956 'module_name': module_name,
957 'umbrella_header': os.path.basename(umbrella_header),
958 'map_file': QuoteShellArgument(module_map_path, self.flavor)
959 }
960 module_map_stamp = self.GypPathToUniqueOutput('modulemap.stamp')
961 self.ninja.build(module_map_stamp, 'modulemap', [umbrella_header],
962 variables=variables)
963 module_inputs.append(module_map_stamp)
964
965 # Resulting module stamp
966 module_stamp = self.GypPathToUniqueOutput('module.stamp')
967 self.ninja.build(module_stamp, 'stamp', module_inputs,
968 order_only=predepends)
969 self.target.module_stamp = module_stamp
970 ninja_file.newline()
971 return module_stamp
972
973 def _as_list(self, input):
974 if input is None:
975 return []
976 if isinstance(input, list):
977 return input
978 return [input]
979
980 def WriteSwiftSourcesForArch(self, ninja_file, config_name, sources,
981 predepends, spec, arch=None):
982 assert self.flavor == 'mac'
983
984 # Collecting all Swift sources
985 swift_sources = []
986 for source in sources:
987 filename, ext = os.path.splitext(source)
988 ext = ext[1:]
989 if ext == 'swift':
990 swift_sources.append(self.GypPathToNinja(source))
991 if not swift_sources:
992 return ([], None)
993
994 if not gyp.xcode_emulation.IsSwiftSupported():
995 raise Exception('You are trying to build Swift files '
996 'with unsupported Xcode version.')
997 self.uses_swift = True
998
999 if not arch:
1000 arch = self.archs[0]
1001
1002 # Writing compile flags
1003 swift_compile_flags = self.xcode_settings.GetSwiftCompileFlags(
1004 config_name, self.GypPathToNinjaWithToolchain, arch)
1005 self.WriteVariableList(ninja_file, 'swift_compile_flags',
1006 map(self.ExpandSpecial, swift_compile_flags))
1007 ninja_file.newline()
1008
1009 single_rule = self.xcode_settings.IsSwiftWMOEnabled(config_name)
1010
1011 # Writing per-file rules
1012 link_deps = []
1013 partial_modules = []
1014 for source in swift_sources:
1015 filename, ext = os.path.splitext(os.path.basename(source))
1016 obj_path = self.GypPathToUniqueOutput(filename + self.obj_ext)
1017 obj_path = AddArch(obj_path, arch)
1018 src_module_path = self.GypPathToUniqueOutput(
1019 self._AddSwiftModuleExt(filename))
1020 src_module_path = AddArch(src_module_path, arch)
1021
1022 link_deps.append(obj_path)
1023 partial_modules.append(src_module_path)
1024
1025 if not single_rule:
1026 compile_input = [source]
1027 for another_source in swift_sources:
1028 if source != another_source:
1029 compile_input.append(another_source)
1030
1031 variables = {
1032 'out_obj': QuoteShellArgument(obj_path, self.flavor),
1033 'out_module': QuoteShellArgument(src_module_path, self.flavor)
1034 }
1035 ninja_file.build([obj_path, src_module_path], 'swift_perfile',
1036 compile_input, variables=variables,
1037 order_only=predepends)
1038
1039 module_predepends = self._as_list(predepends)
1040
1041 # Writing header for first arch without arch extension.
1042 # Obj sources will use it when referencing to <Module>-Swift.h file
1043 common_header_path = self.xcode_settings.GetSwiftHeaderPath(
1044 config_name, self.GypPathToNinja)
1045 if arch == self.archs[0]:
1046 header_path = common_header_path
1047 else:
1048 header_path = self.xcode_settings.GetSwiftHeaderPath(
1049 config_name, self.GypPathToNinja, arch)
1050 module_predepends.append(common_header_path)
1051
1052 module_path = self._GetSwiftModulePath(config_name, spec, arch)
1053
1054 if single_rule:
1055 out_objects = ''
1056 for obj in link_deps:
1057 out_objects += ' -o ' + obj
1058 variables = {
1059 'out_module': QuoteShellArgument(module_path, self.flavor),
1060 'out_header': QuoteShellArgument(header_path, self.flavor),
1061 'out_objects': QuoteShellArgument(out_objects, self.flavor),
1062 'num_threads': str(multiprocessing.cpu_count())
1063 }
1064 ninja_file.build(link_deps + [module_path, header_path], 'swift',
1065 swift_sources, variables=variables,
1066 order_only=module_predepends)
1067 else:
1068 # Writing Swift merge flags
1069 ninja_file.newline()
1070 swift_merge_flags = self.xcode_settings.GetSwiftMergeFlags(
1071 config_name, self.GypPathToNinjaWithToolchain, arch)
1072 self.WriteVariableList(ninja_file, 'swift_merge_flags',
1073 map(self.ExpandSpecial, swift_merge_flags))
1074 # Writing merge rule
1075 ninja_file.newline()
1076 variables = {
1077 'out_module': QuoteShellArgument(module_path, self.flavor),
1078 'out_header': QuoteShellArgument(header_path, self.flavor),
1079 }
1080 ninja_file.build([module_path, header_path], 'swift_merge',
1081 partial_modules, variables=variables,
1082 order_only=module_predepends)
1083 ninja_file.newline()
1084
1085 return (link_deps, module_path)
1086
1087 def WriteSwiftModule(self, ninja_file, config_name, spec):
1088 """Write build rules to build Swift module data"""
1089 if not self.uses_swift:
1090 return
1091
1092 assert self.xcode_settings.AreModulesEnabled(config_name)
1093
1094 ninja_file.newline()
1095
1096 module_inputs = []
1097 map_depends = []
1098 for arch in self.archs:
1099 swift_module_path = self._GetSwiftModulePath(config_name, spec, arch)
1100 module_inputs.append(swift_module_path)
1101 map_depends.append(swift_module_path)
1102
1103 if self._IsFramework(spec):
1104 assert self.xcode_settings.IsModuleDefined(config_name)
1105
1106 # Copying Swift header to framework
1107 swift_header = self.xcode_settings.GetSwiftHeaderPath(
1108 config_name, self.GypPathToNinja)
1109 module_inputs += self.WriteFrameworkHeaders(
1110 ninja_file, [swift_header],
1111 self.xcode_settings.GetBundlePublicHeadersFolderPath())
1112
1113 # Appending Swift info to the module map file in the /Modules folder
1114 module_name = self.xcode_settings.GetProductModuleName(config_name)
1115 module_map_path = self._GetModuleMapFilePath()
1116 variables = {
1117 'module_name': module_name,
1118 'swift_header': os.path.basename(swift_header),
1119 'map_file': QuoteShellArgument(module_map_path, self.flavor)
1120 }
1121 module_map_stamp = self.GypPathToUniqueOutput('swiftmodulemap.stamp')
1122 self.ninja.build(module_map_stamp, 'swiftmodulemap', [swift_header],
1123 order_only=map_depends, variables=variables)
1124 module_inputs.append(module_map_stamp)
1125
1126 # Resulting Swift actions stamp
1127 module_stamp = self.GypPathToUniqueOutput('swift_module.stamp')
1128 self.ninja.build(module_stamp, 'stamp', module_inputs)
1129 self.target.module_stamp = module_stamp
1130 ninja_file.newline()
1131
1132 def AppendSwiftLinkerOptions(self, ldflags, implicit_deps, config_name, spec,
1133 arch):
1134 if not self.uses_swift:
1135 return
1136 if arch is None:
1137 arch = self.archs[0]
1138 module_path = self._GetSwiftModulePath(config_name, spec, arch)
1139 ldflags += self.xcode_settings.GetSwiftLdflags(config_name, module_path)
1140 implicit_deps.add(module_path)
1141
1142 def CopySwiftLibsToBundle(self, spec):
1143 is_final = spec['type'] in ('executable', 'loadable_module')
1144 # We should try to copy swift libs even if the target does not have
1145 # swift files itself, because some of the dependent libs can have it.
1146 if not gyp.xcode_emulation.IsSwiftSupported() or not is_final:
1147 return None
1148
1149 if not self.target.binary:
1150 return None
1151
1152 # Copying all needed Swift dylibs right into the bundle
1153 app_frameworks_path = (
1154 self.xcode_settings.GetBundleFrameworksFolderPath())
1155 codesign_key = self.xcode_settings.GetCodeSignIdentityKey(
1156 self.config_name) or ''
1157 variables = {
1158 'platform': self.xcode_settings.GetPlatform(self.config_name),
1159 'dst_path': QuoteShellArgument(app_frameworks_path, self.flavor),
1160 'codesign_key': codesign_key}
1161 swift_libs_stamp = QuoteShellArgument(
1162 self.GypPathToUniqueOutput('copyswiftlibs.stamp'), self.flavor)
1163 self.ninja.build(swift_libs_stamp, 'copyswiftlibs', self.target.binary,
1164 variables=variables)
1165 return swift_libs_stamp
1166
858 def WriteSources(self, ninja_file, config_name, config, sources, predepends, 1167 def WriteSources(self, ninja_file, config_name, config, sources, predepends,
859 precompiled_header, spec): 1168 precompiled_header, spec):
860 """Write build rules to compile all of |sources|.""" 1169 """Write build rules to compile all of |sources|."""
861 if self.toolset == 'host': 1170 if self.toolset == 'host':
862 self.ninja.variable('ar', '$ar_host') 1171 self.ninja.variable('ar', '$ar_host')
863 self.ninja.variable('cc', '$cc_host') 1172 self.ninja.variable('cc', '$cc_host')
864 self.ninja.variable('cxx', '$cxx_host') 1173 self.ninja.variable('cxx', '$cxx_host')
865 self.ninja.variable('ld', '$ld_host') 1174 self.ninja.variable('ld', '$ld_host')
866 self.ninja.variable('ldxx', '$ldxx_host') 1175 self.ninja.variable('ldxx', '$ldxx_host')
867 self.ninja.variable('nm', '$nm_host') 1176 self.ninja.variable('nm', '$nm_host')
868 self.ninja.variable('readelf', '$readelf_host') 1177 self.ninja.variable('readelf', '$readelf_host')
869 1178
870 if self.flavor != 'mac' or len(self.archs) == 1: 1179 if self.flavor != 'mac' or len(self.archs) == 1:
871 return self.WriteSourcesForArch( 1180 return self.WriteSourcesForArch(
872 self.ninja, config_name, config, sources, predepends, 1181 self.ninja, config_name, config, sources, predepends,
873 precompiled_header, spec) 1182 precompiled_header, spec)
874 else: 1183 else:
875 return dict((arch, self.WriteSourcesForArch( 1184 return dict((arch, self.WriteSourcesForArch(
876 self.arch_subninjas[arch], config_name, config, sources, predepends, 1185 self.arch_subninjas[arch], config_name, config, sources, predepends,
877 precompiled_header, spec, arch=arch)) 1186 precompiled_header, spec, arch=arch))
878 for arch in self.archs) 1187 for arch in self.archs)
879 1188
880 def WriteSourcesForArch(self, ninja_file, config_name, config, sources, 1189 def WriteSourcesForArch(self, ninja_file, config_name, config, sources,
881 predepends, precompiled_header, spec, arch=None): 1190 predepends, precompiled_header, spec, arch=None):
882 """Write build rules to compile all of |sources|.""" 1191 """Write build rules to compile all of |sources|."""
883 1192
884 extra_defines = [] 1193 extra_defines = []
885 if self.flavor == 'mac': 1194 if self.flavor == 'mac':
886 cflags = self.xcode_settings.GetCflags(config_name, arch=arch) 1195 cflags = self.xcode_settings.GetCflags(config_name,
1196 self.GypPathToNinjaWithToolchain, arch=arch)
887 cflags_c = self.xcode_settings.GetCflagsC(config_name) 1197 cflags_c = self.xcode_settings.GetCflagsC(config_name)
888 cflags_cc = self.xcode_settings.GetCflagsCC(config_name) 1198 cflags_cc = self.xcode_settings.GetCflagsCC(config_name)
889 cflags_objc = ['$cflags_c'] + \ 1199 cflags_objc = ['$cflags_c'] + \
890 self.xcode_settings.GetCflagsObjC(config_name) 1200 self.xcode_settings.GetCflagsObjC(config_name)
891 cflags_objcc = ['$cflags_cc'] + \ 1201 cflags_objcc = ['$cflags_cc'] + \
892 self.xcode_settings.GetCflagsObjCC(config_name) 1202 self.xcode_settings.GetCflagsObjCC(config_name)
893 elif self.flavor == 'win': 1203 elif self.flavor == 'win':
894 asmflags = self.msvs_settings.GetAsmflags(config_name) 1204 asmflags = self.msvs_settings.GetAsmflags(config_name)
895 cflags = self.msvs_settings.GetCflags(config_name) 1205 cflags = self.msvs_settings.GetCflags(config_name)
896 cflags_c = self.msvs_settings.GetCflagsC(config_name) 1206 cflags_c = self.msvs_settings.GetCflagsC(config_name)
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 map(self.ExpandSpecial, cflags_cc)) 1279 map(self.ExpandSpecial, cflags_cc))
970 if self.flavor == 'mac': 1280 if self.flavor == 'mac':
971 self.WriteVariableList(ninja_file, 'cflags_objc', 1281 self.WriteVariableList(ninja_file, 'cflags_objc',
972 map(self.ExpandSpecial, cflags_objc)) 1282 map(self.ExpandSpecial, cflags_objc))
973 self.WriteVariableList(ninja_file, 'cflags_objcc', 1283 self.WriteVariableList(ninja_file, 'cflags_objcc',
974 map(self.ExpandSpecial, cflags_objcc)) 1284 map(self.ExpandSpecial, cflags_objcc))
975 self.WriteVariableList(ninja_file, 'arflags', 1285 self.WriteVariableList(ninja_file, 'arflags',
976 map(self.ExpandSpecial, arflags)) 1286 map(self.ExpandSpecial, arflags))
977 ninja_file.newline() 1287 ninja_file.newline()
978 outputs = [] 1288 outputs = []
1289
1290 if self.flavor == 'mac':
1291 swift_outputs, swift_module = self.WriteSwiftSourcesForArch(
1292 ninja_file, config_name, sources, predepends, spec, arch)
1293 outputs += swift_outputs
1294 predepends = swift_module or predepends
1295
979 has_rc_source = False 1296 has_rc_source = False
980 for source in sources: 1297 for source in sources:
981 filename, ext = os.path.splitext(source) 1298 filename, ext = os.path.splitext(source)
982 ext = ext[1:] 1299 ext = ext[1:]
983 obj_ext = self.obj_ext 1300 obj_ext = self.obj_ext
984 if ext in ('cc', 'cpp', 'cxx'): 1301 if ext in ('cc', 'cpp', 'cxx'):
985 command = 'cxx' 1302 command = 'cxx'
986 self.uses_cpp = True 1303 self.uses_cpp = True
987 elif ext == 'c' or (ext == 'S' and self.flavor != 'win'): 1304 elif ext == 'c' or (ext == 'S' and self.flavor != 'win'):
988 command = 'cc' 1305 command = 'cc'
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1130 if arch is None and not self.is_mac_bundle: 1447 if arch is None and not self.is_mac_bundle:
1131 self.AppendPostbuildVariable(extra_bindings, spec, output, output) 1448 self.AppendPostbuildVariable(extra_bindings, spec, output, output)
1132 1449
1133 is_executable = spec['type'] == 'executable' 1450 is_executable = spec['type'] == 'executable'
1134 # The ldflags config key is not used on mac or win. On those platforms 1451 # The ldflags config key is not used on mac or win. On those platforms
1135 # linker flags are set via xcode_settings and msvs_settings, respectively. 1452 # linker flags are set via xcode_settings and msvs_settings, respectively.
1136 env_ldflags = os.environ.get('LDFLAGS', '').split() 1453 env_ldflags = os.environ.get('LDFLAGS', '').split()
1137 if self.flavor == 'mac': 1454 if self.flavor == 'mac':
1138 ldflags = self.xcode_settings.GetLdflags(config_name, 1455 ldflags = self.xcode_settings.GetLdflags(config_name,
1139 self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']), 1456 self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']),
1140 self.GypPathToNinja, arch) 1457 self.GypPathToNinjaWithToolchain, arch)
1141 ldflags = env_ldflags + ldflags 1458 ldflags = env_ldflags + ldflags
1459 self.AppendSwiftLinkerOptions(
1460 ldflags, implicit_deps, config_name, spec, arch)
1142 elif self.flavor == 'win': 1461 elif self.flavor == 'win':
1143 manifest_base_name = self.GypPathToUniqueOutput( 1462 manifest_base_name = self.GypPathToUniqueOutput(
1144 self.ComputeOutputFileName(spec)) 1463 self.ComputeOutputFileName(spec))
1145 ldflags, intermediate_manifest, manifest_files = \ 1464 ldflags, intermediate_manifest, manifest_files = \
1146 self.msvs_settings.GetLdflags(config_name, self.GypPathToNinja, 1465 self.msvs_settings.GetLdflags(config_name, self.GypPathToNinja,
1147 self.ExpandSpecial, manifest_base_name, 1466 self.ExpandSpecial, manifest_base_name,
1148 output, is_executable, 1467 output, is_executable,
1149 self.toplevel_build) 1468 self.toplevel_build)
1150 ldflags = env_ldflags + ldflags 1469 ldflags = env_ldflags + ldflags
1151 self.WriteVariableList(ninja_file, 'manifests', manifest_files) 1470 self.WriteVariableList(ninja_file, 'manifests', manifest_files)
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1241 1560
1242 if len(solibs): 1561 if len(solibs):
1243 extra_bindings.append(('solibs', gyp.common.EncodePOSIXShellList(solibs))) 1562 extra_bindings.append(('solibs', gyp.common.EncodePOSIXShellList(solibs)))
1244 1563
1245 ninja_file.build(output, command + command_suffix, link_deps, 1564 ninja_file.build(output, command + command_suffix, link_deps,
1246 implicit=list(implicit_deps), 1565 implicit=list(implicit_deps),
1247 variables=extra_bindings) 1566 variables=extra_bindings)
1248 return linked_binary 1567 return linked_binary
1249 1568
1250 def WriteTarget(self, spec, config_name, config, link_deps, compile_deps): 1569 def WriteTarget(self, spec, config_name, config, link_deps, compile_deps):
1570 self.WriteSwiftModule(self.ninja, config_name, spec)
1251 extra_link_deps = any(self.target_outputs.get(dep).Linkable() 1571 extra_link_deps = any(self.target_outputs.get(dep).Linkable()
1252 for dep in spec.get('dependencies', []) 1572 for dep in spec.get('dependencies', [])
1253 if dep in self.target_outputs) 1573 if dep in self.target_outputs)
1254 if spec['type'] == 'none' or (not link_deps and not extra_link_deps): 1574 if spec['type'] == 'none' or (not link_deps and not extra_link_deps):
1255 # TODO(evan): don't call this function for 'none' target types, as 1575 # TODO(evan): don't call this function for 'none' target types, as
1256 # it doesn't do anything, and we fake out a 'binary' with a stamp file. 1576 # it doesn't do anything, and we fake out a 'binary' with a stamp file.
1257 self.target.binary = compile_deps 1577 self.target.binary = compile_deps
1258 self.target.type = 'none' 1578 self.target.type = 'none'
1259 elif spec['type'] == 'static_library': 1579 elif spec['type'] == 'static_library':
1260 self.target.binary = self.ComputeOutput(spec) 1580 self.target.binary = self.ComputeOutput(spec)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1293 self.ninja.build(self.target.binary, 'alink', inputs, 1613 self.ninja.build(self.target.binary, 'alink', inputs,
1294 # FIXME: test proving order_only=compile_deps isn't 1614 # FIXME: test proving order_only=compile_deps isn't
1295 # needed. 1615 # needed.
1296 variables=variables) 1616 variables=variables)
1297 else: 1617 else:
1298 self.target.binary = self.WriteLink(spec, config_name, config, link_deps) 1618 self.target.binary = self.WriteLink(spec, config_name, config, link_deps)
1299 return self.target.binary 1619 return self.target.binary
1300 1620
1301 def WriteMacBundle(self, spec, mac_bundle_depends, is_empty): 1621 def WriteMacBundle(self, spec, mac_bundle_depends, is_empty):
1302 assert self.is_mac_bundle 1622 assert self.is_mac_bundle
1623
1624 swift_frameworks = self.CopySwiftLibsToBundle(spec)
1625 if swift_frameworks:
1626 mac_bundle_depends.append(swift_frameworks)
1627
1628 if self.target.module_stamp:
1629 mac_bundle_depends.append(self.target.module_stamp)
1630
1303 package_framework = spec['type'] in ('shared_library', 'loadable_module') 1631 package_framework = spec['type'] in ('shared_library', 'loadable_module')
1304 output = self.ComputeMacBundleOutput() 1632 output = self.ComputeMacBundleOutput()
1305 if is_empty: 1633 if is_empty:
1306 output += '.stamp' 1634 output += '.stamp'
1307 variables = [] 1635 variables = []
1308 self.AppendPostbuildVariable(variables, spec, output, self.target.binary, 1636 self.AppendPostbuildVariable(variables, spec, output, self.target.binary,
1309 is_command_start=not package_framework) 1637 is_command_start=not package_framework)
1310 if package_framework and not is_empty: 1638 if package_framework and not is_empty:
1311 variables.append(('version', self.xcode_settings.GetFrameworkVersion())) 1639 variables.append(('version', self.xcode_settings.GetFrameworkVersion()))
1312 self.ninja.build(output, 'package_framework', mac_bundle_depends, 1640 self.ninja.build(output, 'package_framework', mac_bundle_depends,
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
1915 master_ninja.variable('ldxx', CommandWithWrapper('LINK', wrappers, ldxx)) 2243 master_ninja.variable('ldxx', CommandWithWrapper('LINK', wrappers, ldxx))
1916 master_ninja.variable('ar', GetEnvironFallback(['AR_target', 'AR'], ar)) 2244 master_ninja.variable('ar', GetEnvironFallback(['AR_target', 'AR'], ar))
1917 if flavor != 'mac': 2245 if flavor != 'mac':
1918 # Mac does not use readelf/nm for .TOC generation, so avoiding polluting 2246 # Mac does not use readelf/nm for .TOC generation, so avoiding polluting
1919 # the master ninja with extra unused variables. 2247 # the master ninja with extra unused variables.
1920 master_ninja.variable( 2248 master_ninja.variable(
1921 'nm', GetEnvironFallback(['NM_target', 'NM'], nm)) 2249 'nm', GetEnvironFallback(['NM_target', 'NM'], nm))
1922 master_ninja.variable( 2250 master_ninja.variable(
1923 'readelf', GetEnvironFallback(['READELF_target', 'READELF'], readelf)) 2251 'readelf', GetEnvironFallback(['READELF_target', 'READELF'], readelf))
1924 2252
2253 if flavor == 'mac' and gyp.xcode_emulation.IsSwiftSupported():
2254 master_ninja.variable(
2255 'swift', subprocess.check_output(['xcrun', '-f', 'swift']))
2256
1925 if generator_supports_multiple_toolsets: 2257 if generator_supports_multiple_toolsets:
1926 if not cc_host: 2258 if not cc_host:
1927 cc_host = cc 2259 cc_host = cc
1928 if not cxx_host: 2260 if not cxx_host:
1929 cxx_host = cxx 2261 cxx_host = cxx
1930 2262
1931 master_ninja.variable('ar_host', GetEnvironFallback(['AR_host'], ar_host)) 2263 master_ninja.variable('ar_host', GetEnvironFallback(['AR_host'], ar_host))
1932 master_ninja.variable('nm_host', GetEnvironFallback(['NM_host'], nm_host)) 2264 master_ninja.variable('nm_host', GetEnvironFallback(['NM_host'], nm_host))
1933 master_ninja.variable('readelf_host', 2265 master_ninja.variable('readelf_host',
1934 GetEnvironFallback(['READELF_host'], readelf_host)) 2266 GetEnvironFallback(['READELF_host'], readelf_host))
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
2099 depfile='$out.d', 2431 depfile='$out.d',
2100 deps=deps) 2432 deps=deps)
2101 master_ninja.rule( 2433 master_ninja.rule(
2102 'objcxx', 2434 'objcxx',
2103 description='OBJCXX $out', 2435 description='OBJCXX $out',
2104 command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_objcc ' 2436 command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_objcc '
2105 '$cflags_pch_objcc -c $in -o $out'), 2437 '$cflags_pch_objcc -c $in -o $out'),
2106 depfile='$out.d', 2438 depfile='$out.d',
2107 deps=deps) 2439 deps=deps)
2108 master_ninja.rule( 2440 master_ninja.rule(
2441 'swift',
2442 description='SWIFT $out_module',
2443 command=('$swift -frontend -c $in $swift_compile_flags '
2444 '-emit-module-path $out_module '
2445 '-emit-objc-header-path $out_header '
2446 '-num-threads $num_threads '
2447 '$out_objects'))
2448 master_ninja.rule(
2449 'swift_perfile',
2450 description='SWIFT $out_obj',
2451 command=('$swift -frontend -c -primary-file $in $swift_compile_flags '
2452 '-emit-module-path $out_module '
2453 '-o $out_obj'))
2454 master_ninja.rule(
2455 'swift_merge',
2456 description='SWIFT MERGE $out_module',
2457 command=('$swift -frontend -emit-module $in $swift_merge_flags '
2458 '-emit-objc-header-path $out_header '
2459 '-o $out_module'))
2460 master_ninja.rule(
2461 'copyswiftlibs',
2462 description='COPY SWIFT LIBS $out',
2463 command=('./gyp-mac-tool copy-swift-libs $in $platform $dst_path '
2464 '"$codesign_key" $out'))
2465 master_ninja.rule(
2466 'modulemap',
2467 description='MODULE MAP $map_file',
2468 command=('./gyp-mac-tool build-module-map-file '
2469 '$module_name $umbrella_header $map_file $out'))
2470 master_ninja.rule(
2471 'swiftmodulemap',
2472 description='SWIFT MODULE MAP $map_file',
2473 command=('./gyp-mac-tool append-swift-to-module-map-file '
2474 '$module_name $swift_header $map_file $out'))
2475 master_ninja.rule(
2109 'alink', 2476 'alink',
2110 description='LIBTOOL-STATIC $out, POSTBUILDS', 2477 description='LIBTOOL-STATIC $out, POSTBUILDS',
2111 command='rm -f $out && ' 2478 command='rm -f $out && '
2112 './gyp-mac-tool filter-libtool libtool $libtool_flags ' 2479 './gyp-mac-tool filter-libtool libtool $libtool_flags '
2113 '-static -o $out $in' 2480 '-static -o $out $in'
2114 '$postbuilds') 2481 '$postbuilds')
2115 master_ninja.rule( 2482 master_ninja.rule(
2116 'lipo', 2483 'lipo',
2117 description='LIPO $out, POSTBUILDS', 2484 description='LIPO $out, POSTBUILDS',
2118 command='rm -f $out && lipo -create $in -output $out$postbuilds') 2485 command='rm -f $out && lipo -create $in -output $out$postbuilds')
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
2382 arglists.append( 2749 arglists.append(
2383 (target_list, target_dicts, data, params, config_name)) 2750 (target_list, target_dicts, data, params, config_name))
2384 pool.map(CallGenerateOutputForConfig, arglists) 2751 pool.map(CallGenerateOutputForConfig, arglists)
2385 except KeyboardInterrupt, e: 2752 except KeyboardInterrupt, e:
2386 pool.terminate() 2753 pool.terminate()
2387 raise e 2754 raise e
2388 else: 2755 else:
2389 for config_name in config_names: 2756 for config_name in config_names:
2390 GenerateOutputForConfig(target_list, target_dicts, data, params, 2757 GenerateOutputForConfig(target_list, target_dicts, data, params,
2391 config_name) 2758 config_name)
OLDNEW
« no previous file with comments | « no previous file | pylib/gyp/mac_tool.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698