about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbjorn3 <17426603+bjorn3@users.noreply.github.com>2022-12-01 13:30:03 +0000
committerbjorn3 <17426603+bjorn3@users.noreply.github.com>2022-12-01 19:00:32 +0000
commit4529979330038c6accce45533f34aae681a6017c (patch)
tree11b9f9cd9d87d285b4fab0665664e41b489be246
parente75dfef4d4002dcb8e2daaf99b9d0ce922053f73 (diff)
downloadrust-4529979330038c6accce45533f34aae681a6017c.tar.gz
rust-4529979330038c6accce45533f34aae681a6017c.zip
Introduce RelPath
-rw-r--r--build_system/abi_cafe.rs12
-rw-r--r--build_system/build_backend.rs3
-rw-r--r--build_system/build_sysroot.rs72
-rw-r--r--build_system/mod.rs20
-rw-r--r--build_system/path.rs71
-rw-r--r--build_system/prepare.rs53
-rw-r--r--build_system/tests.rs68
-rw-r--r--build_system/utils.rs30
8 files changed, 165 insertions, 164 deletions
diff --git a/build_system/abi_cafe.rs b/build_system/abi_cafe.rs
index 469df9483a7..acb2bd5aeae 100644
--- a/build_system/abi_cafe.rs
+++ b/build_system/abi_cafe.rs
@@ -9,12 +9,11 @@ use super::SysrootKind;
 pub(crate) static ABI_CAFE_REPO: GitRepo =
     GitRepo::github("Gankra", "abi-cafe", "4c6dc8c9c687e2b3a760ff2176ce236872b37212", "abi-cafe");
 
