summaryrefslogtreecommitdiffstats
path: root/Modules/CMakeDetermineCUDACompiler.cmake
diff options
context:
space:
mode:
authorRaul Tambre <raul@tambre.ee>2020-03-07 15:29:29 (GMT)
committerRaul Tambre <raul@tambre.ee>2020-05-15 14:46:51 (GMT)
commit5df21adf46be14061fe0e8ea53213d905e834600 (patch)
tree9e50ef0dc770d6ad68eede0ad04e5058d1775069 /Modules/CMakeDetermineCUDACompiler.cmake
parentdc2eae1f91f98019efe14c1398e10f23e93a7005 (diff)
downloadCMake-5df21adf46be14061fe0e8ea53213d905e834600.zip
CMake-5df21adf46be14061fe0e8ea53213d905e834600.tar.gz
CMake-5df21adf46be14061fe0e8ea53213d905e834600.tar.bz2
CUDA: Add support for Clang compiler
When crosscompiling we pass the sysroot. We need to try various architecture flags. Clang doesn't automatically select one that works. First try the ones that are more likely to work for modern installations: * <=sm_50 is deprecated since CUDA 10.2, try sm_52 first for future compatibility. * <=sm_20 is removed since CUDA 9.0, try sm_30. Otherwise fallback to Clang's current default. Currently that's `sm_20`, the lowest it supports. Separable compilation isn't supported yet. Fixes: #16586
Diffstat (limited to 'Modules/CMakeDetermineCUDACompiler.cmake')
-rw-r--r--Modules/CMakeDetermineCUDACompiler.cmake60
1 files changed, 55 insertions, 5 deletions
diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake
index ead4125..af36688 100644
--- a/Modules/CMakeDetermineCUDACompiler.cmake
+++ b/Modules/CMakeDetermineCUDACompiler.cmake
@@ -2,7 +2,7 @@
# file Copyright.txt or https://cmake.org/licensing for details.
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
-include(${CMAKE_ROOT}/Modules//CMakeParseImplicitLinkInfo.cmake)
+include(${CMAKE_ROOT}/Modules/CMakeParseImplicitLinkInfo.cmake)
if( NOT ( ("${CMAKE_GENERATOR}" MATCHES "Make") OR
("${CMAKE_GENERATOR}" MATCHES "Ninja") OR
@@ -57,16 +57,39 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN)
file(READ ${CMAKE_ROOT}/Modules/CMakePlatformId.h.in
CMAKE_CUDA_COMPILER_ID_PLATFORM_CONTENT)
- list(APPEND CMAKE_CUDA_COMPILER_ID_MATCH_VENDORS NVIDIA)
- set(CMAKE_CUDA_COMPILER_ID_MATCH_VENDOR_REGEX_NVIDIA "nvcc: NVIDIA \(R\) Cuda compiler driver")
+ list(APPEND CMAKE_CUDA_COMPILER_ID_VENDORS NVIDIA Clang)
+ set(CMAKE_CUDA_COMPILER_ID_VENDOR_REGEX_NVIDIA "nvcc: NVIDIA \\(R\\) Cuda compiler driver")
+ set(CMAKE_CUDA_COMPILER_ID_VENDOR_REGEX_Clang "(clang version)")
set(CMAKE_CXX_COMPILER_ID_TOOL_MATCH_REGEX "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerIdCUDA/(\\./)?(CompilerIdCUDA.xctest/)?CompilerIdCUDA[ \t\n\\\"]")
set(CMAKE_CXX_COMPILER_ID_TOOL_MATCH_INDEX 2)
+ set(CMAKE_CUDA_COMPILER_ID_FLAGS_ALWAYS "-v")
- set(CMAKE_CUDA_COMPILER_ID_FLAGS_ALWAYS -v --keep --keep-dir tmp)
+ # nvcc
+ set(nvcc_test_flags "--keep --keep-dir tmp")
if(CMAKE_CUDA_HOST_COMPILER)
- list(APPEND CMAKE_CUDA_COMPILER_ID_FLAGS_ALWAYS "-ccbin=${CMAKE_CUDA_HOST_COMPILER}")
+ string(APPEND nvcc_test_flags " -ccbin=${CMAKE_CUDA_HOST_COMPILER}")
endif()
+ list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST ${nvcc_test_flags})
+
+ # Clang
+ if(CMAKE_CROSSCOMPILING)
+ # Need to pass the host target and include directories if we're crosscompiling.
+ set(clang_test_flags "--sysroot=\"${CMAKE_SYSROOT}\" --target=${CMAKE_CUDA_COMPILER_TARGET}")
+ else()
+ set(clang_test_flags)
+ endif()
+
+ # Clang doesn't automatically select an architecture supported by the SDK.
+ # Try in reverse order of deprecation with the most recent at front (i.e. the most likely to work for new setups).
+ foreach(arch ${CMAKE_CUDA_ARCHITECTURES} "20" "30" "52")
+ # Strip specifiers.
+ string(REGEX MATCH "[0-9]+" arch_name "${arch}")
+ list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${clang_test_flags} --cuda-gpu-arch=sm_${arch_name}")
+ endforeach()
+
+ # Finally also try the default.
+ list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${clang_test_flags}")
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
CMAKE_DETERMINE_COMPILER_ID(CUDA CUDAFLAGS CMakeCUDACompilerId.cu)
@@ -89,6 +112,33 @@ if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
set(CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES "")
set(CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES "")
set(CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")
+elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang")
+ # Parse default CUDA architecture.
+ if(NOT CMAKE_CUDA_ARCHITECTURES)
+ string(REGEX MATCH "-target-cpu sm_([0-9]+)" dont_care "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}")
+ set(CMAKE_CUDA_ARCHITECTURES "${CMAKE_MATCH_1}" CACHE STRING "CUDA architectures")
+
+ if(NOT CMAKE_CUDA_ARCHITECTURES)
+ message(FATAL_ERROR "Failed to find default CUDA architecture.")
+ endif()
+ endif()
+
+ # Parsing implicit host linker info is as simple as for regular Clang.
+ CMAKE_PARSE_IMPLICIT_LINK_INFO("${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}"
+ CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES
+ CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES
+ CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES
+ log
+ "${CMAKE_CUDA_IMPLICIT_OBJECT_REGEX}")
+
+ # Get SDK directory.
+ string(REGEX MATCH "Found CUDA installation: (.+), version" dont_care "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}")
+ set(__cuda_directory "${CMAKE_MATCH_1}")
+
+ # Clang doesn't add the SDK library directory to the implicit link path. Do it ourselves, so stuff works.
+ include(Internal/CUDAToolkit)
+ set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES "${CUDAToolkit_INCLUDE_DIR}")
+ list(APPEND CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES "${CUDAToolkit_LIBRARY_DIR}")
elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
set(_nvcc_log "")
string(REPLACE "\r" "" _nvcc_output_orig "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}")