前回からの続きです。
このテーマを最初からご覧になる場合はこちらからどうぞ。
「core-image-sato」のビルド(試行錯誤編)
前回までにSSH、Git、そしてNode.jsが使用できる実用的なディストリビューションを作成しました。
しかし、これは「core-image-minimal」という最小限のディストリビューション・タイプにちょっとだけ肉付けをした程度のもの。
ご覧の通り「pcDuino3」にはHDMI端子があるのに、画面に映っているのはテキストだけ…。
せっかくHDMI端子を持っているなら、当初の目的からは外れるけど、ちょっとグラフィカルな表示をさせてみたい!…という貧乏性的な発想から、何か絵を出せるディストリビューションを作ってみましょう。
今までは「Yocto Project」で用意されている最軽量のディストリビューション・タイプである「core-image-minimal」をベースに改造してきました。
グラフィカルなディストリビューションのためには、それの上位版「core-image-sato」というのをベースにするのが良さそうです。
ウ~ン「~sato」って何でしょうね?
どうやらGTKを使用したシンプルなデスクトップ環境のようです。
別に佐藤さんが作ったわけでもなさそうです。
というわけで、いつも通りUbuntuを起動してターミナルを開いて、以下のコマンドを打って今度は「core-image-minimal」の代わりに「core-image-sato」をbitbakeです。
$ cd poky/
$ source oe-init-build-env
その前に、前回いくつかのパッケージを書き加えた「./conf/」ディレクトリ以下にある「local.conf」の末尾の行「CORE_IMAGE_EXTRA_INSTALL += ~」の行を「#」でコメントアウトしておきましょう。
- ...
- # CONF_VERSION is increased each time build/conf/ changes incompatibly and is used to
- # track the version of this file when it was generated. This can safely be ignored if
- # this doesn't mean anything to you.
- CONF_VERSION = "2"
- #
- # for pcDuino3
- #
- #CORE_IMAGE_EXTRA_INSTALL += "nodejs nodejs-npm openssh git"
今までと変わったことをやる場合は、前回の変更はクリアにしておいた方がいいです。
トラブル回避のために。
必要ならば、一度ビルドが通ってからまた書き加えましょう。
そして…
$ bitbake core-image-sato
…どやっ!?
ぐはっ!!
なんか、いきなりエラーが出ちゃった。
面倒ですが、エラーをよく調べてみましょう。
これの意味は…「xf86-input-keyboard」は作れないけど「packagegroup-core-x11-xserver.bb」というレシピでこれが必要とされています…!?
- NOTE: Resolving any missing task queue dependencies
- ERROR: Nothing RPROVIDES 'xf86-input-keyboard' (but /home/yocto/poky/meta/recipes-graphics/packagegroups/packagegroup-core-x11-xserver.bb RDEPENDS on or otherwise requires it)
- NOTE: Runtime target 'xf86-input-keyboard' is unbuildable, removing...
- Missing or unbuildable dependency chain was: ['xf86-input-keyboard']
- NOTE: Runtime target 'packagegroup-core-x11-xserver' is unbuildable, removing...
- Missing or unbuildable dependency chain was: ['packagegroup-core-x11-xserver', 'xf86-input-keyboard']
- NOTE: Runtime target 'packagegroup-core-x11-base' is unbuildable, removing...
- Missing or unbuildable dependency chain was: ['packagegroup-core-x11-base', 'packagegroup-core-x11-xserver', 'xf86-input-keyboard']
- ERROR: Required build target 'core-image-sato' has no buildable providers.
- Missing or unbuildable dependency chain was: ['core-image-sato', 'packagegroup-core-x11-base', 'packagegroup-core-x11-xserver', 'xf86-input-keyboard']
なんのこっちゃ?
ちょっと「xf86-input-keyboard」というものについて調べる必要がありそうですね。
これは、X.Org Server(ウィンドウ・システム)で使用されるキーボードのドライバーだそうです。
さらに、こちらのページの一番上の投稿によると、この「xf86-input-keyboard」や「xf86-input-mouse」は非推奨であり、これらの機能は「xf86-input-evdev」などに置き換えられているとのこと。
このページは「Yocto Project」向けのものではありませんが、同じLinuxの情報ですから軽視はできません。
ひょっとして「xf86-input-keyboard」って、もう使われていないのでは?
それなのに呼び出しているので、これが原因では?
そういった推理から現在の「Yocto Project」のレイヤーから「xf86-input-keyboard」が定義されているレシピを探しましょう。
まずは「meta-sunxi」レイヤーを疑います。
以下のコマンドを入力。
$ cd ../meta-sunxi/
$ grep -r "xf86-input-keyboard" ./*
この結果「./conf/machine/include/sunxi.inc」というレシピの参照ファイル(.inc)に「xf86-input-keyboard」という文字列が見つかりました。
このファイルを開いてみましょう。
/home/yocto/poky/meta-sunxi/conf/machine/include/sunxi.inc
ファイルを見ると冒頭に「XSERVER = 」で始まる行が見つかります。
ここでは「XSERVER」という変数に「xf86-input-keyboard」を代入していることが分かります。
前述のページの投稿では「xf86-input-keyboard」や「xf86-input-mouse」は非推奨であり、これらの機能は「xf86-input-evdev」などに置き換えられ…とありましたね。
なのに、この行では「xf86-input-evdev」に加え、これに置き換えられたはずの「xf86-input-keyboard」や、さらには「xf86-input-mouse」まで加えられています。
- SOC_FAMILY ??= ""
- include conf/machine/include/soc-family.inc
- MACHINEOVERRIDES =. "sunxi:"
- # Sub-architecture support
- MACHINE_SOCARCH_SUFFIX ?= ""
- MACHINE_SOCARCH_SUFFIX_sun4i = "-sun4i"
- PREFERRED_PROVIDER_virtual/xserver = "xserver-xorg"
- XSERVER = "xserver-xorg \
- xf86-input-evdev \
- xf86-input-mouse \
- xf86-input-keyboard"
- PREFERRED_PROVIDER_virtual/kernel ?= "linux-mainline"
- PREFERRED_VERSION_linux-mainline ?= "6.1.%"
- PREFERRED_PROVIDER_u-boot ?= "u-boot"
- PREFERRED_PROVIDER_virtual/bootloader ?= "u-boot"
- ...
これは臭いな~。
ならば、もう要らないと噂の「xf86-input-keyboard」と「xf86-input-mouse」を「XSERVER」変数から削除したいところですね。
これを行うには「local.conf」に記述を行うのが得策です。
(因みにこのファイルを直接修正しても結果は同じですが、お行儀の良い方法としてはコッチです。)
「local.conf」では「Yocto Project」で使用される様々なパラメータを変数単位で追加したり、変更したり、削除したりすることができます。
というわけなので「local.conf」の末尾に以下の記述を追加しましょう。
変数からアイテムを削除するには…
[変数名]:remove = "[削除するアイテム]"
…です。
つまり「XSERVER:remove = "xf86-input-keyboard xf86-input-mouse"」と追記すれば良さそうです。
- ...
- # CONF_VERSION is increased each time build/conf/ changes incompatibly and is used to
- # track the version of this file when it was generated. This can safely be ignored if
- # this doesn't mean anything to you.
- CONF_VERSION = "2"
- #
- # for pcDuino3
- #
- #CORE_IMAGE_EXTRA_INSTALL += "nodejs nodejs-npm openssh git"
- XSERVER:remove = "xf86-input-keyboard xf86-input-mouse"
これを保存して、再び「core-image-sato」のbitbakeにトライ!
$ cd build/
$ bitbake core-image-sato
…
あかん、また違ったエラーが出ちまったい…。
ウーン、この修正は上手く通ったようですが…。
今回のエラーメッセージは、こんな感じ。
「sunxi-mali_git.bb」というレシピのConfigure中でコケている模様。
- ERROR: sunxi-mali-git-r0 do_configure: ExecutionError('/home/yocto/poky/build/tmp/work/cortexa7t2hf-neon-poky-linux-gnueabi/sunxi-mali/git-r0/temp/run.do_configure.5903', 2, None, None)
- ERROR: Logfile of failure stored in: /home/yocto/poky/build/tmp/work/cortexa7t2hf-neon-poky-linux-gnueabi/sunxi-mali/git-r0/temp/log.do_configure.5903
- Log data follows:
- | DEBUG: Executing python function extend_recipe_sysroot
- | NOTE: Direct dependencies are ['/home/yocto/poky/meta-sunxi/recipes-graphics/libump/libump_git.bb:do_populate_sysroot', '/home/yocto/poky/meta-sunxi/recipes-graphics/xorg-xserver/libdri2_git.bb:do_populate_sysroot', '/home/yocto/poky/meta/recipes-core/glibc/glibc_2.37.bb:do_populate_sysroot', '/home/yocto/poky/meta/recipes-devtools/gcc/gcc-cross_12.3.bb:do_populate_sysroot', '/home/yocto/poky/meta/recipes-devtools/gcc/gcc-runtime_12.3.bb:do_populate_sysroot', '/home/yocto/poky/meta/recipes-devtools/quilt/quilt-native_0.67.bb:do_populate_sysroot', '/home/yocto/poky/meta/recipes-graphics/drm/libdrm_2.4.115.bb:do_populate_sysroot', '/home/yocto/poky/meta/recipes-graphics/xorg-lib/libx11_1.8.7.bb:do_populate_sysroot', '/home/yocto/poky/meta/recipes-graphics/xorg-lib/libxau_1.0.11.bb:do_populate_sysroot', '/home/yocto/poky/meta/recipes-graphics/xorg-lib/libxdmcp_1.1.4.bb:do_populate_sysroot', '/home/yocto/poky/meta/recipes-graphics/xorg-proto/xorgproto_2022.2.bb:do_populate_sysroot', 'virtual:native:/home/yocto/poky/meta/recipes-devtools/patch/patch_2.7.6.bb:do_populate_sysroot', 'virtual:native:/home/yocto/poky/meta/recipes-devtools/patchelf/patchelf_0.17.2.bb:do_populate_sysroot', 'virtual:native:/home/yocto/poky/meta/recipes-devtools/pseudo/pseudo_git.bb:do_populate_sysroot']
- | NOTE: Installed into sysroot: []
- | NOTE: Skipping as already exists in sysroot: ['libump', 'libdri2', 'glibc', 'gcc-cross-arm', 'gcc-runtime', 'quilt-native', 'libdrm', 'libx11', 'libxau', 'libxdmcp', 'xorgproto', 'patch-native', 'patchelf-native', 'pseudo-native', 'libtool-native', 'libpciaccess', 'libpthread-stubs', 'xtrans', 'util-macros', 'libxcb', 'attr-native', 'gnu-config-native', 'xz-native', 'binutils-cross-arm', 'zstd-native', 'libmpc-native', 'texinfo-dummy-native', 'linux-libc-headers', 'zlib-native', 'gmp-native', 'mpfr-native', 'flex-native', 'libxext', 'libxfixes', 'libgcc', 'xcb-proto', 'gettext-minimal-native', 'm4-native']
- | DEBUG: Python function extend_recipe_sysroot finished
- | DEBUG: Executing shell function do_configure
- | rm -f config.mk
- | make config.mk
- | make[1]: Entering directory '/home/yocto/poky/build/tmp/work/cortexa7t2hf-neon-poky-linux-gnueabi/sunxi-mali/git-r0/git'
- | make -f Makefile.config
- | make[2]: Entering directory '/home/yocto/poky/build/tmp/work/cortexa7t2hf-neon-poky-linux-gnueabi/sunxi-mali/git-r0/git'
- | ABI="armhf" (Provided)
- | VERSION="r3p0" (Provided)
- | EGL_TYPE="x11" (Detected)
- | make[2]: Leaving directory '/home/yocto/poky/build/tmp/work/cortexa7t2hf-neon-poky-linux-gnueabi/sunxi-mali/git-r0/git'
- | Makefile.config:87: *** No Mali libs exist for r3p0, armhf, x11. Stop.
- | make[1]: *** [Makefile:12: config.mk] Error 2
- | make[1]: Leaving directory '/home/yocto/poky/build/tmp/work/cortexa7t2hf-neon-poky-linux-gnueabi/sunxi-mali/git-r0/git'
- | make: *** [Makefile:9: config] Error 2
- | WARNING: exit code 2 from a shell command.
- ERROR: Task (/home/yocto/poky/meta-sunxi/recipes-graphics/libgles/sunxi-mali_git.bb:do_configure) failed with exit code '1'
- NOTE: Tasks Summary: Attempted 3390 tasks of which 3385 didn't need to be rerun and 1 failed.
- Summary: 1 task failed:
- /home/yocto/poky/meta-sunxi/recipes-graphics/libgles/sunxi-mali_git.bb:do_configure
なにやらライブラリが足りない!とか言っているようですね。
ソースやらライブラリが足りないというエラーの場合は、それらをGitからダウンロードするのに失敗しているケースが大半です。
エラーを起こした「sunxi-mali_git.bb」というレシピを調べてみましょう。
因みに「sunxi-mali」とは「pcDuino3」に搭載されているプロセッサ「Allwinner A20」用のグラフィック・モジュールです。
今回の絵を出すディストリビューションを作るミッションにおいては主役ですね。
/home/yocto/poky/meta-sunxi/recipes-graphics/libgles/sunxi-mali_git.bb
ここでは「SRC_URI = 」から始まる行に注目します。
この「SRC_URI 」は、ソースやライブラリのダウンロード先を示す変数のようです。
- DESCRIPTION = "libGLES for the A10/A13 Allwinner processor with Mali 400 (X11)"
- LICENSE = "Proprietary"
- LIC_FILES_CHKSUM = "file://README;md5=1b81a178e80ee888ee4571772699ab2c"
- COMPATIBLE_MACHINE = "(sun4i|sun5i|sun7i|sun8i)"
- # These libraries shouldn't get installed in world builds unless something
- # explicitly depends upon them.
- EXCLUDE_FROM_WORLD = "1"
- PROVIDES = "virtual/libgles1 virtual/libgles2 virtual/egl"
- # There's only hardfp version available
- python __anonymous() {
- tunes = d.getVar("TUNE_FEATURES", True)
- if not tunes:
- return
- if "callconvention-hard" not in tunes:
- pkgn = d.getVar("PN", True)
- pkgv = d.getVar("PV", True)
- raise bb.parse.SkipPackage("%s-%s ONLY supports hardfp mode for now" % (pkgn, pkgv))
- }
- SRCREV = "d343311efc8db166d8371b28494f0f27b6a58724"
- SRC_URI = "git://github.com/linux-sunxi/sunxi-mali.git;protocol=https;branch=master \
- file://0001-Add-EGLSyncKHR-EGLTimeKHR-and-GLChar-definition.patch \
- file://0002-Add-missing-GLchar-definition.patch \
- file://0003-Fix-sed-to-replace-by-the-correct-var.patch \
- file://0001-fix-test-build.patch \
- "
- S = "${WORKDIR}/git"
- DEPENDS = "libdrm xorgproto libump patchelf-native"
- ...
もし「SRC_URI 」の内容が正しければ、今回のエラーは起こらないはずなんですけどねぇ。
この変数の先頭のアイテム「git://github.com/linux-sunxi/sunxi-mali.git;protocol=https;branch=master」をWebで見てみましょう。
https://github.com/linux-sunxi/sunxi-mali/tree/master/lib
ライブラリが足らないということなので、この中の「lib」のディレクトリを覗いてみましょう。
すると、ここには「mali @ 1c5063f」とかいうディレクトリが含まれていて、それがどうやらサブモジュール扱いになっているようです。
サブモジュールというのは、リポジトリの中で他のリポジトリにリンクするモジュールを意味します。
その証拠、この「mali @ 1c5063f」ディレクトリをクリックすると「sunxi-mali-proprietary」という別のリポジトリに飛ばされます。
これこそが足りないと騒ぎになっているライブラリのソースでは?
試しにダウンロードされた現物を見てみましょう。
「Yocto Peoject」ではbitbake中にダウンロードし、展開されたソースは(デフォルトでは)「/home/yocto/poky/build/tmp/work/」以下のディレクトリに置かれることになっています。
そこで「sunxi-mali」のリポジトリ通りにダウンロード・展開されているかを確認します。
サブモジュール「mali @ 1c5063f」が正しく存在するか?を調べるために以下のディレクトリにアクセスすると…やっぱり何もないじゃん!?
/home/yocto/poky/build/tmp/work/cortexa7t2hf-neon-poky-linux-gnueabi/sunxi-mali/git-r0/git/lib/mali
サブモジュール「mali @ 1c5063f」がここに展開されていない…つまりは、正しくダウンロードできていないことが分かりました。
もう一度、以下の「sunxi-mali_git.bb」を見てみましょう。
/home/yocto/poky/meta-sunxi/recipes-graphics/libgles/sunxi-mali_git.bb
「SRC_URI 」の先頭アイテムとして…
git://github.com/linux-sunxi/sunxi-mali.git;protocol=https;branch=master
…が記述されていましたが、コレがダメなんでしょう。
- DESCRIPTION = "libGLES for the A10/A13 Allwinner processor with Mali 400 (X11)"
- LICENSE = "Proprietary"
- LIC_FILES_CHKSUM = "file://README;md5=1b81a178e80ee888ee4571772699ab2c"
- COMPATIBLE_MACHINE = "(sun4i|sun5i|sun7i|sun8i)"
- # These libraries shouldn't get installed in world builds unless something
- # explicitly depends upon them.
- EXCLUDE_FROM_WORLD = "1"
- PROVIDES = "virtual/libgles1 virtual/libgles2 virtual/egl"
- # There's only hardfp version available
- python __anonymous() {
- tunes = d.getVar("TUNE_FEATURES", True)
- if not tunes:
- return
- if "callconvention-hard" not in tunes:
- pkgn = d.getVar("PN", True)
- pkgv = d.getVar("PV", True)
- raise bb.parse.SkipPackage("%s-%s ONLY supports hardfp mode for now" % (pkgn, pkgv))
- }
- SRCREV = "d343311efc8db166d8371b28494f0f27b6a58724"
- SRC_URI = "git://github.com/linux-sunxi/sunxi-mali.git;protocol=https;branch=master \
- file://0001-Add-EGLSyncKHR-EGLTimeKHR-and-GLChar-definition.patch \
- file://0002-Add-missing-GLchar-definition.patch \
- file://0003-Fix-sed-to-replace-by-the-correct-var.patch \
- file://0001-fix-test-build.patch \
- "
- S = "${WORKDIR}/git"
- DEPENDS = "libdrm xorgproto libump patchelf-native"
- ...
「git://~」と記述した場合は、サブモジュールまではダウンロードしてくれないようです。
サブモジュールまでゲットしたい場合は「gitsm://~」と書くのが正解のようです。
つまり…
gitsm://github.com/linux-sunxi/sunxi-mali.git;protocol=https;branch=master
…が正解?
したがって「sunxi-mali_git.bb」を以下のように修正してみましょう。
「SRC_URI = 」から始まる行です。
- DESCRIPTION = "libGLES for the A10/A13 Allwinner processor with Mali 400 (X11)"
- LICENSE = "Proprietary"
- LIC_FILES_CHKSUM = "file://README;md5=1b81a178e80ee888ee4571772699ab2c"
- COMPATIBLE_MACHINE = "(sun4i|sun5i|sun7i|sun8i)"
- # These libraries shouldn't get installed in world builds unless something
- # explicitly depends upon them.
- EXCLUDE_FROM_WORLD = "1"
- PROVIDES = "virtual/libgles1 virtual/libgles2 virtual/egl"
- # There's only hardfp version available
- python __anonymous() {
- tunes = d.getVar("TUNE_FEATURES", True)
- if not tunes:
- return
- if "callconvention-hard" not in tunes:
- pkgn = d.getVar("PN", True)
- pkgv = d.getVar("PV", True)
- raise bb.parse.SkipPackage("%s-%s ONLY supports hardfp mode for now" % (pkgn, pkgv))
- }
- SRCREV = "d343311efc8db166d8371b28494f0f27b6a58724"
- SRC_URI = "gitsm://github.com/linux-sunxi/sunxi-mali.git;protocol=https;branch=master \
- file://0001-Add-EGLSyncKHR-EGLTimeKHR-and-GLChar-definition.patch \
- file://0002-Add-missing-GLchar-definition.patch \
- file://0003-Fix-sed-to-replace-by-the-correct-var.patch \
- file://0001-fix-test-build.patch \
- "
- S = "${WORKDIR}/git"
- DEPENDS = "libdrm xorgproto libump patchelf-native"
- ...
では修正した「sunxi-mali_git.bb」を保存して、再度bitbakeです。
但し「core-image-sato」全体ではなくて、今回は時短のために「sunxi-mali」単体でbitbakeしてみましょう。
このように、レシピを単体でbitbakeすることもできます。
$ bitbake sunxi-mali
今回は大丈夫かな?
以下表示になれば、とりあえず「sunxi-mali」に関しては正しくbitbakeできています。
さきほどの「sunxi-mali」のサブモジュール、今回は正しく生成できているでしょうか?
まあ、できているのでbitbakeが通ったんですけどね。
一応確認です。
再度、以下のディレクトリを確認しましょう。
今回はちゃんとできています!
Webで見た「sunxi-mali-proprietary」というサブモジュールがそのまま展開されています。
/home/yocto/poky/build/tmp/work/cortexa7t2hf-neon-poky-linux-gnueabi/sunxi-mali/git-r0/git/lib/mali
ヨシ!
なんだ、今までの苦労って全部「meta-sunxi」のバグじゃん!?
思われる気持ちも分かります。
しかし、この程度の障害はオープンソース・ソフトウェアでは付きものです。
メンテナーさんを責めてはいけません。
善意でやってくださっているのだから。
さて、満を持して「core-image-sato」をbitbakeです!
$ bitbake core-image-sato
すでに以前の経験からお分かりだと思いますが、終わるまでに凄い時間が掛かります。
就寝前にbitbakeを仕掛けるのが良いでしょう。
というわけで、今日の作業は終了です。
明日の朝起きれば「core-image-sato」のbitbakeが無事に終了して「pcDuino3」が美麗なグラフィックを表示するだろうと楽しみに眠りに就く私。
しかし、これは新たなる苦悩の序章であるとは知る由もなかった…。
…てなわけで、長くなっちゃうので一回切ります。
今回わざわざ試行錯誤の過程を書いたのは「Yocto Project」でのディストリビューション開発の苦悩と現実を理解いただくためです。
そう、意外に難しいんですよ!「Yocto Project」って。