首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Visual /CMake中未解析的外部符号cuda_library::foo(int)

Visual /CMake中未解析的外部符号cuda_library::foo(int)
EN

Stack Overflow用户
提问于 2021-05-11 17:23:06
回答 2查看 260关注 0票数 2

原始问题(标题:.cu文件在Visual /CMake中作为.cpp文件处理)

我试图添加一个带有CUDA代码的静态库到我的C++项目中。我有一个顶级的CMakeLists.txt文件,一个从那里添加的静态库,还有我从那个库中添加的使用CUDA的库(两个库都有自己的CMakeLists.txt文件)。在根文件中,我使用了enable_language(CUDA),在第一级库的CMakeLists.txt中,我这样做了:

代码语言:javascript
运行
复制
  add_subdirectory(cuda_library)
  set_target_properties(level_1_lib PROPERTIES POSITION_INDEPENDENT_CODE ON)
  set_target_properties(level_1_lib PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
  target_link_libraries(level_1_lib cuda_library)

在CUDA图书馆的CMakeLists.txt

代码语言:javascript
运行
复制
add_library(cuda_library 
  cuda_library.cu cuda_library.h)

target_include_directories(cuda_library
  INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
  )

1级库中的.cpp文件调用cuda_library.h中声明的“接口函数”,该函数在cuda_library.cu中实现,并通过以下方式在内部启动CUDA __global__内核:

代码语言:javascript
运行
复制
namespace cuda_library {
    __global__
    void real_foo(int number, int *out) { 
        *out = number * 2; 
    }

    inline int foo(int number) { 
        int* x;
        
        cudaMallocManaged(&x, sizeof(int));
        real_foo<<<1,1>>>(number, x); 
        cudaDeviceSynchronize();
        int y = *x;
        cudaFree(x);
        return y;
    } 
}

但是,当我从Visual构建(启用了CMake扩展名,并使用ninja作为生成器)时,构建不喜欢__global__关键字,这使我认为.cu文件被视为普通的.cpp文件,而不是编译为CUDA代码。

我做错了什么?

编辑,以更好地澄清我得到的错误。

如果我点击Visual的"Build“(或者从Visual命令提示符运行带有忍者的CMake,它通常可以用nvcc编译简单的CUDA示例,错误是相同的),并且我不是在cuda_library.cu文件上,我只得到归结为unresolved external symbol cuda_library::foo(int)的错误,这意味着函数可能被声明,但没有定义。如果包含了头文件,但是.cu文件没有正确编译,这是有意义的。

但是,只有当我使.cu文件激活VS时,才会显示与CUDA代码相关的与C++代码类似的错误,并且它们没有正常的错误徽标(就像此图像中的第一个错误),而是在第二个和第三个错误中可以看到的错误:

那么,它们是否只是构建时不出现的Intellisense错误?

在这种情况下,可能还有另一个原因导致静态库的实现没有正确链接。为了更彻底地了解它,下面是标题(cuda_library.h):

代码语言:javascript
运行
复制
#ifndef _CUDA_LIBRARY_H_
#define _CUDA_LIBRARY_H_

namespace cuda_library {
    inline int foo(int number);
}

#endif

我试图在发生.cpp错误的unresolved external symbol cuda_library::foo(int)文件中以这种方式导入和使用它:

代码语言:javascript
运行
复制
#include "cuda_library/cuda_library.h"

printf("Result from the GPU: %d\n", cuda_library::foo(5));

有趣的是我也试过

代码语言:javascript
运行
复制
#include <cuda_library.h>

结果是一样的,也许是因为CMake在包含搜索路径中包含了它?

该项目的结构如下:

代码语言:javascript
运行
复制
root_dir\
  CMakeLists.txt
  libs\
    CMakeLists.txt
    level_1_lib\
      CMakeLists.txt
      file_using_cuda_lib.cpp
      cuda_library\
        CMakeLists.txt
        cuda_library.cu
        cuda_library.h

我真的不明白到底出了什么问题,所以任何帮助都是可以接受的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-05-19 16:31:14

我意识到有两件主要的事情妨碍了它的工作:

函数签名中的

  • inline似乎是自己破坏了它(在这一点上,我并不关心它在我的代码中不移除它,如果有人想对它进行更多的调查,他们可以自由地进行)。
  • enable_language(CUDA)必须在顶级CMakeLists.txt文件中。

解决这两件事,它构建没有任何问题。

票数 0
EN

Stack Overflow用户

发布于 2021-05-13 07:57:53

您必须向每个源cpp文件添加一个属性,以说明它实际上是一个cuda源。

代码语言:javascript
运行
复制
    set_source_files_properties(file.cpp PROPERTIES LANGUAGE CUDA)

在启用CUDA作为一种语言(enable_language(CUDA))之后。

我们使用它,但是我不知道它是否是一个好的实践(对此的反馈是值得赞赏的)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67491590

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档