From 522f9757f6b9665b9452dea95fc42ebb604a05fe Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 30 Aug 2021 11:12:07 +0200 Subject: Fix handling of +whole-archive native link modifier. --- compiler/rustc_codegen_ssa/src/back/link.rs | 45 ++++++++++++++++++++++------- compiler/rustc_codegen_ssa/src/lib.rs | 1 + 2 files changed, 36 insertions(+), 10 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index f5463bca338..2e4cef39cfe 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -36,6 +36,7 @@ use regex::Regex; use tempfile::Builder as TempFileBuilder; use std::ffi::OsString; +use std::lazy::OnceCell; use std::path::{Path, PathBuf}; use std::process::{ExitStatus, Output, Stdio}; use std::{ascii, char, env, fmt, fs, io, mem, str}; @@ -2001,7 +2002,7 @@ fn add_local_native_libraries( let relevant_libs = codegen_results.crate_info.used_libraries.iter().filter(|l| relevant_lib(sess, l)); - let search_path = archive_search_paths(sess); + let search_path = OnceCell::new(); let mut last = (NativeLibKind::Unspecified, None); for lib in relevant_libs { let name = match lib.name { @@ -2023,7 +2024,11 @@ fn add_local_native_libraries( } NativeLibKind::Static { bundle: None | Some(true), .. } | NativeLibKind::Static { whole_archive: Some(true), .. } => { - cmd.link_whole_staticlib(name, verbatim, &search_path); + cmd.link_whole_staticlib( + name, + verbatim, + &search_path.get_or_init(|| archive_search_paths(sess)), + ); } NativeLibKind::Static { .. } => cmd.link_staticlib(name, verbatim), NativeLibKind::RawDylib => { @@ -2116,6 +2121,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( } let mut compiler_builtins = None; + let search_path = OnceCell::new(); for &cnum in deps.iter() { if group_start == Some(cnum) { @@ -2149,16 +2155,35 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( // external build system already has the native dependencies defined, and it // will provide them to the linker itself. if sess.opts.debugging_opts.link_native_libraries { - // Skip if this library is the same as the last. let mut last = None; for lib in &codegen_results.crate_info.native_libraries[&cnum] { - if lib.name.is_some() - && relevant_lib(sess, lib) - && matches!(lib.kind, NativeLibKind::Static { bundle: Some(false), .. }) - && last != lib.name - { - cmd.link_staticlib(lib.name.unwrap(), lib.verbatim.unwrap_or(false)); - last = lib.name; + if !relevant_lib(sess, lib) { + // Skip libraries if they are disabled by `#[link(cfg=...)]` + continue; + } + + // Skip if this library is the same as the last. + if last == lib.name { + continue; + } + + if let Some(static_lib_name) = lib.name { + if let NativeLibKind::Static { bundle: Some(false), whole_archive } = + lib.kind + { + let verbatim = lib.verbatim.unwrap_or(false); + if whole_archive == Some(true) { + cmd.link_whole_staticlib( + static_lib_name, + verbatim, + search_path.get_or_init(|| archive_search_paths(sess)), + ); + } else { + cmd.link_staticlib(static_lib_name, verbatim); + } + + last = lib.name; + } } } } diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index b6ee70c419b..634286770d1 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -3,6 +3,7 @@ #![feature(box_patterns)] #![feature(try_blocks)] #![feature(in_band_lifetimes)] +#![feature(once_cell)] #![feature(nll)] #![feature(associated_type_bounds)] #![recursion_limit = "256"] -- cgit 1.4.1-3-g733a5 From 846c372f86dfad597797ee73665f330fc557c63f Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Fri, 20 Aug 2021 16:25:39 -0400 Subject: Don't allow both the `+bundle` and `+whole-archive` modifiers for rlibs --- compiler/rustc_codegen_ssa/src/back/link.rs | 14 ++++++++++++++ .../mix-bundle-and-whole-archive-link-attr.rs | 12 ++++++++++++ .../mix-bundle-and-whole-archive-link-attr.stderr | 6 ++++++ .../mix-bundle-and-whole-archive.rs | 7 +++++++ .../mix-bundle-and-whole-archive.stderr | 6 ++++++ 5 files changed, 45 insertions(+) create mode 100644 src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs create mode 100644 src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr create mode 100644 src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs create mode 100644 src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 2e4cef39cfe..173b91e7903 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -255,6 +255,19 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>( // metadata of the rlib we're generating somehow. for lib in codegen_results.crate_info.used_libraries.iter() { match lib.kind { + NativeLibKind::Static { bundle: None | Some(true), whole_archive: Some(true) } + if flavor == RlibFlavor::Normal => + { + // Don't allow mixing +bundle with +whole_archive since an rlib may contain + // multiple native libs, some of which are +whole-archive and some of which are + // -whole-archive and it isn't clear how we can currently handle such a + // situation correctly. + // See https://github.com/rust-lang/rust/issues/88085#issuecomment-901050897 + sess.err( + "the linking modifiers `+bundle` and `+whole-archive` are not compatible \ + with each other when generating rlibs", + ); + } NativeLibKind::Static { bundle: None | Some(true), .. } => {} NativeLibKind::Static { bundle: Some(false), .. } | NativeLibKind::Dylib { .. } @@ -1223,6 +1236,7 @@ pub fn archive_search_paths(sess: &Session) -> Vec { sess.target_filesearch(PathKind::Native).search_path_dirs() } +#[derive(PartialEq)] enum RlibFlavor { Normal, StaticlibBase, diff --git a/src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs b/src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs new file mode 100644 index 00000000000..c3714a38451 --- /dev/null +++ b/src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs @@ -0,0 +1,12 @@ +// compile-flags: -Zunstable-options --crate-type rlib +// build-fail +// error-pattern: the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs + +#![feature(native_link_modifiers)] +#![feature(native_link_modifiers_bundle)] +#![feature(native_link_modifiers_whole_archive)] + +#[link(name = "mylib", kind = "static", modifiers = "+bundle,+whole-archive")] +extern "C" { } + +fn main() { } diff --git a/src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr b/src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr new file mode 100644 index 00000000000..246efb8d627 --- /dev/null +++ b/src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr @@ -0,0 +1,6 @@ +error: the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs + +error: could not find native static library `mylib`, perhaps an -L flag is missing? + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs b/src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs new file mode 100644 index 00000000000..1d0768d99cf --- /dev/null +++ b/src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs @@ -0,0 +1,7 @@ +// Mixing +bundle and +whole-archive is not allowed + +// compile-flags: -l static:+bundle,+whole-archive=mylib -Zunstable-options --crate-type rlib +// build-fail +// error-pattern: the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs + +fn main() { } diff --git a/src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr b/src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr new file mode 100644 index 00000000000..246efb8d627 --- /dev/null +++ b/src/test/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr @@ -0,0 +1,6 @@ +error: the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs + +error: could not find native static library `mylib`, perhaps an -L flag is missing? + +error: aborting due to 2 previous errors + -- cgit 1.4.1-3-g733a5