| 
 | 1 | +//! This is a regression test for #129020  | 
 | 2 | +//! It ensures we can use `/WHOLEARCHIVE` to link a rust staticlib into DLL  | 
 | 3 | +//! using the MSVC linker  | 
 | 4 | +
  | 
 | 5 | +//@ only-msvc  | 
 | 6 | +// Reason: this is testing the MSVC linker  | 
 | 7 | + | 
 | 8 | +use std::path::PathBuf;  | 
 | 9 | + | 
 | 10 | +use run_make_support::{cc, cmd, env_var, extra_c_flags, rustc};  | 
 | 11 | + | 
 | 12 | +fn main() {  | 
 | 13 | +    // Build the staticlib  | 
 | 14 | +    rustc().crate_type("staticlib").input("static.rs").output("static.lib").run();  | 
 | 15 | +    // Build an empty object to pass to the linker.  | 
 | 16 | +    cc().input("c.c").output("c.obj").args(["-c"]).run();  | 
 | 17 | + | 
 | 18 | +    // Find the C toolchain's linker.  | 
 | 19 | +    let mut linker = PathBuf::from(env_var("CC"));  | 
 | 20 | +    let linker_flavour = if linker.file_stem().is_some_and(|s| s == "cl") {  | 
 | 21 | +        linker.set_file_name("link.exe");  | 
 | 22 | +        "msvc"  | 
 | 23 | +    } else if linker.file_stem().is_some_and(|s| s == "clang-cl") {  | 
 | 24 | +        linker.set_file_name("lld-link.exe");  | 
 | 25 | +        "llvm"  | 
 | 26 | +    } else {  | 
 | 27 | +        panic!("unknown C toolchain");  | 
 | 28 | +    };  | 
 | 29 | + | 
 | 30 | +    // As a sanity check, make sure this works without /WHOLEARCHIVE.  | 
 | 31 | +    // Otherwise the actual test failure may be caused by something else.  | 
 | 32 | +    cmd(&linker)  | 
 | 33 | +        .args(["c.obj", "./static.lib", "-dll", "-def:dll.def", "-out:dll.dll"])  | 
 | 34 | +        .args(extra_c_flags())  | 
 | 35 | +        .run();  | 
 | 36 | + | 
 | 37 | +    // FIXME(@ChrisDenton): this doesn't currently work with llvm's lld-link for other reasons.  | 
 | 38 | +    // May need LLVM patches.  | 
 | 39 | +    if linker_flavour == "msvc" {  | 
 | 40 | +        // Link in the staticlib using `/WHOLEARCHIVE` and produce a DLL.  | 
 | 41 | +        cmd(&linker)  | 
 | 42 | +            .args([  | 
 | 43 | +                "c.obj",  | 
 | 44 | +                "-WHOLEARCHIVE:./static.lib",  | 
 | 45 | +                "-dll",  | 
 | 46 | +                "-def:dll.def",  | 
 | 47 | +                "-out:dll_whole_archive.dll",  | 
 | 48 | +            ])  | 
 | 49 | +            .args(extra_c_flags())  | 
 | 50 | +            .run();  | 
 | 51 | +    }  | 
 | 52 | +}  | 
0 commit comments