【发布时间】:2019-05-04 01:47:14
【问题描述】:
我使用 CMake 3.13 来创建具有单个项目“cudatest”的 Visual Studio (VS 2017) 解决方案。该项目包含两个文件:
main.cpp
kernel.cu
为了整合对 CUDA 的支持,我使用了 Nvidia 提供的脚本,即 FindCUDA.cmake,而不是对基于 CUDA 的应用程序使用最新的 CMake 支持(我没有使用这个最新的支持,因为它不允许我做某些事情,所以我需要求助于 FindCUDA)。
CMake 成功生成包含上述两个文件的项目。无需赘述,文件main.cpp 包含一个函数声明:
cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size);
您可能会将其识别为在 Visual Studio 中使用 CUDA 运行时类型的项目(用于 Visual Studio 的 NVIDIA CUDA 集成)创建新项目时默认创建的函数。
而文件kernel.cu 包含上述函数的定义:
__global__ void addKernel(int *c, const int *a, const int *b)
{
int i = threadIdx.x;
c[i] = a[i] + b[i];
}
cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size)
{
int *dev_a = 0;
int *dev_b = 0;
int *dev_c = 0;
...
addKernel<<<1, size>>>(dev_c, dev_a, dev_b);
...
}
两个文件都编译成功,错误被链接器触发:
Error LNK2019 unresolved external symbol "enum cudaError __cdecl addWithCuda(int *,int const *,int const *,unsigned int)" ...
需要注意的是,kernel.cu 的 *.obj 文件是由 NVCC 成功生成的。
但是 *.obj 文件被放置在不同的目录中,这让我认为这可能是问题所在,并且恰好揭示了我对 Visual Studio 链接器在何处查找 *.obj 文件以解决问题缺乏了解符号。
main.obj 文件以build\cudatest.dir\Debug 结尾,其中build 是包含生成的解决方案的文件夹。
cudatest_generated_kernel.cu.obj 文件以 build\CMakeFiles\cudatest.dir\Debug 结尾
输出文件路径的配置由FindCUDA.cmake脚本设置。
我尝试将cudatest_generated_kernel.cu.obj 与main.obj 放在同一个文件夹中,但没有任何作用。
将链接器的“显示进度”属性设置为 /VERBOSE 表明链接器甚至不会寻找 cudatest_generated_kernel.cu.obj 来尝试查找相应的符号。
======================
问题是:
鉴于我使用 NVCC 将 CUDA 内核编译成 *.obj 文件,并使用 CL.exe 将 *.cpp 文件编译成它自己的 *.obj 文件,我如何告诉链接器检查 cuda 内核 * .obj 文件?
如果我应该扩展问题以使其更清楚,请告诉我,即指定我使用的 NVCC 编译器选项,提供完整的代码列表等。任何正确方向的提示和指针将不胜感激!
编辑:
根据用户@talonmies 的建议(__cdecl addWithCuda 可能建议链接器正在寻找 C 链接),我在 main.cpp 和 kernel.cu 中都用 extern "C" 明确标记了 addWithCuda 函数:
extern "C" cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size)
现在报错如下:
Error LNK2019 unresolved external symbol addWithCuda referenced in function main cudatest D:\projects\vs2017\TestCUDA_CMake\build\main.obj
【问题讨论】:
-
这看起来像是一个符号修饰问题。
__cdecl addWithCuda(表明链接器正在寻找 C 链接,而不是 C++ 链接 -
@talonmies 已编辑:用 extern "C" 显式标记所述函数同样会导致 LNK2019;谢谢你的建议!
标签: c++ visual-studio cuda