Fixing Rust targets depending on C source sets. Previously, such source sets were ignored. Rust targets now link them in correctly. Change-Id: I9d19eb872064b6a888ff5c1829d000e8773b8751 Reviewed-on: https://gn-review.googlesource.com/c/gn/+/8220 Reviewed-by: Brett Wilson <brettw@chromium.org> Reviewed-by: Petr Hosek <phosek@google.com> Commit-Queue: Brett Wilson <brettw@chromium.org>
diff --git a/src/gn/ninja_rust_binary_target_writer.cc b/src/gn/ninja_rust_binary_target_writer.cc index abe903f..983d92f 100644 --- a/src/gn/ninja_rust_binary_target_writer.cc +++ b/src/gn/ninja_rust_binary_target_writer.cc
@@ -108,8 +108,20 @@ // TODO(juliehockett): add inherited library support? and IsLinkable support? // for c-cross-compat void NinjaRustBinaryTargetWriter::Run() { + DCHECK(target_->output_type() != Target::SOURCE_SET); + OutputFile input_dep = WriteInputsStampAndGetDep(); + WriteCompilerVars(); + + // Classify our dependencies. + UniqueVector<const Target*> linkable_deps; + UniqueVector<const Target*> non_linkable_deps; + UniqueVector<const Target*> framework_deps; + UniqueVector<OutputFile> extra_obj_files; + GetDeps(&extra_obj_files, &linkable_deps, &non_linkable_deps, + &framework_deps); + // 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, // but changes in the inputs deps won't cause the file to be recompiled. See @@ -117,24 +129,21 @@ size_t num_stamp_uses = target_->sources().size(); std::vector<OutputFile> order_only_deps = WriteInputDepsStampAndGetDep( std::vector<const Target*>(), num_stamp_uses); - - // Public rust_library deps go in a --extern rlibs, public non-rust deps go in - // -Ldependency rustdeps, and non-public source_sets get passed in as normal - // source files - UniqueVector<OutputFile> deps; - DCHECK(target_->output_type() != Target::SOURCE_SET); - WriteCompilerVars(); - UniqueVector<const Target*> linkable_deps; - UniqueVector<const Target*> non_linkable_deps; - UniqueVector<const Target*> framework_deps; - GetDeps(&deps, &linkable_deps, &non_linkable_deps, &framework_deps); - AppendSourcesToImplicitDeps(&deps); - if (!input_dep.value().empty()) order_only_deps.push_back(input_dep); + // Build lists which will go into different bits of the rustc command line. + // Public rust_library deps go in a --extern rlibs, public non-rust deps go in + // -Ldependency. Also assemble a list of extra (i.e. implicit) deps + // for ninja dependency tracking. + UniqueVector<OutputFile> implicit_deps; + AppendSourcesToImplicitDeps(&implicit_deps); + implicit_deps.Append(extra_obj_files.begin(), extra_obj_files.end()); + std::vector<OutputFile> rustdeps; std::vector<OutputFile> nonrustdeps; + nonrustdeps.insert(nonrustdeps.end(), extra_obj_files.begin(), + extra_obj_files.end()); for (const auto* framework_dep : framework_deps) { order_only_deps.push_back(framework_dep->dependency_output_file()); } @@ -151,7 +160,7 @@ } else { nonrustdeps.push_back(linkable_dep->link_output_file()); } - deps.push_back(linkable_dep->dependency_output_file()); + implicit_deps.push_back(linkable_dep->dependency_output_file()); } // Rust libraries specified by paths. @@ -159,12 +168,13 @@ const ConfigValues& cur = iter.cur(); for (const auto& e : cur.externs()) { if (e.second.is_source_file()) { - deps.push_back( + implicit_deps.push_back( OutputFile(settings_->build_settings(), e.second.source_file())); } } } + // Bubble up the full list of transitive rlib dependencies. std::vector<OutputFile> transitive_rustlibs; for (const auto* dep : target_->rust_values().transitive_libs().GetOrdered()) { @@ -176,8 +186,9 @@ std::vector<OutputFile> tool_outputs; SubstitutionWriter::ApplyListToLinkerAsOutputFile( target_, tool_, tool_->outputs(), &tool_outputs); - WriteCompilerBuildLine(target_->rust_values().crate_root(), deps.vector(), - order_only_deps, tool_->name(), tool_outputs); + WriteCompilerBuildLine(target_->rust_values().crate_root(), + implicit_deps.vector(), order_only_deps, tool_->name(), + tool_outputs); std::vector<const Target*> extern_deps(linkable_deps.vector()); std::copy(non_linkable_deps.begin(), non_linkable_deps.end(),
diff --git a/src/gn/ninja_rust_binary_target_writer_unittest.cc b/src/gn/ninja_rust_binary_target_writer_unittest.cc index 70a7d00..7cfd63d 100644 --- a/src/gn/ninja_rust_binary_target_writer_unittest.cc +++ b/src/gn/ninja_rust_binary_target_writer_unittest.cc
@@ -372,6 +372,14 @@ sharedlib.SetToolchain(setup.toolchain()); ASSERT_TRUE(sharedlib.OnResolved(&err)); + Target csourceset(setup.settings(), Label(SourceDir("//baz/"), "sourceset")); + csourceset.set_output_type(Target::SOURCE_SET); + csourceset.visibility().SetPublic(); + csourceset.sources().push_back(SourceFile("//baz/csourceset.cpp")); + csourceset.source_types_used().Set(SourceFile::SOURCE_CPP); + csourceset.SetToolchain(setup.toolchain()); + ASSERT_TRUE(csourceset.OnResolved(&err)); + Toolchain toolchain_with_toc( setup.settings(), Label(SourceDir("//toolchain_with_toc/"), "with_toc")); TestWithScope::SetupToolchain(&toolchain_with_toc, true); @@ -396,6 +404,7 @@ nonrust.private_deps().push_back(LabelTargetPair(&rlib)); nonrust.private_deps().push_back(LabelTargetPair(&staticlib)); nonrust.private_deps().push_back(LabelTargetPair(&sharedlib)); + nonrust.private_deps().push_back(LabelTargetPair(&csourceset)); nonrust.private_deps().push_back(LabelTargetPair(&sharedlib_with_toc)); nonrust.SetToolchain(setup.toolchain()); ASSERT_TRUE(nonrust.OnResolved(&err)); @@ -417,11 +426,14 @@ "target_output_name = bar\n" "\n" "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/source.rs " - "../../foo/main.rs obj/bar/libmylib.rlib obj/foo/libstatic.a " - "./libshared.so ./libshared_with_toc.so.TOC\n" + "../../foo/main.rs obj/baz/sourceset.csourceset.o " + "obj/bar/libmylib.rlib " + "obj/foo/libstatic.a ./libshared.so ./libshared_with_toc.so.TOC " + "|| obj/baz/sourceset.stamp\n" " externs = --extern mylib=obj/bar/libmylib.rlib\n" - " rustdeps = -Ldependency=obj/bar -Lnative=obj/foo -Lnative=. " - "-lstatic -lshared -lshared_with_toc\n"; + " rustdeps = -Ldependency=obj/bar -Lnative=obj/baz -Lnative=obj/foo " + "-Lnative=. -Clink-arg=obj/baz/sourceset.csourceset.o -lstatic " + "-lshared -lshared_with_toc\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; }