about summary refs log tree commit diff
path: root/compiler/rustc_codegen_gcc/build_system/src/utils.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_gcc/build_system/src/utils.rs')
-rw-r--r--compiler/rustc_codegen_gcc/build_system/src/utils.rs133
1 files changed, 77 insertions, 56 deletions
diff --git a/compiler/rustc_codegen_gcc/build_system/src/utils.rs b/compiler/rustc_codegen_gcc/build_system/src/utils.rs
index d9c13fd143d..3bba8df6c65 100644
--- a/compiler/rustc_codegen_gcc/build_system/src/utils.rs
+++ b/compiler/rustc_codegen_gcc/build_system/src/utils.rs
@@ -1,10 +1,42 @@
 use std::collections::HashMap;
+#[cfg(unix)]
+use std::ffi::c_int;
 use std::ffi::OsStr;
 use std::fmt::Debug;
 use std::fs;
+#[cfg(unix)]
+use std::os::unix::process::ExitStatusExt;
 use std::path::{Path, PathBuf};
 use std::process::{Command, ExitStatus, Output};
 
+#[cfg(unix)]
+extern "C" {
+    fn raise(signal: c_int) -> c_int;
+}
+
+fn exec_command(
+    input: &[&dyn AsRef<OsStr>],
+    cwd: Option<&Path>,
+    env: Option<&HashMap<String, String>>,
+) -> Result<ExitStatus, String> {
+    let status = get_command_inner(input, cwd, env)
+        .spawn()
+        .map_err(|e| command_error(input, &cwd, e))?
+        .wait()
+        .map_err(|e| command_error(input, &cwd, e))?;
+    #[cfg(unix)]
+    {
+        if let Some(signal) = status.signal() {
+            unsafe {
+                raise(signal as _);
+            }
+            // In case the signal didn't kill the current process.
+            return Err(command_error(input, &cwd, format!("Process received signal {}", signal)));
+        }
+    }
+    Ok(status)
+}
+
 fn get_command_inner(
     input: &[&dyn AsRef<OsStr>],
     cwd: Option<&Path>,
@@ -37,13 +69,8 @@ fn check_exit_status(
     }
     let mut error = format!(
         "Command `{}`{} exited with status {:?}",
-        input
-            .iter()
-            .map(|s| s.as_ref().to_str().unwrap())
-            .collect::<Vec<_>>()
-            .join(" "),
-        cwd.map(|cwd| format!(" (running in folder `{}`)", cwd.display()))
-            .unwrap_or_default(),
+        input.iter().map(|s| s.as_ref().to_str().unwrap()).collect::<Vec<_>>().join(" "),
+        cwd.map(|cwd| format!(" (running in folder `{}`)", cwd.display())).unwrap_or_default(),
         exit_status.code()
     );
     let input = input.iter().map(|i| i.as_ref()).collect::<Vec<&OsStr>>();
@@ -68,11 +95,7 @@ fn check_exit_status(
 fn command_error<D: Debug>(input: &[&dyn AsRef<OsStr>], cwd: &Option<&Path>, error: D) -> String {
     format!(
         "Command `{}`{} failed to run: {error:?}",
-        input
-            .iter()
-            .map(|s| s.as_ref().to_str().unwrap())
-            .collect::<Vec<_>>()
-            .join(" "),
+        input.iter().map(|s| s.as_ref().to_str().unwrap()).collect::<Vec<_>>().join(" "),
         cwd.as_ref()
             .map(|cwd| format!(" (running in folder `{}`)", cwd.display(),))
             .unwrap_or_default(),
@@ -88,9 +111,8 @@ pub fn run_command_with_env(
     cwd: Option<&Path>,
     env: Option<&HashMap<String, String>>,
 ) -> Result<Output, String> {
-    let output = get_command_inner(input, cwd, env)
-        .output()
-        .map_err(|e| command_error(input, &cwd, e))?;
+    let output =
+        get_command_inner(input, cwd, env).output().map_err(|e| command_error(input, &cwd, e))?;
     check_exit_status(input, cwd, output.status, Some(&output), true)?;
     Ok(output)
 }
@@ -99,11 +121,7 @@ pub fn run_command_with_output(
     input: &[&dyn AsRef<OsStr>],
     cwd: Option<&Path>,
 ) -> Result<(), String> {
-    let exit_status = get_command_inner(input, cwd, None)
-        .spawn()
-        .map_err(|e| command_error(input, &cwd, e))?
-        .wait()
-        .map_err(|e| command_error(input, &cwd, e))?;
+    let exit_status = exec_command(input, cwd, None)?;
     check_exit_status(input, cwd, exit_status, None, true)?;
     Ok(())
 }
@@ -113,11 +131,7 @@ pub fn run_command_with_output_and_env(
     cwd: Option<&Path>,
     env: Option<&HashMap<String, String>>,
 ) -> Result<(), String> {
-    let exit_status = get_command_inner(input, cwd, env)
-        .spawn()
-        .map_err(|e| command_error(input, &cwd, e))?
-        .wait()
-        .map_err(|e| command_error(input, &cwd, e))?;
+    let exit_status = exec_command(input, cwd, env)?;
     check_exit_status(input, cwd, exit_status, None, true)?;
     Ok(())
 }
@@ -127,11 +141,7 @@ pub fn run_command_with_output_and_env_no_err(
     cwd: Option<&Path>,
     env: Option<&HashMap<String, String>>,
 ) -> Result<(), String> {
-    let exit_status = get_command_inner(input, cwd, env)
-        .spawn()
-        .map_err(|e| command_error(input, &cwd, e))?
-        .wait()
-        .map_err(|e| command_error(input, &cwd, e))?;
+    let exit_status = exec_command(input, cwd, env)?;
     check_exit_status(input, cwd, exit_status, None, false)?;
     Ok(())
 }
@@ -164,10 +174,7 @@ pub fn cargo_install(to_install: &str) -> Result<(), String> {
 
 pub fn get_os_name() -> Result<String, String> {
     let output = run_command(&[&"uname"], None)?;
-    let name = std::str::from_utf8(&output.stdout)
-        .unwrap_or("")
-        .trim()
-        .to_string();
+    let name = std::str::from_utf8(&output.stdout).unwrap_or("").trim().to_string();
     if !name.is_empty() {
         Ok(name)
     } else {
@@ -274,11 +281,7 @@ fn git_clone_inner(
         command.push(&"1");
     }
     run_command_with_output(&command, None)?;
-    Ok(CloneResult {
-        ran_clone: true,
-        repo_name,
-        repo_dir: dest.display().to_string(),
-    })
+    Ok(CloneResult { ran_clone: true, repo_name, repo_dir: dest.display().to_string() })
 }
 
 fn get_repo_name(url: &str) -> String {
@@ -307,6 +310,25 @@ pub fn git_clone(
     git_clone_inner(to_clone, dest, shallow_clone, repo_name)
 }
 
+pub fn create_dir<P: AsRef<Path>>(path: P) -> Result<(), String> {
+    fs::create_dir_all(&path).map_err(|error| {
+        format!("Failed to create directory `{}`: {:?}", path.as_ref().display(), error)
+    })
+}
+
+pub fn copy_file<F: AsRef<Path>, T: AsRef<Path>>(from: F, to: T) -> Result<(), String> {
+    fs::copy(&from, &to)
+        .map_err(|error| {
+            format!(
+                "Failed to copy file `{}` into `{}`: {:?}",
+                from.as_ref().display(),
+                to.as_ref().display(),
+                error
+            )
+        })
+        .map(|_| ())
+}
+
 /// This function differs from `git_clone` in how it handles *where* the repository will be cloned.
 /// In `git_clone`, it is cloned in the provided path. In this function, the path you provide is
 /// the parent folder. So if you pass "a" as folder and try to clone "b.git", it will be cloned into
@@ -318,15 +340,15 @@ pub fn git_clone_root_dir(
 ) -> Result<CloneResult, String> {
     let repo_name = get_repo_name(to_clone);
 
-    git_clone_inner(
-        to_clone,
-        &dest_parent_dir.join(&repo_name),
-        shallow_clone,
-        repo_name,
-    )
+    git_clone_inner(to_clone, &dest_parent_dir.join(&repo_name), shallow_clone, repo_name)
 }
 
-pub fn walk_dir<P, D, F>(dir: P, mut dir_cb: D, mut file_cb: F) -> Result<(), String>
+pub fn walk_dir<P, D, F>(
+    dir: P,
+    dir_cb: &mut D,
+    file_cb: &mut F,
+    recursive: bool,
+) -> Result<(), String>
 where
     P: AsRef<Path>,
     D: FnMut(&Path) -> Result<(), String>,
@@ -341,6 +363,9 @@ where
         let entry_path = entry.path();
         if entry_path.is_dir() {
             dir_cb(&entry_path)?;
+            if recursive {
+                walk_dir(entry_path, dir_cb, file_cb, recursive)?; // Recursive call
+            }
         } else {
             file_cb(&entry_path)?;
         }
@@ -383,11 +408,7 @@ pub fn split_args(args: &str) -> Result<Vec<String>, String> {
                 }
             }
             if !found_end {
-                return Err(format!(
-                    "Didn't find `{}` at the end of `{}`",
-                    end,
-                    &args[start..]
-                ));
+                return Err(format!("Didn't find `{}` at the end of `{}`", end, &args[start..]));
             }
         } else if c == '\\' {
             // We skip the escaped character.
@@ -403,11 +424,7 @@ pub fn split_args(args: &str) -> Result<Vec<String>, String> {
 
 pub fn remove_file<P: AsRef<Path> + ?Sized>(file_path: &P) -> Result<(), String> {
     std::fs::remove_file(file_path).map_err(|error| {
-        format!(
-            "Failed to remove `{}`: {:?}",
-            file_path.as_ref().display(),
-            error
-        )
+        format!("Failed to remove `{}`: {:?}", file_path.as_ref().display(), error)
     })
 }
 
@@ -427,6 +444,10 @@ pub fn create_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> R
     })
 }
 
+pub fn get_sysroot_dir() -> PathBuf {
+    Path::new(crate::BUILD_DIR).join("build_sysroot")
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;