CMake CUDA C++链接错误-对"someFunction()"的未定义引用

CMake CUDA C++ Linking Error - Undefined reference to `someFunction()`

本文关键字:quot 未定义 引用 someFunction CUDA 错误 CMake C++ 链接      更新时间:2024-04-28

我正试图从C++程序调用CUDA内核。我正在使用CMake来管理构建过程。

CMakeLists.txt

cmake_minimum_required(VERSION 3.18)
project(SeamCarving LANGUAGES CUDA CXX VERSION 0.1.0)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CUDA_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CUDA_STANDARD_REQUIRED True)
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
file(GLOB CPU_SRC_FILES 
"src/*.cpp"
"src/*.h"
)
add_library(MyLibrary STATIC src/Kernels.cu src/Kernels.cuh)
set_target_properties( MyLibrary PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
set(SOURCES ${CPU_SRC_FILES})
add_executable(myProject ${SOURCES})
target_link_libraries( myProject PRIVATE ${MyLibrary} )
target_link_libraries( myProject PRIVATE ${OpenCV_LIBS} )

MyClassA.cpp(该文件通过函数调用.cu文件中的CUDA内核(

#include "MyClassA.h"
MyClassA::MyClassA() : MyClassB()
{
myHelloWorldKernel();
}

MyClassA.h

#include <iostream>
#include <opencv2/opencv.hpp>
#include "MyClassB.h"
#include "Kernels.cuh"
class MyClassA : public MyClassB
{
public:
MyClassA();
};

Kernels.cuh

#ifndef MY_KERNEL_H
#define MY_KERNEL_H
void myHelloWorldKernel();
#endif

Kernels.cu

#include <stdio.h>
#include <stdlib.h>
#include <cuda_runtime.h>
#include <device_launch_parameters.h>
#include "Kernels.cuh"
__global__ void helloWorld() {
printf("Hello!n");
}
void myHelloWorldKernel()
{
dim3 block(2, 2);
dim3 grid(3, 3);
helloWorld<<<grid, block>>>();
cudaDeviceSynchronize();    
printf("Completed!n");
}

这是我在尝试构建时从CMake得到的以下错误

...
[build] [ 87%] Linking CUDA static library libMyLibrary.a
[build] [ 87%] Built target MyLibrary
[build] [100%] Linking CXX executable myProject
[build] CMakeFiles/myProject.dir/src/MyClassA.cpp.o: In function `MyClassA::MyClassA()':
[build] /PATH/src/MyClassA.cpp:5: undefined reference to `myHelloWorldKernel()'
[build] collect2: error: ld returned 1 exit status
...

我不太清楚问题出在哪里。如有帮助,不胜感激。

MyLibrary不是变量,它是CMake目标。语法${variable}用于替换变量的内容。创建对MyLibrary的依赖关系的正确语法是:

target_link_libraries( myProject PRIVATE MyLibrary )

${OpenCV_LIBS}的情况下,语法可能是正确的。通常情况下,包定义一个变量,该变量包含使用包所需的库的名称。因此,在您的情况下,${OpenCV_LIBS}的评估结果可能类似于"OpenCV_lib1 OpenCV_lib2"

你可以做的其他一些改进:

  • 将源文件GLOB是个坏主意。glob将在配置时进行评估,如果您在没有重新运行CMake配置的情况下将文件添加到目录中,则不会考虑这些文件。AFAIK的规范方法是只显式地列出您的源代码
  • 考虑使用target_include_directories而不是include_directories,以将效果限制在适当的目标上