14 KiB
Geopro 3.0 桌面客户端 — Windows 开发环境从零搭建指引
适用:Windows 10 22H2 / Windows 11,64 位,MSVC 2022(v143)工具链。
目标:从一台干净的机器,搭到 build.bat app 能编出可运行、且不因 ABI 不匹配崩溃的 Qt6 + VTK9 桌面程序。
最后核对:2026-07-01,已对齐
CMakePresets.json/vcpkg.json/ 根CMakeLists.txt/build.bat的真实配置。 ⚠️ 若你手里有更早版本的本文档:§6.1/§7/§9 曾残留「全 vcpkg(Qt/VTK 也走 vcpkg)」的旧方案,与现状矛盾——以本版为准。 现状是「方案②-修订」:官方预编译 Qt + 源码编 VTK + vcpkg 只管非 Qt 依赖。
0. 总览(方案②-修订)
单一 Qt = 官方 MSVC 预编译 Qt(D:\Qt\6.11.1\msvc2022_64)。凡依赖 Qt 的组件都不走 vcpkg(vcpkg 的 Qt 端口会再编一份 qtbase = 双份 Qt 冲突):
| 组件 | 来源 | 备注 |
|---|---|---|
| Qt 6.11.1(Core/Gui/Widgets/Network/Sql/Concurrent/OpenGL + tools) | 官方 MSVC 2022 64-bit kit(§4) | 路径由预设 CMAKE_PREFIX_PATH 指定 |
| VTK 9.6.x(GUISupportQt/RenderingOpenGL2/RenderingFreeType/InteractionStyle/FiltersSources…) | 源码 Release 编 → external/vtk-install(§5) |
必须对齐同一份 Qt + 同一工具集 + Release//MD |
| ADS(Qt-Advanced-Docking-System 4.3.1) | FetchContent 自动(配置时拉,对接官方 Qt) | 无需手动 |
| QtKeychain v0.14.0 | FetchContent 自动(BUILD_WITH_QT6) |
无需手动 |
| Qwt 6.2(二维科学图表) | 手工克隆到 external/qwt-src(§5.3,gitignored) |
缺失则详情页图表功能不编入 |
| vendored 3DGPRViewer(geopro_gpr3dv) | 仓库内 external/gpr3dviewer(随仓库) |
无需手动 |
| 非 Qt 依赖:eigen3 / gdal / gtest / nlohmann-json / openssl / proj | vcpkg manifest(vcpkg.json,有 baseline 锁版本) |
配置时自动拉 |
ABI 铁律(否则运行时崩溃,见 §10):Qt(预编译 msvc2022) / VTK(你自己编) / app / 所有 FetchContent 组件,必须同一工具集(v143)、同一运行时(/MD)、同一配置(全 Release)。任何一处混 Debug/Release 或换工具集,std::map/std::string 跨界就崩。
1. Visual Studio(MSVC v143 + CMake + Ninja)
- 安装 Visual Studio 2022 Community(或更高)。
build.bat也兼容 VS2026 preview,但其工具集必须与预编译 Qt 的 msvc2022(v143) ABI 兼容——若用 VS2026 的更新工具集,稳妥做法是用同一工具集重编 VTK(§5),别让 Qt(v143 预编译) 与 VTK/app(更新工具集) 混。 - 勾选工作负载 「使用 C++ 的桌面开发」,确保含:
- MSVC v143 - VS 2022 C++ x64/x86 生成工具
- Windows 11 SDK(或 Windows 10 SDK)
- C++ CMake tools for Windows(自带 CMake ≥3.21 + Ninja)
- C++ AddressSanitizer(Debug Sanitizer 用)
- 验证(开「x64 Native Tools Command Prompt for VS」):
cl/cmake --version(≥3.21)/ninja --version。
build.bat会用vswhere自动定位 VS 并激活 MSVC 环境,所以日常构建直接跑build.bat即可,不必手动开 x64 命令行。但cmake/ninja/cl不在 PATH,手动跑 cmake 前需先激活 vcvars64。
2. Git
- 安装 Git for Windows,
git --version验证。 - 本项目已是 git 仓库(无需
git init);正常git clone即可。
3. vcpkg(仅非 Qt 依赖)
git clone https://github.com/microsoft/vcpkg C:\dev\vcpkg # 路径不含空格/中文
C:\dev\vcpkg\bootstrap-vcpkg.bat
setx VCPKG_ROOT "C:\dev\vcpkg" # 永久;新开终端生效
- manifest 模式:根
vcpkg.json声明依赖 +builtin-baseline锁版本,CMake 配置时自动拉取,无需手动vcpkg install。 - 实际依赖(勿加 Qt/VTK 进来):
eigen3, gdal, gtest, nlohmann-json, openssl, proj。 - 不要随意
vcpkg x-update-baseline——baseline 已锁,改动会漂移依赖版本、可能引入 ABI 不一致。 - 首次会编 GDAL/PROJ 等,较久;可选配
VCPKG_BINARY_SOURCES二进制缓存加速。
4. Qt(官方 MSVC 2022 64-bit kit)
必须是 MSVC kit——若你原装的是 mingw_64,MSVC 下不可链:
- 用官方在线安装器(或已装则开
D:\Qt\MaintenanceTool.exe)→ Add or remove components → 登录 Qt 账号。 - 展开 Qt → Qt 6.11.1,勾选 MSVC 2022 64-bit,安装。
- 完成后应存在
D:\Qt\6.11.1\msvc2022_64\lib\cmake\Qt6。 - 设
QT_ROOT环境变量指向该 kit(与VCPKG_ROOT同一套路,预设CMAKE_PREFIX_PATH=$env{QT_ROOT}读它,§6):
全链路只此一份 Qt。 版本仍须是 6.11.1(换版本可能与源码编的 VTK/ADS 不匹配)。setx QT_ROOT "<你的路径>\6.11.1\msvc2022_64" # 永久;新开终端生效
若你的 Qt 装在别处/别的版本:改
QT_ROOT指向你的msvc2022_64即可,无需动预设;但版本仍须是 6.11.1。 未设QT_ROOT时:build.bat会立即报[build] QT_ROOT is not set...并退出;直接跑 cmake 则配置期FATAL_ERROR: QT_ROOT 未设置或无效。
5. 源码依赖(手工准备)
5.1 VTK 9.6.x 源码编到 external/vtk-install(用官方 Qt,Release)
call "<VS>\VC\Auxiliary\Build\vcvars64.bat"
git clone --depth 1 --branch v9.6.2 https://gitlab.kitware.com/vtk/vtk.git D:\dev\vtk-src
cmake -S D:\dev\vtk-src -B D:\dev\vtk-build -G Ninja ^
-D CMAKE_BUILD_TYPE=Release -D BUILD_SHARED_LIBS=ON ^
-D VTK_GROUP_ENABLE_Qt=YES -D VTK_MODULE_ENABLE_VTK_GUISupportQt=YES ^
-D Qt6_DIR=D:/Qt/6.11.1/msvc2022_64/lib/cmake/Qt6 ^
-D CMAKE_PREFIX_PATH=D:/Qt/6.11.1/msvc2022_64 ^
-D VTK_BUILD_TESTING=OFF -D VTK_BUILD_EXAMPLES=OFF ^
-D CMAKE_INSTALL_PREFIX=D:/Git/lanbingtech/geopro/external/vtk-install
cmake --build D:\dev\vtk-build --target install
- 完成后
external/vtk-install/lib/cmake/vtk-9.6供find_package(VTK)(CMakePresets.json里VTK_DIR已指向它)。 - 必须 Release + 与本项目相同的工具集(v143)编;因此本项目也用
msvc-release构建,避免/MDvs/MDd或 Debug/Release 混链(→ §10 崩溃)。需要调试 VTK 时另出一份 Debug VTK,且此时 app 也须整套 Debug。 - 根
CMakeLists.txt里find_package(VTK REQUIRED COMPONENTS ...)必须列组件(否则VTK_LIBRARIES为空、链不到);当前组件:GUISupportQt / RenderingOpenGL2 / RenderingFreeType / InteractionStyle / FiltersSources(随渲染层增补)。
5.2 ADS / QtKeychain(FetchContent,自动)
无需手动——根 CMakeLists.txt 用 FetchContent 拉 ADS 4.3.1 与 QtKeychain v0.14.0,对接同一份官方 Qt(BUILD_WITH_QT6=ON)。首次配置会 clone,需能访问 GitHub。
5.3 Qwt 6.2(手工克隆到 external/qwt-src)
二维科学图表(数据集详情散点/等值线)依赖 Qwt。external/qwt-src 已 gitignore,须自备:
# 克隆/解压 Qwt 6.2 源码到 external/qwt-src,使 external/qwt-src/src 存在
git clone --branch qwt-6.2 https://git.code.sf.net/p/qwt/git external/qwt-src
- CMake 检测到
external/qwt-src/src才 includecmake/qwt.cmake编 Qwt;缺失则相关图表功能不编入(不报错,但详情图表缺失)。
6. CMake 接线(现状,勿照旧文档)
6.1 CMakePresets.json(真实内容)
{
"configurePresets": [
{
"name": "msvc-debug",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
"VCPKG_TARGET_TRIPLET": "x64-windows",
"CMAKE_PREFIX_PATH": "$env{QT_ROOT}",
"VTK_DIR": "${sourceDir}/external/vtk-install/lib/cmake/vtk-9.6"
}
},
{ "name": "msvc-release", "inherits": "msvc-debug",
"binaryDir": "${sourceDir}/build/release",
"cacheVariables": { "CMAKE_BUILD_TYPE": "Release" } }
]
}
- 预设确实设
CMAKE_PREFIX_PATH(官方 Qt,读$env{QT_ROOT})+VTK_DIR(源码编的 VTK,仓库相对、无需环境变量)——这是「方案②-修订」的核心,别按旧文档去掉它。QT_ROOT未 setx 时配置期会 FATAL(§4)。 - vcpkg 只经
CMAKE_TOOLCHAIN_FILE管非 Qt 依赖;tripletx64-windows。
6.2 根 CMakeLists.txt 要点
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Network Sql Concurrent)。find_package(VTK REQUIRED COMPONENTS GUISupportQt RenderingOpenGL2 RenderingFreeType InteractionStyle FiltersSources)(必须列组件)。- MSVC flags:
/utf-8 /MP /W4 /permissive-;非 Debug 配置产 PDB(/Zi+/DEBUG+/OPT:REF,ICF)。 - ADS/QtKeychain 经 FetchContent;Qwt 经
cmake/qwt.cmake(存在才编)。 - 视图层用
QVTKOpenGLStereoWidget(QOpenGLWidget 系,ADS reparent 友好)。
7. 首次配置、编译、运行、部署
日常直接用 build.bat(推荐):
build.bat app # 配置(首次)+ 增量编 geopro_desktop(Release)
build.bat test # 编 + ctest 跑单测
build.bat run # 编 + 启动
build.bat rebuild # 强制 --clean-first 全量重编(增量疑似漏编时用)
build.bat configure # CMakeLists 改动后强制重跑 configure
build.bat固定--preset msvc-release、build/release,自动激活 MSVC 环境。exe:build/release/src/app/geopro_desktop.exe。- 首次会拉 vcpkg 依赖 + FetchContent(ADS/QtKeychain),较久;VTK/Qt/Qwt 须已按 §4/§5 就位。
运行期 DLL 部署(官方 Qt,非 vcpkg):
- Qt6*.dll + plugins:用官方 Qt 的
windeployqt(D:\Qt\6.11.1\msvc2022_64\bin\windeployqt.exe)对齐同一份官方 Qt 到 exe 目录。 - VTK*.dll:从
external/vtk-install/bin拷到 exe 目录(或加进 PATH)。 - 只保证 exe 目录一份 Qt6.dll(无双 Qt)*;勿混入别处/vcpkg 的 Qt。
8. AI/IDE 上下文(clangd)
.clangd:CompileFlags.CompilationDatabase: build/release(对齐build.bat的主构建目录;若你主要用 Debug 则指build/debug)。CMAKE_EXPORT_COMPILE_COMMANDS=ON会在该目录产compile_commands.json。- VS Code 用 clangd 扩展(禁用微软 C++ IntelliSense 避免冲突)。
9. 构建环境兼容性检查清单(交付/接手前逐项核对)
目的:把「配置错→运行时随机崩溃」变成「一眼可查」。任何一项不满足都可能导致 §10 的
std::map/std::stringABI 崩溃。
9.1 前置就位
cl/cmake(≥3.21) /ninja/git可用;VCPKG_ROOT已设。QT_ROOT已 setx 指向 6.11.1msvc2022_64kit(MSVC,非 MinGW);$QT_ROOT/lib/cmake/Qt6在(预设CMAKE_PREFIX_PATH=$env{QT_ROOT}读它;未设则配置期 FATAL)。external/vtk-install/lib/cmake/vtk-9.6存在(VTK 已源码编 install)。external/qwt-src/src存在(如需详情页图表)。vcpkg.json的builtin-baseline未被改动。
9.2 ABI 一致性(最关键,防崩溃)
- 单一配置:Qt(预编译) / VTK(你编) / app / ADS / QtKeychain / Qwt 全 Release(或全 Debug),绝不混。日常一律
build.bat(msvc-release)。 - 同一工具集:VTK/app 用的 MSVC 工具集与预编译 Qt 的 v143(msvc2022) ABI 兼容;若用 VS2026-preview 工具集,用它重编 VTK,别让 Qt(v143) 与 VTK/app(更新集) 混。
- 同一运行时:全部
/MD(Release 动态 CRT),_ITERATOR_DEBUG_LEVEL=0。绝不把 Release 的 Qt/VTK 链进 Debug 的 app(Debug 是/MDd+ IDL=2,STL 布局不同)。 - VTK 来源正确:是你按 §5.1 源码 Release 编、对齐本 Qt 的那份;不是 vcpkg 的 VTK、不是别处/别配置的 VTK。
- 单一 Qt:exe 目录/PATH 只有一份 Qt6*.dll,无双 Qt。
9.3 干净构建验证
- 删
build/后build.bat app从零配置无错(尤其无「找不到 Qt6/VTK」「add_subdirectory 目录不存在」)。 build.bat test→ ctest 全绿。- 启动 app、点对象树、渲染视图不崩(§10 的崩溃即出现在这里)。
10. 已知崩溃签名 → 根因速查
| 现象 | 根因 | 处理 |
|---|---|---|
点对象树/渲染时,崩在 std::_Tree::_Find_lower_bound(std::map/set 查找),_Myhead 是 0xFFFF... 之类垃圾值,读取访问冲突 |
STL ABI 不匹配:Debug/Release 混链、/MD vs /MDd、_ITERATOR_DEBUG_LEVEL 不一致、或工具集不匹配(最常见:别处/别配置的 VTK/Qt,或 Debug app 链 Release 依赖) |
按 §9.2 逐项核对;删 build/ 全 Release 干净重建;确认 VTK 是 §5.1 那份 |
配置期 FATAL_ERROR: QT_ROOT 未设置或无效 / build.bat 报 [build] QT_ROOT is not set |
未 setx QT_ROOT 或指向的 kit 不含 lib/cmake/Qt6 |
setx QT_ROOT "<你的Qt>\6.11.1\msvc2022_64" 后重开终端(§4) |
配置期 FATAL_ERROR: Qt 版本不匹配 / VTK 版本不匹配 / VTK 未就位 |
装了非 6.11.x Qt、非 9.6.x VTK,或 external/vtk-install 缺失 |
按 §4/§5 装对版本/就位 VTK |
| 链接期报「找不到 Qt6::/VTK::」 | 预设 CMAKE_PREFIX_PATH($env{QT_ROOT})/VTK_DIR 指向不存在 |
按 §4/§5 就位或修正 QT_ROOT |
| 配置报「add_subdirectory ... 不是已存在目录」 | 引用了未随仓库的目录(如误提交本地临时工具目录) | 从 CMakeLists.txt 去掉该引用,或补齐该目录 |
| 详情页图表缺失但不报错 | external/qwt-src 未就位(§5.3) |
克隆 Qwt 后重配置 |
| 双 Qt / 起不来找不到 platform 插件 | 混入了 vcpkg/别处的 Qt dll | 只用官方 windeployqt 对齐单一 Qt |
遇到具体报错按规约由工程师复核;AI 协助按 build-error-resolver 流程逐条解决。