[libc-commits] [compiler-rt] [libc] [libclc] [libcxx] [libcxxabi] [libunwind] [llvm] [openmp] [Runtimes][CMake] Add dependency on compiler to source files (PR #198480)
via libc-commits
libc-commits at lists.llvm.org
Tue May 19 03:02:39 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Wenju He (wenju-he)
<details>
<summary>Changes</summary>
Fix runtimes not rebuilt when clang is updated. Rebuild is critical for runtimes like libclc that produces bitcode-based builtin library, where compiler change should immediately trigger a re-compilation.
By default, CMake add_library does not add compiler executable as dependency for objects of source file.
Add a helper LLVMRuntimeCompilerDependency.cmake which exposes llvm_defer_compiler_dependency_tracking function. Each runtime can explicitly opt-in by calling the function at the beginning of its root CMakeLists to add dependency on compilers it uses.
Assisted-by: Claude Sonnet 4.6
---
Full diff: https://github.com/llvm/llvm-project/pull/198480.diff
14 Files Affected:
- (added) cmake/Modules/LLVMRuntimeCompilerDependency.cmake (+14)
- (modified) compiler-rt/CMakeLists.txt (+4)
- (modified) flang-rt/CMakeLists.txt (+4)
- (modified) libc/CMakeLists.txt (+4)
- (modified) libclc/CMakeLists.txt (+3)
- (modified) libcxx/CMakeLists.txt (+3)
- (modified) libcxxabi/CMakeLists.txt (+3)
- (modified) libsycl/CMakeLists.txt (+3)
- (modified) libunwind/CMakeLists.txt (+4)
- (modified) llvm-libgcc/CMakeLists.txt (+4)
- (added) llvm/cmake/modules/LLVMRuntimeCompilerDependency.cmake (+69)
- (modified) offload/CMakeLists.txt (+3)
- (modified) openmp/CMakeLists.txt (+4)
- (modified) orc-rt/CMakeLists.txt (+4)
``````````diff
diff --git a/cmake/Modules/LLVMRuntimeCompilerDependency.cmake b/cmake/Modules/LLVMRuntimeCompilerDependency.cmake
new file mode 100644
index 0000000000000..057eabd5f5404
--- /dev/null
+++ b/cmake/Modules/LLVMRuntimeCompilerDependency.cmake
@@ -0,0 +1,14 @@
+set(_llvm_runtime_compiler_dependency
+ "${CMAKE_CURRENT_LIST_DIR}/../../llvm/cmake/modules/LLVMRuntimeCompilerDependency.cmake")
+
+if(EXISTS "${_llvm_runtime_compiler_dependency}")
+ include("${_llvm_runtime_compiler_dependency}")
+elseif(LLVM_CMAKE_DIR AND EXISTS "${LLVM_CMAKE_DIR}/LLVMRuntimeCompilerDependency.cmake")
+ include("${LLVM_CMAKE_DIR}/LLVMRuntimeCompilerDependency.cmake")
+elseif(LLVM_DIR AND EXISTS "${LLVM_DIR}/LLVMRuntimeCompilerDependency.cmake")
+ include("${LLVM_DIR}/LLVMRuntimeCompilerDependency.cmake")
+else()
+ message(FATAL_ERROR "Could not find LLVMRuntimeCompilerDependency.cmake")
+endif()
+
+unset(_llvm_runtime_compiler_dependency)
diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt
index e88321d822f84..35737cb60de9d 100644
--- a/compiler-rt/CMakeLists.txt
+++ b/compiler-rt/CMakeLists.txt
@@ -51,9 +51,13 @@ include(base-config-ix)
include(CompilerRTUtils)
include(CMakeDependentOption)
include(GetDarwinLinkerVersion)
+include(LLVMRuntimeCompilerDependency)
include(CheckCXXCompilerFlag)
+llvm_defer_compiler_dependency_tracking(
+ "${CMAKE_C_COMPILER}" "${CMAKE_CXX_COMPILER}" "${CMAKE_ASM_COMPILER}")
+
# Check if we can compile with --no-default-config, or if that omits a config
# file that is essential for the toolchain to work properly.
#
diff --git a/flang-rt/CMakeLists.txt b/flang-rt/CMakeLists.txt
index cd1fc8cfbcff9..b51d5d4c0e2cc 100644
--- a/flang-rt/CMakeLists.txt
+++ b/flang-rt/CMakeLists.txt
@@ -57,6 +57,10 @@ if (CMAKE_VERSION VERSION_LESS "3.24")
endif ()
enable_language(Fortran)
+include(LLVMRuntimeCompilerDependency)
+llvm_defer_compiler_dependency_tracking(
+ "${CMAKE_C_COMPILER}" "${CMAKE_CXX_COMPILER}" "${CMAKE_Fortran_COMPILER}")
+
# Try to include the RPC utilities from the `libc` project for GPU I/O support.
include(FindLibcCommonUtils)
diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt
index 3b5f3949b286d..2e0a75dc0c7ef 100644
--- a/libc/CMakeLists.txt
+++ b/libc/CMakeLists.txt
@@ -38,6 +38,10 @@ endif()
set(CMAKE_CXX_STANDARD 17)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
+include(LLVMRuntimeCompilerDependency)
+
+llvm_defer_compiler_dependency_tracking(
+ "${CMAKE_C_COMPILER}" "${CMAKE_CXX_COMPILER}" "${CMAKE_ASM_COMPILER}")
# The top-level source directory.
set(LIBC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt
index 44d9f7a281b5d..05f45e6700e75 100644
--- a/libclc/CMakeLists.txt
+++ b/libclc/CMakeLists.txt
@@ -88,6 +88,9 @@ else()
cmake_path( APPEND LIBCLC_OUTPUT_LIBRARY_DIR ${LIBCLC_INSTALL_DIR} )
endif()
+include(LLVMRuntimeCompilerDependency)
+llvm_defer_compiler_dependency_tracking("${CMAKE_CLC_COMPILER}")
+
if( NOT LIBCLC_USE_SPIRV_BACKEND )
# llvm-spirv is an optional dependency, used to build spirv-* targets when
# the SPIR-V backend hasn't been requested. It may be provided in-tree or
diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index 845240d1b894c..2c0280e485f3a 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -27,8 +27,11 @@ set(LIBCXX_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(LIBCXX_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
include(GNUInstallDirs)
+include(LLVMRuntimeCompilerDependency)
include(WarningFlags)
+llvm_defer_compiler_dependency_tracking("${CMAKE_CXX_COMPILER}")
+
# Require out of source build.
include(MacroEnsureOutOfSourceBuild)
MACRO_ENSURE_OUT_OF_SOURCE_BUILD(
diff --git a/libcxxabi/CMakeLists.txt b/libcxxabi/CMakeLists.txt
index e1a1587fb6283..7e1fe55646166 100644
--- a/libcxxabi/CMakeLists.txt
+++ b/libcxxabi/CMakeLists.txt
@@ -26,6 +26,9 @@ set(LIBCXXABI_LIBCXX_PATH "${CMAKE_CURRENT_LIST_DIR}/../libcxx" CACHE PATH
"Specify path to libc++ source.")
include(GNUInstallDirs)
+include(LLVMRuntimeCompilerDependency)
+
+llvm_defer_compiler_dependency_tracking("${CMAKE_CXX_COMPILER}")
# Require out of source build.
include(MacroEnsureOutOfSourceBuild)
diff --git a/libsycl/CMakeLists.txt b/libsycl/CMakeLists.txt
index ae3fd4359c3f2..7a1b34a126b60 100644
--- a/libsycl/CMakeLists.txt
+++ b/libsycl/CMakeLists.txt
@@ -12,6 +12,9 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS OFF)
+include(LLVMRuntimeCompilerDependency)
+llvm_defer_compiler_dependency_tracking("${CMAKE_CXX_COMPILER}")
+
#===============================================================================
# Limitations
#===============================================================================
diff --git a/libunwind/CMakeLists.txt b/libunwind/CMakeLists.txt
index 02132f6c07fcd..30ceeb564bd73 100644
--- a/libunwind/CMakeLists.txt
+++ b/libunwind/CMakeLists.txt
@@ -23,6 +23,10 @@ set(LIBUNWIND_LIBCXX_PATH "${CMAKE_CURRENT_LIST_DIR}/../libcxx" CACHE PATH
include(GNUInstallDirs)
include(CheckSymbolExists)
+include(LLVMRuntimeCompilerDependency)
+
+llvm_defer_compiler_dependency_tracking(
+ "${CMAKE_C_COMPILER}" "${CMAKE_CXX_COMPILER}" "${CMAKE_ASM_COMPILER}")
if (MSVC)
message(FATAL_ERROR "Libunwind doesn't build for MSVC targets, and that is almost certainly not what you want to do "
diff --git a/llvm-libgcc/CMakeLists.txt b/llvm-libgcc/CMakeLists.txt
index 55c052165dbd1..5c736862ddb24 100644
--- a/llvm-libgcc/CMakeLists.txt
+++ b/llvm-libgcc/CMakeLists.txt
@@ -34,6 +34,10 @@ set(LLVM_LIBGCC_COMPILER_RT_PATH "${CMAKE_CURRENT_LIST_DIR}/../compiler-rt"
CACHE PATH "Specify path to compiler-rt source.")
include(GNUInstallDirs)
+include(LLVMRuntimeCompilerDependency)
+
+llvm_defer_compiler_dependency_tracking(
+ "${CMAKE_C_COMPILER}" "${CMAKE_CXX_COMPILER}" "${CMAKE_ASM_COMPILER}")
if(NOT LLVM_LIBGCC_EXPLICIT_OPT_IN)
message(FATAL_ERROR
diff --git a/llvm/cmake/modules/LLVMRuntimeCompilerDependency.cmake b/llvm/cmake/modules/LLVMRuntimeCompilerDependency.cmake
new file mode 100644
index 0000000000000..f78192e8cf680
--- /dev/null
+++ b/llvm/cmake/modules/LLVMRuntimeCompilerDependency.cmake
@@ -0,0 +1,69 @@
+include_guard(GLOBAL)
+
+function(_llvm_track_compiler_dependency_dir dir)
+ set(_compilers ${ARGN})
+ if(NOT _compilers)
+ return()
+ endif()
+
+ get_property(_targets DIRECTORY "${dir}" PROPERTY BUILDSYSTEM_TARGETS)
+ foreach(_target IN LISTS _targets)
+ get_target_property(_type ${_target} TYPE)
+ if(NOT _type MATCHES "^(OBJECT_LIBRARY|STATIC_LIBRARY|SHARED_LIBRARY|MODULE_LIBRARY|EXECUTABLE)$")
+ continue()
+ endif()
+
+ get_target_property(_sources ${_target} SOURCES)
+
+ # Filter out generator expressions (e.g., $<TARGET_OBJECTS:...>).
+ list(FILTER _sources EXCLUDE REGEX "^\\$<")
+ if(NOT _sources)
+ continue()
+ endif()
+
+ foreach(_compiler IN LISTS _compilers)
+ set_property(SOURCE ${_sources}
+ TARGET_DIRECTORY ${_target}
+ APPEND PROPERTY OBJECT_DEPENDS "${_compiler}")
+ endforeach()
+ endforeach()
+
+ # BUILDSYSTEM_TARGETS is flat, so recurse into subdirectories.
+ get_property(_subdirs DIRECTORY "${dir}" PROPERTY SUBDIRECTORIES)
+ foreach(_subdir IN LISTS _subdirs)
+ _llvm_track_compiler_dependency_dir("${_subdir}" ${_compilers})
+ endforeach()
+endfunction()
+
+# cmake_language(DEFER CALL) re-evaluates arguments at call time in the
+# directory scope.
+function(_llvm_track_compiler_dependency_dir_deferred)
+ get_property(_compilers DIRECTORY PROPERTY _LLVM_TRACK_COMPILERS)
+ if(NOT _compilers)
+ return()
+ endif()
+ _llvm_track_compiler_dependency_dir("${CMAKE_CURRENT_SOURCE_DIR}" ${_compilers})
+endfunction()
+
+# Add compiler binaries as target dependencies for code recompilation tracking.
+#
+# This function registers compiler binaries as build dependencies for all target
+# objects compiled within the specified directory hierarchy. This guarantees
+# that if a compiler binary is rebuilt, all runtime library objects are
+# invalidated and rebuilt.
+#
+# This function must be called at the beginning of a runtime root CMakeLists.
+#
+# Argument COMPILERS is a ist of compiler binary file paths to track.
+#
+function(llvm_defer_compiler_dependency_tracking)
+ set(COMPILERS ${ARGN})
+ if(NOT COMPILERS)
+ message(FATAL_ERROR "COMPILERS is required for llvm_defer_compiler_dependency_tracking")
+ endif()
+
+ # Store compilers as a directory property so the deferred call can read them.
+ set_property(DIRECTORY APPEND PROPERTY _LLVM_TRACK_COMPILERS "${COMPILERS}")
+ # Defer to triggers at the end of the current source dir.
+ cmake_language(DEFER CALL _llvm_track_compiler_dependency_dir_deferred)
+endfunction()
diff --git a/offload/CMakeLists.txt b/offload/CMakeLists.txt
index 472fee8e64156..4a9445823c210 100644
--- a/offload/CMakeLists.txt
+++ b/offload/CMakeLists.txt
@@ -54,6 +54,9 @@ list(INSERT CMAKE_MODULE_PATH 0
"${LLVM_COMMON_CMAKE_UTILS}/Modules"
)
+include(LLVMRuntimeCompilerDependency)
+llvm_defer_compiler_dependency_tracking("${CMAKE_C_COMPILER}" "${CMAKE_CXX_COMPILER}")
+
set(OPENMP_TEST_C_COMPILER_default "${LLVM_TOOLS_BINARY_DIR}/clang${CMAKE_EXECUTABLE_SUFFIX}")
set(OPENMP_TEST_CXX_COMPILER_default "${LLVM_TOOLS_BINARY_DIR}/clang++${CMAKE_EXECUTABLE_SUFFIX}")
set(OPENMP_TEST_Fortran_COMPILER_default "${LLVM_TOOLS_BINARY_DIR}/flang${CMAKE_EXECUTABLE_SUFFIX}")
diff --git a/openmp/CMakeLists.txt b/openmp/CMakeLists.txt
index 08e6c97d43c43..b5776ddcc6613 100644
--- a/openmp/CMakeLists.txt
+++ b/openmp/CMakeLists.txt
@@ -22,6 +22,10 @@ endif()
# Must go below project(..)
include(GNUInstallDirs)
+include(LLVMRuntimeCompilerDependency)
+
+llvm_defer_compiler_dependency_tracking(
+ "${CMAKE_C_COMPILER}" "${CMAKE_CXX_COMPILER}" "${CMAKE_ASM_COMPILER}")
# Usually <llvm-project>/runtimes/CMakeLists.txt sets LLVM_TREE_AVAILABLE and
# we assume it is not available otherwise. The exception is that we are in an
diff --git a/orc-rt/CMakeLists.txt b/orc-rt/CMakeLists.txt
index 95b7b852138e7..e4ea79a84d33f 100644
--- a/orc-rt/CMakeLists.txt
+++ b/orc-rt/CMakeLists.txt
@@ -21,6 +21,10 @@ list(INSERT CMAKE_MODULE_PATH 0
)
include(GNUInstallDirs)
+include(LLVMRuntimeCompilerDependency)
+
+llvm_defer_compiler_dependency_tracking(
+ "${CMAKE_C_COMPILER}" "${CMAKE_CXX_COMPILER}" "${CMAKE_ASM_COMPILER}")
#===============================================================================
# Setup CMake Options
``````````
</details>
https://github.com/llvm/llvm-project/pull/198480
More information about the libc-commits
mailing list