在CMake中链接CUDA库

Linking of CUDA library in CMake

本文关键字:CUDA 链接 CMake      更新时间:2023-10-16

我正在使用 CMake 3.10,但在将编译库链接到 CMake 中的测试可执行文件时遇到问题。 我搜索了很多,发现在早期版本中存在无法在结果可执行文件中链接中间库的问题。我无法判断这是否已解决或仍然是一个问题。

我的 CMake 文件如下所示:

算法:

cmake_minimum_required (VERSION 3.9)
project(${MODULE_NAME}_core LANGUAGES CXX CUDA)

add_subdirectory("${core_impl_dir}" implementation)

set(cuda_src "parallel/ParallelComputation.cu")
set(cuda_hdr "parallel/ParallelComputation.h")
add_library(${PROJECT_NAME} STATIC "${cuda_src}" "${cuda_hdr}"
)

target_include_directories (${PROJECT_NAME} PUBLIC "include/" 
"parallel/"
)
source_group("parallel"  FILES "${cuda_src}" "${cuda_hdr}")

set_property(TARGET ${PROJECT_NAME} PROPERTY FOLDER ${MODULE_NAME})

测试:

project(${MODULE_NAME}_gtest LANGUAGES CXX CUDA)
add_subdirectory("${gtest_impl_dir}" implementation)
add_executable(${PROJECT_NAME} "${gtest_impl_src}")
target_link_libraries(${PROJECT_NAME} ${MODULE_NAME}_core)
enable_testing()
find_package(GTest REQUIRED)
include_directories("${GTEST_INCLUDE_DIRS}")

target_link_libraries(${PROJECT_NAME} ${GTEST_BOTH_LIBRARIES})
source_group("Implementation\Source Files" FILES "${gtest_impl_src}" )
set_property(TARGET ${PROJECT_NAME} PROPERTY FOLDER ${MODULE_NAME})
add_test(${PROJECT_NAME} ${PROJECT_NAME})

仅构建算法工作正常,但是在构建测试时,例如,我遇到链接错误

../implementation/libmatrix1_testCuda_core.a(ParallelComputing.cu.o): In Funktion 'cudaError cudaMalloc(float**, unsigned long)': tmpxft_00005ad0_00000000-5_ParallelComputation.cudafe1.cpp:(.text+0x4f2): 未定义的引用 'cudaMalloc'

编辑 使用make VERBOSE=1我得到了这个链接命令:

/

usr/bin/c++ -Wl,--no-as-need -pthread -g -std=c++14 -Wall
CMakeFiles/matrix1_testCuda_gtest.dir//tests/eclipseProject/algos/testCuda/test/src/main.cpp.o CMakeFiles/matrix1_testCuda_gtest.dir/cmake_device_link.o -o matrix1_testCuda_gtest../实现/libmatrix1_testCuda_core.a/usr/lib/libgtest.a/usr/lib/libgtest_main.a

此答案适用于 CMake 版本 3.10 <。此处显示的方法自 CMake 3.10 起已弃用,但原则上仍适用于较新版本。这就是我最终在 CMake 3.10 中使用的内容。

对于 CMake 版本>= 3.10 但<3.17,请先检查 Pat Lorton 的答案是否有帮助。

对于CMake 3.17+,请查看VojtaK的答案。


我通过打电话来解决这个问题

find_package(CUDA 9.0 REQUIRED)

在两个 CMake 文件中。 另外,在算法文件(包含设备代码)中,我必须做

target_link_libraries(${PROJECT_NAME} ${CUDA_LIBRARIES})

我预计对 CUDA 的语言支持会使这些步骤变得不必要,但显然不是。

我刚刚遇到了与此非常相似的事情,根本问题是我的大部分二进制文件都是用我的系统 cxx 编译器编译的,而 cuda 位是用 cuda gcc 编译器编译的(系统为 9.1,cuda 为 8.3)。

令人惊讶的是,它通过更改来修复:

project(MyProject LANGUAGES CXX CUDA)

project(MyProject LANGUAGES CUDA CXX)

在那次更改之后,CMake 选择了 gcc 编译器的 cuda 版本作为主编译器,我的二进制文件再次开始构建。 我不确定这是否会给其他软件包带来问题,但它解决了我遇到的链接问题。

在 CMake 3.17 及更高版本中添加可能的方法

当您不希望包含任何 CUDA 代码,但例如仅使用来自C++的袖口调用时,执行以下操作就足够

find_package(CUDAToolkit)
target_link_libraries(project CUDA::cudart)
target_link_libraries(project CUDA::cufft)

但是,如果您要启用 CUDA 支持,除非您想遇到麻烦,否则请在启用 CUDA 后致电它。

include(CheckLanguage)
check_language(CUDA)
if(CMAKE_CUDA_COMPILER)
enable_language(CUDA)
find_package(CUDAToolkit)
target_link_libraries(project CUDA::cudart)
target_link_libraries(project CUDA::cuda_driver)
else()
message(STATUS "No CUDA compiler found")
endif()

因为 CUDAToolkit 尊重启用 CUDA 运行时添加,但反之亦然。

请注意,某些 CUDA 版本不适用于更新的 GCC 编译器。因此,当安装了例如 CUDA 11.3 和 GCC 12 时,check_language(CUDA)将无法找到 CUDA,因为它需要 GCC 10 或更低版本。您只是找不到 CUDA,唯一的解决方案是在这种情况下降级 GCC。