CMake + CUDA + 可分离编译->“nvcc 不知道如何处理''”

Posted

技术标签:

【中文标题】CMake + CUDA + 可分离编译->“nvcc 不知道如何处理\'\'”【英文标题】:CMake + CUDA + separable compilation -> "nvcc doesn't know what to do with ' ' "CMake + CUDA + 可分离编译->“nvcc 不知道如何处理''” 【发布时间】:2018-02-15 11:56:10 【问题描述】:

我将 CMake 用于我的一个涉及 CUDA 的项目。最近我不得不打开我的一些 CUDA 代码的“可分离编译”:

set(CUDA_SEPARABLE_COMPILATION ON)

但是,构建开始失败。例如,会发生以下情况:

/usr/local/cuda/bin/nvcc -gencode arch=compute_30,code=compute_30 --std=c++11 \
   -Xcompiler -Wall -O3 -DNDEBUG "" "" "" "" -m64 -ccbin /usr/bin/cc \
   -dlink /some/where/generated_foo.cu.o -o /some/where/foo_intermediate_link.o
nvcc fatal   : Don't know what to do with ''

(为了便于阅读,换行并缩短名称)

所以,问题是某些东西会触发 CMake 向命令行添加一些空(带引号的)字符串,这是 nvcc 不喜欢的。除此之外,该命令似乎很好。

现在,-O3 -DNDEBUG 是我发布版本的 nvcc 编译标志。但我肯定没有在任何地方添加任何空字符串标志。我尝试研究 FindCUDA 如何构造 nvcc 调用,但无法完全弄清楚这些空字符串的来源。

如果不详细说明我的CMakeLists.txt,这可能是 CMake 的 FindaCUDA 模块的一个众所周知的问题,它有一个通用的解决方法?

注意:我使用 GNU/Linux Mint 18.3、CMake 3.5 和 CUDA 9.1。

【问题讨论】:

【参考方案1】:

原来这一个已知的CMake issue。

解决方法是只为活动构建配置设置特定于构建配置的编译标志,例如而不是:

set(CUDA_NVCC_FLAGS_RELEASE $CUDA_NVCC_FLAGS_RELEASE -O3)
set(CUDA_NVCC_FLAGS_DEBUG $CUDA_NVCC_FLAGS_DEBUG -g --generate-line-info)

在您的CMakeLists.txt 中,使用:

if (CMAKE_BUILD_TYPE_UPPER STREQUAL "RELEASE")
    set(CUDA_NVCC_FLAGS_RELEASE $CUDA_NVCC_FLAGS_RELEASE -O3)
elseif (CMAKE_BUILD_TYPE_UPPER STREQUAL "DEBUG")
    set(CUDA_NVCC_FLAGS_DEBUG $CUDA_NVCC_FLAGS_DEBUG -g --generate-line-info)
endif (CMAKE_BUILD_TYPE_UPPER STREQUAL "RELEASE")

改为(如果您有多种构建类型,则可能会出现更多情况)。

另一种可能的选择是根本不使用 FindCUDA,因为 CMake 已添加对 CUDA 作为“一流”语言的支持,从某些 3.X 版本开始(不确定 X 是什么)。

【讨论】:

以上是关于CMake + CUDA + 可分离编译->“nvcc 不知道如何处理''”的主要内容,如果未能解决你的问题,请参考以下文章

CUDA可分离编译+共享库->无效的设备功能/段错误

使用cmake和3.5计算功能编译CUDA代码

即使在构建可执行文件时,CMake 3.0 + Fortran + CUDA也需要-fPIC

CMake 3.x + CUDA - 编译失败

vs2017+opencv+qt+cuda,使用cmake编译opencv的库

CMake Error NOTFOUND CUDA_nppi_LIBRARY (ADVANCED)