vcpkg manifest 的使用

sun發表於2023-10-13

最近專案上要使用 CMakeLists 管理,由於 Windows 版本有依賴到 vcpkg 提供的庫,所以需要使用 vcpkg manifest 來統一設定庫的版本,方便後續維護

推薦一個文章,介紹的可以說是非常全面了

不過裡面也有一些過時的特性,我在後面會補充一下

為了防止上面文章的連結失效,故列出一些常用的命令

這是一個完整的 vcpkg.json

{
    "name": "versions-test",
    "version": "1.0.0",
    "dependencies": [
    {
      "name": "fmt",
      "version>=": "7.1.3"
     },
     "zlib"
    ],
    "builtin-baseline": "6a349fe1fbea1e5fcda2e0775f555d829a5e82df",
    "overrides": [
    {
       "name": "fmt",
       "version": "6.0.0"
     }
    ]
}

原文中說使用 git rev-parse HEAD 獲取 builtin-baseline 其實是不準確的

git rev-parse HEAD

git rev-parse HEAD 是獲取 .git 中當前分支的最新 commit_id,這與庫是沒什麼關係的,如下

// 在 cmd 中輸入
C:\Users\xxx\vcpkg>git rev-parse HEAD
6a349fe1fbea1e5fcda2e0775f555d829a5e82df
C:\Users\xxx\vcpkg>git show 6a349fe1fbea1e5fcda2e0775f555d829a5e82df
commit 6a349fe1fbea1e5fcda2e0775f555d829a5e82df (HEAD -> master, origin/master, origin/HEAD, ffmpeg_test)
Author: Billy O'Neal <bion@microsoft.com>
Date:   Mon Sep 18 16:34:12 2023 -0700

    Update vcpkg-tool to 2023-09-15 (#33804)

    https://github.com/microsoft/vcpkg-tool/releases/tag/2023-09-15

diff --git a/scripts/vcpkg-tool-metadata.txt b/scripts/vcpkg-tool-metadata.txt
index eb6591bf4..c8387661b 100644
--- a/scripts/vcpkg-tool-metadata.txt
+++ b/scripts/vcpkg-tool-metadata.txt
@@ -1,5 +1,5 @@
-VCPKG_TOOL_RELEASE_TAG=2023-08-09
-VCPKG_MACOS_SHA=b46eaabbcc586b40c21f15ae8da671ce67da9022cd7acef4651bf8de81587f06074e7eb4066f521086270c01f9fa557374972159756412e852426a3ff04759d4
-VCPKG_MUSLC_SHA=114de7c643386ca2b8319bacfd83979e109abe490d4f25a23a0918fc0020f918131fb260cdb8abbbbaae7c170952e0327cf77c26cfa9135c6a1bfd7e6c0d8fca
-VCPKG_GLIBC_SHA=4aa9b734b13526385c0d034452a52edd393e9a1d11274634cd4dacf52f16a3579782a9a6069746e15c2b82257046f3be951bf7c7a03846236fb6247211308044
-VCPKG_TOOL_SOURCE_SHA=bcf05ca1f52bd5cd8274fd6e1678bd1d4f9673aecead127fe4a4d7e40c583829f60bc568cdfa9ce36f13a6cbf21d95322dd7088b011024461682813c8ab1ecb3
+VCPKG_TOOL_RELEASE_TAG=2023-09-15
+VCPKG_MACOS_SHA=3c822003ec4e5eb3ea15d8ccf1a156f1d58e742b9d375a79693af9ad5b454796d4a42e05091bafefdf8359b56aee27ff8b07ff9bcb99f549a5bc81cb7ed47cc7
+VCPKG_MUSLC_SHA=125c77acbc6a2271eb882767e44da3fb0acd0719a35f2460e65eafcccae47967a5c370206d7af06b1d5a10d4ea53d04e620ca8df4bface8cd972b27eb89cf04e
+VCPKG_GLIBC_SHA=08d27596961819573a66163ca5373e8f20137856d78d58154cc9ad0ba4864a1d22698d25c08c5ebcb3601f2952a476b0f1d12bed25c42cdbe6dab520870fabf3

  

// 在 git bash 中輸入 git log 檢視歷史提交
xxx@DESKTOP-MS9D4O9 MINGW64 ~/vcpkg (master)
$ git log
commit 6a349fe1fbea1e5fcda2e0775f555d829a5e82df (HEAD -> master, origin/master, origin/HEAD, ffmpeg_test)
Author: Billy O'Neal <bion@microsoft.com>
Date:   Mon Sep 18 16:34:12 2023 -0700

    Update vcpkg-tool to 2023-09-15 (#33804)

    https://github.com/microsoft/vcpkg-tool/releases/tag/2023-09-15

commit 0a50c9623b797eb393ca852099bc3b776c34b532
Author: Fabien Péan <fabien@pean.pro>
Date:   Mon Sep 18 19:12:53 2023 +0200

    [yomm2] Update to v1.4.0 (#33509)

...

 

所以說用上述方法檢視 builtin-baseline 是不準確的,包括後面說的使用 x-history 命令也是過時的

新方法是使用 git blame -l 方法

git blame -l versions/<port-first-char>-/<portname>.json

相關文件:How do I get history versions of a port now

實際使用:

C:\Users\xxx\vcpkg>git blame -l versions/c-/curl.json
2f6537fa2b8928d2329e827f862692112793435d port_versions/c-/curl.json (Victor Romero              2021-01-14 16:08:36 -0800   1) {
2f6537fa2b8928d2329e827f862692112793435d port_versions/c-/curl.json (Victor Romero              2021-01-14 16:08:36 -0800   2)   "versions": [
679df196c1d43210c4dfd079a47fa4bcefe44f00 versions/c-/curl.json      (Lily Wang                  2023-08-02 08:59:01 -0700   3)     {
679df196c1d43210c4dfd079a47fa4bcefe44f00 versions/c-/curl.json      (Lily Wang                  2023-08-02 08:59:01 -0700   4)       "git-tree": "1e4df4c9590fb15d2d73014c66dbbc151b624b9b",
679df196c1d43210c4dfd079a47fa4bcefe44f00 versions/c-/curl.json      (Lily Wang                  2023-08-02 08:59:01 -0700   5)       "version": "8.2.1",
679df196c1d43210c4dfd079a47fa4bcefe44f00 versions/c-/curl.json      (Lily Wang                  2023-08-02 08:59:01 -0700   6)       "port-version": 0
679df196c1d43210c4dfd079a47fa4bcefe44f00 versions/c-/curl.json      (Lily Wang                  2023-08-02 08:59:01 -0700   7)     },
864c70b8369e59c72fb71b50f2a233a91398d591 versions/c-/curl.json      (JonLiu1993                 2023-07-21 08:46:53 -0700   8)     {
864c70b8369e59c72fb71b50f2a233a91398d591 versions/c-/curl.json      (JonLiu1993                 2023-07-21 08:46:53 -0700   9)       "git-tree": "c82d0a822ec7d4044a58c18f2e198df681822cf6",
864c70b8369e59c72fb71b50f2a233a91398d591 versions/c-/curl.json      (JonLiu1993                 2023-07-21 08:46:53 -0700  10)       "version": "8.2.0",
864c70b8369e59c72fb71b50f2a233a91398d591 versions/c-/curl.json      (JonLiu1993                 2023-07-21 08:46:53 -0700  11)       "port-version": 0
864c70b8369e59c72fb71b50f2a233a91398d591 versions/c-/curl.json      (JonLiu1993                 2023-07-21 08:46:53 -0700  12)

  

c- 就是 versions 資料夾的子資料夾

 curl.json 是 c- 資料夾下的 json 檔案

 

那 versions 與 builtin-baseline 是如何配合使用呢?

藉助一開始文章連結,我貼出主要部分,

builtin-baseline 具體作用過程:

1. 從給定的 builtin-baseline(commit id)版本中查詢是否含有 baseline.json 檔案,如果有,就從這個檔案中查詢該庫的版本。

2. 如果沒有 baseline.json,就會報錯。

3. 如果有 baseline.json,但是它不包含庫的歷史版本,也會報錯。

version>=

以上示例中,zlib 的版本號 1.2.11#9 是由 version 和 port-version 兩部分組成,version(1.2.11) 是 zlib 的實際的版本號,port-version(9) 是這個版本在 vcpkg 中的補丁版本。兩者組合可以獲取該庫在 vcpkg 中的具體版本。

當 version 版本更新時,port-version 重置為 0 ,每次改動都加 1。

在 vcpkg 中,版本是如何比較大小呢?實際是比較版本的新舊,例如:

1.2.0 < 1.2.0#1 < 1.2.0#2 < 1.2.0#10
2021-01-01#20 < 2021-01-01.1
windows#7 < windows#8

注意:

1. Version>= 主要用於表示需要使用的最低版本,只有作為 "dependencies"的一部分時才是被允許的。

2. 如果使用 Version>=, vcpkg會從所有滿足條件的版本中選用最低版本,這種做法的好處是更新 vcpkg 時,避免依賴升級出現異常的問題。可以總結為:

如果使用 overrides,那麼會使用 overrides 提供的版本,例如 fmt 6.0.0。如果沒有,會選擇 version>= 和 builtin-baseline 中最高的版本,例如:

version>= 7.1.3 + builtin-baseline(7.1.4) , 會安裝 fmt 7.1.4;

version>= 7.1.3 + builtin-baseline(7.1.2) , 會安裝 fmt 7.1.3。

3. Vcpkg允許升級版本,例如: 如果 zlib 依賴fmt,而且宣告依賴 fmt 的 7.1.4 版本,那麼 vcpkg 就會安裝 7.1.4 版本,而不是 7.1.3。

4. 在您的專案中,如果想升級依賴庫的版本,只需把最低版本改掉,或者是把 builtin-baseline 改為更新的版本。

5. Vcpkg 不會比較version型別不同的版本,例如:同一個庫的2 個版本 ‘version-string: 7.1.3’ 與 `version: 7.1.4`,version 型別不同,所以不能比較。

以上大概都是能用到的知識


 

下面是我在專案中遇到的一些問題包括嘗試的解決方案:

第一個問題:

因為 manifest 無法識別 "triplet" 欄位,故無法在 vcpkg,json 中指定該欄位,只能在外部建立本地的 vcpkg 三方庫

D:\my_project\build>vcpkg install --triplet x86-windows-static
Detecting compiler hash for triplet x86-windows-static...
-- Using HTTP(S)_PROXY in environment variables.
Detecting compiler hash for triplet x64-windows...
The following packages will be built and installed:
....

最後會在專案的 build 檔案下生成相關庫

第二個問題:

我們隨便開啟一個自動生成的 vcpkg.json 會發現多了一些欄位,比如 “port-version”

{
  "name": "libfabric",
  "version-semver": "1.13.2",
  "port-version": 2,
  "description": "The OpenFabrics Interfaces Working Group (OFIWG) and the Libfabr...
  "homepage": "https://github.com/ofiwg/libfabric",
  "supports": "windows & !uwp & x64 & !static",
  "dependencies": [
    {
      "name": "networkdirect-sdk",
      "platform": "windows"
    },
    {
      "name": "vcpkg-msbuild",
      "host": true,
      "platform": "windows"
    }
  ]
}

“port-version” 其實就是補丁,上面有提到,那麼如何獲取呢?

我們拿 curl 來舉例,git show xxx(git show 命令後跟著一個特定的檔案路徑引數可以用於檢視 Git 倉庫中特定檔案在指定提交(17fc556532840f436f67f8d08c943d1ff97ea2f9)的版本)

C:\Users\xxx\vcpkg>git show 17fc556532840f436f67f8d08c943d1ff97ea2f9 versions/c-/curl.json
commit 17fc556532840f436f67f8d08c943d1ff97ea2f9
Author: Theodore Tsirpanis <theodore.tsirpanis@tiledb.com>
Date:   Thu Jul 13 21:24:11 2023 +0300

    [curl] Add zstd feature. (#32533)

diff --git a/versions/c-/curl.json b/versions/c-/curl.json
index ba17a0c9f..9c4f96d98 100644
--- a/versions/c-/curl.json
+++ b/versions/c-/curl.json
@@ -1,5 +1,10 @@
 {
   "versions": [
+    {
+      "git-tree": "c2681b59ec41e4ec760fe10a60385202ee4763bb",
+      "version": "8.1.2",
+      "port-version": 2
+    },
     {
       "git-tree": "7d8ee40552d5b1c103d52b2b28d9577cb45e2593",
       "version": "8.1.2",

可以看到 port_version 是 2,git-tree 是 commit-id,跟 builtin-baseline 不同,我們一般用不到它

順便補充下圖:

 

 

 

最下面的圖顯示的綠顏色字元都是新增的,說明當前分支新增了一個 8.2.1  的版本

 

 

相關文章