Make data_deps in copy() targets work.
Looks like copy targets were never updated for data_deps.
Without this change, having a copy() target have data_deps on
another target and building the copy() target didn't build the
data_dep. For all other target types, it does build the dep,
so this looks like it's unintentional.
See https://gn-review.googlesource.com/c/gn/+/8861/ for a
larger, standalone repro.
Change-Id: I866bbb162619c57636907af13f34213949a54882
Bug: none
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/8860
Reviewed-by: Brett Wilson <brettw@chromium.org>
Commit-Queue: Nico Weber <thakis@chromium.org>
diff --git a/src/gn/ninja_copy_target_writer.cc b/src/gn/ninja_copy_target_writer.cc
index f350086..9299223 100644
--- a/src/gn/ninja_copy_target_writer.cc
+++ b/src/gn/ninja_copy_target_writer.cc
@@ -73,13 +73,17 @@
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())
+ 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
// (the possibility of generated #includes is the main reason for implicit
// dependencies).
//
// It would seem that specifying implicit dependencies on the deps of the
- // copy command would still be harmeless. But Chrome implements copy tools
+ // copy command would still be harmless. But Chrome implements copy tools
// as hard links (much faster) which don't change the timestamp. If the
// ninja rule looks like this:
// output: copy input | foo.stamp
@@ -97,8 +101,9 @@
//
// Note that there is the need in some cases for order-only dependencies
// where a command might need to make sure something else runs before it runs
- // to avoid conflicts. Such cases should be avoided where possible, but
- // sometimes that's not possible.
+ // to avoid conflicts. This is also needed for data_deps on a copy target.
+ // Such cases should be avoided where possible, but sometimes that's not
+ // possible.
for (const auto& input_file : target_->sources()) {
OutputFile output_file =
SubstitutionWriter::ApplyPatternToSourceAsOutputFile(
@@ -109,9 +114,10 @@
path_output_.WriteFile(out_, output_file);
out_ << ": " << tool_name << " ";
path_output_.WriteFile(out_, input_file);
- if (!input_deps.empty()) {
+ if (!input_deps.empty() || !data_outs.empty()) {
out_ << " ||";
path_output_.WriteFiles(out_, input_deps);
+ path_output_.WriteFiles(out_, data_outs);
}
out_ << std::endl;
}
diff --git a/src/gn/ninja_copy_target_writer_unittest.cc b/src/gn/ninja_copy_target_writer_unittest.cc
index 0b4caea..f641ffa 100644
--- a/src/gn/ninja_copy_target_writer_unittest.cc
+++ b/src/gn/ninja_copy_target_writer_unittest.cc
@@ -92,3 +92,35 @@
std::string out_str = out.str();
EXPECT_EQ(expected_linux, out_str);
}
+
+TEST(NinjaCopyTargetWriter, DataDeps) {
+ Err err;
+ TestWithScope setup;
+
+ Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
+ target.set_output_type(Target::COPY_FILES);
+ target.sources().push_back(SourceFile("//foo/input1.txt"));
+ target.action_values().outputs() =
+ SubstitutionList::MakeForTest("//out/Debug/{{source_name_part}}.out");
+
+ Target data_dep(setup.settings(), Label(SourceDir("//foo/"), "datadep"));
+ data_dep.set_output_type(Target::ACTION);
+ data_dep.visibility().SetPublic();
+ data_dep.SetToolchain(setup.toolchain());
+ ASSERT_TRUE(data_dep.OnResolved(&err));
+
+ target.data_deps().push_back(LabelTargetPair(&data_dep));
+ target.SetToolchain(setup.toolchain());
+ ASSERT_TRUE(target.OnResolved(&err));
+
+ std::ostringstream out;
+ NinjaCopyTargetWriter writer(&target, out);
+ writer.Run();
+
+ const char expected_linux[] =
+ "build input1.out: copy ../../foo/input1.txt || obj/foo/datadep.stamp\n"
+ "\n"
+ "build obj/foo/bar.stamp: stamp input1.out\n";
+ std::string out_str = out.str();
+ EXPECT_EQ(expected_linux, out_str);
+}