【问题标题】:CMake CUDA C++ Linking Error - Undefined reference to `someFunction()`CMake CUDA C++ 链接错误 - 未定义引用`someFunction()`
【发布时间】:2021-01-11 11:49:01
【问题描述】:

我正在尝试从 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();
};

内核.cuh

#ifndef MY_KERNEL_H
#define MY_KERNEL_H

void myHelloWorldKernel();

#endif

内核.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
...

我不太确定问题出在哪里。任何帮助表示赞赏。

【问题讨论】:

    标签: c++ cmake cuda


    【解决方案1】:

    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,以将效果限制在适当的目标上。

    【讨论】:

    • 谢谢。我不敢相信我错过了。也感谢您的其他建议。
    猜你喜欢
    • 2016-07-21
    • 2016-06-10
    • 2023-03-05
    • 2014-07-19
    • 1970-01-01
    • 2020-10-08
    • 2020-08-10
    • 2014-02-13
    相关资源
    最近更新 更多