Yoctoのビルドが失敗したとき、大量のログに埋もれて原因がわからない。エラーメッセージを検索しても、古いバージョンの情報ばかりで解決しない。
この記事では、Yocto Scarthgap 5.0 LTS(BitBake 2.8)をベースに、ビルドエラーをタスク別に分類して原因と対処法を解説する。まずデバッグツールの使い方を押さえ、そこから各タスクのエラーパターンを見ていく。
Yoctoが初めての方は入門ガイドから始めることをおすすめする。
ログファイルとデバッグツール
エラーを解決するには、まず正しい場所を見る必要がある。
ログファイルの場所
BitBakeはタスクごとにログファイルを生成する。
tmp/work/<ARCH>/<RECIPE>/<VERSION>/temp/
├── log.do_fetch ← do_fetchの実行ログ
├── log.do_compile ← do_compileの実行ログ
├── run.do_compile ← 実際に実行されたスクリプト
└── ...
log.do_* はシンボリックリンクで、最新の実行結果を指している。ビルドが失敗したら、まずこのログを確認する。
# 例: curlのdo_compileログを確認
cat tmp/work/core2-64-poky-linux/curl/8.7.1/temp/log.do_compile
bitbake-getvar(変数の確認)
変数の最終的な値と、どのファイルで設定されたかを表示する。
# レシピ固有の変数を確認
bitbake-getvar -r curl SRC_URI
# グローバル変数を確認
bitbake-getvar DISTRO_FEATURES
:append や :prepend が適用された後の最終値が表示されるので、変数が意図通りに設定されているかの確認に使う。
devshell(開発シェル)
ビルド環境と同じ環境変数でインタラクティブシェルを起動する。コンパイルエラーの再現と修正に不可欠だ。
bitbake curl -c devshell
devshell内では、BitBakeが設定する CC、CFLAGS、LDFLAGS 等の環境変数がそのまま使える。make clean && make で問題を再現し、修正を試せる。
bitbake -e(全環境の表示)
bitbake-getvar では確認できないPython関数や、変数の展開過程全体を見たいときに使う。
bitbake -e curl | grep ^SRC_URI=
do_fetchエラー
ソースコードのダウンロードに失敗するエラー。ネットワーク関連が主な原因だ。
URLが変更・削除された
ERROR: curl-8.7.1-r0 do_fetch: Fetcher failure for URL: 'https://example.com/old-url/curl-8.7.1.tar.gz'
アップストリームがURLを変更すると発生する。対処法はレシピの SRC_URI を修正するか、ミラーを設定する。
# conf/local.conf — ソースミラーの設定
SOURCE_MIRROR_URL = "http://mirror.example.com/sources/"
INHERIT += "own-mirrors"
git://プロトコルの廃止
GitHubは2021年に git:// プロトコルを廃止した。古いレシピではまだ git://github.com/... が残っていることがある。
ERROR: curl-8.7.1-r0 do_fetch: Fetcher failure: fetch command failed with exit code 128
bbappendで SRC_URI を https:// に書き換えるか、PROTOCOL パラメータを追加する。
# bbappendでプロトコルを修正
SRC_URI:remove = "git://github.com/example/repo.git;branch=main"
SRC_URI:append = " git://github.com/example/repo.git;protocol=https;branch=main"
ネットワーク接続の問題
プロキシ環境やファイアウォール内でビルドしている場合。
# conf/local.conf — プロキシ設定
HTTP_PROXY = "http://proxy.example.com:8080"
HTTPS_PROXY = "http://proxy.example.com:8080"
一時的なネットワーク障害の場合は、そのままビルドを再実行すれば、失敗したタスクからリトライされる。
チェックサムの不一致
ERROR: curl-8.7.1-r0 do_fetch: Checksum mismatch!
アップストリームがファイルを差し替えた場合に発生する。エラーメッセージに正しいチェックサムが表示されるので、レシピの SRC_URI[sha256sum] を更新する。ただし、意図しない変更でないか確認すること。
do_patchエラー
パッチの適用に失敗するエラー。レシピのバージョンアップ時に最も多い。
パッチが適用できない
ERROR: curl-8.7.1-r0 do_patch: Command Error: 'quilt push' failed
Hunk #1 FAILED at 42.
アップストリームのコードが変わり、パッチのコンテキストが一致しなくなった。
対処法:
- devshellで問題を確認する
bitbake curl -c devshell
# devshell内で
quilt push # どのパッチが失敗するか確認
quilt push -f # 強制適用してrejectファイルを確認
*.rejファイルを確認し、パッチを手動で修正する- 修正したパッチをレシピのファイルディレクトリに配置する
パッチの順序問題
SRC_URI に複数のパッチを列挙している場合、適用順序は列挙順だ。パッチ間に依存関係がある場合は順序に注意する。
SRC_URI = "... \
file://0001-first-fix.patch \
file://0002-depends-on-first.patch"
do_compileエラー
コンパイルに失敗するエラー。原因は多岐にわたる。
並列ビルドレース
間歇的に発生するコンパイルエラーは、並列ビルドのレースコンディションを疑う。
fatal error: some_header.h: No such file or directory
ヘッダーファイルの生成が完了する前に、それを使うソースのコンパイルが始まると発生する。
# 診断: PARALLEL_MAKEを1にして再ビルド
PARALLEL_MAKE:pn-problematic-recipe = "-j1"
-j1 で成功するなら並列レースが原因だ。根本的な修正はレシピの Makefile に依存関係を追加すること。
OOM(メモリ不足)
error: internal compiler error: Killed (program cc1plus)
Killed はOOM Killerがプロセスを強制終了したサイン。dmesg で確認できる。
dmesg | grep -i "oom\|killed"
対処法は並列度を下げること。詳しくはビルド高速化ガイドのBB_NUMBER_THREADSチューニングを参照。
# conf/local.conf — 並列度を下げる
BB_NUMBER_THREADS = "4"
PARALLEL_MAKE = "-j4"
ホスト環境のヘッダー競合
/usr/local/include/iconv.h:... error: ...
ホストマシンの /usr/local/include/ にあるヘッダーがクロスコンパイルに干渉する。Yocto公式FAQでも報告されている問題だ。
対処法は /usr/local/include/ の競合ヘッダーをリネームするか、ビルド専用のクリーンな環境を使う。
do_package_qaエラー
パッケージングのQA(品質保証)チェックで検出されるエラー。ビルド自体は成功しているが、パッケージの整合性に問題がある。
installed-vs-shipped
ERROR: QA Issue: <package>: Files/directories were installed but not shipped in any package
do_install でファイルをインストールしたが、どの FILES:${PN} にも含まれていない。
# 対処: FILES変数にパスを追加
FILES:${PN} += "${datadir}/myapp"
already-stripped
WARNING: QA Issue: File '/usr/bin/myapp' from myapp was already stripped
バイナリがビルド中にすでにstripされている。Yoctoは自動でstripするので、レシピ側でのstripは不要だ。
# 対処: レシピ側のstripを無効化
INHIBIT_PACKAGE_STRIP = "1"
ldflags
ERROR: QA Issue: No GNU_HASH in the ELF binary
リンク時に正しい LDFLAGS が使われていない。ビルドシステムが ${LDFLAGS} を無視している場合に発生する。
# 対処: Makefileに LDFLAGS を渡す
EXTRA_OEMAKE += "LDFLAGS='${LDFLAGS}'"
QAチェックの一時的な無効化
問題の根本原因を特定するまで、特定のQAチェックを一時的に無効化できる。
# 特定レシピでQA警告を抑制(根本修正までの一時措置)
INSANE_SKIP:${PN} += "already-stripped ldflags"
その他のよくあるエラー
タスク以外で発生する、環境やレイヤー設定のエラー。
BitBakeサーバーに接続できない
ERROR: Unable to connect to bitbake server, or start one
前回のBitBakeプロセスが異常終了し、ロックファイルが残っている。
# ロックファイルを削除
rm -f build/bitbake.lock
それでも解決しない場合は、別のBitBakeプロセスが動いていないか確認する。
ps aux | grep bitbake
LAYERSERIES_COMPATの不一致
ERROR: Layer 'meta-custom' is not compatible with the current set of layers
レイヤーの conf/layer.conf に LAYERSERIES_COMPAT が設定されていないか、scarthgap が含まれていない。
# meta-custom/conf/layer.conf
LAYERSERIES_COMPAT_meta-custom = "scarthgap"
自分のレイヤーなら上記を追加する。サードパーティレイヤーの場合は、Scarthgap対応版を探すか、フォークして修正する。Kirkstoneからの移行中にこのエラーが出た場合は移行チェックリストも参考になる。
Nothing RPROVIDES
ERROR: Nothing RPROVIDES 'python3-requests'
必要なパッケージを提供するレシピが見つからない。原因は大きく2つ。
- レイヤーが
bblayers.confに登録されていない
# 確認
bitbake-layers show-layers
# レイヤーを追加
bitbake-layers add-layer ../meta-python
- パッケージ名が違う
Yoctoのパッケージ名はディストリビューションと異なる場合がある。
# パッケージを検索
oe-pkgdata-util find-path /usr/bin/python3
ディスク容量不足
No space left on device
core-image-sato のフルビルドには約90GBが必要。rm_work を有効にすると約22GBに抑えられる。詳しくはビルド高速化ガイドを参照。
# conf/local.conf
INHERIT += "rm_work"
RM_WORK_EXCLUDE += "my-custom-recipe"
まとめ
Yoctoのビルドエラーは、タスクの種類で原因を絞り込める。
| タスク | よくある原因 | まず確認すること |
|---|---|---|
| do_fetch | URL変更、ネットワーク、チェックサム | エラーメッセージのURL、ミラー設定 |
| do_patch | コンテキスト不一致 | devshellで quilt push |
| do_compile | 並列レース、OOM | -j1 で再試行、dmesg でOOM確認 |
| do_package_qa | FILES未設定、LDFLAGS | QAエラーメッセージのチェック名 |
デバッグの基本は3ステップだ。
- ログを読む:
tmp/work/<ARCH>/<RECIPE>/<VERSION>/temp/log.do_* - 変数を確認する:
bitbake-getvar -r <recipe> <variable> - 環境を再現する:
bitbake <recipe> -c devshell
この3つを使いこなせば、大半のビルドエラーは自力で解決できる。
Yoctoのビルドシステムをより深く理解したい人には、以下の書籍が役立つ。ビルドの仕組みがわかれば、エラーの原因特定も格段に速くなる。