你正在開發(fā)一個(gè)依賴其他庫的c++項(xiàng)目嗎?你是否厭倦了用“膠水腳本”和git子模塊維護(hù)定制的包管理工作流?那么贪壳,你應(yīng)該考慮試用包管理器校摩。也許你已經(jīng)關(guān)注vcpkg有一段時(shí)間了冗荸,它看起來是你的團(tuán)隊(duì)的完美解決方案父阻,但有一個(gè)問題:您的所有依賴項(xiàng)都是開源的!您的公司也有希望每個(gè)人都使用的內(nèi)部庫。
vcpkg 可以與非開源依賴項(xiàng)一起使用嗎侄旬?
是的肺蔚。在此之前,你的最佳選擇是創(chuàng)建overlay ports或者fork vcpkg ports的分支儡羔。但是這還有改進(jìn)的空間⌒颍現(xiàn)在,我們高興地宣布一項(xiàng)實(shí)驗(yàn)性的特性來管理你期望的任何代碼庫汰蜘。不管它們是內(nèi)部使用的仇冯、開源的還是你自己fork的開源項(xiàng)目分支。在這篇文章中族操,我們將深入研究registries苛坚, 我們新的實(shí)驗(yàn)性功能。我們希望您嘗試這個(gè)功能色难,給我們反饋炕婶,并幫助我們使它最好的功能,它可以!
registries入門
前面我們討論了為什么需要registries莱预, 現(xiàn)在我們來討論怎么使用。假設(shè)我們是North Wind Traders的開發(fā)人員项滑,我們公司訂閱了Github企業(yè)版依沮。當(dāng)然涯贞,基于你公司或者你個(gè)人的實(shí)際情況,你可以繼續(xù)使用你目前的工作流程危喉。這篇文章的目標(biāo)是建立一個(gè)最為常見的git registry宋渔。
1. 創(chuàng)建一個(gè)新的registry
公司的Github地址是https://github.com/northwindtraders,可以用例創(chuàng)建registry辜限。我們將在https://github.com/northwindtraders/vcpkg-registry創(chuàng)建我們的registry皇拣,因?yàn)檫@是一個(gè)很好的名稱,你可以在那里跟蹤分支薄嫡。
創(chuàng)建好registry后氧急,我們需要做一些事來向里面添加我們需要的包,在本例中是我們內(nèi)部的JSON和Unicode庫毫深。
- 首先吩坝,我們將創(chuàng)建一個(gè)空的基線,這是registry的最低需求哑蔫。
- 然后钉寝,我們要添加庫需要構(gòu)建的文件,并確保他們是可工作的闸迷。
- 最后嵌纲,我們通過把庫添加到版本庫中,并寫明在git庫中的位置來把庫添加進(jìn)registry中腥沽。
2. 創(chuàng)建一個(gè)空的registry基線
克麓摺(空的)代碼倉庫,在根目錄下添加versions/baseline.json文件巡球,包含下面的內(nèi)容:
{
"default": {}
}
3. 創(chuàng)建一個(gè)vcpkg port
現(xiàn)在言沐,我們開始為我們兩個(gè)庫中的第一個(gè)(Unicode庫beicode)創(chuàng)建一個(gè)port條目.如果你曾經(jīng)編寫過port,那么你將知道如何執(zhí)行此操作酣栈,但是對(duì)于那些還沒有寫過port的人险胰,讓我們還是進(jìn)行一遍操作。
我們首先創(chuàng)建一個(gè)存放port的文件夾矿筝。根據(jù)vcpkg central registry的標(biāo)準(zhǔn)起便,我們稱這個(gè)文件夾為ports。因?yàn)槲覀兪褂梅€(wěn)定的git標(biāo)識(shí)符來指定目錄窖维,所以我們不需要將它放在特定的位置榆综,但最好遵循習(xí)慣。在這個(gè)目錄中铸史,創(chuàng)建beicode的port目錄鼻疮,其中放入兩個(gè)空文件:portfile.cmake 和 vcpkg.json。
現(xiàn)在琳轿,registry目錄應(yīng)該看起來像下面這樣:
ports/
beicode/
portfile.cmake
vcpkg.json
versions/
baseline.json
現(xiàn)在判沟,我們來填寫port耿芹。首先,由于beicode的Github倉庫已經(jīng)有了vcpkg.json挪哄,將里面的manifest信息拷貝到剛剛創(chuàng)建的vcpkg.json文件中:
{
"name" : "beicode",
"version" : "1.0.0",
"description" : "A simple utf-8 based unicode decoding and encoding library",
"homepage" : "https://github.com/northwindtraders/beicode"
}
4. 使用overlays測(cè)試新的vcpkg port
讓我們通過嘗試安裝來確保它工作吧秕;我們還沒有使用registries,使用預(yù)先存在的overlay-ports功能來測(cè)試:
> vcpkg install beicode --overlay-ports=vcpkg-registry/ports/beicode
我們應(yīng)該得到一個(gè)錯(cuò)誤:“文件夾/include為空或者不存在”迹炼。既然我們還什么都沒做砸彬,這個(gè)錯(cuò)誤是正常的。現(xiàn)在斯入,讓我們來填寫port砂碉!因?yàn)槲覀兊膒ort是一個(gè)簡(jiǎn)單的CMake庫,我們可以創(chuàng)建一個(gè)非常簡(jiǎn)單的portifle.cmake文件:
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO northwindtraders/beicode
REF 19a1f95c2f56a27ced90227b5e2754a602a08e69
SHA512 7b2bb7acb2a8ff07bff59cfa27247a7b2cced03828919cd65cc0c8cf1f724f5f1e947ed6992dcdbc913fb470694a52613d1861eaaadbf8903e94eb9cdfe4d000
HEAD_REF main
)
vcpkg_configure_cmake(
SOURCE_PATH "${SOURCE_PATH}"
PREFER_NINJA
)
vcpkg_install_cmake()
vcpkg_fixup_cmake_targets()
file(REMOVE_RECURES "${CURRENT_PACKAGES_DIR}/debug/include")
file(
INSTALL "${SOURCE_PATH}?LICENSE"
DESTINATION "${CURENT_PACKAGES_DIR}/share/${PORT}"
RENAME copyright)
如果我們?cè)俅芜\(yùn)行
> vcpkg install beicode --overlay-ports=vcpkg-registry/ports/beicode
我們會(huì)看到它已經(jīng)成功安裝了咱扣。我們已經(jīng)為我們的registry寫了第一個(gè)port绽淘,現(xiàn)在剩下要做的就是把port添加到registry的版本集中。
5. 為registry中的庫指定版本
每一個(gè)port的版本信息都存放在它自己的文件中:versions/[first character]-/[portname].json闹伪。例如沪铭,fmt的版本信息存放在versions/f-/fmt.json文件中;zlib的版本信息存放在versions/z-/zlib.json文件中偏瓤。所以杀怠,為beicode創(chuàng)建文件versions/b-/beicode.json:
{
"versions" : [
{
"versions" : "1.0.0",
"git_tree" : ""
}
]
}
在*versions/vaseline.json"文件中添加如下信息:
{
"default" : {
"deicode" : { "baseline" : "1.0.0", "port-version" : 0 }
}
}
現(xiàn)在,讓我們來看看”git-tree"字段中應(yīng)該是什么內(nèi)容厅克。進(jìn)行一次beicode的git提交(但是不push):
> git add ports/beicode
> git commit -m "[beicode] new port"
然后赔退,獲取該目錄的樹標(biāo)識(shí):
> git rev-parse HEAD:ports/beicode
你應(yīng)該得到一個(gè)類似于7fb5482270b093d40ab8ac31db89da4f880f01ba
的一串信息。把它放到beicode.json文件中“git-tree”字段處证舟,并提交新文件:
> git add versions
> git commit --amend --no-edit
我們應(yīng)該完成了!我們必須執(zhí)行這個(gè)稍微復(fù)雜的步驟的原因是硕旗,我們可以準(zhǔn)確地抓取我們想要的版本的文件;其他版本將存在于存儲(chǔ)庫的歷史中,因此總是可以簽出女责。
6. 在C++項(xiàng)目中使用vcpkg registry 中的庫
完成此操作后漆枚,讓我們嘗試在示例代碼庫中使用新registry中的庫。在registry外部創(chuàng)建一個(gè)目錄并切換到該目錄抵知。創(chuàng)建一個(gè)依賴于 beicode 的 vcpkg.json:
{
"name": "test",
"version": "0",
"dependencies": [
"fmt",
"beicode"
]
}
以及將注冊(cè)表設(shè)置為 git registry的 vcpkg-configuration.json:
{
"registries": [
{
"kind": "git",
"repository": "[full path to]/vcpkg-registry",
"packages": [ "beicode", "beison" ]
}
]
}
并嘗試安裝 vcpkg:
> vcpkg install --feature-flags=registries,manifests
如果它有效墙基,那么您已經(jīng)準(zhǔn)備好將注冊(cè)表推向上游!您可以通過將 vcpkg-configuration.json 文件中的“respository”字段替換為實(shí)際的上游存儲(chǔ)庫 URL刷喜,使用實(shí)際的遠(yuǎn)程注冊(cè)表重試残制。
vcpkg如何從registries中獲取庫
您會(huì)注意到beicode和beison取自我們創(chuàng)建的registry;這是因?yàn)槲覀冊(cè)趘cpkg-configuration.json中明確地設(shè)置了它們的來源。因?yàn)槲覀儧]有說fmt應(yīng)該來自哪里掖疮,所以它只是來自默認(rèn)registry初茶,在本例中是vcpkg本身附帶的registry表。registries永遠(yuǎn)不會(huì)傳遞;如果在vcpkg-configuration.json中去掉beicode浊闪,這將無法工作纺蛆,因?yàn)閎eicode不存在在默認(rèn)registry中吐葵。如果希望用自己的副本覆蓋fmt,可以將其添加到registry桥氏,然后將其添加到packages字段。
代碼包beison將會(huì)是一樣的猛铅,只是名字不同而已字支。您可以自己嘗試一下,然后看看您的代碼與上游代碼是否有任何不同奸忽。
本文來自
《Registries: Bring your own libraries to vcpkg - C++ Team Blog (microsoft.com)》