about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDaniil Belov <70999565+BelovDV@users.noreply.github.com>2023-01-26 17:10:13 +0300
committerBelovDV <70999565+BelovDV@users.noreply.github.com>2023-02-10 12:51:12 +0300
commit601fc8b36b1962285e371cf3c54eeb3b1b9b3a74 (patch)
tree7442411b8396d87173d00ba1adb5f77dcd275d38
parentdffea43fc1102bdfe16d88ed412c23d4f0f08d9d (diff)
downloadrust-601fc8b36b1962285e371cf3c54eeb3b1b9b3a74.tar.gz
rust-601fc8b36b1962285e371cf3c54eeb3b1b9b3a74.zip
[link] enable packed bundled lib in non stable cases
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs135
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs1
-rw-r--r--compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl2
-rw-r--r--compiler/rustc_feature/src/active.rs2
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs27
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--tests/run-make/rlib-format-packed-bundled-libs-3/Makefile35
-rw-r--r--tests/run-make/rlib-format-packed-bundled-libs-3/main.rs5
-rw-r--r--tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_1.c1
-rw-r--r--tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_2.c1
-rw-r--r--tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_3.c1
-rw-r--r--tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_4.c1
-rw-r--r--tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs16
-rw-r--r--tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep_cfg.rs10
-rw-r--r--tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs13
-rw-r--r--tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr6
-rw-r--r--tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs9
-rw-r--r--tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr6
19 files changed, 146 insertions, 127 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 4ac7bea03eb..6fe8527ada6 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -270,10 +270,9 @@ pub fn each_linked_rlib(
 
 /// Create an 'rlib'.
 ///
-/// An rlib in its current incarnation is essentially a renamed .a file. The rlib primarily contains
-/// the object file of the crate, but it also contains all of the object files from native
-/// libraries. This is done by unzipping native libraries and inserting all of the contents into
-/// this archive.
+/// An rlib in its current incarnation is essentially a renamed .a file (with "dummy" object files).
+/// The rlib primarily contains the object file of the crate, but it also some of the object files
+/// from native libraries.
 fn link_rlib<'a>(
     sess: &'a Session,
     archive_builder_builder: &dyn ArchiveBuilderBuilder,
@@ -347,44 +346,23 @@ fn link_rlib<'a>(
     // loaded from the libraries found here and then encode that into the
     // 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 && sess.opts.unstable_opts.packed_bundled_libs => {}
-            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.emit_err(errors::IncompatibleLinkingModifiers);
-            }
-            NativeLibKind::Static { bundle: None | Some(true), .. } => {}
-            NativeLibKind::Static { bundle: Some(false), .. }
-            | NativeLibKind::Dylib { .. }
-            | NativeLibKind::Framework { .. }
-            | NativeLibKind::RawDylib
-            | NativeLibKind::LinkArg
-            | NativeLibKind::Unspecified => continue,
-        }
-        if let Some(name) = lib.name {
-            let location =
+        let NativeLibKind::Static { bundle: None | Some(true), whole_archive } = lib.kind else {
+            continue;
+        };
+        if whole_archive == Some(true) && !codegen_results.crate_info.feature_packed_bundled_libs {
+            sess.emit_err(errors::IncompatibleLinkingModifiers);
+        }
+        if flavor == RlibFlavor::Normal && let Some(filename) = lib.filename {
+            let path = find_native_static_library(filename.as_str(), true, &lib_search_paths, sess);
+            let src = read(path).map_err(|e| sess.emit_fatal(errors::ReadFileError {message: e }))?;
+            let (data, _) = create_wrapper_file(sess, b".bundled_lib".to_vec(), &src);
+            let wrapper_file = emit_wrapper_file(sess, &data, tmpdir, filename.as_str());
+            packed_bundled_libs.push(wrapper_file);
+        } else if let Some(name) = lib.name {
+            let path =
                 find_native_static_library(name.as_str(), lib.verbatim, &lib_search_paths, sess);
-            if sess.opts.unstable_opts.packed_bundled_libs && flavor == RlibFlavor::Normal {
-                let filename = lib.filename.unwrap();
-                let lib_path =
-                    find_native_static_library(filename.as_str(), true, &lib_search_paths, sess);
-                let src = read(lib_path)
-                    .map_err(|e| sess.emit_fatal(errors::ReadFileError { message: e }))?;
-                let (data, _) = create_wrapper_file(sess, b".bundled_lib".to_vec(), &src);
-                let wrapper_file = emit_wrapper_file(sess, &data, tmpdir, filename.as_str());
-                packed_bundled_libs.push(wrapper_file);
-                continue;
-            }
-            ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|error| {
-                sess.emit_fatal(errors::AddNativeLibrary { library_path: location, error });
-            });
+            ab.add_archive(&path, Box::new(|_| false)).unwrap_or_else(|error| {
+                sess.emit_fatal(errors::AddNativeLibrary { library_path: path, error })});
         }
     }
 
