Skip to content

Rustify prepare.sh command #319

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ jobs:

- name: Build
run: |
./prepare_build.sh
./y.sh prepare --only-libcore
${{ matrix.libgccjit_version.env_extra }} ./build.sh ${{ matrix.libgccjit_version.extra }}
${{ matrix.libgccjit_version.env_extra }} cargo test ${{ matrix.libgccjit_version.extra }}
./clean_all.sh
Expand All @@ -128,7 +128,7 @@ jobs:
run: |
git config --global user.email "[email protected]"
git config --global user.name "User"
./prepare.sh
./y.sh prepare

# Compile is a separate step, as the actions-rs/cargo action supports error annotations
- name: Compile
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ jobs:

- name: Build
run: |
./prepare_build.sh
./y.sh prepare --only-libcore
./build.sh --release --release-sysroot
cargo test
./clean_all.sh
Expand All @@ -97,7 +97,7 @@ jobs:
run: |
git config --global user.email "[email protected]"
git config --global user.name "User"
./prepare.sh
./y.sh prepare

# Compile is a separate step, as the actions-rs/cargo action supports error annotations
- name: Compile
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/stdarch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ jobs:

- name: Build
run: |
./prepare_build.sh
./y.sh prepare --only-libcore
./build.sh --release --release-sysroot
cargo test

Expand All @@ -115,7 +115,7 @@ jobs:
run: |
git config --global user.email "[email protected]"
git config --global user.name "User"
./prepare.sh
./y.sh prepare

# Compile is a separate step, as the actions-rs/cargo action supports error annotations
- name: Compile
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ tools/llvmint
tools/llvmint-2
# The `llvm` folder is generated by the `tools/generate_intrinsics.py` script to update intrinsics.
llvm
build_system/target
2 changes: 1 addition & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ $ export RUST_COMPILER_RT_ROOT="$PWD/llvm/compiler-rt"
Then you can run commands like this:

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

Expand Down
39 changes: 0 additions & 39 deletions build_sysroot/prepare_sysroot_src.sh

This file was deleted.

7 changes: 7 additions & 0 deletions build_system/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions build_system/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "y"
version = "0.1.0"
edition = "2021"

[[bin]]
name = "y"
path = "src/main.rs"
3 changes: 3 additions & 0 deletions build_system/src/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub fn run() -> Result<(), String> {
Ok(())
}
49 changes: 49 additions & 0 deletions build_system/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use std::env;
use std::process;

mod build;
mod prepare;
mod rustc_info;
mod utils;

macro_rules! arg_error {
($($err:tt)*) => {{
eprintln!($($err)*);
usage();
std::process::exit(1);
}};
}

fn usage() {
// println!("{}", include_str!("usage.txt"));
}

pub enum Command {
Prepare,
Build,
}

fn main() {
if env::var("RUST_BACKTRACE").is_err() {
env::set_var("RUST_BACKTRACE", "1");
}

let command = match env::args().nth(1).as_deref() {
Some("prepare") => Command::Prepare,
Some("build") => Command::Build,
Some(flag) if flag.starts_with('-') => arg_error!("Expected command found flag {}", flag),
Some(command) => arg_error!("Unknown command {}", command),
None => {
usage();
process::exit(0);
}
};

if let Err(e) = match command {
Command::Prepare => prepare::run(),
Command::Build => build::run(),
} {
eprintln!("Command failed to run: {e:?}");
process::exit(1);
}
}
175 changes: 175 additions & 0 deletions build_system/src/prepare.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
use crate::rustc_info::get_rustc_path;
use crate::utils::{cargo_install, git_clone, run_command, run_command_with_output, walk_dir};

use std::fs;
use std::path::Path;

fn prepare_libcore(sysroot_path: &Path) -> Result<(), String> {
let rustc_path = match get_rustc_path() {
Some(path) => path,
None => return Err("`rustc` path not found".to_owned()),
};

let parent = match rustc_path.parent() {
Some(path) => path,
None => return Err(format!("No parent for `{}`", rustc_path.display())),
};

let rustlib_dir =
parent
.join("../lib/rustlib/src/rust")
.canonicalize()
.map_err(|e| format!("Failed to canonicalize path: {e:?}"))?;
if !rustlib_dir.is_dir() {
return Err("Please install `rust-src` component".to_owned());
}

let sysroot_dir = sysroot_path.join("sysroot_src");
if sysroot_dir.is_dir() {
if let Err(e) = fs::remove_dir_all(&sysroot_dir) {
return Err(format!("Failed to remove `{}`: {:?}", sysroot_dir.display(), e));
}
}

let sysroot_library_dir = sysroot_dir.join("library");
fs::create_dir_all(&sysroot_library_dir)
.map_err(|e| format!(
"Failed to create folder `{}`: {e:?}",
sysroot_library_dir.display(),
))?;

run_command(&[&"cp", &"-r", &rustlib_dir.join("library"), &sysroot_dir], None)?;

println!("[GIT] init (cwd): `{}`", sysroot_dir.display());
run_command(&[&"git", &"init"], Some(&sysroot_dir))?;
println!("[GIT] add (cwd): `{}`", sysroot_dir.display());
run_command(&[&"git", &"add", &"."], Some(&sysroot_dir))?;
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.
run_command(&[&"git", &"config", &"user.email", &"[email protected]"], 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))?;

