From 5719a536e88c75166c8707f176b427d587d486db Mon Sep 17 00:00:00 2001 From: "Darryl L. Miles" Date: Thu, 23 Jul 2026 14:21:47 +0000 Subject: [PATCH] build: autodetect ccache (configure --disable-ccache to opt out) When ccache is on PATH, prefix CC/CXX with it so every compile goes through ccache -- no Makefile change, since rules.mak already runs `${CC} ... -c` and defs.mak substitutes @CC@/@CXX@. Autodetected on by default; --disable-ccache opts out. Placed after the AC_PROG_C* checks so configure's own feature tests use the plain compiler and only the build picks up the prefix. Pairs with the build-info isolation (utils/buildinfo.c): with the volatile MAGIC_BUILDDATE on only that one unit, a full rebuild hits the cache for every other unit. Measured (default Tcl build, all objects deleted then rebuilt): 323/324 hits with the date enabled (only buildinfo.o misses), 324/324 with --disable-magic-builddate. Verified: default configure -> CC="ccache gcc", CXX="ccache g++"; --disable-ccache -> CC="gcc". Co-Authored-By: Claude Opus 4.8 (1M context) --- scripts/configure | 56 ++++++++++++++++++++++++++++++++++++++++++++ scripts/configure.in | 20 ++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/scripts/configure b/scripts/configure index 45d54f02..80019f26 100755 --- a/scripts/configure +++ b/scripts/configure @@ -691,6 +691,7 @@ ALLOCA EGREP GREP PERL +CCACHE SED RANLIB INSTALL_DATA @@ -760,6 +761,7 @@ SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking +enable_ccache with_gnu_ld enable_assertions enable_debug @@ -1425,6 +1427,7 @@ Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-ccache do not use ccache even if it is installed --enable-assertions build with fatal assertions enabled --enable-debug build with fatal debug enabled --disable-compression disable file compression @@ -4233,6 +4236,59 @@ $as_echo "$ac_cv_path_SED" >&6; } rm -f conftest.sed +# Check whether --enable-ccache was given. +if test "${enable_ccache+set}" = set; then : + enableval=$enable_ccache; +else + enable_ccache=yes +fi + +if test "x$enable_ccache" = "xyes"; then + # Extract the first word of "ccache", so it can be a program name with args. +set dummy ccache; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CCACHE+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CCACHE"; then + ac_cv_prog_CCACHE="$CCACHE" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CCACHE="ccache" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CCACHE=$ac_cv_prog_CCACHE +if test -n "$CCACHE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CCACHE" >&5 +$as_echo "$CCACHE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "x$CCACHE" != "x"; then + CC="$CCACHE $CC" + test "x$CXX" != "x" && CXX="$CCACHE $CXX" + { $as_echo "$as_me:${as_lineno-$LINENO}: using ccache: CC=\"$CC\"" >&5 +$as_echo "$as_me: using ccache: CC=\"$CC\"" >&6;} + fi +fi + # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 diff --git a/scripts/configure.in b/scripts/configure.in index 7db34e18..ec655c83 100644 --- a/scripts/configure.in +++ b/scripts/configure.in @@ -29,6 +29,26 @@ AC_PROG_INSTALL AC_PROG_RANLIB AC_PROG_SED +dnl Prefix the compilers with ccache when it is installed (autodetected; opt out +dnl with --disable-ccache). Done after the AC_PROG_C* checks above so those +dnl feature tests run with the plain compiler; only the substituted @CC@/@CXX@ +dnl used by the build pick up the prefix, and rules.mak's `${CC} ... -c` recipe +dnl then goes through ccache with no Makefile change. This pairs with the +dnl build-info isolation (utils/buildinfo.c): the volatile MAGIC_BUILDDATE lives +dnl only on that one unit's command line, so a rebuild hits the cache for every +dnl other unit instead of missing all of them. +AC_ARG_ENABLE(ccache, +[ --disable-ccache do not use ccache even if it is installed], +[], [enable_ccache=yes]) +if test "x$enable_ccache" = "xyes"; then + AC_CHECK_PROG(CCACHE, ccache, ccache) + if test "x$CCACHE" != "x"; then + CC="$CCACHE $CC" + test "x$CXX" != "x" && CXX="$CCACHE $CXX" + AC_MSG_NOTICE([using ccache: CC="$CC"]) + fi +fi + AC_PATH_PROG(PERL, perl, no) AC_SUBST(PERL)