about summary refs log tree commit diff
path: root/build_system
diff options
context:
space:
mode:
authorbjorn3 <bjorn3@users.noreply.github.com>2021-06-08 14:33:25 +0200
committerbjorn3 <bjorn3@users.noreply.github.com>2021-06-19 13:54:25 +0200
commit2db4e50618faf277aa6e7b0b45b6fc1aa5389653 (patch)
tree16e5161bc9e7bab878fef065247cf8a3355cb6db /build_system
parent0ddb937624265f167f66b034422252d00801cd29 (diff)
downloadrust-2db4e50618faf277aa6e7b0b45b6fc1aa5389653.tar.gz
rust-2db4e50618faf277aa6e7b0b45b6fc1aa5389653.zip
Rewrite build.sh in rust
This makes it easier to compile cg_clif on systems that don't support
bash shell scripts like Windows
Diffstat (limited to 'build_system')
-rw-r--r--build_system/build_backend.rs41
-rw-r--r--build_system/build_sysroot.rs128
-rw-r--r--build_system/rustc_info.rs41
3 files changed, 210 insertions, 0 deletions
diff --git a/build_system/build_backend.rs b/build_system/build_backend.rs
new file mode 100644
index 00000000000..cdddeae2a33
--- /dev/null
+++ b/build_system/build_backend.rs
@@ -0,0 +1,41 @@
+use std::env;
+use std::process::{self, Command};
+
+pub(crate) fn build_backend(channel: &str) -> String {
+    let mut cmd = Command::new("cargo");
+    cmd.arg("build");
+
+    match channel {
+        "debug" => {}
+        "release" => {
+            cmd.arg("--release");
+        }
+        _ => unreachable!(),
+    }
+
+    if cfg!(unix) {
+        if cfg!(target_os = "macos") {
+            cmd.env(
+                "RUSTFLAGS",
+                "-Csplit-debuginfo=unpacked \
+                -Clink-arg=-Wl,-rpath,@loader_path/../lib \
+                -Zosx-rpath-install-name"
+                    .to_string()
+                    + env::var("RUSTFLAGS").as_deref().unwrap_or(""),
+            );
+        } else {
+            cmd.env(
+                "RUSTFLAGS",
+                "-Clink-arg=-Wl,-rpath=$ORIGIN/../lib ".to_string()
+                    + env::var("RUSTFLAGS").as_deref().unwrap_or(""),
+            );
+        }
+    }
+
+    eprintln!("[BUILD] rustc_codegen_cranelift");
+    if !cmd.spawn().unwrap().wait().unwrap().success() {
+        process::exit(1);
+    }
+
+    crate::rustc_info::get_dylib_name("rustc_codegen_cranelift")
+}
diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs
new file mode 100644
index 00000000000..d6ac19dd1cc
--- /dev/null
+++ b/build_system/build_sysroot.rs
@@ -0,0 +1,128 @@
+use crate::{try_hard_link, SysrootKind};
+use std::env;
+use std::fs;
+use std::path::Path;
+use std::process::{self, Command};
+
+pub(crate) fn build_sysroot(
+    channel: &str,
+    sysroot_kind: SysrootKind,
+    target_dir: &Path,
+    cg_clif_dylib: String,
+    host_triple: &str,
+    target_triple: &str,
+) {
+    if target_dir.exists() {
+        fs::remove_dir_all(target_dir).unwrap();
+    }
+    fs::create_dir_all(target_dir.join("bin")).unwrap();
+    fs::create_dir_all(target_dir.join("lib")).unwrap();
+
+    // Copy the backend
+    for file in ["cg_clif", "cg_clif_build_sysroot"] {
+        try_hard_link(
+            Path::new("target").join(channel).join(file),
+            target_dir.join("bin").join(file),
+        );
+    }
+
+    try_hard_link(
+        Path::new("target").join(channel).join(&cg_clif_dylib),
+        target_dir.join("lib").join(cg_clif_dylib),
+    );
+
+    // Copy supporting files
+    try_hard_link("rust-toolchain", target_dir.join("rust-toolchain"));
+    try_hard_link("scripts/config.sh", target_dir.join("config.sh"));
+    try_hard_link("scripts/cargo.sh", target_dir.join("cargo.sh"));
+
+    let default_sysroot = crate::rustc_info::get_default_sysroot();
+
+    let rustlib = target_dir.join("lib").join("rustlib");
+    let host_rustlib_lib = rustlib.join(host_triple).join("lib");
+    let target_rustlib_lib = rustlib.join(target_triple).join("lib");
+    fs::create_dir_all(&host_rustlib_lib).unwrap();
+    fs::create_dir_all(&target_rustlib_lib).unwrap();
+
+    if target_triple == "x86_64-pc-windows-gnu" {
+        if !default_sysroot.join("lib").join("rustlib").join(target_triple).join("lib").exists() {
+            eprintln!(
+                "The x86_64-pc-windows-gnu target needs to be installed first before it is possible \
+                to compile a sysroot for it.",
+            );
+            process::exit(1);
+        }
+        for file in fs::read_dir(
+            default_sysroot.join("lib").join("rustlib").join(target_triple).join("lib"),
+        )
+        .unwrap()
+        {
+            let file = file.unwrap().path();
+            if file.extension().map_or(true, |ext| ext.to_str().unwrap() != "o") {
+                continue; // only copy object files
+            }
+            try_hard_link(&file, target_rustlib_lib.join(file.file_name().unwrap()));
+        }
+    }
+
+    match sysroot_kind {
+        SysrootKind::None => {} // Nothing to do
+        SysrootKind::Llvm => {
+            for file in fs::read_dir(
+                default_sysroot.join("lib").join("rustlib").join(host_triple).join("lib"),
+            )
+            .unwrap()
+            {
+                let file = file.unwrap().path();
+                let file_name_str = file.file_name().unwrap().to_str().unwrap();
+                if file_name_str.contains("rustc_")
+                    || file_name_str.contains("chalk")
+                    || file_name_str.contains("tracing")
+                    || file_name_str.contains("regex")
+                {
+                    // These are large crates that are part of the rustc-dev component and are not
+                    // necessary to run regular programs.
+                    continue;
+                }
+                try_hard_link(&file, host_rustlib_lib.join(file.file_name().unwrap()));
+            }
+
+            if target_triple != host_triple {
+                for file in fs::read_dir(
+                    default_sysroot.join("lib").join("rustlib").join(target_triple).join("lib"),
+                )
+                .unwrap()
+                {
+                    let file = file.unwrap().path();
+                    try_hard_link(&file, target_rustlib_lib.join(file.file_name().unwrap()));
+                }
+            }
+        }
+        SysrootKind::Clif => {
+            let cwd = env::current_dir().unwrap();
+
+            let mut cmd = Command::new(cwd.join("build_sysroot").join("build_sysroot.sh"));
+            cmd.current_dir(target_dir).env("TARGET_TRIPLE", target_triple);
+            eprintln!("[BUILD] sysroot");
+            if !cmd.spawn().unwrap().wait().unwrap().success() {
+                process::exit(1);
+            }
+
+            if host_triple != target_triple {
+                let mut cmd = Command::new(cwd.join("build_sysroot").join("build_sysroot.sh"));
+                cmd.current_dir(target_dir).env("TARGET_TRIPLE", host_triple);
+                eprintln!("[BUILD] sysroot");
+                if !cmd.spawn().unwrap().wait().unwrap().success() {
+                    process::exit(1);
+                }
+            }
+
+            for file in fs::read_dir(host_rustlib_lib).unwrap() {
+                let file = file.unwrap().path();
+                if file.file_name().unwrap().to_str().unwrap().contains("std-") {
+                    try_hard_link(&file, target_dir.join("lib").join(file.file_name().unwrap()));
+                }
+            }
+        }
+    }
+}
diff --git a/build_system/rustc_info.rs b/build_system/rustc_info.rs
new file mode 100644
index 00000000000..28222743022
--- /dev/null
+++ b/build_system/rustc_info.rs
@@ -0,0 +1,41 @@
+use std::path::{Path, PathBuf};
+use std::process::{Command, Stdio};
+
+pub(crate) fn get_host_triple() -> String {
+    let version_info =
+        Command::new("rustc").stderr(Stdio::inherit()).args(&["-vV"]).output().unwrap().stdout;
+    String::from_utf8(version_info)
+        .unwrap()
+        .lines()
+        .to_owned()
+        .find(|line| line.starts_with("host"))
+        .unwrap()
+        .split(":")
+        .nth(1)
+        .unwrap()
+        .trim()
+        .to_owned()
+}
+
+pub(crate) fn get_default_sysroot() -> PathBuf {
+    let default_sysroot = Command::new("rustc")
+        .stderr(Stdio::inherit())
+        .args(&["--print", "sysroot"])
+        .output()
+        .unwrap()
+        .stdout;
+    Path::new(String::from_utf8(default_sysroot).unwrap().trim()).to_owned()
+}
+
+pub(crate) fn get_dylib_name(crate_name: &str) -> String {
+    let dylib_name = Command::new("rustc")
+        .stderr(Stdio::inherit())
+        .args(&["--crate-name", crate_name, "--crate-type", "dylib", "--print", "file-names", "-"])
+        .output()
+        .unwrap()
+        .stdout;
+    let dylib_name = String::from_utf8(dylib_name).unwrap().trim().to_owned();
+    assert!(!dylib_name.contains('\n'));
+    assert!(dylib_name.contains(crate_name));
+    dylib_name
+}