CMake CUDA 在 Windows 上单独编译静态库链接错误,但在 Ubuntu 上没有

WDC*_*WDC 6 c++ cuda cmake

我正在使用 CMake 编译一个 CUDA 项目,其中包含一个静态库和一个主文件。MWE在这里。目录是:

??? CMakeLists.txt ??? src ??? mylib.h ??? mylib.cu ??? test ??? CMakeLists.txt ??? main.cpp

在 Ubuntu 上一切正常。但是在 Windows 上,我收到了一个链接错误:

mylib.lib(mylib.cu.obj) : error LNK2019: unresolved external symbol __cudaRegisterLinkedBinary_40_tmpxft_00006024_00000000_7_mylib_cpp1_ii_935b38c5 referenced in function "void __cdecl __sti____cudaRegisterAll(void)" (?__sti____cudaRegisterAll@@YAXXZ)\build\test\Release\main.exe : fatal error LNK1120: 1 unresolved externals
Run Code Online (Sandbox Code Playgroud)

这个问题只涉及第一个CMakeLists.txt

cmake_minimum_required(VERSION 3.8)
project(MyTest LANGUAGES CXX CUDA)

# check requirements
find_package(CUDA   8.0 REQUIRED)

# set include and link directories
if (UNIX)
    set(CUDA_SAMPLE_INC ${CUDA_TOOLKIT_ROOT_DIR}/samples/common/inc)
    set(CUDA_TARGET_INC ${CUDA_TOOLKIT_ROOT_DIR}/targets/x86_64-linux/include)
    set(CUDA_SAMPLE_LKN ${CUDA_TOOLKIT_ROOT_DIR}/targets/x86_64-linux/lib)
endif (UNIX)
if (WIN32)
    set(CUDA_SAMPLE_INC C:/ProgramData/NVIDIA\ Corporation/CUDA\ Samples/v9.0/common/inc)
    set(CUDA_TARGET_INC C:/Program\ Files/NVIDIA GPU\ Computing\ Toolkit/CUDA/v9.0/include)
    set(CUDA_SAMPLE_LKN C:/Program\ Files/NVIDIA\ GPU\ Computing\ Toolkit/CUDA/v9.0/lib/x64)
endif (WIN32)
include_directories(src ${CUDA_SAMPLE_INC} ${CUDA_TARGET_INC})
link_directories(${CUDA_SAMPLE_LKN})

# define and compile our static library 
set(STATIC_MY_LIB mylib)
add_library(${STATIC_MY_LIB} STATIC src/mylib.cu)

# install
install(TARGETS ${STATIC_MY_LIB}
        ARCHIVE DESTINATION ${CMAKE_SOURCE_DIR}/lib
        LIBRARY DESTINATION ${CMAKE_SOURCE_DIR}/lib)

# comment it out to suppress the error
set_target_properties( ${STATIC_MY_LIB} PROPERTIES CUDA_SEPARABLE_COMPILATION ON)

# add our test project
add_subdirectory(test)
Run Code Online (Sandbox Code Playgroud)

如果我注释掉set_target_properties( ${STATIC_MY_LIB} PROPERTIES CUDA_SEPARABLE_COMPILATION ON),链接错误就消失了。

环境:

  • Ubuntu 16.04、gcc 5.4、Tesla Titan X、CUDA 9.1、CMake 3.10.1
  • Windows 10、VS 2015、K20c、CUDA 9.0、CMake 3.10.1

我已经尝试过12 中的建议。但它们都不起作用。

为什么会发生这种情况?以及如何克服?

JAu*_*tin 11

在为这个问题挣扎了几天之后,我想我已经找到了解决方案。使用CMake创建静态库时,设置CUDA_RESOLVE_DEVICE_SYMBOLS,即用

set_target_properties(your_project PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS ON)

根据Nvidia 的这篇文章,此设置强制 CMake 在构建库时编译和链接所有 CUDA 符号(函数调用等)。

如果您需要在共享库或可执行文件使用之前进行可分离的编译设备链接,您可以通过设置目标属性 CUDA_RESOLVE_DEVICE_SYMBOLS 显式请求 CMake 调用设备链接