非官方
本頁內容
  1. 01建立專案
  2. 02起始配方
  3. 03您程式的原始碼
  4. 04檢查配方
  5. 05建置兩個應用程式
  6. 06打包與安裝
  7. 07第二個配方

您的第一個自訂配方:把配方庫沒有的程式做成 QTS 套件

App Builder 的配方庫能建置一長串程式。若您的程式不在其中,專案可以帶有自己的配方:以配方庫的格式,在專案的 recipes/ 資料夾中放兩個檔案。本指南把 cmatrix 2.0 打包成適用於 x86_64 與 ARM 64 位元 NAS 的 QTS 套件;cmatrix 是一個小型終端機程式,需要配方庫中的 ncurses。

  1. 專案從原始碼建置的套件
  2. 配方recipe.json、build.sh
  3. 檢查編輯器中的 lint
  4. 建置兩個應用程式、兩種處理器
  5. 打包make qpkg

圖片取自 Bucket & Code Server IDE 的面板與編輯器,每個步驟都依本指南的說明完成。資料目錄為 /share/ZFS530_DATA/BucketVS。

01建立專案

在 專案 頁面,新專案 會先詢問範本。選擇 從原始碼建置的套件:這種 QTS 套件裡的程式,是用您自己的配方從原始碼編譯的,適用於 x86_64 與 arm64。

新專案中 QTS 套件的範本:已選擇「從原始碼建置的套件」

將它命名為 cmatrix。專案名稱會成為套件名稱;轉為小寫並去掉配方名稱不能包含的字元後,也會成為起始配方與兩個應用程式的名稱。服務 步驟決定套件執行時做什麼。命令列工具 在步驟開啟時就已選取,它會在套件啟動期間,把套件的 bin/cmatrix 連結到 /usr/bin。完成後,專案資料夾包含:

路徑說明
recipes/<name>/起始配方:recipe.json 與 build.sh
recipes.txt兩個應用程式要建置的配方,每行一個名稱:包括本專案的與配方庫的
Makefilemake 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 說明如何建置。

開啟專案 cmatrix 的編輯器:recipes/cmatrix 下的起始 recipe.json,含佔位位址與全為 0 的 sha256
欄位內容
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 那一行都會出現警告。

問題檢視:bvs recipe lint 警告 recipe.json 第 10 行的 sha256 是範本的佔位值

同樣的檢查也能在終端機與 CI 工作中執行:

make lint                  # bvs recipe lint . (the project folder)
bvs recipe lint --json .   # the findings as JSON, for a CI step

專案檢視的 配方 卡片會依應用程式採用的方式列出專案的配方,每個配方都附上檢查結果與發現。點一下某一列會在編輯器中開啟該配方的資料夾,該列的選單則可複製檢查指令。

專案檢視的「配方」卡片:配方 cmatrix 2.0,無問題

05建置兩個應用程式

專案檢視中的 建置 會執行專案的 Makefile:兩個應用程式不存在時會先建立,再依序逐一建置。在 應用程式 頁面上,每個應用程式的頁面都會註明其配方來自哪個專案,建置日誌則依順序列出每個配方,最先是 ncurses。

已建置的應用程式 cmatrix:名稱下方顯示「來自專案 cmatrix 的配方」;ncurses(cmatrix 需要)與 cmatrix(已選擇)都已通過
  • 建置只在開始時讀取一次專案的配方。之後才儲存的檔案會等到下一次建置。
  • 與配方庫配方同名的專案配方,只會在本專案的應用程式中取代該配方,建置日誌也會註明。
  • 最後一個配方完成後,每個配方的檢查都會在完成的前綴上再執行一次:此配方的檢查是 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,並檢查專案。

Bucket: New recipe 在專案的 recipes 資料夾中詢問新配方的名稱
  • 若要讓之後建立的應用程式使用新配方,請把新名稱加入 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 都會取得的已簽署目錄。