From 2e3f51775a6427f34878c2041be8e0c8d656ea3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Thu, 28 May 2020 19:54:08 +0200 Subject: [PATCH 1/3] Add unstable rustc option to control self-contained linkage mode --- src/librustc_codegen_ssa/back/link.rs | 54 ++++++++++++++++++--------- src/librustc_session/filesearch.rs | 4 +- src/librustc_session/options.rs | 3 ++ 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 6c995be913c9e..ae1e4da753331 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -140,7 +140,12 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>( // The third parameter is for env vars, used on windows to set up the // path for MSVC to find its DLLs, and gcc to find its bundled // toolchain -fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> Command { +fn get_linker( + sess: &Session, + linker: &Path, + flavor: LinkerFlavor, + self_contained: bool, +) -> Command { let msvc_tool = windows_registry::find_tool(&sess.opts.target_triple.triple(), "link.exe"); // If our linker looks like a batch script on Windows then to execute this @@ -199,7 +204,7 @@ fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> Command { // The compiler's sysroot often has some bundled tools, so add it to the // PATH for the child. - let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(); + let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(self_contained); let mut msvc_changed_path = false; if sess.target.target.options.is_like_msvc { if let Some(ref tool) = msvc_tool { @@ -563,7 +568,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( .iter() .copied() .flatten() - .map(|obj| get_object_file_path(sess, obj).into_os_string()) + .map(|obj| get_object_file_path(sess, obj, fallback).into_os_string()) .collect::>() }; let pre_objects_static_pie = get_objects(pre_objects, LinkOutputKind::StaticPicExe); @@ -1066,9 +1071,11 @@ fn get_crt_libs_path(sess: &Session) -> Option { } } -fn get_object_file_path(sess: &Session, name: &str) -> PathBuf { +fn get_object_file_path(sess: &Session, name: &str, self_contained: bool) -> PathBuf { // prefer system {,dll}crt2.o libs, see get_crt_libs_path comment for more details - if sess.target.target.llvm_target.contains("windows-gnu") { + if sess.opts.debugging_opts.link_self_contained.is_none() + && sess.target.target.llvm_target.contains("windows-gnu") + { if let Some(compiler_libs_path) = get_crt_libs_path(sess) { let file_path = compiler_libs_path.join(name); if file_path.exists() { @@ -1081,9 +1088,12 @@ fn get_object_file_path(sess: &Session, name: &str) -> PathBuf { if file_path.exists() { return file_path; } - let file_path = fs.get_selfcontained_lib_path().join(name); - if file_path.exists() { - return file_path; + // Special directory with objects used only in self-contained linkage mode + if self_contained { + let file_path = fs.get_selfcontained_lib_path().join(name); + if file_path.exists() { + return file_path; + } } for search_path in fs.search_paths() { let file_path = search_path.dir.join(name); @@ -1268,6 +1278,10 @@ fn link_output_kind(sess: &Session, crate_type: CrateType) -> LinkOutputKind { /// Whether we link to our own CRT objects instead of relying on gcc to pull them. /// We only provide such support for a very limited number of targets. fn crt_objects_fallback(sess: &Session, crate_type: CrateType) -> bool { + if let Some(self_contained) = sess.opts.debugging_opts.link_self_contained { + return self_contained; + } + match sess.target.target.options.crt_objects_fallback { // FIXME: Find a better heuristic for "native musl toolchain is available", // based on host and linker path, for example. @@ -1292,7 +1306,7 @@ fn add_pre_link_objects( let opts = &sess.target.target.options; let objects = if fallback { &opts.pre_link_objects_fallback } else { &opts.pre_link_objects }; for obj in objects.get(&link_output_kind).iter().copied().flatten() { - cmd.add_object(&get_object_file_path(sess, obj)); + cmd.add_object(&get_object_file_path(sess, obj, fallback)); } } @@ -1306,7 +1320,7 @@ fn add_post_link_objects( let opts = &sess.target.target.options; let objects = if fallback { &opts.post_link_objects_fallback } else { &opts.post_link_objects }; for obj in objects.get(&link_output_kind).iter().copied().flatten() { - cmd.add_object(&get_object_file_path(sess, obj)); + cmd.add_object(&get_object_file_path(sess, obj, fallback)); } } @@ -1468,9 +1482,12 @@ fn link_local_crate_native_libs_and_dependent_crate_libs<'a, B: ArchiveBuilder<' } /// Add sysroot and other globally set directories to the directory search list. -fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session) { +fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session, self_contained: bool) { // Prefer system mingw-w64 libs, see get_crt_libs_path comment for more details. - if cfg!(windows) && sess.target.target.llvm_target.contains("windows-gnu") { + if sess.opts.debugging_opts.link_self_contained.is_none() + && cfg!(windows) + && sess.target.target.llvm_target.contains("windows-gnu") + { if let Some(compiler_libs_path) = get_crt_libs_path(sess) { cmd.include_path(&compiler_libs_path); } @@ -1481,8 +1498,11 @@ fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session) { let lib_path = sess.target_filesearch(PathKind::All).get_lib_path(); cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path)); - let lib_path = sess.target_filesearch(PathKind::All).get_selfcontained_lib_path(); - cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path)); + // Special directory with libraries used only in self-contained linkage mode + if self_contained { + let lib_path = sess.target_filesearch(PathKind::All).get_selfcontained_lib_path(); + cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path)); + } } /// Add options making relocation sections in the produced ELF files read-only @@ -1545,13 +1565,13 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( codegen_results: &CodegenResults, target_cpu: &str, ) -> Command { - let base_cmd = get_linker(sess, path, flavor); + let crt_objects_fallback = crt_objects_fallback(sess, crate_type); + let base_cmd = get_linker(sess, path, flavor, crt_objects_fallback); // FIXME: Move `/LIBPATH` addition for uwp targets from the linker construction // to the linker args construction. 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); let link_output_kind = link_output_kind(sess, crate_type); - let crt_objects_fallback = crt_objects_fallback(sess, crate_type); // NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT add_pre_link_args(cmd, sess, flavor); @@ -1597,7 +1617,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER // FIXME: Order-dependent, at least relatively to other args adding searh directories. - add_library_search_dirs(cmd, sess); + add_library_search_dirs(cmd, sess, crt_objects_fallback); // OBJECT-FILES-YES add_local_crate_regular_objects(cmd, codegen_results); diff --git a/src/librustc_session/filesearch.rs b/src/librustc_session/filesearch.rs index 5586b82b0edc0..675a880cef47c 100644 --- a/src/librustc_session/filesearch.rs +++ b/src/librustc_session/filesearch.rs @@ -92,13 +92,13 @@ impl<'a> FileSearch<'a> { } // Returns a list of directories where target-specific tool binaries are located. - pub fn get_tools_search_paths(&self) -> Vec { + pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec { let mut p = PathBuf::from(self.sysroot); p.push(find_libdir(self.sysroot).as_ref()); p.push(RUST_LIB_DIR); p.push(&self.triple); p.push("bin"); - vec![p.clone(), p.join("self-contained")] + if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p.clone()] } } } diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs index 6c6f27502b614..055ae2fa2b5e5 100644 --- a/src/librustc_session/options.rs +++ b/src/librustc_session/options.rs @@ -888,6 +888,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "keep hygiene data after analysis (default: no)"), link_native_libraries: bool = (true, parse_bool, [UNTRACKED], "link native libraries in the linker invocation (default: yes)"), + link_self_contained: Option = (None, parse_opt_bool, [TRACKED], + "control whether to link Rust provided C objects/libraries or rely + on C toolchain installed in the system"), link_only: bool = (false, parse_bool, [TRACKED], "link the `.rlink` file generated by `-Z no-link` (default: no)"), llvm_time_trace: bool = (false, parse_bool, [UNTRACKED], From 54293c1f157ee83d8e9949a7908e093ae0d5817a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Mon, 22 Jun 2020 19:56:56 +0200 Subject: [PATCH 2/3] Rename get_self_contained_lib_path --- src/librustc_codegen_ssa/back/link.rs | 4 ++-- src/librustc_session/filesearch.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index ae1e4da753331..39f54b83a23bc 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -1090,7 +1090,7 @@ fn get_object_file_path(sess: &Session, name: &str, self_contained: bool) -> Pat } // Special directory with objects used only in self-contained linkage mode if self_contained { - let file_path = fs.get_selfcontained_lib_path().join(name); + let file_path = fs.get_self_contained_lib_path().join(name); if file_path.exists() { return file_path; } @@ -1500,7 +1500,7 @@ fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session, self_contained: // Special directory with libraries used only in self-contained linkage mode if self_contained { - let lib_path = sess.target_filesearch(PathKind::All).get_selfcontained_lib_path(); + let lib_path = sess.target_filesearch(PathKind::All).get_self_contained_lib_path(); cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path)); } } diff --git a/src/librustc_session/filesearch.rs b/src/librustc_session/filesearch.rs index 675a880cef47c..27396c524f4e6 100644 --- a/src/librustc_session/filesearch.rs +++ b/src/librustc_session/filesearch.rs @@ -41,7 +41,7 @@ impl<'a> FileSearch<'a> { make_target_lib_path(self.sysroot, self.triple) } - pub fn get_selfcontained_lib_path(&self) -> PathBuf { + pub fn get_self_contained_lib_path(&self) -> PathBuf { self.get_lib_path().join("self-contained") } From f27dcd7ee05e948c92fb7e742d6b26c34e20b39c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Thu, 25 Jun 2020 11:15:09 +0200 Subject: [PATCH 3/3] Rename remaining `fallback` to `self_contained` --- src/librustc_codegen_ssa/back/link.rs | 32 +++++++++++++++++---------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 39f54b83a23bc..a34029410784a 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -556,19 +556,25 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( "Linker does not support -static-pie command line option. Retrying with -static instead." ); // Mirror `add_(pre,post)_link_objects` to replace CRT objects. - let fallback = crt_objects_fallback(sess, crate_type); + let self_contained = crt_objects_fallback(sess, crate_type); let opts = &sess.target.target.options; - let pre_objects = - if fallback { &opts.pre_link_objects_fallback } else { &opts.pre_link_objects }; - let post_objects = - if fallback { &opts.post_link_objects_fallback } else { &opts.post_link_objects }; + let pre_objects = if self_contained { + &opts.pre_link_objects_fallback + } else { + &opts.pre_link_objects + }; + let post_objects = if self_contained { + &opts.post_link_objects_fallback + } else { + &opts.post_link_objects + }; let get_objects = |objects: &CrtObjects, kind| { objects .get(&kind) .iter() .copied() .flatten() - .map(|obj| get_object_file_path(sess, obj, fallback).into_os_string()) + .map(|obj| get_object_file_path(sess, obj, self_contained).into_os_string()) .collect::>() }; let pre_objects_static_pie = get_objects(pre_objects, LinkOutputKind::StaticPicExe); @@ -1301,12 +1307,13 @@ fn add_pre_link_objects( cmd: &mut dyn Linker, sess: &Session, link_output_kind: LinkOutputKind, - fallback: bool, + self_contained: bool, ) { let opts = &sess.target.target.options; - let objects = if fallback { &opts.pre_link_objects_fallback } else { &opts.pre_link_objects }; + let objects = + if self_contained { &opts.pre_link_objects_fallback } else { &opts.pre_link_objects }; for obj in objects.get(&link_output_kind).iter().copied().flatten() { - cmd.add_object(&get_object_file_path(sess, obj, fallback)); + cmd.add_object(&get_object_file_path(sess, obj, self_contained)); } } @@ -1315,12 +1322,13 @@ fn add_post_link_objects( cmd: &mut dyn Linker, sess: &Session, link_output_kind: LinkOutputKind, - fallback: bool, + self_contained: bool, ) { let opts = &sess.target.target.options; - let objects = if fallback { &opts.post_link_objects_fallback } else { &opts.post_link_objects }; + let objects = + if self_contained { &opts.post_link_objects_fallback } else { &opts.post_link_objects }; for obj in objects.get(&link_output_kind).iter().copied().flatten() { - cmd.add_object(&get_object_file_path(sess, obj, fallback)); + cmd.add_object(&get_object_file_path(sess, obj, self_contained)); } }