みつきんのメモ

組み込みエンジニアです。Interface誌で「My オリジナルLinuxの作り方」連載中

Kasのコンフィグファイルを提供してみる

はじめに

なにか適当なレイヤをでっち上げて、kasのコンフィグファイルを作ってみる。

サンプルのレイヤとしてラズパイ向けにハローワールドプログラムを追加したレイヤを作成する。

環境の作成

ソース取得

ラズパイ環境のビルドのためのレイヤをダウンロードする。

$ mkdir -p rpi-dunfell/layers
$ cd rpi-dunfell/layers
$ git clone git://git.yoctoproject.org/poky.git -b dunfell
$ git clone git://git.yoctoproject.org/meta-raspberrypi -b dunfell
$ cd ../

環境変数の設定

bitbakeを実行できるようにするため環境変数を設定する。

$ source layers/poky/oe-init-build-env build

レイヤの追加

ビルド対象にレイヤを追加する。

$ bitbake-layers add-layer ../layers/meta-raspberrypi

local.confの修正

MACHINEをラズパイ4にする。

INITはsystemdで。あとは細かい設定。 弊ブログでは定番の設定だが、今回はこの部分もkasのコンフィグに組み込む。

MACHINE = "raspberrypi4"
DL_DIR ?= "${TOPDIR}/../downloads"

# enable uart
ENABLE_UART = "1"

# systemd
DISTRO_FEATURES_append = " systemd pam"
VIRTUAL-RUNTIME_init_manager = "systemd"
DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
VIRTUAL-RUNTIME_initscripts = ""

イメージの作成

コンソール向けイメージをビルドする。

$ bitbake core-image-base

これで最初の環境は完成。

レイヤの作成

ハローワールドを組み込むためのレイヤを作成する。

$ bitbake-layers create-layer meta-hello
$ mv meta-hello ../layers
$ bitbake-layers add-layer ../layers/meta-hello

レシピの作成

ハローワールドのレシピは自作しても良いが、今回は本筋からそれてしまうため、pokyのドキュメントに含まれているhello.bbを拝借することにする。

$ cp -r ../layers/poky/documentation/ref-manual/examples/hello-single ../layers/meta-hello/recipes-example/

ただしこのままではbitbakeに失敗する。

ERROR: hello-1.0-r0 do_package_qa: QA Issue: File /usr/bin/helloworld in package hello doesn't have GNU_HASH (didn't pass LDFLAGS?) [ldflags]
ERROR: hello-1.0-r0 do_package_qa: QA run found fatal errors. Please consider fixing them.
ERROR: Logfile of failure stored in: /home/mickey/work/yocto/kas-dunfell/build/tmp/work/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/hello/1.0-r0/temp/log.do_package_qa.26500
ERROR: Task (/home/mickey/work/yocto/kas-dunfell/layers/meta-hello/recipes-example/hello-single/hello.bb:do_package_qa) failed with exit code '1'
NOTE: Tasks Summary: Attempted 550 tasks of which 0 didn't need to be rerun and 1 failed.

ので、下記のように修正する。

