diff options
| author | bjorn3 <bjorn3@users.noreply.github.com> | 2021-06-08 14:33:25 +0200 |
|---|---|---|
| committer | bjorn3 <bjorn3@users.noreply.github.com> | 2021-06-19 13:54:25 +0200 |
| commit | 2db4e50618faf277aa6e7b0b45b6fc1aa5389653 (patch) | |
| tree | 16e5161bc9e7bab878fef065247cf8a3355cb6db /build_system | |
| parent | 0ddb937624265f167f66b034422252d00801cd29 (diff) | |
| download | rust-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.rs | 41 | ||||
| -rw-r--r-- | build_system/build_sysroot.rs | 128 | ||||
| -rw-r--r-- | build_system/rustc_info.rs | 41 |
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 +} |
