From 4632b216d06c29c5f4a83a94c9bc13309208c0bf Mon Sep 17 00:00:00 2001 From: Ashay Rane <253344819+raneashay@users.noreply.github.com> Date: Tue, 23 Jun 2026 04:25:41 -0500 Subject: [PATCH] Add sccache support to Linux, Windows, and macOS builds This patch enables the `--enable-sccache` flag to enable build caching using sccache. Specifically, if the toolchain is one among gcc, clang, or MSVC and if the sccache version is 0.10 and above, then the build prefixes all compiler invocations with the path to the sccache binary. Since sccache is incompatible with ccache and precompiled headers, this patch makes the build fail if either ccache or precompiled headers are enabled in addition to sccache at the same time. Validated this patch on {Linux, Windows, macOS} x {x64, aarch64} machines. In the best-case scenario (i.e. when there are no changes to the source files), the time required to run the "make images" step is roughly cut in half. Side note: the individual machines have very different configurations, so build times _across_ machines aren't comparable. - Windows/x64: 2,107s -> 848s - Windows/ARM64: 1,264s -> 748s - macOS/x64: 808s -> 243s - macOS/AArch64: 480s -> 142s - Linux/x64: 225s -> 111s - Linux/AArch64: 364s -> 246s --- doc/building.html | 9 +++ doc/building.md | 9 +++ make/autoconf/build-performance.m4 | 103 ++++++++++++++++++++++++++++- make/autoconf/configure.ac | 3 + make/autoconf/help.m4 | 3 + make/autoconf/spec.gmk.template | 5 +- 6 files changed, 129 insertions(+), 3 deletions(-) diff --git a/doc/building.html b/doc/building.html index be3c8c364d7b6..ed77db508346c 100644 --- a/doc/building.html +++ b/doc/building.html @@ -146,6 +146,7 @@

