[libclc] Add custom CMake language handling for OpenCL files (#185243)

Summary:
The current handling of `libclc` is to use custom clang jobs to compile
source files. This is the way we used to compile GPU libraries, but we
have largely moved away from this. The eventual goal is to simple be
able to use `clang` like a normal project. One barrier to this is the
lack of language support for OpenCL in CMake.

This PR uses CMake's custom language support to define a minimal OpenCL
language, largely just a wrapper around `clang -x cl`. This does
nothing, just enables the support. Future PRs will need to untangle the
mess of dependencies.

The 'link+opt' steps that we now do should be able to simply be done as
a custom `llvm-link` and `opt` job on the library, which isn't ideal but
it still better than the current state.
This commit is contained in:
Joseph Huber 2026-03-07 22:34:17 -06:00 committed by GitHub
parent b883091bad
commit 088f740035
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 94 additions and 0 deletions

View File

@ -10,6 +10,8 @@ set(CMAKE_CXX_STANDARD 17)
# Add path for custom modules
list( INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" )
enable_language( CLC )
set( LIBCLC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )
set( LIBCLC_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} )
set( LIBCLC_OBJFILE_DIR ${LIBCLC_BINARY_DIR}/obj.libclc.dir )

View File

@ -0,0 +1,13 @@
set(CMAKE_CLC_COMPILER "@CMAKE_CLC_COMPILER@")
set(CMAKE_CLC_COMPILER_ID "@CMAKE_CLC_COMPILER_ID@")
set(CMAKE_CLC_COMPILER_LOADED 1)
set(CMAKE_CLC_COMPILER_WORKS @CMAKE_CLC_COMPILER_WORKS@)
set(CMAKE_CLC_COMPILER_ENV_VAR "CLC")
set(CMAKE_CLC_COMPILER_ID_RUN 1)
set(CMAKE_CLC_SOURCE_FILE_EXTENSIONS cl)
set(CMAKE_CLC_LINKER_PREFERENCE 0)
set(CMAKE_CLC_LINKER_PREFERENCE_PROPAGATES 0)

View File

@ -0,0 +1 @@
kernel void __test_clc(global int *out) { *out = 0; }

View File

@ -0,0 +1,26 @@
set(CMAKE_CLC_OUTPUT_EXTENSION .o)
set(CMAKE_INCLUDE_FLAG_CLC "-I")
set(CMAKE_CLC_DEPFILE_FORMAT gcc)
set(CMAKE_DEPFILE_FLAGS_CLC "-MD -MT <DEP_TARGET> -MF <DEP_FILE>")
cmake_initialize_per_config_variable(CMAKE_CLC_FLAGS "Flags used by the CLC compiler")
if(NOT CMAKE_CLC_COMPILE_OBJECT)
set(CMAKE_CLC_COMPILE_OBJECT
"<CMAKE_CLC_COMPILER> -x cl <DEFINES> <INCLUDES> <FLAGS> -c -o <OBJECT> <SOURCE>")
endif()
if(NOT DEFINED CMAKE_CLC_ARCHIVE_CREATE)
set(CMAKE_CLC_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_CLC_ARCHIVE_APPEND)
set(CMAKE_CLC_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_CLC_ARCHIVE_FINISH)
set(CMAKE_CLC_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
endif()
set(CMAKE_CLC_USE_LINKER_INFORMATION FALSE)
set(CMAKE_CLC_INFORMATION_LOADED 1)

View File

@ -0,0 +1,18 @@
if(NOT CMAKE_CLC_COMPILER)
if(NOT CMAKE_C_COMPILER_ID MATCHES "Clang")
message(FATAL_ERROR
"The CLC language requires the C compiler (CMAKE_C_COMPILER) to be "
"Clang, but CMAKE_C_COMPILER_ID is '${CMAKE_C_COMPILER_ID}'.")
endif()
set(CMAKE_CLC_COMPILER "${CMAKE_C_COMPILER}" CACHE FILEPATH "CLC compiler")
endif()
mark_as_advanced(CMAKE_CLC_COMPILER)
set(CMAKE_CLC_COMPILER_ID "Clang")
set(CMAKE_CLC_COMPILER_ID_RUN TRUE)
configure_file(${CMAKE_CURRENT_LIST_DIR}/CMakeCLCCompiler.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeCLCCompiler.cmake @ONLY)
set(CMAKE_CLC_COMPILER_ENV_VAR "CLC")

View File

@ -0,0 +1,34 @@
configure_file(${CMAKE_CURRENT_LIST_DIR}/CMakeCLCCompiler.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeCLCCompiler.cmake @ONLY)
include(${CMAKE_PLATFORM_INFO_DIR}/CMakeCLCCompiler.cmake)
if(CMAKE_CLC_COMPILER_FORCED)
set(CMAKE_CLC_COMPILER_WORKS TRUE)
return()
endif()
set(_test_file "${CMAKE_CURRENT_LIST_DIR}/CMakeCLCCompilerTest.cl")
set(_test_dir "${CMAKE_PLATFORM_INFO_DIR}/CMakeTmp")
set(_test_out "${_test_dir}/test_clc.o")
file(MAKE_DIRECTORY "${_test_dir}")
message(STATUS "Check for working CLC compiler: ${CMAKE_CLC_COMPILER}")
execute_process(
COMMAND "${CMAKE_CLC_COMPILER}" -x cl -c -flto
-o "${_test_out}" "${_test_file}"
RESULT_VARIABLE _clc_result
ERROR_VARIABLE _clc_error
)
if(_clc_result EQUAL 0)
set(CMAKE_CLC_COMPILER_WORKS TRUE)
message(STATUS "Check for working CLC compiler: ${CMAKE_CLC_COMPILER} - works")
file(REMOVE "${_test_out}")
else()
message(FATAL_ERROR
"The CLC compiler\n"
" ${CMAKE_CLC_COMPILER}\n"
"is not able to compile a simple OpenCL test program.\n"
"Output:\n${_clc_error}")
endif()