Pass ldflags to Rust tools. Rust tools may involve ldd or some other linker, which may require access to the ldflags used for a given toolchain. Example instances might be: * building against an Android NDK or some other platform with a special sysroot * absorbing ldflags required for ASAN configurations. Previously, these ldflags weren't passed to rust tools. With this change, they are. Bug: 170 Change-Id: I7e8dd150740ab7a4a61d0b9c919fbe28ed736ac1 Reviewed-on: https://gn-review.googlesource.com/c/gn/+/11940 Commit-Queue: Adrian Taylor <adetaylor@google.com> Reviewed-by: Brett Wilson <brettw@chromium.org>
diff --git a/src/gn/ninja_binary_target_writer.cc b/src/gn/ninja_binary_target_writer.cc index 50e3e29..a5dcd66 100644 --- a/src/gn/ninja_binary_target_writer.cc +++ b/src/gn/ninja_binary_target_writer.cc
@@ -294,18 +294,22 @@ out_ << std::endl; } -void NinjaBinaryTargetWriter::WriteLinkerFlags( +void NinjaBinaryTargetWriter::WriteCustomLinkerFlags( std::ostream& out, - const Tool* tool, - const SourceFile* optional_def_file) { - if (tool->AsC()) { + const Tool* tool) { + + if (tool->AsC() || (tool->AsRust() && tool->AsRust()->MayLink())) { // First the ldflags from the target and its config. RecursiveTargetConfigStringsToStream(kRecursiveWriterKeepDuplicates, target_, &ConfigValues::ldflags, GetFlagOptions(), out); } +} - // Followed by library search paths that have been recursively pushed +void NinjaBinaryTargetWriter::WriteLibrarySearchPath( + std::ostream& out, + const Tool* tool) { + // Write library search paths that have been recursively pushed // through the dependency tree. const UniqueVector<SourceDir>& all_lib_dirs = target_->all_lib_dirs(); if (!all_lib_dirs.empty()) { @@ -334,6 +338,16 @@ PathOutput::DIR_NO_LAST_SLASH); } } +} + +void NinjaBinaryTargetWriter::WriteLinkerFlags( + std::ostream& out, + const Tool* tool, + const SourceFile* optional_def_file) { + // First any ldflags + WriteCustomLinkerFlags(out, tool); + // Then the library search path + WriteLibrarySearchPath(out, tool); if (optional_def_file) { out_ << " /DEF:";
diff --git a/src/gn/ninja_binary_target_writer.h b/src/gn/ninja_binary_target_writer.h index 76a8a4e..66e0b6a 100644 --- a/src/gn/ninja_binary_target_writer.h +++ b/src/gn/ninja_binary_target_writer.h
@@ -69,6 +69,10 @@ void WriteLinkerFlags(std::ostream& out, const Tool* tool, const SourceFile* optional_def_file); + void WriteCustomLinkerFlags(std::ostream& out, + const Tool* tool); + void WriteLibrarySearchPath(std::ostream& out, + const Tool* tool); void WriteLibs(std::ostream& out, const Tool* tool); void WriteFrameworks(std::ostream& out, const Tool* tool); void WriteSwiftModules(std::ostream& out,
diff --git a/src/gn/ninja_rust_binary_target_writer.cc b/src/gn/ninja_rust_binary_target_writer.cc index 82149bf..73cc9e8 100644 --- a/src/gn/ninja_rust_binary_target_writer.cc +++ b/src/gn/ninja_rust_binary_target_writer.cc
@@ -320,8 +320,10 @@ out_ << " -Clink-arg="; path_output_.WriteFile(out_, nonrustdep); } - - WriteLinkerFlags(out_, tool_, nullptr); + WriteLibrarySearchPath(out_, tool_); WriteLibs(out_, tool_); out_ << std::endl; + out_ << " ldflags ="; + WriteCustomLinkerFlags(out_, tool_); + out_ << std::endl; }
diff --git a/src/gn/ninja_rust_binary_target_writer_unittest.cc b/src/gn/ninja_rust_binary_target_writer_unittest.cc index a65a961..d130abb 100644 --- a/src/gn/ninja_rust_binary_target_writer_unittest.cc +++ b/src/gn/ninja_rust_binary_target_writer_unittest.cc
@@ -42,6 +42,7 @@ target.source_types_used().Set(SourceFile::SOURCE_RS); target.rust_values().set_crate_root(main); target.rust_values().crate_name() = "foo_bar"; + target.config_values().ldflags().push_back("-fsanitize=address"); target.SetToolchain(setup.toolchain()); ASSERT_TRUE(target.OnResolved(&err)); @@ -65,6 +66,7 @@ "../../foo/main.rs\n" " externs =\n" " rustdeps =\n" + " ldflags = -fsanitize=address\n" " sources = ../../foo/input3.rs ../../foo/main.rs\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -107,6 +109,7 @@ "../../bar/mylib.rs ../../bar/lib.rs\n" " externs =\n" " rustdeps =\n" + " ldflags =\n" " sources = ../../bar/mylib.rs ../../bar/lib.rs\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -158,6 +161,7 @@ "../../foo/main.rs obj/foo/libdirect.rlib\n" " externs = --extern direct=obj/foo/libdirect.rlib\n" " rustdeps = -Ldependency=obj/foo -Ldependency=obj/bar\n" + " ldflags =\n" " sources = ../../foo/source.rs ../../foo/main.rs\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -201,6 +205,7 @@ "../../bar/mylib.rs ../../bar/lib.rs\n" " externs =\n" " rustdeps =\n" + " ldflags =\n" " sources = ../../bar/mylib.rs ../../bar/lib.rs\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -247,6 +252,7 @@ "obj/baz/group.stamp\n" " externs = --extern mymacro=obj/bar/libmymacro.so\n" " rustdeps = -Ldependency=obj/bar\n" + " ldflags =\n" " sources = ../../bar/mylib.rs ../../bar/lib.rs\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -285,6 +291,7 @@ "../../foo/source.rs ../../foo/main.rs obj/bar/libmylib.rlib\n" " externs = --extern mylib=obj/bar/libmylib.rlib\n" " rustdeps = -Ldependency=obj/bar\n" + " ldflags =\n" " sources = ../../foo/source.rs ../../foo/main.rs\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -341,6 +348,7 @@ "../../foo/main.rs obj/foo/libdirect.rlib\n" " externs = --extern direct_renamed=obj/foo/libdirect.rlib\n" " rustdeps = -Ldependency=obj/foo\n" + " ldflags =\n" " sources = ../../foo/source.rs ../../foo/main.rs\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -443,6 +451,7 @@ "-Clink-arg=obj/baz/sourceset.csourceset.o " "-Clink-arg=obj/foo/libstatic.a -Clink-arg=./libshared.so " "-Clink-arg=./libshared_with_toc.so\n" + " ldflags =\n" " sources = ../../foo/source.rs ../../foo/main.rs\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -480,6 +489,7 @@ "../../foo/main.rs obj/foo/libstatic.a\n" " externs =\n" " rustdeps = -Lnative=obj/foo -Clink-arg=obj/foo/libstatic.a\n" + " ldflags =\n" " sources = ../../foo/source.rs ../../foo/main.rs\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -518,6 +528,7 @@ "obj/foo/libstatic.a\n" " externs =\n" " rustdeps = -Lnative=obj/foo -Clink-arg=obj/foo/libstatic.a\n" + " ldflags =\n" " sources = ../../baz/lib.rs\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -562,6 +573,7 @@ "../../foo/main.rs\n" " externs =\n" " rustdeps =\n" + " ldflags =\n" " sources = ../../foo/input3.rs ../../foo/main.rs\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -607,6 +619,7 @@ "../../foo/main.rs\n" " externs =\n" " rustdeps = -Lnative=../../baz -lquux\n" + " ldflags =\n" " sources = ../../foo/input.rs ../../foo/main.rs\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -666,6 +679,7 @@ "../../bar/mylib.rs ../../bar/lib.rs obj/baz/libmymacrodep.rlib\n" " externs = --extern mymacrodep=obj/baz/libmymacrodep.rlib\n" " rustdeps = -Ldependency=obj/baz\n" + " ldflags =\n" " sources = ../../bar/mylib.rs ../../bar/lib.rs\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -704,6 +718,7 @@ "../../foo/main.rs obj/bar/libmymacro.so\n" " externs = --extern mymacro=obj/bar/libmymacro.so\n" " rustdeps = -Ldependency=obj/bar\n" + " ldflags =\n" " sources = ../../foo/source.rs ../../foo/main.rs\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -746,6 +761,7 @@ "../../bar/mylib.rs ../../bar/lib.rs\n" " externs =\n" " rustdeps =\n" + " ldflags =\n" " sources = ../../bar/mylib.rs ../../bar/lib.rs\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -791,6 +807,7 @@ "../../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" + " ldflags =\n" " sources = ../../foo/source.rs ../../foo/main.rs\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -838,6 +855,7 @@ " externs = --extern lib1=../../foo/lib1.rlib --extern " "lib2=lib2.rlib\n" " rustdeps =\n" + " ldflags =\n" " sources = ../../foo/source.rs ../../foo/main.rs\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -884,6 +902,7 @@ "|| obj/foo/bar.inputs.stamp\n" " externs =\n" " rustdeps =\n" + " ldflags =\n" " sources = ../../foo/source.rs ../../foo/main.rs " "../../foo/config.json ../../foo/template.h\n"; std::string out_str = out.str(); @@ -924,6 +943,7 @@ "../../bar/lib.rs\n" " externs =\n" " rustdeps =\n" + " ldflags =\n" " sources = ../../bar/lib.rs\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str; @@ -962,6 +982,7 @@ " externs =\n" " rustdeps = -Ldependency=obj/bar -Lnative=obj/bar " "-Clink-arg=obj/bar/libmylib.so\n" + " ldflags =\n" " sources = ../../foo/source.rs ../../foo/main.rs\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
diff --git a/src/gn/rust_substitution_type.cc b/src/gn/rust_substitution_type.cc index c417019..69e6cf6 100644 --- a/src/gn/rust_substitution_type.cc +++ b/src/gn/rust_substitution_type.cc
@@ -9,6 +9,7 @@ #include "gn/err.h" #include "gn/substitution_type.h" +#include "gn/c_substitution_type.h" const SubstitutionTypes RustSubstitutions = { &kRustSubstitutionCrateName, &kRustSubstitutionCrateType, @@ -40,3 +41,8 @@ type == &kRustSubstitutionRustFlags || type == &kRustSubstitutionSources; } + +bool IsValidRustLinkerSubstitution(const Substitution* type) { + return IsValidRustSubstitution(type) || + type == &CSubstitutionLdFlags; +}
diff --git a/src/gn/rust_substitution_type.h b/src/gn/rust_substitution_type.h index 2eeb7dc..36ba953 100644 --- a/src/gn/rust_substitution_type.h +++ b/src/gn/rust_substitution_type.h
@@ -23,5 +23,6 @@ extern const Substitution kRustSubstitutionSources; bool IsValidRustSubstitution(const Substitution* type); +bool IsValidRustLinkerSubstitution(const Substitution* type); #endif // TOOLS_GN_RUST_SUBSTITUTION_TYPE_H_
diff --git a/src/gn/rust_tool.cc b/src/gn/rust_tool.cc index 0b8921f..eaffb5b 100644 --- a/src/gn/rust_tool.cc +++ b/src/gn/rust_tool.cc
@@ -38,6 +38,11 @@ name == kRsToolStaticlib; } +bool RustTool::MayLink() const { + return name_ == kRsToolBin || name_ == kRsToolCDylib || name_ == kRsToolDylib || + name_ == kRsToolMacro; +} + void RustTool::SetComplete() { SetToolComplete(); } @@ -114,9 +119,9 @@ } bool RustTool::ValidateSubstitution(const Substitution* sub_type) const { - if (name_ == kRsToolBin || name_ == kRsToolCDylib || name_ == kRsToolDylib || - name_ == kRsToolMacro || name_ == kRsToolRlib || - name_ == kRsToolStaticlib) + if (MayLink()) + return IsValidRustLinkerSubstitution(sub_type); + if (ValidateName(name_)) return IsValidRustSubstitution(sub_type); NOTREACHED(); return false;
diff --git a/src/gn/rust_tool.h b/src/gn/rust_tool.h index 8eec377..836191c 100644 --- a/src/gn/rust_tool.h +++ b/src/gn/rust_tool.h
@@ -38,6 +38,7 @@ bool ValidateName(const char* name) const override; void SetComplete() override; bool ValidateSubstitution(const Substitution* sub_type) const override; + bool MayLink() const; RustTool* AsRust() override; const RustTool* AsRust() const override;