Skip to content

Commit

Permalink
Pass ldflags to Rust tools.
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Brett Wilson <[email protected]>
  • Loading branch information
adetaylor authored and Commit Bot committed Jul 8, 2021
1 parent 31f2bba commit 24e2f7d
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 10 deletions.
24 changes: 19 additions & 5 deletions src/gn/ninja_binary_target_writer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -294,18 +294,22 @@ void NinjaBinaryTargetWriter::WriteCompilerBuildLine(
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()) {
Expand Down Expand Up @@ -334,6 +338,16 @@ void NinjaBinaryTargetWriter::WriteLinkerFlags(
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:";
Expand Down
4 changes: 4 additions & 0 deletions src/gn/ninja_binary_target_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ class NinjaBinaryTargetWriter : public NinjaTargetWriter {
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,
Expand Down
6 changes: 4 additions & 2 deletions src/gn/ninja_rust_binary_target_writer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,10 @@ void NinjaRustBinaryTargetWriter::WriteRustdeps(
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;
}
21 changes: 21 additions & 0 deletions src/gn/ninja_rust_binary_target_writer_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, RustExecutable) {
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));

Expand All @@ -65,6 +66,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, RustExecutable) {
"../../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;
Expand Down Expand Up @@ -107,6 +109,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, RlibDeps) {
"../../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;
Expand Down Expand Up @@ -158,6 +161,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, RlibDeps) {
"../../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;
Expand Down Expand Up @@ -201,6 +205,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, RlibDepsAcrossGroups) {
"../../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;
Expand Down Expand Up @@ -247,6 +252,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, RlibDepsAcrossGroups) {
"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;
Expand Down Expand Up @@ -285,6 +291,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, RlibDepsAcrossGroups) {
"../../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;
Expand Down Expand Up @@ -341,6 +348,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, RenamedDeps) {
"../../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;
Expand Down Expand Up @@ -443,6 +451,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, NonRustDeps) {
"-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;
Expand Down Expand Up @@ -480,6 +489,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, NonRustDeps) {
"../../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;
Expand Down Expand Up @@ -518,6 +528,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, NonRustDeps) {
"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;
Expand Down Expand Up @@ -562,6 +573,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, RustOutputExtensionAndDir) {
"../../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;
Expand Down Expand Up @@ -607,6 +619,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, LibsAndLibDirs) {
"../../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;
Expand Down Expand Up @@ -666,6 +679,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, RustProcMacro) {
"../../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;
Expand Down Expand Up @@ -704,6 +718,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, RustProcMacro) {
"../../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;
Expand Down Expand Up @@ -746,6 +761,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, GroupDeps) {
"../../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;
Expand Down Expand Up @@ -791,6 +807,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, GroupDeps) {
"../../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;
Expand Down Expand Up @@ -838,6 +855,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, Externs) {
" 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;
Expand Down Expand Up @@ -884,6 +902,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, Inputs) {
"|| 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();
Expand Down Expand Up @@ -924,6 +943,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, CdylibDeps) {
"../../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;
Expand Down Expand Up @@ -962,6 +982,7 @@ TEST_F(NinjaRustBinaryTargetWriterTest, CdylibDeps) {
" 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;
Expand Down
6 changes: 6 additions & 0 deletions src/gn/rust_substitution_type.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "gn/err.h"
#include "gn/substitution_type.h"
#include "gn/c_substitution_type.h"

const SubstitutionTypes RustSubstitutions = {
&kRustSubstitutionCrateName, &kRustSubstitutionCrateType,
Expand Down Expand Up @@ -40,3 +41,8 @@ bool IsValidRustSubstitution(const Substitution* type) {
type == &kRustSubstitutionRustFlags ||
type == &kRustSubstitutionSources;
}

bool IsValidRustLinkerSubstitution(const Substitution* type) {
return IsValidRustSubstitution(type) ||
type == &CSubstitutionLdFlags;
}
1 change: 1 addition & 0 deletions src/gn/rust_substitution_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ extern const Substitution kRustSubstitutionRustFlags;
extern const Substitution kRustSubstitutionSources;

bool IsValidRustSubstitution(const Substitution* type);
bool IsValidRustLinkerSubstitution(const Substitution* type);

#endif // TOOLS_GN_RUST_SUBSTITUTION_TYPE_H_
11 changes: 8 additions & 3 deletions src/gn/rust_tool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ bool RustTool::ValidateName(const char* name) const {
name == kRsToolStaticlib;
}

bool RustTool::MayLink() const {
return name_ == kRsToolBin || name_ == kRsToolCDylib || name_ == kRsToolDylib ||
name_ == kRsToolMacro;
}

void RustTool::SetComplete() {
SetToolComplete();
}
Expand Down Expand Up @@ -114,9 +119,9 @@ bool RustTool::InitTool(Scope* scope, Toolchain* toolchain, Err* err) {
}

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;
Expand Down
1 change: 1 addition & 0 deletions src/gn/rust_tool.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class RustTool : public Tool {
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;
Expand Down

0 comments on commit 24e2f7d

Please sign in to comment.