diff --git a/src/gn/ninja_binary_target_writer.cc b/src/gn/ninja_binary_target_writer.cc index 50e3e291..a5dcd664 100644 --- a/src/gn/ninja_binary_target_writer.cc +++ b/src/gn/ninja_binary_target_writer.cc @@ -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& all_lib_dirs = target_->all_lib_dirs(); if (!all_lib_dirs.empty()) { @@ -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:"; diff --git a/src/gn/ninja_binary_target_writer.h b/src/gn/ninja_binary_target_writer.h index 76a8a4eb..66e0b6ab 100644 --- a/src/gn/ninja_binary_target_writer.h +++ b/src/gn/ninja_binary_target_writer.h @@ -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, diff --git a/src/gn/ninja_rust_binary_target_writer.cc b/src/gn/ninja_rust_binary_target_writer.cc index 82149bfc..73cc9e86 100644 --- a/src/gn/ninja_rust_binary_target_writer.cc +++ b/src/gn/ninja_rust_binary_target_writer.cc @@ -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; } diff --git a/src/gn/ninja_rust_binary_target_writer_unittest.cc b/src/gn/ninja_rust_binary_target_writer_unittest.cc index a65a961c..d130abb9 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 @@ 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)); @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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(); @@ -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; @@ -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; diff --git a/src/gn/rust_substitution_type.cc b/src/gn/rust_substitution_type.cc index c4170196..69e6cf6a 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 @@ bool IsValidRustSubstitution(const Substitution* type) { 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 2eeb7dc7..36ba9538 100644 --- a/src/gn/rust_substitution_type.h +++ b/src/gn/rust_substitution_type.h @@ -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_ diff --git a/src/gn/rust_tool.cc b/src/gn/rust_tool.cc index 0b8921f0..eaffb5b4 100644 --- a/src/gn/rust_tool.cc +++ b/src/gn/rust_tool.cc @@ -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(); } @@ -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; diff --git a/src/gn/rust_tool.h b/src/gn/rust_tool.h index 8eec3774..836191c6 100644 --- a/src/gn/rust_tool.h +++ b/src/gn/rust_tool.h @@ -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;