Yoctoの概要

# 初めに
YoctoはReferenceが読みにくく、Referenceを参照して学習することが困難(だと筆者は思う)なツールです
一回勉強したことを忘れないよう、覚えたことをここにまとめます

# 目標
「Yoctoを触ったことがない人」、「Yoctoを触ってるけど全体像がよくわからない人」が
「大雑把なイメージをつかむこと」「細かいことは自分でググって解決できるようになること」を目標とします

# 参考
###### YoctoのQuickStart
https://www.yoctoproject.org/docs/latest/brief-yoctoprojectqs/brief-yoctoprojectqs.html
###### YoctoのReference
https://www.yoctoproject.org/docs/latest/ref-manual/ref-manual.html
###### bitbakeのReference
https://www.yoctoproject.org/docs/latest/bitbake-user-manual/bitbake-user-manual.html
(「bitbake reference」でググると古い資料がトップに来るので注意!)
<br>

---
 
# Yoctoとは
Linuxをビルドするプロジェクトです。bitbakeをビルドツールとして使います
VisualStudio風に以下のような関係と思っておけばわかりやすい

 - bitbake　⇔　VisualStudio
 - Yocto　　⇔　Yocto.sln

bitbakeはIDEと呼ぶには随分コンパクトですが....

# 構造
## 概要
Yoctoの主たる構成要素はレイヤとレシピファイルです。
レシピファイルは**ビルド対象のリポジトリのURIとビルド用のパラメータをまとめたもの**と言えます

