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); +}