32blogby StudioMitsu
yocto11 min read

Yocto bbappendの書き方と実践パターン5選

Yocto Projectで既存レシピをカスタマイズするbbappendファイルの書き方を、Scarthgap 5.0 LTSベースで基礎から実践パターンまで解説する。

yoctoembedded-linuxbbappendscarthgap
目次

Yoctoで既存のレシピをカスタマイズしたいとき、.bb ファイルを直接編集してはいけない。アップストリームが更新されたら、あなたの変更は消える。

代わりに使うのが .bbappend ファイルだ。元のレシピに「追記」する仕組みで、アップストリームの更新を取り込んでも自分の変更が生き残る。

この記事では、Yocto Scarthgap 5.0 LTS をベースに、bbappendの基礎から実践的なユースケース5つまでを解説する。

bbappendとは何か

.bbappend ファイルは、別のレイヤーにある .bb レシピに対して変数やタスクを追記するためのファイルだ。

仕組みはシンプル。BitBakeがレシピを読み込むとき、対応する .bbappend があれば、レシピの末尾に内容を追記してから処理する。つまり .bbappend に書いた設定は .bb の設定を上書きできる。

meta-poky/recipes-example/someapp/someapp_1.0.bb     ← 元のレシピ
meta-mylayer/recipes-example/someapp/someapp_%.bbappend  ← あなたの追記

この分離が重要な理由は2つある。

  • アップストリームとの共存: meta-pokygit pull で更新しても、あなたのカスタマイズは meta-mylayer に残る
  • 変更の可視性: どのレイヤーが何を変更しているか、bitbake-layers show-appends で一覧できる

レイヤーの作成方法についてはレイヤー作成ガイドを参照。

ファイル名の命名規則

bbappendのファイル名は、対象レシピのファイル名と一致させる必要がある。

バージョン完全一致

someapp_1.0.bbappend  → someapp_1.0.bb にのみ適用
someapp_1.1.bbappend  → someapp_1.1.bb にのみ適用

バージョンが完全に一致しないと適用されない。レシピのバージョンが上がると bbappend が無視される。

ワイルドカード % を使う(推奨)

バージョンアップのたびに bbappend のファイル名を変えるのは面倒だ。% ワイルドカードを使えば、バージョンに関係なく適用できる。

someapp_%.bbappend  → someapp_1.0.bb, someapp_2.3.bb 等すべてに適用

適用確認

bbappendが正しく認識されているか確認するには、以下のコマンドを使う。

bash
# bbappend の一覧と対応レシピを表示
bitbake-layers show-appends

# 特定レシピの全バージョンを確認(バージョン不一致の特定に便利)
bitbake-layers show-recipes someapp

変数の操作方法

bbappendで最も使う操作は、変数への値の追加と上書きだ。

値を追加する(:append)

:append は変数の末尾に値を追加する。先頭にスペースを入れること。 :append はスペースを自動挿入しない。

bash
# 正しい(先頭スペースあり)
SRC_URI:append = " file://my-patch.patch"

# 間違い(スペースなし → 前の値と結合して壊れる)
SRC_URI:append = "file://my-patch.patch"

+= でも追加できるが、:append のほうが「追記である」ことが明示的で好まれる。

bash
# これも動く(+= はスペースを自動挿入する)
SRC_URI += "file://my-patch.patch"

値を削除する(:remove)

bash
DISTRO_FEATURES:remove = "bluetooth wifi"

値を上書きする

bash
# 完全に上書き
SOME_VARIABLE = "new-value"

FILESEXTRAPATHS — 追加ファイルの検索パス

bbappendで独自のファイル(パッチ、設定ファイル等)を追加する場合、そのファイルの置き場所をBitBakeに教える必要がある。

bash
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"

この1行には3つの重要なポイントがある。

  1. :=(即時展開)を使う: ${THISDIR} は「このファイルがあるディレクトリ」を指す変数。遅延展開(=)だと .bb ファイル側のディレクトリに解決されてしまう
  2. 末尾のコロン : は必須: FILESEXTRAPATHS はコロン区切りのリスト。コロンがないと次のパスと結合して壊れる
  3. :prepend を使う: 既存のパスより先に検索させるため

タスクの拡張

bbappendでは、レシピのタスク(do_install, do_configure等)に処理を追加できる。

bash
do_install:append() {
    install -d ${D}${sysconfdir}
    install -m 0644 ${WORKDIR}/myconfig.conf ${D}${sysconfdir}/
}

:append はタスクの末尾に処理を追加する。元のタスクの処理は維持される。

:prepend を使えば先頭に追加することもできる。

bash
do_configure:prepend() {
    # configure の前に実行される処理
    cp ${WORKDIR}/my-makefile ${S}/Makefile
}

実践パターン5選

ここからは実際のユースケースを5つ紹介する。

パターン1: パッチを当てる

最も基本的なユースケース。アップストリームのソースコードにバグ修正や機能追加のパッチを当てる。

ディレクトリ構成:

