Merge pull request #1339 from bjorn3/better_compiler_management

Many build system improvements
This commit is contained in:
bjorn3 2023-01-13 19:01:01 +01:00 committed by GitHub
commit 20a829acb4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 369 additions and 480 deletions

View file

@ -62,14 +62,6 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Cache cargo registry and index
uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo target dir
uses: actions/cache@v3
with:
@ -99,9 +91,12 @@ jobs:
sudo apt-get update
sudo apt-get install -y gcc-s390x-linux-gnu qemu-user
- name: Windows setup
if: matrix.os == 'windows-latest'
run: git config --global core.autocrlf false
- name: Use sparse cargo registry
run: |
cat >> ~/.cargo/config.toml <<EOF
[unstable]
sparse-registry = true
EOF
- name: Prepare dependencies
run: ./y.rs prepare

View file

@ -13,11 +13,15 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Prepare dependencies
- name: Use sparse cargo registry
run: |
git config --global user.email "user@example.com"
git config --global user.name "User"
./y.rs prepare
cat >> ~/.cargo/config.toml <<EOF
[unstable]
sparse-registry = true
EOF
- name: Prepare dependencies
run: ./y.rs prepare
- name: Patch Cranelift
run: |
@ -32,6 +36,8 @@ jobs:
cat Cargo.toml
cargo fetch
- name: Build without unstable features
# This is the config rust-lang/rust uses for builds
run: ./y.rs build --no-unstable-features

View file

@ -10,25 +10,21 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Cache cargo registry and index
uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo target dir
uses: actions/cache@v3
with:
path: build/cg_clif
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
- name: Prepare dependencies
- name: Use sparse cargo registry
run: |
git config --global user.email "user@example.com"
git config --global user.name "User"
./y.rs prepare
cat >> ~/.cargo/config.toml <<EOF
[unstable]
sparse-registry = true
EOF
- name: Prepare dependencies
run: ./y.rs prepare
- name: Test
run: ./scripts/test_bootstrap.sh
@ -38,25 +34,21 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Cache cargo registry and index
uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo target dir
uses: actions/cache@v3
with:
path: build/cg_clif
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
- name: Prepare dependencies
- name: Use sparse cargo registry
run: |
git config --global user.email "user@example.com"
git config --global user.name "User"
./y.rs prepare
cat >> ~/.cargo/config.toml <<EOF
[unstable]
sparse-registry = true
EOF
- name: Prepare dependencies
run: ./y.rs prepare
- name: Test
run: ./scripts/test_rustc_tests.sh

View file

