Merge commit '3a31c6d8272c14388a34622193baf553636fe470' into sync_cg_clif-2021-07-07
This commit is contained in:
parent
4cfa1fcb5b
commit
fb92375755
55 changed files with 1285 additions and 448 deletions
|
@ -14,7 +14,7 @@ task:
|
|||
- . $HOME/.cargo/env
|
||||
- git config --global user.email "user@example.com"
|
||||
- git config --global user.name "User"
|
||||
- ./prepare.sh
|
||||
- ./y.rs prepare
|
||||
test_script:
|
||||
- . $HOME/.cargo/env
|
||||
- # Enable backtraces for easier debugging
|
||||
|
|
73
.github/workflows/main.yml
vendored
73
.github/workflows/main.yml
vendored
|
@ -19,6 +19,9 @@ jobs:
|
|||
- os: ubuntu-latest
|
||||
env:
|
||||
TARGET_TRIPLE: x86_64-pc-windows-gnu
|
||||
- os: ubuntu-latest
|
||||
env:
|
||||
TARGET_TRIPLE: aarch64-unknown-linux-gnu
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
@ -49,11 +52,19 @@ jobs:
|
|||
sudo apt-get install -y gcc-mingw-w64-x86-64 wine-stable
|
||||
rustup target add x86_64-pc-windows-gnu
|
||||
|
||||
- name: Install AArch64 toolchain and qemu
|
||||
if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'aarch64-unknown-linux-gnu'
|
||||
run: |
|
||||
sudo apt-get install -y gcc-aarch64-linux-gnu qemu-user
|
||||
|
||||
- name: Prepare dependencies
|
||||
run: |
|
||||
git config --global user.email "user@example.com"
|
||||
git config --global user.name "User"
|
||||
./prepare.sh
|
||||
./y.rs prepare
|
||||
|
||||
- name: Build
|
||||
run: ./y.rs build --sysroot none
|
||||
|
||||
- name: Test
|
||||
env:
|
||||
|
@ -87,3 +98,63 @@ jobs:
|
|||
with:
|
||||
name: cg_clif-${{ runner.os }}-cross-x86_64-mingw
|
||||
path: cg_clif.tar.xz
|
||||
|
||||
build_windows:
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 60
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
#- name: Cache cargo installed crates
|
||||
# uses: actions/cache@v2
|
||||
# with:
|
||||
# path: ~/.cargo/bin
|
||||
# key: ${{ runner.os }}-cargo-installed-crates
|
||||
|
||||
#- name: Cache cargo registry and index
|
||||
# uses: actions/cache@v2
|
||||
# with:
|
||||
# path: |
|
||||
# ~/.cargo/registry
|
||||
# ~/.cargo/git
|
||||
# key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
#- name: Cache cargo target dir
|
||||
# uses: actions/cache@v2
|
||||
# with:
|
||||
# path: target
|
||||
# key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
|
||||
|
||||
- name: Prepare dependencies
|
||||
run: |
|
||||
git config --global user.email "user@example.com"
|
||||
git config --global user.name "User"
|
||||
git config --global core.autocrlf false
|
||||
rustup set default-host x86_64-pc-windows-gnu
|
||||
rustc y.rs -o y.exe -g
|
||||
./y.exe prepare
|
||||
|
||||
- name: Build
|
||||
#name: Test
|
||||
run: |
|
||||
# Enable backtraces for easier debugging
|
||||
#export RUST_BACKTRACE=1
|
||||
|
||||
# Reduce amount of benchmark runs as they are slow
|
||||
#export COMPILE_RUNS=2
|
||||
#export RUN_RUNS=2
|
||||
|
||||
# Enable extra checks
|
||||
#export CG_CLIF_ENABLE_VERIFIER=1
|
||||
|
||||
./y.exe build
|
||||
|
||||
#- name: Package prebuilt cg_clif
|
||||
# run: tar cvfJ cg_clif.tar.xz build
|
||||
|
||||
#- name: Upload prebuilt cg_clif
|
||||
# uses: actions/upload-artifact@v2
|
||||
# with:
|
||||
# name: cg_clif-${{ runner.os }}
|
||||
# path: cg_clif.tar.xz
|
||||
|
|
4
.github/workflows/rustc.yml
vendored
4
.github/workflows/rustc.yml
vendored
|
@ -34,7 +34,7 @@ jobs:
|
|||
run: |
|
||||
git config --global user.email "user@example.com"
|
||||
git config --global user.name "User"
|
||||
./prepare.sh
|
||||
./y.rs prepare
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
|
@ -72,7 +72,7 @@ jobs:
|
|||
run: |
|
||||
git config --global user.email "user@example.com"
|
||||
git config --global user.name "User"
|
||||
./prepare.sh
|
||||
./y.rs prepare
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -6,9 +6,11 @@ perf.data
|
|||
perf.data.old
|
||||
*.events
|
||||
*.string*
|
||||
/y.bin
|
||||
/build
|
||||
/build_sysroot/sysroot_src
|
||||
/build_sysroot/compiler-builtins
|
||||
/build_sysroot/rustc_version
|
||||
/rust
|
||||
/rand
|
||||
/regex
|
||||
|
|
21
.vscode/settings.json
vendored
21
.vscode/settings.json
vendored
|
@ -1,7 +1,9 @@
|
|||
{
|
||||
// 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.assist.importMergeBehavior": "last",
|
||||
"rust-analyzer.assist.importGranularity": "module",
|
||||
"rust-analyzer.assist.importEnforceGranularity": true,
|
||||
"rust-analyzer.assist.importPrefix": "crate",
|
||||
"rust-analyzer.cargo.runBuildScripts": true,
|
||||
"rust-analyzer.linkedProjects": [
|
||||
"./Cargo.toml",
|
||||
|
@ -49,6 +51,23 @@
|
|||
"cfg": [],
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"roots": ["./y.rs"],
|
||||
"crates": [
|
||||
{
|
||||
"root_module": "./y.rs",
|
||||
"edition": "2018",
|
||||
"deps": [{ "crate": 1, "name": "std" }],
|
||||
"cfg": [],
|
||||
},
|
||||
{
|
||||
"root_module": "./build_sysroot/sysroot_src/library/std/src/lib.rs",
|
||||
"edition": "2018",
|
||||
"deps": [],
|
||||
"cfg": [],
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
58
Cargo.lock
generated
58
Cargo.lock
generated
|
@ -33,16 +33,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-bforest"
|
||||
version = "0.74.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
|
||||
version = "0.75.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
|
||||
dependencies = [
|
||||
"cranelift-entity",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen"
|
||||
version = "0.74.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
|
||||
version = "0.75.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
|
||||
dependencies = [
|
||||
"cranelift-bforest",
|
||||
"cranelift-codegen-meta",
|
||||
|
@ -57,8 +57,8 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-meta"
|
||||
version = "0.74.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
|
||||
version = "0.75.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
|
||||
dependencies = [
|
||||
"cranelift-codegen-shared",
|
||||
"cranelift-entity",
|
||||
|
@ -66,18 +66,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-shared"
|
||||
version = "0.74.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
|
||||
version = "0.75.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-entity"
|
||||
version = "0.74.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
|
||||
version = "0.75.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-frontend"
|
||||
version = "0.74.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
|
||||
version = "0.75.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"log",
|
||||
|
@ -87,8 +87,8 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-jit"
|
||||
version = "0.74.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
|
||||
version = "0.75.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
|
@ -104,8 +104,8 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-module"
|
||||
version = "0.74.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
|
||||
version = "0.75.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
|
@ -115,17 +115,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-native"
|
||||
version = "0.74.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
|
||||
version = "0.75.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"libc",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-object"
|
||||
version = "0.74.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
|
||||
version = "0.75.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
|
@ -171,9 +172,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.86"
|
||||
version = "0.2.97"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"
|
||||
checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
|
@ -204,13 +205,20 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.24.0"
|
||||
name = "memchr"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a5b3dd1c072ee7963717671d1ca129f1048fda25edea6b752bfc71ac8854170"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.25.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a38f2be3697a57b4060074ff41b44c16870d916ad7877c17696e063257482bc7"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"indexmap",
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -9,7 +9,7 @@ crate-type = ["dylib"]
|
|||
|
||||
[dependencies]
|
||||
# These have to be in sync with each other
|
||||
cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "main", features = ["unwind"] }
|
||||
cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "main", features = ["unwind", "all-arch"] }
|
||||
cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "main" }
|
||||
cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "main" }
|
||||
cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "main" }
|
||||
|
@ -17,7 +17,7 @@ cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", bran
|
|||
cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "main" }
|
||||
target-lexicon = "0.12.0"
|
||||
gimli = { version = "0.24.0", default-features = false, features = ["write"]}
|
||||
object = { version = "0.24.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
|
||||
object = { version = "0.25.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
|
||||
|
||||
ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" }
|
||||
indexmap = "1.0.2"
|
||||
|
|
10
Readme.md
10
Readme.md
|
@ -10,8 +10,8 @@ If not please open an issue.
|
|||
```bash
|
||||
$ git clone https://github.com/bjorn3/rustc_codegen_cranelift.git
|
||||
$ cd rustc_codegen_cranelift
|
||||
$ ./prepare.sh # download and patch sysroot src and install hyperfine for benchmarking
|
||||
$ ./build.sh
|
||||
$ ./y.rs prepare # download and patch sysroot src and install hyperfine for benchmarking
|
||||
$ ./y.rs build
|
||||
```
|
||||
|
||||
To run the test suite replace the last command with:
|
||||
|
@ -20,7 +20,7 @@ To run the test suite replace the last command with:
|
|||
$ ./test.sh
|
||||
```
|
||||
|
||||
This will implicitly build cg_clif too. Both `build.sh` and `test.sh` accept a `--debug` argument to
|
||||
This will implicitly build cg_clif too. Both `y.rs build` and `test.sh` accept a `--debug` argument to
|
||||
build in debug mode.
|
||||
|
||||
Alternatively you can download a pre built version from [GHA]. It is listed in the artifacts section
|
||||
|
@ -32,12 +32,12 @@ of workflow runs. Unfortunately due to GHA restrictions you need to be logged in
|
|||
|
||||
rustc_codegen_cranelift can be used as a near-drop-in replacement for `cargo build` or `cargo run` for existing projects.
|
||||
|
||||
Assuming `$cg_clif_dir` is the directory you cloned this repo into and you followed the instructions (`prepare.sh` and `build.sh` or `test.sh`).
|
||||
Assuming `$cg_clif_dir` is the directory you cloned this repo into and you followed the instructions (`y.rs prepare` and `y.rs build` or `test.sh`).
|
||||
|
||||
In the directory with your project (where you can do the usual `cargo build`), run:
|
||||
|
||||
```bash
|
||||
$ $cg_clif_dir/build/cargo.sh build
|
||||
$ $cg_clif_dir/build/cargo build
|
||||
```
|
||||
|
||||
This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend.
|
||||
|
|
89
build.sh
89
build.sh
|
@ -1,89 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# Settings
|
||||
export CHANNEL="release"
|
||||
build_sysroot="clif"
|
||||
target_dir='build'
|
||||
while [[ $# != 0 ]]; do
|
||||
case $1 in
|
||||
"--debug")
|
||||
export CHANNEL="debug"
|
||||
;;
|
||||
"--sysroot")
|
||||
build_sysroot=$2
|
||||
shift
|
||||
;;
|
||||
"--target-dir")
|
||||
target_dir=$2
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Unknown flag '$1'"
|
||||
echo "Usage: ./build.sh [--debug] [--sysroot none|clif|llvm] [--target-dir DIR]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Build cg_clif
|
||||
unset CARGO_TARGET_DIR
|
||||
unamestr=$(uname)
|
||||
if [[ "$unamestr" == 'Linux' || "$unamestr" == "FreeBSD" ]]; then
|
||||
export RUSTFLAGS='-Clink-arg=-Wl,-rpath=$ORIGIN/../lib '$RUSTFLAGS
|
||||
elif [[ "$unamestr" == 'Darwin' ]]; then
|
||||
export RUSTFLAGS='-Csplit-debuginfo=unpacked -Clink-arg=-Wl,-rpath,@loader_path/../lib -Zosx-rpath-install-name '$RUSTFLAGS
|
||||
dylib_ext='dylib'
|
||||
else
|
||||
echo "Unsupported os $unamestr"
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$CHANNEL" == "release" ]]; then
|
||||
cargo build --release
|
||||
else
|
||||
cargo build
|
||||
fi
|
||||
|
||||
source scripts/ext_config.sh
|
||||
|
||||
rm -rf "$target_dir"
|
||||
mkdir "$target_dir"
|
||||
mkdir "$target_dir"/bin "$target_dir"/lib
|
||||
ln target/$CHANNEL/cg_clif{,_build_sysroot} "$target_dir"/bin
|
||||
ln target/$CHANNEL/*rustc_codegen_cranelift* "$target_dir"/lib
|
||||
ln rust-toolchain scripts/config.sh scripts/cargo.sh "$target_dir"
|
||||
|
||||
mkdir -p "$target_dir/lib/rustlib/$TARGET_TRIPLE/lib/"
|
||||
mkdir -p "$target_dir/lib/rustlib/$HOST_TRIPLE/lib/"
|
||||
if [[ "$TARGET_TRIPLE" == "x86_64-pc-windows-gnu" ]]; then
|
||||
cp $(rustc --print sysroot)/lib/rustlib/$TARGET_TRIPLE/lib/*.o "$target_dir/lib/rustlib/$TARGET_TRIPLE/lib/"
|
||||
fi
|
||||
|
||||
case "$build_sysroot" in
|
||||
"none")
|
||||
;;
|
||||
"llvm")
|
||||
cp -r $(rustc --print sysroot)/lib/rustlib/$TARGET_TRIPLE/lib "$target_dir/lib/rustlib/$TARGET_TRIPLE/"
|
||||
if [[ "$HOST_TRIPLE" != "$TARGET_TRIPLE" ]]; then
|
||||
cp -r $(rustc --print sysroot)/lib/rustlib/$HOST_TRIPLE/lib "$target_dir/lib/rustlib/$HOST_TRIPLE/"
|
||||
fi
|
||||
;;
|
||||
"clif")
|
||||
echo "[BUILD] sysroot"
|
||||
dir=$(pwd)
|
||||
cd "$target_dir"
|
||||
time "$dir/build_sysroot/build_sysroot.sh"
|
||||
if [[ "$HOST_TRIPLE" != "$TARGET_TRIPLE" ]]; then
|
||||
time TARGET_TRIPLE="$HOST_TRIPLE" "$dir/build_sysroot/build_sysroot.sh"
|
||||
fi
|
||||
cp lib/rustlib/*/lib/libstd-* lib/
|
||||
;;
|
||||
*)
|
||||
echo "Unknown sysroot kind \`$build_sysroot\`."
|
||||
echo "The allowed values are:"
|
||||
echo " none A sysroot that doesn't contain the standard library"
|
||||
echo " llvm Copy the sysroot from rustc compiled by cg_llvm"
|
||||
echo " clif Build a new sysroot using cg_clif"
|
||||
exit 1
|
||||
esac
|
14
build_sysroot/Cargo.lock
generated
14
build_sysroot/Cargo.lock
generated
|
@ -56,7 +56,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "compiler_builtins"
|
||||
version = "0.1.43"
|
||||
version = "0.1.46"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
@ -121,9 +121,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.18"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"libc",
|
||||
|
@ -132,9 +132,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.95"
|
||||
version = "0.2.97"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36"
|
||||
checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
@ -195,9 +195,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.19"
|
||||
version = "0.1.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "410f7acf3cb3a44527c5d9546bad4bf4e6c460915d5f9f2fc524498bfe8f70ce"
|
||||
checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Requires the CHANNEL env var to be set to `debug` or `release.`
|
||||
|
||||
set -e
|
||||
|
||||
source ./config.sh
|
||||
|
||||
dir=$(pwd)
|
||||
|
||||
# Use rustc with cg_clif as hotpluggable backend instead of the custom cg_clif driver so that
|
||||
# build scripts are still compiled using cg_llvm.
|
||||
export RUSTC=$dir"/bin/cg_clif_build_sysroot"
|
||||
export RUSTFLAGS=$RUSTFLAGS" --clif"
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
# Cleanup for previous run
|
||||
# v Clean target dir except for build scripts and incremental cache
|
||||
rm -r target/*/{debug,release}/{build,deps,examples,libsysroot*,native} 2>/dev/null || true
|
||||
|
||||
# We expect the target dir in the default location. Guard against the user changing it.
|
||||
export CARGO_TARGET_DIR=target
|
||||
|
||||
# Build libs
|
||||
export RUSTFLAGS="$RUSTFLAGS -Zforce-unstable-if-unmarked -Cpanic=abort"
|
||||
export __CARGO_DEFAULT_LIB_METADATA="cg_clif"
|
||||
if [[ "$1" != "--debug" ]]; then
|
||||
sysroot_channel='release'
|
||||
# FIXME Enable incremental again once rust-lang/rust#74946 is fixed
|
||||
CARGO_INCREMENTAL=0 RUSTFLAGS="$RUSTFLAGS -Zmir-opt-level=3" cargo build --target "$TARGET_TRIPLE" --release
|
||||
else
|
||||
sysroot_channel='debug'
|
||||
cargo build --target "$TARGET_TRIPLE"
|
||||
fi
|
||||
|
||||
# Copy files to sysroot
|
||||
ln "target/$TARGET_TRIPLE/$sysroot_channel/deps/"* "$dir/lib/rustlib/$TARGET_TRIPLE/lib/"
|
||||
rm "$dir/lib/rustlib/$TARGET_TRIPLE/lib/"*.{rmeta,d}
|
|
@ -1,39 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
SRC_DIR="$(dirname "$(rustup which rustc)")/../lib/rustlib/src/rust/"
|
||||
DST_DIR="sysroot_src"
|
||||
|
||||
if [ ! -e "$SRC_DIR" ]; then
|
||||
echo "Please install rust-src component"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -rf $DST_DIR
|
||||
mkdir -p $DST_DIR/library
|
||||
cp -a "$SRC_DIR/library" $DST_DIR/
|
||||
|
||||
pushd $DST_DIR
|
||||
echo "[GIT] init"
|
||||
git init
|
||||
echo "[GIT] add"
|
||||
git add .
|
||||
echo "[GIT] commit"
|
||||
git commit -m "Initial commit" -q
|
||||
for file in $(ls ../../patches/ | grep -v patcha); do
|
||||
echo "[GIT] apply" "$file"
|
||||
git apply ../../patches/"$file"
|
||||
git add -A
|
||||
git commit --no-gpg-sign -m "Patch $file"
|
||||
done
|
||||
popd
|
||||
|
||||
git clone https://github.com/rust-lang/compiler-builtins.git || echo "rust-lang/compiler-builtins has already been cloned"
|
||||
pushd compiler-builtins
|
||||
git checkout -- .
|
||||
git checkout 0.1.43
|
||||
git apply ../../crate_patches/000*-compiler-builtins-*.patch
|
||||
popd
|
||||
|
||||
echo "Successfully prepared sysroot source for building"
|
40
build_system/build_backend.rs
Normal file
40
build_system/build_backend.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
pub(crate) fn build_backend(channel: &str, host_triple: &str) -> PathBuf {
|
||||
let mut cmd = Command::new("cargo");
|
||||
cmd.arg("build").arg("--target").arg(host_triple);
|
||||
|
||||
match channel {
|
||||
"debug" => {}
|
||||
"release" => {
|
||||
cmd.arg("--release");
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
if cfg!(unix) {
|
||||
if cfg!(target_os = "macos") {
|
||||
cmd.env(
|
||||
"RUSTFLAGS",
|
||||
"-Csplit-debuginfo=unpacked \
|
||||
-Clink-arg=-Wl,-rpath,@loader_path/../lib \
|
||||
-Zosx-rpath-install-name"
|
||||
.to_string()
|
||||
+ env::var("RUSTFLAGS").as_deref().unwrap_or(""),
|
||||
);
|
||||
} else {
|
||||
cmd.env(
|
||||
"RUSTFLAGS",
|
||||
"-Clink-arg=-Wl,-rpath=$ORIGIN/../lib ".to_string()
|
||||
+ env::var("RUSTFLAGS").as_deref().unwrap_or(""),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
eprintln!("[BUILD] rustc_codegen_cranelift");
|
||||
crate::utils::spawn_and_wait(cmd);
|
||||
|
||||
Path::new("target").join(host_triple).join(channel)
|
||||
}
|
216
build_system/build_sysroot.rs
Normal file
216
build_system/build_sysroot.rs
Normal file
|
@ -0,0 +1,216 @@
|
|||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{self, Command};
|
||||
|
||||
use crate::rustc_info::{get_file_name, get_rustc_version};
|
||||
use crate::utils::{spawn_and_wait, try_hard_link};
|
||||
use crate::SysrootKind;
|
||||
|
||||
pub(crate) fn build_sysroot(
|
||||
channel: &str,
|
||||
sysroot_kind: SysrootKind,
|
||||
target_dir: &Path,
|
||||
cg_clif_build_dir: PathBuf,
|
||||
host_triple: &str,
|
||||
target_triple: &str,
|
||||
) {
|
||||
if target_dir.exists() {
|
||||
fs::remove_dir_all(target_dir).unwrap();
|
||||
}
|
||||
fs::create_dir_all(target_dir.join("bin")).unwrap();
|
||||
fs::create_dir_all(target_dir.join("lib")).unwrap();
|
||||
|
||||
// Copy the backend
|
||||
for file in ["cg_clif", "cg_clif_build_sysroot"] {
|
||||
try_hard_link(
|
||||
cg_clif_build_dir.join(get_file_name(file, "bin")),
|
||||
target_dir.join("bin").join(get_file_name(file, "bin")),
|
||||
);
|
||||
}
|
||||
|
||||
let cg_clif_dylib = get_file_name("rustc_codegen_cranelift", "dylib");
|
||||
try_hard_link(
|
||||
cg_clif_build_dir.join(&cg_clif_dylib),
|
||||
target_dir
|
||||
.join(if cfg!(windows) {
|
||||
// Windows doesn't have rpath support, so the cg_clif dylib needs to be next to the
|
||||
// binaries.
|
||||
"bin"
|
||||
} else {
|
||||
"lib"
|
||||
})
|
||||
.join(cg_clif_dylib),
|
||||
);
|
||||
|
||||
// Build and copy cargo wrapper
|
||||
let mut build_cargo_wrapper_cmd = Command::new("rustc");
|
||||
build_cargo_wrapper_cmd
|
||||
.arg("scripts/cargo.rs")
|
||||
.arg("-o")
|
||||
.arg(target_dir.join("cargo"))
|
||||
.arg("-g");
|
||||
spawn_and_wait(build_cargo_wrapper_cmd);
|
||||
|
||||
let default_sysroot = crate::rustc_info::get_default_sysroot();
|
||||
|
||||
let rustlib = target_dir.join("lib").join("rustlib");
|
||||
let host_rustlib_lib = rustlib.join(host_triple).join("lib");
|
||||
let target_rustlib_lib = rustlib.join(target_triple).join("lib");
|
||||
fs::create_dir_all(&host_rustlib_lib).unwrap();
|
||||
fs::create_dir_all(&target_rustlib_lib).unwrap();
|
||||
|
||||
if target_triple == "x86_64-pc-windows-gnu" {
|
||||
if !default_sysroot.join("lib").join("rustlib").join(target_triple).join("lib").exists() {
|
||||
eprintln!(
|
||||
"The x86_64-pc-windows-gnu target needs to be installed first before it is possible \
|
||||
to compile a sysroot for it.",
|
||||
);
|
||||
process::exit(1);
|
||||
}
|
||||
for file in fs::read_dir(
|
||||
default_sysroot.join("lib").join("rustlib").join(target_triple).join("lib"),
|
||||
)
|
||||
.unwrap()
|
||||
{
|
||||
let file = file.unwrap().path();
|
||||
if file.extension().map_or(true, |ext| ext.to_str().unwrap() != "o") {
|
||||
continue; // only copy object files
|
||||
}
|
||||
try_hard_link(&file, target_rustlib_lib.join(file.file_name().unwrap()));
|
||||
}
|
||||
}
|
||||
|
||||
match sysroot_kind {
|
||||
SysrootKind::None => {} // Nothing to do
|
||||
SysrootKind::Llvm => {
|
||||
for file in fs::read_dir(
|
||||
default_sysroot.join("lib").join("rustlib").join(host_triple).join("lib"),
|
||||
)
|
||||
.unwrap()
|
||||
{
|
||||
let file = file.unwrap().path();
|
||||
let file_name_str = file.file_name().unwrap().to_str().unwrap();
|
||||
if file_name_str.contains("rustc_")
|
||||
|| file_name_str.contains("chalk")
|
||||
|| file_name_str.contains("tracing")
|
||||
|| file_name_str.contains("regex")
|
||||
{
|
||||
// These are large crates that are part of the rustc-dev component and are not
|
||||
// necessary to run regular programs.
|
||||
continue;
|
||||
}
|
||||
try_hard_link(&file, host_rustlib_lib.join(file.file_name().unwrap()));
|
||||
}
|
||||
|
||||
if target_triple != host_triple {
|
||||
for file in fs::read_dir(
|
||||
default_sysroot.join("lib").join("rustlib").join(target_triple).join("lib"),
|
||||
)
|
||||
.unwrap()
|
||||
{
|
||||
let file = file.unwrap().path();
|
||||
try_hard_link(&file, target_rustlib_lib.join(file.file_name().unwrap()));
|
||||
}
|
||||
}
|
||||
}
|
||||
SysrootKind::Clif => {
|
||||
build_clif_sysroot_for_triple(channel, target_dir, host_triple, None);
|
||||
|
||||
if host_triple != target_triple {
|
||||
// When cross-compiling it is often necessary to manually pick the right linker
|
||||
let linker = if target_triple == "aarch64-unknown-linux-gnu" {
|
||||
Some("aarch64-linux-gnu-gcc")
|
||||
} else {
|
||||
None
|
||||
};
|
||||
build_clif_sysroot_for_triple(channel, target_dir, target_triple, linker);
|
||||
}
|
||||
|
||||
// Copy std for the host to the lib dir. This is necessary for the jit mode to find
|
||||
// libstd.
|
||||
for file in fs::read_dir(host_rustlib_lib).unwrap() {
|
||||
let file = file.unwrap().path();
|
||||
if file.file_name().unwrap().to_str().unwrap().contains("std-") {
|
||||
try_hard_link(&file, target_dir.join("lib").join(file.file_name().unwrap()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn build_clif_sysroot_for_triple(
|
||||
channel: &str,
|
||||
target_dir: &Path,
|
||||
triple: &str,
|
||||
linker: Option<&str>,
|
||||
) {
|
||||
match fs::read_to_string(Path::new("build_sysroot").join("rustc_version")) {
|
||||
Err(e) => {
|
||||
eprintln!("Failed to get rustc version for patched sysroot source: {}", e);
|
||||
eprintln!("Hint: Try `./y.rs prepare` to patch the sysroot source");
|
||||
process::exit(1);
|
||||
}
|
||||
Ok(source_version) => {
|
||||
let rustc_version = get_rustc_version();
|
||||
if source_version != rustc_version {
|
||||
eprintln!("The patched sysroot source is outdated");
|
||||
eprintln!("Source version: {}", source_version.trim());
|
||||
eprintln!("Rustc version: {}", rustc_version.trim());
|
||||
eprintln!("Hint: Try `./y.rs prepare` to update the patched sysroot source");
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let build_dir = Path::new("build_sysroot").join("target").join(triple).join(channel);
|
||||
|
||||
if !crate::config::get_bool("keep_sysroot") {
|
||||
// Cleanup the target dir with the exception of build scripts and the incremental cache
|
||||
for dir in ["build", "deps", "examples", "native"] {
|
||||
if build_dir.join(dir).exists() {
|
||||
fs::remove_dir_all(build_dir.join(dir)).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build sysroot
|
||||
let mut build_cmd = Command::new("cargo");
|
||||
build_cmd.arg("build").arg("--target").arg(triple).current_dir("build_sysroot");
|
||||
let mut rustflags = "--clif -Zforce-unstable-if-unmarked".to_string();
|
||||
if channel == "release" {
|
||||
build_cmd.arg("--release");
|
||||
rustflags.push_str(" -Zmir-opt-level=3");
|
||||
}
|
||||
if let Some(linker) = linker {
|
||||
use std::fmt::Write;
|
||||
write!(rustflags, " -Clinker={}", linker).unwrap();
|
||||
}
|
||||
build_cmd.env("RUSTFLAGS", rustflags);
|
||||
build_cmd.env(
|
||||
"RUSTC",
|
||||
env::current_dir().unwrap().join(target_dir).join("bin").join("cg_clif_build_sysroot"),
|
||||
);
|
||||
// FIXME Enable incremental again once rust-lang/rust#74946 is fixed
|
||||
build_cmd.env("CARGO_INCREMENTAL", "0").env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif");
|
||||
spawn_and_wait(build_cmd);
|
||||
|
||||
// Copy all relevant files to the sysroot
|
||||
for entry in
|
||||
fs::read_dir(Path::new("build_sysroot/target").join(triple).join(channel).join("deps"))
|
||||
.unwrap()
|
||||
{
|
||||
let entry = entry.unwrap();
|
||||
if let Some(ext) = entry.path().extension() {
|
||||
if ext == "rmeta" || ext == "d" || ext == "dSYM" {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
try_hard_link(
|
||||
entry.path(),
|
||||
target_dir.join("lib").join("rustlib").join(triple).join("lib").join(entry.file_name()),
|
||||
);
|
||||
}
|
||||
}
|
55
build_system/config.rs
Normal file
55
build_system/config.rs
Normal file
|
@ -0,0 +1,55 @@
|
|||
use std::{fs, process};
|
||||
|
||||
fn load_config_file() -> Vec<(String, Option<String>)> {
|
||||
fs::read_to_string("config.txt")
|
||||
.unwrap()
|
||||
.lines()
|
||||
.map(|line| if let Some((line, _comment)) = line.split_once('#') { line } else { line })
|
||||
.map(|line| line.trim())
|
||||
.filter(|line| !line.is_empty())
|
||||
.map(|line| {
|
||||
if let Some((key, val)) = line.split_once('=') {
|
||||
(key.trim().to_owned(), Some(val.trim().to_owned()))
|
||||
} else {
|
||||
(line.to_owned(), None)
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub(crate) fn get_bool(name: &str) -> bool {
|
||||
let values = load_config_file()
|
||||
.into_iter()
|
||||
.filter(|(key, _)| key == name)
|
||||
.map(|(_, val)| val)
|
||||
.collect::<Vec<_>>();
|
||||
if values.is_empty() {
|
||||
false
|
||||
} else {
|
||||
if values.iter().any(|val| val.is_some()) {
|
||||
eprintln!("Boolean config `{}` has a value", name);
|
||||
process::exit(1);
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_value(name: &str) -> Option<String> {
|
||||
let values = load_config_file()
|
||||
.into_iter()
|
||||
.filter(|(key, _)| key == name)
|
||||
.map(|(_, val)| val)
|
||||
.collect::<Vec<_>>();
|
||||
if values.is_empty() {
|
||||
None
|
||||
} else if values.len() == 1 {
|
||||
if values[0].is_none() {
|
||||
eprintln!("Config `{}` missing value", name);
|
||||
process::exit(1);
|
||||
}
|
||||
values.into_iter().next().unwrap()
|
||||
} else {
|
||||
eprintln!("Config `{}` given multiple values: {:?}", name, values);
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
133
build_system/prepare.rs
Normal file
133
build_system/prepare.rs
Normal file
|
@ -0,0 +1,133 @@
|
|||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::ffi::OsString;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
use crate::rustc_info::{get_file_name, get_rustc_path, get_rustc_version};
|
||||
use crate::utils::{copy_dir_recursively, spawn_and_wait};
|
||||
|
||||
pub(crate) fn prepare() {
|
||||
prepare_sysroot();
|
||||
|
||||
eprintln!("[INSTALL] hyperfine");
|
||||
Command::new("cargo").arg("install").arg("hyperfine").spawn().unwrap().wait().unwrap();
|
||||
|
||||
clone_repo(
|
||||
"rand",
|
||||
"https://github.com/rust-random/rand.git",
|
||||
"0f933f9c7176e53b2a3c7952ded484e1783f0bf1",
|
||||
);
|
||||
apply_patches("rand", Path::new("rand"));
|
||||
|
||||
clone_repo(
|
||||
"regex",
|
||||
"https://github.com/rust-lang/regex.git",
|
||||
"341f207c1071f7290e3f228c710817c280c8dca1",
|
||||
);
|
||||
|
||||
clone_repo(
|
||||
"simple-raytracer",
|
||||
"https://github.com/ebobby/simple-raytracer",
|
||||
"804a7a21b9e673a482797aa289a18ed480e4d813",
|
||||
);
|
||||
|
||||
eprintln!("[LLVM BUILD] simple-raytracer");
|
||||
let mut build_cmd = Command::new("cargo");
|
||||
build_cmd.arg("build").env_remove("CARGO_TARGET_DIR").current_dir("simple-raytracer");
|
||||
spawn_and_wait(build_cmd);
|
||||
fs::copy(
|
||||
Path::new("simple-raytracer/target/debug").join(get_file_name("main", "bin")),
|
||||
// FIXME use get_file_name here too once testing is migrated to rust
|
||||
"simple-raytracer/raytracer_cg_llvm",
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn prepare_sysroot() {
|
||||
let rustc_path = get_rustc_path();
|
||||
let sysroot_src_orig = rustc_path.parent().unwrap().join("../lib/rustlib/src/rust");
|
||||
let sysroot_src = env::current_dir().unwrap().join("build_sysroot").join("sysroot_src");
|
||||
|
||||
assert!(sysroot_src_orig.exists());
|
||||
|
||||
if sysroot_src.exists() {
|
||||
fs::remove_dir_all(&sysroot_src).unwrap();
|
||||
}
|
||||
fs::create_dir_all(sysroot_src.join("library")).unwrap();
|
||||
eprintln!("[COPY] sysroot src");
|
||||
copy_dir_recursively(&sysroot_src_orig.join("library"), &sysroot_src.join("library"));
|
||||
|
||||
let rustc_version = get_rustc_version();
|
||||
fs::write(
|
||||
Path::new("build_sysroot").join("rustc_version"),
|
||||
&rustc_version,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
eprintln!("[GIT] init");
|
||||
let mut git_init_cmd = Command::new("git");
|
||||
git_init_cmd.arg("init").arg("-q").current_dir(&sysroot_src);
|
||||
spawn_and_wait(git_init_cmd);
|
||||
|
||||
let mut git_add_cmd = Command::new("git");
|
||||
git_add_cmd.arg("add").arg(".").current_dir(&sysroot_src);
|
||||
spawn_and_wait(git_add_cmd);
|
||||
|
||||
let mut git_commit_cmd = Command::new("git");
|
||||
git_commit_cmd
|
||||
.arg("commit")
|
||||
.arg("-m")
|
||||
.arg("Initial commit")
|
||||
.arg("-q")
|
||||
.current_dir(&sysroot_src);
|
||||
spawn_and_wait(git_commit_cmd);
|
||||
|
||||
apply_patches("sysroot", &sysroot_src);
|
||||
|
||||
clone_repo(
|
||||
"build_sysroot/compiler-builtins",
|
||||
"https://github.com/rust-lang/compiler-builtins.git",
|
||||
"0.1.46",
|
||||
);
|
||||
apply_patches("compiler-builtins", Path::new("build_sysroot/compiler-builtins"));
|
||||
}
|
||||
|
||||
fn clone_repo(target_dir: &str, 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(target_dir).spawn().unwrap().wait().unwrap();
|
||||
|
||||
let mut clean_cmd = Command::new("git");
|
||||
clean_cmd.arg("checkout").arg("--").arg(".").current_dir(target_dir);
|
||||
spawn_and_wait(clean_cmd);
|
||||
|
||||
let mut checkout_cmd = Command::new("git");
|
||||
checkout_cmd.arg("checkout").arg("-q").arg(rev).current_dir(target_dir);
|
||||
spawn_and_wait(checkout_cmd);
|
||||
}
|
||||
|
||||
fn get_patches(crate_name: &str) -> Vec<OsString> {
|
||||
let mut patches: Vec<_> = fs::read_dir("patches")
|
||||
.unwrap()
|
||||
.map(|entry| entry.unwrap().path())
|
||||
.filter(|path| path.extension() == Some(OsStr::new("patch")))
|
||||
.map(|path| path.file_name().unwrap().to_owned())
|
||||
.filter(|file_name| {
|
||||
file_name.to_str().unwrap().split_once("-").unwrap().1.starts_with(crate_name)
|
||||
})
|
||||
.collect();
|
||||
patches.sort();
|
||||
patches
|
||||
}
|
||||
|
||||
fn apply_patches(crate_name: &str, target_dir: &Path) {
|
||||
for patch in get_patches(crate_name) {
|
||||
eprintln!("[PATCH] {:?} <- {:?}", target_dir.file_name().unwrap(), patch);
|
||||
let patch_arg = env::current_dir().unwrap().join("patches").join(patch);
|
||||
let mut apply_patch_cmd = Command::new("git");
|
||||
apply_patch_cmd.arg("am").arg(patch_arg).arg("-q").current_dir(target_dir);
|
||||
spawn_and_wait(apply_patch_cmd);
|
||||
}
|
||||
}
|
65
build_system/rustc_info.rs
Normal file
65
build_system/rustc_info.rs
Normal file
|
@ -0,0 +1,65 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
pub(crate) fn get_rustc_version() -> String {
|
||||
let version_info =
|
||||
Command::new("rustc").stderr(Stdio::inherit()).args(&["-V"]).output().unwrap().stdout;
|
||||
String::from_utf8(version_info).unwrap()
|
||||
}
|
||||
|
||||
pub(crate) fn get_host_triple() -> String {
|
||||
let version_info =
|
||||
Command::new("rustc").stderr(Stdio::inherit()).args(&["-vV"]).output().unwrap().stdout;
|
||||
String::from_utf8(version_info)
|
||||
.unwrap()
|
||||
.lines()
|
||||
.to_owned()
|
||||
.find(|line| line.starts_with("host"))
|
||||
.unwrap()
|
||||
.split(":")
|
||||
.nth(1)
|
||||
.unwrap()
|
||||
.trim()
|
||||
.to_owned()
|
||||
}
|
||||
|
||||
pub(crate) fn get_rustc_path() -> PathBuf {
|
||||
let rustc_path = Command::new("rustup")
|
||||
.stderr(Stdio::inherit())
|
||||
.args(&["which", "rustc"])
|
||||
.output()
|
||||
.unwrap()
|
||||
.stdout;
|
||||
Path::new(String::from_utf8(rustc_path).unwrap().trim()).to_owned()
|
||||
}
|
||||
|
||||
pub(crate) fn get_default_sysroot() -> PathBuf {
|
||||
let default_sysroot = Command::new("rustc")
|
||||
.stderr(Stdio::inherit())
|
||||
.args(&["--print", "sysroot"])
|
||||
.output()
|
||||
.unwrap()
|
||||
.stdout;
|
||||
Path::new(String::from_utf8(default_sysroot).unwrap().trim()).to_owned()
|
||||
}
|
||||
|
||||
pub(crate) fn get_file_name(crate_name: &str, crate_type: &str) -> String {
|
||||
let file_name = Command::new("rustc")
|
||||
.stderr(Stdio::inherit())
|
||||
.args(&[
|
||||
"--crate-name",
|
||||
crate_name,
|
||||
"--crate-type",
|
||||
crate_type,
|
||||
"--print",
|
||||
"file-names",
|
||||
"-",
|
||||
])
|
||||
.output()
|
||||
.unwrap()
|
||||
.stdout;
|
||||
let file_name = String::from_utf8(file_name).unwrap().trim().to_owned();
|
||||
assert!(!file_name.contains('\n'));
|
||||
assert!(file_name.contains(crate_name));
|
||||
file_name
|
||||
}
|
35
build_system/utils.rs
Normal file
35
build_system/utils.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::process::{self, Command};
|
||||
|
||||
#[track_caller]
|
||||
pub(crate) fn try_hard_link(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
|
||||
let src = src.as_ref();
|
||||
let dst = dst.as_ref();
|
||||
if let Err(_) = fs::hard_link(src, dst) {
|
||||
fs::copy(src, dst).unwrap(); // Fallback to copying if hardlinking failed
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub(crate) fn spawn_and_wait(mut cmd: Command) {
|
||||
if !cmd.spawn().unwrap().wait().unwrap().success() {
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn copy_dir_recursively(from: &Path, to: &Path) {
|
||||
for entry in fs::read_dir(from).unwrap() {
|
||||
let entry = entry.unwrap();
|
||||
let filename = entry.file_name();
|
||||
if filename == "." || filename == ".." {
|
||||
continue;
|
||||
}
|
||||
if entry.metadata().unwrap().is_dir() {
|
||||
fs::create_dir(to.join(&filename)).unwrap();
|
||||
copy_dir_recursively(&from.join(&filename), &to.join(&filename));
|
||||
} else {
|
||||
fs::copy(from.join(&filename), to.join(&filename)).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
rm -rf target/ build/ build_sysroot/{sysroot_src/,target/,compiler-builtins/} perf.data{,.old}
|
||||
rm -rf build_sysroot/{sysroot_src/,target/,compiler-builtins/,rustc_version}
|
||||
rm -rf target/ build/ perf.data{,.old}
|
||||
rm -rf rand/ regex/ simple-raytracer/
|
||||
|
|
17
config.txt
Normal file
17
config.txt
Normal file
|
@ -0,0 +1,17 @@
|
|||
# This file allows configuring the build system.
|
||||
|
||||
# Which triple to produce a compiler toolchain for.
|
||||
#
|
||||
# Defaults to the default triple of rustc on the host system.
|
||||
#host = x86_64-unknown-linux-gnu
|
||||
|
||||
# Which triple to build libraries (core/alloc/std/test/proc_macro) for.
|
||||
#
|
||||
# Defaults to `host`.
|
||||
#target = x86_64-unknown-linux-gnu
|
||||
|
||||
# Disables cleaning of the sysroot dir. This will cause old compiled artifacts to be re-used when
|
||||
# the sysroot source hasn't changed. This is useful when the codegen backend hasn't been modified.
|
||||
# This option can be changed while the build system is already running for as long as sysroot
|
||||
# building hasn't started yet.
|
||||
#keep_sysroot
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
rustc_codegen_cranelift can be used as a near-drop-in replacement for `cargo build` or `cargo run` for existing projects.
|
||||
|
||||
Assuming `$cg_clif_dir` is the directory you cloned this repo into and you followed the instructions (`prepare.sh` and `build.sh` or `test.sh`).
|
||||
Assuming `$cg_clif_dir` is the directory you cloned this repo into and you followed the instructions (`y.rs prepare` and `y.rs build` or `test.sh`).
|
||||
|
||||
## Cargo
|
||||
|
||||
In the directory with your project (where you can do the usual `cargo build`), run:
|
||||
|
||||
```bash
|
||||
$ $cg_clif_dir/build/cargo.sh build
|
||||
$ $cg_clif_dir/build/cargo build
|
||||
```
|
||||
|
||||
This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend.
|
||||
|
@ -30,7 +30,7 @@ In jit mode cg_clif will immediately execute your code without creating an execu
|
|||
> The jit mode will probably need cargo integration to make this possible.
|
||||
|
||||
```bash
|
||||
$ $cg_clif_dir/build/cargo.sh jit
|
||||
$ $cg_clif_dir/build/cargo jit
|
||||
```
|
||||
|
||||
or
|
||||
|
@ -40,11 +40,10 @@ $ $cg_clif_dir/build/bin/cg_clif -Cllvm-args=mode=jit -Cprefer-dynamic my_crate.
|
|||
```
|
||||
|
||||
There is also an experimental lazy jit mode. In this mode functions are only compiled once they are
|
||||
first called. It currently does not work with multi-threaded programs. When a not yet compiled
|
||||
function is called from another thread than the main thread, you will get an ICE.
|
||||
first called.
|
||||
|
||||
```bash
|
||||
$ $cg_clif_dir/build/cargo.sh lazy-jit
|
||||
$ $cg_clif_dir/build/cargo lazy-jit
|
||||
```
|
||||
|
||||
## Shell
|
||||
|
|
|
@ -292,7 +292,7 @@ fn main() {
|
|||
#[cfg(not(any(jit, windows)))]
|
||||
test_tls();
|
||||
|
||||
#[cfg(all(not(jit), target_os = "linux"))]
|
||||
#[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]
|
||||
unsafe {
|
||||
global_asm_test();
|
||||
}
|
||||
|
@ -303,12 +303,12 @@ fn main() {
|
|||
assert_eq!(*REF1, *REF2);
|
||||
}
|
||||
|
||||
#[cfg(all(not(jit), target_os = "linux"))]
|
||||
#[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]
|
||||
extern "C" {
|
||||
fn global_asm_test();
|
||||
}
|
||||
|
||||
#[cfg(all(not(jit), target_os = "linux"))]
|
||||
#[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]
|
||||
global_asm! {
|
||||
"
|
||||
.global global_asm_test
|
||||
|
|
|
@ -15,8 +15,6 @@ fn main() {
|
|||
let stderr = ::std::io::stderr();
|
||||
let mut stderr = stderr.lock();
|
||||
|
||||
// FIXME support lazy jit when multi threading
|
||||
#[cfg(not(lazy_jit))]
|
||||
std::thread::spawn(move || {
|
||||
println!("Hello from another thread!");
|
||||
});
|
||||
|
|
29
prepare.sh
29
prepare.sh
|
@ -1,29 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
./build_sysroot/prepare_sysroot_src.sh
|
||||
cargo install hyperfine || echo "Skipping hyperfine install"
|
||||
|
||||
git clone https://github.com/rust-random/rand.git || echo "rust-random/rand has already been cloned"
|
||||
pushd rand
|
||||
git checkout -- .
|
||||
git checkout 0f933f9c7176e53b2a3c7952ded484e1783f0bf1
|
||||
git am ../crate_patches/*-rand-*.patch
|
||||
popd
|
||||
|
||||
git clone https://github.com/rust-lang/regex.git || echo "rust-lang/regex has already been cloned"
|
||||
pushd regex
|
||||
git checkout -- .
|
||||
git checkout 341f207c1071f7290e3f228c710817c280c8dca1
|
||||
popd
|
||||
|
||||
git clone https://github.com/ebobby/simple-raytracer || echo "ebobby/simple-raytracer has already been cloned"
|
||||
pushd simple-raytracer
|
||||
git checkout -- .
|
||||
git checkout 804a7a21b9e673a482797aa289a18ed480e4d813
|
||||
|
||||
# build with cg_llvm for perf comparison
|
||||
unset CARGO_TARGET_DIR
|
||||
cargo build
|
||||
mv target/debug/main raytracer_cg_llvm
|
||||
popd
|
|
@ -1,3 +1,3 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2021-05-26"
|
||||
channel = "nightly-2021-07-07"
|
||||
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
|
||||
|
|
70
scripts/cargo.rs
Normal file
70
scripts/cargo.rs
Normal file
|
@ -0,0 +1,70 @@
|
|||
use std::env;
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::process::CommandExt;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
fn main() {
|
||||
if env::var("RUSTC_WRAPPER").map_or(false, |wrapper| wrapper.contains("sccache")) {
|
||||
eprintln!(
|
||||
"\x1b[1;93m=== Warning: Unsetting RUSTC_WRAPPER to prevent interference with sccache ===\x1b[0m"
|
||||
);
|
||||
env::remove_var("RUSTC_WRAPPER");
|
||||
}
|
||||
|
||||
let sysroot = PathBuf::from(env::current_exe().unwrap().parent().unwrap());
|
||||
|
||||
env::set_var("RUSTC", sysroot.join("bin/cg_clif".to_string() + env::consts::EXE_SUFFIX));
|
||||
|
||||
let mut rustdoc_flags = env::var("RUSTDOCFLAGS").unwrap_or(String::new());
|
||||
rustdoc_flags.push_str(" -Cpanic=abort -Zpanic-abort-tests -Zcodegen-backend=");
|
||||
rustdoc_flags.push_str(
|
||||
sysroot
|
||||
.join(if cfg!(windows) { "bin" } else { "lib" })
|
||||
.join(
|
||||
env::consts::DLL_PREFIX.to_string()
|
||||
+ "rustc_codegen_cranelift"
|
||||
+ env::consts::DLL_SUFFIX,
|
||||
)
|
||||
.to_str()
|
||||
.unwrap(),
|
||||
);
|
||||
rustdoc_flags.push_str(" --sysroot ");
|
||||
rustdoc_flags.push_str(sysroot.to_str().unwrap());
|
||||
env::set_var("RUSTDOCFLAGS", rustdoc_flags);
|
||||
|
||||
// Ensure that the right toolchain is used
|
||||
env::set_var("RUSTUP_TOOLCHAIN", env!("RUSTUP_TOOLCHAIN"));
|
||||
|
||||
let args: Vec<_> = match env::args().nth(1).as_deref() {
|
||||
Some("jit") => {
|
||||
env::set_var(
|
||||
"RUSTFLAGS",
|
||||
env::var("RUSTFLAGS").unwrap_or(String::new()) + " -Cprefer-dynamic",
|
||||
);
|
||||
std::array::IntoIter::new(["rustc".to_string()])
|
||||
.chain(env::args().skip(2))
|
||||
.chain(["--".to_string(), "-Cllvm-args=mode=jit".to_string()])
|
||||
.collect()
|
||||
}
|
||||
Some("lazy-jit") => {
|
||||
env::set_var(
|
||||
"RUSTFLAGS",
|
||||
env::var("RUSTFLAGS").unwrap_or(String::new()) + " -Cprefer-dynamic",
|
||||
);
|
||||
std::array::IntoIter::new(["rustc".to_string()])
|
||||
.chain(env::args().skip(2))
|
||||
.chain(["--".to_string(), "-Cllvm-args=mode=jit-lazy".to_string()])
|
||||
.collect()
|
||||
}
|
||||
_ => env::args().skip(1).collect(),
|
||||
};
|
||||
|
||||
#[cfg(unix)]
|
||||
Command::new("cargo").args(args).exec();
|
||||
|
||||
#[cfg(not(unix))]
|
||||
std::process::exit(
|
||||
Command::new("cargo").args(args).spawn().unwrap().wait().unwrap().code().unwrap_or(1),
|
||||
);
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
dir=$(dirname "$0")
|
||||
source "$dir/config.sh"
|
||||
|
||||
# read nightly compiler from rust-toolchain file
|
||||
TOOLCHAIN=$(cat "$dir/rust-toolchain" | grep channel | sed "s/channel = \"\(.*\)\"/\1/")
|
||||
|
||||
cmd=$1
|
||||
shift || true
|
||||
|
||||
if [[ "$cmd" = "jit" ]]; then
|
||||
cargo "+${TOOLCHAIN}" rustc "$@" -- -Cllvm-args=mode=jit -Cprefer-dynamic
|
||||
elif [[ "$cmd" = "lazy-jit" ]]; then
|
||||
cargo "+${TOOLCHAIN}" rustc "$@" -- -Cllvm-args=mode=jit-lazy -Cprefer-dynamic
|
||||
else
|
||||
cargo "+${TOOLCHAIN}" "$cmd" "$@"
|
||||
fi
|
|
@ -2,26 +2,5 @@
|
|||
|
||||
set -e
|
||||
|
||||
dylib=$(echo "" | rustc --print file-names --crate-type dylib --crate-name rustc_codegen_cranelift -)
|
||||
|
||||
if echo "$RUSTC_WRAPPER" | grep sccache; then
|
||||
echo
|
||||
echo -e "\x1b[1;93m=== Warning: Unset RUSTC_WRAPPER to prevent interference with sccache ===\x1b[0m"
|
||||
echo
|
||||
export RUSTC_WRAPPER=
|
||||
fi
|
||||
|
||||
dir=$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)
|
||||
|
||||
export RUSTC=$dir"/bin/cg_clif"
|
||||
|
||||
export RUSTDOCFLAGS=$linker' -Cpanic=abort -Zpanic-abort-tests '\
|
||||
'-Zcodegen-backend='$dir'/lib/'$dylib' --sysroot '$dir
|
||||
|
||||
# FIXME fix `#[linkage = "extern_weak"]` without this
|
||||
if [[ "$(uname)" == 'Darwin' ]]; then
|
||||
export RUSTFLAGS="$RUSTFLAGS -Clink-arg=-undefined -Clink-arg=dynamic_lookup"
|
||||
fi
|
||||
|
||||
export LD_LIBRARY_PATH="$(rustc --print sysroot)/lib:"$dir"/lib"
|
||||
export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH
|
||||
export LD_LIBRARY_PATH="$(rustc --print sysroot)/lib:$LD_LIBRARY_PATH"
|
||||
export DYLD_LIBRARY_PATH="$(rustc --print sysroot)/lib:$DYLD_LIBRARY_PATH"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Note to people running shellcheck: this file should only be sourced, not executed directly.
|
||||
|
||||
# Various env vars that should only be set for the build system but not for cargo.sh
|
||||
# Various env vars that should only be set for the build system
|
||||
|
||||
set -e
|
||||
|
||||
|
@ -25,3 +25,8 @@ if [[ "$HOST_TRIPLE" != "$TARGET_TRIPLE" ]]; then
|
|||
echo "Unknown non-native platform"
|
||||
fi
|
||||
fi
|
||||
|
||||
# FIXME fix `#[linkage = "extern_weak"]` without this
|
||||
if [[ "$(uname)" == 'Darwin' ]]; then
|
||||
export RUSTFLAGS="$RUSTFLAGS -Clink-arg=-undefined -Clink-arg=dynamic_lookup"
|
||||
fi
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
#![forbid(unsafe_code)]/* This line is ignored by bash
|
||||
# This block is ignored by rustc
|
||||
pushd $(dirname "$0")/../
|
||||
source build/config.sh
|
||||
source scripts/config.sh
|
||||
RUSTC="$(pwd)/build/bin/cg_clif"
|
||||
popd
|
||||
PROFILE=$1 OUTPUT=$2 exec $RUSTC $RUSTFLAGS -Cllvm-args=mode=jit -Cprefer-dynamic $0
|
||||
PROFILE=$1 OUTPUT=$2 exec $RUSTC -Cllvm-args=mode=jit -Cprefer-dynamic $0
|
||||
#*/
|
||||
|
||||
//! This program filters away uninteresting samples and trims uninteresting frames for stackcollapse
|
||||
|
|
|
@ -17,7 +17,7 @@ case $1 in
|
|||
done
|
||||
|
||||
./clean_all.sh
|
||||
./prepare.sh
|
||||
./y.rs prepare
|
||||
|
||||
(cd build_sysroot && cargo update)
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
./build.sh
|
||||
source build/config.sh
|
||||
./y.rs build
|
||||
source scripts/config.sh
|
||||
|
||||
echo "[SETUP] Rust fork"
|
||||
git clone https://github.com/rust-lang/rust.git || true
|
||||
|
@ -33,7 +33,7 @@ index d95b5b7f17f..00b6f0e3635 100644
|
|||
[dependencies]
|
||||
core = { path = "../core" }
|
||||
-compiler_builtins = { version = "0.1.40", features = ['rustc-dep-of-std'] }
|
||||
+compiler_builtins = { version = "0.1.43", features = ['rustc-dep-of-std', 'no-asm'] }
|
||||
+compiler_builtins = { version = "0.1.45", features = ['rustc-dep-of-std', 'no-asm'] }
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.7"
|
||||
|
|
|
@ -38,7 +38,8 @@ rm src/test/ui/threads-sendsync/task-stderr.rs
|
|||
rm src/test/ui/numbers-arithmetic/int-abs-overflow.rs
|
||||
rm src/test/ui/drop/drop-trait-enum.rs
|
||||
rm src/test/ui/numbers-arithmetic/issue-8460.rs
|
||||
rm src/test/incremental/change_crate_dep_kind.rs # requires -Cpanic=unwind
|
||||
rm src/test/ui/rt-explody-panic-payloads.rs
|
||||
rm src/test/incremental/change_crate_dep_kind.rs
|
||||
|
||||
rm src/test/ui/issues/issue-28950.rs # depends on stack size optimizations
|
||||
rm src/test/ui/init-large-type.rs # same
|
||||
|
@ -64,6 +65,7 @@ rm src/test/incremental/lto.rs # requires lto
|
|||
|
||||
rm -r src/test/run-make/emit-shared-files # requires the rustdoc executable in build/bin/
|
||||
rm -r src/test/run-make/unstable-flag-required # same
|
||||
rm -r src/test/run-make/emit-named-files # requires full --emit support
|
||||
|
||||
rm src/test/pretty/asm.rs # inline asm
|
||||
rm src/test/pretty/raw-str-nonexpr.rs # same
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
|
||||
set -e
|
||||
|
||||
source build/config.sh
|
||||
source scripts/config.sh
|
||||
source scripts/ext_config.sh
|
||||
MY_RUSTC="$RUSTC $RUSTFLAGS -L crate=target/out --out-dir target/out -Cdebuginfo=2"
|
||||
export RUSTC=false # ensure that cg_llvm isn't accidentally used
|
||||
MY_RUSTC="$(pwd)/build/bin/cg_clif $RUSTFLAGS -L crate=target/out --out-dir target/out -Cdebuginfo=2"
|
||||
|
||||
function no_sysroot_tests() {
|
||||
echo "[BUILD] mini_core"
|
||||
|
@ -46,7 +47,7 @@ function base_sysroot_tests() {
|
|||
$MY_RUSTC -Cllvm-args=mode=jit -Cprefer-dynamic example/std_example.rs --target "$HOST_TRIPLE"
|
||||
|
||||
echo "[JIT-lazy] std_example"
|
||||
$MY_RUSTC -Cllvm-args=mode=jit-lazy -Cprefer-dynamic example/std_example.rs --cfg lazy_jit --target "$HOST_TRIPLE"
|
||||
$MY_RUSTC -Cllvm-args=mode=jit-lazy -Cprefer-dynamic example/std_example.rs --target "$HOST_TRIPLE"
|
||||
else
|
||||
echo "[JIT] std_example (skipped)"
|
||||
fi
|
||||
|
@ -75,63 +76,64 @@ function base_sysroot_tests() {
|
|||
|
||||
function extended_sysroot_tests() {
|
||||
pushd rand
|
||||
cargo clean
|
||||
../build/cargo clean
|
||||
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
||||
echo "[TEST] rust-random/rand"
|
||||
../build/cargo.sh test --workspace
|
||||
../build/cargo test --workspace
|
||||
else
|
||||
echo "[AOT] rust-random/rand"
|
||||
../build/cargo.sh build --workspace --target $TARGET_TRIPLE --tests
|
||||
../build/cargo build --workspace --target $TARGET_TRIPLE --tests
|
||||
fi
|
||||
popd
|
||||
|
||||
pushd simple-raytracer
|
||||
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
||||
echo "[BENCH COMPILE] ebobby/simple-raytracer"
|
||||
hyperfine --runs "${RUN_RUNS:-10}" --warmup 1 --prepare "cargo clean" \
|
||||
hyperfine --runs "${RUN_RUNS:-10}" --warmup 1 --prepare "../build/cargo clean" \
|
||||
"RUSTC=rustc RUSTFLAGS='' cargo build" \
|
||||
"../build/cargo.sh build"
|
||||
"../build/cargo build"
|
||||
|
||||
echo "[BENCH RUN] ebobby/simple-raytracer"
|
||||
cp ./target/debug/main ./raytracer_cg_clif
|
||||
hyperfine --runs "${RUN_RUNS:-10}" ./raytracer_cg_llvm ./raytracer_cg_clif
|
||||
else
|
||||
../build/cargo clean
|
||||
echo "[BENCH COMPILE] ebobby/simple-raytracer (skipped)"
|
||||
echo "[COMPILE] ebobby/simple-raytracer"
|
||||
../build/cargo.sh build --target $TARGET_TRIPLE
|
||||
../build/cargo build --target $TARGET_TRIPLE
|
||||
echo "[BENCH RUN] ebobby/simple-raytracer (skipped)"
|
||||
fi
|
||||
popd
|
||||
|
||||
pushd build_sysroot/sysroot_src/library/core/tests
|
||||
echo "[TEST] libcore"
|
||||
cargo clean
|
||||
../../../../../build/cargo clean
|
||||
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
||||
../../../../../build/cargo.sh test
|
||||
../../../../../build/cargo test
|
||||
else
|
||||
../../../../../build/cargo.sh build --target $TARGET_TRIPLE --tests
|
||||
../../../../../build/cargo build --target $TARGET_TRIPLE --tests
|
||||
fi
|
||||
popd
|
||||
|
||||
pushd regex
|
||||
echo "[TEST] rust-lang/regex example shootout-regex-dna"
|
||||
cargo clean
|
||||
../build/cargo clean
|
||||
export RUSTFLAGS="$RUSTFLAGS --cap-lints warn" # newer aho_corasick versions throw a deprecation warning
|
||||
# Make sure `[codegen mono items] start` doesn't poison the diff
|
||||
../build/cargo.sh build --example shootout-regex-dna --target $TARGET_TRIPLE
|
||||
../build/cargo build --example shootout-regex-dna --target $TARGET_TRIPLE
|
||||
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
||||
cat examples/regexdna-input.txt \
|
||||
| ../build/cargo.sh run --example shootout-regex-dna --target $TARGET_TRIPLE \
|
||||
| ../build/cargo run --example shootout-regex-dna --target $TARGET_TRIPLE \
|
||||
| grep -v "Spawned thread" > res.txt
|
||||
diff -u res.txt examples/regexdna-output.txt
|
||||
fi
|
||||
|
||||
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
||||
echo "[TEST] rust-lang/regex tests"
|
||||
../build/cargo.sh test --tests -- --exclude-should-panic --test-threads 1 -Zunstable-options -q
|
||||
../build/cargo test --tests -- --exclude-should-panic --test-threads 1 -Zunstable-options -q
|
||||
else
|
||||
echo "[AOT] rust-lang/regex tests"
|
||||
../build/cargo.sh build --tests --target $TARGET_TRIPLE
|
||||
../build/cargo build --tests --target $TARGET_TRIPLE
|
||||
fi
|
||||
popd
|
||||
}
|
||||
|
|
25
src/base.rs
25
src/base.rs
|
@ -21,6 +21,11 @@ pub(crate) fn codegen_fn<'tcx>(
|
|||
debug_assert!(!instance.substs.needs_infer());
|
||||
|
||||
let mir = tcx.instance_mir(instance.def);
|
||||
let _mir_guard = crate::PrintOnPanic(|| {
|
||||
let mut buf = Vec::new();
|
||||
rustc_mir::util::write_mir_pretty(tcx, Some(instance.def_id()), &mut buf).unwrap();
|
||||
String::from_utf8_lossy(&buf).into_owned()
|
||||
});
|
||||
|
||||
// Declare function
|
||||
let symbol_name = tcx.symbol_name(instance);
|
||||
|
@ -52,7 +57,6 @@ pub(crate) fn codegen_fn<'tcx>(
|
|||
module,
|
||||
tcx,
|
||||
pointer_type,
|
||||
vtables: FxHashMap::default(),
|
||||
constants_cx: ConstantCx::new(),
|
||||
|
||||
instance,
|
||||
|
@ -105,7 +109,14 @@ pub(crate) fn codegen_fn<'tcx>(
|
|||
let context = &mut cx.cached_context;
|
||||
context.func = func;
|
||||
|
||||
crate::pretty_clif::write_clif_file(tcx, "unopt", None, instance, &context, &clif_comments);
|
||||
crate::pretty_clif::write_clif_file(
|
||||
tcx,
|
||||
"unopt",
|
||||
module.isa(),
|
||||
instance,
|
||||
&context,
|
||||
&clif_comments,
|
||||
);
|
||||
|
||||
// Verify function
|
||||
verify_func(tcx, &clif_comments, &context.func);
|
||||
|
@ -122,7 +133,13 @@ pub(crate) fn codegen_fn<'tcx>(
|
|||
|
||||
// Perform rust specific optimizations
|
||||
tcx.sess.time("optimize clif ir", || {
|
||||
crate::optimize::optimize_function(tcx, instance, context, &mut clif_comments);
|
||||
crate::optimize::optimize_function(
|
||||
tcx,
|
||||
module.isa(),
|
||||
instance,
|
||||
context,
|
||||
&mut clif_comments,
|
||||
);
|
||||
});
|
||||
|
||||
// Define function
|
||||
|
@ -137,7 +154,7 @@ pub(crate) fn codegen_fn<'tcx>(
|
|||
crate::pretty_clif::write_clif_file(
|
||||
tcx,
|
||||
"opt",
|
||||
Some(module.isa()),
|
||||
module.isa(),
|
||||
instance,
|
||||
&context,
|
||||
&clif_comments,
|
||||
|
|
|
@ -6,8 +6,8 @@ extern crate rustc_interface;
|
|||
extern crate rustc_session;
|
||||
extern crate rustc_target;
|
||||
|
||||
use std::panic;
|
||||
use std::lazy::SyncLazy;
|
||||
use std::panic;
|
||||
|
||||
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
|
||||
use rustc_interface::interface;
|
||||
|
|
|
@ -233,7 +233,6 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
|
|||
pub(crate) module: &'m mut dyn Module,
|
||||
pub(crate) tcx: TyCtxt<'tcx>,
|
||||
pub(crate) pointer_type: Type, // Cached from module
|
||||
pub(crate) vtables: FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), Pointer>,
|
||||
pub(crate) constants_cx: ConstantCx,
|
||||
|
||||
pub(crate) instance: Instance<'tcx>,
|
||||
|
|
143
src/constant.rs
143
src/constant.rs
|
@ -1,16 +1,13 @@
|
|||
//! Handling of `static`s, `const`s and promoted allocations
|
||||
|
||||
use rustc_span::DUMMY_SP;
|
||||
|
||||
use rustc_ast::Mutability;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_errors::ErrorReported;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use rustc_middle::mir::interpret::{
|
||||
alloc_range, read_target_uint, AllocId, Allocation, ConstValue, ErrorHandled, GlobalAlloc,
|
||||
Scalar,
|
||||
read_target_uint, AllocId, Allocation, ConstValue, ErrorHandled, GlobalAlloc, Scalar,
|
||||
};
|
||||
use rustc_middle::ty::ConstKind;
|
||||
use rustc_span::DUMMY_SP;
|
||||
|
||||
use cranelift_codegen::ir::GlobalValueData;
|
||||
use cranelift_module::*;
|
||||
|
@ -171,66 +168,74 @@ pub(crate) fn codegen_const_value<'tcx>(
|
|||
}
|
||||
|
||||
match const_val {
|
||||
ConstValue::Scalar(x) => {
|
||||
if fx.clif_type(layout.ty).is_none() {
|
||||
let (size, align) = (layout.size, layout.align.pref);
|
||||
let mut alloc = Allocation::from_bytes(
|
||||
std::iter::repeat(0).take(size.bytes_usize()).collect::<Vec<u8>>(),
|
||||
align,
|
||||
Mutability::Not,
|
||||
);
|
||||
alloc.write_scalar(fx, alloc_range(Size::ZERO, size), x.into()).unwrap();
|
||||
let alloc = fx.tcx.intern_const_alloc(alloc);
|
||||
return CValue::by_ref(pointer_for_allocation(fx, alloc), layout);
|
||||
}
|
||||
ConstValue::Scalar(x) => match x {
|
||||
Scalar::Int(int) => {
|
||||
if fx.clif_type(layout.ty).is_some() {
|
||||
return CValue::const_val(fx, layout, int);
|
||||
} else {
|
||||
let raw_val = int.to_bits(int.size()).unwrap();
|
||||
let val = match int.size().bytes() {
|
||||
1 => fx.bcx.ins().iconst(types::I8, raw_val as i64),
|
||||
2 => fx.bcx.ins().iconst(types::I16, raw_val as i64),
|
||||
4 => fx.bcx.ins().iconst(types::I32, raw_val as i64),
|
||||
8 => fx.bcx.ins().iconst(types::I64, raw_val as i64),
|
||||
16 => {
|
||||
let lsb = fx.bcx.ins().iconst(types::I64, raw_val as u64 as i64);
|
||||
let msb =
|
||||
fx.bcx.ins().iconst(types::I64, (raw_val >> 64) as u64 as i64);
|
||||
fx.bcx.ins().iconcat(lsb, msb)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
match x {
|
||||
Scalar::Int(int) => CValue::const_val(fx, layout, int),
|
||||
Scalar::Ptr(ptr) => {
|
||||
let alloc_kind = fx.tcx.get_global_alloc(ptr.alloc_id);
|
||||
let base_addr = match alloc_kind {
|
||||
Some(GlobalAlloc::Memory(alloc)) => {
|
||||
fx.constants_cx.todo.push(TodoItem::Alloc(ptr.alloc_id));
|
||||
let data_id = data_id_for_alloc_id(
|
||||
&mut fx.constants_cx,
|
||||
fx.module,
|
||||
ptr.alloc_id,
|
||||
alloc.mutability,
|
||||
);
|
||||
let local_data_id =
|
||||
fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
|
||||
if fx.clif_comments.enabled() {
|
||||
fx.add_comment(local_data_id, format!("{:?}", ptr.alloc_id));
|
||||
}
|
||||
fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
|
||||
}
|
||||
Some(GlobalAlloc::Function(instance)) => {
|
||||
let func_id = crate::abi::import_function(fx.tcx, fx.module, instance);
|
||||
let local_func_id =
|
||||
fx.module.declare_func_in_func(func_id, &mut fx.bcx.func);
|
||||
fx.bcx.ins().func_addr(fx.pointer_type, local_func_id)
|
||||
}
|
||||
Some(GlobalAlloc::Static(def_id)) => {
|
||||
assert!(fx.tcx.is_static(def_id));
|
||||
let data_id = data_id_for_static(fx.tcx, fx.module, def_id, false);
|
||||
let local_data_id =
|
||||
fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
|
||||
if fx.clif_comments.enabled() {
|
||||
fx.add_comment(local_data_id, format!("{:?}", def_id));
|
||||
}
|
||||
fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
|
||||
}
|
||||
None => bug!("missing allocation {:?}", ptr.alloc_id),
|
||||
};
|
||||
let val = if ptr.offset.bytes() != 0 {
|
||||
fx.bcx.ins().iadd_imm(base_addr, i64::try_from(ptr.offset.bytes()).unwrap())
|
||||
} else {
|
||||
base_addr
|
||||
};
|
||||
CValue::by_val(val, layout)
|
||||
let place = CPlace::new_stack_slot(fx, layout);
|
||||
place.to_ptr().store(fx, val, MemFlags::trusted());
|
||||
place.to_cvalue(fx)
|
||||
}
|
||||
}
|
||||
}
|
||||
Scalar::Ptr(ptr) => {
|
||||
let alloc_kind = fx.tcx.get_global_alloc(ptr.alloc_id);
|
||||
let base_addr = match alloc_kind {
|
||||
Some(GlobalAlloc::Memory(alloc)) => {
|
||||
let data_id = data_id_for_alloc_id(
|
||||
&mut fx.constants_cx,
|
||||
fx.module,
|
||||
ptr.alloc_id,
|
||||
alloc.mutability,
|
||||
);
|
||||
let local_data_id =
|
||||
fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
|
||||
if fx.clif_comments.enabled() {
|
||||
fx.add_comment(local_data_id, format!("{:?}", ptr.alloc_id));
|
||||
}
|
||||
fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
|
||||
}
|
||||
Some(GlobalAlloc::Function(instance)) => {
|
||||
let func_id = crate::abi::import_function(fx.tcx, fx.module, instance);
|
||||
let local_func_id =
|
||||
fx.module.declare_func_in_func(func_id, &mut fx.bcx.func);
|
||||
fx.bcx.ins().func_addr(fx.pointer_type, local_func_id)
|
||||
}
|
||||
Some(GlobalAlloc::Static(def_id)) => {
|
||||
assert!(fx.tcx.is_static(def_id));
|
||||
let data_id = data_id_for_static(fx.tcx, fx.module, def_id, false);
|
||||
let local_data_id =
|
||||
fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
|
||||
if fx.clif_comments.enabled() {
|
||||
fx.add_comment(local_data_id, format!("{:?}", def_id));
|
||||
}
|
||||
fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
|
||||
}
|
||||
None => bug!("missing allocation {:?}", ptr.alloc_id),
|
||||
};
|
||||
let val = if ptr.offset.bytes() != 0 {
|
||||
fx.bcx.ins().iadd_imm(base_addr, i64::try_from(ptr.offset.bytes()).unwrap())
|
||||
} else {
|
||||
base_addr
|
||||
};
|
||||
CValue::by_val(val, layout)
|
||||
}
|
||||
},
|
||||
ConstValue::ByRef { alloc, offset } => CValue::by_ref(
|
||||
pointer_for_allocation(fx, alloc)
|
||||
.offset_i64(fx, i64::try_from(offset.bytes()).unwrap()),
|
||||
|
@ -254,7 +259,6 @@ pub(crate) fn pointer_for_allocation<'tcx>(
|
|||
alloc: &'tcx Allocation,
|
||||
) -> crate::pointer::Pointer {
|
||||
let alloc_id = fx.tcx.create_memory_alloc(alloc);
|
||||
fx.constants_cx.todo.push(TodoItem::Alloc(alloc_id));
|
||||
let data_id =
|
||||
data_id_for_alloc_id(&mut fx.constants_cx, &mut *fx.module, alloc_id, alloc.mutability);
|
||||
|
||||
|
@ -266,12 +270,13 @@ pub(crate) fn pointer_for_allocation<'tcx>(
|
|||
crate::pointer::Pointer::new(global_ptr)
|
||||
}
|
||||
|
||||
fn data_id_for_alloc_id(
|
||||
pub(crate) fn data_id_for_alloc_id(
|
||||
cx: &mut ConstantCx,
|
||||
module: &mut dyn Module,
|
||||
alloc_id: AllocId,
|
||||
mutability: rustc_hir::Mutability,
|
||||
) -> DataId {
|
||||
cx.todo.push(TodoItem::Alloc(alloc_id));
|
||||
*cx.anon_allocs.entry(alloc_id).or_insert_with(|| {
|
||||
module.declare_anonymous_data(mutability == rustc_hir::Mutability::Mut, false).unwrap()
|
||||
})
|
||||
|
@ -352,7 +357,14 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
|||
GlobalAlloc::Memory(alloc) => alloc,
|
||||
GlobalAlloc::Function(_) | GlobalAlloc::Static(_) => unreachable!(),
|
||||
};
|
||||
let data_id = data_id_for_alloc_id(cx, module, alloc_id, alloc.mutability);
|
||||
let data_id = *cx.anon_allocs.entry(alloc_id).or_insert_with(|| {
|
||||
module
|
||||
.declare_anonymous_data(
|
||||
alloc.mutability == rustc_hir::Mutability::Mut,
|
||||
false,
|
||||
)
|
||||
.unwrap()
|
||||
});
|
||||
(data_id, alloc, None)
|
||||
}
|
||||
TodoItem::Static(def_id) => {
|
||||
|
@ -415,7 +427,6 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
|||
continue;
|
||||
}
|
||||
GlobalAlloc::Memory(target_alloc) => {
|
||||
cx.todo.push(TodoItem::Alloc(reloc));
|
||||
data_id_for_alloc_id(cx, module, reloc, target_alloc.mutability)
|
||||
}
|
||||
GlobalAlloc::Static(def_id) => {
|
||||
|
|
|
@ -10,7 +10,7 @@ use rustc_span::{
|
|||
};
|
||||
|
||||
use cranelift_codegen::binemit::CodeOffset;
|
||||
use cranelift_codegen::machinst::MachSrcLoc;
|
||||
use cranelift_codegen::MachSrcLoc;
|
||||
|
||||
use gimli::write::{
|
||||
Address, AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable,
|
||||
|
|
|
@ -61,9 +61,11 @@ impl<'tcx> DebugContext<'tcx> {
|
|||
|
||||
let mut dwarf = DwarfUnit::new(encoding);
|
||||
|
||||
// FIXME: how to get version when building out of tree?
|
||||
// Normally this would use option_env!("CFG_VERSION").
|
||||
let producer = format!("cg_clif (rustc {})", "unknown version");
|
||||
let producer = format!(
|
||||
"cg_clif (rustc {}, cranelift {})",
|
||||
rustc_interface::util::version_str().unwrap_or("unknown version"),
|
||||
cranelift_codegen::VERSION,
|
||||
);
|
||||
let comp_dir = tcx.sess.working_dir.to_string_lossy(false).into_owned();
|
||||
let (name, file_info) = match tcx.sess.local_crate_source_file.clone() {
|
||||
Some(path) => {
|
||||
|
|
|
@ -289,13 +289,16 @@ pub(crate) fn run_aot(
|
|||
None
|
||||
};
|
||||
|
||||
// FIXME handle `-Ctarget-cpu=native`
|
||||
let target_cpu =
|
||||
tcx.sess.opts.cg.target_cpu.as_ref().unwrap_or(&tcx.sess.target.cpu).to_owned();
|
||||
Box::new((
|
||||
CodegenResults {
|
||||
modules,
|
||||
allocator_module,
|
||||
metadata_module,
|
||||
metadata,
|
||||
crate_info: CrateInfo::new(tcx, crate::target_triple(tcx.sess).to_string()),
|
||||
crate_info: CrateInfo::new(tcx, target_cpu),
|
||||
},
|
||||
work_products,
|
||||
))
|
||||
|
|
|
@ -3,11 +3,14 @@
|
|||
|
||||
use std::cell::RefCell;
|
||||
use std::ffi::CString;
|
||||
use std::lazy::{Lazy, SyncOnceCell};
|
||||
use std::os::raw::{c_char, c_int};
|
||||
use std::sync::{mpsc, Mutex};
|
||||
|
||||
use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink};
|
||||
use rustc_codegen_ssa::CrateInfo;
|
||||
use rustc_middle::mir::mono::MonoItem;
|
||||
use rustc_session::Session;
|
||||
|
||||
use cranelift_jit::{JITBuilder, JITModule};
|
||||
|
||||
|
@ -23,12 +26,48 @@ thread_local! {
|
|||
static LAZY_JIT_STATE: RefCell<Option<JitState>> = RefCell::new(None);
|
||||
}
|
||||
|
||||
/// The Sender owned by the rustc thread
|
||||
static GLOBAL_MESSAGE_SENDER: SyncOnceCell<Mutex<mpsc::Sender<UnsafeMessage>>> =
|
||||
SyncOnceCell::new();
|
||||
|
||||
/// A message that is sent from the jitted runtime to the rustc thread.
|
||||
/// Senders are responsible for upholding `Send` semantics.
|
||||
enum UnsafeMessage {
|
||||
/// Request that the specified `Instance` be lazily jitted.
|
||||
///
|
||||
/// Nothing accessible through `instance_ptr` may be moved or mutated by the sender after
|
||||
/// this message is sent.
|
||||
JitFn {
|
||||
instance_ptr: *const Instance<'static>,
|
||||
trampoline_ptr: *const u8,
|
||||
tx: mpsc::Sender<*const u8>,
|
||||
},
|
||||
}
|
||||
unsafe impl Send for UnsafeMessage {}
|
||||
|
||||
impl UnsafeMessage {
|
||||
/// Send the message.
|
||||
fn send(self) -> Result<(), mpsc::SendError<UnsafeMessage>> {
|
||||
thread_local! {
|
||||
/// The Sender owned by the local thread
|
||||
static LOCAL_MESSAGE_SENDER: Lazy<mpsc::Sender<UnsafeMessage>> = Lazy::new(||
|
||||
GLOBAL_MESSAGE_SENDER
|
||||
.get().unwrap()
|
||||
.lock().unwrap()
|
||||
.clone()
|
||||
);
|
||||
}
|
||||
LOCAL_MESSAGE_SENDER.with(|sender| sender.send(self))
|
||||
}
|
||||
}
|
||||
|
||||
fn create_jit_module<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
backend_config: &BackendConfig,
|
||||
hotswap: bool,
|
||||
) -> (JITModule, CodegenCx<'tcx>) {
|
||||
let imported_symbols = load_imported_symbols_for_jit(tcx);
|
||||
let crate_info = CrateInfo::new(tcx, "dummy_target_cpu".to_string());
|
||||
let imported_symbols = load_imported_symbols_for_jit(tcx.sess, crate_info);
|
||||
|
||||
let isa = crate::build_isa(tcx.sess, backend_config);
|
||||
let mut jit_builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names());
|
||||
|
@ -116,11 +155,6 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
|
|||
.chain(backend_config.jit_args.iter().map(|arg| &**arg))
|
||||
.map(|arg| CString::new(arg).unwrap())
|
||||
.collect::<Vec<_>>();
|
||||
let mut argv = args.iter().map(|arg| arg.as_ptr()).collect::<Vec<_>>();
|
||||
|
||||
// Push a null pointer as a terminating argument. This is required by POSIX and
|
||||
// useful as some dynamic linkers use it as a marker to jump over.
|
||||
argv.push(std::ptr::null());
|
||||
|
||||
let start_sig = Signature {
|
||||
params: vec![
|
||||
|
@ -128,7 +162,7 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
|
|||
AbiParam::new(jit_module.target_config().pointer_type()),
|
||||
],
|
||||
returns: vec![AbiParam::new(jit_module.target_config().pointer_type() /*isize*/)],
|
||||
call_conv: CallConv::triple_default(&crate::target_triple(tcx.sess)),
|
||||
call_conv: jit_module.target_config().default_call_conv,
|
||||
};
|
||||
let start_func_id = jit_module.declare_function("main", Linkage::Import, &start_sig).unwrap();
|
||||
let finalized_start: *const u8 = jit_module.get_finalized_function(start_func_id);
|
||||
|
@ -141,12 +175,51 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
|
|||
|
||||
let f: extern "C" fn(c_int, *const *const c_char) -> c_int =
|
||||
unsafe { ::std::mem::transmute(finalized_start) };
|
||||
let ret = f(args.len() as c_int, argv.as_ptr());
|
||||
std::process::exit(ret);
|
||||
|
||||
let (tx, rx) = mpsc::channel();
|
||||
GLOBAL_MESSAGE_SENDER.set(Mutex::new(tx)).unwrap();
|
||||
|
||||
// Spawn the jitted runtime in a new thread so that this rustc thread can handle messages
|
||||
// (eg to lazily JIT further functions as required)
|
||||
std::thread::spawn(move || {
|
||||
let mut argv = args.iter().map(|arg| arg.as_ptr()).collect::<Vec<_>>();
|
||||
|
||||
// Push a null pointer as a terminating argument. This is required by POSIX and
|
||||
// useful as some dynamic linkers use it as a marker to jump over.
|
||||
argv.push(std::ptr::null());
|
||||
|
||||
let ret = f(args.len() as c_int, argv.as_ptr());
|
||||
std::process::exit(ret);
|
||||
});
|
||||
|
||||
// Handle messages
|
||||
loop {
|
||||
match rx.recv().unwrap() {
|
||||
// lazy JIT compilation request - compile requested instance and return pointer to result
|
||||
UnsafeMessage::JitFn { instance_ptr, trampoline_ptr, tx } => {
|
||||
tx.send(jit_fn(instance_ptr, trampoline_ptr))
|
||||
.expect("jitted runtime hung up before response to lazy JIT request was sent");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn __clif_jit_fn(instance_ptr: *const Instance<'static>) -> *const u8 {
|
||||
extern "C" fn __clif_jit_fn(
|
||||
instance_ptr: *const Instance<'static>,
|
||||
trampoline_ptr: *const u8,
|
||||
) -> *const u8 {
|
||||
// send the JIT request to the rustc thread, with a channel for the response
|
||||
let (tx, rx) = mpsc::channel();
|
||||
UnsafeMessage::JitFn { instance_ptr, trampoline_ptr, tx }
|
||||
.send()
|
||||
.expect("rustc thread hung up before lazy JIT request was sent");
|
||||
|
||||
// block on JIT compilation result
|
||||
rx.recv().expect("rustc thread hung up before responding to sent lazy JIT request")
|
||||
}
|
||||
|
||||
fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) -> *const u8 {
|
||||
rustc_middle::ty::tls::with(|tcx| {
|
||||
// lift is used to ensure the correct lifetime for instance.
|
||||
let instance = tcx.lift(unsafe { *instance_ptr }).unwrap();
|
||||
|
@ -160,6 +233,17 @@ extern "C" fn __clif_jit_fn(instance_ptr: *const Instance<'static>) -> *const u8
|
|||
let name = tcx.symbol_name(instance).name;
|
||||
let sig = crate::abi::get_function_sig(tcx, jit_module.isa().triple(), instance);
|
||||
let func_id = jit_module.declare_function(name, Linkage::Export, &sig).unwrap();
|
||||
|
||||
let current_ptr = jit_module.read_got_entry(func_id);
|
||||
|
||||
// If the function's GOT entry has already been updated to point at something other
|
||||
// than the shim trampoline, don't re-jit but just return the new pointer instead.
|
||||
// This does not need synchronization as this code is executed only by a sole rustc
|
||||
// thread.
|
||||
if current_ptr != trampoline_ptr {
|
||||
return current_ptr;
|
||||
}
|
||||
|
||||
jit_module.prepare_for_function_redefine(func_id).unwrap();
|
||||
|
||||
let mut cx = crate::CodegenCx::new(tcx, backend_config, jit_module.isa(), false);
|
||||
|
@ -173,14 +257,16 @@ extern "C" fn __clif_jit_fn(instance_ptr: *const Instance<'static>) -> *const u8
|
|||
})
|
||||
}
|
||||
|
||||
fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> {
|
||||
fn load_imported_symbols_for_jit(
|
||||
sess: &Session,
|
||||
crate_info: CrateInfo,
|
||||
) -> Vec<(String, *const u8)> {
|
||||
use rustc_middle::middle::dependency_format::Linkage;
|
||||
|
||||
let mut dylib_paths = Vec::new();
|
||||
|
||||
let crate_info = CrateInfo::new(tcx, "dummy_target_cpu".to_string());
|
||||
let formats = tcx.dependency_formats(());
|
||||
let data = &formats
|
||||
let data = &crate_info
|
||||
.dependency_formats
|
||||
.iter()
|
||||
.find(|(crate_type, _data)| *crate_type == rustc_session::config::CrateType::Executable)
|
||||
.unwrap()
|
||||
|
@ -190,9 +276,8 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> {
|
|||
match data[cnum.as_usize() - 1] {
|
||||
Linkage::NotLinked | Linkage::IncludedFromDylib => {}
|
||||
Linkage::Static => {
|
||||
let name = tcx.crate_name(cnum);
|
||||
let mut err =
|
||||
tcx.sess.struct_err(&format!("Can't load static lib {}", name.as_str()));
|
||||
let name = &crate_info.crate_name[&cnum];
|
||||
let mut err = sess.struct_err(&format!("Can't load static lib {}", name.as_str()));
|
||||
err.note("rustc_codegen_cranelift can only load dylibs in JIT mode.");
|
||||
err.emit();
|
||||
}
|
||||
|
@ -232,7 +317,7 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> {
|
|||
std::mem::forget(lib)
|
||||
}
|
||||
|
||||
tcx.sess.abort_if_errors();
|
||||
sess.abort_if_errors();
|
||||
|
||||
imported_symbols
|
||||
}
|
||||
|
@ -254,7 +339,7 @@ fn codegen_shim<'tcx>(cx: &mut CodegenCx<'tcx>, module: &mut JITModule, inst: In
|
|||
Linkage::Import,
|
||||
&Signature {
|
||||
call_conv: module.target_config().default_call_conv,
|
||||
params: vec![AbiParam::new(pointer_type)],
|
||||
params: vec![AbiParam::new(pointer_type), AbiParam::new(pointer_type)],
|
||||
returns: vec![AbiParam::new(pointer_type)],
|
||||
},
|
||||
)
|
||||
|
@ -267,6 +352,7 @@ fn codegen_shim<'tcx>(cx: &mut CodegenCx<'tcx>, module: &mut JITModule, inst: In
|
|||
let mut builder_ctx = FunctionBuilderContext::new();
|
||||
let mut trampoline_builder = FunctionBuilder::new(trampoline, &mut builder_ctx);
|
||||
|
||||
let trampoline_fn = module.declare_func_in_func(func_id, trampoline_builder.func);
|
||||
let jit_fn = module.declare_func_in_func(jit_fn, trampoline_builder.func);
|
||||
let sig_ref = trampoline_builder.func.import_signature(sig);
|
||||
|
||||
|
@ -276,7 +362,8 @@ fn codegen_shim<'tcx>(cx: &mut CodegenCx<'tcx>, module: &mut JITModule, inst: In
|
|||
|
||||
trampoline_builder.switch_to_block(entry_block);
|
||||
let instance_ptr = trampoline_builder.ins().iconst(pointer_type, instance_ptr as u64 as i64);
|
||||
let jitted_fn = trampoline_builder.ins().call(jit_fn, &[instance_ptr]);
|
||||
let trampoline_ptr = trampoline_builder.ins().func_addr(pointer_type, trampoline_fn);
|
||||
let jitted_fn = trampoline_builder.ins().call(jit_fn, &[instance_ptr, trampoline_ptr]);
|
||||
let jitted_fn = trampoline_builder.func.dfg.inst_results(jitted_fn)[0];
|
||||
let call_inst = trampoline_builder.ins().call_indirect(sig_ref, jitted_fn, &fn_args);
|
||||
let ret_vals = trampoline_builder.func.dfg.inst_results(call_inst).to_vec();
|
||||
|
|
|
@ -106,6 +106,26 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
|
|||
let dest = CPlace::for_ptr(Pointer::new(mem_addr), a.layout());
|
||||
dest.write_cvalue(fx, a);
|
||||
};
|
||||
"llvm.x86.addcarry.64", (v c_in, c a, c b) {
|
||||
llvm_add_sub(
|
||||
fx,
|
||||
BinOp::Add,
|
||||
ret,
|
||||
c_in,
|
||||
a,
|
||||
b
|
||||
);
|
||||
};
|
||||
"llvm.x86.subborrow.64", (v b_in, c a, c b) {
|
||||
llvm_add_sub(
|
||||
fx,
|
||||
BinOp::Sub,
|
||||
ret,
|
||||
b_in,
|
||||
a,
|
||||
b
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
if let Some((_, dest)) = destination {
|
||||
|
@ -121,3 +141,41 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
|
|||
// llvm.x86.avx2.pshuf.b
|
||||
// llvm.x86.avx2.psrli.w
|
||||
// llvm.x86.sse2.psrli.w
|
||||
|
||||
fn llvm_add_sub<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
bin_op: BinOp,
|
||||
ret: CPlace<'tcx>,
|
||||
cb_in: Value,
|
||||
a: CValue<'tcx>,
|
||||
b: CValue<'tcx>,
|
||||
) {
|
||||
assert_eq!(
|
||||
a.layout().ty,
|
||||
fx.tcx.types.u64,
|
||||
"llvm.x86.addcarry.64/llvm.x86.subborrow.64 second operand must be u64"
|
||||
);
|
||||
assert_eq!(
|
||||
b.layout().ty,
|
||||
fx.tcx.types.u64,
|
||||
"llvm.x86.addcarry.64/llvm.x86.subborrow.64 third operand must be u64"
|
||||
);
|
||||
|
||||
// c + carry -> c + first intermediate carry or borrow respectively
|
||||
let int0 = crate::num::codegen_checked_int_binop(fx, bin_op, a, b);
|
||||
let c = int0.value_field(fx, mir::Field::new(0));
|
||||
let cb0 = int0.value_field(fx, mir::Field::new(1)).load_scalar(fx);
|
||||
|
||||
// c + carry -> c + second intermediate carry or borrow respectively
|
||||
let cb_in_as_u64 = fx.bcx.ins().uextend(types::I64, cb_in);
|
||||
let cb_in_as_u64 = CValue::by_val(cb_in_as_u64, fx.layout_of(fx.tcx.types.u64));
|
||||
let int1 = crate::num::codegen_checked_int_binop(fx, bin_op, c, cb_in_as_u64);
|
||||
let (c, cb1) = int1.load_scalar_pair(fx);
|
||||
|
||||
// carry0 | carry1 -> carry or borrow respectively
|
||||
let cb_out = fx.bcx.ins().bor(cb0, cb1);
|
||||
|
||||
let layout = fx.layout_of(fx.tcx.mk_tup([fx.tcx.types.u8, fx.tcx.types.u64].iter()));
|
||||
let val = CValue::by_val_pair(cb_out, c, layout);
|
||||
ret.write_cvalue(fx, val);
|
||||
}
|
||||
|
|
14
src/lib.rs
14
src/lib.rs
|
@ -1,4 +1,4 @@
|
|||
#![feature(rustc_private, decl_macro, never_type, hash_drain_filter, vec_into_raw_parts)]
|
||||
#![feature(rustc_private, decl_macro, never_type, hash_drain_filter, vec_into_raw_parts, once_cell)]
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![warn(unused_lifetimes)]
|
||||
#![warn(unreachable_pub)]
|
||||
|
@ -14,7 +14,9 @@ extern crate rustc_fs_util;
|
|||
extern crate rustc_hir;
|
||||
extern crate rustc_incremental;
|
||||
extern crate rustc_index;
|
||||
extern crate rustc_interface;
|
||||
extern crate rustc_metadata;
|
||||
extern crate rustc_mir;
|
||||
extern crate rustc_session;
|
||||
extern crate rustc_span;
|
||||
extern crate rustc_target;
|
||||
|
@ -284,10 +286,12 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Box<dyn isa::Tar
|
|||
}
|
||||
None => {
|
||||
let mut builder =
|
||||
cranelift_codegen::isa::lookup_variant(target_triple, variant).unwrap();
|
||||
// Don't use "haswell" as the default, as it implies `has_lzcnt`.
|
||||
// macOS CI is still at Ivy Bridge EP, so `lzcnt` is interpreted as `bsr`.
|
||||
builder.enable("nehalem").unwrap();
|
||||
cranelift_codegen::isa::lookup_variant(target_triple.clone(), variant).unwrap();
|
||||
if target_triple.architecture == target_lexicon::Architecture::X86_64 {
|
||||
// Don't use "haswell" as the default, as it implies `has_lzcnt`.
|
||||
// macOS CI is still at Ivy Bridge EP, so `lzcnt` is interpreted as `bsr`.
|
||||
builder.enable("nehalem").unwrap();
|
||||
}
|
||||
builder
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
//! Various optimizations specific to cg_clif
|
||||
|
||||
use cranelift_codegen::isa::TargetIsa;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
pub(crate) mod peephole;
|
||||
|
||||
pub(crate) fn optimize_function<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
isa: &dyn TargetIsa,
|
||||
instance: Instance<'tcx>,
|
||||
ctx: &mut Context,
|
||||
clif_comments: &mut crate::pretty_clif::CommentWriter,
|
||||
) {
|
||||
// FIXME classify optimizations over opt levels once we have more
|
||||
|
||||
crate::pretty_clif::write_clif_file(tcx, "preopt", None, instance, &ctx, &*clif_comments);
|
||||
crate::pretty_clif::write_clif_file(tcx, "preopt", isa, instance, &ctx, &*clif_comments);
|
||||
crate::base::verify_func(tcx, &*clif_comments, &ctx.func);
|
||||
}
|
||||
|
|
|
@ -233,7 +233,7 @@ pub(crate) fn write_ir_file(
|
|||
pub(crate) fn write_clif_file<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
postfix: &str,
|
||||
isa: Option<&dyn cranelift_codegen::isa::TargetIsa>,
|
||||
isa: &dyn cranelift_codegen::isa::TargetIsa,
|
||||
instance: Instance<'tcx>,
|
||||
context: &cranelift_codegen::Context,
|
||||
mut clif_comments: &CommentWriter,
|
||||
|
@ -242,22 +242,23 @@ pub(crate) fn write_clif_file<'tcx>(
|
|||
tcx,
|
||||
|| format!("{}.{}.clif", tcx.symbol_name(instance).name, postfix),
|
||||
|file| {
|
||||
let value_ranges = isa
|
||||
.map(|isa| context.build_value_labels_ranges(isa).expect("value location ranges"));
|
||||
|
||||
let mut clif = String::new();
|
||||
cranelift_codegen::write::decorate_function(
|
||||
&mut clif_comments,
|
||||
&mut clif,
|
||||
&context.func,
|
||||
&DisplayFunctionAnnotations { isa, value_ranges: value_ranges.as_ref() },
|
||||
&DisplayFunctionAnnotations { isa: Some(isa), value_ranges: None },
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
writeln!(file, "test compile")?;
|
||||
writeln!(file, "set is_pic")?;
|
||||
writeln!(file, "set enable_simd")?;
|
||||
writeln!(file, "target {} haswell", crate::target_triple(tcx.sess))?;
|
||||
for flag in isa.flags().iter() {
|
||||
writeln!(file, "set {}", flag)?;
|
||||
}
|
||||
write!(file, "target {}", isa.triple().architecture.to_string())?;
|
||||
for isa_flag in isa.isa_flags().iter() {
|
||||
write!(file, " {}", isa_flag)?;
|
||||
}
|
||||
writeln!(file, "\n")?;
|
||||
writeln!(file)?;
|
||||
file.write_all(clif.as_bytes())?;
|
||||
Ok(())
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
//! Codegen vtables and vtable accesses.
|
||||
//!
|
||||
//! See `rustc_codegen_ssa/src/meth.rs` for reference.
|
||||
// FIXME dedup this logic between miri, cg_llvm and cg_clif
|
||||
|
||||
use crate::constant::data_id_for_alloc_id;
|
||||
use crate::prelude::*;
|
||||
use super::constant::pointer_for_allocation;
|
||||
|
||||
fn vtable_memflags() -> MemFlags {
|
||||
let mut flags = MemFlags::trusted(); // A vtable access is always aligned and will never trap.
|
||||
|
@ -38,7 +37,7 @@ pub(crate) fn min_align_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -
|
|||
pointer_ty(fx.tcx),
|
||||
vtable_memflags(),
|
||||
vtable,
|
||||
(ty::COMMON_VTABLE_ENTRIES_SIZE * usize_size) as i32,
|
||||
(ty::COMMON_VTABLE_ENTRIES_ALIGN * usize_size) as i32,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -69,16 +68,12 @@ pub(crate) fn get_vtable<'tcx>(
|
|||
ty: Ty<'tcx>,
|
||||
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
|
||||
) -> Value {
|
||||
let vtable_ptr = if let Some(vtable_ptr) = fx.vtables.get(&(ty, trait_ref)) {
|
||||
*vtable_ptr
|
||||
} else {
|
||||
let vtable_alloc_id = fx.tcx.vtable_allocation(ty, trait_ref);
|
||||
let vtable_allocation = fx.tcx.global_alloc(vtable_alloc_id).unwrap_memory();
|
||||
let vtable_ptr = pointer_for_allocation(fx, vtable_allocation);
|
||||
|
||||
fx.vtables.insert((ty, trait_ref), vtable_ptr);
|
||||
vtable_ptr
|
||||
};
|
||||
|
||||
vtable_ptr.get_addr(fx)
|
||||
let alloc_id = fx.tcx.vtable_allocation(ty, trait_ref);
|
||||
let data_id =
|
||||
data_id_for_alloc_id(&mut fx.constants_cx, &mut *fx.module, alloc_id, Mutability::Not);
|
||||
let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
|
||||
if fx.clif_comments.enabled() {
|
||||
fx.add_comment(local_data_id, format!("vtable: {:?}", alloc_id));
|
||||
}
|
||||
fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
|
||||
}
|
||||
|
|
4
test.sh
4
test.sh
|
@ -1,13 +1,13 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
./build.sh --sysroot none "$@"
|
||||
./y.rs build --sysroot none "$@"
|
||||
|
||||
rm -r target/out || true
|
||||
|
||||
scripts/tests.sh no_sysroot
|
||||
|
||||
./build.sh "$@"
|
||||
./y.rs build "$@"
|
||||
|
||||
scripts/tests.sh base_sysroot
|
||||
scripts/tests.sh extended_sysroot
|
||||
|
|
153
y.rs
Executable file
153
y.rs
Executable file
|
@ -0,0 +1,153 @@
|
|||
#!/usr/bin/env bash
|
||||
#![allow()] /*This line is ignored by bash
|
||||
# This block is ignored by rustc
|
||||
set -e
|
||||
echo "[BUILD] y.rs" 1>&2
|
||||
rustc $0 -o ${0/.rs/.bin} -g
|
||||
exec ${0/.rs/.bin} $@
|
||||
*/
|
||||
|
||||
//! The build system for cg_clif
|
||||
//!
|
||||
//! # Manual compilation
|
||||
//!
|
||||
//! If your system doesn't support shell scripts you can manually compile and run this file using
|
||||
//! for example:
|
||||
//!
|
||||
//! ```shell
|
||||
//! $ rustc y.rs -o build/y.bin
|
||||
//! $ build/y.bin
|
||||
//! ```
|
||||
//!
|
||||
//! # Naming
|
||||
//!
|
||||
//! The name `y.rs` was chosen to not conflict with rustc's `x.py`.
|
||||
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::process;
|
||||
|
||||
#[path = "build_system/build_backend.rs"]
|
||||
mod build_backend;
|
||||
#[path = "build_system/build_sysroot.rs"]
|
||||
mod build_sysroot;
|
||||
#[path = "build_system/config.rs"]
|
||||
mod config;
|
||||
#[path = "build_system/prepare.rs"]
|
||||
mod prepare;
|
||||
#[path = "build_system/rustc_info.rs"]
|
||||
mod rustc_info;
|
||||
#[path = "build_system/utils.rs"]
|
||||
mod utils;
|
||||
|
||||
fn usage() {
|
||||
eprintln!("Usage:");
|
||||
eprintln!(" ./y.rs prepare");
|
||||
eprintln!(" ./y.rs build [--debug] [--sysroot none|clif|llvm] [--target-dir DIR]");
|
||||
}
|
||||
|
||||
macro_rules! arg_error {
|
||||
($($err:tt)*) => {{
|
||||
eprintln!($($err)*);
|
||||
usage();
|
||||
std::process::exit(1);
|
||||
}};
|
||||
}
|
||||
|
||||
enum Command {
|
||||
Build,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum SysrootKind {
|
||||
None,
|
||||
Clif,
|
||||
Llvm,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
env::set_var("CG_CLIF_DISPLAY_CG_TIME", "1");
|
||||
env::set_var("CG_CLIF_DISABLE_INCR_CACHE", "1");
|
||||
// The target dir is expected in the default location. Guard against the user changing it.
|
||||
env::set_var("CARGO_TARGET_DIR", "target");
|
||||
|
||||
let mut args = env::args().skip(1);
|
||||
let command = match args.next().as_deref() {
|
||||
Some("prepare") => {
|
||||
if args.next().is_some() {
|
||||
arg_error!("./x.rs prepare doesn't expect arguments");
|
||||
}
|
||||
prepare::prepare();
|
||||
process::exit(0);
|
||||
}
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
let mut target_dir = PathBuf::from("build");
|
||||
let mut channel = "release";
|
||||
let mut sysroot_kind = SysrootKind::Clif;
|
||||
while let Some(arg) = args.next().as_deref() {
|
||||
match arg {
|
||||
"--target-dir" => {
|
||||
target_dir = PathBuf::from(args.next().unwrap_or_else(|| {
|
||||
arg_error!("--target-dir requires argument");
|
||||
}))
|
||||
}
|
||||
"--debug" => channel = "debug",
|
||||
"--sysroot" => {
|
||||
sysroot_kind = match args.next().as_deref() {
|
||||
Some("none") => SysrootKind::None,
|
||||
Some("clif") => SysrootKind::Clif,
|
||||
Some("llvm") => SysrootKind::Llvm,
|
||||
Some(arg) => arg_error!("Unknown sysroot kind {}", arg),
|
||||
None => arg_error!("--sysroot requires argument"),
|
||||
}
|
||||
}
|
||||
flag if flag.starts_with("-") => arg_error!("Unknown flag {}", flag),
|
||||
arg => arg_error!("Unexpected argument {}", arg),
|
||||
}
|
||||
}
|
||||
|
||||
let host_triple = if let Ok(host_triple) = std::env::var("HOST_TRIPLE") {
|
||||
host_triple
|
||||
} else if let Some(host_triple) = crate::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) = crate::config::get_value("target") {
|
||||
target_triple
|
||||
} else {
|
||||
host_triple.clone()
|
||||
};
|
||||
|
||||
if target_triple.ends_with("-msvc") {
|
||||
eprintln!("The MSVC toolchain is not yet supported by rustc_codegen_cranelift.");
|
||||
eprintln!("Switch to the MinGW toolchain for Windows support.");
|
||||
eprintln!("Hint: You can use `rustup set default-host x86_64-pc-windows-gnu` to");
|
||||
eprintln!("set the global default target to MinGW");
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
let cg_clif_build_dir = build_backend::build_backend(channel, &host_triple);
|
||||
build_sysroot::build_sysroot(
|
||||
channel,
|
||||
sysroot_kind,
|
||||
&target_dir,
|
||||
cg_clif_build_dir,
|
||||
&host_triple,
|
||||
&target_triple,
|
||||
);
|
||||
}
|
Loading…
Add table
Reference in a new issue