-static ABI_CAFE: CargoProject = CargoProject::git(&ABI_CAFE_REPO, ".", "abi_cafe");
+static ABI_CAFE: CargoProject = CargoProject::new(&ABI_CAFE_REPO.source_dir(), "abi_cafe");
 
 pub(crate) fn run(
     channel: &str,
     sysroot_kind: SysrootKind,
-    dist_dir: &Path,
     cg_clif_dylib: &Path,
     host_triple: &str,
     target_triple: &str,
@@ -30,14 +29,7 @@ pub(crate) fn run(
     }
 
     eprintln!("Building sysroot for abi-cafe");
-    build_sysroot::build_sysroot(
-        channel,
-        sysroot_kind,
-        dist_dir,
-        cg_clif_dylib,
-        host_triple,
-        target_triple,
-    );
+    build_sysroot::build_sysroot(channel, sysroot_kind, cg_clif_dylib, host_triple, target_triple);
 
     eprintln!("Running abi-cafe");
 
diff --git a/build_system/build_backend.rs b/build_system/build_backend.rs
index b1c902abd17..5cbeb7d0f9f 100644
--- a/build_system/build_backend.rs
+++ b/build_system/build_backend.rs
@@ -1,10 +1,11 @@
 use std::env;
 use std::path::PathBuf;
 
+use super::path::RelPath;
 use super::rustc_info::get_file_name;
 use super::utils::{is_ci, CargoProject, Compiler};
 
-static CG_CLIF: CargoProject = CargoProject::local(".", "cg_clif");
+static CG_CLIF: CargoProject = CargoProject::new(&RelPath::SOURCE, "cg_clif");
 
 pub(crate) fn build_backend(
     channel: &str,
diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs
index f78803268d3..fcd668b8aa5 100644
--- a/build_system/build_sysroot.rs
+++ b/build_system/build_sysroot.rs
@@ -2,36 +2,39 @@ use std::fs;
 use std::path::Path;
 use std::process::{self, Command};
 
+use super::path::RelPath;
 use super::rustc_info::{get_file_name, get_rustc_version, get_wrapper_file_name};
 use super::utils::{spawn_and_wait, try_hard_link, CargoProject, Compiler};
 use super::SysrootKind;
 
+static DIST_DIR: RelPath = RelPath::DIST;
+static BIN_DIR: RelPath = RelPath::DIST.join("bin");
+static LIB_DIR: RelPath = RelPath::DIST.join("lib");
+static RUSTLIB_DIR: RelPath = LIB_DIR.join("rustlib");
+
 pub(crate) fn build_sysroot(
     channel: &str,
     sysroot_kind: SysrootKind,
-    dist_dir: &Path,
     cg_clif_dylib_src: &Path,
     host_triple: &str,
     target_triple: &str,
 ) {
     eprintln!("[BUILD] sysroot {:?}", sysroot_kind);
 
-    if dist_dir.exists() {
-        fs::remove_dir_all(dist_dir).unwrap();
-    }
-    fs::create_dir_all(dist_dir.join("bin")).unwrap();
-    fs::create_dir_all(dist_dir.join("lib")).unwrap();
+    DIST_DIR.ensure_fresh();
+    BIN_DIR.ensure_exists();
+    LIB_DIR.ensure_exists();
 
     // Copy the backend
-    let cg_clif_dylib_path = dist_dir
-        .join(if cfg!(windows) {
-            // Windows doesn't have rpath support, so the cg_clif dylib needs to be next to the
-            // binaries.
-            "bin"
-        } else {
-            "lib"
-        })
-        .join(get_file_name("rustc_codegen_cranelift", "dylib"));
+    let cg_clif_dylib_path = if cfg!(windows) {
+        // Windows doesn't have rpath support, so the cg_clif dylib needs to be next to the
+        // binaries.
+        BIN_DIR
+    } else {
+        LIB_DIR
+    }
+    .to_path()
+    .join(get_file_name("rustc_codegen_cranelift", "dylib"));
     try_hard_link(cg_clif_dylib_src, &cg_clif_dylib_path);
 
     // Build and copy rustc and cargo wrappers
@@ -40,18 +43,17 @@ pub(crate) fn build_sysroot(
 
         let mut build_cargo_wrapper_cmd = Command::new("rustc");
         build_cargo_wrapper_cmd
-            .arg(Path::new("scripts").join(format!("{wrapper}.rs")))
+            .arg(RelPath::SCRIPTS.to_path().join(&format!("{wrapper}.rs")))
             .arg("-o")
-            .arg(dist_dir.join(wrapper_name))
+            .arg(DIST_DIR.to_path().join(wrapper_name))
             .arg("-g");
         spawn_and_wait(build_cargo_wrapper_cmd);
     }
 
     let default_sysroot = super::rustc_info::get_default_sysroot();
 
-    let rustlib = dist_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");
+    let host_rustlib_lib = RUSTLIB_DIR.to_path().join(host_triple).join("lib");
+    let target_rustlib_lib = RUSTLIB_DIR.to_path().join(target_triple).join("lib");
     fs::create_dir_all(&host_rustlib_lib).unwrap();
     fs::create_dir_all(&target_rustlib_lib).unwrap();
 
@@ -112,13 +114,7 @@ pub(crate) fn build_sysroot(
             }
         }
         SysrootKind::Clif => {
-            build_clif_sysroot_for_triple(
-                channel,
-                dist_dir,
-                host_triple,
-                &cg_clif_dylib_path,
-                None,
-            );
+            build_clif_sysroot_for_triple(channel, host_triple, &cg_clif_dylib_path, None);
 
             if host_triple != target_triple {
                 // When cross-compiling it is often necessary to manually pick the right linker
@@ -127,13 +123,7 @@ pub(crate) fn build_sysroot(
                 } else {
                     None
                 };
-                build_clif_sysroot_for_triple(
-                    channel,
-                    dist_dir,
-                    target_triple,
-                    &cg_clif_dylib_path,
-                    linker,
-                );
+                build_clif_sysroot_for_triple(channel, target_triple, &cg_clif_dylib_path, linker);
             }
 
             // Copy std for the host to the lib dir. This is necessary for the jit mode to find
@@ -142,23 +132,25 @@ pub(crate) fn build_sysroot(
                 let file = file.unwrap().path();
                 let filename = file.file_name().unwrap().to_str().unwrap();
                 if filename.contains("std-") && !filename.contains(".rlib") {
-                    try_hard_link(&file, dist_dir.join("lib").join(file.file_name().unwrap()));
+                    try_hard_link(&file, LIB_DIR.to_path().join(file.file_name().unwrap()));
                 }
             }
         }
     }
 }
 