@ -1,4 +1,6 @@
{
"editor.formatOnSave": true,
// source for rustc_* is not included in the rust-src component; disable the errors about this
"rust-analyzer.diagnostics.disabled": ["unresolved-extern-crate", "unresolved-macro-call"],
"rust-analyzer.imports.granularity.enforce": true,

View file

@ -8,9 +8,9 @@ If not please open an issue.
## Building and testing
```bash
$ git clone https://github.com/bjorn3/rustc_codegen_cranelift.git
$ git clone https://github.com/bjorn3/rustc_codegen_cranelift
$ cd rustc_codegen_cranelift
$ ./y.rs prepare # download and patch sysroot src and install hyperfine for benchmarking
$ ./y.rs prepare
$ ./y.rs build
```
@ -20,13 +20,12 @@ To run the test suite replace the last command with:
$ ./test.sh
```
This will implicitly build cg_clif too. Both `y.rs build` and `test.sh` accept a `--debug` argument to
build in debug mode.
For more docs on how to build and test see [build_system/usage.txt](build_system/usage.txt) or the help message of `./y.rs`.
Alternatively you can download a pre built version from [GHA]. It is listed in the artifacts section
Alternatively you can download a pre built version from [Github Actions]. It is listed in the artifacts section
of workflow runs. Unfortunately due to GHA restrictions you need to be logged in to access it.
[GHA]: https://github.com/bjorn3/rustc_codegen_cranelift/actions?query=branch%3Amaster+event%3Apush+is%3Asuccess
[Github Actions]: https://github.com/bjorn3/rustc_codegen_cranelift/actions?query=branch%3Amaster+event%3Apush+is%3Asuccess
## Usage

View file

@ -10,41 +10,36 @@ use super::SysrootKind;
pub(crate) static ABI_CAFE_REPO: GitRepo =
GitRepo::github("Gankra", "abi-cafe", "4c6dc8c9c687e2b3a760ff2176ce236872b37212", "abi-cafe");
static ABI_CAFE: CargoProject = CargoProject::new(&ABI_CAFE_REPO.source_dir(), "abi_cafe");
pub(crate) static ABI_CAFE: CargoProject =
CargoProject::new(&ABI_CAFE_REPO.source_dir(), "abi_cafe");
pub(crate) fn run(
channel: &str,
sysroot_kind: SysrootKind,
dirs: &Dirs,
cg_clif_dylib: &Path,
host_triple: &str,
target_triple: &str,
host_compiler: &Compiler,
) {
if !config::get_bool("testsuite.abi-cafe") {
eprintln!("[SKIP] abi-cafe");
return;
}
if host_triple != target_triple {
eprintln!("[SKIP] abi-cafe (cross-compilation not supported)");
return;
}
eprintln!("Building sysroot for abi-cafe");
build_sysroot::build_sysroot(
dirs,
channel,
sysroot_kind,
cg_clif_dylib,
host_triple,
target_triple,
host_compiler,
&host_compiler.triple,
);
eprintln!("Running abi-cafe");
let pairs = ["rustc_calls_cgclif", "cgclif_calls_rustc", "cgclif_calls_cc", "cc_calls_cgclif"];
let mut cmd = ABI_CAFE.run(&Compiler::host(), dirs);
let mut cmd = ABI_CAFE.run(host_compiler, dirs);
cmd.arg("--");
cmd.arg("--pairs");
cmd.args(pairs);

View file

@ -21,11 +21,11 @@ pub(crate) static SIMPLE_RAYTRACER_LLVM: CargoProject =
pub(crate) static SIMPLE_RAYTRACER: CargoProject =
CargoProject::new(&SIMPLE_RAYTRACER_REPO.source_dir(), "simple_raytracer");
pub(crate) fn benchmark(dirs: &Dirs) {
benchmark_simple_raytracer(dirs);
pub(crate) fn benchmark(dirs: &Dirs, host_compiler: &Compiler) {
benchmark_simple_raytracer(dirs, host_compiler);
}
fn benchmark_simple_raytracer(dirs: &Dirs) {
fn benchmark_simple_raytracer(dirs: &Dirs, host_compiler: &Compiler) {
if std::process::Command::new("hyperfine").output().is_err() {
eprintln!("Hyperfine not installed");
eprintln!("Hint: Try `cargo install hyperfine` to install hyperfine");
@ -33,8 +33,7 @@ fn benchmark_simple_raytracer(dirs: &Dirs) {
}
eprintln!("[LLVM BUILD] simple-raytracer");
let host_compiler = Compiler::host();
let build_cmd = SIMPLE_RAYTRACER_LLVM.build(&host_compiler, dirs);
let build_cmd = SIMPLE_RAYTRACER_LLVM.build(host_compiler, dirs);
spawn_and_wait(build_cmd);
fs::copy(
SIMPLE_RAYTRACER_LLVM

View file

@ -5,15 +5,15 @@ use super::path::{Dirs, RelPath};
use super::rustc_info::get_file_name;
use super::utils::{is_ci, CargoProject, Compiler};
static CG_CLIF: CargoProject = CargoProject::new(&RelPath::SOURCE, "cg_clif");
pub(crate) static CG_CLIF: CargoProject = CargoProject::new(&RelPath::SOURCE, "cg_clif");
pub(crate) fn build_backend(
dirs: &Dirs,
channel: &str,
host_triple: &str,
host_compiler: &Compiler,
use_unstable_features: bool,
) -> PathBuf {
let mut cmd = CG_CLIF.build(&Compiler::host(), dirs);
let mut cmd = CG_CLIF.build(&host_compiler, dirs);
cmd.env("CARGO_BUILD_INCREMENTAL", "true"); // Force incr comp even in release mode
@ -48,7 +48,7 @@ pub(crate) fn build_backend(
CG_CLIF
.target_dir(dirs)
.join(host_triple)
.join(&host_compiler.triple)
.join(channel)
.join(get_file_name("rustc_codegen_cranelift", "dylib"))
}

View file

@ -17,7 +17,7 @@ pub(crate) fn build_sysroot(
channel: &str,
sysroot_kind: SysrootKind,
cg_clif_dylib_src: &Path,
host_triple: &str,
host_compiler: &Compiler,
target_triple: &str,
) {
eprintln!("[BUILD] sysroot {:?}", sysroot_kind);
@ -53,7 +53,7 @@ pub(crate) fn build_sysroot(
let default_sysroot = super::rustc_info::get_default_sysroot();
let host_rustlib_lib = RUSTLIB_DIR.to_path(dirs).join(host_triple).join("lib");
let host_rustlib_lib = RUSTLIB_DIR.to_path(dirs).join(&host_compiler.triple).join("lib");
let target_rustlib_lib = RUSTLIB_DIR.to_path(dirs).join(target_triple).join("lib");
fs::create_dir_all(&host_rustlib_lib).unwrap();
fs::create_dir_all(&target_rustlib_lib).unwrap();
@ -83,7 +83,7 @@ pub(crate) fn build_sysroot(
SysrootKind::None => {} // Nothing to do
SysrootKind::Llvm => {
for file in fs::read_dir(
default_sysroot.join("lib").join("rustlib").join(host_triple).join("lib"),
default_sysroot.join("lib").join("rustlib").join(&host_compiler.triple).join("lib"),
)
.unwrap()
{
@ -103,7 +103,7 @@ pub(crate) fn build_sysroot(
try_hard_link(&file, host_rustlib_lib.join(file.file_name().unwrap()));
}
if target_triple != host_triple {
if target_triple != host_compiler.triple {
for file in fs::read_dir(
default_sysroot.join("lib").join("rustlib").join(target_triple).join("lib"),
)
@ -115,21 +115,24 @@ pub(crate) fn build_sysroot(
}
}
SysrootKind::Clif => {
build_clif_sysroot_for_triple(dirs, channel, host_triple, &cg_clif_dylib_path, None);
build_clif_sysroot_for_triple(
dirs,
channel,
host_compiler.clone(),
&cg_clif_dylib_path,
);
if host_triple != target_triple {
// When cross-compiling it is often necessary to manually pick the right linker
let linker = match target_triple {
"aarch64-unknown-linux-gnu" => Some("aarch64-linux-gnu-gcc"),
"s390x-unknown-linux-gnu" => Some("s390x-linux-gnu-gcc"),
_ => None,
};
if host_compiler.triple != target_triple {
build_clif_sysroot_for_triple(
dirs,
channel,
target_triple,
{
let mut target_compiler = host_compiler.clone();
target_compiler.triple = target_triple.to_owned();
target_compiler.set_cross_linker_and_runner();
target_compiler
},
&cg_clif_dylib_path,
linker,
);
}
@ -150,14 +153,14 @@ pub(crate) static ORIG_BUILD_SYSROOT: RelPath = RelPath::SOURCE.join("build_sysr
pub(crate) static BUILD_SYSROOT: RelPath = RelPath::DOWNLOAD.join("sysroot");
pub(crate) static SYSROOT_RUSTC_VERSION: RelPath = BUILD_SYSROOT.join("rustc_version");
pub(crate) static SYSROOT_SRC: RelPath = BUILD_SYSROOT.join("sysroot_src");
static STANDARD_LIBRARY: CargoProject = CargoProject::new(&BUILD_SYSROOT, "build_sysroot");
pub(crate) static STANDARD_LIBRARY: CargoProject =
CargoProject::new(&BUILD_SYSROOT, "build_sysroot");
fn build_clif_sysroot_for_triple(
dirs: &Dirs,
channel: &str,
triple: &str,
mut compiler: Compiler,
cg_clif_dylib_path: &Path,
linker: Option<&str>,
) {
match fs::read_to_string(SYSROOT_RUSTC_VERSION.to_path(dirs)) {
Err(e) => {
@ -177,7 +180,7 @@ fn build_clif_sysroot_for_triple(
}
}
let build_dir = STANDARD_LIBRARY.target_dir(dirs).join(triple).join(channel);
let build_dir = STANDARD_LIBRARY.target_dir(dirs).join(&compiler.triple).join(channel);
if !super::config::get_bool("keep_sysroot") {
// Cleanup the deps dir, but keep build scripts and the incremental cache for faster
@ -188,18 +191,13 @@ fn build_clif_sysroot_for_triple(
}
// Build sysroot
let mut rustflags = "-Zforce-unstable-if-unmarked -Cpanic=abort".to_string();
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_path(dirs).to_str().unwrap()));
if channel == "release" {
rustflags.push_str(" -Zmir-opt-level=3");
}
if let Some(linker) = linker {
use std::fmt::Write;
write!(rustflags, " -Clinker={}", linker).unwrap();
}
let mut compiler = Compiler::with_triple(triple.to_owned());
compiler.rustflags = rustflags;
compiler.rustflags += &rustflags;
let mut build_cmd = STANDARD_LIBRARY.build(&compiler, dirs);
if channel == "release" {
build_cmd.arg("--release");
@ -219,7 +217,7 @@ fn build_clif_sysroot_for_triple(
};
try_hard_link(
entry.path(),
RUSTLIB_DIR.to_path(dirs).join(triple).join("lib").join(entry.file_name()),
RUSTLIB_DIR.to_path(dirs).join(&compiler.triple).join("lib").join(entry.file_name()),
);
}
}

View file

@ -2,7 +2,7 @@ use std::env;
use std::path::PathBuf;
use std::process;
use self::utils::is_ci;
use self::utils::{is_ci, Compiler};
mod abi_cafe;
mod bench;
@ -15,32 +15,8 @@ mod rustc_info;
mod tests;
mod utils;
const USAGE: &str = r#"The build system of cg_clif.
USAGE:
./y.rs prepare [--out-dir DIR]
./y.rs build [--debug] [--sysroot none|clif|llvm] [--out-dir DIR] [--no-unstable-features]
./y.rs test [--debug] [--sysroot none|clif|llvm] [--out-dir DIR] [--no-unstable-features]
./y.rs bench [--debug] [--sysroot none|clif|llvm] [--out-dir DIR] [--no-unstable-features]
OPTIONS:
--sysroot none|clif|llvm
Which sysroot libraries to use:
`none` will not include any standard library in the sysroot.
`clif` will build the standard library using Cranelift.
`llvm` will use the pre-compiled standard library of rustc which is compiled with LLVM.
--out-dir DIR
Specify the directory in which the download, build and dist directories are stored.
By default this is the working directory.
--no-unstable-features
fSome features are not yet ready for production usage. This option will disable these
features. This includes the JIT mode and inline assembly support.
"#;
fn usage() {
eprintln!("{USAGE}");
eprintln!("{}", include_str!("usage.txt"));
}
macro_rules! arg_error {
@ -121,24 +97,16 @@ pub fn main() {
}
}
let host_triple = if let Ok(host_triple) = std::env::var("HOST_TRIPLE") {
host_triple
} else if let Some(host_triple) = config::get_value("host") {
host_triple
} else {
rustc_info::get_host_triple()
};
let target_triple = if let Ok(target_triple) = std::env::var("TARGET_TRIPLE") {
if target_triple != "" {
target_triple
} else {
host_triple.clone() // Empty target triple can happen on GHA
}
} else if let Some(target_triple) = config::get_value("target") {
target_triple
} else {
host_triple.clone()
};
let host_compiler = Compiler::llvm_with_triple(
std::env::var("HOST_TRIPLE")
.ok()
.or_else(|| config::get_value("host"))
.unwrap_or_else(|| rustc_info::get_host_triple()),
);
let target_triple = std::env::var("TARGET_TRIPLE")
.ok()
.or_else(|| config::get_value("target"))
.unwrap_or_else(|| host_compiler.triple.clone());
// FIXME allow changing the location of these dirs using cli arguments
let current_dir = std::env::current_dir().unwrap();
@ -167,7 +135,7 @@ pub fn main() {
}
let cg_clif_dylib =
build_backend::build_backend(&dirs, channel, &host_triple, use_unstable_features);
build_backend::build_backend(&dirs, channel, &host_compiler, use_unstable_features);
match command {
Command::Prepare => {
// Handled above
@ -178,18 +146,16 @@ pub fn main() {
channel,
sysroot_kind,
&cg_clif_dylib,
&host_triple,
&host_compiler,
&target_triple,
);
abi_cafe::run(
channel,
sysroot_kind,
&dirs,
&cg_clif_dylib,
&host_triple,
&target_triple,
);
if host_compiler.triple == target_triple {
abi_cafe::run(channel, sysroot_kind, &dirs, &cg_clif_dylib, &host_compiler);
} else {
eprintln!("[SKIP] abi-cafe (cross-compilation not supported)");
return;
}
}
Command::Build => {
build_sysroot::build_sysroot(
@ -197,7 +163,7 @@ pub fn main() {
channel,
sysroot_kind,
&cg_clif_dylib,
&host_triple,
&host_compiler,
&target_triple,
);
}
@ -207,10 +173,10 @@ pub fn main() {
channel,
sysroot_kind,
&cg_clif_dylib,
&host_triple,
&host_compiler,
&target_triple,
);
bench::benchmark(&dirs);
bench::benchmark(&dirs, &host_compiler);
}
}
}

View file

@ -8,7 +8,7 @@ use crate::build_system::rustc_info::get_default_sysroot;
use super::build_sysroot::{BUILD_SYSROOT, ORIG_BUILD_SYSROOT, SYSROOT_RUSTC_VERSION, SYSROOT_SRC};
use super::path::{Dirs, RelPath};
use super::rustc_info::get_rustc_version;
use super::utils::{copy_dir_recursively, retry_spawn_and_wait, spawn_and_wait};
use super::utils::{copy_dir_recursively, git_command, retry_spawn_and_wait, spawn_and_wait};
pub(crate) fn prepare(dirs: &Dirs) {
if RelPath::DOWNLOAD.to_path(dirs).exists() {
@ -16,13 +16,22 @@ pub(crate) fn prepare(dirs: &Dirs) {
}
std::fs::create_dir_all(RelPath::DOWNLOAD.to_path(dirs)).unwrap();
spawn_and_wait(super::build_backend::CG_CLIF.fetch("cargo", dirs));
prepare_sysroot(dirs);
spawn_and_wait(super::build_sysroot::STANDARD_LIBRARY.fetch("cargo", dirs));
spawn_and_wait(super::tests::LIBCORE_TESTS.fetch("cargo", dirs));
super::abi_cafe::ABI_CAFE_REPO.fetch(dirs);
spawn_and_wait(super::abi_cafe::ABI_CAFE.fetch("cargo", dirs));
super::tests::RAND_REPO.fetch(dirs);
spawn_and_wait(super::tests::RAND.fetch("cargo", dirs));
super::tests::REGEX_REPO.fetch(dirs);
spawn_and_wait(super::tests::REGEX.fetch("cargo", dirs));
super::tests::PORTABLE_SIMD_REPO.fetch(dirs);
spawn_and_wait(super::tests::PORTABLE_SIMD.fetch("cargo", dirs));
super::bench::SIMPLE_RAYTRACER_REPO.fetch(dirs);
spawn_and_wait(super::bench::SIMPLE_RAYTRACER.fetch("cargo", dirs));
}
fn prepare_sysroot(dirs: &Dirs) {
@ -31,6 +40,7 @@ fn prepare_sysroot(dirs: &Dirs) {
eprintln!("[COPY] sysroot src");
// FIXME ensure builds error out or update the copy if any of the files copied here change
BUILD_SYSROOT.ensure_fresh(dirs);
copy_dir_recursively(&ORIG_BUILD_SYSROOT.to_path(dirs), &BUILD_SYSROOT.to_path(dirs));
@ -95,14 +105,14 @@ impl GitRepo {
fn clone_repo(download_dir: &Path, repo: &str, rev: &str) {
eprintln!("[CLONE] {}", repo);
// Ignore exit code as the repo may already have been checked out
Command::new("git").arg("clone").arg(repo).arg(&download_dir).spawn().unwrap().wait().unwrap();
git_command(None, "clone").arg(repo).arg(download_dir).spawn().unwrap().wait().unwrap();
let mut clean_cmd = Command::new("git");
clean_cmd.arg("checkout").arg("--").arg(".").current_dir(&download_dir);
let mut clean_cmd = git_command(download_dir, "checkout");
clean_cmd.arg("--").arg(".");
spawn_and_wait(clean_cmd);
let mut checkout_cmd = Command::new("git");
checkout_cmd.arg("checkout").arg("-q").arg(rev).current_dir(download_dir);
let mut checkout_cmd = git_command(download_dir, "checkout");
checkout_cmd.arg("-q").arg(rev);
spawn_and_wait(checkout_cmd);
}
@ -158,25 +168,16 @@ fn clone_repo_shallow_github(dirs: &Dirs, download_dir: &Path, user: &str, repo:
}
fn init_git_repo(repo_dir: &Path) {
let mut git_init_cmd = Command::new("git");
git_init_cmd.arg("init").arg("-q").current_dir(repo_dir);
let mut git_init_cmd = git_command(repo_dir, "init");
git_init_cmd.arg("-q");
spawn_and_wait(git_init_cmd);
let mut git_add_cmd = Command::new("git");
git_add_cmd.arg("add").arg(".").current_dir(repo_dir);
let mut git_add_cmd = git_command(repo_dir, "add");
git_add_cmd.arg(".");
spawn_and_wait(git_add_cmd);
let mut git_commit_cmd = Command::new("git");
git_commit_cmd
.arg("-c")
.arg("user.name=Dummy")
.arg("-c")
.arg("user.email=dummy@example.com")
.arg("commit")
.arg("-m")
.arg("Initial commit")
.arg("-q")
.current_dir(repo_dir);
let mut git_commit_cmd = git_command(repo_dir, "commit");
git_commit_cmd.arg("-m").arg("Initial commit").arg("-q");
spawn_and_wait(git_commit_cmd);
}
@ -211,16 +212,8 @@ fn apply_patches(dirs: &Dirs, crate_name: &str, target_dir: &Path) {
target_dir.file_name().unwrap(),
patch.file_name().unwrap()
);
let mut apply_patch_cmd = Command::new("git");
apply_patch_cmd
.arg("-c")
.arg("user.name=Dummy")
.arg("-c")
.arg("user.email=dummy@example.com")
.arg("am")
.arg(patch)
.arg("-q")
.current_dir(target_dir);
let mut apply_patch_cmd = git_command(target_dir, "am");
apply_patch_cmd.arg(patch).arg("-q");
spawn_and_wait(apply_patch_cmd);
}
}

View file

@ -15,229 +15,94 @@ static BUILD_EXAMPLE_OUT_DIR: RelPath = RelPath::BUILD.join("example");
struct TestCase {
config: &'static str,
func: &'static dyn Fn(&TestRunner),
cmd: TestCaseCmd,
}
enum TestCaseCmd {
Custom { func: &'static dyn Fn(&TestRunner) },
BuildLib { source: &'static str, crate_types: &'static str },
BuildBinAndRun { source: &'static str, args: &'static [&'static str] },
JitBin { source: &'static str, args: &'static str },
}
impl TestCase {
const fn new(config: &'static str, func: &'static dyn Fn(&TestRunner)) -> Self {
Self { config, func }
// FIXME reduce usage of custom test case commands
const fn custom(config: &'static str, func: &'static dyn Fn(&TestRunner)) -> Self {
Self { config, cmd: TestCaseCmd::Custom { func } }
}
const fn build_lib(
config: &'static str,
source: &'static str,
crate_types: &'static str,
) -> Self {
Self { config, cmd: TestCaseCmd::BuildLib { source, crate_types } }
}
const fn build_bin_and_run(
config: &'static str,
source: &'static str,
args: &'static [&'static str],
) -> Self {
Self { config, cmd: TestCaseCmd::BuildBinAndRun { source, args } }
}
const fn jit_bin(config: &'static str, source: &'static str, args: &'static str) -> Self {
Self { config, cmd: TestCaseCmd::JitBin { source, args } }
}
}
const NO_SYSROOT_SUITE: &[TestCase] = &[
TestCase::new("build.mini_core", &|runner| {
runner.run_rustc([
"example/mini_core.rs",
"--crate-name",
"mini_core",
"--crate-type",
"lib,dylib",
"--target",
&runner.target_compiler.triple,
]);
}),
TestCase::new("build.example", &|runner| {
runner.run_rustc([
"example/example.rs",
"--crate-type",
"lib",
"--target",
&runner.target_compiler.triple,
]);
}),
TestCase::new("jit.mini_core_hello_world", &|runner| {
let mut jit_cmd = runner.rustc_command([
"-Zunstable-options",
"-Cllvm-args=mode=jit",
"-Cprefer-dynamic",
"example/mini_core_hello_world.rs",
"--cfg",
"jit",
"--target",
&runner.target_compiler.triple,
]);
jit_cmd.env("CG_CLIF_JIT_ARGS", "abc bcd");
spawn_and_wait(jit_cmd);
eprintln!("[JIT-lazy] mini_core_hello_world");
let mut jit_cmd = runner.rustc_command([
"-Zunstable-options",
"-Cllvm-args=mode=jit-lazy",
"-Cprefer-dynamic",
"example/mini_core_hello_world.rs",
"--cfg",
"jit",
"--target",
&runner.target_compiler.triple,
]);
jit_cmd.env("CG_CLIF_JIT_ARGS", "abc bcd");
spawn_and_wait(jit_cmd);
}),
TestCase::new("aot.mini_core_hello_world", &|runner| {
runner.run_rustc([
"example/mini_core_hello_world.rs",
"--crate-name",
"mini_core_hello_world",
"--crate-type",
"bin",
"-g",
"--target",
&runner.target_compiler.triple,
]);
runner.run_out_command("mini_core_hello_world", ["abc", "bcd"]);
}),
TestCase::build_lib("build.mini_core", "example/mini_core.rs", "lib,dylib"),
TestCase::build_lib("build.example", "example/example.rs", "lib"),
TestCase::jit_bin("jit.mini_core_hello_world", "example/mini_core_hello_world.rs", "abc bcd"),
TestCase::build_bin_and_run(
"aot.mini_core_hello_world",
"example/mini_core_hello_world.rs",
&["abc", "bcd"],
),
];
const BASE_SYSROOT_SUITE: &[TestCase] = &[
TestCase::new("aot.arbitrary_self_types_pointers_and_wrappers", &|runner| {
runner.run_rustc([
"example/arbitrary_self_types_pointers_and_wrappers.rs",
"--crate-name",
"arbitrary_self_types_pointers_and_wrappers",
"--crate-type",
"bin",
"--target",
&runner.target_compiler.triple,
]);
runner.run_out_command("arbitrary_self_types_pointers_and_wrappers", []);
}),
TestCase::new("aot.issue_91827_extern_types", &|runner| {
runner.run_rustc([
"example/issue-91827-extern-types.rs",
"--crate-name",
"issue_91827_extern_types",
"--crate-type",
"bin",
"--target",
&runner.target_compiler.triple,
]);
runner.run_out_command("issue_91827_extern_types", []);
}),
TestCase::new("build.alloc_system", &|runner| {
runner.run_rustc([
"example/alloc_system.rs",
"--crate-type",
"lib",
"--target",
&runner.target_compiler.triple,
]);
}),
TestCase::new("aot.alloc_example", &|runner| {
runner.run_rustc([
"example/alloc_example.rs",
"--crate-type",
"bin",
"--target",
&runner.target_compiler.triple,
]);
runner.run_out_command("alloc_example", []);
}),
TestCase::new("jit.std_example", &|runner| {
runner.run_rustc([
"-Zunstable-options",
"-Cllvm-args=mode=jit",
"-Cprefer-dynamic",
"example/std_example.rs",
"--target",
&runner.target_compiler.triple,
]);
eprintln!("[JIT-lazy] std_example");
runner.run_rustc([
"-Zunstable-options",
"-Cllvm-args=mode=jit-lazy",
"-Cprefer-dynamic",
"example/std_example.rs",
"--target",
&runner.target_compiler.triple,
]);
}),
TestCase::new("aot.std_example", &|runner| {
runner.run_rustc([
"example/std_example.rs",
"--crate-type",
"bin",
"--target",
&runner.target_compiler.triple,
]);
runner.run_out_command("std_example", ["arg"]);
}),
TestCase::new("aot.dst_field_align", &|runner| {
runner.run_rustc([
"example/dst-field-align.rs",
"--crate-name",
"dst_field_align",
"--crate-type",
"bin",
"--target",
&runner.target_compiler.triple,
]);
runner.run_out_command("dst_field_align", []);
}),
TestCase::new("aot.subslice-patterns-const-eval", &|runner| {
runner.run_rustc([
"example/subslice-patterns-const-eval.rs",
"--crate-type",
"bin",
"-Cpanic=abort",
"--target",
&runner.target_compiler.triple,
]);
runner.run_out_command("subslice-patterns-const-eval", []);
}),
TestCase::new("aot.track-caller-attribute", &|runner| {
runner.run_rustc([
"example/track-caller-attribute.rs",
"--crate-type",
"bin",
"-Cpanic=abort",
"--target",
&runner.target_compiler.triple,
]);
runner.run_out_command("track-caller-attribute", []);
}),
TestCase::new("aot.float-minmax-pass", &|runner| {
runner.run_rustc([
"example/float-minmax-pass.rs",
"--crate-type",
"bin",
"-Cpanic=abort",
"--target",
&runner.target_compiler.triple,
]);
runner.run_out_command("float-minmax-pass", []);
}),
TestCase::new("aot.mod_bench", &|runner| {
runner.run_rustc([
"example/mod_bench.rs",
"--crate-type",
"bin",
"--target",
&runner.target_compiler.triple,
]);
runner.run_out_command("mod_bench", []);
}),
TestCase::new("aot.issue-72793", &|runner| {
runner.run_rustc([
"example/issue-72793.rs",
"--crate-type",
"bin",
"--target",
&runner.target_compiler.triple,
]);
runner.run_out_command("issue-72793", []);
}),
TestCase::build_bin_and_run(
"aot.arbitrary_self_types_pointers_and_wrappers",
"example/arbitrary_self_types_pointers_and_wrappers.rs",
&[],
),
TestCase::build_bin_and_run(
"aot.issue_91827_extern_types",
"example/issue-91827-extern-types.rs",
&[],
),
TestCase::build_lib("build.alloc_system", "example/alloc_system.rs", "lib"),
TestCase::build_bin_and_run("aot.alloc_example", "example/alloc_example.rs", &[]),
TestCase::jit_bin("jit.std_example", "example/std_example.rs", ""),
TestCase::build_bin_and_run("aot.std_example", "example/std_example.rs", &["arg"]),
TestCase::build_bin_and_run("aot.dst_field_align", "example/dst-field-align.rs", &[]),
TestCase::build_bin_and_run(
"aot.subslice-patterns-const-eval",
"example/subslice-patterns-const-eval.rs",
&[],
),
TestCase::build_bin_and_run(
"aot.track-caller-attribute",
"example/track-caller-attribute.rs",
&[],
),
TestCase::build_bin_and_run("aot.float-minmax-pass", "example/float-minmax-pass.rs", &[]),
TestCase::build_bin_and_run("aot.mod_bench", "example/mod_bench.rs", &[]),
TestCase::build_bin_and_run("aot.issue-72793", "example/issue-72793.rs", &[]),
];
pub(crate) static RAND_REPO: GitRepo =
GitRepo::github("rust-random", "rand", "0f933f9c7176e53b2a3c7952ded484e1783f0bf1", "rand");
static RAND: CargoProject = CargoProject::new(&RAND_REPO.source_dir(), "rand");
pub(crate) 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::new(&REGEX_REPO.source_dir(), "regex");
pub(crate) static REGEX: CargoProject = CargoProject::new(&REGEX_REPO.source_dir(), "regex");
pub(crate) static PORTABLE_SIMD_REPO: GitRepo = GitRepo::github(
"rust-lang",
@ -246,14 +111,14 @@ pub(crate) static PORTABLE_SIMD_REPO: GitRepo = GitRepo::github(
"portable-simd",
);
static PORTABLE_SIMD: CargoProject =
pub(crate) static PORTABLE_SIMD: CargoProject =
CargoProject::new(&PORTABLE_SIMD_REPO.source_dir(), "portable_simd");
static LIBCORE_TESTS: CargoProject =
pub(crate) static LIBCORE_TESTS: CargoProject =
CargoProject::new(&SYSROOT_SRC.join("library/core/tests"), "core_tests");
const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
TestCase::new("test.rust-random/rand", &|runner| {
TestCase::custom("test.rust-random/rand", &|runner| {
spawn_and_wait(RAND.clean(&runner.target_compiler.cargo, &runner.dirs));
if runner.is_native {
@ -268,11 +133,11 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
spawn_and_wait(build_cmd);
}
}),
TestCase::new("test.simple-raytracer", &|runner| {
TestCase::custom("test.simple-raytracer", &|runner| {
spawn_and_wait(SIMPLE_RAYTRACER.clean(&runner.host_compiler.cargo, &runner.dirs));
spawn_and_wait(SIMPLE_RAYTRACER.build(&runner.target_compiler, &runner.dirs));
}),
TestCase::new("test.libcore", &|runner| {
TestCase::custom("test.libcore", &|runner| {
spawn_and_wait(LIBCORE_TESTS.clean(&runner.host_compiler.cargo, &runner.dirs));
if runner.is_native {
@ -284,7 +149,7 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
spawn_and_wait(build_cmd);
}
}),
TestCase::new("test.regex-shootout-regex-dna", &|runner| {
TestCase::custom("test.regex-shootout-regex-dna", &|runner| {
spawn_and_wait(REGEX.clean(&runner.target_compiler.cargo, &runner.dirs));
// newer aho_corasick versions throw a deprecation warning
@ -304,9 +169,10 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
REGEX.source_dir(&runner.dirs).join("examples").join("regexdna-input.txt"),
)
.unwrap();
let expected_path =
REGEX.source_dir(&runner.dirs).join("examples").join("regexdna-output.txt");
let expected = fs::read_to_string(&expected_path).unwrap();
let expected = fs::read_to_string(
REGEX.source_dir(&runner.dirs).join("examples").join("regexdna-output.txt"),
)
.unwrap();
let output = spawn_and_wait_with_input(run_cmd, input);
// Make sure `[codegen mono items] start` doesn't poison the diff
@ -319,26 +185,15 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
let output_matches = expected.lines().eq(output.lines());
if !output_matches {
let res_path = REGEX.source_dir(&runner.dirs).join("res.txt");
fs::write(&res_path, &output).unwrap();
if cfg!(windows) {
println!("Output files don't match!");
println!("Expected Output:\n{}", expected);
println!("Actual Output:\n{}", output);
} else {
let mut diff = Command::new("diff");
diff.arg("-u");
diff.arg(res_path);
diff.arg(expected_path);
spawn_and_wait(diff);
}
println!("Output files don't match!");
println!("Expected Output:\n{}", expected);
println!("Actual Output:\n{}", output);
std::process::exit(1);
}
}
}),
TestCase::new("test.regex", &|runner| {
TestCase::custom("test.regex", &|runner| {
spawn_and_wait(REGEX.clean(&runner.host_compiler.cargo, &runner.dirs));
// newer aho_corasick versions throw a deprecation warning
@ -365,7 +220,7 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
spawn_and_wait(build_cmd);
}
}),
TestCase::new("test.portable-simd", &|runner| {
TestCase::custom("test.portable-simd", &|runner| {
spawn_and_wait(PORTABLE_SIMD.clean(&runner.host_compiler.cargo, &runner.dirs));
let mut build_cmd = PORTABLE_SIMD.build(&runner.target_compiler, &runner.dirs);
@ -385,10 +240,11 @@ pub(crate) fn run_tests(
channel: &str,
sysroot_kind: SysrootKind,
cg_clif_dylib: &Path,
host_triple: &str,
host_compiler: &Compiler,
target_triple: &str,
) {
let runner = TestRunner::new(dirs.clone(), host_triple.to_string(), target_triple.to_string());
let runner =
TestRunner::new(dirs.clone(), host_compiler.triple.clone(), target_triple.to_string());
if config::get_bool("testsuite.no_sysroot") {
build_sysroot::build_sysroot(
@ -396,7 +252,7 @@ pub(crate) fn run_tests(
channel,
SysrootKind::None,
cg_clif_dylib,
&host_triple,
host_compiler,
&target_triple,
);
@ -415,7 +271,7 @@ pub(crate) fn run_tests(
channel,
sysroot_kind,
cg_clif_dylib,
&host_triple,
host_compiler,
&target_triple,
);
}
@ -445,58 +301,33 @@ impl TestRunner {
pub fn new(dirs: Dirs, host_triple: String, target_triple: String) -> Self {
let is_native = host_triple == target_triple;
let jit_supported =
target_triple.contains("x86_64") && is_native && !host_triple.contains("windows");
let mut rustflags = env::var("RUSTFLAGS").ok().unwrap_or("".to_string());
let mut runner = vec![];
if !is_native {
match target_triple.as_str() {
"aarch64-unknown-linux-gnu" => {
// We are cross-compiling for aarch64. Use the correct linker and run tests in qemu.
rustflags = format!("-Clinker=aarch64-linux-gnu-gcc{}", rustflags);
runner = vec![
"qemu-aarch64".to_owned(),
"-L".to_owned(),
"/usr/aarch64-linux-gnu".to_owned(),
];
}
"s390x-unknown-linux-gnu" => {
// We are cross-compiling for s390x. Use the correct linker and run tests in qemu.
rustflags = format!("-Clinker=s390x-linux-gnu-gcc{}", rustflags);
runner = vec![
"qemu-s390x".to_owned(),
"-L".to_owned(),
"/usr/s390x-linux-gnu".to_owned(),
];
}
"x86_64-pc-windows-gnu" => {
// We are cross-compiling for Windows. Run tests in wine.
runner = vec!["wine".to_owned()];
}
_ => {
println!("Unknown non-native platform");
}
}
}
// FIXME fix `#[linkage = "extern_weak"]` without this
if target_triple.contains("darwin") {
rustflags = format!("{} -Clink-arg=-undefined -Clink-arg=dynamic_lookup", rustflags);
}
is_native && host_triple.contains("x86_64") && !host_triple.contains("windows");
let host_compiler = Compiler::clif_with_triple(&dirs, host_triple);
let mut target_compiler = Compiler::clif_with_triple(&dirs, target_triple);
target_compiler.rustflags = rustflags.clone();
target_compiler.rustdocflags = rustflags;
target_compiler.runner = runner;
if !is_native {
target_compiler.set_cross_linker_and_runner();
}
if let Ok(rustflags) = env::var("RUSTFLAGS") {
target_compiler.rustflags.push(' ');
target_compiler.rustflags.push_str(&rustflags);
}
if let Ok(rustdocflags) = env::var("RUSTDOCFLAGS") {
target_compiler.rustdocflags.push(' ');
target_compiler.rustdocflags.push_str(&rustdocflags);
}
// FIXME fix `#[linkage = "extern_weak"]` without this
if target_compiler.triple.contains("darwin") {
target_compiler.rustflags.push_str(" -Clink-arg=-undefined -Clink-arg=dynamic_lookup");
}
Self { is_native, jit_supported, dirs, host_compiler, target_compiler }
}
pub fn run_testsuite(&self, tests: &[TestCase]) {
for &TestCase { config, func } in tests {
for TestCase { config, cmd } in tests {
let (tag, testname) = config.split_once('.').unwrap();
let tag = tag.to_uppercase();
let is_jit_test = tag == "JIT";
@ -508,7 +339,47 @@ impl TestRunner {
eprintln!("[{tag}] {testname}");
}
func(self);
match *cmd {
TestCaseCmd::Custom { func } => func(self),
TestCaseCmd::BuildLib { source, crate_types } => {
self.run_rustc([source, "--crate-type", crate_types]);
}
TestCaseCmd::BuildBinAndRun { source, args } => {
self.run_rustc([source]);
self.run_out_command(
source.split('/').last().unwrap().split('.').next().unwrap(),
args,
);
}
TestCaseCmd::JitBin { source, args } => {
let mut jit_cmd = self.rustc_command([
"-Zunstable-options",
"-Cllvm-args=mode=jit",
"-Cprefer-dynamic",
source,
"--cfg",
"jit",
]);
if !args.is_empty() {
jit_cmd.env("CG_CLIF_JIT_ARGS", args);
}
spawn_and_wait(jit_cmd);
eprintln!("[JIT-lazy] {testname}");
let mut jit_cmd = self.rustc_command([
"-Zunstable-options",
"-Cllvm-args=mode=jit-lazy",
"-Cprefer-dynamic",
source,
"--cfg",
"jit",
]);
if !args.is_empty() {
jit_cmd.env("CG_CLIF_JIT_ARGS", args);
}
spawn_and_wait(jit_cmd);
}
}
}
}
@ -525,6 +396,9 @@ impl TestRunner {
cmd.arg("--out-dir");
cmd.arg(format!("{}", BUILD_EXAMPLE_OUT_DIR.to_path(&self.dirs).display()));
cmd.arg("-Cdebuginfo=2");
cmd.arg("--target");
cmd.arg(&self.target_compiler.triple);
cmd.arg("-Cpanic=abort");
cmd.args(args);
cmd
}
@ -537,10 +411,7 @@ impl TestRunner {
spawn_and_wait(self.rustc_command(args));
}
fn run_out_command<'a, I>(&self, name: &str, args: I)
where
I: IntoIterator<Item = &'a str>,
{
fn run_out_command<'a>(&self, name: &str, args: &[&str]) {
let mut full_cmd = vec![];
// Prepend the RUN_WRAPPER's
@ -552,7 +423,7 @@ impl TestRunner {
BUILD_EXAMPLE_OUT_DIR.to_path(&self.dirs).join(name).to_str().unwrap().to_string(),
);
for arg in args.into_iter() {
for arg in args {
full_cmd.push(arg.to_string());
}

34
build_system/usage.txt Normal file
View file

@ -0,0 +1,34 @@
The build system of cg_clif.
USAGE:
./y.rs prepare [--out-dir DIR]
./y.rs build [--debug] [--sysroot none|clif|llvm] [--out-dir DIR] [--no-unstable-features]
./y.rs test [--debug] [--sysroot none|clif|llvm] [--out-dir DIR] [--no-unstable-features]
./y.rs bench [--debug] [--sysroot none|clif|llvm] [--out-dir DIR] [--no-unstable-features]
OPTIONS:
--debug
Build cg_clif and the standard library in debug mode rather than release mode.
Warning: An unoptimized cg_clif is very slow.
--sysroot none|clif|llvm
Which sysroot libraries to use:
`none` will not include any standard library in the sysroot.
`clif` will build the standard library using Cranelift.
`llvm` will use the pre-compiled standard library of rustc which is compiled with LLVM.
--out-dir DIR
Specify the directory in which the download, build and dist directories are stored.
By default this is the working directory.
--no-unstable-features
Some features are not yet ready for production usage. This option will disable these
features. This includes the JIT mode and inline assembly support.
REQUIREMENTS:
* Rustup: The build system has a hard coded dependency on rustup to install the right nightly
version and make sure it is used where necessary.
* Git: `./y.rs prepare` uses git for applying patches and on Windows for downloading test repos.
* Curl and tar (non-Windows only): Used by `./y.rs prepare` to download a single commit for
repos. Git will be used to clone the whole repo when using Windows.
* [Hyperfine](https://github.com/sharkdp/hyperfine/): Used for benchmarking with `./y.rs bench`.

View file

@ -5,10 +5,9 @@ use std::path::{Path, PathBuf};
use std::process::{self, Command, Stdio};
use super::path::{Dirs, RelPath};
use super::rustc_info::{
get_cargo_path, get_host_triple, get_rustc_path, get_rustdoc_path, get_wrapper_file_name,
};
use super::rustc_info::{get_cargo_path, get_rustc_path, get_rustdoc_path, get_wrapper_file_name};
#[derive(Clone, Debug)]
pub(crate) struct Compiler {
pub(crate) cargo: PathBuf,
pub(crate) rustc: PathBuf,
@ -20,19 +19,7 @@ pub(crate) struct Compiler {
}
impl Compiler {
pub(crate) fn host() -> Compiler {
Compiler {
cargo: get_cargo_path(),
rustc: get_rustc_path(),
rustdoc: get_rustdoc_path(),
rustflags: String::new(),
rustdocflags: String::new(),
triple: get_host_triple(),
runner: vec![],
}
}
pub(crate) fn with_triple(triple: String) -> Compiler {
pub(crate) fn llvm_with_triple(triple: String) -> Compiler {
Compiler {
cargo: get_cargo_path(),
rustc: get_rustc_path(),
@ -60,6 +47,38 @@ impl Compiler {
runner: vec![],
}
}
pub(crate) fn set_cross_linker_and_runner(&mut self) {
match self.triple.as_str() {
"aarch64-unknown-linux-gnu" => {
// We are cross-compiling for aarch64. Use the correct linker and run tests in qemu.
self.rustflags += " -Clinker=aarch64-linux-gnu-gcc";
self.rustdocflags += " -Clinker=aarch64-linux-gnu-gcc";
self.runner = vec![
"qemu-aarch64".to_owned(),
"-L".to_owned(),
"/usr/aarch64-linux-gnu".to_owned(),
];
}
"s390x-unknown-linux-gnu" => {
// We are cross-compiling for s390x. Use the correct linker and run tests in qemu.
self.rustflags += " -Clinker=s390x-linux-gnu-gcc";
self.rustdocflags += " -Clinker=s390x-linux-gnu-gcc";
self.runner = vec![
"qemu-s390x".to_owned(),
"-L".to_owned(),
"/usr/s390x-linux-gnu".to_owned(),
];
}
"x86_64-pc-windows-gnu" => {
// We are cross-compiling for Windows. Run tests in wine.
self.runner = vec!["wine".to_owned()];
}
_ => {
println!("Unknown non-native platform");
}
}
}
}
pub(crate) struct CargoProject {
@ -84,6 +103,7 @@ impl CargoProject {
RelPath::BUILD.join(self.target).to_path(dirs)
}
#[must_use]
fn base_cmd(&self, command: &str, cargo: &Path, dirs: &Dirs) -> Command {
let mut cmd = Command::new(cargo);
@ -91,11 +111,13 @@ impl CargoProject {
.arg("--manifest-path")
.arg(self.manifest_path(dirs))
.arg("--target-dir")
.arg(self.target_dir(dirs));
.arg(self.target_dir(dirs))
.arg("--frozen");
cmd
}
#[must_use]
fn build_cmd(&self, command: &str, compiler: &Compiler, dirs: &Dirs) -> Command {
let mut cmd = self.base_cmd(command, &compiler.cargo, dirs);
@ -172,6 +194,23 @@ pub(crate) fn hyperfine_command(
bench
}
#[must_use]
pub(crate) fn git_command<'a>(repo_dir: impl Into<Option<&'a Path>>, cmd: &str) -> Command {
let mut git_cmd = Command::new("git");
git_cmd
.arg("-c")
.arg("user.name=Dummy")
.arg("-c")
.arg("user.email=dummy@example.com")
.arg("-c")
.arg("core.autocrlf=false")
.arg(cmd);
if let Some(repo_dir) = repo_dir.into() {
git_cmd.current_dir(repo_dir);
}
git_cmd
}
#[track_caller]
pub(crate) fn try_hard_link(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
let src = src.as_ref();

View file

@ -10,7 +10,7 @@ git fetch
git checkout -- .
git checkout "$(rustc -V | cut -d' ' -f3 | tr -d '(')"
git am ../patches/*-sysroot-*.patch
git -c user.name=Dummy -c user.email=dummy@example.com am ../patches/*-sysroot-*.patch
git apply - <<EOF
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml

2
y.rs
View file

@ -3,7 +3,7 @@
# This block is ignored by rustc
set -e
echo "[BUILD] y.rs" 1>&2
rustc $0 -o ${0/.rs/.bin} -Cdebuginfo=1 --edition 2021
rustc $0 -o ${0/.rs/.bin} -Cdebuginfo=1 --edition 2021 -Cpanic=abort
exec ${0/.rs/.bin} $@
*/