3 use std::path::{Path, PathBuf};
4 use std::process::Command;
6 use super::build_sysroot::{SYSROOT_RUSTC_VERSION, SYSROOT_SRC};
7 use super::path::{Dirs, RelPath};
8 use super::rustc_info::{get_file_name, get_rustc_path, get_rustc_version};
9 use super::utils::{copy_dir_recursively, spawn_and_wait, Compiler};
11 pub(crate) fn prepare(dirs: &Dirs) {
12 if RelPath::DOWNLOAD.to_path(dirs).exists() {
13 std::fs::remove_dir_all(RelPath::DOWNLOAD.to_path(dirs)).unwrap();
15 std::fs::create_dir_all(RelPath::DOWNLOAD.to_path(dirs)).unwrap();
17 prepare_sysroot(dirs);
19 // FIXME maybe install this only locally?
20 eprintln!("[INSTALL] hyperfine");
24 .env_remove("CARGO_TARGET_DIR")
30 super::abi_cafe::ABI_CAFE_REPO.fetch(dirs);
31 super::tests::RAND_REPO.fetch(dirs);
32 super::tests::REGEX_REPO.fetch(dirs);
33 super::tests::PORTABLE_SIMD_REPO.fetch(dirs);
34 super::tests::SIMPLE_RAYTRACER_REPO.fetch(dirs);
36 eprintln!("[LLVM BUILD] simple-raytracer");
37 let host_compiler = Compiler::host();
38 let build_cmd = super::tests::SIMPLE_RAYTRACER.build(&host_compiler, dirs);
39 spawn_and_wait(build_cmd);
41 super::tests::SIMPLE_RAYTRACER
43 .join(&host_compiler.triple)
45 .join(get_file_name("main", "bin")),
46 RelPath::BUILD.to_path(dirs).join(get_file_name("raytracer_cg_llvm", "bin")),
51 fn prepare_sysroot(dirs: &Dirs) {
52 let rustc_path = get_rustc_path();
53 let sysroot_src_orig = rustc_path.parent().unwrap().join("../lib/rustlib/src/rust");
54 let sysroot_src = SYSROOT_SRC;
56 assert!(sysroot_src_orig.exists());
58 sysroot_src.ensure_fresh(dirs);
59 fs::create_dir_all(sysroot_src.to_path(dirs).join("library")).unwrap();
60 eprintln!("[COPY] sysroot src");
62 &sysroot_src_orig.join("library"),
63 &sysroot_src.to_path(dirs).join("library"),
66 let rustc_version = get_rustc_version();
67 fs::write(SYSROOT_RUSTC_VERSION.to_path(dirs), &rustc_version).unwrap();
69 eprintln!("[GIT] init");
70 init_git_repo(&sysroot_src.to_path(dirs));
72 apply_patches(dirs, "sysroot", &sysroot_src.to_path(dirs));
75 pub(crate) struct GitRepo {
78 patch_name: &'static str,
82 Github { user: &'static str, repo: &'static str },
86 pub(crate) const fn github(
90 patch_name: &'static str,
92 GitRepo { url: GitRepoUrl::Github { user, repo }, rev, patch_name }
95 pub(crate) const fn source_dir(&self) -> RelPath {
97 GitRepoUrl::Github { user: _, repo } => RelPath::DOWNLOAD.join(repo),
101 fn fetch(&self, dirs: &Dirs) {
103 GitRepoUrl::Github { user, repo } => {
104 clone_repo_shallow_github(
106 &self.source_dir().to_path(dirs),
113 apply_patches(dirs, self.patch_name, &self.source_dir().to_path(dirs));
118 fn clone_repo(download_dir: &Path, repo: &str, rev: &str) {
119 eprintln!("[CLONE] {}", repo);
120 // Ignore exit code as the repo may already have been checked out
121 Command::new("git").arg("clone").arg(repo).arg(&download_dir).spawn().unwrap().wait().unwrap();
123 let mut clean_cmd = Command::new("git");
124 clean_cmd.arg("checkout").arg("--").arg(".").current_dir(&download_dir);
125 spawn_and_wait(clean_cmd);
127 let mut checkout_cmd = Command::new("git");
128 checkout_cmd.arg("checkout").arg("-q").arg(rev).current_dir(download_dir);
129 spawn_and_wait(checkout_cmd);
132 fn clone_repo_shallow_github(dirs: &Dirs, download_dir: &Path, user: &str, repo: &str, rev: &str) {
134 // Older windows doesn't have tar or curl by default. Fall back to using git.
135 clone_repo(download_dir, &format!("https://github.com/{}/{}.git", user, repo), rev);
139 let archive_url = format!("https://github.com/{}/{}/archive/{}.tar.gz", user, repo, rev);
140 let archive_file = RelPath::DOWNLOAD.to_path(dirs).join(format!("{}.tar.gz", rev));
141 let archive_dir = RelPath::DOWNLOAD.to_path(dirs).join(format!("{}-{}", repo, rev));
143 eprintln!("[DOWNLOAD] {}/{} from {}", user, repo, archive_url);
145 // Remove previous results if they exists
146 let _ = std::fs::remove_file(&archive_file);
147 let _ = std::fs::remove_dir_all(&archive_dir);
148 let _ = std::fs::remove_dir_all(&download_dir);
150 // Download zip archive
151 let mut download_cmd = Command::new("curl");
152 download_cmd.arg("--location").arg("--output").arg(&archive_file).arg(archive_url);
153 spawn_and_wait(download_cmd);
155 // Unpack tar archive
156 let mut unpack_cmd = Command::new("tar");
157 unpack_cmd.arg("xf").arg(&archive_file).current_dir(RelPath::DOWNLOAD.to_path(dirs));
158 spawn_and_wait(unpack_cmd);
160 // Rename unpacked dir to the expected name
161 std::fs::rename(archive_dir, &download_dir).unwrap();
163 init_git_repo(&download_dir);
166 std::fs::remove_file(archive_file).unwrap();
169 fn init_git_repo(repo_dir: &Path) {
170 let mut git_init_cmd = Command::new("git");
171 git_init_cmd.arg("init").arg("-q").current_dir(repo_dir);
172 spawn_and_wait(git_init_cmd);
174 let mut git_add_cmd = Command::new("git");
175 git_add_cmd.arg("add").arg(".").current_dir(repo_dir);
176 spawn_and_wait(git_add_cmd);
178 let mut git_commit_cmd = Command::new("git");
181 .arg("user.name=Dummy")
183 .arg("user.email=dummy@example.com")
186 .arg("Initial commit")
188 .current_dir(repo_dir);
189 spawn_and_wait(git_commit_cmd);
192 fn get_patches(dirs: &Dirs, crate_name: &str) -> Vec<PathBuf> {
193 let mut patches: Vec<_> = fs::read_dir(RelPath::PATCHES.to_path(dirs))
195 .map(|entry| entry.unwrap().path())
196 .filter(|path| path.extension() == Some(OsStr::new("patch")))
205 .starts_with(crate_name)
212 fn apply_patches(dirs: &Dirs, crate_name: &str, target_dir: &Path) {
213 if crate_name == "<none>" {
217 for patch in get_patches(dirs, crate_name) {
219 "[PATCH] {:?} <- {:?}",
220 target_dir.file_name().unwrap(),
221 patch.file_name().unwrap()
223 let mut apply_patch_cmd = Command::new("git");
226 .arg("user.name=Dummy")
228 .arg("user.email=dummy@example.com")
232 .current_dir(target_dir);
233 spawn_and_wait(apply_patch_cmd);