-static STANDARD_LIBRARY: CargoProject = CargoProject::local("build_sysroot", "build_sysroot");
+// FIXME move to download/ or dist/
+pub(crate) static SYSROOT_RUSTC_VERSION: RelPath = RelPath::BUILD_SYSROOT.join("rustc_version");
+pub(crate) static SYSROOT_SRC: RelPath = RelPath::BUILD_SYSROOT.join("sysroot_src");
+static STANDARD_LIBRARY: CargoProject = CargoProject::new(&RelPath::BUILD_SYSROOT, "build_sysroot");
 
 fn build_clif_sysroot_for_triple(
     channel: &str,
-    dist_dir: &Path,
     triple: &str,
     cg_clif_dylib_path: &Path,
     linker: Option<&str>,
 ) {
-    match fs::read_to_string(Path::new("build_sysroot").join("rustc_version")) {
+    match fs::read_to_string(SYSROOT_RUSTC_VERSION.to_path()) {
         Err(e) => {
             eprintln!("Failed to get rustc version for patched sysroot source: {}", e);
             eprintln!("Hint: Try `./y.rs prepare` to patch the sysroot source");
@@ -189,7 +181,7 @@ fn build_clif_sysroot_for_triple(
     // Build sysroot
     let mut rustflags = "-Zforce-unstable-if-unmarked -Cpanic=abort".to_string();
     rustflags.push_str(&format!(" -Zcodegen-backend={}", cg_clif_dylib_path.to_str().unwrap()));
-    rustflags.push_str(&format!(" --sysroot={}", dist_dir.to_str().unwrap()));
+    rustflags.push_str(&format!(" --sysroot={}", DIST_DIR.to_path().to_str().unwrap()));
     if channel == "release" {
         rustflags.push_str(" -Zmir-opt-level=3");
     }
@@ -218,7 +210,7 @@ fn build_clif_sysroot_for_triple(
         };
         try_hard_link(
             entry.path(),
-            dist_dir.join("lib").join("rustlib").join(triple).join("lib").join(entry.file_name()),
+            RUSTLIB_DIR.to_path().join(triple).join("lib").join(entry.file_name()),
         );
     }
 }
diff --git a/build_system/mod.rs b/build_system/mod.rs
index f3ccfcb1518..cc789c8f10b 100644
--- a/build_system/mod.rs
+++ b/build_system/mod.rs
@@ -8,6 +8,7 @@ mod abi_cafe;
 mod build_backend;
 mod build_sysroot;
 mod config;
+mod path;
 mod prepare;
 mod rustc_info;
 mod tests;
@@ -133,29 +134,14 @@ pub fn main() {
     let cg_clif_dylib = build_backend::build_backend(channel, &host_triple, use_unstable_features);
     match command {
         Command::Test => {
-            tests::run_tests(
-                channel,
-                sysroot_kind,
-                &dist_dir,
-                &cg_clif_dylib,
-                &host_triple,
-                &target_triple,
-            );
+            tests::run_tests(channel, sysroot_kind, &cg_clif_dylib, &host_triple, &target_triple);
 
-            abi_cafe::run(
-                channel,
-                sysroot_kind,
-                &dist_dir,
-                &cg_clif_dylib,
-                &host_triple,
-                &target_triple,
-            );
+            abi_cafe::run(channel, sysroot_kind, &cg_clif_dylib, &host_triple, &target_triple);
         }
         Command::Build => {
             build_sysroot::build_sysroot(
                 channel,
                 sysroot_kind,
-                &dist_dir,
                 &cg_clif_dylib,
                 &host_triple,
                 &target_triple,
diff --git a/build_system/path.rs b/build_system/path.rs
new file mode 100644
index 00000000000..73a17a3980f
--- /dev/null
+++ b/build_system/path.rs
@@ -0,0 +1,71 @@
+use std::fs;
+use std::path::PathBuf;
+
+/*pub(crate) struct Paths {
+    source_dir: PathBuf,
+    download_dir: PathBuf,
+    build_dir: PathBuf,
+    dist_dir: PathBuf,
+}*/
+
+#[doc(hidden)]
+#[derive(Debug, Copy, Clone)]
+pub(crate) enum PathBase {
+    Source,
+    Download,
+    Build,
+    Dist,
+}
+
+impl PathBase {
+    fn to_path(self) -> PathBuf {
+        // FIXME pass in all paths instead
+        let current_dir = std::env::current_dir().unwrap();
+        match self {
+            PathBase::Source => current_dir,
+            PathBase::Download => current_dir.join("download"),
+            PathBase::Build => current_dir.join("build"),
+            PathBase::Dist => current_dir.join("dist"),
+        }
+    }
+}
+
+#[derive(Debug, Copy, Clone)]
+pub(crate) enum RelPath {
+    Base(PathBase),
+    Join(&'static RelPath, &'static str),
+}
+
+impl RelPath {
+    pub(crate) const SOURCE: RelPath = RelPath::Base(PathBase::Source);
+    pub(crate) const DOWNLOAD: RelPath = RelPath::Base(PathBase::Download);
+    pub(crate) const BUILD: RelPath = RelPath::Base(PathBase::Build);
+    pub(crate) const DIST: RelPath = RelPath::Base(PathBase::Dist);
+
+    pub(crate) const SCRIPTS: RelPath = RelPath::SOURCE.join("scripts");
+    pub(crate) const BUILD_SYSROOT: RelPath = RelPath::SOURCE.join("build_sysroot");
+    pub(crate) const PATCHES: RelPath = RelPath::SOURCE.join("patches");
+
+    pub(crate) const fn join(&'static self, suffix: &'static str) -> RelPath {
+        RelPath::Join(self, suffix)
+    }
+
+    pub(crate) fn to_path(&self) -> PathBuf {
+        match self {
+            RelPath::Base(base) => base.to_path(),
+            RelPath::Join(base, suffix) => base.to_path().join(suffix),
+        }
+    }
+
+    pub(crate) fn ensure_exists(&self) {
+        fs::create_dir_all(self.to_path()).unwrap();
+    }
+
+    pub(crate) fn ensure_fresh(&self) {
+        let path = self.to_path();
+        if path.exists() {
+            fs::remove_dir_all(&path).unwrap();
+        }
+        fs::create_dir_all(path).unwrap();
+    }
+}
diff --git a/build_system/prepare.rs b/build_system/prepare.rs
index 99ec3ef2092..09568aae9f3 100644
--- a/build_system/prepare.rs
+++ b/build_system/prepare.rs
@@ -1,17 +1,18 @@
-use std::env;
 use std::ffi::OsStr;
 use std::fs;
 use std::path::{Path, PathBuf};
 use std::process::Command;
 
+use super::build_sysroot::{SYSROOT_RUSTC_VERSION, SYSROOT_SRC};
+use super::path::RelPath;
 use super::rustc_info::{get_file_name, get_rustc_path, get_rustc_version};
 use super::utils::{copy_dir_recursively, spawn_and_wait, Compiler};
 
 pub(crate) fn prepare() {
-    if Path::new("download").exists() {
-        std::fs::remove_dir_all(Path::new("download")).unwrap();
+    if RelPath::DOWNLOAD.to_path().exists() {
+        std::fs::remove_dir_all(RelPath::DOWNLOAD.to_path()).unwrap();
     }
-    std::fs::create_dir_all(Path::new("download")).unwrap();
+    std::fs::create_dir_all(RelPath::DOWNLOAD.to_path()).unwrap();
 
     prepare_sysroot();
 
@@ -35,7 +36,7 @@ pub(crate) fn prepare() {
             .join(&host_compiler.triple)
             .join("debug")
             .join(get_file_name("main", "bin")),
-        Path::new("build").join(get_file_name("raytracer_cg_llvm", "bin")),
+        RelPath::BUILD.to_path().join(get_file_name("raytracer_cg_llvm", "bin")),
     )
     .unwrap();
 }
@@ -43,28 +44,26 @@ pub(crate) fn prepare() {
 fn prepare_sysroot() {
     let rustc_path = get_rustc_path();
     let sysroot_src_orig = rustc_path.parent().unwrap().join("../lib/rustlib/src/rust");
-    let sysroot_src = env::current_dir().unwrap().join("build_sysroot").join("sysroot_src");
+    let sysroot_src = SYSROOT_SRC;
 
     assert!(sysroot_src_orig.exists());
 
-    if sysroot_src.exists() {
-        fs::remove_dir_all(&sysroot_src).unwrap();
-    }
-    fs::create_dir_all(sysroot_src.join("library")).unwrap();
+    sysroot_src.ensure_fresh();
+    fs::create_dir_all(sysroot_src.to_path().join("library")).unwrap();
     eprintln!("[COPY] sysroot src");
-    copy_dir_recursively(&sysroot_src_orig.join("library"), &sysroot_src.join("library"));
+    copy_dir_recursively(&sysroot_src_orig.join("library"), &sysroot_src.to_path().join("library"));
 
     let rustc_version = get_rustc_version();
-    fs::write(Path::new("build_sysroot").join("rustc_version"), &rustc_version).unwrap();
+    fs::write(SYSROOT_RUSTC_VERSION.to_path(), &rustc_version).unwrap();
 
     eprintln!("[GIT] init");
     let mut git_init_cmd = Command::new("git");
-    git_init_cmd.arg("init").arg("-q").current_dir(&sysroot_src);
+    git_init_cmd.arg("init").arg("-q").current_dir(sysroot_src.to_path());
     spawn_and_wait(git_init_cmd);
 
-    init_git_repo(&sysroot_src);
+    init_git_repo(&sysroot_src.to_path());
 
-    apply_patches("sysroot", &sysroot_src);
+    apply_patches("sysroot", &sysroot_src.to_path());
 }
 
 pub(crate) struct GitRepo {
@@ -87,21 +86,19 @@ impl GitRepo {
         GitRepo { url: GitRepoUrl::Github { user, repo }, rev, patch_name }
     }
 
-    pub(crate) fn source_dir(&self) -> PathBuf {
+    pub(crate) const fn source_dir(&self) -> RelPath {
         match self.url {
-            GitRepoUrl::Github { user: _, repo } => {
-                std::env::current_dir().unwrap().join("download").join(repo)
-            }
+            GitRepoUrl::Github { user: _, repo } => RelPath::DOWNLOAD.join(repo),
         }
     }
 
     fn fetch(&self) {
         match self.url {
             GitRepoUrl::Github { user, repo } => {
-                clone_repo_shallow_github(&self.source_dir(), user, repo, self.rev);
+                clone_repo_shallow_github(&self.source_dir().to_path(), user, repo, self.rev);
             }
         }
-        apply_patches(self.patch_name, &self.source_dir());
+        apply_patches(self.patch_name, &self.source_dir().to_path());
     }
 }
 
@@ -127,11 +124,9 @@ fn clone_repo_shallow_github(download_dir: &Path, user: &str, repo: &str, rev: &
         return;
     }
 
-    let downloads_dir = std::env::current_dir().unwrap().join("download");
-
     let archive_url = format!("https://github.com/{}/{}/archive/{}.tar.gz", user, repo, rev);
-    let archive_file = downloads_dir.join(format!("{}.tar.gz", rev));
-    let archive_dir = downloads_dir.join(format!("{}-{}", repo, rev));
+    let archive_file = RelPath::DOWNLOAD.to_path().join(format!("{}.tar.gz", rev));
+    let archive_dir = RelPath::DOWNLOAD.to_path().join(format!("{}-{}", repo, rev));
 
     eprintln!("[DOWNLOAD] {}/{} from {}", user, repo, archive_url);
 
@@ -147,7 +142,7 @@ fn clone_repo_shallow_github(download_dir: &Path, user: &str, repo: &str, rev: &
 
     // Unpack tar archive
     let mut unpack_cmd = Command::new("tar");
-    unpack_cmd.arg("xf").arg(&archive_file).current_dir(downloads_dir);
+    unpack_cmd.arg("xf").arg(&archive_file).current_dir(RelPath::DOWNLOAD.to_path());
     spawn_and_wait(unpack_cmd);
 
     // Rename unpacked dir to the expected name
@@ -173,8 +168,8 @@ fn init_git_repo(repo_dir: &Path) {
     spawn_and_wait(git_commit_cmd);
 }
 
-fn get_patches(source_dir: &Path, crate_name: &str) -> Vec<PathBuf> {
-    let mut patches: Vec<_> = fs::read_dir(source_dir.join("patches"))
+fn get_patches(crate_name: &str) -> Vec<PathBuf> {
+    let mut patches: Vec<_> = fs::read_dir(RelPath::PATCHES.to_path())
         .unwrap()
         .map(|entry| entry.unwrap().path())
         .filter(|path| path.extension() == Some(OsStr::new("patch")))
@@ -198,7 +193,7 @@ fn apply_patches(crate_name: &str, target_dir: &Path) {
         return;
     }
 
-    for patch in get_patches(&std::env::current_dir().unwrap(), crate_name) {
+    for patch in get_patches(crate_name) {
         eprintln!(
             "[PATCH] {:?} <- {:?}",
             target_dir.file_name().unwrap(),
diff --git a/build_system/tests.rs b/build_system/tests.rs
index 0645b69bf7c..3e495617fb2 100644
--- a/build_system/tests.rs
+++ b/build_system/tests.rs
@@ -1,9 +1,8 @@
-use crate::build_system::rustc_info::get_cargo_path;
-
 use super::build_sysroot;
 use super::config;
+use super::path::RelPath;
 use super::prepare::GitRepo;
-use super::rustc_info::get_wrapper_file_name;
+use super::rustc_info::{get_cargo_path, get_wrapper_file_name};
 use super::utils::{
     hyperfine_command, spawn_and_wait, spawn_and_wait_with_input, CargoProject, Compiler,
 };
@@ -11,9 +10,11 @@ use super::SysrootKind;
 use std::env;
 use std::ffi::OsStr;
 use std::fs;
-use std::path::{Path, PathBuf};
+use std::path::Path;
 use std::process::Command;
 
+static BUILD_EXAMPLE_OUT_DIR: RelPath = RelPath::BUILD.join("example");
+
 struct TestCase {
     config: &'static str,
     func: &'static dyn Fn(&TestRunner),
@@ -223,12 +224,12 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
 pub(crate) static RAND_REPO: GitRepo =
     GitRepo::github("rust-random", "rand", "0f933f9c7176e53b2a3c7952ded484e1783f0bf1", "rand");
 
-static RAND: CargoProject = CargoProject::git(&RAND_REPO, ".", "rand");
+static RAND: CargoProject = CargoProject::new(&RAND_REPO.source_dir(), "rand");
 
 pub(crate) static REGEX_REPO: GitRepo =
     GitRepo::github("rust-lang", "regex", "341f207c1071f7290e3f228c710817c280c8dca1", "regex");
 
-static REGEX: CargoProject = CargoProject::git(&REGEX_REPO, ".", "regex");
+static REGEX: CargoProject = CargoProject::new(&REGEX_REPO.source_dir(), "regex");
 
 pub(crate) static PORTABLE_SIMD_REPO: GitRepo = GitRepo::github(
     "rust-lang",
@@ -237,7 +238,8 @@ pub(crate) static PORTABLE_SIMD_REPO: GitRepo = GitRepo::github(
     "portable-simd",
 );
 
-static PORTABLE_SIMD: CargoProject = CargoProject::git(&PORTABLE_SIMD_REPO, ".", "portable_simd");
+static PORTABLE_SIMD: CargoProject =
+    CargoProject::new(&PORTABLE_SIMD_REPO.source_dir(), "portable_simd");
 
 pub(crate) static SIMPLE_RAYTRACER_REPO: GitRepo = GitRepo::github(
     "ebobby",
@@ -247,10 +249,10 @@ pub(crate) static SIMPLE_RAYTRACER_REPO: GitRepo = GitRepo::github(
 );
 
 pub(crate) static SIMPLE_RAYTRACER: CargoProject =
-    CargoProject::git(&SIMPLE_RAYTRACER_REPO, ".", "simple_raytracer");
+    CargoProject::new(&SIMPLE_RAYTRACER_REPO.source_dir(), "simple_raytracer");
 
 static LIBCORE_TESTS: CargoProject =
-    CargoProject::local("build_sysroot/sysroot_src/library/core/tests", "core_tests");
+    CargoProject::new(&RelPath::BUILD_SYSROOT.join("sysroot_src/library/core/tests"), "core_tests");
 
 const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
     TestCase::new("test.rust-random/rand", &|runner| {
@@ -273,10 +275,8 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
 
         if runner.is_native {
             eprintln!("[BENCH COMPILE] ebobby/simple-raytracer");
-            let cargo_clif = env::current_dir()
-                .unwrap()
-                .join("dist")
-                .join(get_wrapper_file_name("cargo-clif", "bin"));
+            let cargo_clif =
+                RelPath::DIST.to_path().join(get_wrapper_file_name("cargo-clif", "bin"));
             let manifest_path = SIMPLE_RAYTRACER.manifest_path();
             let target_dir = SIMPLE_RAYTRACER.target_dir();
 
@@ -305,13 +305,13 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
             eprintln!("[BENCH RUN] ebobby/simple-raytracer");
             fs::copy(
                 target_dir.join("debug").join("main"),
-                Path::new("build").join("raytracer_cg_clif"),
+                RelPath::BUILD.to_path().join("raytracer_cg_clif"),
             )
             .unwrap();
 
             let mut bench_run =
                 hyperfine_command(0, run_runs, None, "./raytracer_cg_llvm", "./raytracer_cg_clif");
-            bench_run.current_dir(Path::new("build"));
+            bench_run.current_dir(RelPath::BUILD.to_path());
             spawn_and_wait(bench_run);
         } else {
             spawn_and_wait(SIMPLE_RAYTRACER.clean(&runner.target_compiler.cargo));
@@ -430,7 +430,6 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
 pub(crate) fn run_tests(
     channel: &str,
     sysroot_kind: SysrootKind,
-    dist_dir: &Path,
     cg_clif_dylib: &Path,
     host_triple: &str,
     target_triple: &str,
@@ -441,13 +440,12 @@ pub(crate) fn run_tests(
         build_sysroot::build_sysroot(
             channel,
             SysrootKind::None,
-            &dist_dir,
             cg_clif_dylib,
             &host_triple,
             &target_triple,
         );
 
-        let _ = fs::remove_dir_all(Path::new("build").join("example"));
+        BUILD_EXAMPLE_OUT_DIR.ensure_fresh();
         runner.run_testsuite(NO_SYSROOT_SUITE);
     } else {
         eprintln!("[SKIP] no_sysroot tests");
@@ -460,7 +458,6 @@ pub(crate) fn run_tests(
         build_sysroot::build_sysroot(
             channel,
             sysroot_kind,
-            &dist_dir,
             cg_clif_dylib,
             &host_triple,
             &target_triple,
@@ -481,7 +478,6 @@ pub(crate) fn run_tests(
 }
 
 struct TestRunner {
-    out_dir: PathBuf,
     is_native: bool,
     jit_supported: bool,
     host_compiler: Compiler,
@@ -490,23 +486,13 @@ struct TestRunner {
 
 impl TestRunner {
     pub fn new(host_triple: String, target_triple: String) -> Self {
-        let root_dir = env::current_dir().unwrap();
-
-        let mut out_dir = root_dir.clone();
-        out_dir.push("build");
-        out_dir.push("example");
-
         let is_native = host_triple == target_triple;
         let jit_supported =
             target_triple.contains("x86_64") && is_native && !host_triple.contains("windows");
 
-        let mut rustc_clif = root_dir.clone();
-        rustc_clif.push("dist");
-        rustc_clif.push(get_wrapper_file_name("rustc-clif", "bin"));
-
-        let mut rustdoc_clif = root_dir.clone();
-        rustdoc_clif.push("dist");
-        rustdoc_clif.push(get_wrapper_file_name("rustdoc-clif", "bin"));
+        let rustc_clif = RelPath::DIST.to_path().join(get_wrapper_file_name("rustc-clif", "bin"));
+        let rustdoc_clif =
+            RelPath::DIST.to_path().join(get_wrapper_file_name("rustdoc-clif", "bin"));
 
         let mut rustflags = env::var("RUSTFLAGS").ok().unwrap_or("".to_string());
         let mut runner = vec![];
@@ -549,15 +535,15 @@ impl TestRunner {
 
         let target_compiler = Compiler {
             cargo: get_cargo_path(),
-            rustc: rustc_clif.clone(),
-            rustdoc: rustdoc_clif.clone(),
+            rustc: rustc_clif,
+            rustdoc: rustdoc_clif,
             rustflags: rustflags.clone(),
             rustdocflags: rustflags,
             triple: target_triple,
             runner,
         };
 
-        Self { out_dir, is_native, jit_supported, host_compiler, target_compiler }
+        Self { is_native, jit_supported, host_compiler, target_compiler }
     }
 
     pub fn run_testsuite(&self, tests: &[TestCase]) {
@@ -586,9 +572,9 @@ impl TestRunner {
         let mut cmd = Command::new(&self.target_compiler.rustc);
         cmd.args(self.target_compiler.rustflags.split_whitespace());
         cmd.arg("-L");
-        cmd.arg(format!("crate={}", self.out_dir.display()));
+        cmd.arg(format!("crate={}", BUILD_EXAMPLE_OUT_DIR.to_path().display()));
         cmd.arg("--out-dir");
-        cmd.arg(format!("{}", self.out_dir.display()));
+        cmd.arg(format!("{}", BUILD_EXAMPLE_OUT_DIR.to_path().display()));
         cmd.arg("-Cdebuginfo=2");
         cmd.args(args);
         cmd
@@ -613,11 +599,7 @@ impl TestRunner {
             full_cmd.extend(self.target_compiler.runner.iter().cloned());
         }
 
-        full_cmd.push({
-            let mut out_path = self.out_dir.clone();
-            out_path.push(name);
-            out_path.to_str().unwrap().to_string()
-        });
+        full_cmd.push(BUILD_EXAMPLE_OUT_DIR.to_path().join(name).to_str().unwrap().to_string());
 
         for arg in args.into_iter() {
             full_cmd.push(arg.to_string());
diff --git a/build_system/utils.rs b/build_system/utils.rs
index 5a03fcf0856..422492df007 100644
--- a/build_system/utils.rs
+++ b/build_system/utils.rs
@@ -4,7 +4,7 @@ use std::io::Write;
 use std::path::{Path, PathBuf};
 use std::process::{self, Command, Stdio};
 
-use super::prepare::GitRepo;
+use super::path::RelPath;
 use super::rustc_info::{get_cargo_path, get_host_triple, get_rustc_path, get_rustdoc_path};
 
 pub(crate) struct Compiler {
@@ -43,36 +43,18 @@ impl Compiler {
     }
 }
 
-enum CargoProjectSource {
-    Local,
-    GitRepo(&'static GitRepo),
-}
-
 pub(crate) struct CargoProject {
-    source: CargoProjectSource,
-    path: &'static str,
+    source: &'static RelPath,
     target: &'static str,
 }
 
 impl CargoProject {
-    pub(crate) const fn local(path: &'static str, target: &'static str) -> CargoProject {
-        CargoProject { source: CargoProjectSource::Local, path, target }
-    }
-
-    pub(crate) const fn git(
-        git_repo: &'static GitRepo,
-        path: &'static str,
-        target: &'static str,
-    ) -> CargoProject {
-        CargoProject { source: CargoProjectSource::GitRepo(git_repo), path, target }
+    pub(crate) const fn new(path: &'static RelPath, target: &'static str) -> CargoProject {
+        CargoProject { source: path, target }
     }
 
     pub(crate) fn source_dir(&self) -> PathBuf {
-        match self.source {
-            CargoProjectSource::Local => std::env::current_dir().unwrap(),
-            CargoProjectSource::GitRepo(git_repo) => git_repo.source_dir(),
-        }
-        .join(self.path)
+        self.source.to_path()
     }
 
     pub(crate) fn manifest_path(&self) -> PathBuf {
@@ -80,7 +62,7 @@ impl CargoProject {
     }
 
     pub(crate) fn target_dir(&self) -> PathBuf {
-        std::env::current_dir().unwrap().join("build").join(self.target)
+        RelPath::BUILD.join(self.target).to_path()
     }
 
     fn base_cmd(&self, command: &str, cargo: &Path) -> Command {