meta-mylayer/
  recipes-example/
    someapp/
      someapp_%.bbappend
      someapp/
        0001-fix-memory-leak.patch
bash
# someapp_%.bbappend
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
SRC_URI:append = " file://0001-fix-memory-leak.patch"

${PN} はパッケージ名(この場合 someapp)に展開される。${THISDIR}/${PN} でbbappendと同じディレクトリ内の someapp/ サブディレクトリを指す。

パターン2: 設定ファイルを追加する

独自の設定ファイルをターゲットに配置する。

meta-mylayer/
  recipes-core/
    busybox/
      busybox_%.bbappend
      files/
        custom-inittab
bash
# busybox_%.bbappend
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI:append = " file://custom-inittab"

do_install:append() {
    install -m 0644 ${WORKDIR}/custom-inittab ${D}${sysconfdir}/inittab
}

パターン3: systemdサービスを追加する

既存のアプリケーションにsystemdサービスファイルを追加して自動起動させる。systemdレシピの詳しい書き方はsystemd自動起動ガイドを参照。

meta-mylayer/
  recipes-example/
    myapp/
      myapp_%.bbappend
      files/
        myapp.service
bash
# myapp_%.bbappend
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI:append = " file://myapp.service"

SYSTEMD_SERVICE:${PN} = "myapp.service"
SYSTEMD_AUTO_ENABLE:${PN} = "enable"

FILES:${PN} += "${systemd_system_unitdir}/myapp.service"

do_install:append() {
    install -d ${D}${systemd_system_unitdir}
    install -m 0644 ${WORKDIR}/myapp.service ${D}${systemd_system_unitdir}/
}

注意: このパターンは、元の .bb レシピが inherit systemd を含んでいる前提だ。inherit ディレクティブは .bb.bbclass でのみ有効で、.bbappend では公式にサポートされていない。元のレシピがsystemdクラスを継承していない場合は、bbappendではなくレシピ自体の修正が必要になる。

パターン4: コンパイルオプションを変更する

PACKAGECONFIG を使って、レシピのビルドオプションを変更する。

bash
# curl_%.bbappend
# OpenSSLサポートを有効化
PACKAGECONFIG:append = " openssl"

# GnuTLSサポートを無効化
PACKAGECONFIG:remove = "gnutls"

PACKAGECONFIG は多くのレシピで対応しているオプション管理の仕組みだ。対応オプションはレシピの .bb ファイル内の PACKAGECONFIG[xxx] で定義されている。

autotools系のレシピでは、configure オプションを直接追加することもできる。

bash
EXTRA_OECONF:append = " --enable-my-feature"

パターン5: 依存関係を追加する

ビルド時やランタイムの依存関係を追加する。

bash
# mypackage_%.bbappend

# ビルド時依存
DEPENDS:append = " libssl"

# ランタイム依存(${PN} でパッケージを明示する)
RDEPENDS:${PN}:append = " python3"

RDEPENDS には ${PN} が必要だ。RDEPENDS はパッケージごとに設定する変数で、${PN} を省略するとどのパッケージの依存関係かが不明になる。

よくあるトラブルと対処法

bbappendが適用されない

bash
# まず bbappend が認識されているか確認
bitbake-layers show-appends | grep someapp

# レイヤーが bblayers.conf に登録されているか確認
bitbake-layers show-layers

原因として多いのは、バージョン番号の不一致(% を使っていない)とレイヤーの未登録だ。

変数の値がおかしい

bash
# Scarthgap 推奨のデバッグコマンド
bitbake-getvar -r someapp SRC_URI
bitbake-getvar -r someapp FILESEXTRAPATHS

bitbake-getvar は変数の最終的な値と、どのファイルで設定されたかを表示してくれる。

ファイルが見つからない(do_fetch エラー)

FILESEXTRAPATHS の設定ミスが原因であることが多い。

  • :== にしていないか
  • 末尾のコロン : を忘れていないか
  • files/ ディレクトリの位置がFILESEXTRAPATHSのパスと一致しているか

まとめ

bbappendは、Yoctoで既存レシピをカスタマイズする唯一の正しい方法だ。覚えるポイントは少ない。

  • ファイル名は レシピ名_%.bbappend% ワイルドカード推奨)
  • ファイルを追加するときは FILESEXTRAPATHS:prepend := "${THISDIR}/files:":= と末尾コロン必須)
  • 値の追加は :append(先頭スペース忘れずに)
  • タスクの拡張は do_install:append() { ... }
  • 困ったら bitbake-layers show-appendsbitbake-getvar で確認

基礎を押さえたら、次はビルド環境の最適化にも取り組もう。

bbappendやレシピのカスタマイズをもっと深く学びたい人には、以下の書籍がおすすめだ。特に『Yocto Project Customization』はカスタムレイヤーの設計パターンに特化している。

PR
Yocto Project Customization for Linux (Apress, 2025)
Amazonで見る
PR
Mastering Embedded Linux Development 4th Ed (2024)
Amazonで見る
PR
Embedded Linux Development Using Yocto Project 3rd Ed (2023)
Amazonで見る