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;