--- hello.bb~    2020-11-17 13:19:16.719291894 +0900
+++ hello.bb  2020-11-17 13:47:15.962567623 +0900
@@ -8,7 +8,7 @@
 S = "${WORKDIR}"
 
 do_compile() {
-  ${CC} helloworld.c -o helloworld
+   ${CC} ${CFLAGS} ${LDFLAGS} helloworld.c -o helloworld
 }
 
 do_install() {

local.confの修正

local.confにハローワールドを追加する。

# hello world
IMAGE_INSTALL_append = " hello"

kasコンフィグについて

kasコンフィグはYAML形式で記述されたテキストファイルとなっている。 YAMLなので階層構造をスペースのインデントで表現する。

kasコンフィグの詳細についてはWelcome to the kas documentation, a setup tool for bitbake based projects を参照してほしい。

トップレベルの階層

最低限記述しなければならないトップレベルの階層としては下記のものがある。

アイテム 概要 備考
header コンフィグのヘッダ情報
machine ターゲットマシン raspberrypi4など
distro ディストリビューション pokyなど
target ビルドターゲット core-image-baseなど
repos リポジトリ情報
bblayers_config_header bblayers.confの雛形
local_conf_header local.confの雛形

header

コンフィグ自体のヘッダ情報、具体的にはコンフィグ形式のバージョンを指定する。

下記のように記載する。

header:
  version: 9

2020年11月時点でバージョンは1〜9まで指定できる。

machine

ターゲットマシン(ボード)を指定する。local.confのMACHINEに設定される。

machine: raspberrypi4

distro

bitbakeで生成されるディストリビューションを指定する。local.confのDISTROに設定される。

distro: poky

target

ビルドターゲットを指定する。bitbakeコマンドのターゲットに使用される。

target:
 - core-image-base

repos

使用するメタデータ(レイヤ)のリポジトリ情報を指定する。リポジトリのURLやrefspecを指定する。 リポジトリが複数のレイヤを含んでいる場合はlayersで指定する。 meta-raspberrypiのようにリポジトリが1つのレイヤのみを含んでいる場合はlayersの記述は必要ない。

最初は自分自身の情報を記載する。

repos:
  meta-hello: # 自分自身

  poky: # pokyのリポジトリ情報
    url: https://git.yoctoproject.org/git/poky 
    refspec: dunfell
    layers:
      meta:           # 
      meta-poky:      # pokyからはこの3つのレイヤがしようされる
      meta-yocto-bsp: #

  meta-raspberrypi:
    url: git://git.yoctoproject.org/meta-raspberrypi
    refspec: dunfell

上記はブランチ名を指定しているが下記のようにコミットハッシュを指定することもできる。

repos:
  meta-hello:

  poky:
    url: https://git.yoctoproject.org/git/poky
    refspec: d3ad6a22dbb8b9a21d7fe11bf437a20dea95ec81
    layers:
      meta:
      meta-poky:
      meta-yocto-bsp:

  meta-raspberrypi:
    url: git://git.yoctoproject.org/meta-raspberrypi
    refspec: 987993209716302eb8f314f69a2a3340555f94d8

ちなみにbitbakeを実行した時点で使用されたレイヤのコミットハッシュはtmp/log/cooker/raspberrypi4/console-latest.logで確認できる。

$ cat ./tmp/log/cooker/raspberrypi4/console-latest.log | head -n 20

bblayers_conf_header

bblayers.confの雛形を記述する。

bblayers_conf_header:
  standard: |
    POKY_BBLAYERS_CONF_VERSION ?= "2"
    BBPATH ?= "${TOPDIR}"
    BBFILES ?= ""

BBLAYERSに設定されるビルド対象となるレイヤ情報はreposから自動的に構成されるため、改めて記述する必要はない。

local_conf_header

local.confの雛形を記述する。

local_conf_header:
  standard: |
    CONF_VERSION ?= "1"
    PACKAGE_CLASSES ?= "package_rpm"
    USER_CLASSES ?= "buildstats image-mklibs image-prelink"
    PATCHRESOLVE ?= "noop"
  debug-tweaks: |
    EXTRA_IMAGE_FEATURES ?= "debug-tweaks"

階層構造となっているが、local.confへは下記のようにコメントと1つのかたまりとして展開される。

# standard
CONF_VERSION ?= "1"
PACKAGE_CLASSES ?= "package_rpm"
USER_CLASSES ?= "buildstats image-mklibs image-prelink"
PATCHRESOLVE ?= "noop"

# debug-tweaks
EXTRA_IMAGE_FEATURES ?= "debug-tweaks"

ちょっと調べた感じだと、kasコマンド実行時に特定の階層を削除する(たとえばdebug-tweaksは無効とか)ようなことはできなさそう*1なので、 おそらく見た目以外の意味はなさそう。

kasコンフィグの作成

ここまでの内容を踏まえてmeta-hello向けのkasコンフィグを作成する。

meta-helloの直下にkas-poky-hello.ymlとしてコンフィグファイルを作成する。

$ vi ../layers/meta-hello/kas-poky-hello.yml

kas-poky-hello.ymlを下記の内容にする。

header:
  version: 9

machine: raspberrypi4
distro: poky
target:
 - core-image-base

repos:
  meta-hello:

  poky:
    url: https://git.yoctoproject.org/git/poky 
    refspec: dunfell
    layers:
      meta:
      meta-poky:
      meta-yocto-bsp:

  meta-raspberrypi:
    url: git://git.yoctoproject.org/meta-raspberrypi
    refspec: dunfell

bblayers_conf_header:
  standard: |
    POKY_BBLAYERS_CONF_VERSION ?= "2"
    BBPATH ?= "${TOPDIR}"
    BBFILES ?= ""

local_conf_header:
  standard: |
    PACKAGE_CLASSES ?= "package_rpm"
    USER_CLASSES ?= "buildstats image-mklibs image-prelink"
    PATCHRESOLVE = "noop"
    CONF_VERSION = "1"
    PACKAGECONFIG_append_pn-qemu-system-native = " sdl"

  image features: |
    EXTRA_IMAGE_FEATURES ?= "debug-tweaks"

  diskmon: |
    BB_DISKMON_DIRS ??= "\
      STOPTASKS,${TMPDIR},1G,100K \
      STOPTASKS,${DL_DIR},1G,100K \
      STOPTASKS,${SSTATE_DIR},1G,100K \
      STOPTASKS,/tmp,100M,100K \
      ABORT,${TMPDIR},100M,1K \
      ABORT,${DL_DIR},100M,1K \
      ABORT,${SSTATE_DIR},100M,1K \
      ABORT,/tmp,10M,1K"

  change download directory: |
    DL_DIR ?= "${TOPDIR}/../downloads"

  enable uart: |
    ENABLE_UART = "1"

  systemd: |
    DISTRO_FEATURES_append = " systemd pam"
    VIRTUAL-RUNTIME_init_manager = "systemd"
    DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
    VIRTUAL-RUNTIME_initscripts = ""

  hello world: |
    IMAGE_INSTALL_append = " hello"

kasによるビルド

新しいシェルを開き下記のコマンドを実行する。

$ kas build meta-hello/kas-poky-hello.yml

まとめ

kasコンフィグはyaml形式のテキストであるため、比較的簡単に書ける。 複数のgitリポジトリを管理するためにrepoツールなどもあるが、 bitbakeに特化した作業をするのであればkasは便利かもしれない。

ただ、kasはあくまでも完成したレイヤを利用する人が使うには便利だが、 レイヤを開発する段階ではbitbakeを直接使用したほうが便利だと思う。

*1:できたらやり方教えてください