CMake + CUDA + 可分离编译 -> "nvcc doesn't know what to do with ' ' "
CMake + CUDA + separable compilation -> "nvcc doesn't know what to do with ' ' "
我在一个涉及CUDA的项目中使用CMake。最近我不得不打开我的一些 CUDA 代码的 "separable compilation":
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。
原来这个是一个已知的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 作为 "first-class" 语言的支持,从某些 3.X 版本开始(不确定 X 是什么)。
我在一个涉及CUDA的项目中使用CMake。最近我不得不打开我的一些 CUDA 代码的 "separable compilation":
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。
原来这个是一个已知的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 作为 "first-class" 语言的支持,从某些 3.X 版本开始(不确定 X 是什么)。