Skip to content

Commit 4ffa425

Browse files
authored
Merge pull request #319 from GuillaumeGomez/build-system
Rustify prepare.sh command
2 parents 186320a + 08eb006 commit 4ffa425

File tree

17 files changed

+413
-82
lines changed

17 files changed

+413
-82
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ jobs:
119119

120120
- name: Build
121121
run: |
122-
./prepare_build.sh
122+
./y.sh prepare --only-libcore
123123
${{ matrix.libgccjit_version.env_extra }} ./build.sh ${{ matrix.libgccjit_version.extra }}
124124
${{ matrix.libgccjit_version.env_extra }} cargo test ${{ matrix.libgccjit_version.extra }}
125125
./clean_all.sh
@@ -128,7 +128,7 @@ jobs:
128128
run: |
129129
git config --global user.email "[email protected]"
130130
git config --global user.name "User"
131-
./prepare.sh
131+
./y.sh prepare
132132
133133
# Compile is a separate step, as the actions-rs/cargo action supports error annotations
134134
- name: Compile

.github/workflows/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ jobs:
8888

8989
- name: Build
9090
run: |
91-
./prepare_build.sh
91+
./y.sh prepare --only-libcore
9292
./build.sh --release --release-sysroot
9393
cargo test
9494
./clean_all.sh
@@ -97,7 +97,7 @@ jobs:
9797
run: |
9898
git config --global user.email "[email protected]"
9999
git config --global user.name "User"
100-
./prepare.sh
100+
./y.sh prepare
101101
102102
# Compile is a separate step, as the actions-rs/cargo action supports error annotations
103103
- name: Compile

.github/workflows/stdarch.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ jobs:
102102

103103
- name: Build
104104
run: |
105-
./prepare_build.sh
105+
./y.sh prepare --only-libcore
106106
./build.sh --release --release-sysroot
107107
cargo test
108108
@@ -115,7 +115,7 @@ jobs:
115115
run: |
116116
git config --global user.email "[email protected]"
117117
git config --global user.name "User"
118-
./prepare.sh
118+
./y.sh prepare
119119
120120
# Compile is a separate step, as the actions-rs/cargo action supports error annotations
121121
- name: Compile

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ tools/llvmint
2525
tools/llvmint-2
2626
# The `llvm` folder is generated by the `tools/generate_intrinsics.py` script to update intrinsics.
2727
llvm
28+
build_system/target

Readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ $ export RUST_COMPILER_RT_ROOT="$PWD/llvm/compiler-rt"
6565
Then you can run commands like this:
6666

6767
```bash
68-
$ ./prepare.sh # download and patch sysroot src and install hyperfine for benchmarking
68+
$ ./y.sh prepare # download and patch sysroot src and install hyperfine for benchmarking
6969
$ LIBRARY_PATH=$(cat gcc_path) LD_LIBRARY_PATH=$(cat gcc_path) ./build.sh --release
7070
```
7171

build_sysroot/prepare_sysroot_src.sh

Lines changed: 0 additions & 39 deletions
This file was deleted.

build_system/Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build_system/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "y"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[[bin]]
7+
name = "y"
8+
path = "src/main.rs"

build_system/src/build.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub fn run() -> Result<(), String> {
2+
Ok(())
3+
}

build_system/src/main.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use std::env;
2+
use std::process;
3+
4+
mod build;
5+
mod prepare;
6+
mod rustc_info;
7+
mod utils;
8+
9+
macro_rules! arg_error {
10+
($($err:tt)*) => {{
11+
eprintln!($($err)*);
12+
usage();
13+
std::process::exit(1);
14+
}};
15+
}
16+
17+
fn usage() {
18+
// println!("{}", include_str!("usage.txt"));
19+
}
20+
21+
pub enum Command {
22+
Prepare,
23+
Build,
24+
}
25+
26+
fn main() {
27+
if env::var("RUST_BACKTRACE").is_err() {
28+
env::set_var("RUST_BACKTRACE", "1");
29+
}
30+
31+
let command = match env::args().nth(1).as_deref() {
32+
Some("prepare") => Command::Prepare,
33+
Some("build") => Command::Build,
34+
Some(flag) if flag.starts_with('-') => arg_error!("Expected command found flag {}", flag),
35+
Some(command) => arg_error!("Unknown command {}", command),
36+
None => {
37+
usage();
38+
process::exit(0);
39+
}
40+
};
41+
42+
if let Err(e) = match command {
43+
Command::Prepare => prepare::run(),
44+
Command::Build => build::run(),
45+
} {
46+
eprintln!("Command failed to run: {e:?}");
47+
process::exit(1);
48+
}
49+
}

