Yocto 入門

標準的な Yocto の知識についてまとめる。Yocto 開発環境の構築には、git clone を使う。(pyro で 200MB)

    git clone git://git.yoctoproject.org/poky

以下の項目が含まれる

* oe-init-build-env: 環境設定スクリプト
* bitbake, bitbake-layers, oe-pkgdata-util: 各種コマンド

## 用語

* layer: conf/layer.conf の置いてあるディレクトリの事
* recipe: ソフトウェアの単位 .bb ファイルの事
* package: 生成物インストールの単位 dev doc 等に分割出来る。

## Bitbake の動作

bitbake recipe で何が起こるか?

* Bitbake は conf/bblayers.conf を読む
* Bitbake は BBLAYERS を読む
    * BBLAYER には空白区切りでディレクトリが書いてある (例: `${METADIR}/poky/meta`)
        * METADIR とは poky ディレクトリ
    * Bitbake は BBLAYER それぞれの conf/layer.conf を読む
* Bitbake は BBPATH を読む (例: `BBPATH = "${TOPDIR}"`)
    * TOPDIR は build ディレクトリを指す
    * Bitbake は BBPATH の conf/bitbake.conf を読む
        * 謎: 実際には conf.bitbake は build では無く、poky/meta/ にある。
        * include によって local.conf が読まれる。
* Bitbake は BBFILES に空白区切りで指定された .bb ファイルを読む
* 指定した recipe を実行

## layer が有効になるまで

* build/conf/layer.conf が生成される
    * todo: どうやって?
* build/conf/layer.conf で BBLAYERS に追加される。

## ファイルの種類

