cmake_minimum_required (VERSION 3.1) # Include guard for including this project multiple times if(TARGET OpenCL) return() endif() project (OpenCL-ICD-Loader VERSION 1.2 LANGUAGES C) find_package (Threads REQUIRED) set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED ON) # The option below allows building the ICD Loader library as a shared library # (ON, default) or a static library (OFF). # # Khronos OpenCL Working Group strongly recommends building and using the ICD # loader as a shared library due to the following benefits: # # 1. The shared library can be updated independent of the application. This # allows releasing new fixes and features in the ICD loader without updating # the application. # # In rare cases when there are backward-incompatible changes to the ICD # loader (due to platform requirements, for instance), using a shared # library allows updating the library to make the transition seamless to # installed applications. # # 2. On platforms that require the ICD mechanism there are multiple vendors # shipping their OpenCL implementations. The vendor installers collaborate # to make sure that the installed ICD shared library version is suitable for # working with all vendor implementations installed on the system. # # If applications statically link to ICD Loader then that version of the ICD # loader may not work with one or more installed vendor implementations. # # Using the OpenCL ICD loader as a static library is NOT recommended for # end-user installations in general. However in some controlled environments it # may be useful to simplify the build and distribution of the application. E.g. # in test farms, or in cases where the end-user system configs are known in # advance. Use it with discretion. if(DEFINED BUILD_SHARED_LIBS) set(OPENCL_ICD_LOADER_BUILD_SHARED_LIBS_DEFAULT ${BUILD_SHARED_LIBS}) else() set(OPENCL_ICD_LOADER_BUILD_SHARED_LIBS_DEFAULT ON) endif() option(OPENCL_ICD_LOADER_BUILD_SHARED_LIBS "Build OpenCL ICD Loader as shared library" ${OPENCL_ICD_LOADER_BUILD_SHARED_LIBS_DEFAULT}) # This option enables/disables support for OpenCL layers in the ICD loader. # It is currently needed default while the specification is being formalized, # and to study the performance impact. option (ENABLE_OPENCL_LAYERS "Enable OpenCL Layers" ON) include(CMakeDependentOption) cmake_dependent_option(ENABLE_OPENCL_LAYERINFO "Enable building cllayerinfo tool" ON ENABLE_OPENCL_LAYERS OFF) set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include(JoinPaths) include(CheckFunctionExists) check_function_exists(secure_getenv HAVE_SECURE_GETENV) check_function_exists(__secure_getenv HAVE___SECURE_GETENV) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/loader/icd_cmake_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/icd_cmake_config.h) set (OPENCL_ICD_LOADER_SOURCES loader/icd.c loader/icd.h loader/icd_version.h loader/icd_dispatch.c loader/icd_dispatch.h loader/icd_dispatch_generated.c loader/icd_envvars.h loader/icd_platform.h) if (WIN32) list (APPEND OPENCL_ICD_LOADER_SOURCES loader/windows/adapter.h loader/windows/icd_windows.c loader/windows/icd_windows.h loader/windows/icd_windows_dxgk.c loader/windows/icd_windows_dxgk.h loader/windows/icd_windows_envvars.c loader/windows/icd_windows_hkr.c loader/windows/icd_windows_hkr.h loader/windows/icd_windows_apppackage.c loader/windows/icd_windows_apppackage.h loader/windows/OpenCL.rc) # Only add the DXSDK include directory if the environment variable is # defined. Since the DXSDK has merged into the Windows SDK, this is # only required in rare cases. if (DEFINED ENV{DXSDK_DIR} AND NOT (MINGW OR MSYS OR CYGWIN)) include_directories ($ENV{DXSDK_DIR}/Include) endif () # For mingw-i686 builds only we need a special .def file with stdcall # exports. In all other cases we can use a standard .def file. if ((CMAKE_SIZEOF_VOID_P EQUAL 4) AND (MINGW OR MSYS OR CYGWIN)) list (APPEND OPENCL_ICD_LOADER_SOURCES loader/windows/OpenCL-mingw-i686.def) else () list (APPEND OPENCL_ICD_LOADER_SOURCES loader/windows/OpenCL.def) endif () else () list (APPEND OPENCL_ICD_LOADER_SOURCES loader/linux/icd_linux.c loader/linux/icd_linux_envvars.c loader/linux/icd_exports.map) endif () set (OPENCL_ICD_LOADER_HEADERS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/inc" CACHE PATH "Path to OpenCL Headers") if (${OPENCL_ICD_LOADER_BUILD_SHARED_LIBS}) add_library (OpenCL SHARED ${OPENCL_ICD_LOADER_SOURCES}) else() add_library (OpenCL STATIC ${OPENCL_ICD_LOADER_SOURCES}) endif() add_library (OpenCL::OpenCL ALIAS OpenCL) set_target_properties (OpenCL PROPERTIES VERSION "1.2" SOVERSION "1") if (WIN32) target_link_libraries (OpenCL PRIVATE cfgmgr32.lib runtimeobject.lib) # Generate a DLL without a "lib" prefix for mingw. if (MINGW OR MSYS OR CYGWIN) set_target_properties(OpenCL PROPERTIES PREFIX "") set_target_properties(OpenCL PROPERTIES LINK_FLAGS "-Wl,-disable-stdcall-fixup") endif() else() target_link_libraries (OpenCL PRIVATE ${CMAKE_THREAD_LIBS_INIT}) if (NOT APPLE) set_target_properties (OpenCL PROPERTIES LINK_FLAGS "-Wl,--version-script -Wl,${CMAKE_CURRENT_SOURCE_DIR}/loader/linux/icd_exports.map") if (OPENCL_ICD_LOADER_PIC) set_target_properties(OpenCL PROPERTIES POSITION_INDEPENDENT_CODE ON) endif () endif () endif () if (EXISTS ${OPENCL_ICD_LOADER_HEADERS_DIR}/CL/cl.h) message (STATUS "Defining OpenCL::Headers through OPENCL_ICD_LOADER_HEADERS_DIR") add_library (OpenCLHeaders INTERFACE) add_library (OpenCL::Headers ALIAS OpenCLHeaders) target_include_directories (OpenCLHeaders INTERFACE ${OPENCL_ICD_LOADER_HEADERS_DIR}) target_include_directories (OpenCL PUBLIC $) else () if (NOT TARGET OpenCL::Headers) find_package (OpenCLHeaders REQUIRED) endif () target_link_libraries (OpenCL PUBLIC OpenCL::Headers) endif () set (OPENCL_COMPILE_DEFINITIONS CL_TARGET_OPENCL_VERSION=300 CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES OPENCL_ICD_LOADER_VERSION_MAJOR=3 OPENCL_ICD_LOADER_VERSION_MINOR=0 OPENCL_ICD_LOADER_VERSION_REV=6 $<$:CL_ENABLE_LAYERS> ) target_compile_definitions (OpenCL PRIVATE ${OPENCL_COMPILE_DEFINITIONS} ) target_include_directories (OpenCL PRIVATE ${CMAKE_CURRENT_BINARY_DIR} loader ) target_link_libraries (OpenCL PUBLIC ${CMAKE_DL_LIBS}) if (ENABLE_OPENCL_LAYERINFO) set (OPENCL_LAYER_INFO_SOURCES loader/cllayerinfo.c ${OPENCL_ICD_LOADER_SOURCES} ) add_executable(cllayerinfo ${OPENCL_LAYER_INFO_SOURCES}) add_executable(OpenCL::cllayerinfo ALIAS cllayerinfo) target_compile_definitions (cllayerinfo PRIVATE CL_LAYER_INFO ${OPENCL_COMPILE_DEFINITIONS} ) if (EXISTS ${OPENCL_ICD_LOADER_HEADERS_DIR}/CL/cl.h) target_include_directories (cllayerinfo PUBLIC $) else () target_link_libraries (cllayerinfo PUBLIC OpenCL::Headers) endif () if (WIN32) target_link_libraries (cllayerinfo PRIVATE cfgmgr32.lib runtimeobject.lib) else () target_link_libraries (cllayerinfo PRIVATE ${CMAKE_THREAD_LIBS_INIT}) endif () target_link_libraries (cllayerinfo PUBLIC ${CMAKE_DL_LIBS}) target_include_directories (cllayerinfo PRIVATE ${CMAKE_CURRENT_BINARY_DIR} loader ) endif () option (OPENCL_ICD_LOADER_BUILD_TESTING "Enable support for OpenCL ICD Loader testing." OFF) if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR OPENCL_ICD_LOADER_BUILD_TESTING) include(CTest) endif() if((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR OPENCL_ICD_LOADER_BUILD_TESTING) AND BUILD_TESTING) add_subdirectory (test) endif() include (GNUInstallDirs) install( TARGETS OpenCL EXPORT OpenCLICDLoaderTargets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} # obtained from GNUInstallDirs ) install( # FILES $ is cleanest, but is MSVC link.exe specific. LLVM's lld.exe and lld-link.exe don't support it (configure-time error) # FILES $/OpenCL.pdb looks OK, but even though there's a PDB, this prop is empty on non-MSVC toolchains FILES $/OpenCL.pdb # is the most implicit (expect PDB be next to the library), yet the only one that universally works DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL ) if (ENABLE_OPENCL_LAYERINFO) install( TARGETS cllayerinfo EXPORT OpenCLICDLoaderTargets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) endif() export( EXPORT OpenCLICDLoaderTargets FILE ${PROJECT_BINARY_DIR}/OpenCLICDLoader/OpenCLICDLoaderTargets.cmake NAMESPACE OpenCL:: ) file( WRITE ${PROJECT_BINARY_DIR}/OpenCLICDLoader/OpenCLICDLoaderConfig.cmake "include(\"\${CMAKE_CURRENT_LIST_DIR}/OpenCLICDLoaderTargets.cmake\")" ) set(config_package_location ${CMAKE_INSTALL_DATADIR}/cmake/OpenCLICDLoader) install( EXPORT OpenCLICDLoaderTargets FILE OpenCLICDLoaderTargets.cmake NAMESPACE OpenCL:: DESTINATION ${config_package_location} ) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/OpenCLICDLoader/OpenCLICDLoaderConfig.cmake DESTINATION ${config_package_location} ) unset(CMAKE_SIZEOF_VOID_P) include(CMakePackageConfigHelpers) write_basic_package_version_file( ${CMAKE_CURRENT_BINARY_DIR}/OpenCLICDLoader/OpenCLICDLoaderConfigVersion.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY AnyNewerVersion ) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/OpenCLICDLoader/OpenCLICDLoaderConfigVersion.cmake DESTINATION ${config_package_location} ) install (TARGETS OpenCL RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) join_paths(OPENCL_LIBDIR_PC "\${exec_prefix}" "${CMAKE_INSTALL_LIBDIR}") join_paths(OPENCL_INCLUDEDIR_PC "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}") if (NOT MSVC) configure_file(OpenCL.pc.in OpenCL.pc @ONLY) set(pkg_config_location ${CMAKE_INSTALL_LIBDIR}/pkgconfig) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/OpenCL.pc DESTINATION ${pkg_config_location}) endif()