非公式
このページの内容
  1. 01プロジェクトを作る
  2. 02スターターレシピ
  3. 03自分のプログラムのソース
  4. 04検査する
  5. 052 つのアプリをビルドする
  6. 06パッケージにしてインストールする
  7. 072 つ目のレシピ

はじめての自作レシピ: ライブラリにないプログラムを QTS パッケージに

App Builder のレシピライブラリは数多くのプログラムをビルドします。使いたいプログラムがその中にない場合は、プロジェクトに独自のレシピを持たせることができます。ライブラリと同じ形式で、プロジェクトの recipes/ フォルダーに置く 2 つのファイルです。このガイドでは、ライブラリの ncurses を必要とする小さなターミナルプログラム cmatrix 2.0 を、x86_64 と ARM 64 ビットの NAS 向けの QTS パッケージにします。

  1. プロジェクトソースからのパッケージ
  2. レシピrecipe.json、build.sh
  3. 検査エディターでの lint
  4. ビルドアプリ 2 つ、プロセッサー 2 種類
  5. パッケージmake qpkg

画像は Bucket & Code Server IDE のパネルとエディターのもので、各ステップをこのガイドの説明どおりに行っています。データフォルダーは /share/ZFS530_DATA/BucketVS です。

01プロジェクトを作る

プロジェクト ページでは、新しいプロジェクト を押すと、最初にテンプレートを選ぶよう求められます。ソースからのパッケージ を選びます。自作のレシピでソースからコンパイルするプログラムを収めた、x86_64 と arm64 向けの QTS パッケージです。

新しいプロジェクト、QTS パッケージのテンプレート: ソースからのパッケージを選択

名前は cmatrix にします。プロジェクトの名前はパッケージの名前になり、それを小文字にしてレシピ名に使えない文字を除いたものが、スターターレシピと 2 つのアプリの名前になります。サービス のステップでは、パッケージが動作中に何をするかを決めます。ステップを開いたときに選ばれている コマンドラインツール は、パッケージが起動している間、パッケージの bin/cmatrix を /usr/bin にリンクします。作成後、プロジェクトのフォルダーには次のものがあります:

パス内容
recipes/<name>/スターターレシピ: recipe.json と build.sh
recipes.txt2 つのアプリがビルドするレシピ (1 行に 1 つの名前): このプロジェクトのレシピとライブラリのレシピ
Makefilemake app、make build、make lint、make qpkg
licenses.txtパッケージに含まれるライセンス (1 レシピにつき 1 行)
qpkg/パッケージ: qpkg.cfg と、サービス のステップで作られた起動・停止スクリプト

Makefile は 2 つのアプリをビルドします。この NAS のプロセッサー向けの <name> と、ARM 64 ビットの NAS 向けの <name>-arm64 で、後者は x86_64 の NAS ではクロスビルドになります。どちらも Ubuntu 24.04 builder でビルドし、静的にリンクします。その環境がない場合は、ツールチェーンページの この環境を作成 で作成します。このテンプレートでは 作成後すぐにビルド はオフです。スターターレシピは仮のソースを指定していて、その sha256 は 64 個のゼロです。そのため、レシピに自分のプログラムを指定するまで、ビルドは失敗します。

02スターターレシピ

プロジェクトビューの エディターで開く を押すと、プロジェクトのフォルダーがエディターで開きます。recipe.json は何をビルドするかを、build.sh はどうビルドするかを記述します。

プロジェクト cmatrix を開いたエディター: recipes/cmatrix の下のスターター recipe.json。仮のアドレスと、ゼロが並ぶ sha256
フィールド記述する内容
name、versionレシピの名前 (フォルダーの名前) とプログラムのバージョン
summary、category、license、homepageパネルに表示される、そのレシピの情報
sourceソースアーカイブのアドレスとその sha256。一致しないダウンロードは拒否されます
deps先に必要なレシピ。ライブラリのものか、このプロジェクトのもの
env_packagesビルダー環境がこのレシピのためにインストールするビルドツール (ライブラリは含めません)
static、nss静的にリンクするかどうか、ユーザーやホスト名を参照するかどうか
check完成したプレフィックスで実行し、プログラムが動作することを確かめるコマンド

build.sh は 3 つのフェーズを定義し、それぞれ展開したソースの中で実行されます。スターターのフェーズは 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 で描画します。cmatrix の CMake スクリプトは、ncurses をファイル libncurses.a として見つけます。静的なアプリでは、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 が指定できるベンダーファイルだけです。パッチはヒアドキュメントとして build.sh に入れます。
  • recipes.txt にはすでにスターターレシピの名前があります。このレシピが依存するライブラリのレシピは、必要な順序でビルドに加わります。