let mut patches = Vec::new();
walk_dir("patches", |_| Ok(()), |file_path: &Path| {
patches.push(file_path.to_path_buf());
Ok(())
})?;
patches.sort();
for file_path in patches {
println!("[GIT] apply `{}`", file_path.display());
let path = Path::new("../..").join(file_path);
run_command_with_output(&[&"git", &"apply", &path], Some(&sysroot_dir))?;
run_command_with_output(&[&"git", &"add", &"-A"], Some(&sysroot_dir))?;
run_command_with_output(
&[&"git", &"commit", &"--no-gpg-sign", &"-m", &format!("Patch {}", path.display())],
Some(&sysroot_dir),
)?;
}
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))?;
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()))?;
}
run_command(&[&"mv", &"target/debug/main", &"raytracer_cg_llvm"], Some(repo_dir))?;
Ok(())
}

fn clone_and_setup<F>(repo_url: &str, checkout_commit: &str, extra: Option<F>) -> Result<(), String>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GitRepo struct of cg_clif handles using the github zip archives for much faster downloads when curl is available as well as applying patches and writing a lockfile for reproducibility: https://github.com/bjorn3/rustc_codegen_cranelift/blob/9aa5fbf79c39867f144e5a38c53a8edd2e2069ba/build_system/prepare.rs#L96 For an initial rewrite the current code is fine too.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be nice to have later on indeed.

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);
run_command(&[&"git", &"checkout", &"--", &"."], Some(&repo_path))?;
run_command(&[&"git", &"checkout", &checkout_commit], Some(&repo_path))?;
let filter = format!("-{}-", clone_result.repo_name);
walk_dir("crate_patches", |_| Ok(()), |file_path| {
let s = file_path.as_os_str().to_str().unwrap();
if s.contains(&filter) && s.ends_with(".patch") {
run_command_with_output(
&[&"git", &"am", &file_path.canonicalize().unwrap()],
Some(&repo_path),
)?;
}
Ok(())
})?;
if let Some(extra) = extra {
extra(&repo_path)?;
}
Ok(())
}

struct PrepareArg {
only_libcore: bool,
}

impl PrepareArg {
fn new() -> Result<Option<Self>, String> {
let mut only_libcore = false;

for arg in std::env::args().skip(2) {
match arg.as_str() {
"--only-libcore" => only_libcore = true,
"--help" => {
Self::usage();
return Ok(None)
}
a => return Err(format!("Unknown argument `{a}`")),
}
}
Ok(Some(Self {
only_libcore,
}))
}

fn usage() {
println!(r#"
`prepare` command help:

--only-libcore : Only setup libcore and don't clone other repositories
--help : Show this help
"#)
}
}

pub fn run() -> Result<(), String> {
let args = match PrepareArg::new()? {
Some(a) => a,
None => return Ok(()),
};
let sysroot_path = Path::new("build_sysroot");
prepare_libcore(sysroot_path)?;

if !args.only_libcore {
cargo_install("hyperfine")?;

let to_clone = &[
("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)),
];

for (repo_url, checkout_commit, cb) in to_clone {
clone_and_setup(repo_url, checkout_commit, *cb)?;
}
}

println!("Successfully ran `prepare`");
Ok(())
}
12 changes: 12 additions & 0 deletions build_system/src/rustc_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use std::path::{Path, PathBuf};

use crate::utils::run_command;

pub fn get_rustc_path() -> Option<PathBuf> {
if let Ok(rustc) = std::env::var("RUSTC") {
return Some(PathBuf::from(rustc));
}
run_command(&[&"rustup", &"which", &"rustc"], None)
.ok()
.map(|out| Path::new(String::from_utf8(out.stdout).unwrap().trim()).to_owned())
}
Loading