xref: /aosp_15_r20/external/OpenCL-CLHPP/tests/CMakeLists.txt (revision 6fee86a4f833e4f32f25770a262884407554133d)
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()