Ccache clang and -fno-pch-timestamp

The latest ccache recommends adding -fno-pch-timestamp to the Clang compile command for PCH, but I can’t find anywhere how to do it in CMake.

I’m creating precompiled header like this:

target_precompile_headers(${TinyOrm_target} PRIVATE $<$<COMPILE_LANGUAGE:CXX>:"pch.h">)

if(NOT CMAKE_DISABLE_PRECOMPILE_HEADERS)
    target_compile_definitions(${TinyOrm_target} PRIVATE TINYORM_USING_PCH)
endif()

My question is how can I add the -fno-pch-timestamp compiler option only to this precompiled header compiler command?

The target_compile_options() command is probably what you are looking for. The tricky part here though is that you need to precede the option with -Xclang because it needs to be passed to the internal compiler, not given to the compiler front end like most options.

if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    target_compile_options(${TinyOrm_target} PRIVATE
        "$<$<COMPILE_LANGUAGE:CXX>:SHELL:-Xclang -fno-pch-timestamp>"
    )
endif()

We need to use SHELL: to keep the two flags together and prevent any de-duplication with other -Xclang options that may also appear on the command line.

1 Like

Thx, it compiles. But it also adds it to every compile command, what I understood from this PR then this option should be only added to the compile command for PCH, so compile command that contains -emit-pch option. We don’t need to add it to compile commands for *.cpp files.

I know that CMake uses this variable to set options for the PCH compile command:
CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH.

You can use this to commands to check if the `-fno-pch-timestamp` option is in effect.

pragma-once2-pch.h:

#include "pragma-once2.h"

pragma-once2.h:

#pragma once

inline void f() {}

Should fail:

clang++ -std=c++20 -Winvalid-pch -Xclang -emit-pch -x c++-header -o ./cmake_pch.hxx.pch ./pragma-once2-pch.h
touch -m -a -t 201008011501 ./pragma-once2.h
clang++ -std=c++20 -include-pch ./cmake_pch.hxx.pch ./include-timestamp.cpp

Should compile ok:

clang++ -Xclang -fno-pch-timestamp -std=c++20 -Winvalid-pch -Xclang -emit-pch -x c++-header -o ./cmake_pch.hxx.pch ./pragma-once2-pch.h
touch -m -a -t 201008011501 ./pragma-once2.h
clang++ -std=c++20 -include-pch ./cmake_pch.hxx.pch ./include-timestamp.cpp

I have something like this at the end of the day:

if(NOT MSVC AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    list(APPEND CMAKE_CXX_COMPILE_OPTIONS_CREATE_PCH -Xclang -fno-pch-timestamp)
endif()

CMAKE_CXX_COMPILE_OPTIONS_CREATE_PCH is not a publicly documented part of CMake’s API. It could change at any time without notice, including the way it gets used or formed internally. You would be using that at your own risk.

As far as I can tell, there doesn’t seem to be any harm in having -fno-pch-timestamp for all command lines. It doesn’t generate any warnings for non-PCH compiles, at least not that I’ve seen.

1 Like

You are right, everything you wrote is true.