OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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) |
OLD | NEW |