* recipe (bb)
    * ファイル名形式: [${PN}_${PV}.bb](http://www.yoctoproject.org/docs/current/bitbake-user-manual/bitbake-user-manual.html#bb-bitbake-preferences)
        * busybox_1.22.1.bb: 1.22 を明示的に指定
        * busybox_git.bb: 最新バージョンを指定
    * ビルド手順を示す。PROVIDES を定義する。
* [bbappend](http://www.yoctoproject.org/docs/current/dev-manual/dev-manual.html#using-bbappend-files)
    * ファイル名形式: ${PN}_${PV}.bbappend
    * レイヤ内に記述する。

## conf

## コマンド

* `bitbake (recipe)` でビルド
* `bitbake -e (recipe)` 変数の確認
* `bitbake-layers show-layers` 読み込むレイヤの表示
* `bitbake-layers show-recipes` 読み込むレシピの表示
* `oe-pkgdata-util list-pkgs` パッケージリストを表示
* `oe-pkgdata-util list-pkg-files (package)` パッケージに含まれるファイル

## 生成物のディレクトリ構成

* [tmp/deploy/](http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#structure-build-tmp-deploy)
    * ビルド結果。
* [tmp/sysroots/(machine)/](http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#structure-build-tmp-sysroots)
    * 互換性のためにある。マシンごとに必要なファイルが置いてあった。
* [TMPDIR](http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-TMPDIR)
    * `${TOPDIR}/tmp`
* [WORKDIR](http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-WORKDIR)
    * `${TMPDIR}/work/${MULTIMACH_TARGET_SYS}/${PN}/${EXTENDPE}${PV}-${PR}` ... `build/tmp/work/機種/レシピ/バージョン/`
* [build/tmp/work/tunearch/recipename/version/](http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#structure-build-tmp-work-tunearch-recipename-version)
* `build/tmp/work/tunearch/recipename/version/image`
    * `do_install` の結果 ${D} 変数の結果
* `build/tmp/work/tunearch/recipename/version/sysroot-destdir/`
    * `do_populate_sysroot` の結果
* `build/tmp/work/tunearch/recipename/version/package/`
    * `do_package` の結果 (パッケージ分割前)
* `build/tmp/work/tunearch/recipename/version/package-split/`
    * `do_package` の結果 (パッケージ分割後)
* [build/tmp/work/tunearch/recipename/version/pkgdata/](http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-PKGDATA_DIR)
    * 依存情報を持つ。`PKGDATA_DIR` で参照。

## 変数

変数のスコープは [Variable Context](http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#ref-varlocality) 記述されている。

デフォルト値が local.conf, bblayers.conf, [poky/meta/conf/bitbake.conf](http://git.yoctoproject.org/cgit/cgit.cgi/poky/tree/meta/conf/bitbake.conf) 等で定義されているので `bitbake -e (recipe)` で確認する。

あるレシピで定義した変数を、他のレシピから参照する事は出来ない。グローバル変数をレシピで再定義しても他のレシピからは見えない。

* bblayers.conf のスコープ
    * [BBLAYER](http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-BBLAYERS)
        * 追加するレイヤのリスト
        * レイヤとは conf/layer.conf が存在するディレクトリ。layer.conf 内でレシピ等を指定する。
* local.conf のスコープ
    * [BBFILES](http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-BBFILES)
        * レシピ (bb と bbappend) のリスト
    * [BBMASK](http://www.yoctoproject.org/docs/latest/ref-manual/ref-manual.html#var-BBMASK)
        * あるレシピ (bb と bbappend) を取り除く。正規表現パターンを記述。
    * [DISTRO_FEATURES](https://docs.yoctoproject.org/current/ref-manual/variables.html#term-DISTRO_FEATURES)
        * ディストリビューションに必要な機能のキーワードを指定。複数のレシピを有効にしたり無効にしたりする。レシピ側では REQUIRED_DISTRO_FEATURES を使って自分がどの機能に必要なのか宣言する。
* layer.conf のスコープ
    * [LAYERDIR](http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-BBLAYERS)
        * 現在のレイヤ
* [recipe のスコープ](http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#ref-varlocality-recipes)
    * [PN](http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-PN)
        * recipe_0.1.bb の場合　recipe となる。
    * [B](http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-B)
        * ビルド結果を置く。S と同じでも良い。
    * [D](http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-D)
        * ${WORKDIR}/image do_install でここに書き込む
    * [DEPENDS](http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-DEPENDS)
        * ビルド時の依存リスト。大体レシピ名 (PN) や PROVIDES に指定された値を書く。package name ではない。
    * [WORKDIR](http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-WORKDIR)
        * レシピごとの作業ディレクトリ
    * [S](http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-S)
        * ソースコードの場所。git の場合自分で設定する必要がある。
    * [FILES](http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-FILES)
        * package に含むファイルやディレクトリ。${D} 内のディレクトリに応じて予めどこがどのパッケージになるか大体 [poky/meta/conf/bitbake.conf で決まっている](http://git.yoctoproject.org/cgit/cgit.cgi/poky/tree/meta/conf/bitbake.conf?h=morty#n283)。
            * `FILES_${PN}` のように指定すると default pacakge
            * `FILES_${PN}-dev` のように指定すると {PN}-dev pacakge
    * [SRCREV](http://www.yoctoproject.org/docs/latest/ref-manual/ref-manual.html#var-SRCREV)
        * git 等の revision
    * [AUTOREV](http://www.yoctoproject.org/docs/latest/ref-manual/ref-manual.html#var-AUTOREV)
        * git 等の最新のリビジョン。使い方は [Automatically Incrementing a Package Version Number](http://www.yoctoproject.org/docs/current/dev-manual/dev-manual.html#automatically-incrementing-a-binary-package-revision-number) 参照。
        * `SRCREV = "${AUTOREV}"`
        * `PV = "1.0+git${SRCPV}"`

## Fakeroot

do_install では、生成物を ${D} にコピーするが、その際にユーザ権限の設定等をしたい。本来なら root じゃないとそういう操作は出来ないはずだが、bitbake では通常ユーザでもユーザ権限の操作が出来るように [Fakeroot](http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#fakeroot-and-pseudo) という仕組みでなんちゃって Root 権限を実現している。

Fakeroot 環境では `LD_PRELOAD` でシステムコールを横取りし環境下のプログラムに root 権限があるかのように思わせるが、実際には `${WORKDIR}/pseudo/files.db` にある sqlite3 ファイルで権限を管理している。試しにテーブルを見てみると、何やらそれっぽいデータが出て来る。

```
$ ./tmp/sysroots/x86_64-linux/usr/bin/sqlite3 ./tmp/work/armv7vehf-neon-vfpv4-agl-linux-gnueabi/weston/1.11.0-r0/pseudo/files.db "select * from files;" | head
2|/work/build/tmp/work/armv7vehf-neon-vfpv4-agl-linux-gnueabi/weston/1.11.0-r0/temp/log.do_install.6002|64770|23156|0|0|33188|0|0
3|/work/build/tmp/buildstats/20170913141538/weston-1.11.0-r0/do_install|64770|23157|0|0|33188|0|0
4|/work/build/tmp/work/armv7vehf-neon-vfpv4-agl-linux-gnueabi/weston/1.11.0-r0/temp/run.useradd_sysroot.6002|64770|23158|0|0|33277|0|0
5|/work/build/tmp/work/armv7vehf-neon-vfpv4-agl-linux-gnueabi/weston/1.11.0-r0/image|64770|22169642|0|0|16877|0|0
6|/work/build/tmp/work/armv7vehf-neon-vfpv4-agl-linux-gnueabi/weston/1.11.0-r0/temp/run.do_install|64770|23159|0|0|41471|0|0
7|/work/build/tmp/work/armv7vehf-neon-vfpv4-agl-linux-gnueabi/weston/1.11.0-r0/temp/run.do_install.6002|64770|23160|0|0|33277|0
```

イメージ作成の時に `${WORKDIR}/pseudo/files.db` に基づいて権限を設定してやれば一般ユーザで作業しても root で作ったかのようにちゃんと権限のついたイメージが出来るという仕組みらしい。