From 2c910431c93a58c131450bc138057e3ee2d1ff07 Mon Sep 17 00:00:00 2001 From: Kajetan Puchalski Date: Fri, 14 Mar 2025 21:35:08 +0000 Subject: [PATCH 1/5] [CMake] Fix using precompiled headers with ccache Using precompiled headers with ccache requires special accommodations. Add the required CCACHE option and clang compiler flag to CMake. Signed-off-by: Kajetan Puchalski --- flang/CMakeLists.txt | 5 +++++ llvm/CMakeLists.txt | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/flang/CMakeLists.txt b/flang/CMakeLists.txt index 4b703b456cae2..3be84eeca21ba 100644 --- a/flang/CMakeLists.txt +++ b/flang/CMakeLists.txt @@ -446,6 +446,11 @@ if (APPLE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_POSIX_C_SOURCE=200809") endif() +# Clang requires this flag in order for precompiled headers to work with ccache. +if (CMAKE_CXX_COMPILER_ID MATCHES Clang) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Xclang -fno-pch-timestamp") +endif() + list(REMOVE_DUPLICATES CMAKE_CXX_FLAGS) # Determine HOST_LINK_VERSION on Darwin. diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index c5d3e23a47f0e..1b1def5e2537c 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -277,7 +277,7 @@ if(LLVM_CCACHE_BUILD) if(CCACHE_PROGRAM) set(LLVM_CCACHE_MAXSIZE "" CACHE STRING "Size of ccache") set(LLVM_CCACHE_DIR "" CACHE STRING "Directory to keep ccached data") - set(LLVM_CCACHE_PARAMS "CCACHE_CPP2=yes CCACHE_HASHDIR=yes" + set(LLVM_CCACHE_PARAMS "CCACHE_CPP2=yes CCACHE_HASHDIR=yes CCACHE_SLOPPINESS=pch_defines,time_macros" CACHE STRING "Parameters to pass through to ccache") if(NOT CMAKE_SYSTEM_NAME MATCHES "Windows") @@ -291,7 +291,7 @@ if(LLVM_CCACHE_BUILD) set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_PROGRAM}) else() if(LLVM_CCACHE_MAXSIZE OR LLVM_CCACHE_DIR OR - NOT LLVM_CCACHE_PARAMS MATCHES "CCACHE_CPP2=yes CCACHE_HASHDIR=yes") + NOT LLVM_CCACHE_PARAMS MATCHES "CCACHE_CPP2=yes CCACHE_HASHDIR=yes CCACHE_SLOPPINESS=pch_defines,time_macros") message(FATAL_ERROR "Ccache configuration through CMake is not supported on Windows. Please use environment variables.") endif() # RULE_LAUNCH_COMPILE should work with Ninja but currently has issues From a05645be1f224c5e93b9ae3c660df6f2c9535d4a Mon Sep 17 00:00:00 2001 From: Kajetan Puchalski Date: Tue, 18 Mar 2025 15:01:00 +0000 Subject: [PATCH 2/5] [CMake] Configure ccache using command line options Since ccache 4.8, it is possible to pass configuration options directly to ccache on the command line as opposed to through environment variables. This is the intended way for CMake to configure ccache, as described on the GitHub wiki for the project: https://github.com/ccache/ccache/wiki/CMake Rework the way ccache is configured by LLVM accordingly. Signed-off-by: Kajetan Puchalski --- llvm/CMakeLists.txt | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index 1b1def5e2537c..dfc506b643570 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -277,28 +277,19 @@ if(LLVM_CCACHE_BUILD) if(CCACHE_PROGRAM) set(LLVM_CCACHE_MAXSIZE "" CACHE STRING "Size of ccache") set(LLVM_CCACHE_DIR "" CACHE STRING "Directory to keep ccached data") - set(LLVM_CCACHE_PARAMS "CCACHE_CPP2=yes CCACHE_HASHDIR=yes CCACHE_SLOPPINESS=pch_defines,time_macros" + set(LLVM_CCACHE_PARAMS "run_second_cpp=true;hash_dir=true;sloppiness=pch_defines,time_macros" CACHE STRING "Parameters to pass through to ccache") - if(NOT CMAKE_SYSTEM_NAME MATCHES "Windows") - set(CCACHE_PROGRAM "${LLVM_CCACHE_PARAMS} ${CCACHE_PROGRAM}") - if (LLVM_CCACHE_MAXSIZE) - set(CCACHE_PROGRAM "CCACHE_MAXSIZE=${LLVM_CCACHE_MAXSIZE} ${CCACHE_PROGRAM}") - endif() - if (LLVM_CCACHE_DIR) - set(CCACHE_PROGRAM "CCACHE_DIR=${LLVM_CCACHE_DIR} ${CCACHE_PROGRAM}") - endif() - set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_PROGRAM}) - else() - if(LLVM_CCACHE_MAXSIZE OR LLVM_CCACHE_DIR OR - NOT LLVM_CCACHE_PARAMS MATCHES "CCACHE_CPP2=yes CCACHE_HASHDIR=yes CCACHE_SLOPPINESS=pch_defines,time_macros") - message(FATAL_ERROR "Ccache configuration through CMake is not supported on Windows. Please use environment variables.") - endif() - # RULE_LAUNCH_COMPILE should work with Ninja but currently has issues - # with cmd.exe and some MSVC tools other than cl.exe - set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM}) - set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM}) - endif() + set(launcher_params ${LLVM_CCACHE_PARAMS}) + if (CCACHE_MAXSIZE) + set(launcher_params "max_size=${CCACHE_MAXSIZE};${launcher_params}") + endif () + if (CCACHE_DIR) + set(launcher_params "cache_dir=${CCACHE_DIR};${launcher_params}") + endif () + set(launcher "${CCACHE_PROGRAM};${launcher_params}") + set(CMAKE_C_COMPILER_LAUNCHER ${launcher}) + set(CMAKE_CXX_COMPILER_LAUNCHER ${launcher}) else() message(FATAL_ERROR "Unable to find the program ccache. Set LLVM_CCACHE_BUILD to OFF") endif() From 422312551bccd80cf5394f1463468b97892a3d47 Mon Sep 17 00:00:00 2001 From: Kajetan Puchalski Date: Tue, 18 Mar 2025 15:53:04 +0000 Subject: [PATCH 3/5] [flang] [CMake] Set compiler flags for ccache+pch Reference ccache documentation: https://ccache.dev/manual/latest.html#_precompiled_headers For clang, only pass -Xclang -fno-pch-timestamp if precompiled headers are enabled in CMake. For gcc, pass -fpch-preprocess in the same scenario. Signed-off-by: Kajetan Puchalski --- flang/CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/flang/CMakeLists.txt b/flang/CMakeLists.txt index 3be84eeca21ba..b67cda79839da 100644 --- a/flang/CMakeLists.txt +++ b/flang/CMakeLists.txt @@ -436,6 +436,10 @@ if (LLVM_COMPILER_IS_GCC_COMPATIBLE) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-semantic-interposition") endif() + # gcc requires this flag in order for precompiled headers to work with ccache + if (NOT CMAKE_CXX_COMPILER_ID MATCHES Clang AND NOT CMAKE_DISABLE_PRECOMPILE_HEADERS) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpch-preprocess") + endif() endif() # Clang on Darwin enables non-POSIX extensions by default, which allows the @@ -446,8 +450,8 @@ if (APPLE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_POSIX_C_SOURCE=200809") endif() -# Clang requires this flag in order for precompiled headers to work with ccache. -if (CMAKE_CXX_COMPILER_ID MATCHES Clang) +# Clang requires this flag in order for precompiled headers to work with ccache +if (CMAKE_CXX_COMPILER_ID MATCHES Clang AND NOT CMAKE_DISABLE_PRECOMPILE_HEADERS) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Xclang -fno-pch-timestamp") endif() From fc4e84b0216dedb64d7fd299091e0066b5ddd4db Mon Sep 17 00:00:00 2001 From: Kajetan Puchalski Date: Wed, 19 Mar 2025 14:45:20 +0000 Subject: [PATCH 4/5] [CMake] Add a workaround for pre-4.8 ccache configuration With ccache only supporting passing arguments on the command line since version 4.8, a workaround is needed for systems with older versions. Whenever possible, we want to use the new way of configuring ccache because it will ensure uniform behaviour across platforms in a way that just setting environment variables might not. Signed-off-by: Kajetan Puchalski --- llvm/CMakeLists.txt | 48 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index dfc506b643570..3e276dbeb76c4 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -275,19 +275,45 @@ set(LLVM_CCACHE_BUILD OFF CACHE BOOL "Set to ON for a ccache enabled build") if(LLVM_CCACHE_BUILD) find_program(CCACHE_PROGRAM ccache) if(CCACHE_PROGRAM) + # ccache --version example output: "ccache version 4.9.1\n(..)" + execute_process(COMMAND ${CCACHE_PROGRAM} --version OUTPUT_VARIABLE CCACHE_VERSION_STR) + # Strip the prefix before the version number, taking some extra characters + string(SUBSTRING "${CCACHE_VERSION_STR}" 15 10 CCACHE_VERSION_STR) + string(FIND "${CCACHE_VERSION_STR}" "\n" CCACHE_VERSION_ENDPOS) + # Extract the actual version number + string(SUBSTRING "${CCACHE_VERSION_STR}" 0 "${CCACHE_VERSION_ENDPOS}" CCACHE_VERSION) + set(LLVM_CCACHE_MAXSIZE "" CACHE STRING "Size of ccache") set(LLVM_CCACHE_DIR "" CACHE STRING "Directory to keep ccached data") - set(LLVM_CCACHE_PARAMS "run_second_cpp=true;hash_dir=true;sloppiness=pch_defines,time_macros" - CACHE STRING "Parameters to pass through to ccache") - - set(launcher_params ${LLVM_CCACHE_PARAMS}) - if (CCACHE_MAXSIZE) - set(launcher_params "max_size=${CCACHE_MAXSIZE};${launcher_params}") - endif () - if (CCACHE_DIR) - set(launcher_params "cache_dir=${CCACHE_DIR};${launcher_params}") - endif () - set(launcher "${CCACHE_PROGRAM};${launcher_params}") + + # ccache only supports passing options on the command line from version 4.8.0 + # use a workaround with ad-hoc environment variables for older versions + if (CCACHE_VERSION VERSION_LESS "4.8.0") + set(LLVM_CCACHE_PARAMS "CCACHE_CPP2=yes;CCACHE_HASHDIR=yes;CCACHE_SLOPPINESS=pch_defines,time_macros" + CACHE STRING "Parameters to pass through to ccache") + + set(launcher_params ${LLVM_CCACHE_PARAMS}) + if (CCACHE_MAXSIZE) + set(launcher_params "CCACHE_MAXSIZE=${CCACHE_MAXSIZE};${launcher_params}") + endif() + if (CCACHE_DIR) + set(launcher_params "CCACHE_DIR=${CCACHE_DIR};${launcher_params}") + endif() + set(launcher "${launcher_params};${CCACHE_PROGRAM}") + else() + set(LLVM_CCACHE_PARAMS "run_second_cpp=true;hash_dir=true;sloppiness=pch_defines,time_macros" + CACHE STRING "Parameters to pass through to ccache") + + set(launcher_params ${LLVM_CCACHE_PARAMS}) + if (CCACHE_MAXSIZE) + set(launcher_params "max_size=${CCACHE_MAXSIZE};${launcher_params}") + endif() + if (CCACHE_DIR) + set(launcher_params "cache_dir=${CCACHE_DIR};${launcher_params}") + endif() + set(launcher "${CCACHE_PROGRAM};${launcher_params}") + endif() + set(CMAKE_C_COMPILER_LAUNCHER ${launcher}) set(CMAKE_CXX_COMPILER_LAUNCHER ${launcher}) else() From b5b0add5433d1e5570b4b5fdfeadf94348ba1cd5 Mon Sep 17 00:00:00 2001 From: Kajetan Puchalski Date: Tue, 1 Apr 2025 10:17:18 +0000 Subject: [PATCH 5/5] [CMake] Use regex to extract ccache version flang - Explicitly match gcc to add gcc-specific flag. Signed-off-by: Kajetan Puchalski --- flang/CMakeLists.txt | 4 ++-- llvm/CMakeLists.txt | 6 +----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/flang/CMakeLists.txt b/flang/CMakeLists.txt index b67cda79839da..b13e617d92763 100644 --- a/flang/CMakeLists.txt +++ b/flang/CMakeLists.txt @@ -436,8 +436,8 @@ if (LLVM_COMPILER_IS_GCC_COMPATIBLE) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-semantic-interposition") endif() - # gcc requires this flag in order for precompiled headers to work with ccache - if (NOT CMAKE_CXX_COMPILER_ID MATCHES Clang AND NOT CMAKE_DISABLE_PRECOMPILE_HEADERS) + # GCC requires this flag in order for precompiled headers to work with ccache + if (CMAKE_CXX_COMPILER_ID MATCHES GCC AND NOT CMAKE_DISABLE_PRECOMPILE_HEADERS) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpch-preprocess") endif() endif() diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index 3e276dbeb76c4..8e913d17c35e4 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -277,11 +277,7 @@ if(LLVM_CCACHE_BUILD) if(CCACHE_PROGRAM) # ccache --version example output: "ccache version 4.9.1\n(..)" execute_process(COMMAND ${CCACHE_PROGRAM} --version OUTPUT_VARIABLE CCACHE_VERSION_STR) - # Strip the prefix before the version number, taking some extra characters - string(SUBSTRING "${CCACHE_VERSION_STR}" 15 10 CCACHE_VERSION_STR) - string(FIND "${CCACHE_VERSION_STR}" "\n" CCACHE_VERSION_ENDPOS) - # Extract the actual version number - string(SUBSTRING "${CCACHE_VERSION_STR}" 0 "${CCACHE_VERSION_ENDPOS}" CCACHE_VERSION) + string(REGEX MATCH "[0-9]+\.[0-9]+\.?[0-9]*" CCACHE_VERSION "${CCACHE_VERSION_STR}") set(LLVM_CCACHE_MAXSIZE "" CACHE STRING "Size of ccache") set(LLVM_CCACHE_DIR "" CACHE STRING "Directory to keep ccached data")