CMAKE:错误的链接器g ++用于CUDA库链接的可执行文件

问题描述

我有一个基于CUDA的静态库(.cu和.cpp文件的混合物),我试图将其链接到测试文件test.cu,该文件将包含库中的lib_file_1.cuh。因此,我想将我的.cu可执行文件链接到我的CUDA库,直到现在,在链接器步骤中使用g ++代替nvcc。 如何解决此问题?,因为由于错误的链接,我现在只收到undefined reference to "__cudaRegisterLinkedBinary_name_..."类型的错误。

根目录,根目录/ my_library和根目录/测试代码中的以下CMakeLists.txt文件应该可以重现该问题。

根:

cmake_minimum_required(VERSION 3.17.3)
project(library_test LANGUAGES CUDA CXX)

if (MSVC)
    add_compile_options(/W4)
else()
    add_compile_options(-Wall -Wextra -fno-omit-frame-pointer -g)
endif()

add_subdirectory(my_library)
add_subdirectory(test)

set(CMAKE_VERBOSE_MAKEFILE ON)

target_link_libraries(tester PRIVATE my_library)

在root / my_library中:

find_package(CUDA COMPONENTS THRUST REQUIRED)

add_library(my_library STATIC src/lib_file_1.cu)

target_include_directories(my_library PUBLIC 
    include
    ${CUDA_INCLUDE_DIRS}
)

target_compile_options(my_library
    PRIVATE $<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler -Wno-pedantic -dc -gencode arch=compute_61,code=sm_61 --expt-relaxed-constexpr -Xlinker -dlink>
)

target_link_libraries(my_library
    PUBLIC ${CUDA_LIBRARIES}
)

在根目录/测试中:

add_executable(tester test.cu)

target_include_directories(tester PUBLIC
    ${CMAKE_SOURCE_DIR}/my_library
    )

让实例lib_file_1.cuh为:

#include <thrust/device_vector.h>

__host__ __device__ void foo(double &r);

lib_file_1.cu

#include <thrust/device_vector.h>
#include "lib_file_1.cuh"

__host__ __device__ void foo(double &r)
{
     r = 0;
}

test.cu

#include "lib_file_1.cuh"

int main()
{
     double random_number;
     foo(random_number);
     return 0;
}

我已经看到,该错误是一个潜在的问题,如6.6.3隐式CUDA主机代码https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#potential-separate-compilation-issues所述,我发现了几篇文章解决了一般命令行项目构建/手动makefile构建的问题。 但是,我还没有找到解决cmake的好方法

在根目录/调试中运行make VERBOSE=1后使用cmake -DCMAKE_BUILD_TYPE=debug ..链接CUDA可执行测试器时,将得到以下结果:

/usr/bin/g++  CMakeFiles/tester.dir/test.cu.o -o tester  ../my_library/libmy_library.a /usr/local/cuda-10.2/lib64/libcudart_static.a -lpthread -ldl /usr/lib/x86_64-linux-gnu/librt.so -lcudadevrt -lcudart_static  -L"/usr/local/cuda-10.2/targets/x86_64-linux/lib/stubs" -L"/usr/local/cuda-10.2/targets/x86_64-linux/lib" -lrt -lpthread -ldl
CMakeFiles/tester.dir/test.cu.o: In function `__sti____cudaRegisterAll()':
/tmp/tmpxft_00005a8a_00000000-5_test.cudafe1.stub.c:20: undefined reference to `__cudaRegisterLinkedBinary_39_tmpxft_00005a8a_00000000_6_test_cpp1_ii_main'
../my_library/libmy_library.a(lib_file_1.cu.o): In function `__sti____cudaRegisterAll()':
/tmp/tmpxft_000057c7_00000000-5_lib_file_1.cudafe1.stub.c:20: undefined reference to `__cudaRegisterLinkedBinary_45_tmpxft_000057c7_00000000_6_lib_file_1_cpp1_ii__Z3fooRd'
collect2: error: ld returned 1 exit status
test/CMakeFiles/tester.dir/build.make:106: recipe for target 'test/tester' failed

解决方法

显然,添加

set_target_properties(my_library PROPERTIES CUDA_SEPARABLE_COMPILATION ON)

root/my_library中的CMakeLists.txt可以解决问题。我确实在全球尝试了该选项

set(CUDA_SEPARABLE_COMPILATION ON)

root目录中CMakeLists.txt中的

,但这无效。我不知道为什么。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...