• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1cmake_minimum_required (VERSION 3.16)
2
3# Include guard for including this project multiple times
4if(TARGET OpenCL)
5  return()
6endif()
7
8project (OpenCL-ICD-Loader
9    VERSION 3.0
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()
49option(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
58include(GNUInstallDirs)
59
60set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
61include(CheckFunctionExists)
62include(JoinPaths)
63include(Package)
64
65check_function_exists(secure_getenv HAVE_SECURE_GETENV)
66check_function_exists(__secure_getenv HAVE___SECURE_GETENV)
67configure_file(${CMAKE_CURRENT_SOURCE_DIR}/loader/icd_cmake_config.h.in
68    ${CMAKE_CURRENT_BINARY_DIR}/icd_cmake_config.h)
69
70set (OPENCL_ICD_LOADER_SOURCES
71    loader/icd.c
72    loader/icd.h
73    loader/icd_version.h
74    loader/icd_dispatch.c
75    loader/icd_dispatch.h
76    loader/icd_dispatch_generated.c
77    loader/icd_envvars.h
78    loader/icd_platform.h)
79
80if (WIN32)
81    list (APPEND OPENCL_ICD_LOADER_SOURCES
82        loader/windows/adapter.h
83        loader/windows/icd_windows.c
84        loader/windows/icd_windows.h
85        loader/windows/icd_windows_dxgk.c
86        loader/windows/icd_windows_dxgk.h
87        loader/windows/icd_windows_envvars.c
88        loader/windows/icd_windows_hkr.c
89        loader/windows/icd_windows_hkr.h
90        loader/windows/icd_windows_apppackage.c
91        loader/windows/icd_windows_apppackage.h
92        loader/windows/OpenCL.rc)
93    # Only add the DXSDK include directory if the environment variable is
94    # defined.  Since the DXSDK has merged into the Windows SDK, this is
95    # only required in rare cases.
96    if (DEFINED ENV{DXSDK_DIR} AND NOT (MINGW OR MSYS OR CYGWIN))
97        include_directories ($ENV{DXSDK_DIR}/Include)
98    endif ()
99
100    # For mingw-i686 builds only we need a special .def file with stdcall
101    # exports.  In all other cases we can use a standard .def file.
102    if ((CMAKE_SIZEOF_VOID_P EQUAL 4) AND (MINGW OR MSYS OR CYGWIN))
103        list (APPEND OPENCL_ICD_LOADER_SOURCES loader/windows/OpenCL-mingw-i686.def)
104    else ()
105        list (APPEND OPENCL_ICD_LOADER_SOURCES loader/windows/OpenCL.def)
106    endif ()
107else ()
108    list (APPEND OPENCL_ICD_LOADER_SOURCES
109        loader/linux/icd_linux.c
110        loader/linux/icd_linux_envvars.c
111        loader/linux/icd_exports.map)
112endif ()
113
114set (OPENCL_ICD_LOADER_HEADERS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/inc" CACHE PATH "Path to OpenCL Headers")
115
116if (${OPENCL_ICD_LOADER_BUILD_SHARED_LIBS})
117  add_library (OpenCL SHARED ${OPENCL_ICD_LOADER_SOURCES})
118else()
119  add_library (OpenCL STATIC ${OPENCL_ICD_LOADER_SOURCES})
120endif()
121
122add_library (OpenCL::OpenCL ALIAS OpenCL)
123
124set_target_properties (OpenCL PROPERTIES VERSION 1\.0\.0 SOVERSION "1")
125
126if (WIN32)
127    target_link_libraries (OpenCL PRIVATE cfgmgr32.lib runtimeobject.lib)
128
129    # Generate a DLL without a "lib" prefix for mingw.
130    if (MINGW OR MSYS OR CYGWIN)
131        set_target_properties(OpenCL PROPERTIES PREFIX "")
132        set_target_properties(OpenCL PROPERTIES LINK_FLAGS "-Wl,-disable-stdcall-fixup")
133    endif()
134else()
135    target_link_libraries (OpenCL PRIVATE ${CMAKE_THREAD_LIBS_INIT})
136    if (NOT APPLE)
137        set_target_properties (OpenCL PROPERTIES LINK_FLAGS "-Wl,--version-script -Wl,${CMAKE_CURRENT_SOURCE_DIR}/loader/linux/icd_exports.map")
138        if (OPENCL_ICD_LOADER_PIC)
139            set_target_properties(OpenCL PROPERTIES POSITION_INDEPENDENT_CODE ON)
140        endif ()
141    endif ()
142endif ()
143
144if (EXISTS ${OPENCL_ICD_LOADER_HEADERS_DIR}/CL/cl.h)
145    message (STATUS "Defining OpenCL::Headers through OPENCL_ICD_LOADER_HEADERS_DIR")
146    add_library (OpenCLHeaders INTERFACE)
147    add_library (OpenCL::Headers ALIAS OpenCLHeaders)
148    target_include_directories (OpenCLHeaders INTERFACE ${OPENCL_ICD_LOADER_HEADERS_DIR})
149    target_include_directories (OpenCL PUBLIC $<BUILD_INTERFACE:${OPENCL_ICD_LOADER_HEADERS_DIR}>)
150else ()
151    if (NOT TARGET OpenCL::Headers)
152        find_package (OpenCLHeaders REQUIRED)
153    endif ()
154    target_link_libraries (OpenCL PUBLIC OpenCL::Headers)
155endif ()
156
157set (OPENCL_COMPILE_DEFINITIONS
158    CL_TARGET_OPENCL_VERSION=300
159    CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES
160    OPENCL_ICD_LOADER_VERSION_MAJOR=3
161    OPENCL_ICD_LOADER_VERSION_MINOR=0
162    OPENCL_ICD_LOADER_VERSION_REV=6
163    $<$<BOOL:${ENABLE_OPENCL_LAYERS}>:CL_ENABLE_LAYERS>
164)
165
166target_compile_definitions (OpenCL
167  PRIVATE
168    ${OPENCL_COMPILE_DEFINITIONS}
169)
170
171target_include_directories (OpenCL
172  PRIVATE
173    ${CMAKE_CURRENT_BINARY_DIR}
174    loader
175)
176target_link_libraries (OpenCL PUBLIC ${CMAKE_DL_LIBS})
177
178if (ENABLE_OPENCL_LAYERINFO)
179
180  set (OPENCL_LAYER_INFO_SOURCES
181      loader/cllayerinfo.c
182      ${OPENCL_ICD_LOADER_SOURCES}
183  )
184
185  add_executable(cllayerinfo ${OPENCL_LAYER_INFO_SOURCES})
186
187  add_executable(OpenCL::cllayerinfo ALIAS cllayerinfo)
188
189  target_compile_definitions (cllayerinfo
190    PRIVATE
191      CL_LAYER_INFO
192      ${OPENCL_COMPILE_DEFINITIONS}
193  )
194
195  if (EXISTS ${OPENCL_ICD_LOADER_HEADERS_DIR}/CL/cl.h)
196      target_include_directories (cllayerinfo PUBLIC $<BUILD_INTERFACE:${OPENCL_ICD_LOADER_HEADERS_DIR}>)
197  else ()
198      target_link_libraries (cllayerinfo PUBLIC OpenCL::Headers)
199  endif ()
200
201  if (WIN32)
202    target_link_libraries (cllayerinfo PRIVATE cfgmgr32.lib runtimeobject.lib)
203  else ()
204    target_link_libraries (cllayerinfo PRIVATE ${CMAKE_THREAD_LIBS_INIT})
205  endif ()
206
207  target_link_libraries (cllayerinfo PUBLIC ${CMAKE_DL_LIBS})
208
209  target_include_directories (cllayerinfo
210    PRIVATE
211      ${CMAKE_CURRENT_BINARY_DIR}
212      loader
213  )
214endif ()
215
216option (OPENCL_ICD_LOADER_BUILD_TESTING "Enable support for OpenCL ICD Loader testing." OFF)
217
218if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR OPENCL_ICD_LOADER_BUILD_TESTING)
219    include(CTest)
220endif()
221if((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR OPENCL_ICD_LOADER_BUILD_TESTING) AND BUILD_TESTING)
222    add_subdirectory (test)
223endif()
224
225install(
226  TARGETS OpenCL
227  EXPORT OpenCLICDLoaderTargets
228  LIBRARY
229  DESTINATION ${CMAKE_INSTALL_LIBDIR} # obtained from GNUInstallDirs
230)
231install(
232# 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)
233# 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
234  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
235  DESTINATION ${CMAKE_INSTALL_BINDIR}
236  OPTIONAL
237)
238
239if (ENABLE_OPENCL_LAYERINFO)
240  install(
241    TARGETS cllayerinfo
242    RUNTIME
243      DESTINATION ${CMAKE_INSTALL_BINDIR}
244    COMPONENT cllayerinfo
245  )
246endif()
247
248export(
249  EXPORT OpenCLICDLoaderTargets
250  FILE ${PROJECT_BINARY_DIR}/OpenCLICDLoader/OpenCLICDLoaderTargets.cmake
251  NAMESPACE OpenCL::
252)
253file(
254  WRITE ${PROJECT_BINARY_DIR}/OpenCLICDLoader/OpenCLICDLoaderConfig.cmake
255  "include(\"\${CMAKE_CURRENT_LIST_DIR}/OpenCLICDLoaderTargets.cmake\")"
256)
257
258set(config_package_location ${CMAKE_INSTALL_DATADIR}/cmake/OpenCLICDLoader)
259install(
260  EXPORT OpenCLICDLoaderTargets
261  FILE OpenCLICDLoaderTargets.cmake
262  NAMESPACE OpenCL::
263  DESTINATION ${config_package_location}
264  COMPONENT dev
265)
266install(
267  FILES ${CMAKE_CURRENT_BINARY_DIR}/OpenCLICDLoader/OpenCLICDLoaderConfig.cmake
268  DESTINATION ${config_package_location}
269  COMPONENT dev
270)
271
272unset(CMAKE_SIZEOF_VOID_P)
273include(CMakePackageConfigHelpers)
274write_basic_package_version_file(
275  ${CMAKE_CURRENT_BINARY_DIR}/OpenCLICDLoader/OpenCLICDLoaderConfigVersion.cmake
276  VERSION ${PROJECT_VERSION}
277  COMPATIBILITY AnyNewerVersion
278)
279install(
280  FILES ${CMAKE_CURRENT_BINARY_DIR}/OpenCLICDLoader/OpenCLICDLoaderConfigVersion.cmake
281  DESTINATION ${config_package_location}
282  COMPONENT dev
283)
284
285# Separate namelink from shared library and symlink for DEB packaging
286install (TARGETS OpenCL
287    LIBRARY
288      DESTINATION ${CMAKE_INSTALL_LIBDIR}
289    COMPONENT runtime
290    NAMELINK_SKIP)
291
292install (TARGETS OpenCL
293    LIBRARY
294      DESTINATION ${CMAKE_INSTALL_LIBDIR}
295    COMPONENT dev
296    NAMELINK_ONLY)
297