1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "gn/swift_values.h"
6
7 #include "gn/deps_iterator.h"
8 #include "gn/err.h"
9 #include "gn/settings.h"
10 #include "gn/substitution_writer.h"
11 #include "gn/target.h"
12
13 SwiftValues::SwiftValues() = default;
14
15 SwiftValues::~SwiftValues() = default;
16
17 // static
OnTargetResolved(Target * target,Err * err)18 bool SwiftValues::OnTargetResolved(Target* target, Err* err) {
19 if (!FillModuleOutputFile(target, err))
20 return false;
21
22 FillModuleDependencies(target);
23 return true;
24 }
25
26 // static
FillModuleDependencies(Target * target)27 void SwiftValues::FillModuleDependencies(Target* target) {
28 for (const auto& pair : target->GetDeps(Target::DEPS_LINKED)) {
29 if (!pair.ptr->has_swift_values())
30 continue;
31
32 if (pair.ptr->toolchain() == target->toolchain() ||
33 pair.ptr->toolchain()->propagates_configs()) {
34 target->swift_values().modules_.Append(
35 pair.ptr->swift_values().public_modules().begin(),
36 pair.ptr->swift_values().public_modules().end());
37 }
38 }
39
40 for (const auto& pair : target->public_deps()) {
41 if (!pair.ptr->has_swift_values())
42 continue;
43
44 if (pair.ptr->toolchain() == target->toolchain() ||
45 pair.ptr->toolchain()->propagates_configs())
46 target->swift_values().public_modules_.Append(
47 pair.ptr->swift_values().public_modules().begin(),
48 pair.ptr->swift_values().public_modules().end());
49 }
50
51 if (target->builds_swift_module())
52 target->swift_values().public_modules_.push_back(target);
53 }
54
55 // static
FillModuleOutputFile(Target * target,Err * err)56 bool SwiftValues::FillModuleOutputFile(Target* target, Err* err) {
57 if (!target->IsBinary() || !target->source_types_used().SwiftSourceUsed())
58 return true;
59
60 const Tool* tool =
61 target->toolchain()->GetToolForSourceType(SourceFile::SOURCE_SWIFT);
62 CHECK(tool->outputs().list().size() >= 1);
63
64 OutputFile module_output_file =
65 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
66 target, tool, tool->outputs().list()[0]);
67
68 const SourceFile module_output_file_as_source =
69 module_output_file.AsSourceFile(target->settings()->build_settings());
70 if (!module_output_file_as_source.IsSwiftModuleType()) {
71 *err = Err(tool->defined_from(), "Incorrect outputs for tool",
72 "The first output of tool " + std::string(tool->name()) +
73 " must be a .swiftmodule file.");
74 return false;
75 }
76
77 SwiftValues& swift_values = target->swift_values();
78 swift_values.module_output_file_ = std::move(module_output_file);
79 swift_values.module_output_dir_ = module_output_file_as_source.GetDir();
80
81 return true;
82 }
83