build_system/src/prepare.rs

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
use crate::rustc_info::get_rustc_path;
2+
use crate::utils::{cargo_install, git_clone, run_command, run_command_with_output, walk_dir};
3+
4+
use std::fs;
5+
use std::path::Path;
6+
7+
fn prepare_libcore(sysroot_path: &Path) -> Result<(), String> {
8+
let rustc_path = match get_rustc_path() {
9+
Some(path) => path,
10+
None => return Err("`rustc` path not found".to_owned()),
11+
};
12+
13+
let parent = match rustc_path.parent() {
14+
Some(path) => path,
15+
None => return Err(format!("No parent for `{}`", rustc_path.display())),
16+
};
17+
18+
let rustlib_dir =
19+
parent
20+
.join("../lib/rustlib/src/rust")
21+
.canonicalize()
22+
.map_err(|e| format!("Failed to canonicalize path: {e:?}"))?;
23+
if !rustlib_dir.is_dir() {
24+
return Err("Please install `rust-src` component".to_owned());
25+
}
26+
27+
let sysroot_dir = sysroot_path.join("sysroot_src");
28+
if sysroot_dir.is_dir() {
29+
if let Err(e) = fs::remove_dir_all(&sysroot_dir) {
30+
return Err(format!("Failed to remove `{}`: {:?}", sysroot_dir.display(), e));
31+
}
32+
}
33+
34+
let sysroot_library_dir = sysroot_dir.join("library");
35+
fs::create_dir_all(&sysroot_library_dir)
36+
.map_err(|e| format!(
37+
"Failed to create folder `{}`: {e:?}",
38+
sysroot_library_dir.display(),
39+
))?;
40+
41+
run_command(&[&"cp", &"-r", &rustlib_dir.join("library"), &sysroot_dir], None)?;
42+
43+
println!("[GIT] init (cwd): `{}`", sysroot_dir.display());
44+
run_command(&[&"git", &"init"], Some(&sysroot_dir))?;
45+
println!("[GIT] add (cwd): `{}`", sysroot_dir.display());
46+
run_command(&[&"git", &"add", &"."], Some(&sysroot_dir))?;
47+
println!("[GIT] commit (cwd): `{}`", sysroot_dir.display());
48+
49+
// This is needed on systems where nothing is configured.
50+
// git really needs something here, or it will fail.
51+
// Even using --author is not enough.
52+
run_command(&[&"git", &"config", &"user.email", &"[email protected]"], Some(&sysroot_dir))?;
53+
run_command(&[&"git", &"config", &"user.name", &"None"], Some(&sysroot_dir))?;
54+
run_command(&[&"git", &"config", &"core.autocrlf", &"false"], Some(&sysroot_dir))?;
55+
run_command(&[&"git", &"config", &"commit.gpgSign", &"false"], Some(&sysroot_dir))?;
56+
run_command(&[&"git", &"commit", &"-m", &"Initial commit", &"-q"], Some(&sysroot_dir))?;
57+
58+
let mut patches = Vec::new();
59+
walk_dir("patches", |_| Ok(()), |file_path: &Path| {
60+
patches.push(file_path.to_path_buf());
61+
Ok(())
62+
})?;
63+
patches.sort();
64+
for file_path in patches {
65+
println!("[GIT] apply `{}`", file_path.display());
66+
let path = Path::new("../..").join(file_path);
67+
run_command_with_output(&[&"git", &"apply", &path], Some(&sysroot_dir))?;
68+
run_command_with_output(&[&"git", &"add", &"-A"], Some(&sysroot_dir))?;
69+
run_command_with_output(
70+
&[&"git", &"commit", &"--no-gpg-sign", &"-m", &format!("Patch {}", path.display())],
71+
Some(&sysroot_dir),
72+
)?;
73+
}
74+
println!("Successfully prepared libcore for building");
75+
Ok(())
76+
}
77+
78+
// build with cg_llvm for perf comparison
79+
fn build_raytracer(repo_dir: &Path) -> Result<(), String> {
80+
run_command(&[&"cargo", &"build"], Some(repo_dir))?;
81+
let mv_target = repo_dir.join("raytracer_cg_llvm");
82+
if mv_target.is_file() {
83+
std::fs::remove_file(&mv_target)
84+
.map_err(|e| format!("Failed to remove file `{}`: {e:?}", mv_target.display()))?;
85+
}
86+
run_command(&[&"mv", &"target/debug/main", &"raytracer_cg_llvm"], Some(repo_dir))?;
87+
Ok(())
88+
}
89+
90+
fn clone_and_setup<F>(repo_url: &str, checkout_commit: &str, extra: Option<F>) -> Result<(), String>
91+
where
92+
F: Fn(&Path) -> Result<(), String>,
93+
{
94+
let clone_result = git_clone(repo_url, None)?;
95+
if !clone_result.ran_clone {
96+
println!("`{}` has already been cloned", clone_result.repo_name);
97+
}
98+
let repo_path = Path::new(&clone_result.repo_name);
99+
run_command(&[&"git", &"checkout", &"--", &"."], Some(&repo_path))?;
100+
run_command(&[&"git", &"checkout", &checkout_commit], Some(&repo_path))?;
101+
let filter = format!("-{}-", clone_result.repo_name);
102+
walk_dir("crate_patches", |_| Ok(()), |file_path| {
103+
let s = file_path.as_os_str().to_str().unwrap();
104+
if s.contains(&filter) && s.ends_with(".patch") {
105+
run_command_with_output(
106+
&[&"git", &"am", &file_path.canonicalize().unwrap()],
107+
Some(&repo_path),
108+
)?;
109+
}
110+
Ok(())
111+
})?;
112+
if let Some(extra) = extra {
113+
extra(&repo_path)?;
114+
}
115+
Ok(())
116+
}
117+
118+
struct PrepareArg {
119+
only_libcore: bool,
120+
}
121+
122+
impl PrepareArg {
123+
fn new() -> Result<Option<Self>, String> {
124+
let mut only_libcore = false;
125+
126+
for arg in std::env::args().skip(2) {
127+
match arg.as_str() {
128+
"--only-libcore" => only_libcore = true,
129+
"--help" => {
130+
Self::usage();
131+
return Ok(None)
132+
}
133+
a => return Err(format!("Unknown argument `{a}`")),
134+
}
135+
}
136+
Ok(Some(Self {
137+
only_libcore,
138+
}))
139+
}
140+
141+
fn usage() {
142+
println!(r#"
143+
`prepare` command help:
144+
145+
--only-libcore : Only setup libcore and don't clone other repositories
146+
--help : Show this help
147+
"#)
148+
}
149+
}
150+
151+
pub fn run() -> Result<(), String> {
152+
let args = match PrepareArg::new()? {
153+
Some(a) => a,
154+
None => return Ok(()),
155+
};
156+
let sysroot_path = Path::new("build_sysroot");
157+
prepare_libcore(sysroot_path)?;
158+
159+
if !args.only_libcore {
160+
cargo_install("hyperfine")?;
161+
162+
let to_clone = &[
163+
("https://github.com/rust-random/rand.git", "0f933f9c7176e53b2a3c7952ded484e1783f0bf1", None),
164+
("https://github.com/rust-lang/regex.git", "341f207c1071f7290e3f228c710817c280c8dca1", None),
165+
("https://github.com/ebobby/simple-raytracer", "804a7a21b9e673a482797aa289a18ed480e4d813", Some(build_raytracer)),
166+
];
167+
168+
for (repo_url, checkout_commit, cb) in to_clone {
169+
clone_and_setup(repo_url, checkout_commit, *cb)?;
170+
}
171+
}
172+
173+
println!("Successfully ran `prepare`");
174+
Ok(())
175+
}

build_system/src/rustc_info.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use std::path::{Path, PathBuf};
2+
3+
use crate::utils::run_command;
4+
5+
pub fn get_rustc_path() -> Option<PathBuf> {
6+
if let Ok(rustc) = std::env::var("RUSTC") {
7+
return Some(PathBuf::from(rustc));
8+
}
9+
run_command(&[&"rustup", &"which", &"rustc"], None)
10+
.ok()
11+
.map(|out| Path::new(String::from_utf8(out.stdout).unwrap().trim()).to_owned())
12+
}

0 commit comments

Comments
 (0)