Skip to content

Commit d323fc7

Browse files
committed
unix: use sccache more during gcc build
I discovered this optimization as part of extracting the toolchain bootstrap logic to a separate, not-yet-published project. Let's "backport" it to python-build-standalone to hopefully realize a build speedup. In order to make this work, we had to move `sccache` to PATH. Well, we strictly didn't need to. But I think that makes more sense.
1 parent bbca779 commit d323fc7

File tree

3 files changed

+47
-7
lines changed

3 files changed

+47
-7
lines changed

cpython-unix/build-gcc.sh

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,17 @@ set -ex
77

88
cd /build
99

10-
ROOT=$(pwd)
11-
SCCACHE="${ROOT}/sccache"
12-
1310
tar -C /tools -xf /build/binutils-${BINUTILS_VERSION}-linux64.tar
1411
export PATH=/tools/host/bin:$PATH
1512

13+
HAVE_SCCACHE=
14+
15+
if [ -x sccache ]; then
16+
HAVE_SCCACHE=1
17+
mv sccache /tools/host/bin/
18+
cp sccache-wrapper.sh /tools/host/bin/
19+
fi
20+
1621
tar -xf gcc-${GCC_VERSION}.tar.xz
1722
tar -xf gmp-${GMP_VERSION}.tar.xz
1823
tar -xf isl-${ISL_VERSION}.tar.bz2
@@ -26,10 +31,11 @@ ln -sf ../mpc-${MPC_VERSION} mpc
2631
ln -sf ../mpfr-${MPFR_VERSION} mpfr
2732
popd
2833

29-
if [ -x "${SCCACHE}" ]; then
30-
"${SCCACHE}" --start-server
31-
export CC="${SCCACHE} /usr/bin/gcc"
32-
export CXX="${SCCACHE} /usr/bin/g++"
34+
if [ -n "${HAVE_SCCACHE}" ]; then
35+
sccache --start-server
36+
export CC="sccache /usr/bin/gcc"
37+
export CXX="sccache /usr/bin/g++"
38+
export STAGE_CC_WRAPPER=sccache-wrapper.sh
3339
fi
3440

3541
mkdir gcc-objdir
@@ -51,3 +57,5 @@ pushd gcc-objdir
5157
make -j `nproc`
5258
make -j `nproc` install DESTDIR=/build/out
5359
popd
60+
61+
sccache -s

cpython-unix/build.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ def build_gcc(client, image, host_platform):
294294
build_env.copy_file(a)
295295

296296
build_env.copy_file(toolchain_archive_path("binutils", host_platform))
297+
build_env.copy_file(SUPPORT / "sccache-wrapper.sh")
297298
build_env.copy_file(SUPPORT / "build-gcc.sh")
298299

299300
env = {

cpython-unix/sccache-wrapper.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env bash
2+
# This script is needed to handle a race in GCC's build system and a bug in
3+
# sccache.
4+
#
5+
# GCC's build system could materialize `xgcc` and invoke commands like
6+
# `xgcc -dumpspecs` before make materializes `cc1`. This is relevant because
7+
# sccache invokes `<compiler> -E` on the first invocation of a compiler to
8+
# determine which flavor of compiler to treat it as. And `gcc -E` requires
9+
# support binaries like `cc1` in order to work. Our wrapper script sniffs
10+
# for existence of `cc1` to mitigate this race condiion.
11+
#
12+
# Furthermore, sccache doesn't honor `-B` arguments when running
13+
# `<compiler> -E`. So even if a support binary like `cc1` may exist, GCC may
14+
# not know where to find it. Our wrapper script works around this by ensuring
15+
# the compiler's directory is always on PATH.
16+
#
17+
# This script/approach is arguably not sound for use outside of the value of
18+
# STAGE_CC_WRAPPER in GCC's build system. You have been warned.
19+
20+
set -o errexit
21+
set -o pipefail
22+
23+
dir=$(dirname $1)
24+
cc1=${dir}/cc1
25+
26+
if [ -e "${cc1}" ]; then
27+
export PATH=${dir}:${PATH}
28+
exec sccache "$@"
29+
else
30+
exec "$@"
31+
fi

0 commit comments

Comments
 (0)