diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 1e780c5f86771..74df66ca757a7 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -489,11 +489,6 @@ 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); @@ -556,18 +551,31 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( ); cmd = linker.finalize(); } - if let Some(args) = sess.target.target.options.late_link_args.get(&flavor) { + + // Linker arguments provided on the command line along with any #[link_args] attributes + // found inside the crate and linker arguments provided by the target specification. + if let Some(ref args) = sess.opts.cg.link_args { + cmd.args(args); + } + cmd.args(&sess.opts.cg.link_arg); + cmd.args(codegen_results.crate_info.link_args.iter()); + if let Some(args) = sess.target.target.options.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) { + if 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) + }) + { + if let Some(args) = sess.target.target.options.link_args_dynamic.get(&flavor) { cmd.args(args); } } else { - if let Some(args) = sess.target.target.options.late_link_args_static.get(&flavor) { + if let Some(args) = sess.target.target.options.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)); } @@ -1302,8 +1310,6 @@ fn link_args<'a, B: ArchiveBuilder<'a>>( cmd.gc_sections(keep_metadata); } - let used_link_args = &codegen_results.crate_info.link_args; - if crate_type == config::CrateType::Executable { let mut position_independent_executable = false; @@ -1311,6 +1317,7 @@ fn link_args<'a, B: ArchiveBuilder<'a>>( let empty_vec = Vec::new(); let args = sess.opts.cg.link_args.as_ref().unwrap_or(&empty_vec); let more_args = &sess.opts.cg.link_arg; + let used_link_args = &codegen_results.crate_info.link_args; let mut args = args.iter().chain(more_args.iter()).chain(used_link_args.iter()); if is_pic(sess) && !sess.crt_static(Some(crate_type)) && !args.any(|x| *x == "-static") @@ -1441,14 +1448,6 @@ fn link_args<'a, B: ArchiveBuilder<'a>>( }; cmd.args(&rpath::get_rpath_flags(&mut rpath_config)); } - - // Finally add all the linker arguments provided on the command line along - // with any #[link_args] attributes found inside the crate - if let Some(ref args) = sess.opts.cg.link_args { - cmd.args(args); - } - cmd.args(&sess.opts.cg.link_arg); - cmd.args(&used_link_args); } // # Native library linking diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 1bc2bf12fad9e..26e9b6fdc6d80 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -577,16 +577,16 @@ pub struct TargetOptions { pub pre_link_objects_exe: Vec, // ... when linking an executable, unconditionally pub pre_link_objects_exe_crt: Vec, // ... when linking an executable with a bundled crt pub pre_link_objects_dll: Vec, // ... when linking a dylib - /// Linker arguments that are unconditionally passed after any - /// user-defined but before post_link_objects. Standard platform + /// Linker arguments that are unconditionally passed immediately after any + /// user-defined linker arguments (`-C link-args` and friends). 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 + pub link_args: LinkArgs, + /// Linker arguments used in addition to `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 + pub link_args_dynamic: LinkArgs, + /// Linker arguments used in addition to `link_args` if aall Rust /// dependencies are statically linked. - pub late_link_args_static: LinkArgs, + pub link_args_static: LinkArgs, /// Objects to link after all others, always found within the /// sysroot folder. pub post_link_objects: Vec, // ... unconditionally @@ -857,9 +857,9 @@ impl Default for TargetOptions { pre_link_objects_dll: Vec::new(), 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_args: LinkArgs::new(), + link_args_dynamic: LinkArgs::new(), + link_args_static: LinkArgs::new(), link_env: Vec::new(), link_env_remove: Vec::new(), archive_format: "gnu".to_string(), @@ -1135,9 +1135,9 @@ impl Target { key!(pre_link_objects_exe, list); 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!(link_args, link_args); + key!(link_args_dynamic, link_args); + key!(link_args_static, link_args); key!(post_link_objects, list); key!(post_link_objects_crt, list); key!(post_link_args, link_args); @@ -1362,9 +1362,9 @@ impl ToJson for Target { target_option_val!(pre_link_objects_exe); 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!(link_args - link_args); + target_option_val!(link_args - link_args_dynamic); + target_option_val!(link_args - link_args_static); target_option_val!(post_link_objects); target_option_val!(post_link_objects_crt); target_option_val!(link_args - post_link_args); diff --git a/src/librustc_target/spec/windows_base.rs b/src/librustc_target/spec/windows_base.rs index 5f59ca8a5a311..c5988acef09c2 100644 --- a/src/librustc_target/spec/windows_base.rs +++ b/src/librustc_target/spec/windows_base.rs @@ -16,10 +16,10 @@ 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( + let mut link_args = LinkArgs::new(); + let mut link_args_dynamic = LinkArgs::new(); + let mut link_args_static = LinkArgs::new(); + link_args.insert( LinkerFlavor::Gcc, vec![ "-lmingwex".to_string(), @@ -38,7 +38,7 @@ pub fn opts() -> TargetOptions { "-lkernel32".to_string(), ], ); - late_link_args_dynamic.insert( + link_args_dynamic.insert( LinkerFlavor::Gcc, vec![ // If any of our crates are dynamically linked then we need to use @@ -49,7 +49,7 @@ pub fn opts() -> TargetOptions { "-lkernel32".to_string(), ], ); - late_link_args_static.insert( + link_args_static.insert( LinkerFlavor::Gcc, vec![ // If all of our crates are statically linked then we can get away @@ -90,9 +90,9 @@ pub fn opts() -> TargetOptions { "dllcrt2.o".to_string(), // mingw C runtime initialization for dlls "rsbegin.o".to_string(), ], - late_link_args, - late_link_args_dynamic, - late_link_args_static, + link_args, + link_args_dynamic, + link_args_static, post_link_objects: vec!["rsend.o".to_string()], abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, diff --git a/src/librustc_target/spec/windows_uwp_base.rs b/src/librustc_target/spec/windows_uwp_base.rs index 3f7eb442bbc73..f16fb352cd40f 100644 --- a/src/librustc_target/spec/windows_uwp_base.rs +++ b/src/librustc_target/spec/windows_uwp_base.rs @@ -14,8 +14,8 @@ pub fn opts() -> TargetOptions { ], ); - let mut late_link_args = LinkArgs::new(); - late_link_args.insert( + let mut link_args = LinkArgs::new(); + link_args.insert( LinkerFlavor::Gcc, vec![ //"-lwinstorecompat".to_string(), @@ -52,7 +52,7 @@ pub fn opts() -> TargetOptions { "rsbegin.o".to_string(), // Rust compiler runtime initialization, see rsbegin.rs ], pre_link_objects_dll: vec!["rsbegin.o".to_string()], - late_link_args, + link_args, post_link_objects: vec!["rsend.o".to_string()], abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs index 0628e5d2fc03a..b61244d659edc 100644 --- a/src/libunwind/build.rs +++ b/src/libunwind/build.rs @@ -33,7 +33,7 @@ fn main() { } else if target.contains("dragonfly") { println!("cargo:rustc-link-lib=gcc_pic"); } else if target.contains("pc-windows-gnu") { - // This is handled in the target spec with late_link_args_[static|dynamic] + // This is handled in the target spec with link_args_[static|dynamic] // cfg!(bootstrap) doesn't work in build scripts if env::var("RUSTC_STAGE").ok() == Some("0".to_string()) {