@@ -516,36 +494,14 @@ fn link_staticlib<'a>(
         &codegen_results.crate_info,
         Some(CrateType::Staticlib),
         &mut |cnum, path| {
-            let name = codegen_results.crate_info.crate_name[&cnum];
-            let native_libs = &codegen_results.crate_info.native_libraries[&cnum];
-
-            // Here when we include the rlib into our staticlib we need to make a
-            // decision whether to include the extra object files along the way.
-            // These extra object files come from statically included native
-            // libraries, but they may be cfg'd away with #[link(cfg(..))].
-            //
-            // This unstable feature, though, only needs liblibc to work. The only
-            // use case there is where musl is statically included in liblibc.rlib,
-            // so if we don't want the included version we just need to skip it. As
-            // a result the logic here is that if *any* linked library is cfg'd away
-            // we just skip all object files.
-            //
-            // Clearly this is not sufficient for a general purpose feature, and
-            // we'd want to read from the library's metadata to determine which
-            // object files come from where and selectively skip them.
-            let skip_object_files = native_libs.iter().any(|lib| {
-                matches!(lib.kind, NativeLibKind::Static { bundle: None | Some(true), .. })
-                    && !relevant_lib(sess, lib)
-            });
-
             let lto = are_upstream_rust_objects_already_included(sess)
                 && !ignored_for_lto(sess, &codegen_results.crate_info, cnum);
 
-            // Ignoring obj file starting with the crate name
-            // as simple comparison is not enough - there
-            // might be also an extra name suffix
-            let obj_start = name.as_str().to_owned();
+            let native_libs = codegen_results.crate_info.native_libraries[&cnum].iter();
+            let relevant = native_libs.clone().filter(|lib| relevant_lib(sess, &lib));
+            let relevant_libs: FxHashSet<_> = relevant.filter_map(|lib| lib.filename).collect();
 
+            let bundled_libs: FxHashSet<_> = native_libs.filter_map(|lib| lib.filename).collect();
             ab.add_archive(
                 path,
                 Box::new(move |fname: &str| {
@@ -559,20 +515,25 @@ fn link_staticlib<'a>(
                         return true;
                     }
 
-                    // Otherwise if this is *not* a rust object and we're skipping
-                    // objects then skip this file
-                    if skip_object_files
-                        && (!fname.starts_with(&obj_start) || !fname.ends_with(".o"))
-                    {
+                    // Skip objects for bundled libs.
+                    if bundled_libs.contains(&Symbol::intern(fname)) {
                         return true;
                     }
 
-                    // ok, don't skip this
                     false
                 }),
             )
             .unwrap();
 
+            archive_builder_builder
+                .extract_bundled_libs(path, tempdir.as_ref(), &relevant_libs)
+                .unwrap_or_else(|e| sess.emit_fatal(e));
+            for filename in relevant_libs {
+                let joined = tempdir.as_ref().join(filename.as_str());
+                let path = joined.as_path();
+                ab.add_archive(path, Box::new(|_| false)).unwrap();
+            }
+
             all_native_libs
                 .extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned());
         },
@@ -2590,18 +2551,8 @@ fn add_static_crate<'a>(
         cmd.link_rlib(&fix_windows_verbatim_for_gcc(path));
     };
 
