- 构建工具
- 开发工具
- CLI
【免费下载链接】CMake
Mirror of CMake upstream repository
导读
FindCUDAToolkit是 CMake 提供的一个 find 模块,用于定位 NVIDIA CUDA Toolkit 及其关联库(cudart、cuBLAS、cuFFT、NPP 等),并且不要求项目启用CUDA语言。这意味着你可以用纯 C/C++ 项目调用find_package(CUDAToolkit),通过CUDA::cudart、CUDA::cublas等导入目标直接链接 GPU 库,而无须让 nvcc 参与整个项目的编译。读完本文你将掌握:该模块的完整搜索顺序与版本探测机制、全部导入目标及其引入的 CUDA 版本前提、结果变量的含义,以及结合源码与测试用例的最佳实践。
模块定位与设计动机
FindCUDAToolkit自CMake 3.17引入(Help/module/FindCUDAToolkit.rst首行即标注versionadded:: 3.17),其核心设计目标在模块文档中写得非常明确:
Finds the NVIDIA CUDA toolkit and the associated libraries, but does not require the
CUDAlanguage be enabled for a given project.
也就是说,它把「查找 CUDA 安装」这件事从「编译 CUDA 源码」中解耦出来。典型场景包括:
- 项目主体用 C/C++ 编写,只需调用
cudaMalloc/cudaFree等 Runtime API,用 nvcc 编译整个项目成本过高; - 只想链接 cuBLAS、cuFFT、NPP 等库而本身不写
.cu文件; - 需要在使用
enable_language(CUDA)之前先拿到 CUDA 的路径与版本信息。
注意两个边界:该模块不搜索 NVIDIA CUDA Samples(模块文档明确说明);模块文档同时标注了QNX 支持自 3.19 起(versionadded:: 3.19)。
该模块的前身是历史悠久的FindCUDA.cmake,源码开头注释NOTE: much of this was simply extracted from FindCUDA.cmake.直接点明了继承关系——代码最初源自 NVIDIA 的 James Bigler 与犹他大学 SCI 研究所的 Abe Stephens 编写的 FindCuda 脚本(Modules/FindCUDAToolkit.cmake)。
基础用法与参数
基本语法
模块文档给出的调用形式为:
find_package(CUDAToolkit [<version>] [QUIET] [REQUIRED] [EXACT] [...])最小可用写法:
find_package(CUDAToolkit REQUIRED)一旦找到,即可直接用导入目标链接 CUDA Runtime:
add_executable(my_app main.cpp) target_link_libraries(my_app PRIVATE CUDA::cudart)参数语义
| 参数 | 含义 |
|---|---|
[<version>] | 请求一个兼容的 CUDA Toolkit 版本,版本格式遵循find_package版本格式 的约定 |
REQUIRED | 找不到合适的 CUDA Toolkit 时配置直接报错 |
QUIET | 搜索过程不输出任何消息 |
EXACT | 只有找到与VERSION完全一致的 CUDA Toolkit 才算找到 |
版本比较由find_package_handle_standard_args完成。源码中模块通过include(FindPackageHandleStandardArgs)与find_package_handle_standard_args(CUDAToolkit ...)(Modules/FindCUDAToolkit.cmake)将CUDAToolkit_INCLUDE_DIRECTORIES、CUDA_CUDART、CUDAToolkit_BIN_DIR作为必需变量,并以CUDAToolkit_VERSION作为版本比较依据。
与 CUDA 语言的关系
模块允许项目不启用CUDA语言,这是它与enable_language(CUDA)最主要的区别。仓库测试Tests/Cuda/Toolkit/CMakeLists.txt就是这一场景的直接验证:project(Toolkit CXX)只启用 CXX,然后find_package(CUDAToolkit REQUIRED),再逐个断言CUDA::cudart、CUDA::cuda_driver、CUDA::cublas、CUDA::cufft、CUDA::curand、CUDA::cusolver、CUDA::cusparse等目标存在(Tests/Cuda/Toolkit/CMakeLists.txt#L37-L90)。
反过来,如果项目启用了 CUDA 语言,模块也会优先复用语言探测阶段已确定的工具链路径(见下文搜索顺序第 1 条),保证CUDAToolkit_NVCC_EXECUTABLE与CMAKE_CUDA_COMPILER一致——这正是Tests/Cuda/ToolkitBeforeLang/CMakeLists.txt的测试目标:
find_package(CUDAToolkit REQUIRED) enable_language(CUDA) 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()搜索行为详解:七级优先级
模块文档给出了完整的搜索顺序,源码Modules/FindCUDAToolkit.cmake中的实际执行顺序与文档严格对应:
1. 已启用 CUDA 语言时,优先使用编译器所在目录
若CMAKE_CUDA_COMPILER_LOADED且编译器 ID 为NVIDIA,则先由CMAKE_CUDA_COMPILER所在目录推导CUDAToolkit_BIN_DIR(源码Modules/FindCUDAToolkit.cmake#L981-L988)。更进一步,当语言探测已完成时,模块直接复用编译器探测阶段缓存的结果——CMAKE_CUDA_COMPILER_TOOLKIT_ROOT、CMAKE_CUDA_COMPILER_LIBRARY_ROOT、CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES等变量(Modules/FindCUDAToolkit.cmake#L675-L695),"to avoid re-searching and to avoid finding a possibly different installation",即避免重复搜索、避免命中另一套安装。
2.CMAKE_CUDA_COMPILER或环境变量CUDACXX
若定义了CMAKE_CUDA_COMPILER或环境变量CUDACXX,将其作为 nvcc 的路径线索(源码通过COMPILER_PATHS分支处理,Modules/FindCUDAToolkit.cmake#L990-L993)。该分支对clang这类非 nvcc 编译器也做了兼容——注释 "need to find parent dir, since this could clang and not nvcc"(Modules/FindCUDAToolkit.cmake#L702),即从 clang 所在目录寻找同目录的 nvcc。
3.CUDAToolkit_ROOT(配置变量优先于环境变量)
CMake 配置变量CUDAToolkit_ROOT(如-DCUDAToolkit_ROOT=/some/path)或同名环境变量均会被搜索;若两者同时指定,配置变量优先。源码中先尝试配置变量并在此失败时直接报错(Modules/FindCUDAToolkit.cmake#L995-L1002),再尝试环境变量并报错(Modules/FindCUDAToolkit.cmake#L1004-L1010),与文档描述一致。
该目录必须满足:在指定目录下能找到nvcc可执行文件,或合适的version.txt/version.json文件(后两者即"哨兵文件"CUDAToolkit_SENTINEL_FILE,源码Modules/FindCUDAToolkit.cmake#L727-L732)。
4. 环境变量CUDA_PATH
CUDA_PATH环境变量定义时,在其中搜索 nvcc(源码Modules/FindCUDAToolkit.cmake#L1012-L1015)。
5. 用户的PATH
通过find_program在用户 PATH 中查找nvcc;一旦在 PATH 中找到,就不再继续后续搜索。因此当机器上装有多个 CUDA Toolkit 时,用户须自行保证 PATH 中第一个nvcc是想要的版本。
6. Unix 符号链接/usr/local/cuda
Unix 系统上若存在符号链接/usr/local/cuda,直接使用,不再继续搜索;Windows 平台不存在默认符号链接位置。源码中_CUDAToolkit_guess_root_dir会把/usr/local/cuda强制插入搜索列表首位(Modules/FindCUDAToolkit.cmake#L900-L903)。
7. 平台默认安装位置
按平台搜索默认安装位置,只有恰好找到一个候选时才使用:
| 平台 | 搜索模式 |
|---|---|
| macOS | /Developer/NVIDIA/CUDA-X.Y |
| 其他 Unix | /usr/local/cuda-X.Y |
| Windows | C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y |
其中X.Y是具体版本号,如/usr/local/cuda-9.0、C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0。源码实现会对所有候选路径按版本号降序排列(list(SORT versions COMPARE NATURAL ORDER DESCENDING),Modules/FindCUDAToolkit.cmake#L892),优先尝试较新版本。
多版本并存的特殊情形
文档特别给出警告:当系统默认位置安装了多个 CUDA Toolkit(例如/usr/local/cuda-9.0和/usr/local/cuda-10.0同时存在,但/usr/local/cuda符号链接不存在)时,本模块判定为未找到。理由是在这种局面下自动决策涉及因素过多。文档给出的建议是:要么设置CUDAToolkit_ROOT,要么确保正确的nvcc出现在$PATH中供find_program找到。失败时的报错文案也写得很明确:Could not find 'nvcc' executable in any searched paths, please set CUDAToolkit_ROOT(Modules/FindCUDAToolkit.cmake#L962)。
版本探测机制:nvcc 输出与版本文件
模块通过三种途径确定版本(Modules/FindCUDAToolkit.cmake#L1032-L1058),优先级如下:
- 编译器缓存版本:当
CUDAToolkit_NVCC_EXECUTABLE与CMAKE_CUDA_COMPILER完全一致且CMAKE_CUDA_COMPILER_VERSION已知时,直接复用该值; - 执行
nvcc --version:解析输出中的V(\d+)\.(\d+)\.(\d+)模式; - 解析版本文件:
version.txt(匹配CUDA Version (\d+)\.(\d+)\.(\d+))或version.json(读取cuda.version字段),见_CUDAToolkit_parse_version_file(Modules/FindCUDAToolkit.cmake#L938-L957)。
此外,在已启用 CUDA 语言的情况下,模块还会执行nvcc -v并解析其输出中的#\$ TOP=、#\$ INCLUDES=、#\$ SYSTEM_INCLUDES=、#\$ LIBRARIES=行,来推导 BIN 目录、隐式头文件目录与隐式链接目录(Modules/FindCUDAToolkit.cmake#L775-L827),并使用CMakeParseImplicitLinkInfo.cmake解析隐式链接信息。这也正是模块能支持 ccache/colornvcc 包装脚本、NVIDIA HPC SDK(NVHPC)以及发行版散落布局(splayed layouts)的原因(源码注释Modules/FindCUDAToolkit.cmake#L736-L739)。
导入目标总览
模块文档给出的核心交付物是CUDA::toolkit与一系列CUDA::前缀的导入目标。自 CMake 4.5 起(文档versionadded:: 4.5),每个目标还提供了对应的CUDAToolkit::命名空间别名;两个命名空间指向同一底层目标,可混用。
完整清单如下:
- CUDA Runtime Library:
CUDA::cudart、CUDA::cudart_static - CUDA Driver Library:
CUDA::cuda_driver - cuBLAS:
CUDA::cublas、CUDA::cublas_static、CUDA::cublasLt(CUDA 10.1 起)、CUDA::cublasLt_static(CUDA 10.1 起) - cuDLA(3.27 起):
CUDA::cudla(CUDA 11.6 起) - cuFile(3.25 起):
CUDA::cuFile、CUDA::cuFile_static、CUDA::cuFile_rdma、CUDA::cuFile_rdma_static(均 CUDA 11.4 起) - cuFFT:
CUDA::cufft、CUDA::cufftw、CUDA::cufft_static、CUDA::cufft_static_nocallback(CUDA 9.2 起,需 CMake 3.23+)、CUDA::cufftw_static - cuRAND:
CUDA::curand、CUDA::curand_static - cuSOLVER:
CUDA::cusolver、CUDA::cusolver_static - cuSPARSE:
CUDA::cusparse、CUDA::cusparse_static - cuPTI:
CUDA::cupti、CUDA::cupti_static,以及 3.27 起新增的CUDA::nvperf_host/_static(CUDA 10.2 起)、CUDA::nvperf_target(CUDA 10.2 起)、CUDA::pcsamplingutil(CUDA 11.3 起) - NPP(全套):
CUDA::nppc、nppial、nppicc、nppicom、nppidei、nppif、nppig、nppim、nppist、nppisu、nppitc、npps及各自_static变体 - nvBLAS:
CUDA::nvblas(仅共享库) - nvGRAPH:
CUDA::nvgraph、CUDA::nvgraph_static(CUDA 11.0 起移除) - nvJPEG:
CUDA::nvjpeg、CUDA::nvjpeg_static(CUDA 10 引入) - nvPTX Compiler(3.25 起):
CUDA::nvptxcompiler_static(CUDA 11.1 起,仅静态库) - nvRTC:
CUDA::nvrtc;3.26 起增加CUDA::nvrtc_builtins、CUDA::nvrtc_static(CUDA 11.5 起)、CUDA::nvrtc_builtins_static(CUDA 11.5 起) - nvJitLink:
CUDA::nvJitLink、CUDA::nvJitLink_static(均 CUDA 12.0 起) - nvFatBin(3.30 起):
CUDA::nvfatbin、CUDA::nvfatbin_static(均 CUDA 12.4 起) - nvidia-ML:
CUDA::nvml;3.31 起增加CUDA::nvml_static(CUDA 12.4 起) - nvToolsExt(3.25 起标记弃用):
CUDA::nvToolsExt(仅共享库;CUDA 12.9 起该库不再存在) - nvtx3(3.25 起):
CUDA::nvtx3(仅头文件);4.1 起增加CUDA::nvtx3_interop(CUDA 12.9 起提供,供 Fortran 等无法消费 C++ 头文件的语言使用) - OpenCL:
CUDA::OpenCL(仅共享库) - cuLIBOS:
CUDA::culibos(仅静态库) - bin2c(4.3 起):
CUDA::bin2c(把二进制文件转换为包含字节数组的 C 文件的工具) - compute-sanitizer(4.4 起):
CUDA::sanitizer(用于追踪 CUDA runtime/driver 调用的库) - cufilt(4.4 起):
CUDA::cufilt(CUDA 11.4 起,由 cu++filt 提供的符号反修饰静态库)
关键库目标与底层依赖关系
Runtime 与 Driver
CUDA Runtime 库(cudart)是绝大多数应用所需的——所有cudaMalloc、cudaFree调用都来自它。Driver 库(cuda)则面向使用cuMemAlloc、cuMemFree等驱动 API 的应用。
源码中_CUDAToolkit_find_and_add_import_lib(Modules/FindCUDAToolkit.cmake#L1287-L1355)是所有库目标的统一构造器,它会依次在CUDAToolkit_LIBRARY_SEARCH_DIRS中按nvidia/current、lib64、Windows 的lib/x64等后缀查找,失败后才降级到 stub 目录(lib64/stubs等)。cudart的查找还单独处理了lib64与 stub 两轮(Modules/FindCUDAToolkit.cmake#L1176-L1185)。
值得注意的细节:cuda_driver与cudart/cudart_static都依赖内部目标CUDAToolkit::cudart_static_deps,后者在 Unix 上自动链接Threads::Threads与${CMAKE_DL_LIBS},在 Linux 上还会查找并链接librt——这是静态链接 CUDA runtime 的硬性要求(Modules/FindCUDAToolkit.cmake#L1367-L1384)。
cuLIBOS 与静态库依赖
cuLIBOS 是仅静态的"后端线程抽象层"库。CUDA::cublas_static、CUDA::cusparse_static、CUDA::cufft_static、CUDA::curand_static以及 NPP 静态库都会自动链接它(源码foreach (cuda_lib cublasLt cufft nvjpeg)等循环中DEPS cudart_static_deps culibos的写法,Modules/FindCUDAToolkit.cmake#L1402-L1409)。文档特别注明:消费者不应直接使用CUDA::culibos。
版本门槛驱动的目标创建
许多目标只在特定 CUDA 版本以上才会创建,源码中通过CUDAToolkit_VERSION VERSION_GREATER_EQUAL ...条件实现,例如:
- CUDA 12.0 起才创建
nvJitLink系列(Modules/FindCUDAToolkit.cmake#L1391-L1394); - CUDA 12.4 起才创建
nvfatbin系列(Modules/FindCUDAToolkit.cmake#L1396-L1399); - CUDA 11.0 起
cublas依赖cublasLt(Modules/FindCUDAToolkit.cmake#L1414-L1422); - CUDA 11.2.2 以上
cusolver额外依赖cusolver_metis_static与cublasLt,CUDA 10.1 Update 2 以上还依赖cusolver_lapack_static(Modules/FindCUDAToolkit.cmake#L1444-L1461); - nvGRAPH 依赖 cuRAND 与 cuSOLVER(
Modules/FindCUDAToolkit.cmake#L1466-L1467)。
这些依赖关系的存在意味着:你只需链接CUDA::cusolver_static,模块会替你串联好所有底层静态库,这是 FindCUDAToolkit 相对裸find_library方案的核心价值。
cuPTI 的特殊处理
cupti 头文件通常位于 Toolkit 的extras/CUPTI/include下,模块通过find_path专门搜索cupti.h(Modules/FindCUDAToolkit.cmake#L1475-L1481),并在找到后为其配置额外的库搜索后缀(extras/CUPTI/lib64/等)与额外头文件目录。仓库测试Tests/Cuda/Toolkit/CMakeLists.txt把 cupti 视为可选组件:if(TARGET CUDA::cupti)时才链接,并随版本追加nvperf_target、pcsamplingutil。
结果变量详解
模块在成功时设置以下变量(文档 Result Variables 一节),源码在Modules/FindCUDAToolkit.cmake#L1211-L1269构造它们:
| 变量 | 含义 |
|---|---|
CUDAToolkit_FOUND | 是否找到 CUDA Toolkit 的布尔值 |
CUDAToolkit_VERSION | 找到的 CUDA Toolkit 精确版本(来自nvcc --version、version.txt或version.json) |
CUDAToolkit_VERSION_MAJOR/_MINOR/_PATCH | 主/次/补丁版本号 |
CUDAToolkit_BIN_DIR | 包含 nvcc 可执行文件的目录 |
CUDAToolkit_INCLUDE_DIRS | 编译链接 CUDA 所需的所有头文件目录列表 |
CUDAToolkit_LIBRARY_DIR | 包含 CUDA Runtime 库cudart的库目录 |
CUDAToolkit_LIBRARY_ROOT | (3.18 起)包含 nvvm 目录以及version.txt/version.json的 Toolkit 目录 |
CUDAToolkit_TARGET_DIR | 交叉编译时包含目标架构的目录;非交叉编译时等价于CUDAToolkit_BIN_DIR的父目录 |
CUDAToolkit_NVCC_EXECUTABLE | nvcc 的路径。注意该路径可能不同于CMAKE_CUDA_COMPILER。找到 nvcc 是确定版本及其它特性的前提,此变量主要为依赖本模块的其他模块提供便利 |
其中CUDAToolkit_LIBRARY_ROOT的推导规则是:在CUDAToolkit_LIBRARY_DIR与CUDAToolkit_BIN_DIR的父目录中查找包含nvvm/子目录的那一个(Modules/FindCUDAToolkit.cmake#L1242-L1252);代码还修补了某些环境下CUDAToolkit_LIBRARY_ROOT被误设为targets/...目录的问题(Modules/FindCUDAToolkit.cmake#L1267-L1269)。
另外,模块内部还会设置CUDA_<lib>_LIBRARY系列缓存变量(如CUDA_cudart_LIBRARY、CUDA_cublas_LIBRARY),测试用例正是通过断言这些变量来验证查找结果的(Tests/Cuda/Toolkit/CMakeLists.txt)。
实战示例
最小 C++ 项目:仅链接 CUDA Runtime
不启用 CUDA 语言,直接使用 Runtime API:
cmake_minimum_required(VERSION 3.17) project(GpuApp CXX) find_package(CUDAToolkit REQUIRED) add_executable(gpu_app main.cpp) target_link_libraries(gpu_app PRIVATE CUDA::cudart)main.cpp中即可#include <cuda_runtime_api.h>并调用cudaMalloc/cudaFree。这与仓库测试Tests/Cuda/Toolkit/main.cpp的写法一致——该测试的头文件包含清单(cuda.h、cuda_runtime_api.h、nv/target、thrust/version.h)正是CUDA::toolkit目标提供 include 路径的验证。
链接多个库并做版本分支
参考Tests/Cuda/Toolkit/CMakeLists.txt,可以按版本条件化链接:
find_package(CUDAToolkit 11 REQUIRED) target_link_libraries(app PRIVATE CUDA::cudart CUDA::cublas CUDA::cufft) if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 10.1) target_link_libraries(app PRIVATE CUDA::cublasLt) endif() if(CUDAToolkit_VERSION_MAJOR VERSION_GREATER 11) target_link_libraries(app PRIVATE CUDA::nvJitLink) endif() if(TARGET CUDA::cupti) # cupti 是可选组件,存在才链接 target_link_libraries(app PRIVATE CUDA::cupti) endif()用 bin2c 把二进制资源转为 C 头文件
CUDA::bin2c是导入的可执行目标,可直接用于add_custom_command。仓库测试Tests/Cuda/Bin2C/CMakeLists.txt展示了标准用法:
find_package(CUDAToolkit REQUIRED) add_executable(generate generate.cpp) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/binary.bin COMMAND generate ${CMAKE_CURRENT_BINARY_DIR}/binary.bin ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/binary.h COMMAND CUDA::bin2c ${CMAKE_CURRENT_BINARY_DIR}/binary.bin > ${CMAKE_CURRENT_BINARY_DIR}/binary.h DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/binary.bin ) add_executable(CudaBin2C verify.cpp ${CMAKE_CURRENT_BINARY_DIR}/binary.h) target_include_directories(CudaBin2C PRIVATE ${CMAKE_CURRENT_BINARY_DIR})用 compute-sanitizer 做运行时检查
CUDA::sanitizer目标(4.4 起)既可链接进程序,也可作为追踪 CUDA 调用的手段。仓库测试Tests/Cuda/Sanitizer/CMakeLists.txt在 CUDA 10.1+ 上链接CUDAToolkit::sanitizer与CUDAToolkit::cudart_static并注册 ctest 用例,Windows 上还把 sanitizer 目录加入测试进程 PATH。
交叉编译与目标目录
当交叉编译(或没有 nvcc 时),模块需要推断目标架构。源码逻辑(Modules/FindCUDAToolkit.cmake#L1061-L1118):
- 依次取
CMAKE_CUDA_COMPILER_ARCHITECTURE_ID、CMAKE_CXX_COMPILER_ARCHITECTURE_ID、CMAKE_C_COMPILER_ARCHITECTURE_ID、CMAKE_SYSTEM_PROCESSOR作为目标处理器;交叉编译时若仍为空则直接FATAL_ERROR,要求设置CMAKE_SYSTEM_PROCESSOR; - 按架构映射目标子目录名:
armv7-a→armv7-linux-androideabi(NVPACK 支持)、arm→armv7-linux-gnueabihf、aarch64→ 按 Android/QNX/普通 Linux 分别映射、x86_64→x86_64-linux; - 在
${CUDAToolkit_ROOT_DIR}/targets/<name>下查找实际存在的目录,将结果写入CUDAToolkit_TARGET_DIR,并把该目录加入CMAKE_FIND_ROOT_PATH供后续库搜索使用,搜索完成后弹出(Modules/FindCUDAToolkit.cmake#L1099-L1112、L1625-L1628)。
Windows 平台的库后缀也按架构区分:AMD64/x64/ARM64EC 使用lib/x64,ARM64 使用lib/arm64(Modules/FindCUDAToolkit.cmake#L1121-L1132)。
另外,模块对 NVHPC(NVIDIA HPC SDK)的"散落布局"做了专门适配:当 nvcc 解析输出指向cuda/X.Y/targets/...布局时,会额外追加math_libs/与extras的搜索目录(Modules/FindCUDAToolkit.cmake#L1219-L1235),并将 math 库头文件目录../../math_libs/<major>.<minor>/include加入CUDAToolkit_INCLUDE_DIRECTORIES(Modules/FindCUDAToolkit.cmake#L1151-L1171)。
常见问题与排错
"Could not find nvcc executable"
对应三种失败文案(Modules/FindCUDAToolkit.cmake#L959-L979):
GUESS模式:Could not find 'nvcc' executable in any searched paths, please set CUDAToolkit_ROOTVARIABLE模式:Could not find 'nvcc' executable in path specified by variable CUDAToolkit_ROOT=...ENV模式:Could not find 'nvcc' executable in path specified by environment variable CUDAToolkit_ROOT=...
若指定了REQUIRED,直接FATAL_ERROR;否则降级为 STATUS 消息并置CUDAToolkit_FOUND=FALSE。解决思路:设置CUDAToolkit_ROOT(命令行或环境变量)指向 Toolkit 根目录,或把正确的 nvcc 目录放入 PATH。
多版本 Toolkit 并存导致"未找到"
回顾上文第 7 级搜索:默认位置存在多个cuda-X.Y且无/usr/local/cuda符号链接时模块判定未找到。按文档建议设置CUDAToolkit_ROOT或 PATH 即可。
nvToolsExt 已弃用
CUDA::nvToolsExt自 3.25 起被标记弃用:CUDA 10.0+ 应改用CUDA::nvtx3;从 CUDA 12.9 起 nvToolsExt 库本身已不存在。源码中当CMAKE_MINIMUM_REQUIRED_VERSION >= 3.25时会给该目标附加DEPRECATION属性,提示 "Use CUDAToolkit::nvtx3 and include <nvtx3/nvToolsExt.h> instead."(Modules/FindCUDAToolkit.cmake#L1562-L1584)。此外,Windows 上 nvToolsExt 可能独立安装在 Toolkit 之外,模块会优先使用NVTOOLSEXT_PATH环境变量查找(Modules/FindCUDAToolkit.cmake#L1566-L1573)。
失败后缓存清理
模块在未找到时会主动清理CUDA_CUDART、CUDAToolkit_BIN_DIR、CUDAToolkit_NVCC_EXECUTABLE、CUDAToolkit_SENTINEL_FILE等缓存项,避免旧结果污染后续配置(Modules/FindCUDAToolkit.cmake#L1253-L1261)。
相关资源
- 模块文档:
Help/module/FindCUDAToolkit.rst - 模块实现:
Modules/FindCUDAToolkit.cmake - 集成测试:
Tests/Cuda/Toolkit/CMakeLists.txt与Tests/Cuda/Toolkit/main.cpp(验证不启用 CUDA 语言时的目标与变量)、Tests/Cuda/ToolkitBeforeLang/CMakeLists.txt(验证与enable_language(CUDA)的一致性)、Tests/Cuda/Bin2C/CMakeLists.txt(bin2c 用法)、Tests/Cuda/Sanitizer/CMakeLists.txt(compute-sanitizer 用法)、Tests/Cuda/NotEnabled/CMakeLists.txt(无 CUDA 语言时 CUDA 相关 target 属性不报错) - 历史模块:
Modules/FindCUDA.cmake(FindCUDAToolkit 的代码来源) - 隐式链接解析:
Modules/CMakeParseImplicitLinkInfo.cmake
- 构建工具
- 开发工具
- CLI
【免费下载链接】CMake
Mirror of CMake upstream repository
相关推荐
PaddleNLP 中 ERNIE 1.0 模型中文情感分类推理部署实战指南
PaddleNLP 中 ERNIE 1.0 模型中文情感分类推理部署实战指南 ERNIE 1.0(Enhanced Representation through
构建工具开发工具CLIGraphene Python 枚举类型(Enum)完全指南:定义、描述、复用与底层实现
Graphene Python 枚举类型(Enum)完全指南:定义、描述、复用与底层实现 本篇技术指南以 Graphene(Python 的 GraphQL 框
构建工具开发工具CLICMake `enable_language()` 命令详解:按需启用 C/CXX/Fortran/CUDA 等编译语言
CMake enable_language 命令详解:按需启用 C/CXX/Fortran/CUDA 等编译语言 enable_language 是 CMake
构建工具开发工具CLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考