Building the JDK

  • Virus Checking
  • Ccache
  • +
  • Sccache
  • Precompiled Headers
  • Icecc / @@ -1814,6 +1815,14 @@

    Ccache

    often rebuild the same sources. Your mileage may vary however, so we recommend evaluating it for yourself. To enable it, make sure it's on the path and configure with --enable-ccache.

    +

    Sccache

    +

    The JDK build supports building with sccache when using gcc, clang, or +Microsoft toolchains. To enable it, make sure the sccache binary is on the path +(or specify the path to the binary using the SCCACHE argument to +the configure script) and configure with --enable-sccache. To +optionally specify where sccache stores its cache files, use +--with-sccache-dir. Precompiled headers are disabled when sccache +is enabled.

    Precompiled Headers

    By default, the Hotspot build uses pre-compiled headers (PCH) on the toolchains were it is properly supported (clang, gcc, and Visual diff --git a/doc/building.md b/doc/building.md index adf116764fa0c..7e9211d8f66df 100644 --- a/doc/building.md +++ b/doc/building.md @@ -1555,6 +1555,15 @@ the same sources. Your mileage may vary however, so we recommend evaluating it for yourself. To enable it, make sure it's on the path and configure with `--enable-ccache`. +### Sccache + +The JDK build supports building with sccache when using gcc, clang, or Microsoft +toolchains. To enable it, make sure the sccache binary is on the path (or +specify the path to the binary using the `SCCACHE` argument to the configure +script) and configure with `--enable-sccache`. To optionally specify where +sccache stores its cache files, use `--with-sccache-dir`. Precompiled headers +are disabled when sccache is enabled. + ### Precompiled Headers By default, the Hotspot build uses pre-compiled headers (PCH) on the toolchains diff --git a/make/autoconf/build-performance.m4 b/make/autoconf/build-performance.m4 index dfc9e979d2fd5..76332e0b7f8b4 100644 --- a/make/autoconf/build-performance.m4 +++ b/make/autoconf/build-performance.m4 @@ -252,6 +252,101 @@ AC_DEFUN([BPERF_SETUP_CCACHE_USAGE], fi ]) +AC_DEFUN([BPERF_SETUP_SCCACHE], +[ + # Check if sccache is available + SCCACHE_AVAILABLE=true + + UTIL_LOOKUP_TOOLCHAIN_PROGS(SCCACHE, sccache) + + AC_MSG_CHECKING([if sccache is available]) + if test "x$TOOLCHAIN_TYPE" != "xgcc" && test "x$TOOLCHAIN_TYPE" != "xclang" && \ + test "x$TOOLCHAIN_TYPE" != "xmicrosoft"; then + AC_MSG_RESULT([no, not supported for toolchain type $TOOLCHAIN_TYPE]) + SCCACHE_AVAILABLE=false + elif test "x$SCCACHE" = "x"; then + AC_MSG_RESULT([no, sccache binary missing or not executable]) + SCCACHE_AVAILABLE=false + else + AC_MSG_RESULT([yes]) + fi + + SCCACHE_STATUS="" + UTIL_ARG_ENABLE(NAME: sccache, DEFAULT: false, AVAILABLE: $SCCACHE_AVAILABLE, + DESC: [enable using sccache to speed up recompilations], + CHECKING_MSG: [if sccache is enabled], + IF_ENABLED: [ + if test "x$CCACHE" != x; then + AC_MSG_ERROR([Cannot enable both ccache and sccache]) + fi + # Versions of sccache before 0.10.0 can restore stale or incorrect + # dependency files for cached C/C++ compilations, breaking our build. + SCCACHE_VERSION=[`$SCCACHE --version | head -n1 | $CUT -d " " -f 2 | $TR -d '\r'`] + HAS_BAD_SCCACHE=[`$ECHO $SCCACHE_VERSION | \ + $GREP -e '^0\.[0-9]\.' -e '^0\.[0-9]$'`] + if test "x$HAS_BAD_SCCACHE" != "x"; then + AC_MSG_ERROR([sccache 0.10.0 or later is required, found $SCCACHE_VERSION]) + fi + SCCACHE_STATUS="Active ($SCCACHE_VERSION)" + ], + IF_DISABLED: [ + SCCACHE="" + ]) + AC_SUBST(SCCACHE) + + AC_ARG_WITH([sccache-dir], + [AS_HELP_STRING([--with-sccache-dir], + [where to store sccache files @<:@~/.cache/sccache@:>@])]) + + if test "x$with_sccache_dir" != x; then + SCCACHE_DIR="$with_sccache_dir" + SCCACHE_DIR_FOR_SCCACHE="$SCCACHE_DIR" + if test "x$OPENJDK_BUILD_OS" = "xwindows"; then + SCCACHE_DIR_FOR_SCCACHE=`$FIXPATH_BASE -m print "$SCCACHE_DIR_FOR_SCCACHE"` + fi + SET_SCCACHE_DIR="SCCACHE_DIR=$SCCACHE_DIR_FOR_SCCACHE" + if test "x$SCCACHE" = x; then + AC_MSG_WARN([--with-sccache-dir has no meaning when sccache is not enabled]) + fi + fi + + if test "x$SCCACHE" != x; then + BPERF_SETUP_SCCACHE_USAGE + fi +]) + +AC_DEFUN([BPERF_SETUP_SCCACHE_USAGE], +[ + if test "x$SCCACHE" != x; then + if test "x$USE_PRECOMPILED_HEADER" = "xtrue"; then + if test "x$PRECOMPILED_HEADERS_EXPLICITLY_SET" = "xtrue"; then + AC_MSG_ERROR([Cannot use sccache with precompiled headers. Use --disable-precompiled-headers.]) + else + AC_MSG_NOTICE([Disabling precompiled headers because sccache is enabled]) + USE_PRECOMPILED_HEADER=false + fi + fi + + # On Windows, the sccache binary must be launched through fixpath and the + # compiler argument passed to sccache must be the actual compiler + # (gcc/clang/cl) and not another fixpath invocation, otherwise sccache will + # try to execute fixpath as the compiler. + [ if [[ "$OPENJDK_BUILD_OS" = "windows" && "$SCCACHE" =~ ^"$FIXPATH " ]]; then ] + [ if [[ "$CC" =~ ^"$FIXPATH " ]]; then ] + CC="${CC#"$FIXPATH "}" + [ fi ] + [ if [[ "$CXX" =~ ^"$FIXPATH " ]]; then ] + CXX="${CXX#"$FIXPATH "}" + [ fi ] + [ fi ] + + if test "x$SET_SCCACHE_DIR" != x; then + SCCACHE="$SET_SCCACHE_DIR $SCCACHE" + mkdir -p "$SCCACHE_DIR" > /dev/null 2>&1 + fi + fi +]) + ################################################################################ # # Runs icecc-create-env once and prints the error if it fails @@ -372,7 +467,13 @@ AC_DEFUN_ONCE([BPERF_SETUP_PRECOMPILED_HEADERS], UTIL_ARG_ENABLE(NAME: precompiled-headers, DEFAULT: auto, RESULT: USE_PRECOMPILED_HEADER, AVAILABLE: $PRECOMPILED_HEADERS_AVAILABLE, - DESC: [enable using precompiled headers when compiling C++]) + DESC: [enable using precompiled headers when compiling C++], + IF_GIVEN: [ + PRECOMPILED_HEADERS_EXPLICITLY_SET=true + ], + IF_NOT_GIVEN: [ + PRECOMPILED_HEADERS_EXPLICITLY_SET=false + ]) AC_SUBST(USE_PRECOMPILED_HEADER) ]) diff --git a/make/autoconf/configure.ac b/make/autoconf/configure.ac index 6d65ad93c4087..ae1e8f3c5ef7d 100644 --- a/make/autoconf/configure.ac +++ b/make/autoconf/configure.ac @@ -291,6 +291,9 @@ BPERF_SETUP_PRECOMPILED_HEADERS # Setup use of ccache, if available BPERF_SETUP_CCACHE +# Setup use of sccache, if available +BPERF_SETUP_SCCACHE + ################################################################################ # # And now the finish... diff --git a/make/autoconf/help.m4 b/make/autoconf/help.m4 index d8c0b2ffaeffb..23541cea3efab 100644 --- a/make/autoconf/help.m4 +++ b/make/autoconf/help.m4 @@ -335,6 +335,9 @@ AC_DEFUN_ONCE([HELP_PRINT_SUMMARY_AND_WARNINGS], if test "x$CCACHE_STATUS" != "x"; then $ECHO "* ccache status: $CCACHE_STATUS" fi + if test "x$SCCACHE_STATUS" != "x"; then + $ECHO "* sccache status: $SCCACHE_STATUS" + fi $ECHO "" if test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = "xtrue"; then diff --git a/make/autoconf/spec.gmk.template b/make/autoconf/spec.gmk.template index ecfd5dd0a922e..4e56a3f620758 100644 --- a/make/autoconf/spec.gmk.template +++ b/make/autoconf/spec.gmk.template @@ -541,7 +541,7 @@ ADLC_LANGSTD_CXXFLAGS := @ADLC_LANGSTD_CXXFLAGS@ ADLC_LDFLAGS := @ADLC_LDFLAGS@ # Tools that potentially need to be cross compilation aware. -CC := @CCACHE@ @ICECC@ @CC@ +CC := @SCCACHE@ @CCACHE@ @ICECC@ @CC@ # CFLAGS used to compile the jdk native libraries (C-code) CFLAGS_JDKLIB := @CFLAGS_JDKLIB@ @@ -567,7 +567,7 @@ EXTRA_CXXFLAGS := @EXTRA_CXXFLAGS@ EXTRA_LDFLAGS := @EXTRA_LDFLAGS@ EXTRA_ASFLAGS := @EXTRA_ASFLAGS@ -CXX := @CCACHE@ @ICECC@ @CXX@ +CXX := @SCCACHE@ @CCACHE@ @ICECC@ @CXX@ CPP := @CPP@ @@ -736,6 +736,7 @@ RCFLAGS := @RCFLAGS@ AWK := @AWK@ BASENAME := @BASENAME@ CAT := @CAT@ +SCCACHE := @SCCACHE@ CCACHE := @CCACHE@ # CD is going away, but remains to cater for legacy makefiles. CD := cd