Skip to content

Commit a61568c

Browse files
committed
Initial support for rustc_codegen_gcc
rustc can use different backend and this new script builds all the needed parts to have GCC as the code generator. It needs (at the moment) a patched version of GCC and builds it with libjit support. Some glue code (in Rust) is added in the mix to finally be able to use the rustc compiler with this dynamic backend. Fixes compiler-explorer/compiler-explorer#2683
1 parent b30c481 commit a61568c

File tree

2 files changed

+191
-0
lines changed

2 files changed

+191
-0
lines changed

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ RUN apt update -y -q && apt upgrade -y -q && apt update -y -q && \
1111
gcc \
1212
gcc-multilib \
1313
git \
14+
flex \
1415
libc6-dev-i386 \
1516
libc6-dev:i386 \
1617
linux-libc-dev \

build/build-rustc-cg-gcc.sh

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
#!/bin/bash
2+
3+
## $1 : version, currently rustc_cg_gcc does not have any and only uses master branch.
4+
## $2 : destination: a directory or S3 path (eg. s3://...)
5+
6+
set -ex
7+
8+
ROOT=$PWD
9+
VERSION=$1
10+
11+
if [[ "${VERSION}" != "master" ]]; then
12+
echo "Only support building master"
13+
exit 1
14+
fi
15+
16+
FULLNAME=rustc-cg-gcc-${VERSION}-$(date +%Y%m%d)
17+
18+
OUTPUT=${ROOT}/${FULLNAME}.tar.xz
19+
S3OUTPUT=
20+
if [[ $2 =~ ^s3:// ]]; then
21+
S3OUTPUT=$2
22+
else
23+
if [[ -d "${2}" ]]; then
24+
OUTPUT=$2/${FULLNAME}.tar.xz
25+
else
26+
OUTPUT=${2-$OUTPUT}
27+
fi
28+
fi
29+
30+
## From now, no unset variable
31+
set -u
32+
33+
OUTPUT=$(realpath "${OUTPUT}")
34+
35+
rm -rf build-rustc-cg-gcc
36+
mkdir -p build-rustc-cg-gcc
37+
38+
pushd build-rustc-cg-gcc
39+
PREFIX=$(pwd)/gcc-install
40+
41+
export CARGO_HOME=$PWD/rustup
42+
export RUSTUP_HOME=$PWD/rustup
43+
44+
export PATH=$RUSTUP_HOME/bin:$PATH
45+
46+
## Download rustc_cg_gcc
47+
git clone --depth 1 https://github.com/antoyo/rustc_codegen_gcc.git
48+
49+
## Download rustup and install it in a local dir
50+
## Installs :
51+
## - minimal profile
52+
## - the required build-deps from RUSTUP_COMP_BUILD_DEPS (-c *)
53+
## - version taken from rust-toolchain file
54+
55+
RUSTUP_COMP_BUILD_DEPS=(rust-src rustc-dev llvm-tools-preview)
56+
57+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --profile minimal \
58+
-c "$(printf '%s\n' "$(IFS=,; printf '%s' "${RUSTUP_COMP_BUILD_DEPS[*]}")")" \
59+
--no-modify-path \
60+
-y \
61+
--default-toolchain "$(cat rustc_codegen_gcc/rust-toolchain)"
62+
63+
source "$PWD/rustup/env"
64+
65+
##
66+
## Prepare rustc_cg_gcc
67+
##
68+
pushd rustc_codegen_gcc
69+
70+
# where the libgccjit.so will be installed
71+
echo "$PREFIX/lib" > gcc_path
72+
73+
./build_sysroot/prepare_sysroot_src.sh
74+
popd
75+
76+
##
77+
## Build customized GCC with libgccjit
78+
##
79+
80+
git clone --depth 1 https://github.com/antoyo/gcc.git
81+
82+
GCC_REVISION=$(cd gcc; git ls-remote --heads "${URL}" "refs/heads/${BRANCH}" | cut -f 1)
83+
84+
# clean
85+
rm -rf gcc-build gcc-install
86+
mkdir -p gcc-build gcc-install
87+
88+
echo "Downloading prerequisites"
89+
pushd gcc
90+
./contrib/download_prerequisites
91+
popd
92+
93+
pushd gcc-build
94+
LANGUAGES=jit,c++
95+
PKGVERSION="Compiler-Explorer-Build-libgccjit-${GCC_REVISION}"
96+
97+
CONFIG+=" --enable-checking=release"
98+
CONFIG+=" --enable-host-shared"
99+
CONFIG+=" --build=x86_64-linux-gnu"
100+
CONFIG+=" --host=x86_64-linux-gnu"
101+
CONFIG+=" --target=x86_64-linux-gnu"
102+
CONFIG+=" --disable-bootstrap"
103+
CONFIG+=" --enable-multiarch"
104+
CONFIG+=" --with-abi=m64"
105+
CONFIG+=" --with-multilib-list=m32,m64,mx32"
106+
CONFIG+=" --enable-multilib"
107+
CONFIG+=" --enable-clocale=gnu"
108+
CONFIG+=" --enable-languages=${LANGUAGES}"
109+
CONFIG+=" --enable-ld=yes"
110+
CONFIG+=" --enable-gold=yes"
111+
CONFIG+=" --enable-libstdcxx-debug"
112+
CONFIG+=" --enable-libstdcxx-time=yes"
113+
CONFIG+=" --enable-linker-build-id"
114+
CONFIG+=" --enable-lto"
115+
CONFIG+=" --enable-plugins"
116+
CONFIG+=" --enable-threads=posix"
117+
CONFIG+=" --with-pkgversion=\"${PKGVERSION}\""
118+
119+
## this is needed for all libs (gmp, mpfr, …) to be PIC so as to not cause issue
120+
## when they are statically linked in the libgccjit.so
121+
CONFIG+=" --with-pic"
122+
123+
../gcc/configure --prefix="${PREFIX}" ${CONFIG}
124+
125+
make -j"$(nproc)"
126+
make -j"$(nproc)" install-strip
127+
popd
128+
129+
##
130+
## Back to rustc_cg_gcc for building
131+
##
132+
pushd rustc_codegen_gcc
133+
./build.sh --release
134+
popd
135+
136+
##
137+
## Everything should be correctly build
138+
##
139+
140+
##
141+
## Before packaging, remove build deps
142+
##
143+
144+
for c in "${RUSTUP_COMP_BUILD_DEPS[@]}"
145+
do
146+
rustup component remove "$c"
147+
done
148+
149+
##
150+
## Package everything together:
151+
## - the rustc toolchain from rustup
152+
## - libgccjit
153+
## - librustc_codegen_gcc
154+
## - sysroot
155+
156+
mkdir -p toolroot
157+
158+
# rustc toolchain
159+
mv rustup/toolchains/*/* toolroot/
160+
161+
# libgccjit
162+
mv ./gcc-install/lib/libgccjit.so* toolroot/lib
163+
164+
# cg_gcc backend
165+
mv ./rustc_codegen_gcc/target/release/librustc_codegen_gcc.so toolroot/lib
166+
167+
# sysroot
168+
mv ./rustc_codegen_gcc/build_sysroot/sysroot toolroot/
169+
170+
##
171+
## Simple sanity checks:
172+
## - check for assembly output
173+
## - check for correct exec output
174+
175+
echo "fn main() -> Result<(), &'static str> { Ok(()) }" > /tmp/test.rs
176+
./toolroot/bin/rustc -Cpanic=abort -Zcodegen-backend=librustc_codegen_gcc.so --sysroot toolroot/sysroot --emit asm -o test.s /tmp/test.rs
177+
test test.s
178+
179+
./toolroot/bin/rustc -Cpanic=abort -Zcodegen-backend=librustc_codegen_gcc.so --sysroot toolroot/sysroot /tmp/test.rs
180+
./test
181+
182+
# Don't try to compress the binaries as they don't like it
183+
pushd toolroot
184+
185+
export XZ_DEFAULTS="-T 0"
186+
tar Jcf "${OUTPUT}" --transform "s,^./,./${FULLNAME}/," ./
187+
188+
if [[ -n "${S3OUTPUT}" ]]; then
189+
s3cmd put --rr "${OUTPUT}" "${S3OUTPUT}"
190+
fi

0 commit comments

Comments
 (0)