-    // See the comment above in `link_staticlib` and `link_rlib` for why if
-    // there's a static library that's not relevant we skip all object
-    // files.
-    let native_libs = &codegen_results.crate_info.native_libraries[&cnum];
-    let skip_native = native_libs.iter().any(|lib| {
-        matches!(lib.kind, NativeLibKind::Static { bundle: None | Some(true), .. })
-            && !relevant_lib(sess, lib)
-    });
-
-    if (!are_upstream_rust_objects_already_included(sess)
-        || ignored_for_lto(sess, &codegen_results.crate_info, cnum))
-        && !skip_native
+    if !are_upstream_rust_objects_already_included(sess)
+        || ignored_for_lto(sess, &codegen_results.crate_info, cnum)
     {
         link_upstream(cratepath);
         return;
@@ -2632,17 +2583,13 @@ fn add_static_crate<'a>(
                 let is_rust_object =
                     canonical.starts_with(&canonical_name) && looks_like_rust_object_file(&f);
 
-                // If we've been requested to skip all native object files
-                // (those not generated by the rust compiler) then we can skip
-                // this file. See above for why we may want to do this.
-                let skip_because_cfg_say_so = skip_native && !is_rust_object;
-
                 // If we're performing LTO and this is a rust-generated object
                 // file, then we don't need the object file as it's part of the
                 // LTO module. Note that `#![no_builtins]` is excluded from LTO,
                 // though, so we let that object file slide.
-                let skip_because_lto =
-                    upstream_rust_objects_already_included && is_rust_object && is_builtins;
+                if upstream_rust_objects_already_included && is_rust_object && is_builtins {
+                    return true;
+                }
 
                 // We skip native libraries because:
                 // 1. This native libraries won't be used from the generated rlib,
@@ -2653,10 +2600,6 @@ fn add_static_crate<'a>(
                     return true;
                 }
 
-                if skip_because_cfg_say_so || skip_because_lto {
-                    return true;
-                }
-
                 false
             }),
         ) {
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 02b502d948c..de2727c8a5d 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -858,6 +858,7 @@ impl CrateInfo {
             dependency_formats: tcx.dependency_formats(()).clone(),
             windows_subsystem,
             natvis_debugger_visualizers: Default::default(),
+            feature_packed_bundled_libs: tcx.features().packed_bundled_libs,
         };
         let crates = tcx.crates(());
 
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 0e6596d4ba7..d5530c47680 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -159,6 +159,7 @@ pub struct CrateInfo {
     pub dependency_formats: Lrc<Dependencies>,
     pub windows_subsystem: Option<String>,
     pub natvis_debugger_visualizers: BTreeSet<DebuggerVisualizerFile>,
+    pub feature_packed_bundled_libs: bool, // unstable feature flag.
 }
 
 #[derive(Encodable, Decodable)]
diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
index 4924105128d..8fe5f8d50ab 100644
--- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
@@ -22,7 +22,7 @@ codegen_ssa_ignoring_output = ignoring -o because multiple .{$extension} files w
 
 codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error}
 
