admin管理员组

文章数量:1123063

Faced with strange issue with cmake detection of OpenCL. When I use the following CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)

# Uncomment to make it working
# include(CheckSymbolExists)

# CHECK_SYMBOL_EXISTS(
#     CL_VERSION_3_0
#     "${OPENCL_INCLUDE_DIR}/CL/cl_version.h"
#     OPENCL_VERSION_3_0)

# message(STATUS "OPENCL_VERSION_3_0 = ${OPENCL_VERSION_3_0}")

set(CMAKE_REQUIRED_INCLUDES ${OPENCL_INCLUDE_DIR})
find_package(OpenCL REQUIRED)

message(STATUS "OpenCL_FOUND = ${OpenCL_FOUND}")
message(STATUS "OpenCL_INCLUDE_DIRS = ${OpenCL_INCLUDE_DIRS}")
message(STATUS "OpenCL_LIBRARIES = ${OpenCL_LIBRARIES}")
message(STATUS "OpenCL_VERSION_STRING = ${OpenCL_VERSION_STRING}")
message(STATUS "OpenCL_VERSION_MAJOR = ${OpenCL_VERSION_MAJOR}")
message(STATUS "OpenCL_VERSION_MINOR = ${OpenCL_VERSION_MINOR}")

add_executable(TestOpenCL test_symbol.c)
target_link_libraries(TestOpenCL PUBLIC OpenCL::OpenCL)

It cannot detect OpenCL_VERSION_STRING, this variable is empty. But when I uncomment lines in it, find_package(OpenCL REQUIRED) finally could detect it properly

It is very starange for me, because underhood FindOpenCL.cmake use CHECK_SYMBOL_EXISTS, but it cannot compile simple program, I've debugged it:

Run Build Command(s): /opt/cmake-3.30.2-linux-x86_64/bin/cmake -E env VERBOSE=1 /usr/bin/gmake -f Makefile cmTC_38492/fast
/usr/bin/gmake  -f CMakeFiles/cmTC_38492.dir/build.make CMakeFiles/cmTC_38492.dir/build
gmake[1]: Entering directory '<home_dir>/test_opencl/build/CMakeFiles/CMakeScratch/TryCompile-U9cXep'
Building C object CMakeFiles/cmTC_38492.dir/CheckSymbolExists.c.o
/usr/bin/cc    -o CMakeFiles/cmTC_38492.dir/CheckSymbolExists.c.o -c <home_dir>/test_opencl/build/CMakeFiles/CMakeScratch/TryCompile-U9cXep/CheckSymbolExists.c
In file included from /usr/include/CL/cl.h:20,
                 from <home_dir>/test_opencl/build/CMakeFiles/CMakeScratch/TryCompile-U9cXep/CheckSymbolExists.c:2:
/usr/include/CL/cl_version.h:22:9: note: ‘#pragma message: cl_version.h: CL_TARGET_OPENCL_VERSION is not defined. Defaulting to 300 (OpenCL 3.0)’
   22 | #pragma message("cl_version.h: CL_TARGET_OPENCL_VERSION is not defined. Defaulting to 300 (OpenCL 3.0)")
      |         ^~~~~~~
