[libc-commits] [libc] [libc] Fix libc GPU bitcode entrypoint library build on Windows (PR #210662)

via libc-commits libc-commits at lists.llvm.org
Mon Jul 20 01:36:36 PDT 2026


https://github.com/jinge90 created https://github.com/llvm/llvm-project/pull/210662

None

>From 3ed4bdd51da023ad16f9babfd8342d7b27a91819 Mon Sep 17 00:00:00 2001
From: jinge90 <ge.jin at intel.com>
Date: Mon, 20 Jul 2026 15:54:29 +0800
Subject: [PATCH] [libc] Fix libc GPU bitcode entrypoint library build on
 Windows

Signed-off-by: jinge90 <ge.jin at intel.com>
---
 libc/CMakeLists.txt                           |  7 +++
 libc/cmake/modules/LLVMLibCLibraryRules.cmake | 60 +++++++++++++++++--
 libc/lib/CMakeLists.txt                       | 18 ++++--
 libc/startup/gpu/CMakeLists.txt               | 24 +++++---
 4 files changed, 91 insertions(+), 18 deletions(-)

diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt
index af820ba6ab6c0..3643ef7213a81 100644
--- a/libc/CMakeLists.txt
+++ b/libc/CMakeLists.txt
@@ -289,6 +289,13 @@ endif()
 if(LIBC_TARGET_OS_IS_GPU)
   include(prepare_libc_gpu_build)
   set(LIBC_ENABLE_UNITTESTS OFF)
+
+  if(CMAKE_HOST_WIN32)
+    find_program(LIBC_LLVM_LINK llvm-link PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH)
+    if(NOT LIBC_LLVM_LINK)
+      message(FATAL_ERROR "llvm-link not found in ${LLVM_TOOLS_BINARY_DIR}")
+    endif()
+  endif()
 elseif(LIBC_TARGET_OS_IS_BAREMETAL)
   set(LIBC_ENABLE_UNITTESTS OFF)
 endif()
diff --git a/libc/cmake/modules/LLVMLibCLibraryRules.cmake b/libc/cmake/modules/LLVMLibCLibraryRules.cmake
index 2df8f49100b99..4e6532a4402cb 100644
--- a/libc/cmake/modules/LLVMLibCLibraryRules.cmake
+++ b/libc/cmake/modules/LLVMLibCLibraryRules.cmake
@@ -80,13 +80,43 @@ function(get_all_object_file_deps result fq_deps_list)
   set(${result} ${all_deps} PARENT_SCOPE)
 endfunction()
 
-# A rule to build a library from a collection of entrypoint objects and bundle
-# it in a single LLVM-IR bitcode file.
+# Link bitcode inputs into a single LLVM IR module using llvm-link. Used on
+# Windows where 'add_executable' can't work. Build static archive library
+# firstly and use this static archive library as llvm-link's input.
 # Usage:
-#     add_bitcode_entrypoint_library(
+#     llvm_link_bitcode(
+#       target_name
+#       OUTPUT <output file path>
+#       INPUTS <input file path>
+#       DEPENDS <targets that must be built first>
+#     )
+function(llvm_link_bitcode target_name)
+  cmake_parse_arguments(
+    "ARG"
+    ""
+    "OUTPUT"
+    "INPUTS;DEPENDS"
+    ${ARGN}
+  )
+  add_custom_command(
+    OUTPUT ${ARG_OUTPUT}
+    COMMAND ${LIBC_LLVM_LINK} ${ARG_INPUTS} -o ${ARG_OUTPUT}
+    DEPENDS ${ARG_DEPENDS}
+    COMMENT "Linking bitcode ${ARG_OUTPUT}"
+  )
+  add_custom_target(${target_name} ALL DEPENDS ${ARG_OUTPUT})
+  set_target_properties(${target_name} PROPERTIES TARGET_FILE ${ARG_OUTPUT})
+endfunction(llvm_link_bitcode)
+
+# Build a single LLVM IR module by using clang driver to link object files
+# files with LTO. Used on Linux platform.
+# Usage:
+#     add_bitcode_entrypoint_library_lto(
+#       target_name
+#       base_target_name
 #       DEPENDS <list of add_entrypoint_object targets>
 #     )
-function(add_bitcode_entrypoint_library target_name base_target_name)
+function(add_bitcode_entrypoint_library_lto target_name base_target_name)
   cmake_parse_arguments(
     "ENTRYPOINT_LIBRARY"
     "" # No optional arguments
@@ -112,11 +142,31 @@ function(add_bitcode_entrypoint_library target_name base_target_name)
   if(LIBC_TARGET_ARCHITECTURE_IS_SPIRV)
       target_link_options(${target_name} PRIVATE "${LIBC_COMPILE_OPTIONS_DEFAULT}"
                       "-nostdlib" "-emit-llvm")
-  else()  
+  else()
       target_link_options(${target_name} PRIVATE "${LIBC_COMPILE_OPTIONS_DEFAULT}"
                       "-r" "-nostdlib" "-flto" "-Wl,--lto-emit-llvm")
   endif()
   add_dependencies(${base_target_name} ${target_name})
+endfunction(add_bitcode_entrypoint_library_lto)
+
+# A rule to build a library from a collection of entrypoint objects and bundle
+# it in a single LLVM IR module.
+# Usage:
+#     add_bitcode_entrypoint_library(
+#       target_name
+#       base_target_name
+#       DEPENDS <list of add_entrypoint_object targets>
+#     )
+function(add_bitcode_entrypoint_library target_name base_target_name)
+  if(CMAKE_HOST_WIN32)
+    llvm_link_bitcode(${target_name}
+      OUTPUT ${LIBC_LIBRARY_DIR}/${target_name}.bc
+      INPUTS $<TARGET_FILE:${base_target_name}>
+      DEPENDS ${base_target_name}
+    )
+  else()
+    add_bitcode_entrypoint_library_lto(${target_name} ${base_target_name} ${ARGN})
+  endif()
 endfunction(add_bitcode_entrypoint_library)
 
 # A rule to build a library from a collection of entrypoint objects.
diff --git a/libc/lib/CMakeLists.txt b/libc/lib/CMakeLists.txt
index 8ef0329471521..0029dcabd3ac8 100644
--- a/libc/lib/CMakeLists.txt
+++ b/libc/lib/CMakeLists.txt
@@ -63,11 +63,19 @@ install(
 )
 
 foreach(file ${added_bitcode_targets})
-  install(FILES $<TARGET_FILE:${file}>
-          DESTINATION ${LIBC_INSTALL_LIBRARY_DIR}
-          RENAME $<TARGET_PROPERTY:${file},OUTPUT_NAME>
-          COMPONENT libc
-  )
+  if(CMAKE_HOST_WIN32)
+    install(FILES $<TARGET_PROPERTY:${file},TARGET_FILE>
+            DESTINATION ${LIBC_INSTALL_LIBRARY_DIR}
+            RENAME $<TARGET_PROPERTY:${file},OUTPUT_NAME>
+            COMPONENT libc
+    )
+  else()
+    install(FILES $<TARGET_FILE:${file}>
+            DESTINATION ${LIBC_INSTALL_LIBRARY_DIR}
+            RENAME $<TARGET_PROPERTY:${file},OUTPUT_NAME>
+            COMPONENT libc
+    )
+  endif()
 endforeach()
 
 # Add empty archive libraries for compatibility with systems expecting certain
diff --git a/libc/startup/gpu/CMakeLists.txt b/libc/startup/gpu/CMakeLists.txt
index 12cb891a687d8..cf7ea76a2ba8e 100644
--- a/libc/startup/gpu/CMakeLists.txt
+++ b/libc/startup/gpu/CMakeLists.txt
@@ -27,15 +27,23 @@ function(add_startup_object name)
       OUTPUT_NAME ${name}.o
   )
 
-  # Make an executable target of relocatable bitcode for clang if needed.
+  # Make a relocatable bitcode object for clang if needed.
   if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR)
