Yocto Tips

# レイヤ

```bash
# レイヤを作る
$ bitbake-layers create-layer <レイヤパス>

# BBLAYERS.confに登録する
$ bitbake-layers add-layer <レイヤパス>

# レイヤ一覧を確認
$ bitbake-layers show-layers
```

# レシピ
```bash
# 作業用レシピを作る
$ devtool add <リポジトリURL> -B <branch名>

# 作業用レシピの一覧表示
$ devtool status

# 作業用レシピを削除
$ devtool reset <レシピ名>

# 作業用レシピをレイヤに登録
$ devtool finish <レシピ名> <レイヤパス>

# レシピ一覧を表示
$ bitbake-layers show-recipes
```

## レシピの依存関係を知りたい
以下を実行すると、build/task-depends.dotファイルができる。これがレシピの依存関係を表している

```bash
$ bitbake -g <recipe name>
```

# タスク
```bash
# タスク一覧を表示
bitbake <recipe name> -c listtasks
```

# パッケージ
```
packages-split/
    libexample/         <-- ${PN} のファイル
    libexample-dev/     <-- ${PN}-dev のファイル
    libexample-doc/     <-- ${PN}-doc のファイル
```
* libexample/：実行ファイルや動的ライブラリ
* libexample-dev/：ヘッダーファイルや開発用シンボリックリンク、静的ライブラリ
* libexample-doc/：ドキュメント関連ファイル

上記より、開発用リンク(xxx.so)はlibexampleに含めることができない。

```bash
# パッケージ一覧表示
$ bitbake <レシピ名> -e | grep ^PACKAGES=

# パッケージ内のファイル確認
## 事前にレシピをIMAGE_INSTALLに加え、ファイルをpackageに含めた後、以下のコマンドで確認可能
$ oe-pkgdata-util list-pkg-files <パッケージ名>
```

## PACKAGECONFIGについて

設定変更に用いる。以下bluez5を例にする
```text:bluez5.inc

# ここでPACKAGECONFIGに値を設定。

PACKAGECONFIG ??= "obex-profiles \
    readline \
    ${@bb.utils.filter('DISTRO_FEATURES', 'systemd', d)} \
    a2dp-profiles \
    avrcp-profiles \
    network-profiles \
    hid-profiles \
    hog-profiles \
    tools \
    deprecated \
    udev \
"

# PACKAGECONFIGに[]内の値を設定してあったら左側、設定されてなかったら右側が有効になる
# 上の例では、
# ・PACKAGECONFIGにudevが設定されてるので、--enable-udevが有効
# ・PACKAGECONFIGにnfcが設定されていないので、--disable-nfcが有効

PACKAGECONFIG[obex-profiles] = "--enable-obex,--disable-obex,libical"
PACKAGECONFIG[readline] = "--enable-client,--disable-client,readline,"
PACKAGECONFIG[testing] = "--enable-testing,--disable-testing"
PACKAGECONFIG[midi] = "--enable-midi,--disable-midi,alsa-lib"
PACKAGECONFIG[systemd] = "--enable-systemd,--disable-systemd"
PACKAGECONFIG[cups] = "--enable-cups,--disable-cups,,cups"
PACKAGECONFIG[nfc] = "--enable-nfc,--disable-nfc"
PACKAGECONFIG[sap-profiles] = "--enable-sap,--disable-sap"
PACKAGECONFIG[a2dp-profiles] = "--enable-a2dp,--disable-a2dp"
PACKAGECONFIG[avrcp-profiles] = "--enable-avrcp,--disable-avrcp"
PACKAGECONFIG[network-profiles] = "--enable-network,--disable-network"
PACKAGECONFIG[hid-profiles] = "--enable-hid,--disable-hid"
PACKAGECONFIG[hog-profiles] = "--enable-hog,--disable-hog"
PACKAGECONFIG[health-profiles] = "--enable-health,--disable-health"
PACKAGECONFIG[sixaxis] = "--enable-sixaxis,--disable-sixaxis"
PACKAGECONFIG[tools] = "--enable-tools,--disable-tools"
PACKAGECONFIG[threads] = "--enable-threads,--disable-threads"
PACKAGECONFIG[deprecated] = "--enable-deprecated,--disable-deprecated"
PACKAGECONFIG[mesh] = "--enable-mesh,--disable-mesh, json-c ell"
PACKAGECONFIG[btpclient] = "--enable-btpclient,--disable-btpclient, ell"
PACKAGECONFIG[udev] = "--enable-udev,--disable-udev,udev"
```

bluez5（レシピ名）のPACKAGECONFIGに変更を加えたい場合は、以下を記載
```text:conf/local.conf
PACKAGECONFIG:append:pn-bluez5 = "nfc"　★追加
PACKAGECONFIG:remove:pn-bluez5 = "udev"　★削除
```
<font color="Salmon">※「PACKAGECONFIG:append:bluez5」ではないので注意！「pn-」を接頭辞とする。</font>


# パッチの作り方

