[compiler-rt][profile] Use runtimes-libc-headers in the GPU runtimes build (#192814)

When compiler-rt is built for a GPU target in the same runtimes build
as LLVM-libc, the profile sources `#include <string.h>`, `<limits.h>`,
... Those headers are generated by LLVM-libc for the GPU triple.

A concrete example is the amdgcn runtimes build:

    -DLLVM_RUNTIME_TARGETS='default;amdgcn-amd-amdhsa'
    -DRUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES='compiler-rt;libc'
    -DRUNTIMES_amdgcn-amd-amdhsa_RUNTIMES_USE_LIBC=llvm-libc

Even though `libc` is configured before `compiler-rt`, both sets of
targets live in the same ninja graph and race each other. Ninja can
start compiling `compiler-rt/lib/profile/InstrProfiling.c` before
LLVM-libc has finished generating its GPU `string.h`, and even when
hdrgen has finished, the profile compile needs `-isystem` pointing at
the generated header tree.

Use the runtimes-side libc-provider abstraction in
`runtimes/cmake/Modules/HandleLibC.cmake`:

  - at compiler-rt top level, `include(HandleLibC)` when
    `LLVM_RUNTIMES_BUILD` is set, so all compiler-rt subcomponents can
    reuse the `runtimes-libc-*` targets. `libcxx` / `libcxxabi` /
    `libunwind` include it the same way at their top-level CMakeLists.
  - in `compiler-rt/lib/profile/CMakeLists.txt`, when the GPU build
    sees the sibling `runtimes-libc-headers` target, pass it through
    `LINK_LIBS` of `add_compiler_rt_runtime(clang_rt.profile ...)`.

In the `llvm-libc` case this pulls in LLVM-libc's `libc-headers`
(`-isystem <build>/include/<triple>`), waits for
`generate-libc-headers`, and adds `-nostdlibinc` so the profile compile
does not consult host C library paths.

The dependency is added only when `COMPILER_RT_GPU_BUILD` is on and the
sibling `runtimes-libc-headers` target actually exists, so host
compiler-rt builds, standalone compiler-rt builds, and runtimes builds
without LLVM-libc selected are unchanged.

`add_compiler_rt_runtime` passes `LINK_LIBS` to
`target_link_libraries(<libname> PRIVATE ...)`, so the include path is
used when compiling the profile target itself but is not propagated to
downstream consumers of `libclang_rt.profile.a`.

Related: PR #177665.
This commit is contained in:
Yaxun (Sam) Liu
2026-04-21 17:53:34 -04:00
committed by GitHub
parent 92958a0631
commit e0b4a7063f
2 changed files with 19 additions and 0 deletions

View File

@@ -32,6 +32,14 @@ list(INSERT CMAKE_MODULE_PATH 0
"${LLVM_COMMON_CMAKE_UTILS}/Modules"
)
# Expose the shared `runtimes-libc-*` targets to compiler-rt subcomponents
# (same as libcxx / libcxxabi / libunwind).
if(LLVM_RUNTIMES_BUILD)
list(APPEND CMAKE_MODULE_PATH
"${CMAKE_CURRENT_SOURCE_DIR}/../runtimes/cmake/Modules")
include(HandleLibC)
endif()
if(CMAKE_CONFIGURATION_TYPES)
set(CMAKE_CFG_RESOLVED_INTDIR "${CMAKE_CFG_INTDIR}/")
else()

View File

@@ -186,6 +186,15 @@ append_list_if(COMPILER_RT_HAS_WD4221_FLAG /wd4221 EXTRA_FLAGS)
# Disable 'nonstandard extension used: translation unit is empty'.
append_list_if(COMPILER_RT_HAS_WD4206_FLAG /wd4206 EXTRA_FLAGS)
# In the GPU runtimes build, link `runtimes-libc-headers` for its
# `-isystem` include dir and for waiting on header generation.
# The target is created at compiler-rt top level from `HandleLibC.cmake`
# when `LLVM_RUNTIMES_BUILD` is set.
set(PROFILE_LINK_LIBS)
if(COMPILER_RT_GPU_BUILD AND TARGET runtimes-libc-headers)
list(APPEND PROFILE_LINK_LIBS runtimes-libc-headers)
endif()
if(APPLE)
add_compiler_rt_runtime(clang_rt.profile
STATIC
@@ -194,6 +203,7 @@ if(APPLE)
CFLAGS ${EXTRA_FLAGS}
SOURCES ${PROFILE_SOURCES}
ADDITIONAL_HEADERS ${PROFILE_HEADERS}
LINK_LIBS ${PROFILE_LINK_LIBS}
PARENT_TARGET profile)
else()
add_compiler_rt_runtime(clang_rt.profile
@@ -202,5 +212,6 @@ else()
CFLAGS ${EXTRA_FLAGS}
SOURCES ${PROFILE_SOURCES}
ADDITIONAL_HEADERS ${PROFILE_HEADERS}
LINK_LIBS ${PROFILE_LINK_LIBS}
PARENT_TARGET profile)
endif()