Revert phony targets to stamp targets This CL reverts 4 previous commits that removed stamp files in favor of phony alias targets. This is due to an issue found in the Chromium build with incremental builds. Reverts: f5f465b5 Fix runtime_deps for elided targets c808630c Move runtime_deps file for phony targets to /obj a9eaeb80 Switch remaining stamp targets to phony targets 99f72f88 Switch source_set stamp targets to phony targets Bug: 215 Change-Id: Id83ea946654e597f93012cf1f93fbe3e6704c1d3 Reviewed-on: https://gn-review.googlesource.com/c/gn/+/10620 Reviewed-by: Dirk Pranke <dpranke@google.com> Reviewed-by: Brett Wilson <brettw@chromium.org> Commit-Queue: Brett Wilson <brettw@chromium.org>
diff --git a/build/gen.py b/build/gen.py index a16f16f..486354b 100755 --- a/build/gen.py +++ b/build/gen.py
@@ -504,7 +504,6 @@ 'src/gn/bundle_data.cc', 'src/gn/bundle_data_target_generator.cc', 'src/gn/bundle_file_rule.cc', - 'src/gn/builtin_tool.cc', 'src/gn/c_include_iterator.cc', 'src/gn/c_substitution_type.cc', 'src/gn/c_tool.cc',
diff --git a/docs/reference.md b/docs/reference.md index b321129..9dab518 100644 --- a/docs/reference.md +++ b/docs/reference.md
@@ -2654,7 +2654,7 @@ process_file_template"). source sets and groups: this will return a list containing the path of the - phony target that Ninja completes once all outputs are generated. This + "stamp" file that Ninja will produce once all outputs are generated. This probably isn't very useful. ```
diff --git a/src/gn/builtin_tool.cc b/src/gn/builtin_tool.cc deleted file mode 100644 index 8bc1e52..0000000 --- a/src/gn/builtin_tool.cc +++ /dev/null
@@ -1,42 +0,0 @@ -// 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 "base/logging.h" -#include "gn/builtin_tool.h" -#include "gn/target.h" - -const char* BuiltinTool::kBuiltinToolPhony = "phony"; - -BuiltinTool::BuiltinTool(const char* n) : Tool(n) { - CHECK(ValidateName(n)); -} - -BuiltinTool::~BuiltinTool() = default; - -BuiltinTool* BuiltinTool::AsBuiltin() { - return this; -} -const BuiltinTool* BuiltinTool::AsBuiltin() const { - return this; -} - -bool BuiltinTool::ValidateName(const char* name) const { - return name == kBuiltinToolPhony; -} - -void BuiltinTool::SetComplete() { - SetToolComplete(); -} - -bool BuiltinTool::InitTool(Scope* scope, Toolchain* toolchain, Err* err) { - // Initialize default vars. - return Tool::InitTool(scope, toolchain, err); -} - -bool BuiltinTool::ValidateSubstitution(const Substitution* sub_type) const { - if (name_ == kBuiltinToolPhony) - return IsValidToolSubstitution(sub_type); - NOTREACHED(); - return false; -}
diff --git a/src/gn/builtin_tool.h b/src/gn/builtin_tool.h deleted file mode 100644 index 00cc809..0000000 --- a/src/gn/builtin_tool.h +++ /dev/null
@@ -1,39 +0,0 @@ -// 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. - -#ifndef TOOLS_GN_BUILTIN_TOOL_H_ -#define TOOLS_GN_BUILTIN_TOOL_H_ - -#include <string> - -#include "base/macros.h" -#include "gn/substitution_list.h" -#include "gn/substitution_pattern.h" -#include "gn/tool.h" - -// A built-in tool that is always available regardless of toolchain. So far, the -// only example of this is the phony rule that ninja provides. -class BuiltinTool : public Tool { - public: - // Builtin tools - static const char* kBuiltinToolPhony; - - explicit BuiltinTool(const char* n); - ~BuiltinTool(); - - // Manual RTTI and required functions --------------------------------------- - - bool InitTool(Scope* block_scope, Toolchain* toolchain, Err* err); - bool ValidateName(const char* name) const override; - void SetComplete() override; - bool ValidateSubstitution(const Substitution* sub_type) const override; - - BuiltinTool* AsBuiltin() override; - const BuiltinTool* AsBuiltin() const override; - - private: - DISALLOW_COPY_AND_ASSIGN(BuiltinTool); -}; - -#endif // TOOLS_GN_BUILTIN_TOOL_H_
diff --git a/src/gn/commands.cc b/src/gn/commands.cc index 1d2b899..97d2629 100644 --- a/src/gn/commands.cc +++ b/src/gn/commands.cc
@@ -328,13 +328,8 @@ // Use the link output file if there is one, otherwise fall back to the // dependency output file (for actions, for example). OutputFile output_file = target->link_output_file(); - if (output_file.value().empty() && target->dependency_output_file_or_phony()) - output_file = *target->dependency_output_file_or_phony(); - - // This output might be an omitted phony target, but that would mean we - // don't have an output file to list. if (output_file.value().empty()) - continue; + output_file = target->dependency_output_file(); SourceFile output_as_source = output_file.AsSourceFile(build_settings); std::string result =
diff --git a/src/gn/filesystem_utils.cc b/src/gn/filesystem_utils.cc index ab06545..ae6d4d9 100644 --- a/src/gn/filesystem_utils.cc +++ b/src/gn/filesystem_utils.cc
@@ -1028,8 +1028,6 @@ result.value().append("gen/"); else if (type == BuildDirType::OBJ) result.value().append("obj/"); - else if (type == BuildDirType::PHONY) - result.value().append("phony/"); return result; }
diff --git a/src/gn/filesystem_utils.h b/src/gn/filesystem_utils.h index 9ba3b4e..830478a 100644 --- a/src/gn/filesystem_utils.h +++ b/src/gn/filesystem_utils.h
@@ -232,12 +232,6 @@ // Output file directory. OBJ, - - // Phony file directory. As the name implies, this is not a real file - // directory, but a path that is used for the declaration of phony targets. - // This is done to avoid duplicate target names between real files and phony - // aliases that point to them. - PHONY, }; // In different contexts, different information is known about the toolchain in
diff --git a/src/gn/function_get_target_outputs.cc b/src/gn/function_get_target_outputs.cc index 6c5041e..fa851f3 100644 --- a/src/gn/function_get_target_outputs.cc +++ b/src/gn/function_get_target_outputs.cc
@@ -46,7 +46,7 @@ process_file_template"). source sets and groups: this will return a list containing the path of the - phony target that Ninja completes once all outputs are generated. This + "stamp" file that Ninja will produce once all outputs are generated. This probably isn't very useful. Example
diff --git a/src/gn/ninja_action_target_writer.cc b/src/gn/ninja_action_target_writer.cc index c8a8437..28f28c7 100644 --- a/src/gn/ninja_action_target_writer.cc +++ b/src/gn/ninja_action_target_writer.cc
@@ -39,12 +39,12 @@ extra_hard_deps.push_back(pair.ptr); // For ACTIONs, the input deps appear only once in the generated ninja - // file, so WriteInputDepsPhonyAndGetDep() won't create a phony rule + // file, so WriteInputDepsStampAndGetDep() won't create a stamp file // and the action will just depend on all the input deps directly. - size_t num_output_uses = + size_t num_stamp_uses = target_->output_type() == Target::ACTION ? 1u : target_->sources().size(); std::vector<OutputFile> input_deps = - WriteInputDepsPhonyAndGetDep(extra_hard_deps, num_output_uses); + WriteInputDepsStampAndGetDep(extra_hard_deps, num_stamp_uses); out_ << std::endl; // Collects all output files for writing below. @@ -83,17 +83,15 @@ } out_ << std::endl; - // Write the phony, which also depends on all data deps. These are needed at + // Write the stamp, which also depends on all data deps. These are needed at // runtime and should be compiled when the action is, but don't need to be // done before we run the action. // TODO(thakis): If the action has just a single output, make things depend - // on that output directly without writing a phony target. + // on that output directly without writing a stamp file. std::vector<OutputFile> data_outs; - for (const auto& dep : target_->data_deps()) { - if (dep.ptr->dependency_output_file_or_phony()) - data_outs.push_back(*dep.ptr->dependency_output_file_or_phony()); - } - WritePhonyForTarget(output_files, data_outs); + for (const auto& dep : target_->data_deps()) + data_outs.push_back(dep.ptr->dependency_output_file()); + WriteStampForTarget(output_files, data_outs); } std::string NinjaActionTargetWriter::WriteRuleDefinition() {
diff --git a/src/gn/ninja_action_target_writer_unittest.cc b/src/gn/ninja_action_target_writer_unittest.cc index 74f7f90..eb03df1 100644 --- a/src/gn/ninja_action_target_writer_unittest.cc +++ b/src/gn/ninja_action_target_writer_unittest.cc
@@ -67,7 +67,7 @@ build foo.out: __foo_bar___rule | ../../foo/script.py ../../foo/included.txt -build phony/foo/bar: phony foo.out +build obj/foo/bar.stamp: stamp foo.out )"; EXPECT_EQ(expected, out.str()) << expected << "--" << out.str(); } @@ -112,7 +112,7 @@ build foo.out: __foo_bar___rule | ../../foo/script.py ../../foo/included.txt pool = console -build phony/foo/bar: phony foo.out +build obj/foo/bar.stamp: stamp foo.out )"; EXPECT_EQ(expected, out.str()); } @@ -153,7 +153,7 @@ "build foo.out: __foo_bar___rule | ../../foo/script.py " "../../foo/included.txt ../../foo/source.txt\n" "\n" - "build phony/foo/bar: phony foo.out\n"; + "build obj/foo/bar.stamp: stamp foo.out\n"; EXPECT_EQ(expected_linux, out.str()); } @@ -162,9 +162,9 @@ TestWithScope setup; // Some dependencies that the action can depend on. Use actions for these - // so they have a nice platform-independent phony target that can appear in - // the output (rather than having to worry about how the current platform - // names binaries). + // so they have a nice platform-independent stamp file that can appear in the + // output (rather than having to worry about how the current platform names + // binaries). Target dep(setup.settings(), Label(SourceDir("//foo/"), "dep")); dep.set_output_type(Target::ACTION); dep.visibility().SetPublic(); @@ -215,18 +215,18 @@ #endif " description = ACTION //foo:bar()\n" " restat = 1\n" - "build phony/foo/bar.inputdeps: phony ../../foo/script.py " - "../../foo/included.txt phony/foo/dep\n" + "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " + "../../foo/included.txt obj/foo/dep.stamp\n" "\n" "build input1.out: __foo_bar___rule ../../foo/input1.txt | " - "phony/foo/bar.inputdeps\n" + "obj/foo/bar.inputdeps.stamp\n" " source_name_part = input1\n" "build input2.out: __foo_bar___rule ../../foo/input2.txt | " - "phony/foo/bar.inputdeps\n" + "obj/foo/bar.inputdeps.stamp\n" " source_name_part = input2\n" "\n" - "build phony/foo/bar: " - "phony input1.out input2.out || phony/foo/datadep\n"; + "build obj/foo/bar.stamp: " + "stamp input1.out input2.out || obj/foo/datadep.stamp\n"; std::string out_str = out.str(); #if defined(OS_WIN) @@ -280,21 +280,21 @@ #endif " description = ACTION //foo:bar()\n" " restat = 1\n" - "build phony/foo/bar.inputdeps: phony ../../foo/script.py " + "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " "../../foo/included.txt\n" "\n" "build input1.out: __foo_bar___rule ../../foo/input1.txt" - " | phony/foo/bar.inputdeps\n" + " | obj/foo/bar.inputdeps.stamp\n" " source_name_part = input1\n" " depfile = gen/input1.d\n" " deps = gcc\n" "build input2.out: __foo_bar___rule ../../foo/input2.txt" - " | phony/foo/bar.inputdeps\n" + " | obj/foo/bar.inputdeps.stamp\n" " source_name_part = input2\n" " depfile = gen/input2.d\n" " deps = gcc\n" "\n" - "build phony/foo/bar: phony input1.out input2.out\n"; + "build obj/foo/bar.stamp: stamp input1.out input2.out\n"; EXPECT_EQ(expected_linux, out.str()); } @@ -348,7 +348,7 @@ // Substitution for the rspfile contents. " source_name_part = input1\n" "\n" - "build phony/foo/bar: phony input1.out\n"; + "build obj/foo/bar.stamp: stamp input1.out\n"; EXPECT_EQ(expected_linux, out.str()); } @@ -399,7 +399,7 @@ " source_file_part = input1.txt\n" " pool = foo_pool\n" "\n" - "build phony/foo/bar: phony input1.out\n"; + "build obj/foo/bar.stamp: stamp input1.out\n"; EXPECT_EQ(expected_linux, out.str()); } @@ -440,9 +440,9 @@ " restat = 1\n" "\n" "build foo.out: __foo_foo___rule | ../../foo/script.py" - " ../../foo/input1.txt phony/foo/dep\n" + " ../../foo/input1.txt obj/foo/dep.stamp\n" "\n" - "build phony/foo/foo: phony foo.out\n"; + "build obj/foo/foo.stamp: stamp foo.out\n"; EXPECT_EQ(expected_linux, out.str()); } @@ -468,11 +468,11 @@ " description = ACTION //bar:bar()\n" " restat = 1\n" "\n" - // Do not have phony/foo/dep as dependency. + // Do not have obj/foo/dep.stamp as dependency. "build bar.out: __bar_bar___rule | ../../bar/script.py" - " ../../bar/input1.txt phony/foo/foo\n" + " ../../bar/input1.txt obj/foo/foo.stamp\n" "\n" - "build phony/bar/bar: phony bar.out\n"; + "build obj/bar/bar.stamp: stamp bar.out\n"; EXPECT_EQ(expected_linux, out.str()); } }
diff --git a/src/gn/ninja_binary_target_writer.cc b/src/gn/ninja_binary_target_writer.cc index 08df4c1..08e8c93 100644 --- a/src/gn/ninja_binary_target_writer.cc +++ b/src/gn/ninja_binary_target_writer.cc
@@ -7,10 +7,10 @@ #include <sstream> #include "base/strings/string_util.h" -#include "gn/builtin_tool.h" #include "gn/config_values_extractors.h" #include "gn/deps_iterator.h" #include "gn/filesystem_utils.h" +#include "gn/general_tool.h" #include "gn/ninja_c_binary_target_writer.h" #include "gn/ninja_rust_binary_target_writer.h" #include "gn/ninja_target_command_util.h" @@ -50,8 +50,8 @@ writer.Run(); } -std::vector<OutputFile> NinjaBinaryTargetWriter::WriteInputsPhonyAndGetDep( - size_t num_output_uses) const { +std::vector<OutputFile> NinjaBinaryTargetWriter::WriteInputsStampAndGetDep( + size_t num_stamp_uses) const { CHECK(target_->toolchain()) << "Toolchain not set on target " << target_->label().GetUserVisibleName(true); @@ -65,8 +65,8 @@ if (inputs.size() == 0) return std::vector<OutputFile>(); // No inputs - // If we only have one input, return it directly instead of writing a phony - // target for it. + // If we only have one input, return it directly instead of writing a stamp + // file for it. if (inputs.size() == 1) { return std::vector<OutputFile>{ OutputFile(settings_->build_settings(), *inputs[0])}; @@ -76,22 +76,21 @@ for (const SourceFile* source : inputs) outs.push_back(OutputFile(settings_->build_settings(), *source)); - // If there are multiple inputs, but the phony target would be referenced only + // If there are multiple inputs, but the stamp file would be referenced only // once, don't write it but depend on the inputs directly. - if (num_output_uses == 1u) + if (num_stamp_uses == 1u) return outs; - // Make a phony target. We don't need to worry about an empty phony target, as - // those would have been peeled off already. - CHECK(!inputs.empty()); - OutputFile phony_file = - GetBuildDirForTargetAsOutputFile(target_, BuildDirType::PHONY); - phony_file.value().append(target_->label().name()); - phony_file.value().append(".inputs"); + // Make a stamp file. + OutputFile stamp_file = + GetBuildDirForTargetAsOutputFile(target_, BuildDirType::OBJ); + stamp_file.value().append(target_->label().name()); + stamp_file.value().append(".inputs.stamp"); out_ << "build "; - path_output_.WriteFile(out_, phony_file); - out_ << ": " << BuiltinTool::kBuiltinToolPhony; + path_output_.WriteFile(out_, stamp_file); + out_ << ": " << GetNinjaRulePrefixForToolchain(settings_) + << GeneralTool::kGeneralToolStamp; // File inputs. for (const auto* input : inputs) { @@ -100,12 +99,12 @@ } out_ << std::endl; - return {phony_file}; + return {stamp_file}; } -void NinjaBinaryTargetWriter::WriteSourceSetPhony( +void NinjaBinaryTargetWriter::WriteSourceSetStamp( const std::vector<OutputFile>& object_files) { - // The phony rule for source sets is generally not used, since targets that + // The stamp rule for source sets is generally not used, since targets that // 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. @@ -117,12 +116,10 @@ DCHECK(classified_deps.extra_object_files.empty()); std::vector<OutputFile> order_only_deps; - for (auto* dep : classified_deps.non_linkable_deps) { - if (dep->dependency_output_file_or_phony()) - order_only_deps.push_back(*dep->dependency_output_file_or_phony()); - } + for (auto* dep : classified_deps.non_linkable_deps) + order_only_deps.push_back(dep->dependency_output_file()); - WritePhonyForTarget(object_files, order_only_deps); + WriteStampForTarget(object_files, order_only_deps); } NinjaBinaryTargetWriter::ClassifiedDeps @@ -180,7 +177,7 @@ AddSourceSetFiles(dep, &classified_deps->extra_object_files); // Add the source set itself as a non-linkable dependency on the current - // target. This will make sure that anything the source set's phony target + // target. This will make sure that anything the source set's stamp file // depends on (like data deps) are also built before the current target // can be complete. Otherwise, these will be skipped since this target // will depend only on the source set's object files.
diff --git a/src/gn/ninja_binary_target_writer.h b/src/gn/ninja_binary_target_writer.h index fcf90bf..76a8a4e 100644 --- a/src/gn/ninja_binary_target_writer.h +++ b/src/gn/ninja_binary_target_writer.h
@@ -33,18 +33,18 @@ UniqueVector<const Target*> swiftmodule_deps; }; - // Writes to the output stream a phony rule for inputs, and - // returns the target to be appended to source rules that encodes the + // Writes to the output stream a stamp rule for inputs, and + // returns the file to be appended to source rules that encodes the // implicit dependencies for the current target. - // If num_output_uses is small, this might return all input dependencies - // directly, without writing a phony rule. + // If num_stamp_uses is small, this might return all input dependencies + // directly, without writing a stamp file. // If there are no implicit dependencies and no extra target dependencies // are passed in, this returns an empty vector. - std::vector<OutputFile> WriteInputsPhonyAndGetDep( - size_t num_phony_uses) const; + std::vector<OutputFile> WriteInputsStampAndGetDep( + size_t num_stamp_uses) const; - // Writes the phony line for a source set. These are not linked. - void WriteSourceSetPhony(const std::vector<OutputFile>& object_files); + // Writes the stamp line for a source set. These are not linked. + void WriteSourceSetStamp(const std::vector<OutputFile>& object_files); // Gets all target dependencies and classifies them, as well as accumulates // object files from source sets we need to link.
diff --git a/src/gn/ninja_binary_target_writer_unittest.cc b/src/gn/ninja_binary_target_writer_unittest.cc index afcc4d6..970aa82 100644 --- a/src/gn/ninja_binary_target_writer_unittest.cc +++ b/src/gn/ninja_binary_target_writer_unittest.cc
@@ -44,7 +44,7 @@ "build obj/foo/bar.input1.o: cxx ../../foo/input1.cc\n" "build obj/foo/bar.input2.o: cxx ../../foo/input2.cc\n" "\n" - "build phony/foo/bar: phony obj/foo/bar.input1.o " + "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.o " "obj/foo/bar.input2.o ../../foo/input3.o ../../foo/input4.obj\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str); @@ -71,7 +71,8 @@ "target_out_dir = obj/foo\n" "target_output_name = bar\n" "\n" - "\n"; + "\n" + "build obj/foo/bar.stamp: stamp\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str); } @@ -137,7 +138,7 @@ "build obj/foo/bar.source1.o: cxx ../../foo/source1.cc | " "../../foo/input1 ../../foo/input2\n" "\n" - "build phony/foo/bar: phony obj/foo/bar.source1.o\n"; + "build obj/foo/bar.stamp: stamp obj/foo/bar.source1.o\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; } @@ -167,14 +168,14 @@ "target_out_dir = obj/foo\n" "target_output_name = bar\n" "\n" - "build phony/foo/bar.inputs: phony " + "build obj/foo/bar.inputs.stamp: stamp " "../../foo/input1 ../../foo/input2\n" "build obj/foo/bar.source1.o: cxx ../../foo/source1.cc | " - "phony/foo/bar.inputs\n" + "obj/foo/bar.inputs.stamp\n" "build obj/foo/bar.source2.o: cxx ../../foo/source2.cc | " - "phony/foo/bar.inputs\n" + "obj/foo/bar.inputs.stamp\n" "\n" - "build phony/foo/bar: phony obj/foo/bar.source1.o " + "build obj/foo/bar.stamp: stamp obj/foo/bar.source1.o " "obj/foo/bar.source2.o\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
diff --git a/src/gn/ninja_build_writer.cc b/src/gn/ninja_build_writer.cc index 50f1155..f801fb6 100644 --- a/src/gn/ninja_build_writer.cc +++ b/src/gn/ninja_build_writer.cc
@@ -595,11 +595,8 @@ EscapeOptions ninja_escape; ninja_escape.mode = ESCAPE_NINJA; for (const Target* target : default_toolchain_targets_) { - if (target->dependency_output_file_or_phony()) { - out_ << " $\n "; - path_output_.WriteFile(out_, - *target->dependency_output_file_or_phony()); - } + out_ << " $\n "; + path_output_.WriteFile(out_, target->dependency_output_file()); } } out_ << std::endl; @@ -608,13 +605,9 @@ // Use the short name when available if (written_rules.find("default") != written_rules.end()) { out_ << "\ndefault default" << std::endl; - } else if (default_target->dependency_output_file_or_phony()) { - // If the default target does not have a dependency output file or phony, - // then the target specified as default is a no-op. We omit the default - // statement entirely to avoid ninja runtime failure. + } else { out_ << "\ndefault "; - path_output_.WriteFile( - out_, *default_target->dependency_output_file_or_phony()); + path_output_.WriteFile(out_, default_target->dependency_output_file()); out_ << std::endl; } } else if (!default_toolchain_targets_.empty()) { @@ -632,12 +625,7 @@ // Escape for special chars Ninja will handle. std::string escaped = EscapeString(phony_name, ninja_escape, nullptr); - // If the target doesn't have a dependency_output_file_or_phony, we should - // still emit the phony rule, but with no dependencies. This allows users to - // continue to use the phony rule, but it will effectively be a no-op. out_ << "build " << escaped << ": phony "; - if (target->dependency_output_file_or_phony()) { - path_output_.WriteFile(out_, *target->dependency_output_file_or_phony()); - } + path_output_.WriteFile(out_, target->dependency_output_file()); out_ << std::endl; }
diff --git a/src/gn/ninja_build_writer_unittest.cc b/src/gn/ninja_build_writer_unittest.cc index f98787c..8bc6839 100644 --- a/src/gn/ninja_build_writer_unittest.cc +++ b/src/gn/ninja_build_writer_unittest.cc
@@ -155,16 +155,16 @@ " depth = 42\n"; const char expected_toolchain[] = "subninja toolchain.ninja\n"; const char expected_targets[] = - "build bar: phony phony/bar/bar\n" - "build baz: phony phony/baz/baz\n" - "build foo$:bar: phony phony/foo/bar\n" - "build bar$:bar: phony phony/bar/bar\n" - "build baz$:baz: phony phony/baz/baz\n"; + "build bar: phony obj/bar/bar.stamp\n" + "build baz: phony obj/baz/baz.stamp\n" + "build foo$:bar: phony obj/foo/bar.stamp\n" + "build bar$:bar: phony obj/bar/bar.stamp\n" + "build baz$:baz: phony obj/baz/baz.stamp\n"; const char expected_root_target[] = "build all: phony $\n" - " phony/foo/bar $\n" - " phony/bar/bar $\n" - " phony/baz/baz\n"; + " obj/foo/bar.stamp $\n" + " obj/bar/bar.stamp $\n" + " obj/baz/baz.stamp\n"; const char expected_default[] = "default all\n"; std::string out_str = ninja_out.str(); #define EXPECT_SNIPPET(expected) \
diff --git a/src/gn/ninja_bundle_data_target_writer.cc b/src/gn/ninja_bundle_data_target_writer.cc index 2281978..0e3bcb0 100644 --- a/src/gn/ninja_bundle_data_target_writer.cc +++ b/src/gn/ninja_bundle_data_target_writer.cc
@@ -21,15 +21,13 @@ OutputFile(settings_->build_settings(), source_file)); } - std::vector<OutputFile> input_deps = WriteInputDepsPhonyAndGetDep( - std::vector<const Target*>(), /*num_output_uses=*/1); + std::vector<OutputFile> input_deps = WriteInputDepsStampAndGetDep( + std::vector<const Target*>(), /*num_stamp_uses=*/1); output_files.insert(output_files.end(), input_deps.begin(), input_deps.end()); std::vector<OutputFile> order_only_deps; - for (const auto& pair : target_->data_deps()) { - if (pair.ptr->dependency_output_file_or_phony()) - order_only_deps.push_back(*pair.ptr->dependency_output_file_or_phony()); - } + for (const auto& pair : target_->data_deps()) + order_only_deps.push_back(pair.ptr->dependency_output_file()); - WritePhonyForTarget(output_files, order_only_deps); + WriteStampForTarget(output_files, order_only_deps); }
diff --git a/src/gn/ninja_bundle_data_target_writer_unittest.cc b/src/gn/ninja_bundle_data_target_writer_unittest.cc index ebf0f89..06b5eb2 100644 --- a/src/gn/ninja_bundle_data_target_writer_unittest.cc +++ b/src/gn/ninja_bundle_data_target_writer_unittest.cc
@@ -42,7 +42,7 @@ writer.Run(); const char expected[] = - "build phony/foo/data: phony " + "build obj/foo/data.stamp: stamp " "../../foo/input1.txt " "../../foo/input2.txt " "../../foo/Foo.xcassets/Contents.json "
diff --git a/src/gn/ninja_c_binary_target_writer.cc b/src/gn/ninja_c_binary_target_writer.cc index f0d43a3..17f9c08 100644 --- a/src/gn/ninja_c_binary_target_writer.cc +++ b/src/gn/ninja_c_binary_target_writer.cc
@@ -132,10 +132,10 @@ WriteCompilerVars(module_dep_info); - size_t num_output_uses = target_->sources().size(); + size_t num_stamp_uses = target_->sources().size(); - std::vector<OutputFile> input_deps = - WriteInputsPhonyAndGetDep(num_output_uses); + std::vector<OutputFile> input_deps = WriteInputsStampAndGetDep( + num_stamp_uses); // The input dependencies will be an order-only dependency. This will cause // Ninja to make sure the inputs are up to date before compiling this source, @@ -164,11 +164,11 @@ // The order only deps are referenced by each source file compile, // but also by PCH compiles. The latter are annoying to count, so omit // them here. This means that binary targets with a single source file - // that also use PCH files won't have a phony target even though having + // that also use PCH files won't have a stamp file even though having // one would make output ninja file size a bit lower. That's ok, binary // targets with a single source are rare. - std::vector<OutputFile> order_only_deps = WriteInputDepsPhonyAndGetDep( - std::vector<const Target*>(), num_output_uses); + std::vector<OutputFile> order_only_deps = WriteInputDepsStampAndGetDep( + std::vector<const Target*>(), num_stamp_uses); // For GCC builds, the .gch files are not object files, but still need to be // added as explicit dependencies below. The .gch output files are placed in @@ -207,7 +207,7 @@ return; if (target_->output_type() == Target::SOURCE_SET) { - WriteSourceSetPhony(obj_files); + WriteSourceSetStamp(obj_files); #ifndef NDEBUG // Verify that the function that separately computes a source set's object // files match the object files just computed. @@ -667,11 +667,8 @@ swift_order_only_deps.Append(order_only_deps.begin(), order_only_deps.end()); - for (const Target* swiftmodule : target_->swift_values().modules()) { - CHECK(swiftmodule->dependency_output_file_or_phony()); - swift_order_only_deps.push_back( - *swiftmodule->dependency_output_file_or_phony()); - } + for (const Target* swiftmodule : target_->swift_values().modules()) + swift_order_only_deps.push_back(swiftmodule->dependency_output_file()); WriteCompilerBuildLine(target_->sources(), input_deps, swift_order_only_deps.vector(), tool->name(), @@ -722,12 +719,11 @@ cur->output_type() == Target::RUST_PROC_MACRO) continue; - if (cur->dependency_output_file_or_phony() && - (cur->dependency_output_file_or_phony()->value() != - cur->link_output_file().value())) { + 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_or_phony()); + implicit_deps.push_back(cur->dependency_output_file()); solibs.push_back(cur->link_output_file()); } else { // Normal case, just link to this target. @@ -758,13 +754,12 @@ } // If any target creates a framework bundle, then treat it as an implicit - // dependency via the phony target. This is a pessimisation as it is not + // dependency via the .stamp file. This is a pessimisation as it is not // always necessary to relink the current target if one of the framework // is regenerated, but it ensure that if one of the framework API changes, // any dependent target will relink it (see crbug.com/1037607). for (const Target* dep : classified_deps.framework_deps) { - if (dep->dependency_output_file_or_phony()) - implicit_deps.push_back(*dep->dependency_output_file_or_phony()); + implicit_deps.push_back(dep->dependency_output_file()); } // The input dependency is only needed if there are no object files, as the @@ -779,9 +774,8 @@ for (const auto* dep : target_->rust_values().transitive_libs().GetOrdered()) { if (dep->output_type() == Target::RUST_LIBRARY) { - CHECK(dep->dependency_output_file()); - transitive_rustlibs.push_back(*dep->dependency_output_file()); - implicit_deps.push_back(*dep->dependency_output_file()); + transitive_rustlibs.push_back(dep->dependency_output_file()); + implicit_deps.push_back(dep->dependency_output_file()); } } } @@ -813,11 +807,11 @@ // this target. // // The action dependencies are not strictly necessary in this case. They - // should also have been collected via the input deps phony alias that each - // source file has for an order-only dependency, and since this target depends - // on the sources, there is already an implicit order-only dependency. - // However, it's extra work to separate these out and there's no disadvantage - // to listing them again. + // should also have been collected via the input deps stamp that each source + // file has for an order-only dependency, and since this target depends on + // the sources, there is already an implicit order-only dependency. However, + // it's extra work to separate these out and there's no disadvantage to + // listing them again. WriteOrderOnlyDependencies(classified_deps.non_linkable_deps); // End of the link "build" line. @@ -879,11 +873,8 @@ // Non-linkable targets. for (auto* non_linkable_dep : non_linkable_deps) { - if (non_linkable_dep->dependency_output_file_or_phony()) { - out_ << " "; - path_output_.WriteFile( - out_, *non_linkable_dep->dependency_output_file_or_phony()); - } + out_ << " "; + path_output_.WriteFile(out_, non_linkable_dep->dependency_output_file()); } } }
diff --git a/src/gn/ninja_c_binary_target_writer.h b/src/gn/ninja_c_binary_target_writer.h index ae0b09d..bbc71c5 100644 --- a/src/gn/ninja_c_binary_target_writer.h +++ b/src/gn/ninja_c_binary_target_writer.h
@@ -40,7 +40,7 @@ // non-object files (for instance, .gch files from a GCC toolchain, are // appended to |other_files|). // - // input_deps is the phony target collecting the dependencies required before + // input_deps is the stamp file collecting the dependencies required before // compiling this target. It will be empty if there are no input deps. void WritePCHCommands(const std::vector<OutputFile>& input_deps, const std::vector<OutputFile>& order_only_deps,
diff --git a/src/gn/ninja_c_binary_target_writer_unittest.cc b/src/gn/ninja_c_binary_target_writer_unittest.cc index 540e755..99961da 100644 --- a/src/gn/ninja_c_binary_target_writer_unittest.cc +++ b/src/gn/ninja_c_binary_target_writer_unittest.cc
@@ -55,7 +55,7 @@ "build obj/foo/bar.input1.o: cxx ../../foo/input1.cc\n" "build obj/foo/bar.input2.o: cxx ../../foo/input2.cc\n" "\n" - "build phony/foo/bar: phony obj/foo/bar.input1.o " + "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.o " "obj/foo/bar.input2.o ../../foo/input3.o ../../foo/input4.obj\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -86,7 +86,7 @@ // order. "build ./libshlib.so: solink obj/foo/bar.input1.o " "obj/foo/bar.input2.o ../../foo/input3.o ../../foo/input4.obj " - "|| phony/foo/bar\n" + "|| obj/foo/bar.stamp\n" " ldflags =\n" " libs =\n" " frameworks =\n" @@ -119,7 +119,7 @@ "\n" // There are no sources so there are no params to alink. (In practice // this will probably fail in the archive tool.) - "build obj/foo/libstlib.a: alink || phony/foo/bar\n" + "build obj/foo/libstlib.a: alink || obj/foo/bar.stamp\n" " arflags =\n" " output_extension = \n" " output_dir = \n"; @@ -147,7 +147,7 @@ // order. "build obj/foo/libstlib.a: alink obj/foo/bar.input1.o " "obj/foo/bar.input2.o ../../foo/input3.o ../../foo/input4.obj " - "|| phony/foo/bar\n" + "|| obj/foo/bar.stamp\n" " arflags =\n" " output_extension = \n" " output_dir = \n"; @@ -329,15 +329,15 @@ "target_output_name = libshlib\n" "\n" "build obj/foo/libshlib.input1.o: cxx ../../foo/input1.cc" - " || phony/foo/action\n" + " || obj/foo/action.stamp\n" "build obj/foo/libshlib.input2.o: cxx ../../foo/input2.cc" - " || phony/foo/action\n" + " || obj/foo/action.stamp\n" "\n" "build ./libshlib.so.6: solink obj/foo/libshlib.input1.o " // The order-only dependency here is stricly unnecessary since the // sources list this as an order-only dep. See discussion in the code // that writes this. - "obj/foo/libshlib.input2.o || phony/foo/action\n" + "obj/foo/libshlib.input2.o || obj/foo/action.stamp\n" " ldflags =\n" " libs =\n" " frameworks =\n" @@ -392,12 +392,12 @@ "target_output_name = gen_obj\n" "\n" "build obj/out/Debug/gen_obj.generated.o: cxx generated.cc" - " || phony/foo/generate\n" + " || obj/foo/generate.stamp\n" "\n" - "build phony/foo/gen_obj: phony obj/out/Debug/gen_obj.generated.o" + "build obj/foo/gen_obj.stamp: stamp obj/out/Debug/gen_obj.generated.o" // The order-only dependency here is strictly unnecessary since the // sources list this as an order-only dep. - " || phony/foo/generate\n"; + " || obj/foo/generate.stamp\n"; std::string obj_str = obj_out.str(); EXPECT_EQ(obj_expected, obj_str); @@ -429,8 +429,8 @@ "build ./libgen_lib.so: solink obj/out/Debug/gen_obj.generated.o" // The order-only dependency here is strictly unnecessary since // obj/out/Debug/gen_obj.generated.o has dependency to - // phony/foo/gen_obj - " || phony/foo/gen_obj\n" + // obj/foo/gen_obj.stamp + " || obj/foo/gen_obj.stamp\n" " ldflags =\n" " libs =\n" " frameworks =\n" @@ -537,8 +537,6 @@ Target framework(setup.settings(), Label(SourceDir("//bar"), "framework")); framework.set_output_type(Target::CREATE_BUNDLE); framework.bundle_data().product_type() = "com.apple.product-type.framework"; - framework.bundle_data().set_partial_info_plist( - SourceFile("//out/Debug/bar/framework/framework_partial_info.plist")); framework.public_configs().push_back(LabelConfigPair(&framework_config)); framework.SetToolchain(setup.toolchain()); framework.visibility().SetPublic(); @@ -565,7 +563,7 @@ "target_output_name = libshlib\n" "\n" "\n" - "build ./libshlib.so: solink | phony/bar/framework\n" + "build ./libshlib.so: solink | obj/bar/framework.stamp\n" " ldflags = -F.\n" " libs =\n" " frameworks = -framework System -framework Bar " @@ -651,7 +649,7 @@ NinjaCBinaryTargetWriter inter_writer(&inter, inter_out); inter_writer.Run(); - // The intermediate source set will be a phony target that depends on the + // The intermediate source set will be a stamp file that depends on the // object files, and will have an order-only dependency on its data dep and // data file. const char inter_expected[] = @@ -665,7 +663,7 @@ "\n" "build obj/foo/inter.inter.o: cxx ../../foo/inter.cc\n" "\n" - "build phony/foo/inter: phony obj/foo/inter.inter.o || " + "build obj/foo/inter.stamp: stamp obj/foo/inter.inter.o || " "./data_target\n"; EXPECT_EQ(inter_expected, inter_out.str()); @@ -684,7 +682,7 @@ // The final output depends on both object files (one from the final target, // one from the source set) and has an order-only dependency on the source - // set's phony target and the final target's data file. The source set phony + // set's stamp file and the final target's data file. The source set stamp // dependency will create an implicit order-only dependency on the data // target. const char final_expected[] = @@ -699,7 +697,7 @@ "build obj/foo/exe.final.o: cxx ../../foo/final.cc\n" "\n" "build ./exe: link obj/foo/exe.final.o obj/foo/inter.inter.o || " - "phony/foo/inter\n" + "obj/foo/inter.stamp\n" " ldflags =\n" " libs =\n" " frameworks =\n" @@ -888,8 +886,8 @@ "build withpch/obj/foo/no_pch_target.input2.o: " "withpch_cc ../../foo/input2.c\n" "\n" - "build withpch/phony/foo/no_pch_target: " - "phony withpch/obj/foo/no_pch_target.input1.o " + "build withpch/obj/foo/no_pch_target.stamp: " + "withpch_stamp withpch/obj/foo/no_pch_target.input1.o " "withpch/obj/foo/no_pch_target.input2.o\n"; EXPECT_EQ(no_pch_expected, out.str()); } @@ -942,7 +940,7 @@ // Explicit dependency on the PCH build step. "withpch/obj/build/pch_target.precompile.c.o\n" "\n" - "build withpch/phony/foo/pch_target: phony " + "build withpch/obj/foo/pch_target.stamp: withpch_stamp " "withpch/obj/foo/pch_target.input1.o " "withpch/obj/foo/pch_target.input2.o " // The precompiled object files were added to the outputs. @@ -1022,8 +1020,8 @@ "build withpch/obj/foo/no_pch_target.input2.o: " "withpch_cc ../../foo/input2.c\n" "\n" - "build withpch/phony/foo/no_pch_target: " - "phony withpch/obj/foo/no_pch_target.input1.o " + "build withpch/obj/foo/no_pch_target.stamp: " + "withpch_stamp withpch/obj/foo/no_pch_target.input1.o " "withpch/obj/foo/no_pch_target.input2.o\n"; EXPECT_EQ(no_pch_expected, out.str()); } @@ -1074,8 +1072,8 @@ // Explicit dependency on the PCH build step. "withpch/obj/build/pch_target.precompile.h-c.gch\n" "\n" - "build withpch/phony/foo/pch_target: " - "phony withpch/obj/foo/pch_target.input1.o " + "build withpch/obj/foo/pch_target.stamp: " + "withpch_stamp withpch/obj/foo/pch_target.input1.o " "withpch/obj/foo/pch_target.input2.o\n"; EXPECT_EQ(pch_gcc_expected, out.str()); } @@ -1140,7 +1138,7 @@ "build obj/foo/bar.input2.o: cxx ../../foo/input2.cc" " | ../../foo/input.data\n" "\n" - "build phony/foo/bar: phony obj/foo/bar.input1.o " + "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.o " "obj/foo/bar.input2.o\n"; EXPECT_EQ(expected, out.str()); @@ -1204,14 +1202,14 @@ "target_out_dir = obj/foo\n" "target_output_name = bar\n" "\n" - "build phony/foo/bar.inputs: phony" + "build obj/foo/bar.inputs.stamp: stamp" " ../../foo/input1.data ../../foo/input2.data\n" "build obj/foo/bar.input1.o: cxx ../../foo/input1.cc" - " | phony/foo/bar.inputs\n" + " | obj/foo/bar.inputs.stamp\n" "build obj/foo/bar.input2.o: cxx ../../foo/input2.cc" - " | phony/foo/bar.inputs\n" + " | obj/foo/bar.inputs.stamp\n" "\n" - "build phony/foo/bar: phony obj/foo/bar.input1.o " + "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.o " "obj/foo/bar.input2.o\n"; EXPECT_EQ(expected, out.str()); @@ -1254,14 +1252,14 @@ "target_out_dir = obj/foo\n" "target_output_name = bar\n" "\n" - "build phony/foo/bar.inputs: phony" + "build obj/foo/bar.inputs.stamp: stamp" " ../../foo/input1.data ../../foo/input2.data ../../foo/input3.data\n" "build obj/foo/bar.input1.o: cxx ../../foo/input1.cc" - " | phony/foo/bar.inputs\n" + " | obj/foo/bar.inputs.stamp\n" "build obj/foo/bar.input2.o: cxx ../../foo/input2.cc" - " | phony/foo/bar.inputs\n" + " | obj/foo/bar.inputs.stamp\n" "\n" - "build phony/foo/bar: phony obj/foo/bar.input1.o " + "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.o " "obj/foo/bar.input2.o\n"; EXPECT_EQ(expected, out.str()); @@ -1573,7 +1571,7 @@ "\n" "build obj/foo/file1.o obj/foo/file2.o: stamp obj/foo/Foo.swiftmodule\n" "\n" - "build phony/foo/foo: phony" + "build obj/foo/foo.stamp: stamp" " obj/foo/file1.o obj/foo/file2.o\n"; const std::string out_str = out.str(); @@ -1606,13 +1604,13 @@ "target_output_name = bar\n" "\n" "build obj/bar/Bar.swiftmodule: swift ../../bar/bar.swift" - " || phony/foo/foo\n" + " || obj/foo/foo.stamp\n" "\n" "build obj/bar/bar.o: stamp obj/bar/Bar.swiftmodule" - " || phony/foo/foo\n" + " || obj/foo/foo.stamp\n" "\n" - "build phony/bar/bar: phony obj/bar/bar.o " - "|| phony/foo/foo\n"; + "build obj/bar/bar.stamp: stamp obj/bar/bar.o " + "|| obj/foo/foo.stamp\n"; const std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -1652,13 +1650,13 @@ "target_output_name = bar\n" "\n" "build obj/bar/Bar.swiftmodule: swift ../../bar/bar.swift" - " || phony/foo/foo\n" + " || obj/foo/foo.stamp\n" "\n" "build obj/bar/bar.o: stamp obj/bar/Bar.swiftmodule" - " || phony/foo/foo\n" + " || obj/foo/foo.stamp\n" "\n" - "build phony/bar/bar: phony obj/bar/bar.o " - "|| phony/bar/group phony/foo/foo\n"; + "build obj/bar/bar.stamp: stamp obj/bar/bar.o " + "|| obj/bar/group.stamp obj/foo/foo.stamp\n"; const std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -1687,7 +1685,7 @@ "\n" "build ./bar: link obj/foo/file1.o obj/foo/file2.o " "| obj/foo/Foo.swiftmodule " - "|| phony/foo/foo\n" + "|| obj/foo/foo.stamp\n" " ldflags =\n" " libs =\n" " frameworks =\n"
diff --git a/src/gn/ninja_copy_target_writer.cc b/src/gn/ninja_copy_target_writer.cc index 646ec44..9299223 100644 --- a/src/gn/ninja_copy_target_writer.cc +++ b/src/gn/ninja_copy_target_writer.cc
@@ -33,13 +33,28 @@ return; } - // General target-related substitutions needed by the copy tool. - WriteSharedVars(copy_tool->substitution_bits()); + const Tool* stamp_tool = target_->toolchain()->GetTool(GeneralTool::kGeneralToolStamp); + if (!stamp_tool) { + g_scheduler->FailWithError(Err( + nullptr, "Copy tool not defined", + "The toolchain " + + target_->toolchain()->label().GetUserVisibleName(false) + + "\n used by target " + target_->label().GetUserVisibleName(false) + + "\n doesn't define a \"stamp\" tool.")); + return; + } + + // Figure out the substitutions used by the copy and stamp tools. + SubstitutionBits required_bits = copy_tool->substitution_bits(); + required_bits.MergeFrom(stamp_tool->substitution_bits()); + + // General target-related substitutions needed by both tools. + WriteSharedVars(required_bits); std::vector<OutputFile> output_files; WriteCopyRules(&output_files); out_ << std::endl; - WritePhonyForTarget(output_files, std::vector<OutputFile>()); + WriteStampForTarget(output_files, std::vector<OutputFile>()); } void NinjaCopyTargetWriter::WriteCopyRules( @@ -54,15 +69,13 @@ std::string tool_name = GetNinjaRulePrefixForToolchain(settings_) + GeneralTool::kGeneralToolCopy; - size_t num_output_uses = target_->sources().size(); - std::vector<OutputFile> input_deps = WriteInputDepsPhonyAndGetDep( - std::vector<const Target*>(), num_output_uses); + size_t num_stamp_uses = target_->sources().size(); + std::vector<OutputFile> input_deps = WriteInputDepsStampAndGetDep( + std::vector<const Target*>(), num_stamp_uses); std::vector<OutputFile> data_outs; - for (const auto& dep : target_->data_deps()) { - if (dep.ptr->dependency_output_file_or_phony()) - data_outs.push_back(*dep.ptr->dependency_output_file_or_phony()); - } + for (const auto& dep : target_->data_deps()) + data_outs.push_back(dep.ptr->dependency_output_file()); // Note that we don't write implicit deps for copy steps. "copy" only // depends on the output files themselves, rather than having includes
diff --git a/src/gn/ninja_copy_target_writer_unittest.cc b/src/gn/ninja_copy_target_writer_unittest.cc index 1b5077a..f641ffa 100644 --- a/src/gn/ninja_copy_target_writer_unittest.cc +++ b/src/gn/ninja_copy_target_writer_unittest.cc
@@ -35,7 +35,7 @@ "build input1.out: copy ../../foo/input1.txt\n" "build input2.out: copy ../../foo/input2.txt\n" "\n" - "build phony/foo/bar: phony input1.out input2.out\n"; + "build obj/foo/bar.stamp: stamp input1.out input2.out\n"; std::string out_str = out.str(); EXPECT_EQ(expected_linux, out_str); } @@ -63,7 +63,7 @@ const char expected_linux[] = "build output.out: copy ../../foo/input1.txt\n" "\n" - "build phony/foo/bar: phony output.out\n"; + "build obj/foo/bar.stamp: stamp output.out\n"; std::string out_str = out.str(); EXPECT_EQ(expected_linux, out_str); } @@ -88,7 +88,7 @@ const char expected_linux[] = "build input1.out: copy ../../foo/input1.txt || ../../foo/script.py\n" "\n" - "build phony/foo/bar: phony input1.out\n"; + "build obj/foo/bar.stamp: stamp input1.out\n"; std::string out_str = out.str(); EXPECT_EQ(expected_linux, out_str); } @@ -118,9 +118,9 @@ writer.Run(); const char expected_linux[] = - "build input1.out: copy ../../foo/input1.txt || phony/foo/datadep\n" + "build input1.out: copy ../../foo/input1.txt || obj/foo/datadep.stamp\n" "\n" - "build phony/foo/bar: phony input1.out\n"; + "build obj/foo/bar.stamp: stamp input1.out\n"; std::string out_str = out.str(); EXPECT_EQ(expected_linux, out_str); }
diff --git a/src/gn/ninja_create_bundle_target_writer.cc b/src/gn/ninja_create_bundle_target_writer.cc index 002c042..9f000f3 100644 --- a/src/gn/ninja_create_bundle_target_writer.cc +++ b/src/gn/ninja_create_bundle_target_writer.cc
@@ -77,11 +77,11 @@ if (!EnsureAllToolsAvailable(target_)) return; - // Output users are CopyBundleData, CompileAssetsCatalog, CodeSigning and - // PhonyForTarget. - size_t num_output_uses = 4; - std::vector<OutputFile> order_only_deps = WriteInputDepsPhonyAndGetDep( - std::vector<const Target*>(), num_output_uses); + // Stamp users are CopyBundleData, CompileAssetsCatalog, CodeSigning and + // StampForTarget. + size_t num_stamp_uses = 4; + std::vector<OutputFile> order_only_deps = WriteInputDepsStampAndGetDep( + std::vector<const Target*>(), num_stamp_uses); std::string code_signing_rule_name = WriteCodeSigningRuleDefinition(); @@ -90,17 +90,9 @@ WriteCompileAssetsCatalogStep(order_only_deps, &output_files); WriteCodeSigningStep(code_signing_rule_name, order_only_deps, &output_files); - for (const auto& pair : target_->data_deps()) { - if (pair.ptr->dependency_output_file_or_phony()) - order_only_deps.push_back(*pair.ptr->dependency_output_file_or_phony()); - } - - // If the target does not have a phony target to write, then we have nothing - // left to do. - if (!target_->dependency_output_file_or_phony()) - return; - - WritePhonyForTarget(output_files, order_only_deps); + for (const auto& pair : target_->data_deps()) + order_only_deps.push_back(pair.ptr->dependency_output_file()); + WriteStampForTarget(output_files, order_only_deps); // Write a phony target for the outer bundle directory. This allows other // targets to treat the entire bundle as a single unit, even though it is @@ -110,8 +102,7 @@ out_, OutputFile(settings_->build_settings(), target_->bundle_data().GetBundleRootDirOutput(settings_))); - out_ << ": " << BuiltinTool::kBuiltinToolPhony << " "; - out_ << target_->dependency_output_file_or_phony()->value(); + out_ << ": phony " << target_->dependency_output_file().value(); out_ << std::endl; } @@ -227,7 +218,7 @@ return; } - OutputFile input_dep = WriteCompileAssetsCatalogInputDepsPhony( + OutputFile input_dep = WriteCompileAssetsCatalogInputDepsStamp( target_->bundle_data().assets_catalog_deps()); DCHECK(!input_dep.value().empty()); @@ -287,32 +278,28 @@ } OutputFile -NinjaCreateBundleTargetWriter::WriteCompileAssetsCatalogInputDepsPhony( +NinjaCreateBundleTargetWriter::WriteCompileAssetsCatalogInputDepsStamp( const std::vector<const Target*>& dependencies) { DCHECK(!dependencies.empty()); - if (dependencies.size() == 1) { - return dependencies[0]->dependency_output_file_or_phony() - ? *dependencies[0]->dependency_output_file_or_phony() - : OutputFile{}; - } + if (dependencies.size() == 1) + return dependencies[0]->dependency_output_file(); - OutputFile xcassets_input_phony = - GetBuildDirForTargetAsOutputFile(target_, BuildDirType::PHONY); - xcassets_input_phony.value().append(target_->label().name()); - xcassets_input_phony.value().append(".xcassets.inputdeps"); + OutputFile xcassets_input_stamp_file = + GetBuildDirForTargetAsOutputFile(target_, BuildDirType::OBJ); + xcassets_input_stamp_file.value().append(target_->label().name()); + xcassets_input_stamp_file.value().append(".xcassets.inputdeps.stamp"); out_ << "build "; - path_output_.WriteFile(out_, xcassets_input_phony); - out_ << ": " << BuiltinTool::kBuiltinToolPhony; + path_output_.WriteFile(out_, xcassets_input_stamp_file); + out_ << ": " << GetNinjaRulePrefixForToolchain(settings_) + << GeneralTool::kGeneralToolStamp; for (const Target* target : dependencies) { - if (target->dependency_output_file_or_phony()) { - out_ << " "; - path_output_.WriteFile(out_, *target->dependency_output_file_or_phony()); - } + out_ << " "; + path_output_.WriteFile(out_, target->dependency_output_file()); } out_ << std::endl; - return xcassets_input_phony; + return xcassets_input_stamp_file; } void NinjaCreateBundleTargetWriter::WriteCodeSigningStep( @@ -322,9 +309,9 @@ if (code_signing_rule_name.empty()) return; - OutputFile code_signing_input_phony = - WriteCodeSigningInputDepsPhony(order_only_deps, output_files); - DCHECK(!code_signing_input_phony.value().empty()); + OutputFile code_signing_input_stamp_file = + WriteCodeSigningInputDepsStamp(order_only_deps, output_files); + DCHECK(!code_signing_input_stamp_file.value().empty()); out_ << "build"; std::vector<OutputFile> code_signing_output_files; @@ -334,17 +321,17 @@ path_output_.WriteFiles(out_, code_signing_output_files); // Since the code signature step depends on all the files from the bundle, - // the create_bundle phony can just depends on the output of the signature + // the create_bundle stamp can just depends on the output of the signature // script (dependencies are transitive). *output_files = std::move(code_signing_output_files); out_ << ": " << code_signing_rule_name; out_ << " | "; - path_output_.WriteFile(out_, code_signing_input_phony); + path_output_.WriteFile(out_, code_signing_input_stamp_file); out_ << std::endl; } -OutputFile NinjaCreateBundleTargetWriter::WriteCodeSigningInputDepsPhony( +OutputFile NinjaCreateBundleTargetWriter::WriteCodeSigningInputDepsStamp( const std::vector<OutputFile>& order_only_deps, std::vector<OutputFile>* output_files) { std::vector<SourceFile> code_signing_input_files; @@ -363,14 +350,15 @@ if (code_signing_input_files.size() == 1 && order_only_deps.empty()) return OutputFile(settings_->build_settings(), code_signing_input_files[0]); - OutputFile code_signing_input_phony = - GetBuildDirForTargetAsOutputFile(target_, BuildDirType::PHONY); - code_signing_input_phony.value().append(target_->label().name()); - code_signing_input_phony.value().append(".codesigning.inputdeps"); + OutputFile code_signing_input_stamp_file = + GetBuildDirForTargetAsOutputFile(target_, BuildDirType::OBJ); + code_signing_input_stamp_file.value().append(target_->label().name()); + code_signing_input_stamp_file.value().append(".codesigning.inputdeps.stamp"); out_ << "build "; - path_output_.WriteFile(out_, code_signing_input_phony); - out_ << ": " << BuiltinTool::kBuiltinToolPhony; + path_output_.WriteFile(out_, code_signing_input_stamp_file); + out_ << ": " << GetNinjaRulePrefixForToolchain(settings_) + << GeneralTool::kGeneralToolStamp; for (const SourceFile& source : code_signing_input_files) { out_ << " "; @@ -381,5 +369,5 @@ path_output_.WriteFiles(out_, order_only_deps); } out_ << std::endl; - return code_signing_input_phony; + return code_signing_input_stamp_file; }
diff --git a/src/gn/ninja_create_bundle_target_writer.h b/src/gn/ninja_create_bundle_target_writer.h index 189a524..6d4e224 100644 --- a/src/gn/ninja_create_bundle_target_writer.h +++ b/src/gn/ninja_create_bundle_target_writer.h
@@ -46,9 +46,9 @@ const std::vector<OutputFile>& order_only_deps, std::vector<OutputFile>* output_files); - // Writes the phony target for the assets catalog compilation input + // Writes the stamp file for the assets catalog compilation input // dependencies. - OutputFile WriteCompileAssetsCatalogInputDepsPhony( + OutputFile WriteCompileAssetsCatalogInputDepsStamp( const std::vector<const Target*>& dependencies); // Writes the code signing step (if a script is defined). @@ -60,8 +60,8 @@ const std::vector<OutputFile>& order_only_deps, std::vector<OutputFile>* output_files); - // Writes the phony target for the code signing input dependencies. - OutputFile WriteCodeSigningInputDepsPhony( + // Writes the stamp file for the code signing input dependencies. + OutputFile WriteCodeSigningInputDepsStamp( const std::vector<OutputFile>& order_only_deps, std::vector<OutputFile>* output_files);
diff --git a/src/gn/ninja_create_bundle_target_writer_unittest.cc b/src/gn/ninja_create_bundle_target_writer_unittest.cc index 77598c8..d2c5c24 100644 --- a/src/gn/ninja_create_bundle_target_writer_unittest.cc +++ b/src/gn/ninja_create_bundle_target_writer_unittest.cc
@@ -75,17 +75,17 @@ writer.Run(); const char expected[] = - "build phony/baz/bar.inputdeps: phony phony/foo/bar " - "phony/foo/data\n" + "build obj/baz/bar.inputdeps.stamp: stamp obj/foo/bar.stamp " + "obj/foo/data.stamp\n" "build bar.bundle/Contents/Resources/input1.txt: copy_bundle_data " - "../../foo/input1.txt || phony/baz/bar.inputdeps\n" + "../../foo/input1.txt || obj/baz/bar.inputdeps.stamp\n" "build bar.bundle/Contents/Resources/input2.txt: copy_bundle_data " - "../../foo/input2.txt || phony/baz/bar.inputdeps\n" - "build phony/baz/bar: phony " + "../../foo/input2.txt || obj/baz/bar.inputdeps.stamp\n" + "build obj/baz/bar.stamp: stamp " "bar.bundle/Contents/Resources/input1.txt " "bar.bundle/Contents/Resources/input2.txt" - " || phony/baz/bar.inputdeps\n" - "build bar.bundle: phony phony/baz/bar\n"; + " || obj/baz/bar.inputdeps.stamp\n" + "build bar.bundle: phony obj/baz/bar.stamp\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str); } @@ -124,17 +124,17 @@ writer.Run(); const char expected[] = - "build phony/baz/bar.inputdeps: phony phony/foo/bar " - "phony/foo/data\n" + "build obj/baz/bar.inputdeps.stamp: stamp obj/foo/bar.stamp " + "obj/foo/data.stamp\n" "build gen/bar.bundle/Contents/Resources/input1.txt: copy_bundle_data " - "../../foo/input1.txt || phony/baz/bar.inputdeps\n" + "../../foo/input1.txt || obj/baz/bar.inputdeps.stamp\n" "build gen/bar.bundle/Contents/Resources/input2.txt: copy_bundle_data " - "../../foo/input2.txt || phony/baz/bar.inputdeps\n" - "build phony/baz/bar: phony " + "../../foo/input2.txt || obj/baz/bar.inputdeps.stamp\n" + "build obj/baz/bar.stamp: stamp " "gen/bar.bundle/Contents/Resources/input1.txt " "gen/bar.bundle/Contents/Resources/input2.txt || " - "phony/baz/bar.inputdeps\n" - "build gen/bar.bundle: phony phony/baz/bar\n"; + "obj/baz/bar.inputdeps.stamp\n" + "build gen/bar.bundle: phony obj/baz/bar.stamp\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str); } @@ -165,10 +165,10 @@ writer.Run(); const char expected[] = - "build baz/bar/bar_partial_info.plist: stamp || phony/foo/bar\n" - "build phony/baz/bar: phony " - "baz/bar/bar_partial_info.plist || phony/foo/bar\n" - "build bar.bundle: phony phony/baz/bar\n"; + "build baz/bar/bar_partial_info.plist: stamp || obj/foo/bar.stamp\n" + "build obj/baz/bar.stamp: stamp " + "baz/bar/bar_partial_info.plist || obj/foo/bar.stamp\n" + "build bar.bundle: phony obj/baz/bar.stamp\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str); } @@ -225,17 +225,17 @@ writer.Run(); const char expected[] = - "build phony/baz/bar.inputdeps: phony phony/foo/bar " - "phony/foo/data\n" + "build obj/baz/bar.inputdeps.stamp: stamp obj/foo/bar.stamp " + "obj/foo/data.stamp\n" "build bar.bundle/Contents/Resources/Assets.car: compile_xcassets " - "../../foo/Foo.xcassets | phony/foo/data || " - "phony/baz/bar.inputdeps\n" + "../../foo/Foo.xcassets | obj/foo/data.stamp || " + "obj/baz/bar.inputdeps.stamp\n" " product_type = com.apple.product-type\n" " xcasset_compiler_flags = --app-icon foo\n" - "build phony/baz/bar: phony " + "build obj/baz/bar.stamp: stamp " "bar.bundle/Contents/Resources/Assets.car || " - "phony/baz/bar.inputdeps\n" - "build bar.bundle: phony phony/baz/bar\n"; + "obj/baz/bar.inputdeps.stamp\n" + "build bar.bundle: phony obj/baz/bar.stamp\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str); } @@ -253,8 +253,6 @@ SetupBundleDataDir(&create_bundle.bundle_data(), "//out/Debug"); create_bundle.set_output_type(Target::CREATE_BUNDLE); create_bundle.SetToolchain(setup.toolchain()); - create_bundle.bundle_data().set_partial_info_plist( - SourceFile("//out/Debug/baz/bar/bar_partial_info.plist")); ASSERT_TRUE(create_bundle.OnResolved(&err)); std::ostringstream out; @@ -262,11 +260,10 @@ writer.Run(); const char expected[] = - "build baz/bar/bar_partial_info.plist: stamp\n" - "build phony/baz/bar: phony baz/bar/bar_partial_info.plist\n" - "build bar.bundle: phony phony/baz/bar\n"; + "build obj/baz/bar.stamp: stamp\n" + "build bar.bundle: phony obj/baz/bar.stamp\n"; std::string out_str = out.str(); - EXPECT_EQ(expected, out_str) << out_str; + EXPECT_EQ(expected, out_str); } // Tests complex target with multiple bundle_data sources, including @@ -379,32 +376,32 @@ writer.Run(); const char expected[] = - "build phony/baz/bar.inputdeps: phony phony/biz/assets " - "phony/foo/assets phony/foo/bar phony/foo/data " - "phony/qux/info_plist phony/quz/assets\n" + "build obj/baz/bar.inputdeps.stamp: stamp obj/biz/assets.stamp " + "obj/foo/assets.stamp obj/foo/bar.stamp obj/foo/data.stamp " + "obj/qux/info_plist.stamp obj/quz/assets.stamp\n" "build bar.bundle/Contents/Info.plist: copy_bundle_data " - "../../qux/qux-Info.plist || phony/baz/bar.inputdeps\n" + "../../qux/qux-Info.plist || obj/baz/bar.inputdeps.stamp\n" "build bar.bundle/Contents/Resources/input1.txt: copy_bundle_data " - "../../foo/input1.txt || phony/baz/bar.inputdeps\n" + "../../foo/input1.txt || obj/baz/bar.inputdeps.stamp\n" "build bar.bundle/Contents/Resources/input2.txt: copy_bundle_data " - "../../foo/input2.txt || phony/baz/bar.inputdeps\n" - "build phony/baz/bar.xcassets.inputdeps: phony " - "phony/foo/assets " - "phony/quz/assets phony/biz/assets\n" + "../../foo/input2.txt || obj/baz/bar.inputdeps.stamp\n" + "build obj/baz/bar.xcassets.inputdeps.stamp: stamp " + "obj/foo/assets.stamp " + "obj/quz/assets.stamp obj/biz/assets.stamp\n" "build bar.bundle/Contents/Resources/Assets.car | " "baz/bar/bar_partial_info.plist: compile_xcassets " "../../foo/Foo.xcassets ../../quz/Quz.xcassets " - "../../biz/Biz.xcassets | phony/baz/bar.xcassets.inputdeps || " - "phony/baz/bar.inputdeps\n" + "../../biz/Biz.xcassets | obj/baz/bar.xcassets.inputdeps.stamp || " + "obj/baz/bar.inputdeps.stamp\n" " product_type = com.apple.product-type\n" " partial_info_plist = baz/bar/bar_partial_info.plist\n" - "build phony/baz/bar: phony " + "build obj/baz/bar.stamp: stamp " "bar.bundle/Contents/Info.plist " "bar.bundle/Contents/Resources/input1.txt " "bar.bundle/Contents/Resources/input2.txt " "bar.bundle/Contents/Resources/Assets.car " - "baz/bar/bar_partial_info.plist || phony/baz/bar.inputdeps\n" - "build bar.bundle: phony phony/baz/bar\n"; + "baz/bar/bar_partial_info.plist || obj/baz/bar.inputdeps.stamp\n" + "build bar.bundle: phony obj/baz/bar.stamp\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str); } @@ -461,30 +458,30 @@ writer.Run(); const char expected[] = - "build phony/baz/bar.inputdeps: phony ./quz phony/foo/bar " - "phony/foo/data\n" + "build obj/baz/bar.inputdeps.stamp: stamp ./quz obj/foo/bar.stamp " + "obj/foo/data.stamp\n" "rule __baz_bar___toolchain_default__code_signing_rule\n" " command = ../../build/codesign.py -b=quz bar.bundle\n" " description = CODE SIGNING //baz:bar(//toolchain:default)\n" " restat = 1\n" "\n" "build bar.bundle/Contents/Resources/input1.txt: copy_bundle_data " - "../../foo/input1.txt || phony/baz/bar.inputdeps\n" + "../../foo/input1.txt || obj/baz/bar.inputdeps.stamp\n" "build bar.bundle/Contents/Resources/input2.txt: copy_bundle_data " - "../../foo/input2.txt || phony/baz/bar.inputdeps\n" - "build phony/baz/bar.codesigning.inputdeps: phony " + "../../foo/input2.txt || obj/baz/bar.inputdeps.stamp\n" + "build obj/baz/bar.codesigning.inputdeps.stamp: stamp " "../../build/codesign.py " "quz " "bar.bundle/Contents/Resources/input1.txt " "bar.bundle/Contents/Resources/input2.txt || " - "phony/baz/bar.inputdeps\n" + "obj/baz/bar.inputdeps.stamp\n" "build bar.bundle/Contents/quz bar.bundle/_CodeSignature/CodeResources: " "__baz_bar___toolchain_default__code_signing_rule " - "| phony/baz/bar.codesigning.inputdeps\n" - "build phony/baz/bar: phony " + "| obj/baz/bar.codesigning.inputdeps.stamp\n" + "build obj/baz/bar.stamp: stamp " "bar.bundle/Contents/quz " - "bar.bundle/_CodeSignature/CodeResources || phony/baz/bar.inputdeps\n" - "build bar.bundle: phony phony/baz/bar\n"; + "bar.bundle/_CodeSignature/CodeResources || obj/baz/bar.inputdeps.stamp\n" + "build bar.bundle: phony obj/baz/bar.stamp\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str); }
diff --git a/src/gn/ninja_generated_file_target_writer.cc b/src/gn/ninja_generated_file_target_writer.cc index f4508a5..6b0db1b 100644 --- a/src/gn/ninja_generated_file_target_writer.cc +++ b/src/gn/ninja_generated_file_target_writer.cc
@@ -26,23 +26,19 @@ // Write the file. GenerateFile(); - // A generated_file target should generate a phony target with dependencies + // A generated_file target should generate a stamp file with dependencies // on each of the deps and data_deps in the target. The actual collection is // done at gen time, and so ninja doesn't need to know about it. std::vector<OutputFile> output_files; - for (const auto& pair : target_->GetDeps(Target::DEPS_LINKED)) { - if (pair.ptr->dependency_output_file_or_phony()) - output_files.push_back(*pair.ptr->dependency_output_file_or_phony()); - } + for (const auto& pair : target_->GetDeps(Target::DEPS_LINKED)) + output_files.push_back(pair.ptr->dependency_output_file()); std::vector<OutputFile> data_output_files; const LabelTargetVector& data_deps = target_->data_deps(); - for (const auto& pair : data_deps) { - if (pair.ptr->dependency_output_file_or_phony()) - data_output_files.push_back(*pair.ptr->dependency_output_file_or_phony()); - } + for (const auto& pair : data_deps) + data_output_files.push_back(pair.ptr->dependency_output_file()); - WritePhonyForTarget(output_files, data_output_files); + WriteStampForTarget(output_files, data_output_files); } void NinjaGeneratedFileTargetWriter::GenerateFile() {
diff --git a/src/gn/ninja_generated_file_target_writer_unittest.cc b/src/gn/ninja_generated_file_target_writer_unittest.cc index c7eab68..e88ad49 100644 --- a/src/gn/ninja_generated_file_target_writer_unittest.cc +++ b/src/gn/ninja_generated_file_target_writer_unittest.cc
@@ -54,7 +54,7 @@ writer.Run(); const char expected[] = - "build phony/foo/bar: phony phony/foo/dep phony/foo/dep2 || " - "phony/foo/datadep\n"; + "build obj/foo/bar.stamp: stamp obj/foo/dep.stamp obj/foo/dep2.stamp || " + "obj/foo/datadep.stamp\n"; EXPECT_EQ(expected, out.str()); }
diff --git a/src/gn/ninja_group_target_writer.cc b/src/gn/ninja_group_target_writer.cc index 5ba4ba6..b518977 100644 --- a/src/gn/ninja_group_target_writer.cc +++ b/src/gn/ninja_group_target_writer.cc
@@ -17,20 +17,16 @@ NinjaGroupTargetWriter::~NinjaGroupTargetWriter() = default; void NinjaGroupTargetWriter::Run() { - // A group rule just generates a phony target with dependencies on each of + // A group rule just generates a stamp file with dependencies on each of // the deps and data_deps in the group. std::vector<OutputFile> output_files; - for (const auto& pair : target_->GetDeps(Target::DEPS_LINKED)) { - if (pair.ptr->dependency_output_file_or_phony()) - output_files.push_back(*pair.ptr->dependency_output_file_or_phony()); - } + for (const auto& pair : target_->GetDeps(Target::DEPS_LINKED)) + output_files.push_back(pair.ptr->dependency_output_file()); std::vector<OutputFile> data_output_files; const LabelTargetVector& data_deps = target_->data_deps(); - for (const auto& pair : data_deps) { - if (pair.ptr->dependency_output_file_or_phony()) - data_output_files.push_back(*pair.ptr->dependency_output_file_or_phony()); - } + for (const auto& pair : data_deps) + data_output_files.push_back(pair.ptr->dependency_output_file()); - WritePhonyForTarget(output_files, data_output_files); + WriteStampForTarget(output_files, data_output_files); }
diff --git a/src/gn/ninja_group_target_writer_unittest.cc b/src/gn/ninja_group_target_writer_unittest.cc index 2408992..2280bb0 100644 --- a/src/gn/ninja_group_target_writer_unittest.cc +++ b/src/gn/ninja_group_target_writer_unittest.cc
@@ -45,7 +45,7 @@ writer.Run(); const char expected[] = - "build phony/foo/bar: phony phony/foo/dep phony/foo/dep2 || " - "phony/foo/datadep\n"; + "build obj/foo/bar.stamp: stamp obj/foo/dep.stamp obj/foo/dep2.stamp || " + "obj/foo/datadep.stamp\n"; EXPECT_EQ(expected, out.str()); }
diff --git a/src/gn/ninja_rust_binary_target_writer.cc b/src/gn/ninja_rust_binary_target_writer.cc index 66e2804..59960a1 100644 --- a/src/gn/ninja_rust_binary_target_writer.cc +++ b/src/gn/ninja_rust_binary_target_writer.cc
@@ -110,10 +110,10 @@ void NinjaRustBinaryTargetWriter::Run() { DCHECK(target_->output_type() != Target::SOURCE_SET); - size_t num_output_uses = target_->sources().size(); + size_t num_stamp_uses = target_->sources().size(); - std::vector<OutputFile> input_deps = - WriteInputsPhonyAndGetDep(num_output_uses); + std::vector<OutputFile> input_deps = WriteInputsStampAndGetDep( + num_stamp_uses); WriteCompilerVars(); @@ -124,8 +124,8 @@ // Ninja to make sure the inputs are up to date before compiling this source, // but changes in the inputs deps won't cause the file to be recompiled. See // the comment on NinjaCBinaryTargetWriter::Run for more detailed explanation. - std::vector<OutputFile> order_only_deps = WriteInputDepsPhonyAndGetDep( - std::vector<const Target*>(), num_output_uses); + std::vector<OutputFile> order_only_deps = WriteInputDepsStampAndGetDep( + std::vector<const Target*>(), num_stamp_uses); std::copy(input_deps.begin(), input_deps.end(), std::back_inserter(order_only_deps)); @@ -144,19 +144,14 @@ classified_deps.extra_object_files.begin(), classified_deps.extra_object_files.end()); for (const auto* framework_dep : classified_deps.framework_deps) { - CHECK(framework_dep->dependency_output_file()); - order_only_deps.push_back(*framework_dep->dependency_output_file()); + order_only_deps.push_back(framework_dep->dependency_output_file()); } for (const auto* non_linkable_dep : classified_deps.non_linkable_deps) { - if (non_linkable_dep->dependency_output_file_or_phony()) { - if (non_linkable_dep->source_types_used().RustSourceUsed() && - non_linkable_dep->output_type() != Target::SOURCE_SET) { - rustdeps.push_back( - *non_linkable_dep->dependency_output_file_or_phony()); - } - order_only_deps.push_back( - *non_linkable_dep->dependency_output_file_or_phony()); + if (non_linkable_dep->source_types_used().RustSourceUsed() && + non_linkable_dep->output_type() != Target::SOURCE_SET) { + rustdeps.push_back(non_linkable_dep->dependency_output_file()); } + order_only_deps.push_back(non_linkable_dep->dependency_output_file()); } for (const auto* linkable_dep : classified_deps.linkable_deps) { if (linkable_dep->source_types_used().RustSourceUsed()) { @@ -164,8 +159,7 @@ } else { nonrustdeps.push_back(linkable_dep->link_output_file()); } - CHECK(linkable_dep->dependency_output_file()); - implicit_deps.push_back(*linkable_dep->dependency_output_file()); + implicit_deps.push_back(linkable_dep->dependency_output_file()); } // Rust libraries specified by paths. @@ -184,8 +178,7 @@ for (const auto* dep : target_->rust_values().transitive_libs().GetOrdered()) { if (dep->source_types_used().RustSourceUsed()) { - CHECK(dep->dependency_output_file()); - transitive_rustlibs.push_back(*dep->dependency_output_file()); + transitive_rustlibs.push_back(dep->dependency_output_file()); } } @@ -256,7 +249,6 @@ for (const Target* target : deps) { if (target->output_type() == Target::RUST_LIBRARY || target->output_type() == Target::RUST_PROC_MACRO) { - CHECK(target->dependency_output_file()); out_ << " --extern "; const auto& renamed_dep = target_->rust_values().aliased_deps().find(target->label()); @@ -265,7 +257,7 @@ } else { out_ << std::string(target->rust_values().crate_name()) << "="; } - path_output_.WriteFile(out_, *target->dependency_output_file()); + path_output_.WriteFile(out_, target->dependency_output_file()); } }
diff --git a/src/gn/ninja_rust_binary_target_writer_unittest.cc b/src/gn/ninja_rust_binary_target_writer_unittest.cc index d2446ac..34d87f0 100644 --- a/src/gn/ninja_rust_binary_target_writer_unittest.cc +++ b/src/gn/ninja_rust_binary_target_writer_unittest.cc
@@ -244,7 +244,7 @@ "\n" "build obj/bar/libmylib.rlib: rust_rlib ../../bar/lib.rs | " "../../bar/mylib.rs ../../bar/lib.rs obj/bar/libmymacro.so || " - "phony/baz/group\n" + "obj/baz/group.stamp\n" " externs = --extern mymacro=obj/bar/libmymacro.so\n" " rustdeps = -Ldependency=obj/bar\n" " sources = ../../bar/mylib.rs ../../bar/lib.rs\n"; @@ -436,7 +436,7 @@ "../../foo/main.rs obj/baz/sourceset.csourceset.o " "obj/bar/libmylib.rlib " "obj/foo/libstatic.a ./libshared.so ./libshared_with_toc.so.TOC " - "|| phony/baz/sourceset\n" + "|| obj/baz/sourceset.stamp\n" " externs = --extern mylib=obj/bar/libmylib.rlib\n" " rustdeps = -Ldependency=obj/bar -Lnative=obj/baz -Lnative=obj/foo " "-Lnative=. -Clink-arg=obj/baz/sourceset.csourceset.o -lstatic " @@ -748,7 +748,7 @@ "target_output_name = bar\n" "\n" "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/source.rs " - "../../foo/main.rs obj/bar/libmylib.rlib || phony/baz/group\n" + "../../foo/main.rs obj/bar/libmylib.rlib || obj/baz/group.stamp\n" " externs = --extern mylib=obj/bar/libmylib.rlib\n" " rustdeps = -Ldependency=obj/bar\n" " sources = ../../foo/source.rs ../../foo/main.rs\n"; @@ -828,7 +828,7 @@ writer.Run(); const char expected[] = - "build phony/foo/bar.inputs: phony ../../foo/config.json ../../foo/template.h\n" + "build obj/foo/bar.inputs.stamp: stamp ../../foo/config.json ../../foo/template.h\n" "crate_name = foo_bar\n" "crate_type = bin\n" "output_extension = \n" @@ -841,7 +841,7 @@ "\n" "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/source.rs " "../../foo/main.rs ../../foo/config.json ../../foo/template.h " - "|| phony/foo/bar.inputs\n" + "|| obj/foo/bar.inputs.stamp\n" " externs =\n" " rustdeps =\n" " sources = ../../foo/source.rs ../../foo/main.rs "
diff --git a/src/gn/ninja_target_writer.cc b/src/gn/ninja_target_writer.cc index 802852c..b6bbb9f 100644 --- a/src/gn/ninja_target_writer.cc +++ b/src/gn/ninja_target_writer.cc
@@ -8,7 +8,6 @@ #include "base/files/file_util.h" #include "base/strings/string_util.h" -#include "gn/builtin_tool.h" #include "gn/config_values_extractors.h" #include "gn/err.h" #include "gn/escape.h" @@ -188,16 +187,16 @@ out_ << std::endl; } -std::vector<OutputFile> NinjaTargetWriter::WriteInputDepsPhonyAndGetDep( +std::vector<OutputFile> NinjaTargetWriter::WriteInputDepsStampAndGetDep( const std::vector<const Target*>& extra_hard_deps, - size_t num_output_uses) const { + size_t num_stamp_uses) const { CHECK(target_->toolchain()) << "Toolchain not set on target " << target_->label().GetUserVisibleName(true); // ---------- // Collect all input files that are input deps of this target. Knowing the // number before writing allows us to either skip writing the input deps - // phony or optimize it. Use pointers to avoid copies here. + // stamp or optimize it. Use pointers to avoid copies here. std::vector<const SourceFile*> input_deps_sources; input_deps_sources.reserve(32); @@ -246,7 +245,7 @@ // Toolchain dependencies. These must be resolved before doing anything. // This just writes all toolchain deps for simplicity. If we find that // toolchains often have more than one dependency, we could consider writing - // a toolchain-specific phony target and only include the phony here. + // a toolchain-specific stamp file and only include the stamp here. // Note that these are usually empty/small. const LabelTargetVector& toolchain_deps = target_->toolchain()->deps(); for (const auto& toolchain_dep : toolchain_deps) { @@ -263,16 +262,14 @@ return std::vector<OutputFile>(); // No input dependencies. // If we're only generating one input dependency, return it directly instead - // of writing a phony target for it. + // of writing a stamp file for it. if (input_deps_sources.size() == 1 && input_deps_targets.size() == 0) return std::vector<OutputFile>{ OutputFile(settings_->build_settings(), *input_deps_sources[0])}; if (input_deps_sources.size() == 0 && input_deps_targets.size() == 1) { - const std::optional<OutputFile>& dep = - input_deps_targets[0]->dependency_output_file_or_phony(); - if (!dep) - return std::vector<OutputFile>(); - return std::vector<OutputFile>{*dep}; + const OutputFile& dep = input_deps_targets[0]->dependency_output_file(); + DCHECK(!dep.value().empty()); + return std::vector<OutputFile>{dep}; } std::vector<OutputFile> outs; @@ -286,49 +283,48 @@ input_deps_targets.begin(), input_deps_targets.end(), [](const Target* a, const Target* b) { return a->label() < b->label(); }); for (auto* dep : input_deps_targets) { - if (dep->dependency_output_file_or_phony()) - outs.push_back(*dep->dependency_output_file_or_phony()); + DCHECK(!dep->dependency_output_file().value().empty()); + outs.push_back(dep->dependency_output_file()); } - // If there are multiple inputs, but the phony target would be referenced only + // If there are multiple inputs, but the stamp file would be referenced only // once, don't write it but depend on the inputs directly. - if (num_output_uses == 1u) + if (num_stamp_uses == 1u) return outs; - // Make a phony target. We don't need to worry about an empty phony target, as - // we would return early if there were no inputs. - CHECK(!outs.empty()); - OutputFile input_phony_file = - GetBuildDirForTargetAsOutputFile(target_, BuildDirType::PHONY); - input_phony_file.value().append(target_->label().name()); - input_phony_file.value().append(".inputdeps"); + // Make a stamp file. + OutputFile input_stamp_file = + GetBuildDirForTargetAsOutputFile(target_, BuildDirType::OBJ); + input_stamp_file.value().append(target_->label().name()); + input_stamp_file.value().append(".inputdeps.stamp"); out_ << "build "; - path_output_.WriteFile(out_, input_phony_file); - out_ << ": " << BuiltinTool::kBuiltinToolPhony; + path_output_.WriteFile(out_, input_stamp_file); + out_ << ": " << GetNinjaRulePrefixForToolchain(settings_) + << GeneralTool::kGeneralToolStamp; path_output_.WriteFiles(out_, outs); out_ << "\n"; - return std::vector<OutputFile>{input_phony_file}; + return std::vector<OutputFile>{input_stamp_file}; } -void NinjaTargetWriter::WritePhonyForTarget( +void NinjaTargetWriter::WriteStampForTarget( const std::vector<OutputFile>& files, const std::vector<OutputFile>& order_only_deps) { - // If there's no phony, then we should not have any inputs and it is okay to - // omit the build rule. - if (!target_->dependency_output_phony()) { - CHECK(files.empty()); - CHECK(order_only_deps.empty()); - return; - } - const OutputFile& phony_target = *target_->dependency_output_phony(); - CHECK(!phony_target.value().empty()); + const OutputFile& stamp_file = target_->dependency_output_file(); + + // First validate that the target's dependency is a stamp file. Otherwise, + // we shouldn't have gotten here! + CHECK(base::EndsWith(stamp_file.value(), ".stamp", + base::CompareCase::INSENSITIVE_ASCII)) + << "Output should end in \".stamp\" for stamp file output. Instead got: " + << "\"" << stamp_file.value() << "\""; out_ << "build "; - path_output_.WriteFile(out_, phony_target); + path_output_.WriteFile(out_, stamp_file); - out_ << ": " << BuiltinTool::kBuiltinToolPhony; + out_ << ": " << GetNinjaRulePrefixForToolchain(settings_) + << GeneralTool::kGeneralToolStamp; path_output_.WriteFiles(out_, files); if (!order_only_deps.empty()) {
diff --git a/src/gn/ninja_target_writer.h b/src/gn/ninja_target_writer.h index c9c8841..f4c9eae 100644 --- a/src/gn/ninja_target_writer.h +++ b/src/gn/ninja_target_writer.h
@@ -40,20 +40,21 @@ // identified by the given bits will be written. void WriteSharedVars(const SubstitutionBits& bits); - // Writes to the output stream a phony rule for input dependencies, and + // Writes to the output stream a stamp rule for input dependencies, and // returns the file to be appended to source rules that encodes the // order-only dependencies for the current target. - // If num_output_uses is small, this might return all input dependencies - // directly, without writing a phony rule. + // If num_stamp_uses is small, this might return all input dependencies + // directly, without writing a stamp file. // If there are no implicit dependencies and no extra target dependencies // are passed in, this returns an empty vector. - std::vector<OutputFile> WriteInputDepsPhonyAndGetDep( + std::vector<OutputFile> WriteInputDepsStampAndGetDep( const std::vector<const Target*>& extra_hard_deps, - size_t num_output_uses) const; + size_t num_stamp_uses) const; - // Writes to the output file a final phony rule for the target that aliases - // the given list of files. - void WritePhonyForTarget(const std::vector<OutputFile>& deps, + // Writes to the output file a final stamp rule for the target that stamps + // the given list of files. This function assumes the stamp is for the target + // as a whole so the stamp file is set as the target's dependency output. + void WriteStampForTarget(const std::vector<OutputFile>& deps, const std::vector<OutputFile>& order_only_deps); const Settings* settings_; // Non-owning.
diff --git a/src/gn/ninja_target_writer_unittest.cc b/src/gn/ninja_target_writer_unittest.cc index 300dbdd..1b19159 100644 --- a/src/gn/ninja_target_writer_unittest.cc +++ b/src/gn/ninja_target_writer_unittest.cc
@@ -22,17 +22,17 @@ void Run() override {} // Make this public so the test can call it. - std::vector<OutputFile> WriteInputDepsPhonyAndGetDep( + std::vector<OutputFile> WriteInputDepsStampAndGetDep( const std::vector<const Target*>& extra_hard_deps, - size_t num_output_uses) { - return NinjaTargetWriter::WriteInputDepsPhonyAndGetDep(extra_hard_deps, - num_output_uses); + size_t num_stamp_uses) { + return NinjaTargetWriter::WriteInputDepsStampAndGetDep(extra_hard_deps, + num_stamp_uses); } }; } // namespace -TEST(NinjaTargetWriter, WriteInputDepsPhonyAndGetDep) { +TEST(NinjaTargetWriter, WriteInputDepsStampAndGetDep) { TestWithScope setup; Err err; @@ -72,7 +72,7 @@ std::ostringstream stream; TestingNinjaTargetWriter writer(&base_target, setup.toolchain(), stream); std::vector<OutputFile> dep = - writer.WriteInputDepsPhonyAndGetDep(std::vector<const Target*>(), 10u); + writer.WriteInputDepsStampAndGetDep(std::vector<const Target*>(), 10u); // Since there is only one dependency, it should just be returned and // nothing written to the stream. @@ -86,12 +86,12 @@ std::ostringstream stream; TestingNinjaTargetWriter writer(&target, setup.toolchain(), stream); std::vector<OutputFile> dep = - writer.WriteInputDepsPhonyAndGetDep(std::vector<const Target*>(), 10u); + writer.WriteInputDepsStampAndGetDep(std::vector<const Target*>(), 10u); - // Since there is only one dependency, a phony target will be returned + // Since there is only one dependency, a stamp file will be returned // directly without writing any additional rules. ASSERT_EQ(1u, dep.size()); - EXPECT_EQ("phony/foo/base", dep[0].value()); + EXPECT_EQ("obj/foo/base.stamp", dep[0].value()); } { @@ -107,7 +107,7 @@ "build: __foo_action___rule | ../../foo/script.py" " ../../foo/action_source.txt ./target\n" "\n" - "build phony/foo/action: phony\n", + "build obj/foo/action.stamp: stamp\n", stream.str()); } @@ -117,19 +117,19 @@ std::ostringstream stream; TestingNinjaTargetWriter writer(&action, setup.toolchain(), stream); std::vector<OutputFile> dep = - writer.WriteInputDepsPhonyAndGetDep(std::vector<const Target*>(), 10u); + writer.WriteInputDepsStampAndGetDep(std::vector<const Target*>(), 10u); ASSERT_EQ(1u, dep.size()); - EXPECT_EQ("phony/foo/action.inputdeps", dep[0].value()); + EXPECT_EQ("obj/foo/action.inputdeps.stamp", dep[0].value()); EXPECT_EQ( - "build phony/foo/action.inputdeps: phony ../../foo/script.py " + "build obj/foo/action.inputdeps.stamp: stamp ../../foo/script.py " "../../foo/action_source.txt ./target\n", stream.str()); } } -// Tests WriteInputDepsPhonyAndGetDep when toolchain deps are present. -TEST(NinjaTargetWriter, WriteInputDepsPhonyAndGetDepWithToolchainDeps) { +// Tests WriteInputDepsStampAndGetDep when toolchain deps are present. +TEST(NinjaTargetWriter, WriteInputDepsStampAndGetDepWithToolchainDeps) { TestWithScope setup; Err err; @@ -153,11 +153,11 @@ std::ostringstream stream; TestingNinjaTargetWriter writer(&target, setup.toolchain(), stream); std::vector<OutputFile> dep = - writer.WriteInputDepsPhonyAndGetDep(std::vector<const Target*>(), 10u); + writer.WriteInputDepsStampAndGetDep(std::vector<const Target*>(), 10u); - // Since there is more than one dependency, a phony target will be returned - // and the rule for the phony target will be written to the stream. + // Since there is more than one dependency, a stamp file will be returned + // and the rule for the stamp file will be written to the stream. ASSERT_EQ(1u, dep.size()); - EXPECT_EQ("phony/foo/setup", dep[0].value()); + EXPECT_EQ("obj/foo/setup.stamp", dep[0].value()); EXPECT_EQ("", stream.str()); }
diff --git a/src/gn/runtime_deps.cc b/src/gn/runtime_deps.cc index f04857f..3b6d683 100644 --- a/src/gn/runtime_deps.cc +++ b/src/gn/runtime_deps.cc
@@ -176,7 +176,7 @@ return false; } - std::optional<OutputFile> output_file; + OutputFile output_file; const char extension[] = ".runtime_deps"; if (target->output_type() == Target::SHARED_LIBRARY || target->output_type() == Target::LOADABLE_MODULE) { @@ -185,20 +185,11 @@ CHECK(!target->computed_outputs().empty()); output_file = OutputFile(target->computed_outputs()[0].value() + extension); - } else if (target->dependency_output_file()) { - output_file = - OutputFile(target->dependency_output_file()->value() + extension); } else { - // If there is no dependency_output_file, this target's dependency output - // is either a phony alias or was elided entirely (due to lack of real - // inputs). In either case, there is no file to add an additional - // extension to, so we should compute our own name in the OBJ BuildDir. - output_file = GetBuildDirForTargetAsOutputFile(target, BuildDirType::OBJ); - output_file->value().append(target->GetComputedOutputName()); - output_file->value().append(extension); + output_file = + OutputFile(target->dependency_output_file().value() + extension); } - if (output_file) - files_to_write->push_back(std::make_pair(*output_file, target)); + files_to_write->push_back(std::make_pair(output_file, target)); } return true; }
diff --git a/src/gn/switches.cc b/src/gn/switches.cc index b94bc47..0ad3a6b 100644 --- a/src/gn/switches.cc +++ b/src/gn/switches.cc
@@ -229,12 +229,9 @@ an output file "bar.so", GN will create a file "bar.so.runtime_deps" in the build directory. - For targets that don't generate an output file (such as source set, action, - copy or group), the runtime deps file will be in the output directory where an - output file would have been located. For example, the source_set target - "//foo:bar" would result in a runtime dependency file being written to - "<output_dir>/obj/foo/bar.runtime_deps". This is probably not useful; the - use-case for this feature is generally executable targets. + If a source set, action, copy, or group is listed, the runtime deps file will + correspond to the .stamp file corresponding to that target. This is probably + not useful; the use-case for this feature is generally executable targets. The runtime dependency file will list one file per line, with no escaping. The files will be relative to the root_build_dir. The first line of the file
diff --git a/src/gn/target.cc b/src/gn/target.cc index 6b28107..b8a8d05 100644 --- a/src/gn/target.cc +++ b/src/gn/target.cc
@@ -5,7 +5,6 @@ #include "gn/target.h" #include <stddef.h> -#include <algorithm> #include "base/stl_util.h" #include "base/strings/string_util.h" @@ -517,7 +516,8 @@ if (!bundle_data().GetOutputsAsSourceFiles(settings(), this, outputs, err)) return false; } else if (IsBinary() && output_type() != Target::SOURCE_SET) { - // Binary target with normal outputs (source sets have phony targets). + // Binary target with normal outputs (source sets have stamp outputs like + // groups). DCHECK(IsBinary()) << static_cast<int>(output_type()); if (!build_complete) { // Can't access the toolchain for a target before the build is complete. @@ -537,20 +537,15 @@ output_file.AsSourceFile(settings()->build_settings())); } } else { - // Everything else (like a group or bundle_data) has a phony output. The - // dependency output phony should have computed what this is. This won't be + // Everything else (like a group or bundle_data) has a stamp output. The + // dependency output file should have computed what this is. This won't be // valid unless the build is complete. if (!build_complete) { *err = Err(loc_for_error, kBuildIncompleteMsg); return false; } - - // The dependency output might be empty if there is no output file or a - // phony alias for a set of inputs. - if (dependency_output_file_or_phony()) { - outputs->push_back(dependency_output_file_or_phony()->AsSourceFile( - settings()->build_settings())); - } + outputs->push_back( + dependency_output_file().AsSourceFile(settings()->build_settings())); } return true; } @@ -781,65 +776,25 @@ bundle_data_.OnTargetResolved(this); } -bool Target::HasRealInputs() const { - // This check is only necessary if this target will result in a phony target. - // Phony targets with no real inputs are treated as always dirty. - - // Actions always have at least one input file: the script used to execute - // the action. As such, they will never have an input-less phony target. We - // check this first to elide the common checks. - if (output_type() == ACTION || output_type() == ACTION_FOREACH) { - return true; - } - - // If any of this target's dependencies is non-phony target or a phony target - // with real inputs, then this target should be considered to have inputs. - for (const auto& pair : GetDeps(DEPS_ALL)) { - if (pair.ptr->dependency_output_file_or_phony()) { - return true; - } - } - - if (output_type() == BUNDLE_DATA) { - return !sources().empty(); - } - if (output_type() == CREATE_BUNDLE) { - // CREATE_BUNDLE targets pick up most of their inputs in the form of - // dependencies on bundle_data targets, which were checked above when - // looping through GetDeps. This code handles the remaining possible - // CREATE_BUNDLE inputs. - return !bundle_data().assets_catalog_sources().empty() || - !bundle_data().partial_info_plist().is_null() || - !bundle_data().code_signing_script().is_null(); - } - - // If any of this target's sources will result in output files, then this - // target should be considered to have real inputs. - std::vector<OutputFile> tool_outputs; - return std::any_of( - sources().begin(), sources().end(), [&, this](const auto& source) { - const char* tool_name = Tool::kToolNone; - return GetOutputFilesForSource(source, &tool_name, &tool_outputs); - }); -} - bool Target::FillOutputFiles(Err* err) { const Tool* tool = toolchain_->GetToolForTargetFinalOutput(this); bool check_tool_outputs = false; switch (output_type_) { + case GROUP: + case BUNDLE_DATA: + case CREATE_BUNDLE: + case SOURCE_SET: + case COPY_FILES: case ACTION: case ACTION_FOREACH: - case BUNDLE_DATA: - case COPY_FILES: - case CREATE_BUNDLE: - case GENERATED_FILE: - case GROUP: - case SOURCE_SET: { - if (HasRealInputs()) { - dependency_output_phony_ = - GetBuildDirForTargetAsOutputFile(this, BuildDirType::PHONY); - dependency_output_phony_->value().append(GetComputedOutputName()); - } + case GENERATED_FILE: { + // These don't get linked to and use stamps which should be the first + // entry in the outputs. These stamps are named + // "<target_out_dir>/<targetname>.stamp". + dependency_output_file_ = + GetBuildDirForTargetAsOutputFile(this, BuildDirType::OBJ); + dependency_output_file_.value().append(GetComputedOutputName()); + dependency_output_file_.value().append(".stamp"); break; } case EXECUTABLE: @@ -854,7 +809,7 @@ if (tool->runtime_outputs().list().empty()) { // Default to the first output for the runtime output. - runtime_outputs_.push_back(*dependency_output_file_); + runtime_outputs_.push_back(dependency_output_file_); } else { SubstitutionWriter::ApplyListToLinkerAsOutputFile( this, tool, tool->runtime_outputs(), &runtime_outputs_); @@ -866,10 +821,9 @@ // first output. CHECK(tool->outputs().list().size() >= 1); check_tool_outputs = true; - dependency_output_file_ = + link_output_file_ = dependency_output_file_ = SubstitutionWriter::ApplyPatternToLinkerAsOutputFile( this, tool, tool->outputs().list()[0]); - link_output_file_ = *dependency_output_file_; break; case RUST_PROC_MACRO: case SHARED_LIBRARY: @@ -878,10 +832,9 @@ if (const CTool* ctool = tool->AsC()) { if (ctool->link_output().empty() && ctool->depend_output().empty()) { // Default behavior, use the first output file for both. - dependency_output_file_ = + link_output_file_ = dependency_output_file_ = SubstitutionWriter::ApplyPatternToLinkerAsOutputFile( this, tool, tool->outputs().list()[0]); - link_output_file_ = *dependency_output_file_; } else { // Use the tool-specified ones. if (!ctool->link_output().empty()) { @@ -904,10 +857,9 @@ } } else if (const RustTool* rstool = tool->AsRust()) { // Default behavior, use the first output file for both. - dependency_output_file_ = + link_output_file_ = dependency_output_file_ = SubstitutionWriter::ApplyPatternToLinkerAsOutputFile( this, tool, tool->outputs().list()[0]); - link_output_file_ = *dependency_output_file_; } break; case UNKNOWN:
diff --git a/src/gn/target.h b/src/gn/target.h index 1d26301..dbcfa69 100644 --- a/src/gn/target.h +++ b/src/gn/target.h
@@ -320,7 +320,7 @@ // action or a copy step, and the output library or executable file(s) from // binary targets. // - // It will NOT include phony targets or object files. + // It will NOT include stamp files and object files. const std::vector<OutputFile>& computed_outputs() const { return computed_outputs_; } @@ -333,32 +333,15 @@ // a dependency on this one. It could be the same as the link output file // (this will be the case for static libraries). For shared libraries it // could be the same or different than the link output file, depending on the - // system. - // - // The dependency output phony is only set when the target does not have an - // output file and is using a phony alias to represent it. The exception to - // this is for phony targets without any real inputs. Ninja treats empty phony - // targets as always dirty, so no other targets should depend on that target. - // In that scenario, both dependency_output_phony or dependency_output_file - // will be std::nullopt. - // - // Callers that do not care whether the dependency is represented by a file or - // a phony should use dependency_output_file_or_phony(). + // system. For actions this will be the stamp file. // // These are only known once the target is resolved and will be empty before // that. This is a cache of the files to prevent every target that depends on // a given library from recomputing the same pattern. const OutputFile& link_output_file() const { return link_output_file_; } - const std::optional<OutputFile>& dependency_output_file() const { + const OutputFile& dependency_output_file() const { return dependency_output_file_; } - const std::optional<OutputFile>& dependency_output_phony() const { - return dependency_output_phony_; - } - const std::optional<OutputFile>& dependency_output_file_or_phony() const { - return dependency_output_file_ ? dependency_output_file_ - : dependency_output_phony_; - } // The subset of computed_outputs that are considered runtime outputs. const std::vector<OutputFile>& runtime_outputs() const { @@ -383,11 +366,6 @@ // The |loc_for_error| is used to blame a location for any errors produced. It // can be empty if there is no range (like this is being called based on the // command-line. - // - // It is possible for |outputs| to be returned empty without an error being - // reported. This can occur when the output type will result in a phony alias - // target (like a source_set) that is omitted from build files when they have - // no real inputs. bool GetOutputsAsSourceFiles(const LocationRange& loc_for_error, bool build_complete, std::vector<SourceFile>* outputs, @@ -424,11 +402,6 @@ void PullRecursiveHardDeps(); void PullRecursiveBundleData(); - // Checks to see whether this target or any of its dependencies have real - // inputs. If not, this target should be omitted as a dependency. This check - // only applies to targets that will result in a phony rule. - bool HasRealInputs() const; - // Fills the link and dependency output files when a target is resolved. bool FillOutputFiles(Err* err); @@ -516,8 +489,7 @@ // Output files. Empty until the target is resolved. std::vector<OutputFile> computed_outputs_; OutputFile link_output_file_; - std::optional<OutputFile> dependency_output_file_; - std::optional<OutputFile> dependency_output_phony_; + OutputFile dependency_output_file_; std::vector<OutputFile> runtime_outputs_; Metadata metadata_;
diff --git a/src/gn/target_unittest.cc b/src/gn/target_unittest.cc index 2496696..792c530 100644 --- a/src/gn/target_unittest.cc +++ b/src/gn/target_unittest.cc
@@ -726,8 +726,7 @@ ASSERT_TRUE(target.OnResolved(&err)); EXPECT_EQ("./liba.so", target.link_output_file().value()); - ASSERT_TRUE(target.dependency_output_file()); - EXPECT_EQ("./liba.so.TOC", target.dependency_output_file()->value()); + EXPECT_EQ("./liba.so.TOC", target.dependency_output_file().value()); ASSERT_EQ(1u, target.runtime_outputs().size()); EXPECT_EQ("./liba.so", target.runtime_outputs()[0].value()); @@ -773,8 +772,7 @@ ASSERT_TRUE(target.OnResolved(&err)); EXPECT_EQ("./a.dll.lib", target.link_output_file().value()); - ASSERT_TRUE(target.dependency_output_file()); - EXPECT_EQ("./a.dll.lib", target.dependency_output_file()->value()); + EXPECT_EQ("./a.dll.lib", target.dependency_output_file().value()); ASSERT_EQ(2u, target.runtime_outputs().size()); EXPECT_EQ("./a.dll", target.runtime_outputs()[0].value()); @@ -804,7 +802,6 @@ Target target(setup.settings(), Label(SourceDir("//a/"), "a")); target.set_output_type(Target::SOURCE_SET); - target.sources().push_back(SourceFile("//a/source_file1.cc")); target.SetToolchain(&toolchain); Err err; ASSERT_TRUE(target.OnResolved(&err)); @@ -821,12 +818,12 @@ EXPECT_EQ("input.cc.o", output[0].value()) << output[0].value(); // Test GetOutputsAsSourceFiles(). Since this is a source set it should give a - // phony target. + // stamp file. std::vector<SourceFile> computed_outputs; EXPECT_TRUE(target.GetOutputsAsSourceFiles(LocationRange(), true, &computed_outputs, &err)); ASSERT_EQ(1u, computed_outputs.size()); - EXPECT_EQ("//out/Debug/phony/a/a", computed_outputs[0].value()); + EXPECT_EQ("//out/Debug/obj/a/a.stamp", computed_outputs[0].value()); } // Tests Target::GetOutputFilesForSource for action_foreach targets (these, like
diff --git a/src/gn/tool.cc b/src/gn/tool.cc index 9297ce4..5e4186d 100644 --- a/src/gn/tool.cc +++ b/src/gn/tool.cc
@@ -4,7 +4,6 @@ #include "gn/tool.h" -#include "gn/builtin_tool.h" #include "gn/c_tool.h" #include "gn/general_tool.h" #include "gn/rust_tool.h" @@ -53,13 +52,6 @@ return nullptr; } -BuiltinTool* Tool::AsBuiltin() { - return nullptr; -} -const BuiltinTool* Tool::AsBuiltin() const { - return nullptr; -} - bool Tool::IsPatternInOutputList(const SubstitutionList& output_list, const SubstitutionPattern& pattern) const { for (const auto& cur : output_list.list()) { @@ -350,7 +342,7 @@ // static const char* Tool::GetToolTypeForTargetFinalOutput(const Target* target) { - // The contents of this list might be suprising (i.e. phony tool for copy + // The contents of this list might be suprising (i.e. stamp tool for copy // rules). See the header for why. // TODO(crbug.com/gn/39): Don't emit stamp files for single-output targets. if (target->source_types_used().RustSourceUsed()) { @@ -389,6 +381,8 @@ } } switch (target->output_type()) { + case Target::GROUP: + return GeneralTool::kGeneralToolStamp; case Target::EXECUTABLE: return CTool::kCToolLink; case Target::SHARED_LIBRARY: @@ -397,15 +391,15 @@ return CTool::kCToolSolinkModule; case Target::STATIC_LIBRARY: return CTool::kCToolAlink; + case Target::SOURCE_SET: + return GeneralTool::kGeneralToolStamp; case Target::ACTION: case Target::ACTION_FOREACH: case Target::BUNDLE_DATA: - case Target::COPY_FILES: case Target::CREATE_BUNDLE: + case Target::COPY_FILES: case Target::GENERATED_FILE: - case Target::GROUP: - case Target::SOURCE_SET: - return BuiltinTool::kBuiltinToolPhony; + return GeneralTool::kGeneralToolStamp; default: NOTREACHED(); return kToolNone;
diff --git a/src/gn/tool.h b/src/gn/tool.h index 5e824c9..e64935f 100644 --- a/src/gn/tool.h +++ b/src/gn/tool.h
@@ -24,7 +24,6 @@ class CTool; class GeneralTool; class RustTool; -class BuiltinTool; // To add a new Tool category, create a subclass implementing SetComplete() // Add a new category to ToolCategories @@ -64,8 +63,6 @@ virtual const GeneralTool* AsGeneral() const; virtual RustTool* AsRust(); virtual const RustTool* AsRust() const; - virtual BuiltinTool* AsBuiltin(); - virtual const BuiltinTool* AsBuiltin() const; // Basic information ---------------------------------------------------------
diff --git a/src/gn/toolchain.cc b/src/gn/toolchain.cc index a00aec4..bfad81d 100644 --- a/src/gn/toolchain.cc +++ b/src/gn/toolchain.cc
@@ -9,15 +9,13 @@ #include <utility> #include "base/logging.h" -#include "gn/builtin_tool.h" #include "gn/target.h" #include "gn/value.h" Toolchain::Toolchain(const Settings* settings, const Label& label, const SourceFileSet& build_dependency_files) - : Item(settings, label, build_dependency_files), - phony_tool_(BuiltinTool::kBuiltinToolPhony) {} + : Item(settings, label, build_dependency_files) {} Toolchain::~Toolchain() = default; @@ -31,9 +29,6 @@ Tool* Toolchain::GetTool(const char* name) { DCHECK(name != Tool::kToolNone); - if (name == BuiltinTool::kBuiltinToolPhony) { - return &phony_tool_; - } auto pair = tools_.find(name); if (pair != tools_.end()) { return pair->second.get(); @@ -43,9 +38,6 @@ const Tool* Toolchain::GetTool(const char* name) const { DCHECK(name != Tool::kToolNone); - if (name == BuiltinTool::kBuiltinToolPhony) { - return &phony_tool_; - } auto pair = tools_.find(name); if (pair != tools_.end()) { return pair->second.get(); @@ -95,20 +87,6 @@ return nullptr; } -BuiltinTool* Toolchain::GetToolAsBuiltin(const char* name) { - if (Tool* tool = GetTool(name)) { - return tool->AsBuiltin(); - } - return nullptr; -} - -const BuiltinTool* Toolchain::GetToolAsBuiltin(const char* name) const { - if (const Tool* tool = GetTool(name)) { - return tool->AsBuiltin(); - } - return nullptr; -} - void Toolchain::SetTool(std::unique_ptr<Tool> t) { DCHECK(t->name() != Tool::kToolNone); DCHECK(tools_.find(t->name()) == tools_.end()); @@ -142,11 +120,6 @@ return GetToolAsRust(Tool::GetToolTypeForSourceType(type)); } -const BuiltinTool* Toolchain::GetToolForSourceTypeAsBuiltin( - SourceFile::Type type) const { - return GetToolAsBuiltin(Tool::GetToolTypeForSourceType(type)); -} - const Tool* Toolchain::GetToolForTargetFinalOutput(const Target* target) const { return GetTool(Tool::GetToolTypeForTargetFinalOutput(target)); } @@ -165,8 +138,3 @@ const Target* target) const { return GetToolAsRust(Tool::GetToolTypeForTargetFinalOutput(target)); } - -const BuiltinTool* Toolchain::GetToolForTargetFinalOutputAsBuiltin( - const Target* target) const { - return GetToolAsBuiltin(Tool::GetToolTypeForTargetFinalOutput(target)); -}
diff --git a/src/gn/toolchain.h b/src/gn/toolchain.h index e4215ea..eb5a60c 100644 --- a/src/gn/toolchain.h +++ b/src/gn/toolchain.h
@@ -9,7 +9,6 @@ #include <string_view> #include "base/logging.h" -#include "gn/builtin_tool.h" #include "gn/item.h" #include "gn/label_ptr.h" #include "gn/scope.h" @@ -63,8 +62,6 @@ const CTool* GetToolAsC(const char* name) const; RustTool* GetToolAsRust(const char* name); const RustTool* GetToolAsRust(const char* name) const; - BuiltinTool* GetToolAsBuiltin(const char* name); - const BuiltinTool* GetToolAsBuiltin(const char* name) const; // Set a tool. When all tools are configured, you should call // ToolchainSetupComplete(). @@ -96,19 +93,16 @@ const CTool* GetToolForSourceTypeAsC(SourceFile::Type type) const; const GeneralTool* GetToolForSourceTypeAsGeneral(SourceFile::Type type) const; const RustTool* GetToolForSourceTypeAsRust(SourceFile::Type type) const; - const BuiltinTool* GetToolForSourceTypeAsBuiltin(SourceFile::Type type) const; // Returns the tool that produces the final output for the given target type. // This isn't necessarily the tool you would expect. For copy target, this - // will return the phony tool instead since the final output of a copy - // target is a phony alias to the set of copies done so there is one output. + // will return the stamp tool instead since the final output of a copy + // target is to stamp the set of copies done so there is one output. const Tool* GetToolForTargetFinalOutput(const Target* target) const; const CTool* GetToolForTargetFinalOutputAsC(const Target* target) const; const GeneralTool* GetToolForTargetFinalOutputAsGeneral( const Target* target) const; const RustTool* GetToolForTargetFinalOutputAsRust(const Target* target) const; - const BuiltinTool* GetToolForTargetFinalOutputAsBuiltin( - const Target* target) const; const SubstitutionBits& substitution_bits() const { DCHECK(setup_complete_); @@ -120,7 +114,6 @@ } private: - BuiltinTool phony_tool_; std::map<const char*, std::unique_ptr<Tool>> tools_; bool setup_complete_ = false;
diff --git a/src/gn/visual_studio_writer.cc b/src/gn/visual_studio_writer.cc index 6acff14..6ee56e8 100644 --- a/src/gn/visual_studio_writer.cc +++ b/src/gn/visual_studio_writer.cc
@@ -521,14 +521,14 @@ project.SubElement("PropertyGroup", XmlAttributes("Label", "UserMacros")); - auto [ninja_target, ninja_target_is_phony] = GetNinjaTarget(target); + std::string ninja_target = GetNinjaTarget(target); { std::unique_ptr<XmlElementWriter> properties = project.SubElement("PropertyGroup"); properties->SubElement("OutDir")->Text("$(SolutionDir)"); properties->SubElement("TargetName")->Text("$(ProjectName)"); - if (target->output_type() != Target::GROUP && !ninja_target_is_phony) { + if (target->output_type() != Target::GROUP) { properties->SubElement("TargetPath")->Text("$(OutDir)\\" + ninja_target); } } @@ -904,20 +904,13 @@ } } -std::pair<std::string, bool> VisualStudioWriter::GetNinjaTarget(const Target* target) { +std::string VisualStudioWriter::GetNinjaTarget(const Target* target) { std::ostringstream ninja_target_out; - bool is_phony = false; - OutputFile output_file; - if (target->dependency_output_file()) { - output_file = *target->dependency_output_file(); - } else if (target->dependency_output_phony()) { - output_file = *target->dependency_output_phony(); - is_phony = true; - } - - ninja_path_output_.WriteFile(ninja_target_out, output_file); + DCHECK(!target->dependency_output_file().value().empty()); + ninja_path_output_.WriteFile(ninja_target_out, + target->dependency_output_file()); std::string s = ninja_target_out.str(); if (s.compare(0, 2, "./") == 0) s = s.substr(2); - return std::make_pair(s, is_phony); + return s; }
diff --git a/src/gn/visual_studio_writer.h b/src/gn/visual_studio_writer.h index 55ae705..e4957a1 100644 --- a/src/gn/visual_studio_writer.h +++ b/src/gn/visual_studio_writer.h
@@ -127,8 +127,7 @@ // and updates |root_folder_dir_|. Also sets |parent_folder| for |projects_|. void ResolveSolutionFolders(); - // Returns the ninja target string and whether the target is phony. - std::pair<std::string, bool> GetNinjaTarget(const Target* target); + std::string GetNinjaTarget(const Target* target); const BuildSettings* build_settings_;