headerscheck ccache support master github/master
authorPeter Eisentraut <peter@eisentraut.org>
Thu, 4 Dec 2025 10:23:23 +0000 (11:23 +0100)
committerPeter Eisentraut <peter@eisentraut.org>
Thu, 4 Dec 2025 10:23:23 +0000 (11:23 +0100)
Currently, headerscheck and cpluspluscheck are very slow, and they
defeat use of ccache.  This fixes that, and now they are much faster.

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

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

    tmp_headerscheck_c/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 subdirectory is used to keep the cleanup trap simple.)

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.

Co-authored-by: Thomas Munro <thomas.munro@gmail.com>
Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de>
Reviewed-by: Andres Freund <andres@anarazel.de>
Discussion: https://www.postgresql.org/message-id/flat/b49e74d4-3cf9-4d1c-9dce-09f75e55d026%40eisentraut.org

.cirrus.tasks.yml
src/tools/pginclude/headerscheck

index 2fe9671f3dc6fa25ec66707eb4c857f152a62ea8..038d043d00e78d78ea3d55590a920793052224b6 100644 (file)
@@ -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: |
index bf4992e33ae48b13f2360876689405db35e9288e..0c260788b6c05d48574fadd4eb36d0cf4b82d96c 100755 (executable)
@@ -73,8 +73,10 @@ else
    COMPILER_FLAGS="$CPPFLAGS $CFLAGS $ICU_CFLAGS $LLVM_CPPFLAGS"
 fi
 
-# Create temp directory.
-tmp=`mktemp -d /tmp/$me.XXXXXX`
+# Create temp directory.  Help ccache by using a stable name.  Include
+# extension to allow running C and C++ checks in parallel.
+tmp="tmp_${me}_${ext}"
+mkdir -p "$tmp"
 
 trap "ret=$?; rm -rf $tmp; exit $ret" 0 1 2 3 15
 
@@ -200,6 +202,9 @@ do
        test "$f" = src/bin/pg_dump/pg_dump.h && continue
    fi
 
+   # Help ccache by using a stable name.  Remove slashes and dots.
+   test_file_name=$(printf '%s' "$f" | tr '/.' '__')
+
    # OK, create .c file to include this .h file.
    {
        $cplusplus && echo 'extern "C" {'
@@ -232,7 +237,7 @@ do
        esac
        echo "#include \"$f\""
        $cplusplus && echo '};'
-   } >$tmp/test.$ext
+   } >$tmp/$test_file_name.$ext
 
    # Some subdirectories need extra -I switches.
    case "$f" in
@@ -254,10 +259,12 @@ 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 "$tmp/$test_file_name.$ext" -o "$tmp/$test_file_name.o"
    then
        exit_status=1
    fi
+
+   rm -f "$tmp/$test_file_name.$ext" "$tmp/$test_file_name.o"
 done
 
 exit $exit_status