diff options
-rw-r--r-- | Help/release/dev/FindCUDAToolkit-no-nvcc.rst | 5 | ||||
-rw-r--r-- | Modules/FindCUDAToolkit.cmake | 153 |
2 files changed, 104 insertions, 54 deletions
diff --git a/Help/release/dev/FindCUDAToolkit-no-nvcc.rst b/Help/release/dev/FindCUDAToolkit-no-nvcc.rst new file mode 100644 index 0000000..e815876 --- /dev/null +++ b/Help/release/dev/FindCUDAToolkit-no-nvcc.rst @@ -0,0 +1,5 @@ +FindCUDAToolkit-no-nvcc +----------------------- + +* The :module:`FindCUDAToolkit` module gained support for finding CUDA toolkits + that do not contain ``nvcc``. diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake index e3acc3f..1054f60 100644 --- a/Modules/FindCUDAToolkit.cmake +++ b/Modules/FindCUDAToolkit.cmake @@ -14,8 +14,7 @@ module does not search for the NVIDIA CUDA Samples. Search Behavior ^^^^^^^^^^^^^^^ -Finding the CUDA Toolkit requires finding the ``nvcc`` executable, which is -searched for in the following order: +The CUDA Toolkit search behavior uses the following order: 1. If the ``CUDA`` language has been enabled we will use the directory containing the compiler as the first search location for ``nvcc``. @@ -26,13 +25,12 @@ searched for in the following order: configuration variable are specified, the *configuration* variable takes precedence. - The directory specified here must be such that the executable ``nvcc`` can be - found underneath the directory specified by ``CUDAToolkit_ROOT``. If - ``CUDAToolkit_ROOT`` is specified, but no ``nvcc`` is found underneath, this - package is marked as **not** found. No subsequent search attempts are - performed. + The directory specified here must be such that the executable ``nvcc`` or + the appropriate ``version.txt`` file can be found underneath the specified + directory. -3. If the CUDA_PATH environment variable is defined, it will be searched. +3. If the CUDA_PATH environment variable is defined, it will be searched + for ``nvcc``. 4. The user's path is searched for ``nvcc`` using :command:`find_program`. If this is found, no subsequent search attempts are performed. Users are @@ -404,7 +402,7 @@ Result variables ``CUDAToolkit_VERSION`` The exact version of the CUDA Toolkit found (as reported by - ``nvcc --version``). + ``nvcc --version`` or ``version.txt``). ``CUDAToolkit_VERSION_MAJOR`` The major version of the CUDA Toolkit. @@ -434,7 +432,7 @@ Result variables ``CUDAToolkit_TARGET_DIR`` The path to the CUDA Toolkit directory including the target architecture when cross-compiling. When not cross-compiling this will be equivalent to - ``CUDAToolkit_ROOT_DIR``. + the parent directory of ``CUDAToolkit_BIN_DIR``. ``CUDAToolkit_NVCC_EXECUTABLE`` The path to the NVIDIA CUDA compiler ``nvcc``. Note that this path may @@ -493,31 +491,81 @@ if(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT) set(CUDAToolkit_BIN_DIR "${CUDAToolkit_ROOT_DIR}/bin") set(CUDAToolkit_NVCC_EXECUTABLE "${CUDAToolkit_BIN_DIR}/nvcc${CMAKE_EXECUTABLE_SUFFIX}") else() + + function(_CUDAToolkit_find_root_dir ) + cmake_parse_arguments(arg "" "" "SEARCH_PATHS;FIND_FLAGS" ${ARGN}) + + + if(NOT CUDAToolkit_BIN_DIR) + if(NOT CUDAToolkit_SENTINEL_FILE) + find_program(CUDAToolkit_NVCC_EXECUTABLE + NAMES nvcc nvcc.exe + PATHS ${arg_SEARCH_PATHS} + ${arg_FIND_FLAGS} + ) + endif() + + if(NOT CUDAToolkit_NVCC_EXECUTABLE) + find_file(CUDAToolkit_SENTINEL_FILE + NAMES version.txt + PATHS ${arg_SEARCH_PATHS} + NO_DEFAULT_PATH + ) + endif() + + if(CUDAToolkit_NVCC_EXECUTABLE) + get_filename_component(CUDAToolkit_BIN_DIR "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY) + + set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE) + mark_as_advanced(CUDAToolkit_BIN_DIR) + elseif(CUDAToolkit_SENTINEL_FILE) + get_filename_component(CUDAToolkit_BIN_DIR ${CUDAToolkit_SENTINEL_FILE} DIRECTORY ABSOLUTE) + set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}/bin") + + set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE) + mark_as_advanced(CUDAToolkit_BIN_DIR) + endif() + endif() + + if(CUDAToolkit_BIN_DIR) + get_filename_component(CUDAToolkit_ROOT_DIR ${CUDAToolkit_BIN_DIR} DIRECTORY ABSOLUTE) + set(CUDAToolkit_ROOT_DIR "${CUDAToolkit_ROOT_DIR}" PARENT_SCOPE) + endif() + + endfunction() + + function(_CUDAToolkit_find_version_file result_variable) + # We first check for a non-scattered installation to prefer it over a scattered installation. + if(CUDAToolkit_ROOT AND EXISTS "${CUDAToolkit_ROOT}/version.txt") + set(${result_variable} "${CUDAToolkit_ROOT}/version.txt" PARENT_SCOPE) + elseif(CUDAToolkit_ROOT_DIR AND EXISTS "${CUDAToolkit_ROOT_DIR}/version.txt") + set(${result_variable} "${CUDAToolkit_ROOT_DIR}/version.txt" PARENT_SCOPE) + elseif(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/version.txt") + set(${result_variable} "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/version.txt" PARENT_SCOPE) + elseif(EXISTS "${CMAKE_SYSROOT}/usr/lib/cuda/version.txt") + set(${result_variable} "${CMAKE_SYSROOT}/usr/lib/cuda/version.txt" PARENT_SCOPE) + endif() + endfunction() + # For NVCC we can easily deduce the SDK binary directory from the compiler path. if(CMAKE_CUDA_COMPILER_LOADED AND NOT CUDAToolkit_BIN_DIR AND CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") get_filename_component(CUDAToolkit_BIN_DIR "${CMAKE_CUDA_COMPILER}" DIRECTORY) set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "") + # Try language provided path first. + _CUDAToolkit_find_root_dir(SEARCH_PATHS "${CUDAToolkit_BIN_DIR}" FIND_FLAGS NO_DEFAULT_PATH) mark_as_advanced(CUDAToolkit_BIN_DIR) endif() - # Try language- or user-provided path first. - if(CUDAToolkit_BIN_DIR) - find_program(CUDAToolkit_NVCC_EXECUTABLE - NAMES nvcc nvcc.exe - PATHS ${CUDAToolkit_BIN_DIR} - NO_DEFAULT_PATH - ) + # Try user provided path + if(NOT CUDAToolkit_ROOT_DIR AND CUDAToolkit_ROOT) + _CUDAToolkit_find_root_dir(SEARCH_PATHS "${CUDAToolkit_ROOT}" FIND_FLAGS PATH_SUFFIXES bin NO_DEFAULT_PATH) + endif() + if(NOT CUDAToolkit_ROOT_DIR) + _CUDAToolkit_find_root_dir(FIND_FLAGS PATHS "ENV CUDA_PATH" PATH_SUFFIXES bin) endif() - # Search using CUDAToolkit_ROOT - find_program(CUDAToolkit_NVCC_EXECUTABLE - NAMES nvcc nvcc.exe - PATHS ENV CUDA_PATH - PATH_SUFFIXES bin - ) - - # If the user specified CUDAToolkit_ROOT but nvcc could not be found, this is an error. - if(NOT CUDAToolkit_NVCC_EXECUTABLE AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT})) + # If the user specified CUDAToolkit_ROOT but the toolkit could not be found, this is an error. + if(NOT CUDAToolkit_ROOT_DIR AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT})) # Declare error messages now, print later depending on find_package args. set(fail_base "Could not find nvcc executable in path specified by") set(cuda_root_fail "${fail_base} CUDAToolkit_ROOT=${CUDAToolkit_ROOT}") @@ -554,7 +602,7 @@ else() # We will also search the default symlink location /usr/local/cuda first since # if CUDAToolkit_ROOT is not specified, it is assumed that the symlinked # directory is the desired location. - if(NOT CUDAToolkit_NVCC_EXECUTABLE) + if(NOT CUDAToolkit_ROOT_DIR) if(UNIX) if(NOT APPLE) set(platform_base "/usr/local/cuda-") @@ -591,12 +639,8 @@ else() list(INSERT search_paths 0 "/usr/local/cuda") endif() - # Now search for nvcc again using the platform default search paths. - find_program(CUDAToolkit_NVCC_EXECUTABLE - NAMES nvcc nvcc.exe - PATHS ${search_paths} - PATH_SUFFIXES bin - ) + # Now search for the toolkit again using the platform default search paths. + _CUDAToolkit_find_root_dir(SEARCH_PATHS "${search_paths}" FIND_FLAGS PATH_SUFFIXES bin) # We are done with these variables now, cleanup for caller. unset(platform_base) @@ -604,7 +648,7 @@ else() unset(versions) unset(search_paths) - if(NOT CUDAToolkit_NVCC_EXECUTABLE) + if(NOT CUDAToolkit_ROOT_DIR) if(CUDAToolkit_FIND_REQUIRED) message(FATAL_ERROR "Could not find nvcc, please set CUDAToolkit_ROOT.") elseif(NOT CUDAToolkit_FIND_QUIETLY) @@ -616,24 +660,12 @@ else() endif() endif() - if(NOT CUDAToolkit_BIN_DIR AND CUDAToolkit_NVCC_EXECUTABLE) - get_filename_component(CUDAToolkit_BIN_DIR "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY) - set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE) - mark_as_advanced(CUDAToolkit_BIN_DIR) - endif() - - get_filename_component(CUDAToolkit_ROOT_DIR ${CUDAToolkit_BIN_DIR} DIRECTORY ABSOLUTE) - - # CUDAToolkit_LIBRARY_ROOT contains the device library and version file. - # In a non-scattered installation this is equivalent to CUDAToolkit_ROOT_DIR. - # We first check for a non-scattered installation to prefer it over a scattered installation. - if(EXISTS "${CUDAToolkit_ROOT_DIR}/version.txt") - set(CUDAToolkit_LIBRARY_ROOT "${CUDAToolkit_ROOT_DIR}") - elseif(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/version.txt") - set(CUDAToolkit_LIBRARY_ROOT "${CMAKE_SYSROOT_LINK}/usr/lib/cuda") - elseif(EXISTS "${CMAKE_SYSROOT}/usr/lib/cuda/version.txt") - set(CUDAToolkit_LIBRARY_ROOT "${CMAKE_SYSROOT}/usr/lib/cuda") + _CUDAToolkit_find_version_file( _CUDAToolkit_version_file ) + if(_CUDAToolkit_version_file) + # CUDAToolkit_LIBRARY_ROOT contains the device library and version file. + get_filename_component(CUDAToolkit_LIBRARY_ROOT "${_CUDAToolkit_version_file}" DIRECTORY ABSOLUTE) endif() + unset(_CUDAToolkit_version_file) endif() # Handle cross compilation @@ -695,7 +727,7 @@ if(CUDAToolkit_NVCC_EXECUTABLE AND set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}") set(CUDAToolkit_VERSION "${CMAKE_CUDA_COMPILER_VERSION}") endif() -else() +elseif(CUDAToolkit_NVCC_EXECUTABLE) # Compute the version by invoking nvcc execute_process(COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE NVCC_OUT) if(NVCC_OUT MATCHES [=[ V([0-9]+)\.([0-9]+)\.([0-9]+)]=]) @@ -705,6 +737,17 @@ else() set(CUDAToolkit_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}") endif() unset(NVCC_OUT) +else() + _CUDAToolkit_find_version_file(version_file) + if(version_file) + file(READ "${version_file}" VERSION_INFO) + if(VERSION_INFO MATCHES [=[CUDA Version ([0-9]+)\.([0-9]+)\.([0-9]+)]=]) + set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}") + set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}") + set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}") + set(CUDAToolkit_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}") + endif() + endif() endif() # Find the CUDA Runtime Library libcudart @@ -721,7 +764,6 @@ if(NOT CUDA_CUDART AND NOT CUDAToolkit_FIND_QUIETLY) message(STATUS "Unable to find cudart library.") endif() -unset(CUDAToolkit_ROOT_DIR) if(_CUDAToolkit_Pop_Prefix) list(REMOVE_AT CMAKE_PREFIX_PATH -1) unset(_CUDAToolkit_Pop_Prefix) @@ -734,13 +776,16 @@ find_package_handle_standard_args(CUDAToolkit REQUIRED_VARS CUDAToolkit_INCLUDE_DIR CUDA_CUDART - CUDAToolkit_NVCC_EXECUTABLE + CUDAToolkit_BIN_DIR VERSION_VAR CUDAToolkit_VERSION ) + +unset(CUDAToolkit_ROOT_DIR) mark_as_advanced(CUDA_CUDART CUDAToolkit_INCLUDE_DIR CUDAToolkit_NVCC_EXECUTABLE + CUDAToolkit_SENTINEL_FILE ) #----------------------------------------------------------------------------- |