about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2017-09-13 07:41:58 -0700
committerAlex Crichton <alex@alexcrichton.com>2017-09-13 07:41:58 -0700
commit5cad39163132de69512c770ed06e5432641f2c2d (patch)
tree06c085f1427932f5bf8ca4857d5902830d5e995a
parent824952f48b85806c498d700f183dfc42b516cc7d (diff)
downloadrust-5cad39163132de69512c770ed06e5432641f2c2d.tar.gz
rust-5cad39163132de69512c770ed06e5432641f2c2d.zip
rustc: Spawn `cmd /c emcc.bat` explicitly
In #42436 the behavior for spawning processes on Windows was tweaked slightly to
fix various bugs, but this caused #42791 as a regression, namely that to spawn
batch scripts they need to be manually spawned with `cmd /c` instead now. This
updates the compiler to handle this case explicitly for Emscripten.

Closes #42791
-rw-r--r--src/librustc_trans/back/link.rs22
1 files changed, 20 insertions, 2 deletions
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index efb56ab5a6c..08266e86f97 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -107,14 +107,32 @@ pub fn build_link_meta(incremental_hashes_map: &IncrementalHashesMap) -> LinkMet
 pub fn get_linker(sess: &Session) -> (String, Command, Vec<(OsString, OsString)>) {
     let envs = vec![("PATH".into(), command_path(sess))];
 
+    // 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 cmd = |linker: &str| {
+        if cfg!(windows) && linker.ends_with(".bat") {
+            let mut cmd = Command::new("cmd");
+            cmd.arg("/c").arg(linker);
+            cmd
+        } else {
+            Command::new(linker)
+        }
+    };
+
     if let Some(ref linker) = sess.opts.cg.linker {
-        (linker.clone(), Command::new(linker), envs)
+        (linker.clone(), cmd(linker), envs)
     } else if sess.target.target.options.is_like_msvc {
         let (cmd, envs) = msvc_link_exe_cmd(sess);
         ("link.exe".to_string(), cmd, envs)
     } else {
         let linker = &sess.target.target.options.linker;
-        (linker.clone(), Command::new(&linker), envs)
+        (linker.clone(), cmd(linker), envs)
     }
 }