将C代码与CUDA链接时发生CMake错误
我在使用cmake构建项目时出现链接错误。这个构建在linux上使用makefile(手动生成/没有cmake)运行得很好,但是windows构建给我带来了问题。 下面是一个简单的示例来演示我的方法: 我在同一目录中有3个文件(kernel.cu、kernel.h、main.c) 主要条款c:将C代码与CUDA链接时发生CMake错误,c,windows,cmake,cuda,C,Windows,Cmake,Cuda,我在使用cmake构建项目时出现链接错误。这个构建在linux上使用makefile(手动生成/没有cmake)运行得很好,但是windows构建给我带来了问题。 下面是一个简单的示例来演示我的方法: 我在同一目录中有3个文件(kernel.cu、kernel.h、main.c) 主要条款c: extern void kernel_wrapper(); int main(){ kernel_wrapper(); } kernel.h: #ifndef KERNELH #define K
extern void kernel_wrapper();
int main(){
kernel_wrapper();
}
kernel.h:
#ifndef KERNELH
#define KERNELH
extern "C" void kernel_wrapper();
#endif
kernel.cu:
#include <stdio.h>
#include "kernel.h"
__global__ void kernel (){
printf("hello from GPU!");
}
void kernel_wrapper(){
kernel<<<1,1>>>();
}
库和可执行文件已成功编译,但在链接步骤中出现以下错误:
cu-lib.lib(kernel.obj) : error LNK2019: unresolved external symbol __cudaRegisterLinkedBi
nary_41_tmpxft_00003dd0_00000000_7_kernel_cpp1_ii_b81a68a1 referenced in function "void _
_cdecl __nv_cudaEntityRegisterCallback(void * *)" (?__nv_cudaEntityRegisterCallback@@YAXP
EAPEAX@Z) [C:\cudatest\build\c-exec.vcxproj]
C:\cudatest\build\Debug\c-exec.exe : fatal error LNK1120: 1 unresolved externals [C:\cuda
test\build\c-exec.vcxproj]
听起来链接器缺少一些库的include(可能是cudart?),但是,控制台上的link命令在我看来很正常,包括静态include和所有内容:
Link:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\link.exe /ERRORREP
ORT:QUEUE /OUT:"C:\cudatest\build\Debug\c-exec.exe" /INCREMENTAL /NOLOGO /LIBPATH:"C:\P
rogram Files\NVIDIA GPU Computing Toolkit\CUDA\v9.2\lib\x64" "Debug\cu-lib.lib" cudart_
static.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut3
2.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAc
cess='false'" /manifest:embed /DEBUG /PDB:"C:/cudatest/build/Debug/c-exec.pdb" /SUBSYST
EM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:/cudatest/build/Debug/c-exec.lib"
/MACHINE:X64 /machine:x64 "c-exec.dir\Debug\main.obj"
我现在不知所措。如果我放弃单独编译(将add_可执行参数更改为“c-exec main.c kernel.h kernel.cu”并跳过库步骤),问题就会消失,但我必须使用单独编译
这个问题似乎与我的问题有关,我试图应用其中提出的解决方案。在包含行周围和函数定义之前放置外部并没有改变任何内容
我正在使用Windows 10和Cmake v3.11.4、CUDA v9.2,并选择使用“Cmake-G”Visual Studio 15 2017 Win64“-T v140”的Cmake生成器,因为CUDA还不支持最新版本的Visual Studio
编辑:添加了完整的控制台输出
Build started 12.07.2018 03:03:42.
Project "C:\cudatest\build\ALL_BUILD.vcxproj" on node 1 (default targets).
Project "C:\cudatest\build\ALL_BUILD.vcxproj" (1) is building "C:\cudatest\build\ZERO_
CHECK.vcxproj" (2) on node 1 (default targets).
PrepareForBuild:
Creating directory "x64\Debug\ZERO_CHECK\".
Creating directory "x64\Debug\ZERO_CHECK\ZERO_CHECK.tlog\".
InitializeBuildStatus:
Creating "x64\Debug\ZERO_CHECK\ZERO_CHECK.tlog\unsuccessfulbuild" because "AlwaysCre
ate" was specified.
CustomBuild:
Checking Build System
CMake does not need to re-run because C:/cudatest/build/CMakeFiles/generate.stamp is
up-to-date.
FinalizeBuildStatus:
Deleting file "x64\Debug\ZERO_CHECK\ZERO_CHECK.tlog\unsuccessfulbuild".
Touching "x64\Debug\ZERO_CHECK\ZERO_CHECK.tlog\ZERO_CHECK.lastbuildstate".
Done Building Project "C:\cudatest\build\ZERO_CHECK.vcxproj" (default targets).
Project "C:\cudatest\build\ALL_BUILD.vcxproj" (1) is building "C:\cudatest\build\c-exe
c.vcxproj" (3) on node 1 (default targets).
Project "C:\cudatest\build\c-exec.vcxproj" (3) is building "C:\cudatest\build\cu-lib.v
cxproj" (4) on node 1 (default targets).
PrepareForBuild:
Creating directory "cu-lib.dir\Debug\".
Creating directory "C:\cudatest\build\Debug\".
Creating directory "cu-lib.dir\Debug\cu-lib.tlog\".
InitializeBuildStatus:
Creating "cu-lib.dir\Debug\cu-lib.tlog\unsuccessfulbuild" because "AlwaysCreate" was
specified.
CustomBuild:
Building Custom Rule C:/cudatest/CMakeLists.txt
CMake does not need to re-run because C:/cudatest/build/CMakeFiles/generate.stamp is
up-to-date.
AddCudaCompileDeps:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\cl.exe /E /nolo
go /showIncludes /TP /D__CUDACC__ /D_WINDOWS /DCMAKE_INTDIR="Debug" /DCMAKE_INTDIR="
Debug" /D_MBCS /I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.2\include" /
I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.2\bin" /I"C:\Program Files\N
VIDIA GPU Computing Toolkit\CUDA\v9.2\include" /I. /FIcuda_runtime.h /c C:\cudatest\
kernel.cu
Project "C:\cudatest\build\cu-lib.vcxproj" (4) is building "C:\cudatest\build\cu-lib.v
cxproj" (4:2) on node 1 (CudaBuildCore target(s)).
CudaBuildCore:
Compiling CUDA source file ..\kernel.cu...
cmd.exe /C "C:\Users\dulls\AppData\Local\Temp\tmpd0a36f1624184bf982dc8082e9a727be.cm
d"
"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.2\bin\nvcc.exe" -gencode=arch
=compute_30,code=\"sm_30,compute_30\" --use-local-env -ccbin "C:\Program Files (x86)
\Microsoft Visual Studio 14.0\VC\bin\x86_amd64" -x cu -rdc=true -I"C:\Program Files\
NVIDIA GPU Computing Toolkit\CUDA\v9.2\include" -I"C:\Program Files\NVIDIA GPU Compu
ting Toolkit\CUDA\v9.2\include" --keep-dir x64\Debug -maxrregcount=0 --machine
64 --compile -cudart static -Xcompiler="/EHsc -Zi -Ob0" -g -D"_WINDOWS" -D"CMAKE_I
NTDIR=\"Debug\"" -D"CMAKE_INTDIR=\"Debug\"" -D_MBCS -Xcompiler "/EHsc /W3 /nologo /O
d /FS /Zi /RTC1 /MDd /GR" -o cu-lib.dir\Debug\kernel.obj "C:\cudatest\kernel.cu"
C:\cudatest\build>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.2\bin\nvcc.
exe" -gencode=arch=compute_30,code=\"sm_30,compute_30\" --use-local-env -ccbin "C:\P
rogram Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64" -x cu -rdc=true -I
"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.2\include" -I"C:\Program File
s\NVIDIA GPU Computing Toolkit\CUDA\v9.2\include" --keep-dir x64\Debug -maxrregc
ount=0 --machine 64 --compile -cudart static -Xcompiler="/EHsc -Zi -Ob0" -g -D"_W
INDOWS" -D"CMAKE_INTDIR=\"Debug\"" -D"CMAKE_INTDIR=\"Debug\"" -D_MBCS -Xcompiler "/E
Hsc /W3 /nologo /Od /FS /Zi /RTC1 /MDd /GR" -o cu-lib.dir\Debug\kernel.obj "C:\cudat
est\kernel.cu"
kernel.cu
Done Building Project "C:\cudatest\build\cu-lib.vcxproj" (CudaBuildCore target(s)).
Lib:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\Lib.exe /OUT:"C
:\cudatest\build\Debug\cu-lib.lib" /NOLOGO /MACHINE:X64 /machine:x64 "cu-lib.dir\De
bug\kernel.obj"
cu-lib.vcxproj -> C:\cudatest\build\Debug\cu-lib.lib
FinalizeBuildStatus:
Deleting file "cu-lib.dir\Debug\cu-lib.tlog\unsuccessfulbuild".
Touching "cu-lib.dir\Debug\cu-lib.tlog\cu-lib.lastbuildstate".
Done Building Project "C:\cudatest\build\cu-lib.vcxproj" (default targets).
PrepareForBuild:
Creating directory "c-exec.dir\Debug\".
Creating directory "c-exec.dir\Debug\c-exec.tlog\".
InitializeBuildStatus:
Creating "c-exec.dir\Debug\c-exec.tlog\unsuccessfulbuild" because "AlwaysCreate" was
specified.
CustomBuild:
Building Custom Rule C:/cudatest/CMakeLists.txt
CMake does not need to re-run because C:/cudatest/build/CMakeFiles/generate.stamp is
up-to-date.
ClCompile:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\CL.exe /c /I"C:
\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.2\include" /Zi /nologo /W3 /WX-
/Od /Ob0 /D "WIN32" /D "_WINDOWS" /D "CMAKE_INTDIR=\"Debug\"" /D _MBCS /Gm- /RTC1 /M
Dd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /Fo"c-exec.dir\Debug\\" /Fd"c
-exec.dir\Debug\vc140.pdb" /Gd /TC /errorReport:queue C:\cudatest\main.c
main.c
Link:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\link.exe /ERROR
REPORT:QUEUE /OUT:"C:\cudatest\build\Debug\c-exec.exe" /INCREMENTAL /NOLOGO /LIBPATH
:"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.2\lib\x64" "Debug\cu-lib.lib
" cudart_static.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32
.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTUAC:"level='
asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"C:/cudatest/build/Debug/c-
exec.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:/cudatest/bu
ild/Debug/c-exec.lib" /MACHINE:X64 /machine:x64 "c-exec.dir\Debug\main.obj"
Creating library C:/cudatest/build/Debug/c-exec.lib and object C:/cudatest/build/
Debug/c-exec.exp
cu-lib.lib(kernel.obj) : error LNK2019: unresolved external symbol __cudaRegisterLinke
dBinary_41_tmpxft_00013688_00000000_7_kernel_cpp1_ii_b81a68a1 referenced in function "
void __cdecl __nv_cudaEntityRegisterCallback(void * *)" (?__nv_cudaEntityRegisterCallb
ack@@YAXPEAPEAX@Z) [C:\cudatest\build\c-exec.vcxproj]
C:\cudatest\build\Debug\c-exec.exe : fatal error LNK1120: 1 unresolved externals [C:\c
udatest\build\c-exec.vcxproj]
Done Building Project "C:\cudatest\build\c-exec.vcxproj" (default targets) -- FAILED.
Done Building Project "C:\cudatest\build\ALL_BUILD.vcxproj" (default targets) -- FAILE
D.
Build FAILED.
"C:\cudatest\build\ALL_BUILD.vcxproj" (default target) (1) ->
"C:\cudatest\build\c-exec.vcxproj" (default target) (3) ->
(Link target) ->
cu-lib.lib(kernel.obj) : error LNK2019: unresolved external symbol __cudaRegisterLin
kedBinary_41_tmpxft_00013688_00000000_7_kernel_cpp1_ii_b81a68a1 referenced in function
"void __cdecl __nv_cudaEntityRegisterCallback(void * *)" (?__nv_cudaEntityRegisterCal
lback@@YAXPEAPEAX@Z) [C:\cudatest\build\c-exec.vcxproj]
C:\cudatest\build\Debug\c-exec.exe : fatal error LNK1120: 1 unresolved externals [C:
\cudatest\build\c-exec.vcxproj]
0 Warning(s)
2 Error(s)
我想我在这个问题上找到了解决办法。(感谢@talonmies的指导) 我必须使用以下命令强制设备链接:
set_property(TARGET c-lib PROPERTY CUDA_RESOLVE_DEVICE_SYMBOLS ON)
而且它有效
从CUDA\u解析\u设备\u符号手册页:
仅CUDA:启用特定静态库的设备链接
目标
如果设置此选项,将启用此静态库目标上的设备链接。
通常,设备链接延迟到共享库或
生成可执行文件,允许创建多个静态库
同时解析设备符号
我仍然不确定为什么我的可执行文件生成不会在主机将所有内容链接到一起之前触发设备链接
编辑:看起来它是一个影响windows版本但在linux上运行良好的工具。对您有用吗?您不需要对该用例进行单独编译,但可能缺少设备链接stage@KetanMukadam我在问我的问题之前看过那篇帖子,它适用于cmake的旧版本,当时cuda不是一流的语言。说这些东西现在大部分都不是必需的,并且是出于兼容性的原因而保留的。此外,他们的构建系统是Linux,而不是windows。尽管如此,我还是尝试了上面的建议,但没有成功。您没有显示设备链接输出,这就是问题所在。这不是丢失的库,而是nvcc正在发射的GPU对象文件上丢失的操作。日志输出中有一些内容被破坏。kernel.cu被编译了两次,但没有设备链接步骤。
set_property(TARGET c-lib PROPERTY CUDA_RESOLVE_DEVICE_SYMBOLS ON)