rust/compiler/rustc_codegen_gcc/build_system/src/prepare.rs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

256 lines
7.7 KiB
Rust
Raw Normal View History

2023-08-18 14:06:20 +00:00
use crate::rustc_info::get_rustc_path;
2023-08-19 16:24:01 +00:00
use crate::utils::{cargo_install, git_clone, run_command, run_command_with_output, walk_dir};
2023-08-18 14:06:20 +00:00
use std::fs;
use std::path::Path;
2023-10-19 11:48:42 +00:00
fn prepare_libcore(sysroot_path: &Path, libgccjit12_patches: bool, cross_compile: bool) -> Result<(), String> {
2023-08-18 14:06:20 +00:00
let rustc_path = match get_rustc_path() {
Some(path) => path,
2023-10-04 14:01:02 +00:00
None => return Err("`rustc` path not found".to_string()),
2023-08-18 14:06:20 +00:00
};
let parent = match rustc_path.parent() {
Some(path) => path,
None => return Err(format!("No parent for `{}`", rustc_path.display())),
};
2023-09-26 14:09:51 +00:00
let rustlib_dir = parent
.join("../lib/rustlib/src/rust")
.canonicalize()
2023-10-04 14:01:02 +00:00
.map_err(|error| format!("Failed to canonicalize path: {:?}", error))?;
2023-08-18 14:06:20 +00:00
if !rustlib_dir.is_dir() {
2023-10-04 14:01:02 +00:00
return Err("Please install `rust-src` component".to_string());
2023-08-18 14:06:20 +00:00
}
2023-08-19 18:53:47 +00:00
let sysroot_dir = sysroot_path.join("sysroot_src");
2023-08-18 14:06:20 +00:00
if sysroot_dir.is_dir() {
2023-10-04 14:01:02 +00:00
if let Err(error) = fs::remove_dir_all(&sysroot_dir) {
2023-09-26 14:09:51 +00:00
return Err(format!(
"Failed to remove `{}`: {:?}",
sysroot_dir.display(),
2023-10-04 14:01:02 +00:00
error,
2023-09-26 14:09:51 +00:00
));
2023-08-18 14:06:20 +00:00
}
}
let sysroot_library_dir = sysroot_dir.join("library");
2023-10-04 14:01:02 +00:00
fs::create_dir_all(&sysroot_library_dir).map_err(|error| {
2023-09-26 14:09:51 +00:00
format!(
2023-10-04 14:01:02 +00:00
"Failed to create folder `{}`: {:?}",
2023-08-18 14:06:20 +00:00
sysroot_library_dir.display(),
2023-10-04 14:01:02 +00:00
error,
2023-09-26 14:09:51 +00:00
)
})?;
2023-08-18 14:06:20 +00:00
2023-09-26 14:09:51 +00:00
run_command(
&[&"cp", &"-r", &rustlib_dir.join("library"), &sysroot_dir],
None,
)?;
2023-08-18 14:06:20 +00:00
println!("[GIT] init (cwd): `{}`", sysroot_dir.display());
2023-08-19 18:53:47 +00:00
run_command(&[&"git", &"init"], Some(&sysroot_dir))?;
2023-08-18 14:06:20 +00:00
println!("[GIT] add (cwd): `{}`", sysroot_dir.display());
2023-08-19 18:53:47 +00:00
run_command(&[&"git", &"add", &"."], Some(&sysroot_dir))?;
2023-08-18 14:06:20 +00:00
println!("[GIT] commit (cwd): `{}`", sysroot_dir.display());
// This is needed on systems where nothing is configured.
// git really needs something here, or it will fail.
// Even using --author is not enough.
2023-09-26 14:09:51 +00:00
run_command(
&[&"git", &"config", &"user.email", &"none@example.com"],
Some(&sysroot_dir),
)?;
run_command(
&[&"git", &"config", &"user.name", &"None"],
Some(&sysroot_dir),
)?;
run_command(
&[&"git", &"config", &"core.autocrlf", &"false"],
Some(&sysroot_dir),
)?;
run_command(
&[&"git", &"config", &"commit.gpgSign", &"false"],
Some(&sysroot_dir),
)?;
run_command(
&[&"git", &"commit", &"-m", &"Initial commit", &"-q"],
Some(&sysroot_dir),
)?;
2023-08-18 14:06:20 +00:00
2023-08-19 18:53:47 +00:00
let mut patches = Vec::new();
2023-09-26 14:09:51 +00:00
walk_dir(
"patches",
|_| Ok(()),
|file_path: &Path| {
patches.push(file_path.to_path_buf());
Ok(())
},
)?;
2023-09-06 23:01:04 +00:00
if cross_compile {
walk_dir("cross_patches", |_| Ok(()), |file_path: &Path| {
patches.push(file_path.to_path_buf());
Ok(())
})?;
}
2023-10-19 11:48:42 +00:00
if libgccjit12_patches {
walk_dir(
"patches/libgccjit12",
|_| Ok(()),
|file_path: &Path| {
patches.push(file_path.to_path_buf());
Ok(())
},
)?;
}
2023-08-19 18:53:47 +00:00
patches.sort();
for file_path in patches {
2023-08-18 14:06:20 +00:00
println!("[GIT] apply `{}`", file_path.display());
let path = Path::new("../..").join(file_path);
2023-10-04 14:01:02 +00:00
run_command_with_output(&[&"git", &"apply", &path], Some(&sysroot_dir))?;
run_command_with_output(&[&"git", &"add", &"-A"], Some(&sysroot_dir))?;
2023-08-19 16:24:01 +00:00
run_command_with_output(
2023-09-26 14:09:51 +00:00
&[
&"git",
&"commit",
&"--no-gpg-sign",
&"-m",
&format!("Patch {}", path.display()),
],
2023-08-18 14:06:20 +00:00
Some(&sysroot_dir),
)?;
2023-08-19 18:53:47 +00:00
}
2023-08-18 14:06:20 +00:00
println!("Successfully prepared libcore for building");
Ok(())
}
// build with cg_llvm for perf comparison
fn build_raytracer(repo_dir: &Path) -> Result<(), String> {
run_command(&[&"cargo", &"build"], Some(repo_dir))?;
2023-08-19 18:53:47 +00:00
let mv_target = repo_dir.join("raytracer_cg_llvm");
if mv_target.is_file() {
std::fs::remove_file(&mv_target)
.map_err(|e| format!("Failed to remove file `{}`: {e:?}", mv_target.display()))?;
}
2023-09-26 14:09:51 +00:00
run_command(
&[&"mv", &"target/debug/main", &"raytracer_cg_llvm"],
Some(repo_dir),
)?;
2023-08-18 14:06:20 +00:00
Ok(())
}
fn clone_and_setup<F>(repo_url: &str, checkout_commit: &str, extra: Option<F>) -> Result<(), String>
where
F: Fn(&Path) -> Result<(), String>,
{
let clone_result = git_clone(repo_url, None)?;
if !clone_result.ran_clone {
println!("`{}` has already been cloned", clone_result.repo_name);
}
let repo_path = Path::new(&clone_result.repo_name);
2023-08-19 18:53:47 +00:00
run_command(&[&"git", &"checkout", &"--", &"."], Some(&repo_path))?;
run_command(&[&"git", &"checkout", &checkout_commit], Some(&repo_path))?;
2023-08-18 14:06:20 +00:00
let filter = format!("-{}-", clone_result.repo_name);
2023-09-26 14:09:51 +00:00
walk_dir(
"crate_patches",
|_| Ok(()),
|file_path| {
2023-10-04 14:01:02 +00:00
let patch = file_path.as_os_str().to_str().unwrap();
if patch.contains(&filter) && patch.ends_with(".patch") {
2023-09-26 14:09:51 +00:00
run_command_with_output(
&[&"git", &"am", &file_path.canonicalize().unwrap()],
Some(&repo_path),
)?;
}
Ok(())
},
)?;
2023-08-18 14:06:20 +00:00
if let Some(extra) = extra {
2023-08-19 18:53:47 +00:00
extra(&repo_path)?;
2023-08-18 14:06:20 +00:00
}
Ok(())
}
struct PrepareArg {
2023-09-06 23:01:04 +00:00
cross_compile: bool,
2023-08-18 14:06:20 +00:00
only_libcore: bool,
2023-10-19 11:48:42 +00:00
libgccjit12_patches: bool,
2023-08-18 14:06:20 +00:00
}
impl PrepareArg {
fn new() -> Result<Option<Self>, String> {
let mut only_libcore = false;
2023-09-06 23:01:04 +00:00
let mut cross_compile = false;
2023-10-19 11:48:42 +00:00
let mut libgccjit12_patches = false;
2023-08-18 14:06:20 +00:00
for arg in std::env::args().skip(2) {
match arg.as_str() {
"--only-libcore" => only_libcore = true,
2023-09-06 23:01:04 +00:00
"--cross" => cross_compile = true,
2023-10-19 11:48:42 +00:00
"--libgccjit12-patches" => libgccjit12_patches = true,
2023-08-18 14:06:20 +00:00
"--help" => {
Self::usage();
2023-09-26 14:09:51 +00:00
return Ok(None);
2023-08-18 14:06:20 +00:00
}
a => return Err(format!("Unknown argument `{a}`")),
}
}
2023-09-06 23:01:04 +00:00
Ok(Some(Self {
cross_compile,
only_libcore,
2023-10-19 11:48:42 +00:00
libgccjit12_patches,
2023-09-06 23:01:04 +00:00
}))
2023-08-18 14:06:20 +00:00
}
fn usage() {
2023-09-26 14:09:51 +00:00
println!(
r#"
2023-08-18 14:06:20 +00:00
`prepare` command help:
2023-10-19 11:48:42 +00:00
--only-libcore : Only setup libcore and don't clone other repositories
--cross : Apply the patches needed to do cross-compilation
--libgccjit12-patches : Apply patches needed for libgccjit12
--help : Show this help
2023-09-26 14:09:51 +00:00
"#
)
2023-08-18 14:06:20 +00:00
}
}
pub fn run() -> Result<(), String> {
let args = match PrepareArg::new()? {
Some(a) => a,
None => return Ok(()),
};
2023-08-19 18:53:47 +00:00
let sysroot_path = Path::new("build_sysroot");
2023-10-19 11:48:42 +00:00
prepare_libcore(sysroot_path, args.libgccjit12_patches, args.cross_compile)?;
2023-08-18 14:06:20 +00:00
if !args.only_libcore {
cargo_install("hyperfine")?;
let to_clone = &[
2023-09-26 14:09:51 +00:00
(
"https://github.com/rust-random/rand.git",
"0f933f9c7176e53b2a3c7952ded484e1783f0bf1",
None,
),
(
"https://github.com/rust-lang/regex.git",
"341f207c1071f7290e3f228c710817c280c8dca1",
None,
),
(
"https://github.com/ebobby/simple-raytracer",
"804a7a21b9e673a482797aa289a18ed480e4d813",
Some(build_raytracer),
),
2023-08-18 14:06:20 +00:00
];
for (repo_url, checkout_commit, cb) in to_clone {
clone_and_setup(repo_url, checkout_commit, *cb)?;
}
}
println!("Successfully ran `prepare`");
Ok(())
}