In file included from <home_dir>/test_opencl/build/CMakeFiles/CMakeScratch/TryCompile-U9cXep/CheckSymbolExists.c:2:
/usr/include/CL/cl.h:1314:21: error: unknown type name ‘CL_API_PREFIX__VERSION_2_2_DEPRECATED’
 1314 | extern CL_API_ENTRY CL_API_PREFIX__VERSION_2_2_DEPRECATED cl_int CL_API_CALL
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1315:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘clSetProgramReleaseCallback’
 1315 | clSetProgramReleaseCallback(cl_program          program,
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1864:21: error: unknown type name ‘CL_API_PREFIX__VERSION_1_1_DEPRECATED’
 1864 | extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1865:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘clCreateImage2D’
 1865 | clCreateImage2D(cl_context              context,
      | ^~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1874:21: error: unknown type name ‘CL_API_PREFIX__VERSION_1_1_DEPRECATED’
 1874 | extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1875:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘clCreateImage3D’
 1875 | clCreateImage3D(cl_context              context,
      | ^~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1886:21: error: unknown type name ‘CL_API_PREFIX__VERSION_1_1_DEPRECATED’
 1886 | extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1887:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘clEnqueueMarker’
 1887 | clEnqueueMarker(cl_command_queue    command_queue,
      | ^~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1890:21: error: unknown type name ‘CL_API_PREFIX__VERSION_1_1_DEPRECATED’
 1890 | extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1891:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘clEnqueueWaitForEvents’
 1891 | clEnqueueWaitForEvents(cl_command_queue  command_queue,
      | ^~~~~~~~~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1895:21: error: unknown type name ‘CL_API_PREFIX__VERSION_1_1_DEPRECATED’
 1895 | extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1896:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘clEnqueueBarrier’
 1896 | clEnqueueBarrier(cl_command_queue command_queue) CL_API_SUFFIX__VERSION_1_1_DEPRECATED;
      | ^~~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1898:21: error: unknown type name ‘CL_API_PREFIX__VERSION_1_1_DEPRECATED’
 1898 | extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1899:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘clUnloadCompiler’
 1899 | clUnloadCompiler(void) CL_API_SUFFIX__VERSION_1_1_DEPRECATED;
      | ^~~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1901:58: error: expected ‘;’ before ‘void’
 1901 | extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_1_DEPRECATED void * CL_API_CALL
      |                                                          ^~~~~
      |                                                          ;
/usr/include/CL/cl.h: In function ‘clGetExtensionFunctionAddress’:
/usr/include/CL/cl.h:1902:55: error: expected declaration specifiers before ‘CL_API_SUFFIX__VERSION_1_1_DEPRECATED’
 1902 | clGetExtensionFunctionAddress(const char * func_name) CL_API_SUFFIX__VERSION_1_1_DEPRECATED;
      |                                                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1905:21: error: unknown type name ‘CL_API_PREFIX__VERSION_1_2_DEPRECATED’
 1905 | extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_2_DEPRECATED cl_command_queue CL_API_CALL
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1906:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘clCreateCommandQueue’
 1906 | clCreateCommandQueue(cl_context                     context,
      | ^~~~~~~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1911:21: error: unknown type name ‘CL_API_PREFIX__VERSION_1_2_DEPRECATED’
 1911 | extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_2_DEPRECATED cl_sampler CL_API_CALL
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1912:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘clCreateSampler’
 1912 | clCreateSampler(cl_context          context,
      | ^~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1918:21: error: unknown type name ‘CL_API_PREFIX__VERSION_1_2_DEPRECATED’
 1918 | extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_2_DEPRECATED cl_int CL_API_CALL
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/CL/cl.h:1919:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘clEnqueueTask’
 1919 | clEnqueueTask(cl_command_queue  command_queue,
      | ^~~~~~~~~~~~~
<home_dir>/test_opencl/build/CMakeFiles/CMakeScratch/TryCompile-U9cXep/CheckSymbolExists.c:5:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
    5 | {

It is pretty strange how it works ... Why in CMakeLists.txt it works, but under FindOpenCL.cmake it got the compilation error, even thoguht OPENCL_INCLUDE_DIR was provided as "-DOPENCL_INCLUDE_DIR=/usr/include"

What even more strange, that the if I add the following function, it properly detects version of OpenCL:

function(_FIND_OPENCL_VERSION)
  foreach(VERSION "3_0" "2_2" "2_1" "2_0" "1_2" "1_1" "1_0")
    # Write the test program to check OpenCL
    set(SOURCE_CODE
      "
      #include <CL/cl.h>
      #ifndef CL_VERSION_${VERSION}
      #error \"CL_VERSION_${VERSION} is not defined\"
      #endif

      int main() {
        return 0\;
      }
      ")

    # Create a temporary directory for the test
    set(TEST_DIR "${CMAKE_BINARY_DIR}/CheckOpenCLSymbol")
    file(MAKE_DIRECTORY ${TEST_DIR})

    # Write the test program to a file
    set(TEST_SOURCE "${TEST_DIR}/test_opencl_symbol.c")
    file(WRITE ${TEST_SOURCE} ${SOURCE_CODE})
    file(WRITE "${TEST_DIR}/CMakeLists.txt" 
      "
      cmake_minimum_required(VERSION 3.8)

      project(CheckOpenCLSymbol)

      add_executable(TestOpenCL test_opencl_symbol.c)
      target_include_directories(TestOpenCL PUBLIC ${OpenCL_INCLUDE_DIR})
      target_link_libraries(TestOpenCL PUBLIC ${OpenCL_LIBRARIES})
      ")

    # Use try_compile to check if the symbol exists
    try_compile(
      COMPILE_RESULT
      PROJECT "CheckOpenCLSymbol"
      SOURCE_DIR ${TEST_DIR}
      BINARY_DIR ${TEST_DIR}
      OUTPUT_VARIABLE CONSOLOE_OUTPUT
    )

    # Clean up temporary directory
    file(REMOVE_RECURSE ${TEST_DIR})

    # Output the result
    if(COMPILE_RESULT)
      set(OPENCL_VERSION_${VERSION} ${VERSION})
    else()
      set(OPENCL_VERSION_${VERSION} "")
    endif()
    
    message(STATUS "CONSOLOE_OUTPUT = ${CONSOLOE_OUTPUT}")
    if(OPENCL_VERSION_${VERSION})
    message(STATUS "OPENCL_VERSION_${VERSION} is FOUND !!!!!")
      string(REPLACE "_" "." VERSION "${VERSION}")
      set(OpenCL_VERSION_STRING ${VERSION} PARENT_SCOPE)
      string(REGEX MATCHALL "[0-9]+" version_components "${VERSION}")
      list(GET version_components 0 major_version)
      list(GET version_components 1 minor_version)
      set(OpenCL_VERSION_MAJOR ${major_version} PARENT_SCOPE)
      set(OpenCL_VERSION_MINOR ${minor_version} PARENT_SCOPE)
      break()
    endif()
  endforeach()
endfunction()

Also one strange this, this works and find properly symbol:

CHECK_SYMBOL_EXISTS(
    CL_VERSION_3_0
    "CL/cl.h"
    OPENCL_VERSION_3_0)

but this one cannot compile:

CHECK_SYMBOL_EXISTS(
    CL_VERSION_3_0
    "/usr/include/CL/cl.h"
    OPENCL_VERSION_3_0)

Have somebody faced with similar issues ??

本文标签: cmakeCannot detect OpenCL 30 for NVIDIA GPUStack Overflow