Ninja: Always pass linker flags to rlib-generating command.

This is a partial rollback of [1] to restore all linker args in
the Ninja command that builds Rust rlib artifacts.

The Fuchsia build system supports remote builders with a wrapper
script that looks at the command-line arguments of the rustc
invocation to determine which input files to send to remote
builders. This is done with a custom toolchain tool() definition.

For example, the final command looks like:

```
<wrapper_script> <wrapper_args> -- <rustc_invocation>
```

And it is crucial that `<rustc_invocation>` lists all linker inputs
(even with `-Lnative=<dir>` and `-Clink-arg=libfoo.a`) to ensure
they can be detected properly.

A recent GN change [1] removed such inputs, which broke the Fuchsia
build (or more accurately, prevents rolling upstream GN into the
Fuchsia tree). For more information, see https://fxbug.dev/130206.

Note that this does not revert the CL entirely, in particular to keep
the fix  for `framework_dirs` as described in the original bug
description.

+ Update variables.cc to avoid losing a docs/reference.md change
  that was applied manually in [1].

[1] https://gn-review.googlesource.com/c/gn/+/15580

Fixed: 340
Change-Id: Ibd65494a9b180037f21a666da5e6d905751b9c61
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/15760
Commit-Queue: David Turner <digit@google.com>
Reviewed-by: Takuto Ikuta <tikuta@google.com>
diff --git a/src/gn/ninja_rust_binary_target_writer.cc b/src/gn/ninja_rust_binary_target_writer.cc
index 21ae6d0..a400cf7 100644
--- a/src/gn/ninja_rust_binary_target_writer.cc
+++ b/src/gn/ninja_rust_binary_target_writer.cc
@@ -209,8 +209,8 @@
   std::copy(classified_deps.non_linkable_deps.begin(),
             classified_deps.non_linkable_deps.end(),
             std::back_inserter(extern_deps));
-  WriteExternsAndDeps(target_->IsFinal(), extern_deps, transitive_crates,
-                      rustdeps, nonrustdeps);
+
+  WriteExternsAndDeps(extern_deps, transitive_crates, rustdeps, nonrustdeps);
   WriteSourcesAndInputs();
   WritePool(out_);
 }
