You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 00:44:58