はじめに
Yoctoを使う仕事をしていると、依存関係という言葉をよく聞きます
しかしながら、Yoctoにおける依存関係は結構複雑です。
このため、この記事では以下の順番で依存関係を整理します。
- パッケージとタスクの関係
- 依存関係とは何か
- パッケージ間の依存関係の設定
- タスク間の依存関係の設定
- 依存関係を可視化する方法
前提とする知識
yoctoの文脈で以下の言葉を知っていればたぶんOKです
- yocto
- poky
- bitbake
- パッケージ
- タスク
- フラグ
- DEPENDS/RDEPENDS
パッケージとタスクの関係
パッケージとは
パッケージはbitbakeのビルド単位です。例えば、gccやpythonなどのパッケージがあります。
タスクとは
タスクはbitbakeが実行する処理の単位です。例えば、do_buildやdo_compileなどがあります。
パッケージとタスクの関係
パッケージとタスクは1:Nの関係です。つまり、1パッケージに複数のタスクが紐づきます。
以下のようなイメージですね。
package_X -- package_X:do_fetch
|- package_X:do_patch
|- package_X:do_compile
`- package_X:do_package_sysroot
package_Y -- package_Y:do_fetch
|- package_Y:do_patch
|- package_Y:do_compile
`- package_Y:do_package_sysroot
御覧の通り、タスクはパッケージ名:do_** という名前です
(パッケージ名.do_** のように.でつなぐ場合もあります)
ただし、レシピに記載する際はパッケージ名の部分は記載しません
依存関係とは何か
Yoctoにおける 依存関係は以下の2種類が存在します。
- パッケージ間の依存関係
- タスク間の依存関係
bitbakeは最初にパッケージ間の依存関係はタスク間の依存関係に変換します。
つまり、以下の図のようになります。
具体的な設定方法は次のセクションで説明します。
パッケージ間の依存関係の設定
パッケージ間の依存関係はさらに細かく以下の2種類に分類できます。
- ビルド時の依存関係
- 実行時の依存関係
それぞれ方法が異なるため、ひとつづつ設定方法を紹介します。
ビルド時の依存関係
設定方法
端的にいうと、DEPENDSで設定します。1
以下の例はpackage_Xがpackage_Yにビルド時に依存する場合の設定です。
# package_Xのレシピファイル
DEPENDS += " package_Y"
タスクの依存関係への変換方法
各タスクのdeptaskフラグを使って変換を実施します。
例えば、package_Xのレシピファイルが以下の場合を考えます。
# package_Xのレシピファイル
DEPENDS += " package_Y"
do_A[deptask] += "do_B"
この場合、DEPENDSの設定は
package_X:do_Aがpackage_Y:do_Bに依存する
というタスク間の依存関係に変換されます。
deptaskフラグはbbclass(staging.bbclassなど)で設定されています。
ユーザーがdeptaskフラグを設定する必要は基本的にはありません。
実行時の依存関係
ビルド時の依存関係
と同じですが、参照する変数やフラグが以下のように変わります。
- DEPENDS -> RDEPENDS
- deptask -> rdeptask
タスク間の依存関係の設定
ここでは直接タスクとタスクの依存関係を設定する方法を紹介します。
二つのタスクの順番を定義する
二つのタスクの依存関係を定義する場合、depends/rdependsフラグを使います。
この依存関係はタスクの実行順序を制御するだけの関係です。1
# dependsフラグを使用する場合
do_A[depends] += "do_B"
# 別のパッケージのタスクへ依存する場合はこの書き方
do_A[depends] += "package_Y:do_B"
# rdependsフラグを使用する場合
do_A[rdepends] += "do_B"
# 別のパッケージのタスクへ依存する場合はこの書き方
do_A[rdepends] += "package_Y:do_B"
rdependsはdependsとほぼ同じ働きをします
ただし、rdependsではpackage_Yの部分にPACKAGES変数の値が使用できます2
再帰的に依存関係を定義する
recrdeptaskフラグを使用します。
このメーリングリストのログが詳しく説明してくれています。
依存関係を可視化する方法
パッケージ間の依存関係を可視化する方法
存在しません。頑張って自分でスクリプトを書きましょう3
各パッケージのDEPENDSやRDEPENDSは以下の方法で取得できます
$ bitbake -e ${PACKAGE_NAME} | grep ^DEPENDS=
パッケージ毎に上述のコマンドでbitbakeサーバを立てると時間がかかるとおもいます
--server-onlyオプションを活用するとよいかもしれません
タスク間の依存関係を可視化する方法
以下のコマンドで出力されるtask-depends.dotで可視化できます。
$ bitbake -g ${対象のパッケージ}
# 以下のコマンドでpng画像に変換できます。かなり時間かかる上に、巨大すぎて見づらいですが...
$ dot -Tpng -o output.png task-depends.dot