はじめに
Qt 6 in OpenEmbedded and Yoctoが気になったので試してみる。
ここを見る限りまだdev
っぽい。
meta-qt6を覗いてみる
layer.conf
...(snip)... LAYERDEPENDS_qt6-layer = "core" LAYERSERIES_COMPAT_qt6-layer = "zeus dunfell gatesgarth" ...(snip)...
依存はcoreのみ。
互換性はzeus
、dunfell
、gatesgarth
。まぁ妥当なところか。
recipes-qt
treeコマンドの結果(patchは除外)
. ├── meta │ └── meta-toolchain-qt6.bb ├── packagegroups │ ├── nativesdk-packagegroup-qt6-toolchain-host.bb │ ├── packagegroup-qt6-modules.bb │ └── packagegroup-qt6-toolchain-target.bb └── qt6 ├── qt3d_git.bb ├── qt5compat_git.bb ├── qt6-git.inc ├── qt6.inc ├── qtbase ├── qtbase_git.bb ├── qtcoap_git.bb ├── qtdeclarative_git.bb ├── qtgraphicaleffects_git.bb ├── qtimageformats_git.bb ├── qtmqtt_git.bb ├── qtnetworkauth_git.bb ├── qtopcua_git.bb ├── qtquick3d ├── qtquick3d_git.bb ├── qtquickcontrols2_git.bb ├── qtquicktimeline_git.bb ├── qtserialbus_git.bb ├── qtserialport_git.bb ├── qtshadertools_git.bb ├── qtspeech_git.bb ├── qtsvg_git.bb ├── qttools_git.bb ├── qttranslations_git.bb ├── qtvirtualkeyboard_git.bb ├── qtwayland ├── qtwayland_git.bb └── qtwebsockets_git.bb
meta-qt5にはあったqtsmarthome
などのexamplesは今のところ無い。これから生えてくるのだろうか。
QPAプラットフォームの設定
QtをYoctoで使用するといつもついてくるQPAプラットフォームの指定。結構分かりづらいのでいつも何かしら手を入れることになる。
qtbase_git.bbを覗いてみる。
# Default platform plugin QT_QPA_DEFAULT_PLATFORM ?= "${@bb.utils.contains('DISTRO_FEATURES', 'x11', 'xcb', \ bb.utils.contains('PACKAGECONFIG', 'gles2', 'eglfs', 'linuxfb', d), d)}" ...(snip)... EXTRA_OECMAKE_append_class-target = "\ -DFEATURE_rpath=OFF \ -DQT_QPA_DEFAULT_PLATFORM=${QT_QPA_DEFAULT_PLATFORM} \ -DQT_AVOID_CMAKE_ARCHIVING_API=ON \ "
今回ここが秀逸になっていて、DISTRO_FEATURESにx11
が含まれている場合がデフォルトがxcb
になっていて、
含まれない場合はqtbaseのPACKAGECONFIGにgles2があればeglfs
、なければlinuxfb
が設定されるようになっている。
meta-qt5までの環境ではデフォルトがxcbから変更できなかった(はず)ので、実行環境で環境変数を下記のように設定するかアプリケーション実行時に-platform=eglfs
とかする必要があった。
export QT_QPA_PLATFORM=eglfs export QT_QPA_EGLFS_INTEGRATION=eglfs_kms_egldevice
今回はレシピかlocal.confで適切に設定すれば、実行時にQPA_PLATFORMをいちいち気にしないで良いようになっている。
構築手順
ソース取得
下記のコマンドでソースを取得する。
$ mkdir -p rpi-gatesgarth/layers $ cd rpi-gatesgarth/layers $ git clone git://git.yoctoproject.org/poky.git -b gatesgarth $ git clone git://git.yoctoproject.org/meta-raspberrypi -b gatesgarth
meta-qt6の取得
$ git clone git://code.qt.io/yocto/meta-qt6.git
今回構築した時のハッシュは下記の通り。
meta meta-poky meta-yocto-bsp = "gatesgarth:943ef2fad8428f002850e3655a3312e13d0dcb2c" meta-raspberrypi = "gatesgarth:09a3c11696c75593f8e475da5dfb401016c6aaca" meta-qt6 = "dev:aaa3b77573f448c14a9526e85813b2e8c8ca6956"
環境変数設定
$ source layers/poky/oe-init-build-env build
自動的にビルドディレクトリに移動される。 これで、bitbake関連のツールが使用可能になる。
レイヤ追加
下記のコマンドでビルド対象にmeta-raspberrypi
を追加する。
$ bitbake-layers add-layer ../layers/meta-raspberrypi $ bitbake-layers add-layer ../layers/meta-qt6
local.confの修正
MACHINEをraspberrypi4-64
に設定する。
MACHINE = "raspberrypi4-64" DL_DIR ?= "${TOPDIR}/../downloads" # systemd DISTRO_FEATURES_append = " systemd pam" VIRTUAL-RUNTIME_init_manager = "systemd" DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit" VIRTUAL-RUNTIME_initscripts = "" # qt6 modules IMAGE_INSTALL_append = " packagegroup-qt6-modules" # Default QPA platform is eglfs-kms-integration PACKAGECONFIG_append_pn-qtbase = " kms" DISTRO_FEATURES_remove = "x11" IMAGE_INSTALL_append = " ttf-vlgothic"
今回はQt6を動かすためマウスやキーボード、ディスプレイは接続するので、 ネットワークやUARTなどヘッドレスに便利なものは特に追加していない。
ビルド
core-image-baseをビルドする。
$ bitbake core-image-base
ビルド結果
core-image-base-raspberrypi4-64.manifest
を確認する。
...(snip)... libqt6coap-plugins cortexa72 6.0.0 libqt6coap-qmlplugins cortexa72 6.0.0 libqt6coap6 cortexa72 6.0.0 libqt6core5compat-plugins cortexa72 6.0.0 libqt6core5compat-qmlplugins cortexa72 6.0.0 libqt6core5compat6 cortexa72 6.0.0 libqt6mqtt-plugins cortexa72 6.0.0 libqt6mqtt-qmlplugins cortexa72 6.0.0 libqt6mqtt6 cortexa72 6.0.0 libqt6networkauth-plugins cortexa72 6.0.0 libqt6networkauth-qmlplugins cortexa72 6.0.0 libqt6networkauth6 cortexa72 6.0.0 libqt6opcua-plugins cortexa72 6.0.0 libqt6opcua-qmlplugins cortexa72 6.0.0 libqt6opcua6 cortexa72 6.0.0 libqt6serialbus-plugins cortexa72 6.0.0 libqt6serialbus-qmlplugins cortexa72 6.0.0 libqt6serialbus6 cortexa72 6.0.0 libqt6serialport-plugins cortexa72 6.0.0 libqt6serialport-qmlplugins cortexa72 6.0.0 libqt6serialport6 cortexa72 6.0.0 libqt6shadertools-plugins cortexa72 6.0.0 libqt6shadertools-qmlplugins cortexa72 6.0.0 libqt6shadertools6 cortexa72 6.0.0 libqt6texttospeech-plugins cortexa72 6.0.0 libqt6texttospeech-qmlplugins cortexa72 6.0.0 libqt6texttospeech6 cortexa72 6.0.0 libqt6virtualkeyboard-plugins cortexa72 6.0.0 libqt6virtualkeyboard-qmlplugins cortexa72 6.0.0 libqt6virtualkeyboard6 cortexa72 6.0.0 libqt6websockets-plugins cortexa72 6.0.0 libqt6websockets-qmlplugins cortexa72 6.0.0 libqt6websockets6 cortexa72 6.0.0 ...(snip)... packagegroup-qt6-modules raspberrypi4_64 1.0 ...(snip)... qt3d cortexa72 6.0.0 qt3d-plugins cortexa72 6.0.0 qt3d-qmlplugins cortexa72 6.0.0 qtbase cortexa72 6.0.0 qtbase-plugins cortexa72 6.0.0 qtbase-qmlplugins cortexa72 6.0.0 qtdeclarative cortexa72 6.0.0 qtdeclarative-plugins cortexa72 6.0.0 qtdeclarative-qmlplugins cortexa72 6.0.0 qtgraphicaleffects cortexa72 6.0.0 qtgraphicaleffects-plugins cortexa72 6.0.0 qtgraphicaleffects-qmlplugins cortexa72 6.0.0 qtimageformats cortexa72 6.0.0 qtimageformats-plugins cortexa72 6.0.0 qtimageformats-qmlplugins cortexa72 6.0.0 qtquick3d cortexa72 6.0.0 qtquick3d-plugins cortexa72 6.0.0 qtquick3d-qmlplugins cortexa72 6.0.0 qtquickcontrols2 cortexa72 6.0.0 qtquickcontrols2-plugins cortexa72 6.0.0 qtquickcontrols2-qmlplugins cortexa72 6.0.0 qtquicktimeline cortexa72 6.0.0 qtquicktimeline-plugins cortexa72 6.0.0 qtquicktimeline-qmlplugins cortexa72 6.0.0 qtsvg cortexa72 6.0.0 qtsvg-plugins cortexa72 6.0.0 qtsvg-qmlplugins cortexa72 6.0.0 qttools cortexa72 6.0.0 qttools-plugins cortexa72 6.0.0 qttools-qmlplugins cortexa72 6.0.0 qttranslations cortexa72 6.0.0 qttranslations-plugins cortexa72 6.0.0 qttranslations-qmlplugins cortexa72 6.0.0 qtwayland cortexa72 6.0.0 qtwayland-plugins cortexa72 6.0.0 qtwayland-qmlplugins cortexa72 6.0.0
大体のところはイメージに追加されている。
書き込み
bmaptoolで書き込む。
$ sudo bmaptool copy core-image-base-raspberrypi4.wic.bz2 /dev/sdX
/dev/sdX
は環境に応じて適宜読み替える。
Qtのアプリを作成してみる
今のところサンプルアプリケーションが見当たらないのでQtQuickの簡単なアプリを作成してみる。
SDKの作成
meta-toolchain-qt6
でSDKを作成する。
$ bitbake meta-toolchain-qt6
出来上がったSDKをインストールする。
$ cd cd tmp/deploy/sdk/ $ ./poky-glibc-x86_64-meta-toolchain-qt6-cortexa72-raspberrypi4-64-toolchain-3.2.1.sh
デフォルトの設定では/opt/poky/3.2.1
にインストールされる
プログラムの作成
下記のような配置になるようにファイルを作成する。
$ tree . . ├── CMakeLists.txt ├── main.cpp ├── main.qml └── qthello.qrc
QMLファイル
下記の内容でmain.qml
を作成する。
import QtQuick 2.15 import QtQuick.Controls 2.15 ApplicationWindow { visible: true font.pointSize: 64 Button { id: helloButton text: "Hello world" anchors.centerIn: parent onClicked: { Qt.quit() } } }
QtQuickアプリケーションではQMLファイルによってGUIのレイアウトを定義する。
フォントサイズは少し大きめにしてみた。
C++ソースコード
下記の内容でmain.cpp
を作成する。
#include <QGuiApplication> #include <QtQml/QQmlApplicationEngine> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; engine.load("qrc:/main.qml"); return app.exec(); }
QRCファイル
下記の内容でqthello.qrc
を作成する。
<!DOCTYPE RCC> <RCC version="1.0"> <qresource prefix="/"> <file>main.qml</file> </qresource> </RCC>
リソース中のQMLを/main.qml
として参照できるようにしている。
CMakeLists.txt
cmake_minimum_required(VERSION 3.10) project(qthello) find_package(Qt6 COMPONENTS Quick REQUIRED) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) QT6_ADD_RESOURCES(RESOURCES ${PROJECT_NAME}.qrc) add_executable(${PROJECT_NAME} main.cpp ${RESOURCES}) target_link_libraries(${PROJECT_NAME} Qt6::Quick)
Qtプログラムのビルド
下記のコマンドでアプリケーションをビルドする。
$ source /opt/poky/3.2.1/environment-setup-cortexa72-poky-linux $ mkdir build && cd build $ cmake .. $ make -j $(nproc)
qthello
が生成されるのでこれをLinuxイメージを書き込んだSDカードにコピーする。
SDカードがPCに認識されると/media/${USER}/
の下にマウントされる。
$ sudo cp ./qthello /media/${USER}/root/home/root
プログラムの実行
アプリケーションを書き込んだSDでラズパイを起動する。
rootでログインし、下記のコマンドで実行する。
$ ./qthello
無事、アプリケーションが実行される。ボタンをクリックすると終了する。
写真が汚いのはご愛嬌。
まとめ
まだ開発中のmeta-qt6を試してみた。
足りない部分はまだあるが、QPAプラットフォームの扱いに関しては明らかに向上していると思う。
meta-toolchain-qt6のSDKによるアプリケーション開発などについては、現時点でも十分試せるレベルなので、いろいろ遊べそうだ。
リリースが楽しみ。