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