Currently, headerscheck and cpluspluscheck are very slow, and they defeat use of ccache. I have fixed that, and now they are much faster. :-)

The problem was (I think) that the test files are created in a randomly-named directory (`mktemp -d /tmp/$me.XXXXXX`), and this directory is named on the compiler command line, which is part of the cache key.

My solution is to create the test files in the build directory. For example, for src/include/storage/ipc.h I generate

headerscheck_src_include_storage_ipc_h.c (or .cpp)

Now ccache works. (And it's also a bit easier to debug everything with this naming.)

The observed speedup on Cirrus CI for headerscheck plus cpluspluscheck is from about 1min 20s to only 20s. In local use, the speedups are similar.

(I noticed that on Cirrus CI, the first uncached run with this patch was quite a bit slower. I don't know if this was because of the additional cache population that was happening, or if it was a fluke. Maybe others can try it in their environments. Maybe it's not a problem in the long run.)
From fe0517de0ef9017293bf2cbc2ca735e7b8949ced Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Fri, 21 Nov 2025 10:53:53 +0100
Subject: [PATCH] headerscheck ccache support

---
 .cirrus.tasks.yml                |  5 ++---
 src/tools/pginclude/headerscheck | 11 ++++-------
 2 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/.cirrus.tasks.yml b/.cirrus.tasks.yml
index 2fe9671f3dc..038d043d00e 100644
--- a/.cirrus.tasks.yml
+++ b/.cirrus.tasks.yml
@@ -1005,16 +1005,15 @@ task:
   ###
   # Verify headerscheck / cpluspluscheck succeed
   #
-  # - Don't use ccache, the files are uncacheable, polluting ccache's
-  #   cache
   # - Use -fmax-errors, as particularly cpluspluscheck can be very verbose
   ###
   always:
     headers_headerscheck_script: |
       time ./configure \
         ${LINUX_CONFIGURE_FEATURES} \
+        --cache gcc.cache \
         --quiet \
-        CC="gcc" CXX"=g++" CLANG="clang"
+        CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
       make -s -j${BUILD_JOBS} clean
       time make -s headerscheck EXTRAFLAGS='-fmax-errors=10'
     headers_cpluspluscheck_script: |
diff --git a/src/tools/pginclude/headerscheck b/src/tools/pginclude/headerscheck
index a52a5580bdc..c77c4eec2f6 100755
--- a/src/tools/pginclude/headerscheck
+++ b/src/tools/pginclude/headerscheck
@@ -72,11 +72,6 @@ else
        COMPILER_FLAGS="$CPPFLAGS $CFLAGS $ICU_CFLAGS"
 fi
 
-# Create temp directory.
-tmp=`mktemp -d /tmp/$me.XXXXXX`
-
-trap "ret=$?; rm -rf $tmp; exit $ret" 0 1 2 3 15
-
 exit_status=0
 
 # Scan all of src/ and contrib/ for header files.
@@ -200,6 +195,7 @@ do
        fi
 
        # OK, create .c file to include this .h file.
+       test_file_name=${me}_$(printf '%s' "$f" | sed 's![/.]!_!g')
        {
            $cplusplus && echo 'extern "C" {'
            # Ideally we'd pre-include only the appropriate one of
@@ -231,7 +227,7 @@ do
            esac
            echo "#include \"$f\""
            $cplusplus && echo '};'
-       } >$tmp/test.$ext
+       } >$test_file_name.$ext
 
        # Some subdirectories need extra -I switches.
        case "$f" in
@@ -253,10 +249,11 @@ do
        if ! $COMPILER $COMPILER_FLAGS -I $builddir -I $srcdir \
                -I $builddir/src/include -I $srcdir/src/include \
                -I $builddir/src/interfaces/libpq -I 
$srcdir/src/interfaces/libpq \
-               $EXTRAINCLUDES $EXTRAFLAGS -c $tmp/test.$ext -o $tmp/test.o
+               $EXTRAINCLUDES $EXTRAFLAGS -c $test_file_name.$ext -o 
$test_file_name.o
        then
                exit_status=1
        fi
+       rm -f "$test_file_name.$ext" "$test_file_name.o"
 done
 
 exit $exit_status
-- 
2.51.0

Reply via email to