});
}
-// 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,
- 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
- // we'll need to spawn `cmd` explicitly. This is primarily done to handle
- // emscripten where the linker is `emcc.bat` and needs to be spawned as
- // `cmd /c emcc.bat ...`.
- //
- // This worked historically but is needed manually since #42436 (regression
- // was tagged as #42791) and some more info can be found on #44443 for
- // emscripten itself.
- let mut cmd = match linker.to_str() {
- Some(linker) if cfg!(windows) && linker.ends_with(".bat") => Command::bat_script(linker),
- _ => match flavor {
- LinkerFlavor::Lld(f) => Command::lld(linker, f),
- LinkerFlavor::Msvc if sess.opts.cg.linker.is_none() && sess.target.linker.is_none() => {
- Command::new(msvc_tool.as_ref().map_or(linker, |t| t.path()))
- }
- _ => Command::new(linker),
- },
- };
-
- // UWP apps have API restrictions enforced during Store submissions.
- // To comply with the Windows App Certification Kit,
- // MSVC needs to link with the Store versions of the runtime libraries (vcruntime, msvcrt, etc).
- let t = &sess.target;
- if (flavor == LinkerFlavor::Msvc || flavor == LinkerFlavor::Lld(LldFlavor::Link))
- && t.vendor == "uwp"
- {
- if let Some(ref tool) = msvc_tool {
- let original_path = tool.path();
- if let Some(ref root_lib_path) = original_path.ancestors().nth(4) {
- let arch = match t.arch.as_str() {
- "x86_64" => Some("x64"),
- "x86" => Some("x86"),
- "aarch64" => Some("arm64"),
- "arm" => Some("arm"),
- _ => None,
- };
- if let Some(ref a) = arch {
- // FIXME: Move this to `fn linker_with_args`.
- let mut arg = OsString::from("/LIBPATH:");
- arg.push(format!("{}\\lib\\{}\\store", root_lib_path.display(), a));
- cmd.arg(&arg);
- } else {
- warn!("arch is not supported");
- }
- } else {
- warn!("MSVC root path lib location not found");
- }
- } else {
- warn!("link.exe not found");
- }
- }
-
- // 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(self_contained);
- let mut msvc_changed_path = false;
- if sess.target.is_like_msvc {
- if let Some(ref tool) = msvc_tool {
- cmd.args(tool.args());
- for &(ref k, ref v) in tool.env() {
- if k == "PATH" {
- new_path.extend(env::split_paths(v));
- msvc_changed_path = true;
- } else {
- cmd.env(k, v);
- }
- }
- }
- }
-
- if !msvc_changed_path {
- if let Some(path) = env::var_os("PATH") {
- new_path.extend(env::split_paths(&path));
- }
- }
- cmd.env("PATH", env::join_paths(new_path).unwrap());
-
- cmd
-}
-
pub fn each_linked_rlib(
info: &CrateInfo,
f: &mut dyn FnMut(CrateNum, &Path),
codegen_results: &CodegenResults,
) -> Command {
let crt_objects_fallback = crt_objects_fallback(sess, crate_type);
- let base_cmd = get_linker(sess, path, flavor, crt_objects_fallback);
+ let base_cmd = super::linker::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.vendor == "uwp");
use std::fs::{self, File};
use std::io::prelude::*;
use std::io::{self, BufWriter};
-use std::mem;
use std::path::{Path, PathBuf};
+use std::{env, mem, str};
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_middle::ty::TyCtxt;
use rustc_serialize::{json, Encoder};
use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip};
+use rustc_session::search_paths::PathKind;
use rustc_session::Session;
use rustc_span::symbol::Symbol;
use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor};
+use cc::windows_registry;
+
/// Disables non-English messages from localized linkers.
/// Such messages may cause issues with text encoding on Windows (#35785)
/// and prevent inspection of linker output in case of errors, which we occasionally do.
}
}
+// 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
+pub 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
+ // we'll need to spawn `cmd` explicitly. This is primarily done to handle
+ // emscripten where the linker is `emcc.bat` and needs to be spawned as
+ // `cmd /c emcc.bat ...`.
+ //
+ // This worked historically but is needed manually since #42436 (regression
+ // was tagged as #42791) and some more info can be found on #44443 for
+ // emscripten itself.
+ let mut cmd = match linker.to_str() {
+ Some(linker) if cfg!(windows) && linker.ends_with(".bat") => Command::bat_script(linker),
+ _ => match flavor {
+ LinkerFlavor::Lld(f) => Command::lld(linker, f),
+ LinkerFlavor::Msvc if sess.opts.cg.linker.is_none() && sess.target.linker.is_none() => {
+ Command::new(msvc_tool.as_ref().map_or(linker, |t| t.path()))
+ }
+ _ => Command::new(linker),
+ },
+ };
+
+ // UWP apps have API restrictions enforced during Store submissions.
+ // To comply with the Windows App Certification Kit,
+ // MSVC needs to link with the Store versions of the runtime libraries (vcruntime, msvcrt, etc).
+ let t = &sess.target;
+ if (flavor == LinkerFlavor::Msvc || flavor == LinkerFlavor::Lld(LldFlavor::Link))
+ && t.vendor == "uwp"
+ {
+ if let Some(ref tool) = msvc_tool {
+ let original_path = tool.path();
+ if let Some(ref root_lib_path) = original_path.ancestors().nth(4) {
+ let arch = match t.arch.as_str() {
+ "x86_64" => Some("x64"),
+ "x86" => Some("x86"),
+ "aarch64" => Some("arm64"),
+ "arm" => Some("arm"),
+ _ => None,
+ };
+ if let Some(ref a) = arch {
+ // FIXME: Move this to `fn linker_with_args`.
+ let mut arg = OsString::from("/LIBPATH:");
+ arg.push(format!("{}\\lib\\{}\\store", root_lib_path.display(), a));
+ cmd.arg(&arg);
+ } else {
+ warn!("arch is not supported");
+ }
+ } else {
+ warn!("MSVC root path lib location not found");
+ }
+ } else {
+ warn!("link.exe not found");
+ }
+ }
+
+ // 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(self_contained);
+ let mut msvc_changed_path = false;
+ if sess.target.is_like_msvc {
+ if let Some(ref tool) = msvc_tool {
+ cmd.args(tool.args());
+ for &(ref k, ref v) in tool.env() {
+ if k == "PATH" {
+ new_path.extend(env::split_paths(v));
+ msvc_changed_path = true;
+ } else {
+ cmd.env(k, v);
+ }
+ }
+ }
+ }
+
+ if !msvc_changed_path {
+ if let Some(path) = env::var_os("PATH") {
+ new_path.extend(env::split_paths(&path));
+ }
+ }
+ cmd.env("PATH", env::join_paths(new_path).unwrap());
+
+ cmd
+}
+
/// Linker abstraction used by `back::link` to build up the command to invoke a
/// linker.
///