-codegen_ssa_incompatible_linking_modifiers = the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs
+codegen_ssa_incompatible_linking_modifiers = link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs
 
 codegen_ssa_add_native_library = failed to add native library {$library_path}: {$error}
 
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 323f5a368fc..21d211eefbe 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -164,6 +164,8 @@ declare_features! (
     (active, multiple_supertrait_upcastable, "CURRENT_RUSTC_VERSION", None, None),
     /// Allows using `#[omit_gdb_pretty_printer_section]`.
     (active, omit_gdb_pretty_printer_section, "1.5.0", None, None),
+    /// Allows using `+bundled,+whole-archive` native libs.
+    (active, packed_bundled_libs, "1.67.0", None, None),
     /// Allows using `#[prelude_import]` on glob `use` items.
     (active, prelude_import, "1.2.0", None, None),
     /// Used to identify crates that contain the profiler runtime.
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index e263fc74835..a8514c69d1c 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -49,20 +49,21 @@ fn find_bundled_library(
     name: Option<Symbol>,
     verbatim: Option<bool>,
     kind: NativeLibKind,
+    has_cfg: bool,
     sess: &Session,
 ) -> Option<Symbol> {
-    if sess.opts.unstable_opts.packed_bundled_libs &&
-            sess.crate_types().iter().any(|ct| ct == &CrateType::Rlib || ct == &CrateType::Staticlib) &&
-            let NativeLibKind::Static { bundle: Some(true) | None, .. } = kind {
-        find_native_static_library(
-            name.unwrap().as_str(),
-            verbatim.unwrap_or(false),
-            &sess.target_filesearch(PathKind::Native).search_path_dirs(),
-            sess,
-        ).file_name().and_then(|s| s.to_str()).map(Symbol::intern)
-    } else {
-        None
+    if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive } = kind
+        && sess.crate_types().iter().any(|t| matches!(t, &CrateType::Rlib | CrateType::Staticlib))
+        && (sess.opts.unstable_opts.packed_bundled_libs || has_cfg || whole_archive == Some(true))
+    {
+        let verbatim = verbatim.unwrap_or(false);
+        let search_paths = &sess.target_filesearch(PathKind::Native).search_path_dirs();
+        return find_native_static_library(name.unwrap().as_str(), verbatim, search_paths, sess)
+            .file_name()
+            .and_then(|s| s.to_str())
+            .map(Symbol::intern);
     }
+    None
 }
 
 pub(crate) fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLib> {
@@ -385,7 +386,7 @@ impl<'tcx> Collector<'tcx> {
 
             let name = name.map(|(name, _)| name);
             let kind = kind.unwrap_or(NativeLibKind::Unspecified);
-            let filename = find_bundled_library(name, verbatim, kind, sess);
+            let filename = find_bundled_library(name, verbatim, kind, cfg.is_some(), sess);
             self.libs.push(NativeLib {
                 name,
                 filename,
@@ -475,7 +476,7 @@ impl<'tcx> Collector<'tcx> {
                 let name = Some(Symbol::intern(new_name.unwrap_or(&passed_lib.name)));
                 let sess = self.tcx.sess;
                 let filename =
-                    find_bundled_library(name, passed_lib.verbatim, passed_lib.kind, sess);
+                    find_bundled_library(name, passed_lib.verbatim, passed_lib.kind, false, sess);
                 self.libs.push(NativeLib {
                     name,
                     filename,
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index f1119214be4..1933360f722 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1049,6 +1049,7 @@ symbols! {
         overlapping_marker_traits,
         owned_box,
         packed,
+        packed_bundled_libs,
         panic,
         panic_2015,
         panic_2021,
diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile b/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile
new file mode 100644
index 00000000000..62dc1b5f606
--- /dev/null
+++ b/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile
@@ -0,0 +1,35 @@
+-include ../../run-make-fulldeps/tools.mk
+
+# ignore-cross-compile
+# only-linux
+
+# Make sure -Zpacked_bundled_libs-like behavior activates with whole-archive.
+
+# We're using the llvm-nm instead of the system nm to ensure it is compatible
+# with the LLVM bitcode generated by rustc.
+NM = "$(LLVM_BIN_DIR)"/llvm-nm
+
+all: $(call NATIVE_STATICLIB,native_dep_1) $(call NATIVE_STATICLIB,native_dep_2) $(call NATIVE_STATICLIB,native_dep_3) $(call NATIVE_STATICLIB,native_dep_4)
+	# test cfg with packed bundle
+	$(RUSTC) rust_dep_cfg.rs --crate-type=rlib -Zpacked_bundled_libs
+	$(RUSTC) main.rs --extern rust_dep=$(TMPDIR)/librust_dep_cfg.rlib --crate-type=staticlib --cfg should_add
+	$(AR) t $(TMPDIR)/librust_dep_cfg.rlib | $(CGREP) -e "libnative_dep_1.a"
+	$(AR) t $(TMPDIR)/librust_dep_cfg.rlib | $(CGREP) -e "libnative_dep_2.a"
+	$(AR) t $(TMPDIR)/libmain.a | $(CGREP) -e "libnative_dep_1.o"
+	$(AR) t $(TMPDIR)/libmain.a | $(CGREP) -ev "libnative_dep_2.o"
+
+
+	# test bundle with whole_archive
+	$(RUSTC) rust_dep.rs --crate-type=rlib
+	$(AR) t $(TMPDIR)/librust_dep.rlib | $(CGREP) -e "native_dep_1"
+	$(AR) t $(TMPDIR)/librust_dep.rlib | $(CGREP) -e "native_dep_3"
+	$(AR) t $(TMPDIR)/librust_dep.rlib | $(CGREP) -ev "native_dep_2"
+	$(AR) t $(TMPDIR)/librust_dep.rlib | $(CGREP) -ev "native_dep_4"
+
+	# Make sure compiler doesn't use files, that it shouldn't know about.
+	rm $(TMPDIR)/libnative_dep_1.a
+	rm $(TMPDIR)/libnative_dep_3.a
+
+	$(RUSTC) main.rs --extern rust_dep=$(TMPDIR)/librust_dep.rlib --print link-args > $(TMPDIR)/link_args
+	cat $(TMPDIR)/link_args | $(CGREP) -ev "native_dep_3"
+	cat $(TMPDIR)/link_args | $(CGREP) -e "--whole-archive.*native_dep_1.*--whole-archive.*lnative_dep_2.*no-whole-archive.*lnative_dep_4"
diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/main.rs b/tests/run-make/rlib-format-packed-bundled-libs-3/main.rs
new file mode 100644
index 00000000000..8d2b8a2859c
--- /dev/null
+++ b/tests/run-make/rlib-format-packed-bundled-libs-3/main.rs
@@ -0,0 +1,5 @@
+extern crate rust_dep;
+
+pub fn main() {
+    rust_dep::rust_dep();
+}
diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_1.c b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_1.c
new file mode 100644
index 00000000000..07be8562c92
--- /dev/null
+++ b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_1.c
@@ -0,0 +1 @@
+int native_f1() { return 1; }
diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_2.c b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_2.c
new file mode 100644
index 00000000000..a1b94e40dc0
--- /dev/null
+++ b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_2.c
@@ -0,0 +1 @@
+int native_f2() { return 2; }
diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_3.c b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_3.c
new file mode 100644
index 00000000000..f81f397a4b1
--- /dev/null
+++ b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_3.c
@@ -0,0 +1 @@
+int native_f3() { return 3; }
diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_4.c b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_4.c
new file mode 100644
index 00000000000..14d41d60b1f
--- /dev/null
+++ b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_4.c
@@ -0,0 +1 @@
+int native_f4() { return 4; }
diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs b/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs
new file mode 100644
index 00000000000..abd846b6862
--- /dev/null
+++ b/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs
@@ -0,0 +1,16 @@
+#![feature(packed_bundled_libs)]
+
+#[link(name = "native_dep_1", kind = "static", modifiers = "+whole-archive,+bundle")]
+extern "C" {}
+
+#[link(name = "native_dep_2", kind = "static", modifiers = "+whole-archive,-bundle")]
+extern "C" {}
+
+#[link(name = "native_dep_3", kind = "static", modifiers = "+bundle")]
+extern "C" {}
+
+#[link(name = "native_dep_4", kind = "static", modifiers = "-bundle")]
+extern "C" {}
+
+#[no_mangle]
+pub fn rust_dep() {}
diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep_cfg.rs b/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep_cfg.rs
new file mode 100644
index 00000000000..506ca62a8a6
--- /dev/null
+++ b/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep_cfg.rs
@@ -0,0 +1,10 @@
+#![feature(link_cfg)]
+
+#[link(name = "native_dep_1", kind = "static", cfg(should_add))]
+extern "C" {}
+
+#[link(name = "native_dep_2", kind = "static", cfg(should_not_add))]
+extern "C" {}
+
+#[no_mangle]
+pub fn rust_dep() {}
diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs
index 066048795c8..0ccd441cc64 100644
--- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs
+++ b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs
@@ -1,8 +1,11 @@
-// compile-flags: -Zunstable-options --crate-type rlib
+// gate-test-packed_bundled_libs
+
+// ignore-wasm32-bare
+// compile-flags: --crate-type rlib
+// error-pattern: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs
 // build-fail
-// error-pattern: the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs
 
-#[link(name = "mylib", kind = "static", modifiers = "+bundle,+whole-archive")]
-extern "C" { }
+#[link(name = "rust_test_helpers", kind = "static", modifiers = "+bundle,+whole-archive")]
+extern "C" {}
 
-fn main() { }
+fn main() {}
diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr
index 246efb8d627..8a9fed740b0 100644
--- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr
+++ b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr
@@ -1,6 +1,4 @@
-error: the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs
+error: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs
 
-error: could not find native static library `mylib`, perhaps an -L flag is missing?
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs
index 1d0768d99cf..18d4b52a34c 100644
--- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs
+++ b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs
@@ -1,7 +1,8 @@
-// Mixing +bundle and +whole-archive is not allowed
+// gate-test-packed_bundled_libs
 
-// compile-flags: -l static:+bundle,+whole-archive=mylib -Zunstable-options --crate-type rlib
+// ignore-wasm32-bare
+// compile-flags: -l static:+bundle,+whole-archive=rust_test_helpers --crate-type rlib
+// error-pattern: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs
 // build-fail
-// error-pattern: the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs
 
-fn main() { }
+fn main() {}
diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr
index 246efb8d627..8a9fed740b0 100644
--- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr
+++ b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr
@@ -1,6 +1,4 @@
-error: the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs
+error: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs
 
-error: could not find native static library `mylib`, perhaps an -L flag is missing?
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error