您的第一個自訂配方:把配方庫沒有的程式做成 QTS 套件
App Builder 的配方庫能建置一長串程式。若您的程式不在其中,專案可以帶有自己的配方:以配方庫的格式,在專案的 recipes/ 資料夾中放兩個檔案。本指南把 cmatrix 2.0 打包成適用於 x86_64 與 ARM 64 位元 NAS 的 QTS 套件;cmatrix 是一個小型終端機程式,需要配方庫中的 ncurses。
- 專案從原始碼建置的套件
- 配方recipe.json、build.sh
- 檢查編輯器中的 lint
- 建置兩個應用程式、兩種處理器
- 打包make qpkg
圖片取自 Bucket & Code Server IDE 的面板與編輯器,每個步驟都依本指南的說明完成。資料目錄為 /share/ZFS530_DATA/BucketVS。
01建立專案
在 專案 頁面,新專案 會先詢問範本。選擇 從原始碼建置的套件:這種 QTS 套件裡的程式,是用您自己的配方從原始碼編譯的,適用於 x86_64 與 arm64。
將它命名為 cmatrix。專案名稱會成為套件名稱;轉為小寫並去掉配方名稱不能包含的字元後,也會成為起始配方與兩個應用程式的名稱。服務 步驟決定套件執行時做什麼。命令列工具 在步驟開啟時就已選取,它會在套件啟動期間,把套件的 bin/cmatrix 連結到 /usr/bin。完成後,專案資料夾包含:
| 路徑 | 說明 |
|---|---|
recipes/<name>/ | 起始配方:recipe.json 與 build.sh |
recipes.txt | 兩個應用程式要建置的配方,每行一個名稱:包括本專案的與配方庫的 |
Makefile | make app、make build、make lint、make qpkg |
licenses.txt | 套件所附的授權,每個配方一行 |
qpkg/ | 套件本身:qpkg.cfg,以及由 服務 步驟產生的啟動與停止指令碼 |
Makefile 會建置兩個應用程式:為這台 NAS 的處理器建置 <name>,為 ARM 64 位元 NAS 建置 <name>-arm64,後者在 x86_64 NAS 上是交叉建置。兩者都在 Ubuntu 24.04 builder 中建置並靜態連結;如果還沒有這個環境,可以在工具鏈頁面按 建立此環境 建立。對這個範本,建立後立即建置 是關閉的:起始配方指向一個佔位來源,其 sha256 是 64 個 0,因此在配方指定您的程式之前,建置都會失敗。
02起始配方
專案檢視中的 在編輯器中開啟 會在編輯器中開啟專案資料夾。recipe.json 說明要建置什麼;build.sh 說明如何建置。
| 欄位 | 內容 |
|---|---|
name、version | 配方名稱(即其資料夾名稱)與程式的版本 |
summary、category、license、homepage | 面板顯示的相關資訊 |
source | 原始碼封存檔的位址及其 sha256;不相符的下載會被拒絕 |
deps | 它需要先有的配方,來自配方庫或本專案 |
env_packages | 建置環境為它安裝的建置工具(絕不包括函式庫) |
static、nss | 是否靜態連結,以及是否查詢使用者或主機名稱 |
check | 在完成的前綴中執行、用來證明程式可運作的指令 |
build.sh 定義三個階段,各在解開的原始碼中執行。起始配方使用 CMake 的寫法,其註解列出每個階段在 autoconf 與 Meson 的寫法:
do_configure() {
# an autoconf source: configure_std; meson: meson_std. In a static app CMake ends the link line with -Wl,-Bdynamic
# after a library it found as a file (lib<name>.a), and the link then asks for a shared libc;
# CMAKE_LINK_SEARCH_END_STATIC keeps the line static to its end (D312)
if [ "$STATIC" = 1 ]; then cmake_std -DCMAKE_LINK_SEARCH_END_STATIC=ON; else cmake_std; fi
}
do_build() {
cmake --build _build -j"$JOBS" # autoconf: make_j; meson: meson compile -C _build
}
do_install() {
cmake --install _build # autoconf: make install; meson: meson install -C _build
}
cmake_std、configure_std 與 meson_std 會傳入應用程式的前綴、連結方式,以及 ARM 應用程式的交叉目標,因此同一個檔案可用於兩個應用程式。
03您程式的原始碼
取得發行封存檔的位址,讓編輯器的終端機計算它的 sha256:
curl -fsSL https://github.com/abishekvashok/cmatrix/archive/refs/tags/v2.0.tar.gz | sha256sum
ad93ba39acd383696ab6a9ebbed1259ecf2d3cf9f49d6b97038c66f80749e99a -
cmatrix 以 CMake 建置,並以 ncurses 繪製畫面,配方庫中有 ncurses。它的 CMake 指令碼以檔案 libncurses.a 的形式找到 ncurses,而在靜態應用程式中,CMake 會在它之後以 -Wl,-Bdynamic 結束連結指令列,於是連結會要求共用的 libc 並就此停止。起始配方的 do_configure 讓整行直到結尾都保持靜態,因此 build.sh 維持原樣即可:
do_configure() {
if [ "$STATIC" = 1 ]; then cmake_std -DCMAKE_LINK_SEARCH_END_STATIC=ON; else cmake_std; fi
}
在 recipe.json 中,檢查改為 bin/cmatrix -V,這個選項會印出 cmatrix 2.0 的版本(對 --version,它回應的是說明文字):
{
"name": "cmatrix",
"version": "2.0",
"summary": "cmatrix: the falling characters of The Matrix in a terminal",
"category": "tool",
"license": "GPL-3.0-or-later",
"homepage": "https://github.com/abishekvashok/cmatrix",
"source": {
"url": "https://github.com/abishekvashok/cmatrix/archive/refs/tags/v2.0.tar.gz",
"sha256": "ad93ba39acd383696ab6a9ebbed1259ecf2d3cf9f49d6b97038c66f80749e99a"
},
"deps": ["ncurses"],
"env_packages": [],
"static": true,
"nss": false,
"check": "bin/cmatrix -V"
}
- 配方資料夾只包含
recipe.json、build.sh,以及recipe.json可能指定的 vendor 檔案,沒有其他檔案。修補程式以 here-document 的形式放進build.sh。 recipes.txt已列出起始配方;它所依賴的配方庫配方會依其順序加入建置。
04檢查配方
每次儲存配方的檔案,都會檢查專案的配方,並在 問題 檢視中列出發現,每一項都標示所在的檔案與行。檢查會讀取 recipe.json,並以 bash -n 剖析 build.sh;它從不執行配方。起始配方的 64 個 0 就是這樣的發現:在填入真正的校驗和之前,sha256 那一行都會出現警告。
同樣的檢查也能在終端機與 CI 工作中執行:
make lint # bvs recipe lint . (the project folder) bvs recipe lint --json . # the findings as JSON, for a CI step
專案檢視的 配方 卡片會依應用程式採用的方式列出專案的配方,每個配方都附上檢查結果與發現。點一下某一列會在編輯器中開啟該配方的資料夾,該列的選單則可複製檢查指令。
05建置兩個應用程式
專案檢視中的 建置 會執行專案的 Makefile:兩個應用程式不存在時會先建立,再依序逐一建置。在 應用程式 頁面上,每個應用程式的頁面都會註明其配方來自哪個專案,建置日誌則依順序列出每個配方,最先是 ncurses。
- 建置只在開始時讀取一次專案的配方。之後才儲存的檔案會等到下一次建置。
- 與配方庫配方同名的專案配方,只會在本專案的應用程式中取代該配方,建置日誌也會註明。
- 最後一個配方完成後,每個配方的檢查都會在完成的前綴上再執行一次:此配方的檢查是
bin/cmatrix -V。在 x86_64 NAS 上,ARM 應用程式是交叉建置,其檢查只在已登錄 qemu-user 的地方執行;沒有 qemu-user 時,建置會把它們記為未執行。
06打包與安裝
licenses.txt 決定套件的 share/licenses/ 包含什麼:套件所含的每個配方一行,寫出其授權,以及其原始碼封存檔中的授權檔案。起始配方的那一行指向佔位項目。cmatrix 需要兩行,因為 ncurses 連結在它裡面:
cmatrix GPL-3.0-or-later COPYING ncurses X11 COPYING
在編輯器的終端機中執行 make qpkg,會用工具鏈頁面上的 QDK,把每個應用程式最新的成功建置打包進套件,每種架構一個檔案;沒有成功建置的應用程式會略過。這個指令會拒絕動態連結的應用程式:這種程式會到應用程式的前綴尋找函式庫,而套件並不會建立這個前綴。
make qpkg
套件會放在 build/qpkg/build/,依 qpkg.cfg 的 QPKG_NAME 與 QPKG_VER 命名:cmatrix_0.1.0_x86_64.qpkg 與 cmatrix_0.1.0_arm_64.qpkg。每個套件都包含應用程式的 bin/、sbin/、share/(不含 man、doc 與 info)與 etc/:在此是 cmatrix,以及 ncurses 安裝在那裡的內容,也就是它的工具與終端機資料庫。scripts/make-qpkg.sh 開頭的 KEEP 可改為指定套件要包含的路徑,例如 bin/cmatrix share/terminfo。
把程式碼簽署檔案放在 qpkg/ 中 qpkg.cfg 的旁邊,或放在 QPKG_CERT_DIR 指定的資料夾,套件就會簽章,而專案檢視中的 測試部署(僅限管理員)會把它安裝到這台 NAS。您自己的 App Center 更詳細地說明簽署與發佈。從零開始打造 Transmission 帶著一個含五個配方的「從原始碼建置的套件」專案走完全程,從一台尚未設定任何東西的 NAS,到已簽署的套件安裝完成並在瀏覽器中回應。
07第二個配方
Bucket: New recipe 會以同一個起始配方新增一個配方。在專案的檔案開啟時,從命令選擇區(Ctrl+Shift+P)執行它,或在檔案總管中對 recipes 資料夾或某個配方的資料夾按右鍵。它會詢問名稱(小寫字母、數字與 + . _ -),寫出 recipe.json 與 build.sh,開啟 recipe.json,並檢查專案。
- 若要讓之後建立的應用程式使用新配方,請把新名稱加入
recipes.txt。先前建立的應用程式會保留原本的清單:在其頁面按 變更 即可加入該配方。 - 建置時需要 npm、Go 或 Cargo 套件的配方,會在 vendor 檔案中列出這些套件。
/usr/bin/bucketvs/share/bucketvs/tools/中的npm-vendor.py、go-vendor.py與cargo-vendor.py會寫出這份清單;它們需要工具鏈頁面上的 Python 執行環境。 - 專案配方與配方庫的配方一樣,在建置環境中以 root 身分執行,任何開發者都能撰寫並建置它們。檢視者可在應用程式的建置日誌中看到其配方名稱,但絕不會看到配方檔案。
- 專案配方只會留在它的專案中。只有透過一項經過審查、針對 Bucket & Code Server IDE 本身的變更,它才會加入配方庫,以及每台 NAS 都會取得的已簽署目錄。