1set(OPENCL_HEADERS_INCLUDE_DIR_GENEXPR $<TARGET_PROPERTY:OpenCL::Headers,INTERFACE_INCLUDE_DIRECTORIES>) 2############################### 3### ### 4### Workaround to CMake bug ### 5### ### 6############################### 7# 8# The generated mocks\Mockcl.h include the OpenCL headers as 9# 10# #include "CL/cl_platform.h" 11# #include "cl.h" 12# 13# which requires the tests to not only inherit the INTERFACE_INCLUDE_DIRECTORIES, but also the same dir with 14# /CL appended at the end. There seems to be a bug in CMake (3.19 even) where if a target has the same genexpr 15# predicate twice, the second time it always fails. Having both 16# 17# $<TARGET_PROPERTY:Headers,INTERFACE_INCLUDE_DIRECTORIES> (invisbly via linking to OpenCL::Headers) 18# $<TARGET_PROPERTY:Headers,INTERFACE_INCLUDE_DIRECTORIES>/CL 19# 20# means we can only get one of these switches. We forcibly go around it by extracting the value manually. 21# 22# Bug ticket: https://gitlab.kitware.com/cmake/cmake/-/issues/22735 23# 24# ticket closed with by-design. We should find a way to fix the Mock tests to not consume the public API using 25# mixed style includes. 26get_target_property(OPENCL_HEADERS_INTERFACE_INCLUDE_DIRECTORIES OpenCL::Headers INTERFACE_INCLUDE_DIRECTORIES) 27 28if(OPENCL_HEADERS_INTERFACE_INCLUDE_DIRECTORIES MATCHES "BUILD_INTERFACE") 29 # When building OpenCL::Headers is part of this build (OpenCL-SDK), we have a property like for eg. 30 # $<BUILD_INTERFACE:C:/OpenCL-SDK/external/OpenCL-Headers>;$<INSTALL_INTERFACE:include> 31 # and need to touch up this property. We want the BUILD_INTERFACE part only. 32 # When OpenCL::Headers is consumed through a Package Config file (OpenCL-CLHPP), this property 33 # no longer holds unevaluated generator expressions. 34 string(REGEX MATCHALL 35 [[\$<BUILD_INTERFACE:(.*)>;]] 36 OPENCL_HEADERS_INTERFACE_INCLUDE_DIRECTORIES 37 "${OPENCL_HEADERS_INTERFACE_INCLUDE_DIRECTORIES}") 38 set(OPENCL_HEADERS_INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_MATCH_1}") 39endif() 40# End of workaround 41 42add_custom_command( 43 OUTPUT stripped/cl.h stripped/cl_ext.h stripped/cl_gl.h 44 COMMAND ${CMAKE_COMMAND} -E make_directory stripped 45 COMMAND ${CMAKE_COMMAND} -E make_directory mocks 46 COMMAND ${CMAKE_COMMAND} -D INPUT="${OPENCL_HEADERS_INTERFACE_INCLUDE_DIRECTORIES}/CL/cl.h" -D OUTPUT="stripped/cl.h" -P ${CMAKE_CURRENT_SOURCE_DIR}/strip_defines.cmake 47 COMMAND ${CMAKE_COMMAND} -D INPUT="${OPENCL_HEADERS_INTERFACE_INCLUDE_DIRECTORIES}/CL/cl_ext.h" -D OUTPUT="stripped/cl_ext.h" -P ${CMAKE_CURRENT_SOURCE_DIR}/strip_defines.cmake 48 COMMAND ${CMAKE_COMMAND} -D INPUT="${OPENCL_HEADERS_INTERFACE_INCLUDE_DIRECTORIES}/CL/cl_gl.h" -D OUTPUT="stripped/cl_gl.h" -P ${CMAKE_CURRENT_SOURCE_DIR}/strip_defines.cmake 49 COMMENT "Stripping defines from cl.h, cl_ext.h and cl_gl.h" 50 DEPENDS ${OPENCL_HEADERS_INTERFACE_INCLUDE_DIRECTORIES}/CL/cl.h strip_defines.cmake) 51 52add_custom_target( 53 strip_cl_defines ALL 54 DEPENDS stripped/cl.h 55 DEPENDS stripped/cl_ext.h 56 DEPENDS stripped/cl_gl.h 57 SOURCES strip_defines.cmake) 58 59add_custom_command( 60 OUTPUT mocks/Mockcl.c mocks/Mockcl.h mocks/Mockcl_ext.c mocks/Mockcl_ext.h mocks/Mockcl_gl.c mocks/Mockcl_gl.h 61 COMMAND ${RUBY_EXECUTABLE} ${CMOCK_DIR}/lib/cmock.rb -o${CMAKE_CURRENT_SOURCE_DIR}/cmock.yml stripped/cl.h 62 COMMAND ${RUBY_EXECUTABLE} ${CMOCK_DIR}/lib/cmock.rb -o${CMAKE_CURRENT_SOURCE_DIR}/cmock.yml stripped/cl_ext.h 63 COMMAND ${RUBY_EXECUTABLE} ${CMOCK_DIR}/lib/cmock.rb -o${CMAKE_CURRENT_SOURCE_DIR}/cmock.yml stripped/cl_gl.h 64 COMMENT "Generating mocks" 65 DEPENDS stripped/cl.h stripped/cl_ext.h stripped/cl_gl.h cmock.yml) 66 67add_custom_target( 68 mock_cl_header ALL 69 DEPENDS mocks/Mockcl.c mocks/Mockcl.h 70 DEPENDS mocks/Mockcl_ext.c mocks/Mockcl_ext.h 71 DEPENDS mocks/Mockcl_gl.c mocks/Mockcl_gl.h 72 SOURCES cmock.yml) 73 74add_dependencies(mock_cl_header strip_cl_defines) 75 76add_custom_command( 77 OUTPUT test_openclhpp_Runner.c 78 COMMAND ${RUBY_EXECUTABLE} ${UNITY_DIR}/auto/generate_test_runner.rb test_openclhpp.cpp cmock.yml ${CMAKE_CURRENT_BINARY_DIR}/test_openclhpp_Runner.c 79 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 80 COMMENT "Generating test runner" 81 DEPENDS test_openclhpp.cpp cmock.yml) 82 83add_custom_target( 84 openclhpp_runner ALL 85 DEPENDS test_openclhpp_Runner.c 86 SOURCES test_openclhpp.cpp) 87 88if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?Clang") 89 add_compile_options(-Wno-deprecated-declarations) 90elseif(MSVC) 91 add_compile_options(/wd4996) 92endif() 93 94add_definitions(-DCL_TARGET_OPENCL_VERSION=300) 95add_definitions(-DCL_EXPERIMENTAL) 96 97add_definitions(-DUNITY_SUPPORT_64) 98if( CMAKE_SIZEOF_VOID_P EQUAL 8 ) 99 add_definitions(-DUNITY_POINTER_WIDTH=64) 100 add_definitions("-DCMOCK_MEM_PTR_AS_INT=unsigned long long") 101 add_definitions(-DCMOCK_MEM_ALIGN=3) 102endif() 103if( CMAKE_SIZEOF_LONG EQUAL 8 ) 104 add_definitions(-DUNITY_LONG_WIDTH=64) 105endif() 106 107set(TEST_HEADERS 108 ${PROJECT_SOURCE_DIR}/include/CL/opencl.hpp 109 mocks/Mockcl.h 110 mocks/Mockcl_ext.h 111 mocks/Mockcl_gl.h) 112 113set(TEST_SOURCES 114 ${CMAKE_CURRENT_BINARY_DIR}/test_openclhpp_Runner.c 115 test_openclhpp.cpp 116 ${CMAKE_CURRENT_BINARY_DIR}/mocks/Mockcl.c 117 ${CMAKE_CURRENT_BINARY_DIR}/mocks/Mockcl_ext.c 118 ${CMAKE_CURRENT_BINARY_DIR}/mocks/Mockcl_gl.c 119 ${CMOCK_DIR}/src/cmock.c 120 ${UNITY_DIR}/src/unity.c) 121 122# TODO enable testing for OpenCL 1.0 and 1.1 123foreach(VERSION 120 200 210 220 300) 124 foreach(OPTION "" CL_HPP_ENABLE_EXCEPTIONS CL_HPP_ENABLE_SIZE_T_COMPATIBILITY CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY CL_HPP_CL_1_2_DEFAULT_BUILD CL_HPP_USE_CL_SUB_GROUPS_KHR CL_HPP_USE_IL_KHR) 125 if(OPTION STREQUAL "") 126 # The empty string means we're not setting any special option. 127 set(UNDERSCORE_OPTION "${OPTION}") 128 set(DEFINE_OPTION "") 129 else() 130 set(UNDERSCORE_OPTION "_${OPTION}") 131 set(DEFINE_OPTION "-D${OPTION}") 132 endif() 133 134 set(TEST_EXE test_openclhpp_${VERSION}${UNDERSCORE_OPTION}) 135 add_executable(${TEST_EXE} ${TEST_SOURCES}) #${TEST_HEADERS}) 136 target_link_libraries(${TEST_EXE} 137 PRIVATE 138 OpenCL::HeadersCpp 139 OpenCL::Headers 140 Threads::Threads 141 ) 142 target_include_directories(${TEST_EXE} 143 PRIVATE 144 ${CMAKE_CURRENT_BINARY_DIR}/mocks 145 146 ${OPENCL_HEADERS_INTERFACE_INCLUDE_DIRECTORIES}/CL 147 #${OPENCL_HEADERS_INCLUDE_DIR_GENEXPR}/CL 148 149 ${UNITY_DIR}/src 150 ${CMOCK_DIR}/src 151 ) 152 target_compile_definitions(${TEST_EXE} 153 PUBLIC -DCL_HPP_TARGET_OPENCL_VERSION=${VERSION} ${DEFINE_OPTION} 154 ) 155 add_dependencies(${TEST_EXE} 156 strip_cl_defines 157 mock_cl_header 158 openclhpp_runner 159 ) 160 add_test(NAME ${TEST_EXE} COMMAND ${TEST_EXE}) 161 endforeach(OPTION) 162endforeach(VERSION) 163 164if(NOT TARGET OpenCL::openCL) 165 find_package(OpenCLICDLoader) 166endif() 167if(TARGET OpenCL::OpenCL) 168 # TODO enable testing for OpenCL 1.0 and 1.1 169 foreach(MINVERSION 120 200 210 220 300) 170 foreach(TARGETVERSION 120 200 210 220 300) 171 if(NOT (${MINVERSION} GREATER ${TARGETVERSION})) 172 set(TEST_EXE test_openclhpp_version_min_${MINVERSION}_target_${TARGETVERSION}) 173 add_executable(${TEST_EXE} test_versions.cpp) 174 target_compile_definitions(${TEST_EXE} PUBLIC 175 CL_HPP_MINIMUM_OPENCL_VERSION=${MINVERSION} 176 CL_HPP_TARGET_OPENCL_VERSION=${TARGETVERSION}) 177 target_link_libraries(${TEST_EXE} PRIVATE 178 OpenCL::HeadersCpp 179 OpenCL::Headers 180 OpenCL::OpenCL) 181 add_test(NAME ${TEST_EXE} COMMAND ${TEST_EXE}) 182 endif() 183 endforeach() 184 endforeach() 185endif()