build2-package 是做什麼的?
解析 ROOT
令 HERE 為包含此 SKILL.md 的目錄(從系統上下文取得的絕對路徑)。
ROOT 是 build2 技能樹。使用第一個存在 guides/packaging-guide-summary.md 的候選目錄:
HERE/../build2(並列佈局:此目錄與build2技能相鄰,包括複製到使用者級技能目錄中的情況)HERE/../..(巢狀佈局:此目錄位於build2技能的skills/子目錄下)
如果兩者都不存在,則停止。
之後所有的 read_file 路徑均為 ${ROOT}/...。
此檔案為操作程序。${ROOT}/guides/ 和 ${ROOT}/HOWTO/ 下的封裝指南是每個步驟如何執行的真理來源。請勿自行發明佈局、bdep new 調用、分支名稱或發佈序列。
外部操作需要明確批准
此技能會建立一個真實、公開可見的套件,並最終發佈它。任何對您本地工作目錄之外可見的操作都不會自動發生。這包括:在 GitHub 上建立儲存庫、任何 git push(分支或標籤)、在 GitHub 上轉移或重新命名儲存庫、開啟或合併拉取請求、執行 bdep ci 以及執行 bdep publish。
執行 /build2-package(或 /build2 package)並不等同於批准上述任何操作,到達操作閘門點也不等同於批准。在本次執行中首次執行上述操作之前,請停止,準確說明即將發生的事情(命令及其對外可見的內容),並等待使用者對該特定操作給出明確同意。對一個此類操作的批准不會延續到後續操作,每次都需要再次詢問。預設假設為:除非使用者明確要求該步驟,否則這些操作都不會發生。
其他所有操作,包括本機提交、建立分支、編輯檔案、本機建置和測試、唯讀的複製或擷取,都可以直接進行,無需詢問。
硬性規則
這些規則不可選擇。違反任何一條都代表執行失敗。
- 永遠不要從頭開始撰寫
buildfile。始終從bdep new開始。此工作流程不使用${ROOT}/scripts/new-package.sh。 - 在首次
bdep new --type empty,third-party提交之後,到發佈時將review快進合併到main之前,永遠不要碰觸main。 - 永遠不要捆綁(vendoring)依賴項。將它們以
depends的形式解除捆綁。 - 永遠不要將主要的
lib{}/exe{}目標放在根目錄的buildfile中。 - 如果上游提供了編譯模式,永遠不要將函式庫設為僅標頭檔(header-only)。
- 永遠不要跳過原始碼分發配方(
b dist,然後在解壓的壓縮檔中執行configure、update、test、clean)。僅通過bdep ci的綠燈是不夠的。 - 永遠不要降低生成的
depends: * build2/depends: * bpkg行。 - 永遠不要猜測上游的標籤、授權條款或公開標頭檔的包含方案。如果樹中或擷取的頁面上沒有這些資訊,請停止並詢問。
- 每個邏輯封裝步驟(或緊密相關的一組操作)對應一個 git 提交。其樹恰好是單個
bdep new調用的提交,使用該命令列作為提交訊息,不加其他內容。為一個上游檔案建立.orig/.patch覆蓋對的提交,使用Patch <filename>: <reason>(對於非平凡的補丁,可選<details>主體)作為其訊息。請參閱 packaging-guide-antipatterns.md。 - 在本地測試、已安裝案例測試、分發測試和 CI 全部通過之前,不要將
review合併到main,不要執行bdep release,也不要執行bdep publish。 - 每個目錄層級的符號連結(不是普通檔案符號連結)都需要在該套件自身的
<pkg>/.gitattributes中有一個對應的symlink=dir條目(這是一個新檔案,bdep new --package不會生成此檔案),並且在添加符號連結的同一提交中添加。使用find <pkg>/ -type l -exec test -d {} \; -print驗證,並與<pkg>/.gitattributes交叉檢查每個命中結果。git不會記錄符號連結類型,並在 checkout 時總是重新建立檔案符號連結,因此跳過此步驟會破壞在 Windows 上 checkout 的套件。 - 永遠不要在註解或 README 中留下記錄封裝過程本身、早期失敗的方法或過程中發生的事故的註釋。註解和 README 只反映最終狀態(請參閱 packaging-guide-antipatterns.md,「不要留下日記風格的註釋或備註」)。
- 未經使用者對該特定操作給出明確的即時同意,永遠不要建立儲存庫、在 GitHub 上推送、轉移或重新命名儲存庫、開啟或合併拉取請求、執行
bdep ci或執行bdep publish(請參閱上面的「外部操作需要明確批准」)。預設是這些操作都不會發生。
強制閱讀(本次執行中,在任何寫入操作之前)
在建立儲存庫、編輯 buildfile 或發佈之前,使用 read_file 完整閱讀以下檔案。不要略讀。
${ROOT}/guides/packaging-guide-summary.md${ROOT}/guides/packaging-guide-testing.md${ROOT}/guides/packaging-guide-antipatterns.md${ROOT}/HOWTO/package-naming.md
然後根據需要從此檔案末尾的對應中按需載入。永遠不要用記憶來取代本文件指定的指南。
在執行過程中根據檢查清單文件重新驗證
一個完整的封裝流程(閘門 A-K,或 new-version / revision 執行)跨越的上下文視窗可能遠多於一個單一對話所能容納的。當你到達後續閘門時,早期的回合,包括上述的強制閱讀,可能已經被摘要取代。在開始時閱讀過一次指南並不意味著其規則仍在上下文中,不要依賴對話記憶來回憶它們。
至少在每個閘門處重新打開並根據這些檢查清單樣式的文件檢查樹的當前狀態一次,並在閘門 K(發佈時)之前再次檢查:
${ROOT}/guides/packaging-guide-antipatterns.md:不應做的事項(手寫 buildfile、在套件中修復上游問題、改變的上游佈局、儘管有編譯模式卻設為僅標頭檔、捆綁的依賴項、根 buildfile 中的主要目標、過於寬泛的修訂、錯誤的標頭檔包含、隨意打補丁、日記風格的註釋或備註)。${ROOT}/guides/packaging-guide-review.md:cppget.org 審查者使用的同一份檢查清單。在發佈前根據它進行自我檢查,而不是在實際審查時才發現問題。${ROOT}/HOWTO/third-party-private-headers.md:私有標頭檔不得進入安裝目錄樹。${ROOT}/HOWTO/buildfile-compile-options.md:哪些編譯/連結選項是本地使用的,哪些是匯出的。${ROOT}/HOWTO/package-naming.md:在閘門 E 做出的命名決定,後期發現需要重新命名的成本很高。${ROOT}/guides/packaging-guide-summary.md步驟 5:每個套件中的每個目錄符號連結在該套件自身的<pkg>/.gitattributes中都有一個symlink=dir條目(硬性規則 11)。
如果目錄樹不再符合這些文件中的任何一個,請在進入下一個閘門之前修復它,而不是將偏差帶到後續步驟。
引數
$ARGUMENTS 是 /build2-package(或 /build2 package)之後的調用文字。按順序解析它。第一個匹配的規則生效。
| 第一個 Token | 模式 |
|---|---|
| 空 / 省略 | 如果 cwd 尚不是一個包裝儲存庫,則為 new,否則為 continue |
new | 初始包裝流程 |
new-version | 首次發佈後的新上游版本 |
revision | 包裝修訂(X.Y.Z+R) |
continue | 在 cwd 中恢復進行中的流程 |
| 其他任何內容 | 如果看起來像 git URL 或 owner/repo,則將其視為帶有該上游的 new。否則詢問。 |
剩餘的 token:可選的 <upstream-url> 和可選的 <tag-or-version>。如果任何一個缺失且模式需要它,則詢問。不要自行編造。
在第一次寫入之前向使用者報告所選模式。
模式:continue
檢查 cwd(及其 git 歷史記錄),並在匹配模式下第一個未完成的閘門處恢復。證據勝過對話摘要。
| 證據 | 恢復位置 |
|---|---|
沒有 .git,或沒有 bdep new --type empty,third-party 的首次提交 | 從頭開始執行 new |
首次提交存在,沒有 review 分支 | 建立 review 並繼續執行 new |
在 review 上,沒有 upstream/ 子模組 | 添加上游 |
upstream/ 存在,沒有套件目錄 / 沒有 bdep new --package | 套件結構 |
| 套件骨架已存在,測試或 CI 未通過 | 測試 |
測試通過,review 未合併到 main | 發佈時合併 |
合併後在 main 上,沒有 vX.Y.Z 標籤 | 釋出然後發佈 |
| 已發佈,使用者要求新的上游 | new-version |
| 已發佈,使用者要求包裝修復 | revision |
如果儲存庫在 main 上,且包含本應在 review 上的包裝提交,則停止。這是一個流程錯誤。不要改寫已發佈的歷史。詢問使用者如何恢復。
模式:new(初始流程)
遵循 ${ROOT}/guides/packaging-guide-summary.md 中的檢查清單以及 ${ROOT}/guides/packaging-guide-testing.md 中的步驟 8-10。下面的編號閘門是不能跳過或重新排序的。
閘門 A:現有工作
按此順序搜索所有四個來源,並報告找到的結果:
https://cppget.org/?advanced-searchhttps://queue.cppget.orghttps://github.com/build2-packaginghttps://github.com/build2-packaging/WISHLIST
如果儲存庫或已發佈的套件已經存在,則停止並詢問是否要加入該工作(continue / new-version / revision),而不是開始一個重複的工作。
閘門 B:空的儲存庫和首次提交
在執行此閘門的外部操作之前停止並獲得明確批准: 建立 GitHub 儲存庫並向其推送初始提交。首先執行本地框架(bdep new、git add、git commit),如果這有助於顯示即將推送的內容,但請不要建立遠端儲存庫或執行 git push,直到使用者表示可以繼續。
在使用者的個人工作空間中建立一個空的公開 git 儲存庫。描述:build2 package for <name>。使用 SSH 複製。沒有 README,沒有授權條款,沒有 GitHub 生成的檔案。
bdep new --type empty,third-party
git add .
git commit -m "bdep new --type empty,third-party"
git push -u origin main
在繼續之前驗證:
git rev-list --max-parents=0 HEAD是此提交。git show --stat --format=%s HEAD的訊息準確地是bdep new --type empty,third-party。- 樹中只包含該命令生成的檔案。
如果該提交中包含任何額外的檔案或手動編輯,請重置並重做。審查流程依賴於此。
閘門 C:review 分支
git checkout -b review
在本次流程中,所有後續提交都保持在 review 上。不要 git checkout main。不要合併。不要釋出。不要發佈。
閘門 D:上游子模組
git submodule add https://github.com/<upstream>/<repo>.git upstream
僅使用 https://。檢出發佈提交(標籤)。提交:Add upstream submodule, <tag>。
閘門 E:名稱和佈局
如有需要,重新閱讀 ${ROOT}/HOWTO/package-naming.md。在生成套件之前做出決定並記錄下來:
- Git 儲存庫名稱:使用上游大小寫,沒有
build2-前置詞,沒有-package後綴。 project:和project =:除非混合大小寫是上游的識別碼(Qt 是記錄在案的例外),否則使用小寫。- 套件
name::對於函式庫,使用lib前置詞,除非 Debian 和上游都使得可執行檔衝突不可能發生。 - 將函式庫和可執行檔拆分為單獨的套件。
- 公開標頭檔包含方案(子目錄前置詞 vs 檔案名前置詞)。
- 合併的 vs 拆分的
include//src/。
盡可能保持與上游佈局接近。
閘門 F:預先建立然後 bdep new --package
建立套件目錄。僅符號連結存在的上游元檔案(README.md、LICENSE / 等價物、NEWS / CHANGES / ChangeLog)。單獨提交該內容。然後:
bdep new --package --lang ... --type lib,...,third-party <name>
通過刪除並重新執行來迭代,而不是手動編輯框架,直到佈局匹配。third-party 子選項是必需的。使用準確的命令列作為訊息提交。
如果變更日誌的基本名稱不是已知的名稱,稍後手動設定 changes-file:。請參閱 ${ROOT}/HOWTO/package-changes-file.md。
閘門 G:版本、清單、依賴項
- 版本保持
X.Y.Z-a.0.z,直到bdep release --no-open。 summary:少於 70 個字元,沒有模糊用語,沒有尾隨句點。- 附帶的
-tests/-examples/-benchmarks:複製主要摘要並附加(tests)(或匹配的類型)。不要改寫它。請參閱${ROOT}/HOWTO/tests-extra-dependencies.md。 license:是 SPDX(或other:)。請參閱${ROOT}/guides/packaging-license.md。- 取消註解
pkg.cppget.org先決條件。使用包含所有依賴項的最不穩定的部分。不要在長壽命的repositories.manifest中留下queue.cppget.org。 - 在
depends編輯後執行bdep sync -a。 - 此函式庫公開標頭檔中的介面標頭檔放在
intf_libs中。其他所有內容放在impl_libs中。
閘門 H:填充原始碼和 buildfile
在觸碰 buildfile 之前填充套件目錄樹與上游原始碼:首先符號連結單個標頭檔/原始碼檔案,並且僅在可以節省大量單個符號連結時才符號連結整個子目錄(需要 buildfile-in-prefix 佈局,請參閱 packaging-guide-antipatterns.md)。遵循 ${ROOT}/guides/packaging-guide-summary.md 步驟 5 中的實際範例。
強制性: 對於剛添加的每個目錄符號連結,在該套件自身的 <pkg>/.gitattributes 中添加一個對應的 symlink=dir 條目(如果檔案不存在則建立)並在同一提交中完成。使用 find <pkg>/ -type l -exec test -d {} \; -print 驗證並與每個命中結果交叉檢查。這是硬性規則 11,跳過它會破壞在 Windows 上 checkout 的套件。在調整 buildfile 之前提交符號連結(和 .gitattributes),以便於回滾。
然後只調整生成的檔案。保留生成的結構和註解。
按需載入:
- 標頭檔 / 私有標頭檔:
${ROOT}/HOWTO/third-party-private-headers.md - SONAME / 輸出名稱:
${ROOT}/HOWTO/target-name-mapping.md - 編譯/連結選項:
${ROOT}/HOWTO/buildfile-compile-options.md - 構建檔案配置變數:
${ROOT}/HOWTO/buildfile-config-variables.md - 導出依賴項:
${ROOT}/HOWTO/export-dependency-mapping.md - 安裝:
${ROOT}/HOWTO/install-third-party-packages.md - 測試:
${ROOT}/guides/packaging-guide-testing.md - 捆綁的測試依賴項:
${ROOT}/HOWTO/tests-extra-dependencies.md - 測試配置:
${ROOT}/HOWTO/tests-config.md - 如果套件是一個用於 C 標頭檔的 library(例如 libcurl 的 C 標頭檔),請參閱
${ROOT}/HOWTO/third-party-c-library.md。
閘門 I:本地測試、安裝測試、分發測試
遵循 ${ROOT}/guides/packaging-guide-testing.md 中的步驟 8-9(bdep ci 除外,它有自己的門)。
- 本地建置和測試(
b/bdep test/bdep test --all)。 - 已安裝案例測試(
bdep install到暫存位置)。 b dist測試(步驟 5 中的範例,以及 packaging-guide-testing.md 中的步驟 8)。
硬性規則 6: b dist,然後 configure、update、test、clean 解壓的壓縮檔。這條路是強制性的;僅通過 bdep ci 是不夠的。
閘門 J:CI
在執行之前,停止並獲得使用者對 bdep ci 的明確批准(批准對 review 分支的推送和 CI 執行,這使得此分支對外可見)。打開 CI 儀表板 URL 並追蹤進度。請求使用者在最終發佈審查(閘門 K)之前完成 CI 結果的審查。
閘門 K:發佈
在執行任何發佈操作之前停止並獲得明確批准。 這包括 git push 到 review(如果尚未推送)、git push 到 main、建立 vX.Y.Z 標籤並推送它、以及 bdep publish。每個操作都需要單獨的批准。