@@ -256,7 +256,6 @@
 }
 
 void NinjaRustBinaryTargetWriter::WriteExternsAndDeps(
-    bool target_is_final,
     const std::vector<const Target*>& deps,
     const std::vector<ExternCrate>& transitive_rust_deps,
     const std::vector<OutputFile>& rustdeps,
@@ -365,17 +364,16 @@
 
   // If rustc will invoke a linker, then pass linker arguments to include those
   // non-Rust native dependencies in the linking step.
-  if (target_is_final) {
-    // Before outputting any libraries to link, ensure the linker is in a mode
-    // that allows dynamic linking, as rustc may have previously put it into
-    // static-only mode.
-    if (nonrustdeps.size() > 0) {
-      out_ << " " << tool_->dynamic_link_switch();
-    }
-    for (const auto& nonrustdep : nonrustdeps) {
-      out_ << " -Clink-arg=";
-      path_output_.WriteFile(out_, nonrustdep);
-    }
+
+  // Before outputting any libraries to link, ensure the linker is in a mode
+  // that allows dynamic linking, as rustc may have previously put it into
+  // static-only mode.
+  if (nonrustdeps.size() > 0) {
+    out_ << " " << tool_->dynamic_link_switch();
+  }
+  for (const auto& nonrustdep : nonrustdeps) {
+    out_ << " -Clink-arg=";
+    path_output_.WriteFile(out_, nonrustdep);
   }
 
   // Library search paths are required to find system libraries named in #[link]
@@ -383,15 +381,13 @@
   WriteLibrarySearchPath(out_, tool_);
   // If rustc will invoke a linker, all libraries need the passed through to the
   // linker.
-  if (target_is_final) {
-    WriteLibs(out_, tool_);
-  }
+  WriteLibs(out_, tool_);
+
   out_ << std::endl;
   out_ << "  ldflags =";
   // If rustc will invoke a linker, linker flags need to be forwarded through to
   // the linker.
-  if (target_is_final) {
-    WriteCustomLinkerFlags(out_, tool_);
-  }
+  WriteCustomLinkerFlags(out_, tool_);
+
   out_ << std::endl;
 }
diff --git a/src/gn/ninja_rust_binary_target_writer.h b/src/gn/ninja_rust_binary_target_writer.h
index 470a899..69ec916 100644
--- a/src/gn/ninja_rust_binary_target_writer.h
+++ b/src/gn/ninja_rust_binary_target_writer.h
@@ -28,8 +28,7 @@
   void WriteCompilerVars();
   void WriteSources(const OutputFile& input_dep,
                     const std::vector<OutputFile>& order_only_deps);
-  void WriteExternsAndDeps(bool target_is_final,
-                           const std::vector<const Target*>& deps,
+  void WriteExternsAndDeps(const std::vector<const Target*>& deps,
                            const std::vector<ExternCrate>& transitive_rust_deps,
                            const std::vector<OutputFile>& rustdeps,
                            const std::vector<OutputFile>& nonrustdeps);
diff --git a/src/gn/ninja_rust_binary_target_writer_unittest.cc b/src/gn/ninja_rust_binary_target_writer_unittest.cc
index deb2bb6..9a21c1f 100644
--- a/src/gn/ninja_rust_binary_target_writer_unittest.cc
+++ b/src/gn/ninja_rust_binary_target_writer_unittest.cc
@@ -896,7 +896,8 @@
         "  source_file_part = lib.rs\n"
         "  source_name_part = lib\n"
         "  externs =\n"
-        "  rustdeps = -Lnative=obj/foo\n"
+        "  rustdeps = -Lnative=obj/foo -Clink-arg=-Balternative-dynamic "
+        "-Clink-arg=obj/foo/libstatic.a\n"
         "  ldflags =\n"
         "  sources = ../../baz/lib.rs\n";
     std::string out_str = out.str();
@@ -1255,8 +1256,7 @@
   //    requesting a system library. The path to that library must be specified
   //    separately with `-L` in ldflags, the library does not appear in the
   //    rustc compilation of an rlib.
-  rlib.config_values().libs().push_back(
-      LibFile(SourceFile("//dir1/ar.a")));
+  rlib.config_values().libs().push_back(LibFile(SourceFile("//dir1/ar.a")));
   // 2. A dependency on a library name as happens with a `libs` rule. Libraries
   //    need only be named when linking, they do not need to appear in an rlib
   //    compilation.
@@ -1295,12 +1295,15 @@
         "target_out_dir = obj/foo\n"
         "target_output_name = librlibcrate\n"
         "\n"
-        "build obj/foo/librlibcrate.rlib: rust_rlib ../../foo/input.rs | ../../foo/input.rs obj/bar/libpubliclib.rlib obj/clib/libstatic.a\n"
+        "build obj/foo/librlibcrate.rlib: rust_rlib ../../foo/input.rs | "
+        "../../foo/input.rs obj/bar/libpubliclib.rlib obj/clib/libstatic.a\n"
         "  source_file_part = input.rs\n"
         "  source_name_part = input\n"
         "  externs = --extern publiccrate=obj/bar/libpubliclib.rlib\n"
         "  rustdeps = -Ldependency=obj/bar -Lnative=obj/clib "
-"-Lnative=../../baz -Lframework=../../fwdir\n"
+        "-Clink-arg=-Bdynamic -Clink-arg=obj/clib/libstatic.a "
+        "-Lnative=../../baz -Lframework=../../fwdir -Clink-arg=../../dir1/ar.a "
+        "-lquux\n"
         "  ldflags =\n"
         "  sources = ../../foo/input.rs\n";
     std::string out_str = out.str();
diff --git a/src/gn/setup.cc b/src/gn/setup.cc
index 139a919..68acd43 100644
--- a/src/gn/setup.cc
+++ b/src/gn/setup.cc
@@ -191,6 +191,7 @@
       required version is 1.7.2. Specifying a higher version might enable the
       use of some of newer features that can make the build more efficient.
 
+
 Example .gn file contents
 
   buildconfig = "//build/config/BUILDCONFIG.gn"
diff --git a/src/gn/variables.cc b/src/gn/variables.cc
index 5015df5..8eb2a99 100644
--- a/src/gn/variables.cc
+++ b/src/gn/variables.cc
@@ -1177,6 +1177,10 @@
   of targets, and public_configs are always propagated across public deps of
   all types of targets.
 
+  For Rust targets, deps ensures that Rust code can refer to the dependency
+  target. If the dependency is a C/C++ target, the path to that target will
+  be made available to Rust for `#[link]` directives.
+
   Data dependencies are propagated differently. See "gn help data_deps" and
   "gn help runtime_deps".