[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.
GitOrigin-RevId: e0b4a7063f78d36ffa5679e1d0e564a3668db1f0
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1a5520d..6e80456 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,6 +32,14 @@
   "${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()
diff --git a/lib/profile/CMakeLists.txt b/lib/profile/CMakeLists.txt
index 8c196d1..8d9a773 100644
--- a/lib/profile/CMakeLists.txt
+++ b/lib/profile/CMakeLists.txt
@@ -186,6 +186,15 @@
 # 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 @@
     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 @@
     CFLAGS ${EXTRA_FLAGS}
     SOURCES ${PROFILE_SOURCES}
     ADDITIONAL_HEADERS ${PROFILE_HEADERS}
+    LINK_LIBS ${PROFILE_LINK_LIBS}
     PARENT_TARGET profile)
 endif()