04検査する

レシピのファイルを保存するたびにプロジェクトのレシピが検査され、検出結果がファイルと行ごとに 問題 ビューに一覧表示されます。検査は recipe.json を読み、build.sh を bash -n で構文解析します。レシピを実行することはありません。スターターの 64 個のゼロもそうした検出結果の 1 つで、本当のチェックサムが入るまで 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、問題なし

052 つのアプリをビルドする

プロジェクトビューの ビルド は、プロジェクトの Makefile を実行します。2 つのアプリがなければ作成し、1 つずつ順にビルドします。アプリ ページにある各アプリのページには、レシピの取得元のプロジェクトが表示され、ビルドのログには、各レシピがビルドの順に ncurses から並びます。

ビルドされたアプリ cmatrix: 名前の下に「プロジェクト cmatrix のレシピ」。cmatrix が必要とする ncurses と、選択した cmatrix が、どちらも合格
  • ビルドはプロジェクトのレシピを開始時に 1 回だけ読みます。その後に保存したファイルは、次のビルドまで反映されません。
  • ライブラリのレシピと同じ名前のプロジェクトのレシピは、このプロジェクトのアプリの中でだけそのレシピを置き換え、ビルドのログにもそのことが出ます。
  • 最後のレシピの後、完成したプレフィックスに対して各レシピのチェックがもう一度実行されます。このレシピでは bin/cmatrix -V です。x86_64 の NAS では ARM のアプリはクロスビルドで、そのチェックは qemu-user が登録されている環境でのみ実行されます。登録されていなければ、ビルドはチェックを未実行として記録します。

06パッケージにしてインストールする

licenses.txt は、パッケージの share/licenses/ に入るものを指定します。パッケージに含まれるレシピごとに 1 行で、そのライセンスと、ソースアーカイブ内のライセンスファイルを書きます。スターターの行には仮の値が入っています。cmatrix には ncurses がリンクされるため、2 行必要です:

cmatrix GPL-3.0-or-later COPYING
ncurses X11 COPYING

エディターのターミナルで make qpkg を実行すると、ツールチェーンページの QDK を使って、各アプリの成功した最新のビルドを、アーキテクチャーごとに 1 つのファイルとしてパッケージにします。成功したビルドがないアプリは含めません。動的にリンクしたアプリは拒否されます。そのプログラムはアプリのプレフィックスでライブラリを探しますが、パッケージはそのプレフィックスを作らないためです。

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 では、5 つのレシピを持つ「ソースからのパッケージ」のプロジェクトを最初から最後までたどります。何も設定していない NAS から始めて、署名済みのパッケージをインストールし、ブラウザーで応答するところまで進めます。

072 つ目のレシピ

Bucket: New recipe は、同じスターターからレシピを追加します。プロジェクトのファイルを開いた状態で コマンド パレット (Ctrl+Shift+P) から実行するか、エクスプローラーで recipes フォルダーまたはレシピのフォルダーを右クリックします。コマンドは名前 (小文字、数字、+ . _ -) を尋ね、recipe.json と build.sh を書き出し、recipe.json を開いて、プロジェクトを検査します。

Bucket: New recipe が、プロジェクトの recipes フォルダーに作る新しいレシピの名前を尋ねる
  • これから作るアプリのために、新しい名前を recipes.txt に書き加えます。以前に作ったアプリは元の一覧のままです。そのアプリのページの 変更 でレシピを追加します。
  • ビルドに npm、Go、Cargo のパッケージが必要なレシピは、それらをベンダーファイルに列挙します。この一覧は /usr/bin/bucketvs/share/bucketvs/tools/ の npm-vendor.py、go-vendor.py、cargo-vendor.py が書き出します。これらにはツールチェーンページの Python ランタイムが必要です。
  • プロジェクトのレシピは、ライブラリのレシピと同じくビルダー環境の中で root として実行され、developer なら誰でも書いてビルドできます。viewer はアプリのビルドログでレシピの名前を見られますが、レシピのファイルは見られません。
  • プロジェクトのレシピはそのプロジェクトの中にとどまります。レシピライブラリと、すべての NAS が受け取る署名付きカタログに入るのは、Bucket & Code Server IDE 自体へのレビュー済みの変更を通した場合だけです。