Windows 本地开发环境准备
本文面向需要在 Windows x64 上修改、编译和验证 TensorRtSharp4.0 的维护者。普通用户消费托管包和 匹配的 runtime package,不一定需要完整 C++ toolchain;但只要修改 manifest、native bridge、CUDA/TensorRT wrapper 或 runtime packaging,就必须让 .NET、MSVC、CMake、TensorRT、CUDA 和 cuDNN 属于一个明确组合。
本文从空环境开始建立可复现工作区,重点是“先验证输入,再构建产物”,并把大 SDK、包和日志放在 E 盘。
适用读者
- 第一次从源码构建本项目 C++ bridge 的 Windows 开发者。
- 需要复现 TRT8/TRT10/TRT11 native matrix 的维护者。
- 修改 binding generator、manifest 或 runtime package 的贡献者。
- 排查 header/lib/DLL、MSVC、CUDA driver/runtime 不一致的工程师。
最终环境结构
flowchart TD
T["Visual Studio C++ toolchain"] --> C["CMake preset"]
D[".NET SDK from global.json"] --> M["Managed build and tests"]
R["Runtime roots on E drive"] --> V["Input validator"]
V --> C
C --> B["Native bridge DLL"]
B --> M
M --> P["Local package and consumer checks"]
建议在 E 盘准备专用目录:
..\downloads\
nvidia\
TensorRT-8.6.1.6-cuda11.8\
TensorRT-10.11.0.33-cuda12.9\
TensorRT-11.0.0.114-cuda13.2\
cudnn-8.9\
cudnn-9.22\
package-feed\
build-logs\
consumer\
仓库保持在 E 盘。模型、ONNX、engine、plan、nupkg、SDK archive 和大日志也放在这个工作区,避免系统盘 Downloads/Temp 变成不可审计的依赖来源。
工具清单
| 工具 | 仓库用途 | 最低检查 |
|---|---|---|
| Git | 版本和 diff 管理 | git --version |
| PowerShell 7 | 执行 eng/*.ps1 |
$PSVersionTable.PSVersion |
| .NET SDK | solution、tests、generator | dotnet --info 与 global.json |
| Visual Studio 2022 | MSVC、Windows SDK、CMake generator | Desktop development with C++ workload |
| CMake 3.27+ | 使用 CMakePresets.json |
cmake --version |
| NVIDIA driver | 执行 CUDA/TensorRT smoke | nvidia-smi |
| CUDA Toolkit | 编译 CUDA bridge、提供 runtime | runtime key 对应 major.minor |
| TensorRT SDK | headers、import libs、DLL | runtime key 对应 8.6/10.11/11.0 |
| cuDNN | runtime asset 和 package | runtime key 对应 major/version |
版本以仓库 global.json、CMakePresets.json 和 pack/runtime/runtime-packages.manifest.json 为准,
不要把文章中的工具版本当不可变常量。
第一步:确认仓库与工具
在 Developer PowerShell 或已初始化 MSVC 的 PowerShell 中运行:
Set-Location .
git status --short
dotnet --info
cmake --version
pwsh --version
where.exe cl
where.exe cmake
where.exe cl 没有结果时,通常是没有安装 C++ workload,或终端没有加载 Visual Studio 开发环境。
先修复 toolchain,再改 CMake cache;普通 PowerShell 中手工拼接几十个 MSVC 路径不是稳定方案。
保存环境快照:
$logRoot = '..\downloads\build-logs'
New-Item -ItemType Directory -Force $logRoot | Out-Null
dotnet --info | Out-File (Join-Path $logRoot 'dotnet-info.txt')
cmake --version | Out-File (Join-Path $logRoot 'cmake-version.txt')
$PSVersionTable | Out-File (Join-Path $logRoot 'powershell-version.txt')
nvidia-smi | Out-File (Join-Path $logRoot 'nvidia-smi.txt')
第二步:选择唯一 Runtime Key
Windows 当前有六个组合:
| Runtime key | Preset |
|---|---|
win-x64-trt8.6-cuda11.8-cudnn8.9 |
win-x64-trt8-cuda11-release |
win-x64-trt8.6-cuda12.1-cudnn8.9 |
win-x64-trt8-cuda12-release |
win-x64-trt10.11-cuda11.8-cudnn8.9 |
win-x64-trt10-cuda11-release |
win-x64-trt10.11-cuda12.9-cudnn9.22 |
win-x64-trt10-cuda12-release |
win-x64-trt11.0-cuda12.9-cudnn9.22 |
win-x64-trt11-cuda12-release |
win-x64-trt11.0-cuda13.2-cudnn9.22 |
win-x64-trt11-cuda13-release |
key 同时决定 TensorRT、CUDA、cuDNN 与 bridge target。不要选择 TRT11 preset,却把 TRT10 import library 放进 PATH;configure 可能成功,link 或 runtime 才会暴露问题。
第三步:配置本地 Runtime Roots
公开 manifest 只保存可移植默认值,本机路径写入:
- 示例:
pack/runtime/runtime-packages.local.example.json - 本地覆盖:
pack/runtime/runtime-packages.local.json
本地文件应被 Git 忽略。按实际 E 盘目录填写后,用 resolver 读取,不要让各脚本各自猜路径:
$key = 'win-x64-trt10.11-cuda12.9-cudnn9.22'
$roots = pwsh -NoProfile -File .\eng\Resolve-RuntimeRoots.ps1 `
-RuntimePackageKey $key | ConvertFrom-Json
$roots | Format-List
预期得到 tensorRtRoot、cudaRoot、cudnnRoot。这些目录需要指向解压后的 SDK 根,不是某个单独 DLL。
第四步:构建前验证输入
pwsh -NoProfile -File .\eng\Validate-WindowsRuntimeInputs.ps1 `
-RuntimePackageKey $key `
-TensorRtRoot $roots.tensorRtRoot `
-CudaRoot $roots.cudaRoot `
-CudnnRoot $roots.cudnnRoot
输入检查应在 CMake 之前执行。它能提前发现:
- TensorRT include/lib/bin 不属于同一 package。
- 只有 import library,没有运行时 DLL。
- CUDA major 与 key 不符。
- cuDNN 8/9 文件名和目标 major 不一致。
- 本地 root 不存在或指向 archive 上层目录。
如果 validator 失败,修 root,不要从其它 SDK 目录临时复制单个 DLL。
第五步:生成绑定
只改文档通常不需要生成;修改 manifest、schema、template、entry point 或 interop shape 时必须执行:
pwsh -NoProfile -File .\eng\Generate-Bindings.ps1
pwsh -NoProfile -File .\eng\Test-BindingGeneratorOutputs.ps1
关注这些输出:
native/generated/bridge_api_catalog.g.hnative/generated/bridge_entrypoints.g.hsrc/JYPPX.Shared/Generated/GeneratedEntryPointNames.g.cssrc/JYPPX.TensorRtSharp/Internal/Interop/Generated/NativeMethodsTensorRt.Generated.g.cssrc/JYPPX.CudaSharp/Internal/Interop/Generated/NativeMethodsCuda.Generated.g.cs
幂等测试失败时修 manifest/generator/template,不要手改 generated file。
第六步:配置与编译 Native Bridge
以下示例使用前面选择的 TRT10/CUDA12 preset:
$preset = 'win-x64-trt10-cuda12-release'
$configureLog = '..\downloads\build-logs\trt10-cuda12-configure.log'
$buildLog = '..\downloads\build-logs\trt10-cuda12-build.log'
cmake --preset $preset *>&1 | Tee-Object $configureLog
if ($LASTEXITCODE -ne 0) { throw "CMake configure failed: $LASTEXITCODE" }
cmake --build --preset $preset --parallel *>&1 | Tee-Object $buildLog
if ($LASTEXITCODE -ne 0) { throw "CMake build failed: $LASTEXITCODE" }
输出位于 build-out 下以 preset 命名的子目录。Windows Release 构建至少应得到 TensorRT/CUDA bridge DLL;具体文件名和
目录由 CMake targets 决定,不要用其它 preset 的旧 DLL 填补缺失产物。
第七步:验证 ABI 与导出
manifest、public header、编译链接和 PE export 是四层不同证据。先运行三代声明检查:
pwsh -NoProfile -File .\eng\Test-TensorRtNativeAbiSurface.ps1 `
-TensorRtLines 8,10,11
再对本次构建的 DLL 执行仓库已有 PE export parity gate。若手工排障,可先看依赖:
dumpbin /dependents .\build-out\win-x64-trt10-cuda12-release\bin\Release\jyppxtrtbridge.dll
dumpbin 只能帮助定位依赖和导出,不能证明实际 vendor 调用成功。
第八步:构建托管 Solution
先 restore 一次,后续验证使用 --no-restore 避免无意网络下载:
dotnet restore .\TensorRtSharp.sln
dotnet build .\TensorRtSharp.sln -c Debug --no-restore --nologo -m:1
完整 build 应为 0 warning / 0 error。若并行 build 因共享 obj 文件发生写入冲突,先关闭 build server,
再用 -m:1 串行复跑:
dotnet build-server shutdown
dotnet build .\TensorRtSharp.sln -c Debug --no-restore --nologo -m:1
不要把一次并发写入冲突记录成源码功能失败,也不能忽略串行复跑结果。
第九步:运行分层测试
dotnet test .\tests\JYPPX.ProjectQuality.Tests\JYPPX.ProjectQuality.Tests.csproj `
-c Debug --no-restore --filter "FullyQualifiedName~Binding|FullyQualifiedName~NativeAbi"
修改具体 wrapper 时再加对应 focused tests。运行 runtime smoke 前,确认目标 bridge 和 NVIDIA DLL 已进入 同一个隔离输出目录,避免全局 PATH 污染测试结果。
第十步:本地包与 Consumer
托管包项目位于 pack/JYPPX.TensorRT.CSharp.API。本地 pack 输出放到 E 盘:
$feed = '..\downloads\package-feed'
New-Item -ItemType Directory -Force $feed | Out-Null
dotnet pack .\pack\JYPPX.TensorRT.CSharp.API\JYPPX.TensorRT.CSharp.API.csproj `
-c Debug --no-restore -o $feed
随后可运行 eng/Test-BridgePackageConsumer.ps1 或与目标 runtime key 对应的 package consumer gate。
本地 feed、direct nupkg、ProjectReference 和 bridge-only build 都只是本地工程证据,不是 public package
consumer runtime proof。
环境验证阶梯
| 阶段 | 成功标准 | 仍未证明 |
|---|---|---|
| 工具探测 | dotnet/CMake/MSVC 可调用 | NVIDIA roots 正确 |
| root validator | 目标 SDK 文件齐全 | native bridge 能链接 |
| generator | 绑定稳定、无重复 | vendor symbol 存在 |
| CMake build | 指定组合编译链接 | runtime 能加载所有 DLL |
| ABI/export | 声明与产物一致 | API 行为正确 |
| solution build | 托管项目编译 | GPU runtime 执行 |
| local consumer | 包布局和 copy 可验证 | public channel/clean runtime proof |
常见问题
CMake 找不到 NvInfer.h
TensorRtRoot 应指向包含 include/lib/bin 的 SDK 根。检查 resolver 输出和 key,不要只设置 PATH。
Linker 找不到 TensorRT symbol
确认 header 与 import library 来自同一个 TensorRT build。若 header 声明而 vendor binary 不提供 symbol, 应记录 candidate evidence 并保持 deferred,不能用空实现绕过 linker。
DLL 找不到或加载了错误版本
先检查应用输出目录,再检查 PATH 顺序。将 dependency probe 的实际路径和版本写入日志;不要从系统目录 或另一 runtime key 随手复制 DLL。
CUDA error 35
这通常是 NVIDIA driver 不支持目标 CUDA runtime。更换兼容 driver 或选择较低 runtime key,并保留
blocked-by-cuda-driver 分类。它不是 build success,也不是 API missing。
Windows Defender Application Control 拒绝测试 DLL
记录错误码和签名状态,使用项目提供的签名/consumer 选项处理。不要关闭系统安全策略来制造一次性通过。
Restore 把包下载到系统盘
本篇不要求下载额外包。执行 --no-restore 的验证不会发起 restore。确需首次 restore 时,先设置受控的
NuGet cache/feed 策略并记录位置,用后清理本批临时资产;不要把模型、SDK 或 nupkg 长期留在 Downloads/Temp。
边界说明
本文是环境与 source build 教程。local SDK、native build、solution build、local package 和 dependency probe 都不等于 clean public package consumer、real-model runtime、post-publish verification 或 owner authorization。
本阶段不执行发布,保持 performsPublish=false、canPublishPublicly=false、canCloseReleaseIssue=false。
完成清单
- [ ] 仓库和大资产位于 E 盘受控工作区。
- [ ] .NET、PowerShell、CMake、MSVC 与 driver 快照已保存。
- [ ] 选择了唯一 runtime key 与 preset。
- [ ] local runtime roots 不进入 Git。
- [ ] Windows runtime input validator 通过。
- [ ] binding generator 与幂等测试通过。
- [ ] 指定 native preset configure/build 通过。
- [ ] ABI declaration 与 PE export parity 通过。
- [ ] solution build 0 warning / 0 error。
- [ ] 测试和 consumer 结果按证据级别记录。
- [ ] C 盘 Downloads/Temp 无本批重资产残留。