From eed16fbc00efe763e5a79e18a08d4dd3d14166ce Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Wed, 29 May 2024 08:32:21 -0400 Subject: FindCUDAToolkit: Use CUDA compiler path even when CUDA lang not enabled Fixes: #25567 --- Help/release/dev/FindCUDAToolkit-search-paths.rst | 7 +++++ Modules/FindCUDAToolkit.cmake | 35 +++++++++++++++++++---- Tests/Cuda/CMakeLists.txt | 1 + Tests/Cuda/ToolkitBeforeLang/CMakeLists.txt | 22 ++++++++++++++ Tests/Cuda/ToolkitBeforeLang/main.cpp | 8 ++++++ 5 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 Help/release/dev/FindCUDAToolkit-search-paths.rst create mode 100644 Tests/Cuda/ToolkitBeforeLang/CMakeLists.txt create mode 100644 Tests/Cuda/ToolkitBeforeLang/main.cpp diff --git a/Help/release/dev/FindCUDAToolkit-search-paths.rst b/Help/release/dev/FindCUDAToolkit-search-paths.rst new file mode 100644 index 0000000..3229e5c --- /dev/null +++ b/Help/release/dev/FindCUDAToolkit-search-paths.rst @@ -0,0 +1,7 @@ +FindCUDAToolkit-search-paths +---------------------------- + +* The :module:`FindCUDAToolkit` module now searches the + :variable:`CMAKE_CUDA_COMPILER _COMPILER>` and + the environment variable :envvar:`CUDACXX` even when the CUDA + language isn't enabled. diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake index 44d09f5..da33be2 100644 --- a/Modules/FindCUDAToolkit.cmake +++ b/Modules/FindCUDAToolkit.cmake @@ -22,7 +22,11 @@ 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``. -2. If the ``CUDAToolkit_ROOT`` cmake configuration variable (e.g., +2. If the variable :variable:`CMAKE_CUDA_COMPILER _COMPILER>` or + the environment variable :envvar:`CUDACXX` is defined, it will be used + as the path to the ``nvcc`` executable. + +3. If the ``CUDAToolkit_ROOT`` cmake configuration variable (e.g., ``-DCUDAToolkit_ROOT=/some/path``) *or* environment variable is defined, it will be searched. If both an environment variable **and** a configuration variable are specified, the *configuration* variable takes @@ -32,19 +36,19 @@ The CUDA Toolkit search behavior uses the following order: the appropriate ``version.txt`` or ``version.json`` file can be found underneath the specified directory. -3. If the CUDA_PATH environment variable is defined, it will be searched +4. 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 +5. The user's path is searched for ``nvcc`` using :command:`find_program`. If this is found, no subsequent search attempts are performed. Users are responsible for ensuring that the first ``nvcc`` to show up in the path is the desired path in the event that multiple CUDA Toolkits are installed. -5. On Unix systems, if the symbolic link ``/usr/local/cuda`` exists, this is +6. On Unix systems, if the symbolic link ``/usr/local/cuda`` exists, this is used. No subsequent search attempts are performed. No default symbolic link location exists for the Windows platform. -6. The platform specific default install locations are searched. If exactly one +7. The platform specific default install locations are searched. If exactly one candidate is found, this is used. The default CUDA Toolkit install locations searched are: @@ -628,9 +632,27 @@ if(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT) endif() else() function(_CUDAToolkit_find_root_dir ) - cmake_parse_arguments(arg "" "" "SEARCH_PATHS;FIND_FLAGS" ${ARGN}) + cmake_parse_arguments(arg "COMPILER_PATHS" "" "SEARCH_PATHS;FIND_FLAGS" ${ARGN}) if(NOT CUDAToolkit_BIN_DIR) + if(arg_COMPILER_PATHS) + # need to find parent dir, since this could clang and not nvcc + if(EXISTS "${CMAKE_CUDA_COMPILER}") + get_filename_component(possible_nvcc_path "${CMAKE_CUDA_COMPILER}" PROGRAM PROGRAM_ARGS CUDAToolkit_compiler_args) + get_filename_component(possible_nvcc_path "${possible_nvcc_path}" DIRECTORY) + elseif(EXISTS "$ENV{CUDACXX}") + get_filename_component(possible_nvcc_path "$ENV{CUDACXX}" PROGRAM PROGRAM_ARGS CUDAToolkit_compiler_args) + get_filename_component(possible_nvcc_path "${possible_nvcc_path}" DIRECTORY) + endif() + if(possible_nvcc_path) + find_program(CUDAToolkit_NVCC_EXECUTABLE + NAMES nvcc nvcc.exe + NO_DEFAULT_PATH + PATHS ${possible_nvcc_path} + ) + endif() + endif() + if(NOT CUDAToolkit_SENTINEL_FILE) find_program(CUDAToolkit_NVCC_EXECUTABLE NAMES nvcc nvcc.exe @@ -775,6 +797,7 @@ else() endif() # Try user provided path + _CUDAToolkit_find_root_dir(COMPILER_PATHS) 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() diff --git a/Tests/Cuda/CMakeLists.txt b/Tests/Cuda/CMakeLists.txt index 04ef86d..c1952c5 100644 --- a/Tests/Cuda/CMakeLists.txt +++ b/Tests/Cuda/CMakeLists.txt @@ -27,6 +27,7 @@ add_cuda_test_macro(Cuda.ProperLinkFlags ProperLinkFlags) if(CMake_TEST_CUDA AND NOT CMake_TEST_CUDA STREQUAL "Clang") # Clang lacks __CUDACC_VER*__ defines. add_cuda_test_macro(Cuda.ProperDeviceLibraries ProperDeviceLibraries) + add_cuda_test_macro(Cuda.ToolkitBeforeLang ToolkitBeforeLang) endif() add_cuda_test_macro(Cuda.WithC CudaWithC) diff --git a/Tests/Cuda/ToolkitBeforeLang/CMakeLists.txt b/Tests/Cuda/ToolkitBeforeLang/CMakeLists.txt new file mode 100644 index 0000000..6b97a21 --- /dev/null +++ b/Tests/Cuda/ToolkitBeforeLang/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.15) +project(ToolkitBeforeLang CXX) + +#Goal for this example: +# Validate that we use the same CUDA Toolkit as `enable_language(CUDA)` would find +find_package(CUDAToolkit REQUIRED) + +if(NOT DEFINED CUDAToolkit_VERSION) + message(FATAL_ERROR "expected CUDAToolkit variable CUDAToolkit_VERSION not found") +endif() + +enable_language(CUDA) + +message(STATUS "CUDAToolkit_NVCC_EXECUTABLE ${CUDAToolkit_NVCC_EXECUTABLE}") +message(STATUS "CMAKE_CUDA_COMPILER ${CMAKE_CUDA_COMPILER}") + +if( NOT CUDAToolkit_NVCC_EXECUTABLE STREQUAL CMAKE_CUDA_COMPILER) + message(FATAL_ERROR "CUDAToolkit_NVCC_EXECUTABLE ${CUDAToolkit_NVCC_EXECUTABLE} doesn't match CMAKE_CUDA_COMPILER ${CMAKE_CUDA_COMPILER}") +endif() + +add_executable(ToolkitBeforeLang main.cpp) +target_link_libraries(ToolkitBeforeLang PRIVATE CUDA::toolkit) diff --git a/Tests/Cuda/ToolkitBeforeLang/main.cpp b/Tests/Cuda/ToolkitBeforeLang/main.cpp new file mode 100644 index 0000000..c8d5c6b --- /dev/null +++ b/Tests/Cuda/ToolkitBeforeLang/main.cpp @@ -0,0 +1,8 @@ +// Only thing we care about is that these headers are found +#include +#include + +int main() +{ + return 0; +} -- cgit v0.12