xref: /aosp_15_r20/external/OpenCL-ICD-Loader/CMakeLists.txt (revision 1cddb830dba8aa7c1cc1039338e56b3b9fa24952)
1cmake_minimum_required (VERSION 3.1)
2
3# Include guard for including this project multiple times
4if(TARGET OpenCL)
5  return()
6endif()
7
8project (OpenCL-ICD-Loader
9    VERSION 1.2
10    LANGUAGES C)
11
12find_package (Threads REQUIRED)
13
14set(CMAKE_C_STANDARD 99)
15set(CMAKE_C_STANDARD_REQUIRED ON)
16# The option below allows building the ICD Loader library as a shared library
17# (ON, default) or a static library (OFF).
18#
19# Khronos OpenCL Working Group strongly recommends building and using the ICD
20# loader as a shared library due to the following benefits:
21#
22# 1. The shared library can be updated independent of the application. This
23#    allows releasing new fixes and features in the ICD loader without updating
24#    the application.
25#
26#    In rare cases when there are backward-incompatible changes to the ICD
27#    loader (due to platform requirements, for instance), using a shared
28#    library allows updating the library to make the transition seamless to
29#    installed applications.
30#
31# 2. On platforms that require the ICD mechanism there are multiple vendors
32#    shipping their OpenCL implementations. The vendor installers collaborate
33#    to make sure that the installed ICD shared library version is suitable for
34#    working with all vendor implementations installed on the system.
35#
36#    If applications statically link to ICD Loader then that version of the ICD
37#    loader may not work with one or more installed vendor implementations.
38#
39# Using the OpenCL ICD loader as a static library is NOT recommended for
40# end-user installations in general. However in some controlled environments it
41# may be useful to simplify the build and distribution of the application. E.g.
42# in test farms, or in cases where the end-user system configs are known in
43# advance. Use it with discretion.
44if(DEFINED BUILD_SHARED_LIBS)
45  set(OPENCL_ICD_LOADER_BUILD_SHARED_LIBS_DEFAULT ${BUILD_SHARED_LIBS})
46else()
47  set(OPENCL_ICD_LOADER_BUILD_SHARED_LIBS_DEFAULT ON)
48endif()
49  option(OPENCL_ICD_LOADER_BUILD_SHARED_LIBS "Build OpenCL ICD Loader as shared library" ${OPENCL_ICD_LOADER_BUILD_SHARED_LIBS_DEFAULT})
50
51# This option enables/disables support for OpenCL layers in the ICD loader.
52# It is currently needed default while the specification is being formalized,
53# and to study the performance impact.
54option (ENABLE_OPENCL_LAYERS "Enable OpenCL Layers" ON)
55include(CMakeDependentOption)
56cmake_dependent_option(ENABLE_OPENCL_LAYERINFO "Enable building cllayerinfo tool" ON ENABLE_OPENCL_LAYERS OFF)
57
58set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
59include(JoinPaths)
60
61include(CheckFunctionExists)
62check_function_exists(secure_getenv HAVE_SECURE_GETENV)
63check_function_exists(__secure_getenv HAVE___SECURE_GETENV)
64configure_file(${CMAKE_CURRENT_SOURCE_DIR}/loader/icd_cmake_config.h.in
65    ${CMAKE_CURRENT_BINARY_DIR}/icd_cmake_config.h)
66
67set (OPENCL_ICD_LOADER_SOURCES
68    loader/icd.c
69    loader/icd.h
70    loader/icd_version.h
71    loader/icd_dispatch.c
72    loader/icd_dispatch.h
73    loader/icd_dispatch_generated.c
74    loader/icd_envvars.h
75    loader/icd_platform.h)
76
77if (WIN32)
78    list (APPEND OPENCL_ICD_LOADER_SOURCES
79        loader/windows/adapter.h
80        loader/windows/icd_windows.c
81        loader/windows/icd_windows.h
82        loader/windows/icd_windows_dxgk.c
83        loader/windows/icd_windows_dxgk.h
84        loader/windows/icd_windows_envvars.c
85        loader/windows/icd_windows_hkr.c
86        loader/windows/icd_windows_hkr.h
87        loader/windows/icd_windows_apppackage.c
88        loader/windows/icd_windows_apppackage.h
89        loader/windows/OpenCL.rc)
90    # Only add the DXSDK include directory if the environment variable is
91    # defined.  Since the DXSDK has merged into the Windows SDK, this is
92    # only required in rare cases.
93    if (DEFINED ENV{DXSDK_DIR} AND NOT (MINGW OR MSYS OR CYGWIN))
94        include_directories ($ENV{DXSDK_DIR}/Include)
95    endif ()
96
97    # For mingw-i686 builds only we need a special .def file with stdcall
98    # exports.  In all other cases we can use a standard .def file.
99    if ((CMAKE_SIZEOF_VOID_P EQUAL 4) AND (MINGW OR MSYS OR CYGWIN))
100        list (APPEND OPENCL_ICD_LOADER_SOURCES loader/windows/OpenCL-mingw-i686.def)
101    else ()
102        list (APPEND OPENCL_ICD_LOADER_SOURCES loader/windows/OpenCL.def)
103    endif ()
104else ()
105    list (APPEND OPENCL_ICD_LOADER_SOURCES
106        loader/linux/icd_linux.c
107        loader/linux/icd_linux_envvars.c
108        loader/linux/icd_exports.map)
109endif ()
110
111set (OPENCL_ICD_LOADER_HEADERS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/inc" CACHE PATH "Path to OpenCL Headers")
112
113if (${OPENCL_ICD_LOADER_BUILD_SHARED_LIBS})
114  add_library (OpenCL SHARED ${OPENCL_ICD_LOADER_SOURCES})
115else()
116  add_library (OpenCL STATIC ${OPENCL_ICD_LOADER_SOURCES})
117endif()
118
119add_library (OpenCL::OpenCL ALIAS OpenCL)
120
121set_target_properties (OpenCL PROPERTIES VERSION "1.2" SOVERSION "1")
122
123if (WIN32)
124    target_link_libraries (OpenCL PRIVATE cfgmgr32.lib runtimeobject.lib)
125
126    # Generate a DLL without a "lib" prefix for mingw.
127    if (MINGW OR MSYS OR CYGWIN)
128        set_target_properties(OpenCL PROPERTIES PREFIX "")
129        set_target_properties(OpenCL PROPERTIES LINK_FLAGS "-Wl,-disable-stdcall-fixup")
130    endif()
131else()
132    target_link_libraries (OpenCL PRIVATE ${CMAKE_THREAD_LIBS_INIT})
133    if (NOT APPLE)
134        set_target_properties (OpenCL PROPERTIES LINK_FLAGS "-Wl,--version-script -Wl,${CMAKE_CURRENT_SOURCE_DIR}/loader/linux/icd_exports.map")
135        if (OPENCL_ICD_LOADER_PIC)
136            set_target_properties(OpenCL PROPERTIES POSITION_INDEPENDENT_CODE ON)
137        endif ()
138    endif ()
139endif ()
140
141if (EXISTS ${OPENCL_ICD_LOADER_HEADERS_DIR}/CL/cl.h)
142    message (STATUS "Defining OpenCL::Headers through OPENCL_ICD_LOADER_HEADERS_DIR")
143    add_library (OpenCLHeaders INTERFACE)
144    add_library (OpenCL::Headers ALIAS OpenCLHeaders)
145    target_include_directories (OpenCLHeaders INTERFACE ${OPENCL_ICD_LOADER_HEADERS_DIR})
146    target_include_directories (OpenCL PUBLIC $<BUILD_INTERFACE:${OPENCL_ICD_LOADER_HEADERS_DIR}>)
147else ()
148    if (NOT TARGET OpenCL::Headers)
149        find_package (OpenCLHeaders REQUIRED)
150    endif ()
151    target_link_libraries (OpenCL PUBLIC OpenCL::Headers)
152endif ()
153
154set (OPENCL_COMPILE_DEFINITIONS
155    CL_TARGET_OPENCL_VERSION=300
156    CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES
157    OPENCL_ICD_LOADER_VERSION_MAJOR=3
158    OPENCL_ICD_LOADER_VERSION_MINOR=0
159    OPENCL_ICD_LOADER_VERSION_REV=6
160    $<$<BOOL:${ENABLE_OPENCL_LAYERS}>:CL_ENABLE_LAYERS>
161)
162
163target_compile_definitions (OpenCL
164  PRIVATE
165    ${OPENCL_COMPILE_DEFINITIONS}
166)
167
168target_include_directories (OpenCL
169  PRIVATE
170    ${CMAKE_CURRENT_BINARY_DIR}
171    loader
172)
173target_link_libraries (OpenCL PUBLIC ${CMAKE_DL_LIBS})
174
175if (ENABLE_OPENCL_LAYERINFO)
176
177  set (OPENCL_LAYER_INFO_SOURCES
178      loader/cllayerinfo.c
179      ${OPENCL_ICD_LOADER_SOURCES}
180  )
181
182  add_executable(cllayerinfo ${OPENCL_LAYER_INFO_SOURCES})
183
184  add_executable(OpenCL::cllayerinfo ALIAS cllayerinfo)
185
186  target_compile_definitions (cllayerinfo
187    PRIVATE
188      CL_LAYER_INFO
189      ${OPENCL_COMPILE_DEFINITIONS}
190  )
191
192  if (EXISTS ${OPENCL_ICD_LOADER_HEADERS_DIR}/CL/cl.h)
193      target_include_directories (cllayerinfo PUBLIC $<BUILD_INTERFACE:${OPENCL_ICD_LOADER_HEADERS_DIR}>)
194  else ()
195      target_link_libraries (cllayerinfo PUBLIC OpenCL::Headers)
196  endif ()
197
198  if (WIN32)
199    target_link_libraries (cllayerinfo PRIVATE cfgmgr32.lib runtimeobject.lib)
200  else ()
201    target_link_libraries (cllayerinfo PRIVATE ${CMAKE_THREAD_LIBS_INIT})
202  endif ()
203
204  target_link_libraries (cllayerinfo PUBLIC ${CMAKE_DL_LIBS})
205
206  target_include_directories (cllayerinfo
207    PRIVATE
208      ${CMAKE_CURRENT_BINARY_DIR}
209      loader
210  )
211endif ()
212
213option (OPENCL_ICD_LOADER_BUILD_TESTING "Enable support for OpenCL ICD Loader testing." OFF)
214
215if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR OPENCL_ICD_LOADER_BUILD_TESTING)
216    include(CTest)
217endif()
218if((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR OPENCL_ICD_LOADER_BUILD_TESTING) AND BUILD_TESTING)
219    add_subdirectory (test)
220endif()
221
222include (GNUInstallDirs)
223
224install(
225  TARGETS OpenCL
226  EXPORT OpenCLICDLoaderTargets
227  LIBRARY
228    DESTINATION ${CMAKE_INSTALL_LIBDIR} # obtained from GNUInstallDirs
229)
230install(
231# FILES $<TARGET_PDB_FILE:OpenCL> is cleanest, but is MSVC link.exe specific. LLVM's lld.exe and lld-link.exe don't support it (configure-time error)
232# FILES $<TARGET_PROPERTY:OpenCL,COMPILE_PDB_OUTPUT_DIRECTORY>/OpenCL.pdb looks OK, but even though there's a PDB, this prop is empty on non-MSVC toolchains
233  FILES $<TARGET_FILE_DIR:OpenCL>/OpenCL.pdb # is the most implicit (expect PDB be next to the library), yet the only one that universally works
234  DESTINATION ${CMAKE_INSTALL_BINDIR}
235  OPTIONAL
236)
237
238if (ENABLE_OPENCL_LAYERINFO)
239  install(
240    TARGETS cllayerinfo
241    EXPORT OpenCLICDLoaderTargets
242    RUNTIME
243      DESTINATION ${CMAKE_INSTALL_BINDIR}
244  )
245endif()
246
247export(
248  EXPORT OpenCLICDLoaderTargets
249  FILE ${PROJECT_BINARY_DIR}/OpenCLICDLoader/OpenCLICDLoaderTargets.cmake
250  NAMESPACE OpenCL::
251)
252file(
253  WRITE ${PROJECT_BINARY_DIR}/OpenCLICDLoader/OpenCLICDLoaderConfig.cmake
254  "include(\"\${CMAKE_CURRENT_LIST_DIR}/OpenCLICDLoaderTargets.cmake\")"
255)
256
257set(config_package_location ${CMAKE_INSTALL_DATADIR}/cmake/OpenCLICDLoader)
258install(
259  EXPORT OpenCLICDLoaderTargets
260  FILE OpenCLICDLoaderTargets.cmake
261  NAMESPACE OpenCL::
262  DESTINATION ${config_package_location}
263)
264install(
265  FILES ${CMAKE_CURRENT_BINARY_DIR}/OpenCLICDLoader/OpenCLICDLoaderConfig.cmake
266  DESTINATION ${config_package_location}
267)
268
269unset(CMAKE_SIZEOF_VOID_P)
270include(CMakePackageConfigHelpers)
271write_basic_package_version_file(
272  ${CMAKE_CURRENT_BINARY_DIR}/OpenCLICDLoader/OpenCLICDLoaderConfigVersion.cmake
273  VERSION ${PROJECT_VERSION}
274  COMPATIBILITY AnyNewerVersion
275)
276install(
277  FILES ${CMAKE_CURRENT_BINARY_DIR}/OpenCLICDLoader/OpenCLICDLoaderConfigVersion.cmake
278  DESTINATION ${config_package_location}
279)
280
281install (TARGETS OpenCL
282    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
283    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
284    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
285
286join_paths(OPENCL_LIBDIR_PC "\${exec_prefix}" "${CMAKE_INSTALL_LIBDIR}")
287join_paths(OPENCL_INCLUDEDIR_PC "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
288
289if (NOT MSVC)
290  configure_file(OpenCL.pc.in OpenCL.pc @ONLY)
291  set(pkg_config_location ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
292  install(
293    FILES ${CMAKE_CURRENT_BINARY_DIR}/OpenCL.pc
294    DESTINATION ${pkg_config_location})
295endif()
296