Visual Studio静态链接CUDA设备代码时的链接错误求助
在Visual Studio 2022 + CUDA 12环境下构建含设备代码的CUDA静态库问题
问题背景
在Windows x64、Visual Studio 2022、CUDA 12环境中,尝试将包含__device__函数的代码编译为静态库,再链接到可执行项目时,命令行下可成功构建,但Visual Studio中出现设备符号未定义的链接错误(Undefined reference to '_Z4funcd')。
示例代码
Func.cuh
#include "cuda_runtime.h" #include "device_launch_parameters.h" __device__ void func(double d); void hostFunc(double d);
Func.cu
#include "Func.cuh" #include <iostream> __device__ void func(double d) { printf("device %f\n", sqrt(d)); } void hostFunc(double d) { std::printf("host %f\n", std::sqrt(d)); }
Func2.cu
#include "cuda_runtime.h" #include "device_launch_parameters.h" #include "Func.cuh" __global__ void test2(double d) { func(d); } int main() { hostFunc(2.0); test2<<<1, 1>>>(2.0); cudaDeviceSynchronize(); }
命令行成功构建流程
D:\temp>nvcc Func.cu -lib -o Func.lib -rdc true Func.cu tmpxft_000025c8_00000000-10_Func.cudafe1.cpp D:\temp>nvcc Func2.cu -c -o Func2.obj -rdc true Func2.cu tmpxft_000043b8_00000000-10_Func2.cudafe1.cpp D:\temp>nvcc Func2.obj Func.lib -o Func2.exe Func2.obj Func.lib library "Func2.lib" and object "Func2.exp" are built. PS D:\temp> .\Func2 host 1.414214 device 1.414214
Visual Studio构建错误日志
Rebuild started... 1>------ Rebuild All started: Project: LibraryTest, Configuration: Debug x64 ------ 1>Compiling CUDA source file Func.cu... 1> 1>F:\reposVisualStudio\CudaTest\LibraryTest>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0\bin\nvcc.exe" --use-local-env -ccbin "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\bin\HostX64\x64" -x cu -rdc=true -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0\include" -G --keep-dir x64\Debug -maxrregcount=0 --machine 64 --compile -cudart static -g -DWIN32 -DWIN64 -D_DEBUG -D_CONSOLE -D_MBCS -Xcompiler "/EHsc /W3 /nologo /Od /FS /Zi /RTC1 /MDd " -Xcompiler "/FdF:\reposVisualStudio\CudaTest\x64\Debug\LibraryTest.pdb" -o F:\reposVisualStudio\CudaTest\LibraryTest\x64\Debug\Func.cu.obj "F:\reposVisualStudio\CudaTest\LibraryTest\Func.cu" 1>Func.cu 1>tmpxft_00002d18_00000000-7_Func.cudafe1.cpp 1> 1>F:\reposVisualStudio\CudaTest\LibraryTest>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0\bin\nvcc.exe" -dlink -o x64\Debug\LibraryTest.device-link.obj -Xcompiler "/EHsc /W3 /nologo /Od /Zi /RTC1 /MDd " -Xcompiler "/FdF:\reposVisualStudio\CudaTest\x64\Debug\LibraryTest.pdb" -L"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0\bin/crt" -L"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0\lib\x64" cudart_static.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib cudart.lib cudadevrt.lib -G F:\reposVisualStudio\CudaTest\LibraryTest\x64\Debug\Func.cu.obj 1>cudart_static.lib 1>kernel32.lib 1>user32.lib 1>gdi32.lib 1>winspool.lib 1>comdlg32.lib 1>advapi32.lib 1>shell32.lib 1>ole32.lib 1>oleaut32.lib 1>uuid.lib 1>odbc32.lib 1>odbccp32.lib 1>cudart.lib 1>cudadevrt.lib 1>Func.cu.obj 1>LibraryTest.vcxproj -> F:\reposVisualStudio\CudaTest\x64\Debug\LibraryTest.lib 2>------ Rebuild All started: Project: LibraryTest2, Configuration: Debug x64 ------ 2>Compiling CUDA source file Func2.cu... 2> 2>F:\reposVisualStudio\CudaTest\LibraryTest2>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0\bin\nvcc.exe" --use-local-env -ccbin "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\bin\HostX64\x64" -x cu -rdc=true -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0\include" -G --keep-dir x64\Debug -maxrregcount=0 --machine 64 --compile -cudart static -g -DWIN32 -DWIN64 -D_DEBUG -D_CONSOLE -D_MBCS -Xcompiler "/EHsc /W3 /nologo /Od /FS /Zi /RTC1 /MDd " -Xcompiler "/Fdx64\Debug\vc143.pdb" -o F:\reposVisualStudio\CudaTest\LibraryTest2\x64\Debug\Func2.cu.obj "F:\reposVisualStudio\CudaTest\LibraryTest2\Func2.cu" 2>Func2.cu 2>tmpxft_00000c10_00000000-7_Func2.cudafe1.cpp 2> 2>F:\reposVisualStudio\CudaTest\LibraryTest2>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0\bin\nvcc.exe" -dlink -o x64\Debug\LibraryTest2.device-link.obj -Xcompiler "/EHsc /W3 /nologo /Od /Zi /RTC1 /MDd " -Xcompiler "/Fdx64\Debug\vc143.pdb" -L"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0\bin/crt" -L"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0\lib\x64" -L"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0\lib\x64" -LF:\reposVisualStudio\CudaTest\x64\Debug LibraryTest.lib cudart_static.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib cudart.lib cudadevrt.lib -G F:\reposVisualStudio\CudaTest\LibraryTest2\x64\Debug\Func2.cu.obj 2>CUDALINK : nvlink error : Undefined reference to '_Z4funcd' in 'F:/reposVisualStudio/CudaTest/LibraryTest2/x64/Debug/Func2.cu.obj'
解决方案
错误根源是Visual Studio默认会对静态库项目执行device-link步骤,将设备代码符号封装到中间文件,导致主项目无法访问。需修改两个项目的配置:
1. 静态库项目(LibraryTest)配置
- 右键项目 → 属性 → 配置属性 → CUDA C/C++ → 共同:确认生成可重定位设备代码为
是(-rdc=true) - 配置属性 → 链接器 → 输入:移除所有CUDA相关依赖库(如cudart.lib、cudadevrt.lib)
- 关键设置:配置属性 → CUDA Linker → 执行设备链接:设置为
否(或直接编辑vcxproj文件,将<CudaLink>true</CudaLink>改为<CudaLink>false</CudaLink>)
2. 可执行项目(LibraryTest2)配置
- 右键项目 → 属性 → 配置属性 → CUDA C/C++ → 共同:确认生成可重定位设备代码为
是(-rdc=true) - 配置属性 → 链接器 → 输入:添加静态库
LibraryTest.lib,保留CUDA依赖库(cudart_static.lib、cudadevrt.lib等) - 配置属性 → CUDA Linker → 附加库目录:添加静态库所在路径(如
$(SolutionDir)x64\Debug)
修改后,静态库仅编译生成.lib文件,可执行项目会在device-link阶段将静态库中的设备代码与自身代码链接,最终生成可执行文件,运行结果与命令行一致。
内容的提问来源于stack exchange,提问作者RainerMtb
相关产品推荐
相关产品推荐

