Link to libgcc dynamically on windows-gnu when using dylib crates
This commit is contained in:
parent
1c950e5c6f
commit
8e3467c215
@ -490,6 +490,11 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
|
||||
info!("preparing {:?} to {:?}", crate_type, out_filename);
|
||||
let (linker, flavor) = linker_and_flavor(sess);
|
||||
|
||||
let any_dynamic_crate = crate_type == config::CrateType::Dylib
|
||||
|| codegen_results.crate_info.dependency_formats.iter().any(|(ty, list)| {
|
||||
*ty == crate_type && list.iter().any(|&linkage| linkage == Linkage::Dynamic)
|
||||
});
|
||||
|
||||
// The invocations of cc share some flags across platforms
|
||||
let (pname, mut cmd) = get_linker(sess, &linker, flavor);
|
||||
|
||||
@ -555,6 +560,15 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
|
||||
if let Some(args) = sess.target.target.options.late_link_args.get(&flavor) {
|
||||
cmd.args(args);
|
||||
}
|
||||
if any_dynamic_crate {
|
||||
if let Some(args) = sess.target.target.options.late_link_args_dynamic.get(&flavor) {
|
||||
cmd.args(args);
|
||||
}
|
||||
} else {
|
||||
if let Some(args) = sess.target.target.options.late_link_args_static.get(&flavor) {
|
||||
cmd.args(args);
|
||||
}
|
||||
}
|
||||
for obj in &sess.target.target.options.post_link_objects {
|
||||
cmd.arg(get_file_path(sess, obj));
|
||||
}
|
||||
|
@ -579,6 +579,12 @@ pub struct TargetOptions {
|
||||
/// user-defined but before post_link_objects. Standard platform
|
||||
/// libraries that should be always be linked to, usually go here.
|
||||
pub late_link_args: LinkArgs,
|
||||
/// Linker arguments used in addition to `late_link_args` if at least one
|
||||
/// Rust dependency is dynamically linked.
|
||||
pub late_link_args_dynamic: LinkArgs,
|
||||
/// Linker arguments used in addition to `late_link_args` if aall Rust
|
||||
/// dependencies are statically linked.
|
||||
pub late_link_args_static: LinkArgs,
|
||||
/// Objects to link after all others, always found within the
|
||||
/// sysroot folder.
|
||||
pub post_link_objects: Vec<String>, // ... unconditionally
|
||||
@ -858,6 +864,8 @@ impl Default for TargetOptions {
|
||||
post_link_objects: Vec::new(),
|
||||
post_link_objects_crt: Vec::new(),
|
||||
late_link_args: LinkArgs::new(),
|
||||
late_link_args_dynamic: LinkArgs::new(),
|
||||
late_link_args_static: LinkArgs::new(),
|
||||
link_env: Vec::new(),
|
||||
link_env_remove: Vec::new(),
|
||||
archive_format: "gnu".to_string(),
|
||||
@ -1136,6 +1144,8 @@ impl Target {
|
||||
key!(pre_link_objects_exe_crt, list);
|
||||
key!(pre_link_objects_dll, list);
|
||||
key!(late_link_args, link_args);
|
||||
key!(late_link_args_dynamic, link_args);
|
||||
key!(late_link_args_static, link_args);
|
||||
key!(post_link_objects, list);
|
||||
key!(post_link_objects_crt, list);
|
||||
key!(post_link_args, link_args);
|
||||
@ -1363,6 +1373,8 @@ impl ToJson for Target {
|
||||
target_option_val!(pre_link_objects_exe_crt);
|
||||
target_option_val!(pre_link_objects_dll);
|
||||
target_option_val!(link_args - late_link_args);
|
||||
target_option_val!(link_args - late_link_args_dynamic);
|
||||
target_option_val!(link_args - late_link_args_static);
|
||||
target_option_val!(post_link_objects);
|
||||
target_option_val!(post_link_objects_crt);
|
||||
target_option_val!(link_args - post_link_args);
|
||||
|
@ -17,12 +17,13 @@ pub fn opts() -> TargetOptions {
|
||||
);
|
||||
|
||||
let mut late_link_args = LinkArgs::new();
|
||||
let mut late_link_args_dynamic = LinkArgs::new();
|
||||
let mut late_link_args_static = LinkArgs::new();
|
||||
late_link_args.insert(
|
||||
LinkerFlavor::Gcc,
|
||||
vec![
|
||||
"-lmingwex".to_string(),
|
||||
"-lmingw32".to_string(),
|
||||
"-lgcc".to_string(), // alas, mingw* libraries above depend on libgcc
|
||||
"-lmsvcrt".to_string(),
|
||||
// mingw's msvcrt is a weird hybrid import library and static library.
|
||||
// And it seems that the linker fails to use import symbols from msvcrt
|
||||
@ -37,6 +38,31 @@ pub fn opts() -> TargetOptions {
|
||||
"-lkernel32".to_string(),
|
||||
],
|
||||
);
|
||||
late_link_args_dynamic.insert(
|
||||
LinkerFlavor::Gcc,
|
||||
vec![
|
||||
// If any of our crates are dynamically linked then we need to use
|
||||
// the shared libgcc_s-dw2-1.dll. This is required to support
|
||||
// unwinding across DLL boundaries.
|
||||
"-lgcc_s".to_string(),
|
||||
"-lgcc".to_string(),
|
||||
"-lkernel32".to_string(),
|
||||
],
|
||||
);
|
||||
late_link_args_static.insert(
|
||||
LinkerFlavor::Gcc,
|
||||
vec![
|
||||
// If all of our crates are statically linked then we can get away
|
||||
// with statically linking the libgcc unwinding code. This allows
|
||||
// binaries to be redistributed without the libgcc_s-dw2-1.dll
|
||||
// dependency, but unfortunately break unwinding across DLL
|
||||
// boundaries when unwinding across FFI boundaries.
|
||||
"-lgcc".to_string(),
|
||||
"-lgcc_eh".to_string(),
|
||||
"-lpthread".to_string(),
|
||||
"-lkernel32".to_string(),
|
||||
],
|
||||
);
|
||||
|
||||
TargetOptions {
|
||||
// FIXME(#13846) this should be enabled for windows
|
||||
@ -63,8 +89,9 @@ pub fn opts() -> TargetOptions {
|
||||
"rsbegin.o".to_string(),
|
||||
],
|
||||
late_link_args,
|
||||
late_link_args_dynamic,
|
||||
late_link_args_static,
|
||||
post_link_objects: vec!["rsend.o".to_string()],
|
||||
custom_unwind_resume: true,
|
||||
abi_return_struct_as_int: true,
|
||||
emit_debug_gdb_scripts: false,
|
||||
requires_uwtable: true,
|
||||
|
@ -33,8 +33,13 @@ fn main() {
|
||||
} else if target.contains("dragonfly") {
|
||||
println!("cargo:rustc-link-lib=gcc_pic");
|
||||
} else if target.contains("pc-windows-gnu") {
|
||||
println!("cargo:rustc-link-lib=static-nobundle=gcc_eh");
|
||||
println!("cargo:rustc-link-lib=static-nobundle=pthread");
|
||||
// This is handled in the target spec with late_link_args_[static|dynamic]
|
||||
|
||||
// cfg!(bootstrap) doesn't work in build scripts
|
||||
if env::var("RUSTC_STAGE").ok() == Some("0".to_string()) {
|
||||
println!("cargo:rustc-link-lib=static-nobundle=gcc_eh");
|
||||
println!("cargo:rustc-link-lib=static-nobundle=pthread");
|
||||
}
|
||||
} else if target.contains("uwp-windows-gnu") {
|
||||
println!("cargo:rustc-link-lib=unwind");
|
||||
} else if target.contains("fuchsia") {
|
||||
|
Loading…
x
Reference in New Issue
Block a user