为何启用CUDA分离编译时CMake会强制链接libcublas?
为什么启用
CUDA_SEPARABLE_COMPILATION后CMake会自动链接cublas_device? 这个问题是旧版本CMake(比如你使用的3.11)处理CUDA分离编译时的一个“过度谨慎”的行为,咱们来拆解原因和解决办法:
问题原因
- 当开启
CUDA_SEPARABLE_COMPILATION ON时,CMake会触发CUDA的分离编译流程:先将每个CUDA源文件编译成中间目标文件,再通过nvcc -dlink生成统一的中间链接对象,最后和主机代码完成链接。 - 在CMake 3.11版本中,它会默认把一批CUDA核心库(包括
libcublas_device.a)添加到dlink的依赖列表里——哪怕你的项目完全没用到这些库。CMake的初衷是避免漏链潜在依赖,但这种一刀切的逻辑就导致无依赖项目也被强行加上了不必要的库。 - 而关闭
CUDA_SEPARABLE_COMPILATION后,CMake不会走-dlink这个中间步骤,直接将CUDA代码编译链接为最终可执行文件,自然也就不会添加这些额外库了。
解决办法
升级CMake版本(推荐)
后续CMake版本(比如3.18及以后)对CUDA分离编译的依赖处理做了优化,会智能识别项目实际用到的库,不再默认添加cublas_device这类不必要的依赖。如果环境允许,升级到较新的CMake是最彻底的解决方案。手动移除不必要的链接库(针对旧版本CMake)
如果你无法升级CMake,可以在CMakeLists.txt中手动移除自动添加的libcublas_device.a:cmake_minimum_required(VERSION 3.1) find_package(CUDA 7.0 REQUIRED) set(CUDA_SEPARABLE_COMPILATION ON) cuda_add_executable(dummy dummy.cu) # 移除不需要的cublas_device库 get_target_property(_dummy_link_libs dummy LINK_LIBRARIES) list(REMOVE_ITEM _dummy_link_libs ${CUDA_cublas_device_LIBRARY}) set_target_properties(dummy PROPERTIES LINK_LIBRARIES "${_dummy_link_libs}")这段代码会先获取目标当前的链接库列表,移除
cublas_device后重新设置目标的链接属性。关闭分离编译(如果适用)
像你已经发现的那样,如果你的小型项目不需要分离编译(分离编译主要用于大型CUDA项目,拆分编译单元提升编译速度),直接保持CUDA_SEPARABLE_COMPILATION OFF就能避免这个问题,这也是最简单的临时方案。
内容的提问来源于stack exchange,提问作者einpoklum
相关产品推荐
相关产品推荐

