ククログ

株式会社クリアコード > ククログ > YoctoレシピをISAR向けに移植するときにはまらないためのヒント

YoctoレシピをISAR向けに移植するときにはまらないためのヒント

組み込みLinuxでは、ターゲットとなるOSをビルドするためのYoctoレシピが提供されていることがあります。 そのような事例では、広く公開されているレシピをベースに、企業が独自に追加の修正を施したレシピを適用する ということが行われたりします。

今回は、そのようなYoctoのレシピをISAR向けに移植することになったときにはまらないためのヒントをいくつか紹介します。 (Yoctoレシピにはある程度慣れているが、Debianパッケージにはあまり慣れていない人が対象です。)

ISARとは

Yoctoのレシピは(提供元が異なっていても)ソースコードにパッチを積み重ねてビルドすることができたりするので、カスタマイズ性が高いという特長があります。 その一方で、発覚した脆弱性にタイムリーに追従していきたい場合など、利用者自身によるメンテナンスコストが高くならざるを得ないという一面もあります。

上記のような問題を解決する方法のひとつに、Debianのようなバイナリパッケージを配布しているディストリビューションの成果物と、Yoctoのレシピをカスタマイズして ビルドした成果物を組み合わせるというやりかたがあります。 ISARは、そのようなやりかたを実現することのできるソフトウェアの1つです。

ISARを利用すると、大部分のソフトウェアはDebianが提供するものを利用し、DebianになかったりするものだけYoctoのレシピを移植して使うということができます。 Debianの成果物と組み合わせる場合には、長期サポート(LTS)で5年、さらにELTSを利用すると10年のサポートが得られるので、 (組み込み製品にとって)Debian由来のものはそちらのアップデートを利用しつつ、独自にカスタマイズした部分のメンテナンスに注力できるというメリットがあります。 また、Debianのパッケージを一部カスタマイズして採用するということもできます。

ISARの利用者は、使い慣れたbitbakeコマンドを使って、パッケージをビルドしたり、OSのイメージを作成したりできます。

実際にISARを採用している事例としては、EMLinuxがあります。1

ISAR向け移植時のヒント

ISARはYoctoのレシピをベースに動作しますが、いわゆるソースディストリビューションとバイナリディストリビューションという 異なるエコシステムをつなぎあわせて動作します。 Debianのパッケージングポリシーに完全に準拠していなくても、debパッケージが作れるようになっているのは、 Debianパッケージに不慣れなユーザーにとってはとっつきやすいポイントかもしれません。

ただ、そのせいで、期待通りに動作しないときにどうすべきかというのがややわかりにくく感じられるかもしれません。 そのようなハマりどころがあるので、いくつか紹介します。

  • Yoctoレシピではサブディレクトリを指定する
  • debianディレクトリを配置する
  • inherit dpkg-rawをいつ使うべきか
  • Yoctoのdo_patchとDebianパッケージのどちらでパッチを適用すべきか
  • Debianのchangelogを作成するにはどうするのがよいか
  • ソースパッケージの詳細説明をどこに残しておくべきか
  • 複数のバイナリパッケージを生成するときにどうするか
  • Debianとなじまないバージョンが付与されていたとき
  • Yoctoの依存とDebianパッケージの依存を区別する

Yoctoレシピではサブディレクトリを指定する

Yoctoのレシピでソースディレクトリを暗黙的に指定しますが、ISAR向けではサブディレクトリを明示する必要があります。

S = "${WORKDIR}"

上記を記載したレシピでは、次のように警告されます。

S is not a subdir of WORKDIR debian package operations will not work for this recipe.

WORKDIRを直接ソースディレクトリに指定できないので、ソースコードがgit管理されているなら、例えばS = "${WORKDIR}/git"とするなどの対処が必要です。

debianディレクトリを配置する

ISARでdebパッケージをビルドするためには、ソースディレクトリにdebianディレクトリをあらかじめ 配置する必要があります。

Yoctoのレシピとしてdebian/ディレクトリを認識させ、なおかつビルド前に準備を完了させるには 次のようにします。

inherit dpkg

SRC_URI += "file://debian/"

...(途中省略)

do_prepare_build() {
    mkdir -p ${S}
    cp -r ${WORKDIR}/debian ${S}/
}

ビルド開始前にコピーが完了している必要があるので、do_prepare_buildであらかじめ${S}配下にdebianディレクトリを配置するのが定石です。

inherit dpkg-rawをいつ使うべきか

ISARで利用できるクラスにdpkg-rawがあります。 inherit dpkg-rawを利用したレシピでは、do_install等で${D}配下へと配置したファイルがあれば、 自動的にかき集めてdebパッケージを作成してくれます。

そのため、ソースコードをビルドしたりする必要がなく、何らかの設定ファイル等のみを配置できればよいような場合には有用です。

Yoctoのdo_patchとDebianパッケージのどちらでパッチを適用すべきか

ISARではYoctoのレシピをベースに、Debian向けのソースパッケージを作成し、Debianパッケージをビルドするという流れを踏みます。 Yoctoのdo_patchでパッチを適用することもできますし、Debianパッケージをビルドするときにパッチを適用することもできます。 どのように使い分けるとよいのでしょうか。

対象となるパッケージが、git管理されているDebianパッケージであれば、Debianパッケージ側で パッチを適用するのがよいでしょう。

