about summary refs log tree commit diff
path: root/src/librustc_codegen_ssa/back
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2020-06-25 18:00:03 -0700
committerGitHub <noreply@github.com>2020-06-25 18:00:03 -0700
commit9275ff7b218d6aacea649425bf1b603c6f78d578 (patch)
tree2594c9b311a9706c973e570e2dd693b1356620cf /src/librustc_codegen_ssa/back
parent5158b3c9989a1872fae0cb72e5cd0b5228cf12c0 (diff)
parentf27dcd7ee05e948c92fb7e742d6b26c34e20b39c (diff)
downloadrust-9275ff7b218d6aacea649425bf1b603c6f78d578.tar.gz
rust-9275ff7b218d6aacea649425bf1b603c6f78d578.zip
Rollup merge of #72738 - mati865:self-contained-option, r=petrochenkov
Self contained linking option

With objects moved to self-contained directory by https://github.com/rust-lang/rust/pull/72999 we can now add option to control whether to use self-contained on native linkage mode.
Diffstat (limited to 'src/librustc_codegen_ssa/back')
-rw-r--r--src/librustc_codegen_ssa/back/link.rs80
1 files changed, 54 insertions, 26 deletions
diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index 6c995be913c..a3402941078 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 {
@@ -551,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).into_os_string())
+                    .map(|obj| get_object_file_path(sess, obj, self_contained).into_os_string())
                     .collect::<Vec<_>>()
             };
             let pre_objects_static_pie = get_objects(pre_objects, LinkOutputKind::StaticPicExe);
@@ -1066,9 +1077,11 @@ fn get_crt_libs_path(sess: &Session) -> Option<PathBuf> {
     }
 }
 
-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 +1094,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_self_contained_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 +1284,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.
@@ -1287,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));
+        cmd.add_object(&get_object_file_path(sess, obj, self_contained));
     }
 }
 
@@ -1301,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));
+        cmd.add_object(&get_object_file_path(sess, obj, self_contained));
     }
 }
 
@@ -1468,9 +1490,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 +1506,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_self_contained_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 +1573,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 +1625,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);