c++ - 使用 CMake 为 CUDA 构建多配置/多平台

标签 c++ linux visual-studio cuda

我最近与 CMake 发生了一些争执,试图让它在涉及 Cuda 的不同平台上为调试和发布目标生成项目文件。我在 Windows 和 Linux 上使用的 Cuda 版本是 9.1。 CMake 版本在 Windows 上为 3.9,在 Linux 上为 3.10。

问题实际上很简单,因为如果 nvcc 正确传递了 "-DEBUG" 标志,我可以在 Windows 上生成构建。但是,我似乎无法通过配置自动正确传递标志。我尝试使用 CMAKE_NVCC_FLAGS_CONFIGCMAKE_CXX_FLAGS_CONFIG 并将 CUDA_PROPAGATE_HOST_FLAGS 设置为 ON/OFF,切换 CUDA_HOST_COMPILATION_CPPON/OFF 也没有帮助。使用表达式生成器设置标志以使用 set_directory_property 设置目录属性,或作为 cuda_add_executable 的选项也不起作用。

这是我的 cmake 脚本的要点:

# CMake entry point
cmake_minimum_required (VERSION 3.9.1)

set( APP_NAME example-CUDA )

find_package(XYZ)
find_package(CUDA)  # not required according to 1st-class status in CMake3 .8+

enable_language(CUDA)
set(CUDA_VERBOSE_BUILD ON)

set(SRC_EXAMPLE "main.cpp" "gj.cu"  "gj.cuh")
SOURCE_GROUP(Example FILES ${SRC_EXAMPLE})

set(SRC_BUILD_FILES ${SRC_EXAMPLE})

# note: similar stuff for linux ommitted..
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX /sdl- -Zm256")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MD")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /we4146 /we4308 /we4532 /we4533 /we4700 /we4703 /we4789 /we4995 /we4996")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /INCREMENTAL")
    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MP")
    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /we4146 /we4308 /we4532 /we4533 /we4700 /we4703 /we4789 /we4995 /we4996")
    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W4 /WX /sdl- -Zm256")
    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Zi")
    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG" CACHE STRING "compile flags debug" FORCE)
endif()

# cuda 9 flags for max compatibility ( note: no more sm 20!)
set(CUDA_NVCC_FLAGS   ${CUDA_NVCC_FLAGS}    "-arch=sm_30 -gencode=arch=compute_30,code=sm_30 -gencode=arch=compute_50,code=sm_50 -gencode=arch=compute_52,code=sm_52 -gencode=arch=compute_60,code=sm_60 -gencode=arch=compute_61,code=sm_61 -gencode=arch=compute_62,code=sm_62 -gencode=arch=compute_70,code=sm_70 -gencode=arch=compute_70,code=compute_70")

include_directories(SYSTEM  ${CUDA_TOOLKIT_INCLUDE} ${CMAKE_CURRENT_SOURCE_DIR})

#set(CUDA_HOST_COMPILATION_CPP ON) 
#set(CUDA_PROPAGATE_HOST_FLAGS ON)

#set(CUDA_NVCC_FLAGS   ${CUDA_NVCC_FLAGS}   " -D_DEBUG ")             # works, but hadcoded config :(

set(CUDA_NVCC_FLAGS_DEBUG   ${CUDA_NVCC_FLAGS_DEBUG}    " -D_DEBUG ") # fails, not picked up..

#cuda_add_executable (${APP_NAME} ${SRC_EXAMPLE} OPTIONS $<$<CONFIG:Debug>:"-DEBUG">) #fails, generator not run

cuda_add_executable (${APP_NAME} ${SRC_EXAMPLE})
target_link_libraries (${APP_NAME} PUBLIC CUDA XYZ)

我在 VS2015(我也在使用 2017)中得到的错误是典型的 _ITERATOR_DEBUG_LEVEL 不正确,这意味着其中一个编译单元没有正确传递 -DEBUG 标志,链接器看到 rebug 和 release 模块混合.由 nvcc.exe 构建的模块在内部传递给 cl.exe 用于非 cuda 代码位的编译,除了缺少所有 _DEBUG 配置标志。我通读了 FindCUDA.cmake 以找到一些有趣的东西,但几乎不可能分辨什么有效,什么无效。

我显然遗漏了什么,但是什么?有什么解决方法吗?

更新 1:我还在 CMakeLists.txt 层次结构的前面设置了以下方式:

project (MyLittleBigProject)

# Set default build type
set(PROJECT_CONFIGURATIONS      Debug Release               CACHE TYPE INTERNAL FORCE)
if(DEFINED CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Build configs: ${PROJECT_CONFIGURATIONS}")
else()
    set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build configs: ${PROJECT_CONFIGURATIONS}")
endif()

最佳答案

我不了解 CUDA/NVCC,但查看 FindCUDA 的文档,这里有一些您可以尝试的事情:

  • 通过 CMAKE_C_FLAGS_DEBUG 传递调试标志,因为 CUDA_HOST_COMPILER 的文档声明默认使用 CMAKE_C_COMPILER,而不是 CMAKE_CXX_COMPILER,
  • 通过 cuda_add_executable() 传递调试标志:文档表明它调用了 cuda_wrap_srcs(),您可以在其中通过 OPTIONS DEBUG ...

希望这对您有所帮助。

关于c++ - 使用 CMake 为 CUDA 构建多配置/多平台,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48763601/

相关文章:

c++ - 无法链接 C++ 代码

c++ - 将回调从 C++ 转换为 C++/CX

c++ - 使用额外列的行转置密码

c++ - 永不结束的 war 游戏

windows - 我应该在 64 位版本中同时定义 _WIN32 和 _WIN64 吗?

c# - 我如何使用 Javascript 获取 ASP.Net 网格元素

c - 查找共享库函数中定义的局部变量的地址

linux - 如何在 LESS 中找到 "/*"?

linux - 使用 bash 检查 FTP 登录数据

c# - 在 VS 2015 和 VS 2013 上运行同一段代码时出现问题