• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <algorithm>
8 
9 #include "gn/deps_iterator.h"
10 #include "gn/err.h"
11 #include "gn/settings.h"
12 #include "gn/substitution_writer.h"
13 #include "gn/target.h"
14 #include "gn/tool.h"
15 
16 SwiftValues::SwiftValues() = default;
17 
18 SwiftValues::~SwiftValues() = default;
19 
20 // static
OnTargetResolved(Target * target,Err * err)21 bool SwiftValues::OnTargetResolved(Target* target, Err* err) {
22   if (!target->builds_swift_module())
23     return true;
24 
25   return target->swift_values().FillModuleOutputFile(target, err);
26 }
27 
GetTool(const Target * target) const28 const Tool* SwiftValues::GetTool(const Target* target) const {
29   DCHECK(target->builds_swift_module());
30   return target->toolchain()->GetToolForSourceType(SourceFile::SOURCE_SWIFT);
31 }
32 
GetOutputs(const Target * target,std::vector<OutputFile> * result) const33 void SwiftValues::GetOutputs(const Target* target,
34                              std::vector<OutputFile>* result) const {
35   const Tool* tool = GetTool(target);
36 
37   // Expand tool's outputs().
38   SubstitutionWriter::ApplyListToLinkerAsOutputFile(target, tool,
39                                                     tool->outputs(), result);
40 
41   // Expand tool's partial_outputs() for each .swift source file.
42   for (const SourceFile& source : target->sources()) {
43     if (!source.IsSwiftType()) {
44       continue;
45     }
46 
47     SubstitutionWriter::ApplyListToCompilerAsOutputFile(
48         target, source, tool->partial_outputs(), result);
49   }
50 }
51 
GetOutputsAsSourceFiles(const Target * target,std::vector<SourceFile> * result) const52 void SwiftValues::GetOutputsAsSourceFiles(
53     const Target* target,
54     std::vector<SourceFile>* result) const {
55   std::vector<OutputFile> outputs;
56   GetOutputs(target, &outputs);
57 
58   result->reserve(outputs.size());
59 
60   const BuildSettings* build_settings = target->settings()->build_settings();
61   for (const OutputFile& output : outputs) {
62     result->push_back(output.AsSourceFile(build_settings));
63   }
64 }
65 
FillModuleOutputFile(Target * target,Err * err)66 bool SwiftValues::FillModuleOutputFile(Target* target, Err* err) {
67   std::vector<OutputFile> outputs;
68   GetOutputs(target, &outputs);
69 
70   // Keep only .swiftmodule output files.
71   const BuildSettings* build_settings = target->settings()->build_settings();
72   const auto iter = std::remove_if(
73       outputs.begin(), outputs.end(),
74       [build_settings](const OutputFile& output) -> bool {
75         SourceFile output_as_source_file = output.AsSourceFile(build_settings);
76         return !output_as_source_file.IsSwiftModuleType();
77       });
78   outputs.erase(iter, outputs.end());
79 
80   // A target should generate exactly one .swiftmodule file.
81   if (outputs.size() != 1) {
82     const Tool* tool = GetTool(target);
83     *err = Err(tool->defined_from(), "Incorrect outputs for tool",
84                "The outputs of tool " + std::string(tool->name()) +
85                    " must list exactly one .swiftmodule file");
86     return false;
87   }
88 
89   module_output_file_ = outputs.front();
90   module_output_dir_ =
91       module_output_file_.AsSourceFile(build_settings).GetDir();
92 
93   return true;
94 }
95