たいていは、git buildpackageをDebianパッケージのメンテナンスに採用しているでしょうから、Yoctoのレシピではinherit dpkg-gbpを採用し、 追加のパッチをあてるのが、パッチ管理の煩雑さの観点からも望ましいです。 (ベースとしているDebianパッケージが更新されたときも追従しやすいからです。)

Debianパッケージのソースコードがgit管理されているが、git buildpackageのワークフローに沿っていない場合は、 pristine-tarブランチ等もないので、inherit dpkg-gbpは使えません。 その場合、既定でnativeパッケージ扱いになるので、debian/patches配下のパッチが適用されません。 そのような場合には、do_patchで適用するほうが管理が楽になるでしょう。

Debianのchangelogを作成するにはどうするのがよいか

ISARではdebian/changelogを用意していなくても、changelogを自動生成してくれるしくみがあります。 それがdeb_add_changelogです。 do_prepare_build()などで呼び出しておけば、適切なchangelogエントリを作成してくれます。

do_prepare_build() {
    mkdir -p ${S}/
    cp -r ${WORKDIR}/debian ${S}/
    deb_add_changelog
}

ただし、生成されるchangelogはかなりシンプルで、* generated by Isar程度のエントリしか追記してくれません。 細かく変更点を履歴として維持したい場合にはdeb_add_changelogによる自動生成はおすすめできません。 別途、README.Debian等を活用したほうがよいでしょう。

ソースパッケージの詳細説明をどこに残しておくべきか

通常Debianパッケージでソースパッケージのパッケージング特有の説明を残しておきたい場合、 debian/README.sourceにその詳細を記載します。

しかし、ISARではREADME.sourceを用意しても自動的にはパッケージには含まれません。 そのため、お手軽な代替案としてはREADME.Debianに残しておくという案があります。

パッケージの利用者向けという趣旨のREADME.Debianに記載するのがなじまない場合には、自前でパッケージに含めるなどの対処が必要です。

複数のバイナリパッケージを生成するときにどうするか

Debianパッケージでひとつのソースコードから複数のバイナリパッケージを生成するということはよくあります。

debian/controlでサブパッケージを明記するのがよくあるやりかたですが、 ISARを利用してパッケージを生成する場合には、注意すべき点があります。

たとえば、コマンドを含むfooとライブラリーを提供するlibfoo1と開発用のヘッダファイル等を含むlibfoo-devを生成する場合、 レシピにはPROVIDESを書いて、どのようなパッケージをレシピが提供するかを明示しないといけません。

PROVIDES += "foo libfoo1 libfoo-dev"

このように生成されたパッケージを明記しないと、conf/local.confにIMAGE_INSTALL:appendを追記してイメージを生成する際、bitbakeがパッケージをうまく認識できないことがあります。

Debianとなじまないバージョンが付与されていたとき

Yoctoのレシピとしては問題なくても、Debianパッケージのバージョンとしては不適切という場合があります。

たとえば、gitのコミットハッシュであったり、デバイスID等に由来する文字列では、数値からはじまらないというのがありえます。 そのためそのような文字列を含む場合、パッケージとしては不正なバージョンとなってしまうことがあります。

そのような場合には、次のようにCHANGELOG_Vで数値から始まるようなバージョンを明示することで、Debianパッケージとして適切なバージョンを付与できます。

CHANGELOG_V = "2025.04.18+r51p0.00eac0"

Yoctoの依存とDebianパッケージの依存を区別する

Yoctoのレシピでは、DEPENDSやRDEPENDSなど、レシピの依存関係を明示する書き方がいくつかあります。 ただ、ISARを利用してパッケージを生成する際に自前でdebian/controlを用意していた場合、 そのままだと自前で用意していたdebian/controlが優先されるため、RDEPENDS等はdebパッケージに自動的に反映されません。

これは、よりDebianらしいパッケージにしようとして、パッケージを細かく分割するべく自前でdebian/controlを用意していたような場合にはまりがちです。 記述によっては、Yoctoレシピとしての依存関係と、debパッケージに含まれる依存関係とで不整合が発生してしまうということがありえます。

そのため、次のようにdebian/controlをあらかじめ用意したテンプレート(debian/control.tmpl等)を利用してISARが生成するようにし、 依存関係を変数経由で埋め込むように記述すると、レシピ全体の依存関係の見通しがよくなります。

DEBIAN_BUILD_DEPENDS = "foo, bar"
TEMPLATE_FILES = "debian/control.tmpl"
TEMPLATE_VARS += "DEBIAN_COMPAT DEBIAN_BUILD_DEPENDS"

さいごに

今回は、YoctoレシピをISAR向けに移植するときにはまらないためのヒントをいくつか紹介しました。

クリアコードでは、組み込み機器ソフトウェア開発の一環として、お客様からの依頼でYoctoレシピの調査・作成等の実績があります。 家電製品や、機械の制御パネルなどで多く使われる組み込み機器向けのソフトウェア開発に関して、ニーズに合わせた設計、開発、サポートなども提供しています。 詳しくは組み込み機器ソフトウェア開発 をご覧いただき、お問い合わせフォームよりお気軽にお問い合わせください。

  1. 第 10 話:ISAR と EMLinuxにISARとEMLinuxについての解説記事があります。