基于"Rosetta"的CMake原生CUDA支持迁移实操问题咨询
从旧版CUDA CMake命令迁移到原生CUDA支持(CMake 3.8+)
我帮不少开发者做过这种迁移,其实CMake 3.8+的原生CUDA支持设计得非常贴近常规C/C++的用法,根本不用记一堆新命令——核心思路就是把CUDA当成一种普通的编译语言来处理就行。下面逐个解答你的问题:
1. 如何设置全局CUDA相关CMake变量,例如分离编译、宿主标志传播?
- 分离编译:全局开启的话,直接设置
CMAKE_CUDA_SEPARABLE_COMPILATION为ON,这样所有CUDA目标都会默认启用分离编译。如果只是单个目标需要这个特性,用set_target_properties更灵活:set_target_properties(my_cuda_executable PROPERTIES CUDA_SEPARABLE_COMPILATION ON) - 宿主标志传播:CMake默认会把宿主编译器(比如GCC/Clang)的编译标志自动同步给CUDA的宿主代码部分。如果你想手动指定宿主编译器,可以设置
CMAKE_CUDA_HOST_COMPILER;要是需要给CUDA单独加编译选项,用CMAKE_CUDA_FLAGS就行,宿主代码的标志还是保留在CMAKE_CXX_FLAGS里。注意有些宿主标志CUDA编译器不支持,这时可以用生成器表达式区分语言:target_compile_options(my_target PRIVATE $<COMPILE_LANGUAGE:CXX>:-Wall $<COMPILE_LANGUAGE:CUDA>:-Wno-deprecated-gpu-targets )
2. 如何调用与CMAKE_CXX_STANDARD等效的CUDA相关命令?
完全和C++的用法对应!CMake提供了三套直接对应的变量:
CMAKE_CUDA_STANDARD:设置全局CUDA语言标准(比如11、17)CMAKE_CUDA_STANDARD_REQUIRED:强制要求编译器支持指定的标准,不兼容就报错CMAKE_CUDA_EXTENSIONS:是否允许编译器扩展(比如CUDA的专有语法)
全局设置示例:
set(CMAKE_CUDA_STANDARD 17) set(CMAKE_CUDA_STANDARD_REQUIRED ON) set(CMAKE_CUDA_EXTENSIONS OFF)
如果只想给单个目标设置,同样用set_target_properties:
set_target_properties(my_cuda_lib PROPERTIES CUDA_STANDARD 17)
3. 如何添加默认不需要的CUDA库依赖(如NVTX)?
和添加普通C++库依赖的流程完全一致,用find_package找到库,再用target_link_libraries链接到目标即可。以NVTX为例:
# 先找到CUDA Toolkit(NVTX随Toolkit安装) find_package(CUDAToolkit REQUIRED) # 将NVTX链接到目标(PRIVATE表示仅当前目标使用) target_link_libraries(my_cuda_target PRIVATE CUDA::nvtx3)
其他CUDA相关库比如cuBLAS、cuDNN,也可以用CUDA::cublas、CUDA::cudnn这类预定义的别名,CMake的CUDAToolkit模块已经帮你封装好了路径和依赖,不用手动找文件。
4. 其他相关操作该如何处理?是否有统一方法?
当然有统一方法——把CUDA当成和C++完全平等的语言,所有你熟悉的C++相关CMake操作,几乎都能直接套用到CUDA上:
- 添加源文件:直接把
.cu文件加到add_executable或add_library里,再也不用cuda_add_executable这类旧命令 - 包含目录:用
target_include_directories,CUDA目标会自动识别并使用这些目录 - 编译定义:
target_compile_definitions同样对.cu文件生效 - 目标属性:比如
POSITION_INDEPENDENT_CODE,设置后CUDA代码也会生成位置无关代码,和C++代码一致
需要额外注意的几个小细节:
- 必须先启用CUDA语言:要么在
project命令里指定LANGUAGES CXX CUDA,要么单独调用enable_language(CUDA)(建议放在project之后) - 如果用到CUDA动态并行,需要确保目标开启了分离编译,或者手动在
CMAKE_CUDA_FLAGS里加-rdc=true - 可以用
CMAKE_CUDA_COMPILER_VERSION检查CUDA编译器版本,比如做版本兼容判断:if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "11.0") target_compile_definitions(my_target PRIVATE USE_CUDA_11_FEATURES) endif()
内容的提问来源于stack exchange,提问作者einpoklum
相关产品推荐
相关产品推荐

