CMake中CUDA库的链接

kut*_*kem 3 c++ cuda cmake linker-errors

我正在使用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})
Run Code Online (Sandbox Code Playgroud)

测试:

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})
Run Code Online (Sandbox Code Playgroud)

仅构建Algo可以正常工作,但是同时构建Test时,出现链接错误,例如

../implementation/libmatrix1_testCuda_core.a(ParallelComputation.cu.o):在Funktion中'cudaError cudaMalloc(float **,unsigned long)':tmpxft_00005ad0_00000000-5_ParallelComputation.cudafe1.cpp :(。text + 0x4'4' '

使用make VERBOSE=1我得到此链接命令的编辑:

/ usr / bin / c ++ -Wl,-不需要-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 ../implementation/libmatrix1_testCuda_core.a /usr/lib/libgtest.a /usr/lib/libgtest_main.a

小智 6

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

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

project(MyProject LANGUAGES CXX CUDA)

project(MyProject LANGUAGES CUDA CXX)

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


Voj*_*taK 6

在CMake 3.17及进一步添加可能的方式

当您不希望包含任何 CUDA 代码,但例如仅使用对 cufft 的调用C++就足以执行以下操作

find_package(CUDAToolkit)
target_link_libraries(project CUDA::cudart)
target_link_libraries(project CUDA::cufft)
Run Code Online (Sandbox Code Playgroud)

但是,如果您要启用 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()


Run Code Online (Sandbox Code Playgroud)

因为 CUDAToolkit尊重添加的启用 CUDA 运行时,但反之则不起作用。

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

  • 从 cmake 3.17 开始支持 [FindCUDAToolkit](https://cmake.org/cmake/help/latest/module/FindCUDAToolkit.html),而不是 3.18,不是吗?这是真正的答案,至少对于那些出于某种原因不坚持使用中世纪版本的 cmake 的人来说是这样。 (2认同)

kut*_*kem 5

我打电话给我

find_package(CUDA 9.0 REQUIRED)
Run Code Online (Sandbox Code Playgroud)

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

target_link_libraries(${PROJECT_NAME} ${CUDA_LIBRARIES})
Run Code Online (Sandbox Code Playgroud)

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

  • @einpoklum 因为这似乎是一个很多人都看到的问题,如果这对于较新的 CMake 版本有所不同,请使用新方法添加答案。 (4认同)