WinArk 编译环境踩坑:vcpkg 三元组与 v142 工具集
WinArk 的工程文件是按 Visual Studio 2019 的 v142 平台工具集生成的。这一点决定了整条依赖链的口径:只要有任何一个静态库是用别的工具集编出来的,链接期就会失败,而且报错信息并不会直接告诉你「工具集对不上」。
症状:C1900
x86 配置下链接时报:
LINK : fatal error C1900: Il mismatch between 'P1' version '...' and 'P2' version '...'
这个错误的含义是链接进来的目标文件由不同版本的编译器前后端产生。放到 WinArk 的场景里,几乎总是同一个原因:vcpkg 装出来的 x86 静态库用的是 v143(VS2022)工具集,而工程本身是 v142。
正确的配置口径
用 VS2019 的 MSBuild 构建,不要用 VS2022 的。机器上同时装了两个版本时,
PATH里先命中哪个是不确定的,构建脚本里要写全路径。vcpkg 三元组必须钉在 v142。x86 静态库对应的三元组是
x86-windows-static,在它的三元组文件里显式指定工具集:set(VCPKG_PLATFORM_TOOLSET v142)改完之后,已经装过的包要重新装一遍才会生效——vcpkg 不会因为三元组文件变了就自动重建二进制缓存里的包。
CRT 链接方式要一致。静态三元组用
/MT,工程侧的「运行库」选项必须同样是多线程 (/MT),混用/MD会在链接期报一堆LNK2038的RuntimeLibrary不匹配。
一个容易忽略的点
x64 配置往往能编过,x86 才炸。原因通常是 x64 的依赖是早先用对工具集装的,而 x86 是后来补装的——补装那次机器上已经是 VS2022 当道了。所以排查时不要只看工程设置,先确认每个架构的依赖分别是什么时候、用什么工具集装的。
判断办法很直接,对着静态库跑一下:
dumpbin /rawdata:1 /section:.debug$S your.lib | findstr /i "Microsoft (R) C/C++"
输出里的编译器版本号 19.2x 是 v142,19.3x 是 v143。
小结
| 项 | 取值 |
|---|---|
| 平台工具集 | v142(VS2019) |
| 构建工具 | VS2019 的 MSBuild(写全路径) |
| x86 三元组 | x86-windows-static,并 set(VCPKG_PLATFORM_TOOLSET v142) |
| 运行库 | /MT(与静态三元组一致) |
把这四条钉死,C1900 就不会再出现了。