-    add_executable(${fq_target_name}.exe $<TARGET_OBJECTS:${fq_target_name}>)
-    set_target_properties(${fq_target_name}.exe PROPERTIES
-      RUNTIME_OUTPUT_DIRECTORY ${LIBC_LIBRARY_DIR}
-      RUNTIME_OUTPUT_NAME ${name}.o)
-    target_link_options(${fq_target_name}.exe PRIVATE
-                        ${LIBC_COMPILE_OPTIONS_DEFAULT}
-                        "-r" "-nostdlib" "-flto" "-Wl,--lto-emit-llvm")
+    if(CMAKE_HOST_WIN32)
+      llvm_link_bitcode(${fq_target_name}.exe
+        OUTPUT ${LIBC_LIBRARY_DIR}/${name}.o
+        INPUTS $<TARGET_OBJECTS:${fq_target_name}>
+        DEPENDS ${fq_target_name}
+      )
+    else()
+      add_executable(${fq_target_name}.exe $<TARGET_OBJECTS:${fq_target_name}>)
+      set_target_properties(${fq_target_name}.exe PROPERTIES
+        RUNTIME_OUTPUT_DIRECTORY ${LIBC_LIBRARY_DIR}
+        RUNTIME_OUTPUT_NAME ${name}.o)
+      target_link_options(${fq_target_name}.exe PRIVATE
+                          ${LIBC_COMPILE_OPTIONS_DEFAULT}
+                          "-r" "-nostdlib" "-flto" "-Wl,--lto-emit-llvm")
+    endif()
   endif()
 endfunction()
 



More information about the libc-commits mailing list