###### 図1. Yoctoの構成イメージ
![Mindmap 2.png](https://qiita-image-store.s3.amazonaws.com/0/185272/097cf62c-20a1-b935-c617-5233a2b0d1bb.png)


## ディレクトリ構成
[概要](##概要)で記載した構造を実際のディレクトリ構成に落としたものが以下の図です

###### 図2. ディレクトリ構成図
![Package Diagram.png](https://qiita-image-store.s3.amazonaws.com/0/185272/163381b7-d5cf-3ac2-f84a-449ead000ec2.png)


各ファイルの役割は以下の通り
ただしパラメータをどこに記述するかは明確でないようなので、.confファイルの説明は参考程度にしてください

### local.conf
Yocto全体のパラメータを設定する(例:ビルド対象のマシン等)

### bitbake.conf
変数のデフォルト値を定義している

### bblayers.conf
BBLAYERS変数でレイヤのパスを設定する

### layer.conf
レイヤのパラメータを設定する<br>(例:レイヤに属するレシピファイル(=*.bb)のパス)

### *.bb
レシピファイル。対象のモジュールのパラメータを設定する<br>(例:当該レシピファイルのビルド対象モジュールのリポジトリURI)
### *.bbappend
レシピファイルに対する修正ファイル。設定内容を上書きできる

### *.bbclass
複数のレシピファイルで共通する設定・処理をまとめたファイル。<br>bbファイルが継承することで共通する設定・処理の繰り返しの記述を避ける

# 基本的な変数
よく見る変数を紹介します

## プロジェクト全体の設定
| VARIOUBLE         | OVERVIEW                                        |
|:------------------|:------------------------------------------------|
| BBLAYERS          | レイヤのパス                                     |
| BBPATH            | bitbake.confのパス                              |
| BBFILES           | レシピファイルのパス                              |
| IMAGE_INSTALL     | ビルドするLinuxにインストールするパッケージのリスト |
| OVERRIDES         | [変数のオーバーライド](## 変数のオーバーライド)参照 |
| PREFERRED_PROVIDER| [virtual](## virtual)参照            　　　　　　|
| DL_DIR            | bitbakeがリポジトリを落としてくる場所             |
| BB_SRCREV_POLICY  | SRCREVがAUTOREVの時、パースの度にリポジトリに最新版を参照しにいくかどうか |

パースに時間がかかる場合、「BB_SRCREV_POLICY」を「cache」にすると2回目以降が速くなります。
fetchに時間がかかる場合、「DL_DIR」をNAS上においておいて使いまわすようにするといいかも。

## レシピファイルの設定
| VARIOUBLE         | OVERVIEW                                        |
|:------------------|:------------------------------------------------|
| PV                | [プロバイダ名とパッケージ名について](## プロバイダ名とパッケージ名について)参照 |
| PN                | [プロバイダ名とパッケージ名について](## プロバイダ名とパッケージ名について)参照 |
| PACKAGES          | [プロバイダ名とパッケージ名について](## プロバイダ名とパッケージ名について)参照 |
| PROVIDERS         | [プロバイダ名とパッケージ名について](## プロバイダ名とパッケージ名について)参照 |
| DEPENDS           | 当該レシピのビルド時に依存するプロバイダ名                                   |
| RDEPENDS          | 当該レシピがビルドするパッケージが依存するパッケージ名　               　      |
| SRC_URI           | レシピでビルドするソースコードのリポジトリのURI                              |
| SRCREV            | レシピでビルドするソースコードのバージョン指定(コミットID)                    |
| BBCLASSEXTEND     | 指定したクラスを継承したもう一つのレシピを作るイメージ(詳細略)                 |

「DEPENDS」「RDEPENDS」共に、依存先のプロバイダに対応するレシピファイルは当該レシピファイルより先にビルド処理され、当該レシピのビルド時に参照されます
「BBCLASSEXTEND」は"native"を指定するとビルドで使用するモジュールとしてビルドできることを覚えておけば大丈夫です


# レシピファイル/confファイル
## プロバイダ名とパッケージ名について
レシピファイルは「パッケージ名」と「プロバイダ名」を持ちます

###「プロバイダ名」
レシピファイルのあだ名のようなものです
「DEPENDS」に設定するのはこの名前になります

###「パッケージ名」
レシピファイルがビルド・インストールするソフトウェアに付けるラベルです
「RDEPENDS」に設定するのはこの名前になります

### それぞれのデフォルト設定
レシピファイル名が「test_1.0.0.bb」の場合、パッケージ名とプロバイダ名のデフォルト値は以下の通りです

```bash
PACKAGES = "test-dbg test-staticdev test-dev test-doc test-locale test"
PROVIDES = "test "
```

<details><summary>詳細</summary><div>

各々のデフォルト値(bitbake.confで定義)は以下のとおり
(解説のため、一部省略/変更しています)

```bash
PACKAGES = "${PN}-dbg ${PN}-staticdev ${PN}-dev ${PN}-doc ${PN}-locale ${PN}"
PROVIDES = "${PN} "
```

「PN」のデフォルト値(bitbake.confで定義)は以下のとおり

```bash
PN = "${@bb.parse.BBHandler.vars_from_file(d.getVar('FILE', False),d)[0] or 'defaultpkgname'}"
```

「vars_from_file」はレシピファイル名を「_」でsplitした配列を返す関数です
<details><summary>(実装)</summary><div>

```python
def vars_from_file(mypkg, d):
    if not mypkg or not mypkg.endswith((".bb", ".bbappend")):
        return (None, None, None)
    if mypkg in __pkgsplit_cache__:
        return __pkgsplit_cache__[mypkg]

    myfile = os.path.splitext(os.path.basename(mypkg))
    parts = myfile[0].split('_')
    __pkgsplit_cache__[mypkg] = parts
    if len(parts) > 3:
        raise ParseError("Unable to generate default variables from filename (too many underscores)", mypkg)
    exp = 3 - len(parts)
    tmplist = []
    while exp != 0:
        exp -= 1
        tmplist.append(None)
    parts.extend(tmplist)
    return parts
```
</div></details></div></details>

## 変数のオーバーライド
「OVERRIDES」を書き換えることで、変数の値を切り替える仕組みです
例えば、libjpeg-turboのレシピの「SRC_URI」を切り替えてみます

```bash
SRC_URI = "${SOURCEFORGE_MIRROR}/${BPN}/${BPN}-${PV}.tar.gz"
SRC_URI_test = "https://downloads.sourceforge.net/libjpeg-turbo/libjpeg-turbo-2.0.0.tar.gz"
```
これは、SRC_URIを以下のように設定します

 - OVERRIDES変数が"test"文字列を含む　："\${SOURCEFORGE_MIRROR}/\${BPN}/\${BPN}-\${PV}.tar.gz"
 - OVERRIDES変数に"test"文字列を含まない："https://downloads.sourceforge.net/libjpeg-turbo/libjpeg-turbo-2.0.0.tar.gz"

OVERRIDES変数はbitbake.confのデフォルト値を変更して設定するといいと思います
(プロジェクト全体の設定として使用することが多いため)
例えば、以下のような感じ

```bash
OVERRIDES = "${TARGET_OS}:${TRANSLATED_TARGET_ARCH}:build-${BUILD_OS}:pn-${PN}:${MACHINEOVERRIDES}:${DISTROOVERRIDES}:${CLASSOVERRIDE}:forcevariable:test"
```

## virtual/PREFERRED_PROVIDER
同じ機能を提供するモジュールが2つ存在するとき、どちらを使うか切り替えるために使われます
PREFERRED_PROVIDERにはレシピの「PN」値を設定します
![Mindmap 2 (1).png](https://qiita-image-store.s3.amazonaws.com/0/185272/69e518d9-2a7c-31e7-7ede-40424587cf8f.png)



## _append/_remove等
この辺はbitbakenのマニュアルがわかりやすいのでそちらを参照してください
https://www.yoctoproject.org/docs/latest/bitbake-user-manual/bitbake-user-manual.html#basic-syntax


# 知っておくと便利なこと
思いついたら都度追記していきます。

## 特定のタスクだけやり直す
レシピの記述をミスっていて、compileだけやり直したいときとかあると思います。
この場合、ワークディレクトリ(パッケージ毎に$D変数で設定されるディレクトリ)に存在するスクリプトで実行できます
例えば、以下の通りです。openssl_nativeパッケージのコンパイルを実行しています

```bash
root@1.1.1.1:~/workdir/git/poky/build/tmp/work/x86_64-linux/openssl-native/1.0.2o-r0$ cd temp/
root@1.1.1.1:~/workdir/git/poky/build/tmp/work/x86_64-linux/openssl-native/1.0.2o-r0/temp$ ./run.do_compile
NOTE: make -j 4 depend
making depend in crypto...
make[1]: warning: jobserver unavailable: using -j1.  Add '+' to parent make rule.
(以下省略)
```

「bitbake -c compile openssl_native」等とやるとやたらパースが長かったりするので、パース不要のこのやり方は便利です。

## bitbakeサーバのログの場所
実は内部処理のログが出ています。「bitbake-cookerdaemon.log」という名前なので、参照してみてください。
bitbakeは内部でmultiprocessingを使いサーバプロセスを立てて実際の処理を行っているので、制御端末に出てないログがたくさんあります。
あんまり役に立つログ出てなさそうですが...

# あとがき
なんか最後のほう雑になっちゃった
間違ってるところがあったら教えてください