blob: 08f32acf2780d623b94b2e5e5ff2041bb45b206a [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "gn/swift_values.h"
#include <algorithm>
#include "gn/deps_iterator.h"
#include "gn/err.h"
#include "gn/settings.h"
#include "gn/substitution_writer.h"
#include "gn/target.h"
#include "gn/tool.h"
SwiftValues::SwiftValues() = default;
SwiftValues::~SwiftValues() = default;
// static
bool SwiftValues::OnTargetResolved(Target* target, Err* err) {
if (!target->builds_swift_module())
return true;
return target->swift_values().FillModuleOutputFile(target, err);
}
const Tool* SwiftValues::GetTool(const Target* target) const {
DCHECK(target->builds_swift_module());
return target->toolchain()->GetToolForSourceType(SourceFile::SOURCE_SWIFT);
}
void SwiftValues::GetOutputs(const Target* target,
std::vector<OutputFile>* result) const {
const Tool* tool = GetTool(target);
// Expand tool's outputs().
SubstitutionWriter::ApplyListToLinkerAsOutputFile(target, tool,
tool->outputs(), result);
// Expand tool's partial_outputs() for each .swift source file.
for (const SourceFile& source : target->sources()) {
if (!source.IsSwiftType()) {
continue;
}
SubstitutionWriter::ApplyListToCompilerAsOutputFile(
target, source, tool->partial_outputs(), result);
}
}
void SwiftValues::GetOutputsAsSourceFiles(
const Target* target,
std::vector<SourceFile>* result) const {
std::vector<OutputFile> outputs;
GetOutputs(target, &outputs);
result->reserve(outputs.size());
const BuildSettings* build_settings = target->settings()->build_settings();
for (const OutputFile& output : outputs) {
result->push_back(output.AsSourceFile(build_settings));
}
}
bool SwiftValues::FillModuleOutputFile(Target* target, Err* err) {
std::vector<OutputFile> outputs;
GetOutputs(target, &outputs);
// Keep only .swiftmodule output files.
const BuildSettings* build_settings = target->settings()->build_settings();
const auto iter = std::remove_if(
outputs.begin(), outputs.end(),
[build_settings](const OutputFile& output) -> bool {
SourceFile output_as_source_file = output.AsSourceFile(build_settings);
return !output_as_source_file.IsSwiftModuleType();
});
outputs.erase(iter, outputs.end());
// A target should generate exactly one .swiftmodule file.
if (outputs.size() != 1) {
const Tool* tool = GetTool(target);
*err = Err(tool->defined_from(), "Incorrect outputs for tool",
"The outputs of tool " + std::string(tool->name()) +
" must list exactly one .swiftmodule file");
return false;
}
module_output_file_ = outputs.front();
module_output_dir_ =
module_output_file_.AsSourceFile(build_settings).GetDir();
return true;
}