みつきんのメモ

組み込みエンジニアです。Interface誌で「Yocto Projectではじめる 組み込みLinux開発入門」連載中

Yocto Project 5.1(styhead)以降の注意点

はじめに

ぼやぼやしているうちにYocto Projectも5.2がリリーズ済みとなり、5.1はサポート終了していた。

しかし、Migration notes for 5.1 (styhead)を見ると、do_unpackでのWORKDIRの扱いが変更されたため、これまでの一部のレシピについて互換性がなくなる可能性があるということで調べてみた。

WORKDIRの扱いの変更について

主な内容

下記のような内容が一番大きく記載されている。

S = ${WORKDIR} no longer supported

これはS変数に${WORKDIR}を直接指定できなくなったということ。 Local file fetcherを使用する一部のレシピで問題になる。

do_unpackタスクの実装

do_unpackタスクはdo_fetchタスクによってダウンロードされたデータを WORKDIRで指定されるレシピ毎の作業ディレクトリに配置するタスクである。

変数の取り扱い

do_unpackおよびそれ以降のタスクで関係ある変数のデフォルト値を以下の表にまとめる。

変数 5.0以前 5.1
UNPACKDIR -- ${WORKDIR}/sources-unpack
S ${WORKDIR}/${BP} ${WORKDIR}/${BP}
B ${S} ${S}

UNPACKDIRは5.1で新設された変数となる。 5.0以前では、do_unpackタスクでは${WORKDIR}を参照していたが、5.1以降では${UNPACKDIR}を参照するようになった。

実際にソースコードが配置される場所は、レシピによって選択されるFetcherによって異なる。

いくつかのFetcherを例示してみる。

HTTP/FTP wget fetcher

展開後のディレクトリ構成は以下のようになる。

${WORKDIR}/
└── hoge/
    └── hoge.c

Git fetcher

展開後のディレクトリ構成は以下のようになる。

${WORKDIR}/
└── git/
    └── hoge.c

Local file fetcher(5.0以前)

5.0以前の実装では${WORKDIR}直下に展開されたため、以下のようになる。

${WORKDIR}/
└── hoge.c

Local file fetcher(5.1以降)

5.1以降では${UNPACKDIR}以下に展開されるため、以下のようになる。

${WORKDIR}/
└── sources-unpack/
    └── hoge.c

WORKDIR直下にBitBakeが出力するファイル以外のファイルが混在する状況を是正したかったのだろう。

S変数の調整

上記をみてわかるとおり、多くの場合do_unpackで展開された場所とソースコードの場所を示すSのデフォルト値では異なる場所を指している。

そのため、レシピの中でSの値を実際のソースコードの展開場所に修正する必要がある。

Git fetcherの場合は以下のようになる。

S = "${WORKDIR}/git"

5.0以前のLocal file fetcherでは以下のようにしていた。

S = "${WORKDIR}"

5.1以降ではこれが禁止されてしまったため、このようなレシピは以下のように修正するべきとマニュアルに記載されている。

S = "${WORKDIR}/sources"
UNPACKDIR = "${S}"

S${WORKDIR}直下以外の値を設定し、UNPACKDIR${S}を設定している。

この場合、ディレクトリの構成は以下のようになる。

${WORKDIR}/
└── sources/
    └── hoge.c

環境構築

ビルド環境を構築して動作を確認してみる。

作業ディレクト

作業ディレクトリを作成する。

$ mkdir -p ~/yocto/styhead
$ cd ~/yocto/styhead

Pokyの取得

styheadブランチを使用する。

$  git clone git://git.yoctoproject.org/poky.git -b styhead

環境設定

oe-init-build-envを読み込む

$ source poky/oe-init-build-env

作業レイヤの作成

作業用レイヤを作成し、サンプルレシピを削除する。

$ bitbake-layers create-layer -a meta-work
$ rm -rf meta-work/recipes-example/exapmle

動作確認

レシピの作成

レシピ格納用のディレクトリを作成する。

$ mkdir -p meta-work/recipes-example/hoge/files

meta-work/recipes-example/hoge/files/hoge.cを以下の内容で作成する。

/*
 * SPDX-License-Identifier: MIT
 */
#include <stdio.h>

int main(void) {
  printf("hoge\n");
  return 0;
}

meta-work/recipes-example/hoge/hoge.bbを以下の内容で作成する。

DESCRIPTION = "A sample recipe"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://hoge.c;endline=3;md5=e380accbc2e21fd8bb73fbf8c449c2ac"

SRC_URI = "file://hoge.c"

S = "${WORKDIR}"

ここでは試しにSに${WORKDIR}を入れてみる

レシピのディレクトリ構造は以下のようになっている。

hoge/
├── files/
│   └── hoge.c
└── hoge.bb

タスク実行

この状態でBitBakeを実行して見る。

$ bitbake hoge -c unpack
... (snip) ...
ERROR: /home/mickey/yocto/styhead/build/meta-work/recipes-example/hoge/hoge.bb: Using S = ${WORKDIR} is no longer supported     | ETA:  --:--:--
ERROR: Parsing halted due to errors, see error messages above

マニュアルの通りエラーになる。

レシピの修正

meta-work/recipes-example/hoge/hoge.bbを以下の内容になるように修正する。

DESCRIPTION = "A sample recipe"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://hoge.c;endline=3;md5=e380accbc2e21fd8bb73fbf8c449c2ac"

SRC_URI = "file://hoge.c"

S = "${WORKDIR}/sources"
UNPACKDIR = "${S}"

do_compile() {
    ${CC} ${CFLAGS} ${LDFLAGS} -o ${B}/${BPN} ${S}/hoge.c
}

do_install() {
    install -d ${D}${bindir}
    install -m 0755 ${B}/${BPN} ${D}${bindir}
}

ビルド

今度は正しくビルドできる。

$ bitbake hoge -c unpack
... (snip) ...
NOTE: Tasks Summary: Attempted 831 tasks of which 831 didn't need to be rerun and all succeeded.

まとめ

YP5.1以降のバージョンを使用する場合で、過去の自作レイヤを使いまわしたい場合には S = ${WORKDIR}のようなレシピでエラーとななるので注意が必要。