|
| 1 | +// This test case makes sure that native libraries are linked with appropriate semantics |
| 2 | +// when the `[+-]bundle,[+-]whole-archive` modifiers are applied to them. |
| 3 | +// The test works by checking that the resulting executables produce the expected output, |
| 4 | +// part of which is emitted by otherwise unreferenced C code. If +whole-archive didn't work |
| 5 | +// that code would never make it into the final executable and we'd thus be missing some |
| 6 | +// of the output. |
| 7 | +// See https://github.com/rust-lang/rust/issues/88085 |
| 8 | + |
| 9 | +//@ ignore-cross-compile |
| 10 | +// Reason: compiling C++ code does not work well when cross-compiling |
| 11 | +// plus, the compiled binary is executed |
| 12 | + |
| 13 | +use run_make_support::{cxx, is_msvc, llvm_ar, run, run_with_args, rustc, static_lib_name}; |
| 14 | + |
| 15 | +fn main() { |
| 16 | + let mut cxx = cxx(); |
| 17 | + if is_msvc() { |
| 18 | + cxx.arg("-EHs"); |
| 19 | + } |
| 20 | + cxx.input("c_static_lib_with_constructor.cpp") |
| 21 | + .arg("-c") |
| 22 | + .out_exe("libc_static_lib_with_constructor") |
| 23 | + .run(); |
| 24 | + |
| 25 | + let mut llvm_ar = llvm_ar(); |
| 26 | + llvm_ar.obj_to_ar(); |
| 27 | + if is_msvc() { |
| 28 | + llvm_ar |
| 29 | + .output_input( |
| 30 | + static_lib_name("c_static_lib_with_constructor"), |
| 31 | + "libc_static_lib_with_constructor.obj", |
| 32 | + ) |
| 33 | + .run(); |
| 34 | + } else { |
| 35 | + llvm_ar |
| 36 | + .output_input( |
| 37 | + static_lib_name("c_static_lib_with_constructor"), |
| 38 | + "libc_static_lib_with_constructor", |
| 39 | + ) |
| 40 | + .run(); |
| 41 | + } |
| 42 | + |
| 43 | + // Native lib linked directly into executable |
| 44 | + rustc() |
| 45 | + .input("directly_linked.rs") |
| 46 | + .arg("-lstatic:+whole-archive=c_static_lib_with_constructor") |
| 47 | + .run(); |
| 48 | + |
| 49 | + // Native lib linked into test executable, +whole-archive |
| 50 | + rustc() |
| 51 | + .input("directly_linked_test_plus_whole_archive.rs") |
| 52 | + .arg("--test") |
| 53 | + .arg("-lstatic:+whole-archive=c_static_lib_with_constructor") |
| 54 | + .run(); |
| 55 | + |
| 56 | + // Native lib linked into test executable, -whole-archive |
| 57 | + rustc() |
| 58 | + .input("directly_linked_test_minus_whole_archive.rs") |
| 59 | + .arg("--test") |
| 60 | + .arg("-lstatic:-whole-archive=c_static_lib_with_constructor") |
| 61 | + .run(); |
| 62 | + |
| 63 | + // Native lib linked into rlib with via commandline |
| 64 | + rustc() |
| 65 | + .input("rlib_with_cmdline_native_lib.rs") |
| 66 | + .crate_type("rlib") |
| 67 | + .arg("-lstatic:-bundle,+whole-archive=c_static_lib_with_constructor") |
| 68 | + .run(); |
| 69 | + // Native lib linked into RLIB via `-l static:-bundle,+whole-archive` |
| 70 | + // RLIB linked into executable |
| 71 | + rustc().input("indirectly_linked.rs").run(); |
| 72 | + |
| 73 | + // Native lib linked into rlib via `#[link()]` attribute on extern block. |
| 74 | + rustc().input("native_lib_in_src.rs").crate_type("rlib").run(); |
| 75 | + // Native lib linked into RLIB via #[link] attribute, RLIB linked into executable |
| 76 | + rustc().input("indirectly_linked_via_attr.rs").run(); |
| 77 | + |
| 78 | + run("directly_linked").assert_stdout_contains("static-initializer.directly_linked."); |
| 79 | + run_with_args("directly_linked_test_plus_whole_archive", &["--nocapture"]) |
| 80 | + .assert_stdout_contains("static-initializer."); |
| 81 | + run_with_args("directly_linked_test_minus_whole_archive", &["--nocapture"]) |
| 82 | + .assert_stdout_not_contains("static-initializer."); |
| 83 | + run("indirectly_linked").assert_stdout_contains("static-initializer.indirectly_linked."); |
| 84 | + run("indirectly_linked_via_attr") |
| 85 | + .assert_stdout_contains("static-initializer.native_lib_in_src."); |
| 86 | +} |
0 commit comments