# 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) 1. 安装 **Visual Studio 2022 Community**(或更高)。`build.bat` 也兼容 VS2026 preview,但**其工具集必须与预编译 Qt 的 msvc2022(v143) ABI 兼容**——若用 VS2026 的更新工具集,稳妥做法是**用同一工具集重编 VTK**(§5),别让 Qt(v143 预编译) 与 VTK/app(更新工具集) 混。 2. 勾选工作负载 **「使用 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 用) 3. 验证(开「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 1. 安装 [Git for Windows](https://git-scm.com/download/win),`git --version` 验证。 2. 本项目**已是 git 仓库**(无需 `git init`);正常 `git clone` 即可。 --- ## 3. vcpkg(仅非 Qt 依赖) ```powershell 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 下不可链: 1. 用官方在线安装器(或已装则开 `D:\Qt\MaintenanceTool.exe`)→ Add or remove components → 登录 Qt 账号。 2. 展开 Qt → **Qt 6.11.1**,勾选 **MSVC 2022 64-bit**,安装。 3. 完成后应存在 `D:\Qt\6.11.1\msvc2022_64\lib\cmake\Qt6`。 4. **设 `QT_ROOT` 环境变量指向该 kit**(与 `VCPKG_ROOT` 同一套路,预设 `CMAKE_PREFIX_PATH=$env{QT_ROOT}` 读它,§6): ```powershell setx QT_ROOT "<你的路径>\6.11.1\msvc2022_64" # 永久;新开终端生效 ``` **全链路只此一份 Qt。** 版本仍须是 **6.11.1**(换版本可能与源码编的 VTK/ADS 不匹配)。 > 若你的 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) ```bat call "\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` 构建**,避免 `/MD` vs `/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,须自备: ```powershell # 克隆/解压 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` 才 include `cmake/qwt.cmake` 编 Qwt;**缺失则相关图表功能不编入**(不报错,但详情图表缺失)。 --- ## 6. CMake 接线(现状,勿照旧文档) ### 6.1 `CMakePresets.json`(真实内容) ```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 依赖;triplet `x64-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::string` ABI 崩溃。** ### 9.1 前置就位 - [ ] `cl` / `cmake`(≥3.21) / `ninja` / `git` 可用;`VCPKG_ROOT` 已设。 - [ ] `QT_ROOT` 已 setx 指向 **6.11.1 `msvc2022_64`** kit(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 流程逐条解决。*