Make dynamic link switch... dynamic. Previously gn hard-coded the linker switch -Bdynamic which is incorrect on platforms where MSVC tools are used for linking. This CL parameterizes that flag. Bug: https://crbug.com/1271215 Change-Id: I379c86b5eb166d973bc502cdae2552b9e1c6a6a7 Reviewed-on: https://gn-review.googlesource.com/c/gn/+/12460 Commit-Queue: Tyler Mandry <tmandry@google.com> Reviewed-by: Takuto Ikuta <tikuta@google.com> Reviewed-by: Tyler Mandry <tmandry@google.com>
diff --git a/docs/reference.md b/docs/reference.md index eca3032..d04912a 100644 --- a/docs/reference.md +++ b/docs/reference.md
@@ -3870,6 +3870,20 @@ process, but may be used when generating metadata for rust-analyzer. (See --export-rust-project). It enables such metadata to include information about the Rust standard library. + + dynamic_link_switch + Valid for: Rust tools which link + + A switch to be optionally inserted into linker command lines + to indicate that subsequent items may be dynamically linked. + For ld-like linkers, -Clink-arg=-Bdynamic may be a good choice. + This switch is inserted by gn into rustc command lines before + listing any non-Rust dependencies. This may be necessary because + sometimes rustc puts the linker into a mode where it would otherwise + link against static libraries by default. This flag will be + inserted into the {{rustdeps}} variable at the appropriate place; + {{ldflags}} can't be used for the same purpose because the flags + may not be inserted at the desired place in the command line. ``` #### **Expansions for tool variables**
diff --git a/src/gn/function_toolchain.cc b/src/gn/function_toolchain.cc index b0fc5e1..b36b1e9 100644 --- a/src/gn/function_toolchain.cc +++ b/src/gn/function_toolchain.cc
@@ -592,6 +592,20 @@ (See --export-rust-project). It enables such metadata to include information about the Rust standard library. + dynamic_link_switch + Valid for: Rust tools which link + + A switch to be optionally inserted into linker command lines + to indicate that subsequent items may be dynamically linked. + For ld-like linkers, -Clink-arg=-Bdynamic may be a good choice. + This switch is inserted by gn into rustc command lines before + listing any non-Rust dependencies. This may be necessary because + sometimes rustc puts the linker into a mode where it would otherwise + link against static libraries by default. This flag will be + inserted into the {{rustdeps}} variable at the appropriate place; + {{ldflags}} can't be used for the same purpose because the flags + may not be inserted at the desired place in the command line. + )" // String break to prevent overflowing the 16K max VC string length. R"(Expansions for tool variables
diff --git a/src/gn/ninja_rust_binary_target_writer.cc b/src/gn/ninja_rust_binary_target_writer.cc index 06bce2f..694f332 100644 --- a/src/gn/ninja_rust_binary_target_writer.cc +++ b/src/gn/ninja_rust_binary_target_writer.cc
@@ -363,7 +363,7 @@ // that allows dynamic linking, as rustc may have previously put it into // static-only mode. if (nonrustdeps.size() > 0) { - out_ << " -Clink-arg=-Bdynamic"; + out_ << " " << tool_->dynamic_link_switch(); } for (const auto& nonrustdep : nonrustdeps) { out_ << " -Clink-arg=";
diff --git a/src/gn/ninja_rust_binary_target_writer_unittest.cc b/src/gn/ninja_rust_binary_target_writer_unittest.cc index 41a9fdd..21b104f 100644 --- a/src/gn/ninja_rust_binary_target_writer_unittest.cc +++ b/src/gn/ninja_rust_binary_target_writer_unittest.cc
@@ -896,7 +896,7 @@ " source_file_part = lib.rs\n" " source_name_part = lib\n" " externs =\n" - " rustdeps = -Lnative=obj/foo -Clink-arg=-Bdynamic " + " rustdeps = -Lnative=obj/foo -Clink-arg=-Balternative-dynamic " "-Clink-arg=obj/foo/libstatic.a\n" " ldflags =\n" " sources = ../../baz/lib.rs\n";
diff --git a/src/gn/rust_tool.cc b/src/gn/rust_tool.cc index eaffb5b..5f2c2de 100644 --- a/src/gn/rust_tool.cc +++ b/src/gn/rust_tool.cc
@@ -21,6 +21,7 @@ set_lib_dir_switch("-Lnative="); set_lib_switch("-l"); set_linker_arg("-Clink-arg="); + set_dynamic_link_switch("-Clink-arg=-Bdynamic"); } RustTool::~RustTool() = default; @@ -115,6 +116,13 @@ if (!ReadString(scope, "rust_sysroot", &rust_sysroot_, err)) { return false; } + + if (MayLink()) { + if (!ReadString(scope, "dynamic_link_switch", &dynamic_link_switch_, err)) { + return false; + } + } + return true; }
diff --git a/src/gn/rust_tool.h b/src/gn/rust_tool.h index 7b4f7ac..341c48f 100644 --- a/src/gn/rust_tool.h +++ b/src/gn/rust_tool.h
@@ -44,8 +44,15 @@ std::string_view GetSysroot() const; + const std::string& dynamic_link_switch() const { return dynamic_link_switch_; } + void set_dynamic_link_switch(std::string s) { + DCHECK(!complete_); + dynamic_link_switch_ = std::move(s); + } + private: std::string rust_sysroot_; + std::string dynamic_link_switch_; bool SetOutputExtension(const Value* value, std::string* var, Err* err); bool ReadOutputsPatternList(Scope* scope,
diff --git a/src/gn/test_with_scope.cc b/src/gn/test_with_scope.cc index 757dd34..638bf32 100644 --- a/src/gn/test_with_scope.cc +++ b/src/gn/test_with_scope.cc
@@ -242,7 +242,7 @@ "{{target_out_dir}}/{{source_name_part}}.o")); toolchain->SetTool(std::move(swift_tool)); - // CDYLIB + // RUST CDYLIB std::unique_ptr<Tool> cdylib_tool = Tool::CreateTool(RustTool::kRsToolCDylib); SetCommandForTool( "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} " @@ -255,7 +255,7 @@ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}")); toolchain->SetTool(std::move(cdylib_tool)); - // DYLIB + // RUST DYLIB std::unique_ptr<Tool> dylib_tool = Tool::CreateTool(RustTool::kRsToolDylib); SetCommandForTool( "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} " @@ -295,7 +295,7 @@ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}")); toolchain->SetTool(std::move(rlib_tool)); - // STATICLIB + // RUST STATICLIB std::unique_ptr<Tool> staticlib_tool = Tool::CreateTool(RustTool::kRsToolStaticlib); SetCommandForTool( @@ -307,6 +307,7 @@ staticlib_tool->set_default_output_extension(".a"); staticlib_tool->set_outputs(SubstitutionList::MakeForTest( "{{target_out_dir}}/{{target_output_name}}{{output_extension}}")); + static_cast<RustTool*>(staticlib_tool.get())->set_dynamic_link_switch("-Clink-arg=-Balternative-dynamic"); toolchain->SetTool(std::move(staticlib_tool)); toolchain->ToolchainSetupComplete();