1. 修正したいソースコードをbuild/workspace/sources内にfetchする
    ```bash
    # 編集したいソースコードをfetchするレシピを指定
    $ devtool modify <レシピ名>
    ```
1. fetchしてきたソースコードを修正し、コミット。プッシュはしない。
1. bbappendファイルとパッチを指定したレイヤに加える。不要なパッチは削除してOK
    ```bash
    $ devtool finish <レシピ名> <レイヤ名>
    ```
1. パッチの先頭にUpstream-Statusを追加する
    ※これをしないと、追加の修正をするため、次回devtool modifyしたときエラーが出る
    ```bash:yourpatch.patch
    Upstream-Status: Inappropriate [embedded specific]
    ...
    ```

```plaintext:Github Copilot
Upstream-Status は、Yocto プロジェクトのパッチファイルに含めるメタデータフィールドで、パッチの上流（オリジナルのプロジェクト）へのステータスを示します。このフィールドは、パッチがどのように扱われるべきか、または既にどのように扱われているかを明確にするために使用されます。

Upstream-Status の値には以下のようなものがあります：

Accepted: パッチが上流プロジェクトに受け入れられた。
Backport: パッチが上流プロジェクトに既に存在し、古いバージョンにバックポートされた。
Denied: パッチが上流プロジェクトに提出されたが拒否された。
Inappropriate: パッチが上流プロジェクトに適用されるべきではない（例えば、特定のビルド環境にのみ関連する変更）。
Pending: パッチが上流プロジェクトに提出され、まだレビュー中である。
Submitted: パッチが上流プロジェクトに提出されたが、まだ受け入れられていない。
```

# ライセンス情報が知りたい

build/tmp/deploy/licenses内にライセンス情報がある

# yoctoレシピ内でシンボリックリンク張る時の注意点
リンク先を相対パスで指定するようにする。
⇒絶対パスだと、ビルド環境に大きく依存する。

NG例）私の環境では/homeはroot権限になってたので、/home/machine-idが作成されず、ビルドエラー発生
```bash
$ ln -s /home/machine-id ${IMAGE_ROOTFS}${sysconfdir}/machine-id
```
OK例）yoctoのrootfsの/homeに作成
```bash
$ ln -s ../home/machine-id ${IMAGE_ROOTFS}${sysconfdir}/machine-id
```

# レシピ内でmakefileで使う環境変数の定義の仕方
makefile内で使う環境変数をレシピ内で定義するためには、レシピ内に以下を記載してあげればいい

以下例
> EXTRA_OEMAKE += "'LDFLAGS=-L/pf/lib'"

ただし、makeコマンドではなくoe_runmakeコマンドでmake実行をしないと反映されないので注意

```
do_compile() {
    make # これNG
    oe_runmake # これOK
}
```

makefile内で${LDFLAGS}と書くと「-L/pf/lib」と置換される

# bitbakeで各taskを実行する方法

```bash
$ bitabake <レシピ名> --runall=<タスク>
```

例
```bash
$ bitbake <レシピ名> --runall=patch
$ bitbake <レシピ名> --runall=fetch
```

# sstate-cacheを使わずにbitbake
```bash
$ bitbake <レシピ名> --no-setscene
```


# 環境変数
```bash
# 環境変数を表示
$ bitbake <レシピ名> -e
```

## WORKDIR
> build/tmp/work/.../<レシピ名>/<バージョン>/

SRC_URIで指定したローカルファイルやフェッチしたデータを置く場所。
よくフェッチしたリポジトリにアクセスするため、以下のように定義されることが多い。
> S = ${WORKDIR}/git

※SはデフォルトBと一緒で、do_install実行時とかの作業ディレクトリとなる。

# カーネルモジュールのビルド
```Makefile:Makefile
obj-m += hello.o

KDIR := /home/ubuntu/shared/pi-build/tmp/work/raspberrypi4_64-poky-linux/linux-raspberrypi/6.6.22+git/linux-raspberrypi4_64-standard-build
PWD := $(shell pwd)

all:
	make -C $(KDIR) M=$(PWD) modules
clean:
	make -C $(KDIR) M=$(PWD) clean
```

# その他/気づき
* bbclass内でdo_install:appendとかの追記が可能
* bbclassを修正後、一度cleanallして実行しないと、キャッシュが利用されるので注意



# 参考
* [create symbolic link in bitbake recipe](https://stackoverflow.com/questions/48167601/create-symbolic-link-in-bitbake-recipe)
* [Giant BoardをYoctoに対応する](https://mickey-happygolucky.hatenablog.com/entry/2020/12/30/161207)
* [Bitbakeビルド処理の流れと各処理に関して](https://yoctobbq.lineo.co.jp/?q=node/216)
* [YoctoProject devtoolを使ってみる(modify編)](https://mickey-happygolucky.hatenablog.com/entry/2024/02/21/011358)
* [YoctoProject devtoolを使ってみる(add編)](https://mickey-happygolucky.hatenablog.com/entry/2024/02/18/164740)