vcpkg 的 versioning 是通过基线(baseline)和锁定文件(vcpkg-lock.json)实现依赖版本稳定复现的机制:在 vcpkg-configuration.json 中指定 registry 和 baseline commit hash,配合 vcpkg.json 声明依赖,执行 vcpkg install 后生成对应 triplet 的锁定文件,确保构建可重现。
vcpkg 的 versioning 功能不是指给 vcpkg 自身打版本号,而是让 C++ 项目能**稳定复现依赖版本**:通过 vcpkg.json 声明所需库的语义版本范围,再由 vcpkg install 根据 vcpkg-configuration.json 中指定的 baseline(基线)来解析出每个库的**确切 commit hash**,并写入 vcpkg-lock.json(锁定文件)。这类似于 npm 的 package-lock.json 或 pip 的 requirements.txt。
必须显式启用,vcpkg 默认关闭 versioning。启用后,vcpkg install 才会读取 baseline、解析版本、生成锁定文件。
vcpkg-configuration.json,内容至少包含:{
"registries": [
{
"kind": "git",
"repository": "https://github.com/Microsoft/vcpkg",
"baseline": "3712b5e6f0a4d6a82954e7397331523c87381152"
}
],
"default_registry": {
"kind": "builtin"
}
}baseline 值必须是 vcpkg 仓库中某个真实 commit hash(推荐用 vcpkg x-history 查最近稳定 tag 对应的 hash)vcpkg.json(哪怕只声明一个库),例如:{
"name": "myapp",
"version-string": "0.1.0",
"dependencies": ["fmt", "nlohmann-json"]
}vcpkg install --triplet x64-windows(或对应 triplet),成功后自动生成 vcpkg-lock.json
很多人以为加了 vcpkg-configuration.json 就自动生效,其实极易因以下原因失败:
vcpkg-configuration.json 不在当前工作目录或其任意父目录 —— vcpkg 只向上查找,不跨盘符,也不从 VCPKG_
ROOT 自动加载baseline 值无效(拼写错误、非 git commit hash、或该 commit 不存在于 registry 指定的 repo 中)→ vcpkg 会静默回退到无 versioning 模式,不报错也不生成 lock 文件vcpkg.json 中依赖未使用语义版本(如 "fmt" 是允许的,但 "fmt>=10.0.0" 才真正触发 versioning 解析;不过即使写成 "fmt",只要启用了 versioning,也会按 baseline 锁定具体版本)vcpkg install 时未指定 --triplet → vcpkg 可能使用默认 triplet(如 x64-windows),但若项目实际构建用的是 x64-linux,则生成的 vcpkg-lock.json 不匹配,CI 构建会拉错二进制vcpkg-lock.json 是必须提交到 Git 的关键文件,但它本身不包含 binary cache 信息,且对 triplet 敏感:
x64-windows / x64-linux / arm64-osx)会生成**各自独立的 lock 文件**(可通过 --lock-file 指定路径区分),不要共用一个文件git clone https://github.com/Microsoft/vcpkg 并 git checkout ,再运行 vcpkg install,否则 vcpkg 可能用本地已有的、版本不一致的 registry 缓存vcpkg-lock.json 中记录的是每个端口(port)对应的 commitish(通常是 port 目录下的 git hash),不是库源码的版本 —— 即使 fmt 库自身发布新 patch,只要 port 文件没改,hash 就不变;反之,port 文件一改(比如修复了 CMakeLists.txt),hash 就变,即使库源码没动vcpkg.json,必须重新运行 vcpkg install 生成新 lock 文件,并验证三方库头文件/API 是否兼容 —— versioning 稳定的是“构建确定性”,不是“API 兼容性”baseline、vcpkg-lock.json、triplet 和 CI 中的 registry checkout 步骤全部对齐。漏掉任意一环,锁定就失效。