about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-02-25 11:53:09 -0800
committerGitHub <noreply@github.com>2023-02-25 11:53:09 -0800
commit1a599d7d97c7ab4b03a75f1405bb19293ea2ca6a (patch)
treea9c4b6d0c3d15586deab0f97608a33141fd65f3b
parenta4119ba0aeb6b32375be85a1f47cfc785b147084 (diff)
parentfde2e40e43b487357fad103beec0ec228b077f61 (diff)
downloadrust-1a599d7d97c7ab4b03a75f1405bb19293ea2ca6a.tar.gz
rust-1a599d7d97c7ab4b03a75f1405bb19293ea2ca6a.zip
Rollup merge of #107675 - jsgf:link-directives, r=davidtwco
Implement -Zlink-directives=yes/no

`-Zlink-directives=no` will ignored `#[link]` directives while compiling a crate, so nothing is emitted into the crate's metadata.  The assumption is that the build system already knows about the crate's native dependencies and can provide them at link time without these directives.

This is another way to address issue # #70093, which is currently addressed by `-Zlink-native-libraries` (implemented in #70095). The latter is implemented at link time, which has the effect of ignoring `#[link]` in *every* crate. This makes it a very large hammer as it requires all native dependencies to be known to the build system to be at all usable, including those in sysroot libraries. I think this means its effectively unused, and definitely under-used.

Being able to control this on a crate-by-crate basis should make it much easier to apply when needed.

I'm not sure if we need both mechanisms, but we can decide that later.

cc `@pcwalton` `@cramertj`
-rw-r--r--compiler/rustc_interface/src/tests.rs1
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs7
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--tests/rustdoc-ui/z-help.stdout1
-rw-r--r--tests/ui/issues/issue-70093/issue-70093-link-directives.rs10
-rw-r--r--tests/ui/issues/issue-70093/issue-70093.rs (renamed from tests/ui/issues/issue-70093.rs)0
6 files changed, 20 insertions, 1 deletions
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 71a72036994..18d84a7023a 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -756,6 +756,7 @@ fn test_unstable_options_tracking_hash() {
     tracked!(instrument_coverage, Some(InstrumentCoverage::All));
     tracked!(instrument_mcount, true);
     tracked!(instrument_xray, Some(InstrumentXRay::default()));
+    tracked!(link_directives, false);
     tracked!(link_only, true);
     tracked!(llvm_plugins, vec![String::from("plugin_name")]);
     tracked!(location_detail, LocationDetail { file: true, line: false, column: false });
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index 5a4d358e5dd..d6f68b2e140 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -103,8 +103,13 @@ impl<'tcx> Collector<'tcx> {
         }
 
         // Process all of the #[link(..)]-style arguments
-        let sess = &self.tcx.sess;
+        let sess = self.tcx.sess;
         let features = self.tcx.features();
+
+        if !sess.opts.unstable_opts.link_directives {
+            return;
+        }
+
         for m in self.tcx.hir().attrs(it.hir_id()).iter().filter(|a| a.has_name(sym::link)) {
             let Some(items) = m.meta_item_list() else {
                 continue;
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 1f3eb8d4832..4beac931632 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1489,6 +1489,8 @@ options! {
         "keep hygiene data after analysis (default: no)"),
     layout_seed: Option<u64> = (None, parse_opt_number, [TRACKED],
         "seed layout randomization"),
+    link_directives: bool = (true, parse_bool, [TRACKED],
+        "honor #[link] directives in the compiled crate (default: yes)"),
     link_native_libraries: bool = (true, parse_bool, [UNTRACKED],
         "link native libraries in the linker invocation (default: yes)"),
     link_only: bool = (false, parse_bool, [TRACKED],
diff --git a/tests/rustdoc-ui/z-help.stdout b/tests/rustdoc-ui/z-help.stdout
index 58b2f92d150..6aa9785f44e 100644
--- a/tests/rustdoc-ui/z-help.stdout
+++ b/tests/rustdoc-ui/z-help.stdout
@@ -81,6 +81,7 @@
          Multiple options can be combined with commas.
     -Z                     keep-hygiene-data=val -- keep hygiene data after analysis (default: no)
     -Z                           layout-seed=val -- seed layout randomization
+    -Z                       link-directives=val -- honor #[link] directives in the compiled crate (default: yes)
     -Z                 link-native-libraries=val -- link native libraries in the linker invocation (default: yes)
     -Z                             link-only=val -- link the `.rlink` file generated by `-Z no-link` (default: no)
     -Z                          llvm-plugins=val -- a list LLVM plugins to enable (space separated)
diff --git a/tests/ui/issues/issue-70093/issue-70093-link-directives.rs b/tests/ui/issues/issue-70093/issue-70093-link-directives.rs
new file mode 100644
index 00000000000..83f9b16c408
--- /dev/null
+++ b/tests/ui/issues/issue-70093/issue-70093-link-directives.rs
@@ -0,0 +1,10 @@
+// run-pass
+// compile-flags: -Zlink-directives=no
+// ignore-windows - this will probably only work on unixish systems
+// ignore-fuchsia - missing __libc_start_main for some reason (#84733)
+// ignore-cross-compile - default-linker-libraries=yes doesn't play well with cross compiling
+
+#[link(name = "some-random-non-existent-library", kind = "static")]
+extern "C" {}
+
+fn main() {}
diff --git a/tests/ui/issues/issue-70093.rs b/tests/ui/issues/issue-70093/issue-70093.rs
index 86459dc904a..86459dc904a 100644
--- a/tests/ui/issues/issue-70093.rs
+++ b/tests/ui/issues/issue-70093/issue-70093.rs