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』はカスタムレイヤーの設計パターンに特化している。

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