From 7f42d81ea489c53a93f4d2b6e59b8ddeb4ee749a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 5 Apr 2020 17:31:29 +0300 Subject: [PATCH] linker: Factor out addition of pre-, post- and late link args --- src/librustc_codegen_ssa/back/link.rs | 117 ++++++++++++++++++-------- 1 file changed, 82 insertions(+), 35 deletions(-) diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 7f2020f98024..39355baebee7 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -1189,6 +1189,74 @@ fn add_post_link_objects(cmd: &mut dyn Linker, sess: &'a Session, crate_type: co } } +/// Add arbitrary "pre-link" args defined by the target spec or from command line. +/// FIXME: Determine where exactly these args need to be inserted. +fn add_pre_link_args( + cmd: &mut dyn Linker, + sess: &'a Session, + flavor: LinkerFlavor, + crate_type: config::CrateType, +) { + if let Some(args) = sess.target.target.options.pre_link_args.get(&flavor) { + cmd.args(args); + } + if let Some(args) = sess.target.target.options.pre_link_args_crt.get(&flavor) { + if sess.crt_static(Some(crate_type)) { + cmd.args(args); + } + } + cmd.args(&sess.opts.debugging_opts.pre_link_args); +} + +/// Add arbitrary "user defined" args defined from command line and by `#[link_args]` attributes. +/// FIXME: Determine where exactly these args need to be inserted. +fn add_user_defined_link_args( + cmd: &mut dyn Linker, + sess: &'a Session, + codegen_results: &CodegenResults, +) { + cmd.args(&sess.opts.cg.link_args); + cmd.args(&*codegen_results.crate_info.link_args); +} + +/// Add arbitrary "late link" args defined by the target spec. +/// FIXME: Determine where exactly these args need to be inserted. +fn add_late_link_args( + cmd: &mut dyn Linker, + sess: &'a Session, + flavor: LinkerFlavor, + crate_type: config::CrateType, + codegen_results: &CodegenResults, +) { + if let Some(args) = sess.target.target.options.late_link_args.get(&flavor) { + cmd.args(args); + } + 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) + }); + 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); + } + } +} + +/// Add arbitrary "post-link" args defined by the target spec. +/// FIXME: Determine where exactly these args need to be inserted. +fn add_post_link_args(cmd: &mut dyn Linker, sess: &'a Session, flavor: LinkerFlavor) { + if let Some(args) = sess.target.target.options.post_link_args.get(&flavor) { + cmd.args(args); + } +} + +/// Produce the linker command line containing linker path and arguments. +/// `NO-OPT-OUT` marks the arguments that cannot be removed from the command line +/// by the user without creating a custom target specification. fn linker_with_args<'a, B: ArchiveBuilder<'a>>( path: &Path, flavor: LinkerFlavor, @@ -1205,15 +1273,8 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( assert!(base_cmd.get_args().is_empty() || sess.target.target.target_vendor == "uwp"); let cmd = &mut *codegen_results.linker_info.to_linker(base_cmd, &sess, flavor, target_cpu); - if let Some(args) = sess.target.target.options.pre_link_args.get(&flavor) { - cmd.args(args); - } - if let Some(args) = sess.target.target.options.pre_link_args_crt.get(&flavor) { - if sess.crt_static(Some(crate_type)) { - cmd.args(args); - } - } - cmd.args(&sess.opts.debugging_opts.pre_link_args); + // NO-OPT-OUT + add_pre_link_args(cmd, sess, flavor, crate_type); if sess.target.target.options.is_like_fuchsia { let prefix = match sess.opts.debugging_opts.sanitizer { @@ -1294,16 +1355,19 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( cmd.gc_sections(keep_metadata); } - let attr_link_args = codegen_results.crate_info.link_args.iter(); - let user_link_args = sess.opts.cg.link_args.iter().chain(attr_link_args); - if crate_type == config::CrateType::Executable { let mut position_independent_executable = false; if t.options.position_independent_executables { if is_pic(sess) && !sess.crt_static(Some(crate_type)) - && !user_link_args.clone().any(|x| x == "-static") + && !sess + .opts + .cg + .link_args + .iter() + .chain(&*codegen_results.crate_info.link_args) + .any(|x| x == "-static") { position_independent_executable = true; } @@ -1432,35 +1496,18 @@ fn linker_with_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 - cmd.args(user_link_args); + add_user_defined_link_args(cmd, sess, codegen_results); cmd.finalize(); - if let Some(args) = sess.target.target.options.late_link_args.get(&flavor) { - cmd.args(args); - } - 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) - }); - 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); - } - } + // NO-OPT-OUT + add_late_link_args(cmd, sess, flavor, crate_type, codegen_results); // NO-OPT-OUT add_post_link_objects(cmd, sess, crate_type); - if let Some(args) = sess.target.target.options.post_link_args.get(&flavor) { - cmd.args(args); - } + // NO-OPT-OUT + add_post_link_args(cmd, sess, flavor); cmd.take_cmd() }