| Index: tools/gn/ninja_binary_target_writer.cc
|
| diff --git a/tools/gn/ninja_binary_target_writer.cc b/tools/gn/ninja_binary_target_writer.cc
|
| index a5b858e219caa26f83b6e7f77db574efd27e9e41..b96979d66c3009220572c675d9cc5a9c60243274 100644
|
| --- a/tools/gn/ninja_binary_target_writer.cc
|
| +++ b/tools/gn/ninja_binary_target_writer.cc
|
| @@ -10,7 +10,11 @@
|
| #include "tools/gn/config_values_extractors.h"
|
| #include "tools/gn/err.h"
|
| #include "tools/gn/escape.h"
|
| +#include "tools/gn/ninja_utils.h"
|
| +#include "tools/gn/settings.h"
|
| #include "tools/gn/string_utils.h"
|
| +#include "tools/gn/substitution_writer.h"
|
| +#include "tools/gn/target.h"
|
|
|
| namespace {
|
|
|
| @@ -41,9 +45,7 @@ struct DefineWriter {
|
| };
|
|
|
| struct IncludeWriter {
|
| - IncludeWriter(PathOutput& path_output, const NinjaHelper& h)
|
| - : helper(h),
|
| - path_output_(path_output) {
|
| + IncludeWriter(PathOutput& path_output) : path_output_(path_output) {
|
| }
|
| ~IncludeWriter() {
|
| }
|
| @@ -53,30 +55,15 @@ struct IncludeWriter {
|
| path_output_.WriteDir(out, d, PathOutput::DIR_NO_LAST_SLASH);
|
| }
|
|
|
| - const NinjaHelper& helper;
|
| PathOutput& path_output_;
|
| };
|
|
|
| -Toolchain::ToolType GetToolTypeForTarget(const Target* target) {
|
| - switch (target->output_type()) {
|
| - case Target::STATIC_LIBRARY:
|
| - return Toolchain::TYPE_ALINK;
|
| - case Target::SHARED_LIBRARY:
|
| - return Toolchain::TYPE_SOLINK;
|
| - case Target::EXECUTABLE:
|
| - return Toolchain::TYPE_LINK;
|
| - default:
|
| - return Toolchain::TYPE_NONE;
|
| - }
|
| -}
|
| -
|
| } // namespace
|
|
|
| NinjaBinaryTargetWriter::NinjaBinaryTargetWriter(const Target* target,
|
| - const Toolchain* toolchain,
|
| std::ostream& out)
|
| - : NinjaTargetWriter(target, toolchain, out),
|
| - tool_type_(GetToolTypeForTarget(target)){
|
| + : NinjaTargetWriter(target, out),
|
| + tool_(target->toolchain()->GetToolForTargetFinalOutput(target)) {
|
| }
|
|
|
| NinjaBinaryTargetWriter::~NinjaBinaryTargetWriter() {
|
| @@ -95,46 +82,44 @@ void NinjaBinaryTargetWriter::Run() {
|
| }
|
|
|
| void NinjaBinaryTargetWriter::WriteCompilerVars() {
|
| + const SubstitutionBits& subst = target_->toolchain()->substitution_bits();
|
| +
|
| // Defines.
|
| - out_ << "defines =";
|
| - RecursiveTargetConfigToStream<std::string>(target_, &ConfigValues::defines,
|
| - DefineWriter(), out_);
|
| - out_ << std::endl;
|
| + if (subst.used[SUBSTITUTION_DEFINES]) {
|
| + out_ << kSubstitutionNinjaNames[SUBSTITUTION_DEFINES] << " =";
|
| + RecursiveTargetConfigToStream<std::string>(
|
| + target_, &ConfigValues::defines, DefineWriter(), out_);
|
| + out_ << std::endl;
|
| + }
|
|
|
| // Include directories.
|
| - out_ << "includes =";
|
| - RecursiveTargetConfigToStream<SourceDir>(target_, &ConfigValues::include_dirs,
|
| - IncludeWriter(path_output_, helper_),
|
| - out_);
|
| -
|
| - out_ << std::endl;
|
| + if (subst.used[SUBSTITUTION_INCLUDE_DIRS]) {
|
| + out_ << kSubstitutionNinjaNames[SUBSTITUTION_INCLUDE_DIRS] << " =";
|
| + RecursiveTargetConfigToStream<SourceDir>(
|
| + target_, &ConfigValues::include_dirs,
|
| + IncludeWriter(path_output_), out_);
|
| + out_ << std::endl;
|
| + }
|
|
|
| // C flags and friends.
|
| EscapeOptions flag_escape_options = GetFlagOptions();
|
| -#define WRITE_FLAGS(name) \
|
| - out_ << #name " ="; \
|
| - RecursiveTargetConfigStringsToStream(target_, &ConfigValues::name, \
|
| - flag_escape_options, out_); \
|
| - out_ << std::endl;
|
| +#define WRITE_FLAGS(name, subst_enum) \
|
| + if (subst.used[subst_enum]) { \
|
| + out_ << kSubstitutionNinjaNames[subst_enum] << " ="; \
|
| + RecursiveTargetConfigStringsToStream(target_, &ConfigValues::name, \
|
| + flag_escape_options, out_); \
|
| + out_ << std::endl; \
|
| + }
|
|
|
| - WRITE_FLAGS(cflags)
|
| - WRITE_FLAGS(cflags_c)
|
| - WRITE_FLAGS(cflags_cc)
|
| - WRITE_FLAGS(cflags_objc)
|
| - WRITE_FLAGS(cflags_objcc)
|
| + WRITE_FLAGS(cflags, SUBSTITUTION_CFLAGS)
|
| + WRITE_FLAGS(cflags_c, SUBSTITUTION_CFLAGS_C)
|
| + WRITE_FLAGS(cflags_cc, SUBSTITUTION_CFLAGS_CC)
|
| + WRITE_FLAGS(cflags_objc, SUBSTITUTION_CFLAGS_OBJC)
|
| + WRITE_FLAGS(cflags_objcc, SUBSTITUTION_CFLAGS_OBJCC)
|
|
|
| #undef WRITE_FLAGS
|
|
|
| - // Write some variables about the target for the toolchain definition to use.
|
| - out_ << "target_name = " << target_->label().name() << std::endl;
|
| - out_ << "target_out_dir = ";
|
| - path_output_.WriteDir(out_, helper_.GetTargetOutputDir(target_),
|
| - PathOutput::DIR_NO_LAST_SLASH);
|
| - out_ << std::endl;
|
| - out_ << "root_out_dir = ";
|
| - path_output_.WriteDir(out_, target_->settings()->toolchain_output_subdir(),
|
| - PathOutput::DIR_NO_LAST_SLASH);
|
| - out_ << std::endl << std::endl;
|
| + WriteSharedVars(subst);
|
| }
|
|
|
| void NinjaBinaryTargetWriter::WriteSources(
|
| @@ -145,113 +130,105 @@ void NinjaBinaryTargetWriter::WriteSources(
|
| std::string implicit_deps =
|
| WriteInputDepsStampAndGetDep(std::vector<const Target*>());
|
|
|
| + std::string rule_prefix = GetNinjaRulePrefixForToolchain(settings_);
|
| +
|
| + std::vector<OutputFile> tool_outputs; // Prevent reallocation in loop.
|
| for (size_t i = 0; i < sources.size(); i++) {
|
| - const SourceFile& input_file = sources[i];
|
| -
|
| - SourceFileType input_file_type = GetSourceFileType(input_file);
|
| - if (input_file_type == SOURCE_UNKNOWN)
|
| - continue; // Skip unknown file types.
|
| - if (input_file_type == SOURCE_O) {
|
| - // Object files just get passed to the output and not compiled.
|
| - object_files->push_back(helper_.GetOutputFileForSource(
|
| - target_, input_file, input_file_type));
|
| - continue;
|
| + Toolchain::ToolType tool_type = Toolchain::TYPE_NONE;
|
| + if (!GetOutputFilesForSource(target_, sources[i],
|
| + &tool_type, &tool_outputs))
|
| + continue; // No output for this source.
|
| +
|
| + if (tool_type != Toolchain::TYPE_NONE) {
|
| + out_ << "build";
|
| + path_output_.WriteFiles(out_, tool_outputs);
|
| + out_ << ": " << rule_prefix << Toolchain::ToolTypeToName(tool_type);
|
| + out_ << " ";
|
| + path_output_.WriteFile(out_, sources[i]);
|
| + out_ << implicit_deps << std::endl;
|
| }
|
| - std::string command =
|
| - helper_.GetRuleForSourceType(settings_, input_file_type);
|
| - if (command.empty())
|
| - continue; // Skip files not needing compilation.
|
| -
|
| - OutputFile output_file = helper_.GetOutputFileForSource(
|
| - target_, input_file, input_file_type);
|
| - object_files->push_back(output_file);
|
| -
|
| - out_ << "build ";
|
| - path_output_.WriteFile(out_, output_file);
|
| - out_ << ": " << command << " ";
|
| - path_output_.WriteFile(out_, input_file);
|
| - out_ << implicit_deps << std::endl;
|
| +
|
| + // It's theoretically possible for a compiler to produce more than one
|
| + // output, but we'll only link to the first output.
|
| + object_files->push_back(tool_outputs[0]);
|
| }
|
| out_ << std::endl;
|
| }
|
|
|
| void NinjaBinaryTargetWriter::WriteLinkerStuff(
|
| const std::vector<OutputFile>& object_files) {
|
| - // Manifest file on Windows.
|
| - // TODO(brettw) this seems not to be necessary for static libs, skip in
|
| - // that case?
|
| - OutputFile windows_manifest;
|
| - if (settings_->IsWin()) {
|
| - windows_manifest = helper_.GetTargetOutputDir(target_);
|
| - windows_manifest.value().append(target_->label().name());
|
| - windows_manifest.value().append(".intermediate.manifest");
|
| - out_ << "manifests = ";
|
| - path_output_.WriteFile(out_, windows_manifest);
|
| - out_ << std::endl;
|
| - }
|
| + std::vector<OutputFile> output_files;
|
| + SubstitutionWriter::ApplyListToLinkerAsOutputFile(
|
| + target_, tool_, tool_->outputs(), &output_files);
|
|
|
| - const Toolchain::Tool& tool = toolchain_->GetTool(tool_type_);
|
| - WriteLinkerFlags(tool, windows_manifest);
|
| - WriteLibs(tool);
|
| -
|
| - // The external output file is the one that other libs depend on.
|
| - OutputFile external_output_file = helper_.GetTargetOutputFile(target_);
|
| -
|
| - // The internal output file is the "main thing" we think we're making. In
|
| - // the case of shared libraries, this is the shared library and the external
|
| - // output file is the import library. In other cases, the internal one and
|
| - // the external one are the same.
|
| - OutputFile internal_output_file;
|
| - if (target_->output_type() == Target::SHARED_LIBRARY) {
|
| - if (settings_->IsWin()) {
|
| - internal_output_file.value() =
|
| - target_->settings()->toolchain_output_subdir().value();
|
| - internal_output_file.value().append(target_->label().name());
|
| - internal_output_file.value().append(".dll");
|
| - } else {
|
| - internal_output_file = external_output_file;
|
| - }
|
| - } else {
|
| - internal_output_file = external_output_file;
|
| - }
|
| + out_ << "build";
|
| + path_output_.WriteFiles(out_, output_files);
|
|
|
| - // In Python see "self.ninja.build(output, command, input,"
|
| - WriteLinkCommand(external_output_file, internal_output_file, object_files);
|
| + out_ << ": "
|
| + << GetNinjaRulePrefixForToolchain(settings_)
|
| + << Toolchain::ToolTypeToName(
|
| + target_->toolchain()->GetToolTypeForTargetFinalOutput(target_));
|
|
|
| - if (target_->output_type() == Target::SHARED_LIBRARY) {
|
| - // The shared object name doesn't include a path.
|
| - out_ << " soname = ";
|
| - out_ << FindFilename(&internal_output_file.value());
|
| - out_ << std::endl;
|
| + UniqueVector<OutputFile> extra_object_files;
|
| + UniqueVector<const Target*> linkable_deps;
|
| + UniqueVector<const Target*> non_linkable_deps;
|
| + GetDeps(&extra_object_files, &linkable_deps, &non_linkable_deps);
|
|
|
| - out_ << " lib = ";
|
| - path_output_.WriteFile(out_, internal_output_file);
|
| - out_ << std::endl;
|
| + // Object files.
|
| + for (size_t i = 0; i < object_files.size(); i++) {
|
| + out_ << " ";
|
| + path_output_.WriteFile(out_, object_files[i]);
|
| + }
|
| + for (size_t i = 0; i < extra_object_files.size(); i++) {
|
| + out_ << " ";
|
| + path_output_.WriteFile(out_, extra_object_files[i]);
|
| + }
|
|
|
| - if (settings_->IsWin()) {
|
| - out_ << " dll = ";
|
| - path_output_.WriteFile(out_, internal_output_file);
|
| - out_ << std::endl;
|
| - }
|
| + std::vector<OutputFile> implicit_deps;
|
| + std::vector<OutputFile> solibs;
|
|
|
| - if (settings_->IsWin()) {
|
| - out_ << " implibflag = /IMPLIB:";
|
| - path_output_.WriteFile(out_, external_output_file);
|
| - out_ << std::endl;
|
| + for (size_t i = 0; i < linkable_deps.size(); i++) {
|
| + const Target* cur = linkable_deps[i];
|
| +
|
| + // All linkable deps should have a link output file.
|
| + DCHECK(!cur->link_output_file().value().empty())
|
| + << "No link output file for "
|
| + << target_->label().GetUserVisibleName(false);
|
| +
|
| + if (cur->dependency_output_file().value() !=
|
| + cur->link_output_file().value()) {
|
| + // This is a shared library with separate link and deps files. Save for
|
| + // later.
|
| + implicit_deps.push_back(cur->dependency_output_file());
|
| + solibs.push_back(cur->link_output_file());
|
| + } else {
|
| + // Normal case, just link to this target.
|
| + out_ << " ";
|
| + path_output_.WriteFile(out_, cur->link_output_file());
|
| }
|
| + }
|
|
|
| - // TODO(brettw) postbuild steps.
|
| - if (settings_->IsMac())
|
| - out_ << " postbuilds = $ && (export BUILT_PRODUCTS_DIR=/Users/brettw/prj/src/out/gn; export CONFIGURATION=Debug; export DYLIB_INSTALL_NAME_BASE=@rpath; export EXECUTABLE_NAME=libbase.dylib; export EXECUTABLE_PATH=libbase.dylib; export FULL_PRODUCT_NAME=libbase.dylib; export LD_DYLIB_INSTALL_NAME=@rpath/libbase.dylib; export MACH_O_TYPE=mh_dylib; export PRODUCT_NAME=base; export PRODUCT_TYPE=com.apple.product-type.library.dynamic; export SDKROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk; export SRCROOT=/Users/brettw/prj/src/out/gn/../../base; export SOURCE_ROOT=\"$${SRCROOT}\"; export TARGET_BUILD_DIR=/Users/brettw/prj/src/out/gn; export TEMP_DIR=\"$${TMPDIR}\"; (cd ../../base && ../build/mac/strip_from_xcode); G=$$?; ((exit $$G) || rm -rf libbase.dylib) && exit $$G)";
|
| + // Append implicit dependencies collected above.
|
| + if (!implicit_deps.empty()) {
|
| + out_ << " |";
|
| + path_output_.WriteFiles(out_, implicit_deps);
|
| }
|
|
|
| + // Append data dependencies as order-only dependencies.
|
| + WriteOrderOnlyDependencies(non_linkable_deps);
|
| +
|
| + // End of the link "build" line.
|
| out_ << std::endl;
|
| +
|
| + // These go in the inner scope of the link line.
|
| + WriteLinkerFlags();
|
| + WriteLibs();
|
| + WriteOutputExtension();
|
| + WriteSolibs(solibs);
|
| }
|
|
|
| -void NinjaBinaryTargetWriter::WriteLinkerFlags(
|
| - const Toolchain::Tool& tool,
|
| - const OutputFile& windows_manifest) {
|
| - out_ << "ldflags =";
|
| +void NinjaBinaryTargetWriter::WriteLinkerFlags() {
|
| + out_ << " ldflags =";
|
|
|
| // First the ldflags from the target and its config.
|
| EscapeOptions flag_options = GetFlagOptions();
|
| @@ -267,23 +244,16 @@ void NinjaBinaryTargetWriter::WriteLinkerFlags(
|
| PathOutput lib_path_output(path_output_.current_dir(),
|
| ESCAPE_NINJA_COMMAND);
|
| for (size_t i = 0; i < all_lib_dirs.size(); i++) {
|
| - out_ << " " << tool.lib_dir_prefix;
|
| + out_ << " " << tool_->lib_dir_switch();
|
| lib_path_output.WriteDir(out_, all_lib_dirs[i],
|
| PathOutput::DIR_NO_LAST_SLASH);
|
| }
|
| }
|
| -
|
| - // Append manifest flag on Windows to reference our file.
|
| - // HACK ERASEME BRETTW FIXME
|
| - if (settings_->IsWin()) {
|
| - out_ << " /MANIFEST /ManifestFile:";
|
| - path_output_.WriteFile(out_, windows_manifest);
|
| - }
|
| out_ << std::endl;
|
| }
|
|
|
| -void NinjaBinaryTargetWriter::WriteLibs(const Toolchain::Tool& tool) {
|
| - out_ << "libs =";
|
| +void NinjaBinaryTargetWriter::WriteLibs() {
|
| + out_ << " libs =";
|
|
|
| // Libraries that have been recursively pushed through the dependency tree.
|
| EscapeOptions lib_escape_opts;
|
| @@ -299,51 +269,33 @@ void NinjaBinaryTargetWriter::WriteLibs(const Toolchain::Tool& tool) {
|
| all_libs[i].substr(0, all_libs[i].size() - framework_ending.size()),
|
| lib_escape_opts);
|
| } else {
|
| - out_ << " " << tool.lib_prefix;
|
| + out_ << " " << tool_->lib_switch();
|
| EscapeStringToStream(out_, all_libs[i], lib_escape_opts);
|
| }
|
| }
|
| out_ << std::endl;
|
| }
|
|
|
| -void NinjaBinaryTargetWriter::WriteLinkCommand(
|
| - const OutputFile& external_output_file,
|
| - const OutputFile& internal_output_file,
|
| - const std::vector<OutputFile>& object_files) {
|
| - out_ << "build ";
|
| - path_output_.WriteFile(out_, internal_output_file);
|
| - if (external_output_file != internal_output_file) {
|
| - out_ << " ";
|
| - path_output_.WriteFile(out_, external_output_file);
|
| - }
|
| - out_ << ": "
|
| - << helper_.GetRulePrefix(target_->settings())
|
| - << Toolchain::ToolTypeToName(tool_type_);
|
| -
|
| - UniqueVector<OutputFile> extra_object_files;
|
| - UniqueVector<const Target*> linkable_deps;
|
| - UniqueVector<const Target*> non_linkable_deps;
|
| - GetDeps(&extra_object_files, &linkable_deps, &non_linkable_deps);
|
| -
|
| - // Object files.
|
| - for (size_t i = 0; i < object_files.size(); i++) {
|
| - out_ << " ";
|
| - path_output_.WriteFile(out_, object_files[i]);
|
| - }
|
| - for (size_t i = 0; i < extra_object_files.size(); i++) {
|
| - out_ << " ";
|
| - path_output_.WriteFile(out_, extra_object_files[i]);
|
| - }
|
| -
|
| - // Libs.
|
| - for (size_t i = 0; i < linkable_deps.size(); i++) {
|
| - out_ << " ";
|
| - path_output_.WriteFile(out_, helper_.GetTargetOutputFile(linkable_deps[i]));
|
| +void NinjaBinaryTargetWriter::WriteOutputExtension() {
|
| + out_ << " output_extension = ";
|
| + if (target_->output_extension().empty()) {
|
| + // Use the default from the tool.
|
| + out_ << tool_->default_output_extension();
|
| + } else {
|
| + // Use the one specified in the target. Note that the one in the target
|
| + // does not include the leading dot, so add that.
|
| + out_ << "." << target_->output_extension();
|
| }
|
| + out_ << std::endl;
|
| +}
|
|
|
| - // Append data dependencies as implicit dependencies.
|
| - WriteImplicitDependencies(non_linkable_deps);
|
| +void NinjaBinaryTargetWriter::WriteSolibs(
|
| + const std::vector<OutputFile>& solibs) {
|
| + if (solibs.empty())
|
| + return;
|
|
|
| + out_ << " solibs =";
|
| + path_output_.WriteFiles(out_, solibs);
|
| out_ << std::endl;
|
| }
|
|
|
| @@ -353,12 +305,6 @@ void NinjaBinaryTargetWriter::WriteSourceSetStamp(
|
| // depend on this will reference the object files directly. However, writing
|
| // this rule allows the user to type the name of the target and get a build
|
| // which can be convenient for development.
|
| - out_ << "build ";
|
| - path_output_.WriteFile(out_, helper_.GetTargetOutputFile(target_));
|
| - out_ << ": "
|
| - << helper_.GetRulePrefix(target_->settings())
|
| - << "stamp";
|
| -
|
| UniqueVector<OutputFile> extra_object_files;
|
| UniqueVector<const Target*> linkable_deps;
|
| UniqueVector<const Target*> non_linkable_deps;
|
| @@ -369,15 +315,11 @@ void NinjaBinaryTargetWriter::WriteSourceSetStamp(
|
| // deps instead.
|
| DCHECK(extra_object_files.empty());
|
|
|
| - for (size_t i = 0; i < object_files.size(); i++) {
|
| - out_ << " ";
|
| - path_output_.WriteFile(out_, object_files[i]);
|
| - }
|
| + std::vector<OutputFile> order_only_deps;
|
| + for (size_t i = 0; i < non_linkable_deps.size(); i++)
|
| + order_only_deps.push_back(non_linkable_deps[i]->dependency_output_file());
|
|
|
| - // Append data dependencies as implicit dependencies.
|
| - WriteImplicitDependencies(non_linkable_deps);
|
| -
|
| - out_ << std::endl;
|
| + WriteStampForTarget(object_files, order_only_deps);
|
| }
|
|
|
| void NinjaBinaryTargetWriter::GetDeps(
|
| @@ -432,14 +374,13 @@ void NinjaBinaryTargetWriter::ClassifyDependency(
|
| target_->output_type() != Target::STATIC_LIBRARY) {
|
| // Linking in a source set to an executable or shared library, copy its
|
| // object files.
|
| + std::vector<OutputFile> tool_outputs; // Prevent allocation in loop.
|
| for (size_t i = 0; i < dep->sources().size(); i++) {
|
| - SourceFileType input_file_type = GetSourceFileType(dep->sources()[i]);
|
| - if (input_file_type != SOURCE_UNKNOWN &&
|
| - input_file_type != SOURCE_H) {
|
| - // Note we need to specify the target as the source_set target
|
| - // itself, since this is used to prefix the object file name.
|
| - extra_object_files->push_back(helper_.GetOutputFileForSource(
|
| - dep, dep->sources()[i], input_file_type));
|
| + Toolchain::ToolType tool_type = Toolchain::TYPE_NONE;
|
| + if (GetOutputFilesForSource(dep, dep->sources()[i], &tool_type,
|
| + &tool_outputs)) {
|
| + // Only link the first output if there are more than one.
|
| + extra_object_files->push_back(tool_outputs[0]);
|
| }
|
| }
|
| }
|
| @@ -450,7 +391,7 @@ void NinjaBinaryTargetWriter::ClassifyDependency(
|
| }
|
| }
|
|
|
| -void NinjaBinaryTargetWriter::WriteImplicitDependencies(
|
| +void NinjaBinaryTargetWriter::WriteOrderOnlyDependencies(
|
| const UniqueVector<const Target*>& non_linkable_deps) {
|
| const std::vector<SourceFile>& data = target_->data();
|
| if (!non_linkable_deps.empty() || !data.empty()) {
|
| @@ -459,15 +400,39 @@ void NinjaBinaryTargetWriter::WriteImplicitDependencies(
|
| // Non-linkable targets.
|
| for (size_t i = 0; i < non_linkable_deps.size(); i++) {
|
| out_ << " ";
|
| - path_output_.WriteFile(out_,
|
| - helper_.GetTargetOutputFile(non_linkable_deps[i]));
|
| + path_output_.WriteFile(
|
| + out_, non_linkable_deps[i]->dependency_output_file());
|
| }
|
| + }
|
| +}
|
|
|
| - // Data files.
|
| - const std::vector<SourceFile>& data = target_->data();
|
| - for (size_t i = 0; i < data.size(); i++) {
|
| - out_ << " ";
|
| - path_output_.WriteFile(out_, data[i]);
|
| - }
|
| +bool NinjaBinaryTargetWriter::GetOutputFilesForSource(
|
| + const Target* target,
|
| + const SourceFile& source,
|
| + Toolchain::ToolType* computed_tool_type,
|
| + std::vector<OutputFile>* outputs) const {
|
| + outputs->clear();
|
| + *computed_tool_type = Toolchain::TYPE_NONE;
|
| +
|
| + SourceFileType file_type = GetSourceFileType(source);
|
| + if (file_type == SOURCE_UNKNOWN)
|
| + return false;
|
| + if (file_type == SOURCE_O) {
|
| + // Object files just get passed to the output and not compiled.
|
| + outputs->push_back(OutputFile(settings_->build_settings(), source));
|
| + return true;
|
| }
|
| +
|
| + *computed_tool_type =
|
| + target->toolchain()->GetToolTypeForSourceType(file_type);
|
| + if (*computed_tool_type == Toolchain::TYPE_NONE)
|
| + return false; // No tool for this file (it's a header file or something).
|
| + const Tool* tool = target->toolchain()->GetTool(*computed_tool_type);
|
| + if (!tool)
|
| + return false; // Tool does not apply for this toolchain.file.
|
| +
|
| + // Figure out what output(s) this compiler produces.
|
| + SubstitutionWriter::ApplyListToCompilerAsOutputFile(
|
| + target, source, tool->outputs(), outputs);
|
| + return !outputs->empty();
|
| }
|
|
|