インストール - Qt6 PinePhone
概要
Allwinner A64 SoC(sun50iw1)は、Cortex-A53 ARM CPU(クアッドコア)とARM社のMali400 MP2 GPUを搭載している。
A64は、基本的にAllwinner H3のCortex-A7コアをCortex-A53コアに置き換えたものである。
メモリマップ、クロック、割り込みのほとんどを共有しており、IPブロックも同じものを使用している。
H3とA64の違いは以下の通りである。
H3は、USBホストコントローラを3つ搭載しているのに対して、A64は1つしか搭載していない。
どちらのSoCもUSB-OTGコントローラを追加しているが、これは通常のホストコントローラとしても使用することを想定している。
H3のDRAMコントローラは最大2[GB]のRAMをサポートしており、A64は最大3[GB]をサポートしている。
64bitチップでありながら、物理的には完全に3bitのSoCとなっている。
H3は5個のUARTをサポートしており、A64は6個のUARTをサポートしている。
MMCコントローラーが更新され、より高速な転送モードをサポートしている。
MMCのクロックは途中で変更され、現在はMMCコントローラ自身が出力とサンプルフェーズをサポートしている。
H3はSRAM A1がアドレス0にマッピングされており、BROMは0xffff0000にある。
A64はBROMがアドレス0にマッピングされており、SRAM A1はそのすぐ後ろの0x10000(64KB)にマッピングされている。
pinmuxの構成はまだ多少似ているが、互換性のない程度に異なる。
顕著な例は(デバッグ用の)UART0で、H3ではPortAにあるが、A64ではPortBにある。
H3にはPortBが無い。
参考書 | ||
---|---|---|
![]() Introducing Qt 6 C++でモバイルとデスクトップ向けのアプリとゲームを作ることを学ぶ |
![]() Cross-Platform Development with Qt 6 and Modern C++ プラットフォーム依存性を気にすることなく、 モダンなグラフィカルユーザーインターフェースを持つアプリケーションを設計・構築する |
![]() A Guide to Qt 6 Qt 6の初心者向けガイド |
ホストPCの設定
Linux PCにおいて、以下の依存関係のライブラリをインストールする。
(Texinfoは、GNU公式Webサイトにアクセスして、ソースコードからインストールすることを推奨する)
# SUSE sudo zypper install autoconf automake cmake unzip tar git wget pkg-config gperf gcc gcc-c++ \ gawk bison openssl flex figlet pigz ncurses-devel ncurses5-devel texinfo # QtWebEngineをインストールする場合 libicu-devel libopus-devel openjpeg2-devel pciutils-devel libpciaccess-devel libxshmfence-devel \ libvpx-devel python3-html5lib # QtWebEngineをインストールする場合 (デフォルトパッケージ) ffmpeg-4-libavcodec-devel ffmpeg-4-libavdevice-devel ffmpeg-4-libavfilter-devel ffmpeg-4-libavformat-devel \ ffmpeg-4-libavresample-devel ffmpeg-4-libavutil-devel ffmpeg-4-libpostproc-devel ffmpeg-4-libswresample-devel \ ffmpeg-4-libswscale-devel ffmpeg-4-private-devel # QtWebEngineをインストールする場合 (Packmanパッケージ) ffmpeg-6-libavcodec-devel ffmpeg-6-libavdevice-devel ffmpeg-6-libavfilter-devel ffmpeg-6-libavformat-devel \ ffmpeg-6-libavresample-devel ffmpeg-6-libavutil-devel ffmpeg-6-libpostproc-devel ffmpeg-6-libswresample-devel \ ffmpeg-6-libswscale-devel ffmpeg-6-private-devel
GCC ARMツールチェーンにおいて、GCC 8以降が必要である
Linaroは、アップストリームビルドのスナップショットをユーザに提供するGNUツールチェーン・インテグレーションビルドを毎月提供している。
これらのビルドにより、開発者はビルド済みバイナリの機能をアップストリームですぐにテストすることができる。
Linero社が提供しているGCC ARMツールチェーンをダウンロードする。
※注意
クロスコンパイラのlibstdc++.so.6ファイルにおいて、PinePhone OSのlibstdc++.so.6ファイルのバージョンと同等または古いものを使用する必要がある。
例えば、Mobian 12.0のlibstdc++.so.6ファイルはGLIBCXX_3.4.30までであるため、GCC 12.2ツールチェーン、または、それ以前のものを使用する。
GCCツールチェーン群 : https://snapshots.linaro.org/gnu-toolchain/
tar xf gcc-linaro-<バージョン>-x86_64_aarch64-linux-gnu.tar.xz
また、開発者がGCC ARMツールチェーンを作成する場合、インストール - GCC#クロスコンパイラ向けGCCツールチェーンのインストールを参照すること。
Qt 6を使用してクロスコンパイルする場合、x86 64向けのQtライブラリも必要となる。
そのため、Qtオンラインインストーラからx86 64向けのQtライブラリをインストールする。
(Qt 6のソースコードからx86 64向けのQt 6ライブラリをビルドおよびインストールしてもよいが、煩雑なため推奨しない)
wget http://download.qt.io/official_releases/online_installers/qt-unified-linux-x64-online.run
ダウンロードしたファイルに実行権限を付加する。
chmod +x qt-unified-linux-x64-online.run
次に、GCCおよびmake等の開発に付随するライブラリをインストールする。
# RHEL sudo dnf groupinstall "Development tools" # SUSE sudo zypper install --type pattern devel_basis
Qtオンラインインストーラを実行する。
./qt-unified-linux-x64-online.run
Qtのインストール画面に従って、Qt 6をインストールする。
PinePhoneの設定
Qtのクロスコンパイルの手順において、SSH接続ができることが必須のため、SSH Serverをインストールおよび設定する。
# Mobian sudo apt-get install openssh-server # Manjaro sudo pacman -S openssh
必要に応じて、公開鍵認証を行う場合は、設定 - SSHの公開鍵認証を参照すること。
SSH Serverの自動起動設定および開始する。
sudo systemctl enable ssh sudo systemctl restart ssh
MobianまたはManjaroをアップデートする。
# Mobian sudo apt-get update sudo apt-get dist-upgrade sudo systemctl reboot # Manajro sudo pacman -Syyu sudo systemctl reboot
不要なライブラリをアンインストールする。
Qt6 D-Busがインストールされている場合、Qt SharedToolsライブラリのクロスコンパイルがエラーになることに注意する。
sudo pacman -R --needed qt6-base
Qtライブラリをクロスコンパイルするために必要なライブラリをインストールする。
Qtライブラリのビルド設定によっては、不要なパッケージも含まれている。
# Mobian sudo apt-get install unzip ccache pkgconf-bin pkg-config libpkgconf3 pkgconf build-essential make cmake gcc gfortran gdb gdbserver python3 libgtk-3-dev \ libc6 libc6-dev linux-libc-dev glibc-source libc-dev-bin libc-devtools libglib2.0-0 libglib2.0-dev libglib2.0-dev-bin \ libgmp-dev libmpc-dev libmpfr-dev libisl-dev gconf2 gconf2-common libgconf2-dev \ libdbus-1-3 libdbus-1-dev libdbus-c++-bin libdbus-c++-dev libdbus-cpp-dev libdbus-glib-1-dev libdbus-glib-1-dev-bin libsctp1 libsctp-dev \ libatspi2.0-0 libatspi2.0-dev at-spi2-core gir1.2-atspi-2.0 libatk1.0-dev libatkmm-1.6-dev libatk-bridge2.0-dev \ libzstd1 libzstd-dev libinput-bin libinput-dev libts0 libts-bin libts-dev libmtdev1 libmtdev-dev libevdev2 libevdev-dev libicu-dev icu-devtools \ libblkid1 libblkid-dev libffi8 libffi-dev libmount1 libmount-dev libudev1 libudev-dev libhd21 libhd-dev libtsm-dev \ pcre2-utils libpcre2-32-0 libpcre2-dev libselinux1 libselinux1-dev libsepol2 libsepol-dev libwacom9 libwacom-dev \ libproxy-dev liblttng-ust1 liblttng-ust-common1 liblttng-ust-dev libb2-1 libb2-dev libsdl2-dev libsystemd-dev \ libfontconfig1 libfontconfig-dev libfontconfig1-dev libjpeg-dev libjpeg62-turbo libjpeg62-turbo-dev libjpeg-dev libasound2 libasound2-dev \ sqlite3 libsqlite3-0 libsqlite3-dev libssl3 libssl-dev libnss3 libnss3-dev libxslt1.1 libxslt1-dev libpugixml1v5 libpugixml-dev \ libbz2-dev libatkmm-1.6-dev libsrtp2-dev libsnappy-dev re2c libpoppler-dev libmd4c-dev libmd4c-html0-dev liblitehtml0 liblitehtml-dev \ libxkbcommon-dev libxcb-xinerama0 libxcb-xinerama0-dev libglut3.12 libglut-dev \ libwayland-bin libwayland-dev libwayland-egl1 libwayland-egl++1 libwayland-egl1-mesa libwayland-egl-backend-dev \ libwayland-client++1 libwayland-client-extra++1 libwayland-cursor++1 wayland-scanner++ wayland-protocols waylandpp-dev \ libosmesa6-dev mesa-common-dev libopengl-dev libgl-dev libglm-dev libgl1-mesa-dev libgle3-dev libgles-dev libgles2-mesa-dev libegl-dev libegl1-mesa-dev \ libgegl-dev libglu1-mesa libglu1-mesa-dev libglw1-mesa-dev libglfw3-dev libglew-dev libglx-dev libgbm-dev libdrm-dev libdirectfb-dev \ libglvnd-dev libglvnd-core-dev libglut-dev libopenal-dev libalut-dev \ libweston-10-0 libweston-10-dev \ libvulkan1 libvulkan-dev \ # Vulkanを使用する場合 libclang-dev libclang-cpp-dev clang-tools clang-format \ # QDoc, Clangベースのlupdateパーサーを使用する場合はインストールする llvm-dev llvm-runtime \ # QDoc, Clangベースのlupdateパーサーを使用する場合はインストールする libassimp5 libassimp-dev \ # 現在(2023/11)において、libassimp-devをインストールするとlibdracoライブラリの探索に失敗するため、 \ # libassimp-devはインストールしない libdouble-conversion3 libdouble-conversion-dev \ # 現在(2023/11)において、libdouble-conversion-devをインストールするとdouble-conversionのヘッダファイルの探索に失敗するため、 \ # libdouble-conversion-devはインストールしない linux-headers-arm64 linux-headers-6.1-sunxi64 # 不要の可能性あり # Manjaro sudo pacman -S --needed base-devel util-linux-libs glib2 cmake unzip pkg-config gdb gdb-common gdbm gcc gcc-libs gcc-fortran python3 \ gmp libmpc mpfr libisl ccache icu lksctp-tools python-atspi zstd libinput mtdev libevdev libffi pcre pcre2 gconfmm \ libwacom assimp fontconfig dbus dbus-c++ nss libxkbcommon xcb-util-cursor libxinerama xorg-xinput xcb-util-xrm alsa-lib \ pugixml libxslt openssl libproxy libb2 lttng-ust libglvnd systemd double-conversion \ clang llvm \ # QtDocをインストールする場合 wayland wayland-utils wayland-protocols egl-wayland waylandpp waylandpp wlc wayfire glew-wayland glfw-wayland libva1 \ mesa mesa-utils glu vulkan-headers qt6ct
Manjaroにおいて、マルチメディア関連やBluetooth等を使用する場合、下表に示す任意のパッケージをインストールする。
Mobianの場合、上記のセクションにあるRaspberry Piの表も参照すること。
機能 | インストールするライブラリ | configureスクリプトのオプション |
---|---|---|
Bluetooth | bluez bluez-tools libbluetooth-dev | |
画像 | libjpeg-dev libpng-dev libtiff-dev libmng-dev libwebp-dev | |
コーデック | libavcodec-dev libavformat-dev libavutil-dev libavdevice-dev libavfilter-dev libswscale-dev libswresample-dev libpostproc-dev libv4l-dev libxvidcore-dev libx264-dev libx265-dev |
|
マルチメディア | libwmf-dev libgstreamer1.0-0 libgstreamer1.0-dev libgstreamermm-1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly gstreamer1.0-plugins-bad libgstreamer-plugins-bad1.0-dev gstreamer1.0-libav gstreamer1.0-pulseaudio gstreamer1.0-tools gstreamer1.0-alsa gstreamer1.0-x gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 libwayland-dev(Wayland開発パッケージは、gstreamerヘッダで必要) |
|
ALSAオーディオ | libasound2-dev | |
Pulseオーディオ | pulseaudio libpulse-dev | |
OpenALオーディオ | libopenal-data libopenal1 libopenal-dev libsndio7.0 libsndio-dev | |
Text to Speech | flite1-dev libspeechd-dev | |
シリアルポート | libserialport-dev | |
センサ | libsensors-dev libsensors4-dev ※要調査 | |
GPS | libgps-dev ※要調査 | |
データベース | unixodbc unixodbc-common unixodbc-dev (ODBC) libsqlite3-dev (SQLite) libpq-dev(PostgreSQL) libmariadbclient-dev(MariaDB / MySQL) |
|
プリンタ | libcups2-dev | |
Wayland | libwayland-dev | |
X11 | libfontconfig-dev libfontconfig1-dev libfreetype6-dev libx11-dev libx11-xcb-dev libsm-dev libice-dev libxcb1-dev libxext-dev libxi-dev libxcomposite-dev libxcursor-dev libxtst-dev libxrandr-dev libxfixes-dev libxrender-dev libxdamage-dev libxkbfile-dev libxcb-glx0-dev libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev libxcb-util0-dev libxcb-xinerama0-dev libxcb-xkb-dev libxkbcommon-dev libxkbcommon-x11-dev libxcb-damage0-dev libxcb-composite0-dev libxcb-record0-dev libxcb-present-dev libxcb-res0-dev libxcb-render0-dev libxcb-xinput-dev libxcb-xv0-dev libxcb-xtest0-dev libxcb-cursor-dev libxcb-util-dev libxcb-ewmh-dev libxcb-xvmc0-dev libxcb-imdkit-dev libxcb-xrm-dev libxcb-dri2-0-dev libxcb-dri3-dev libxcb-dpms0-dev libxcb-xf86dri0-dev |
|
WebEngine | 必須 : flex bison gperf libre2-dev libnss3-dev libopenjp2-7-dev libdrm-dev libxshmfence-dev python3-html5lib オプション1 : libxml2-dev libxslt1-dev libminizip-dev libjsoncpp-dev liblcms2-dev libpci-dev libpciaccess-dev libevent-dev libev-dev libev-libevent-dev libevhtp-dev libuev-dev libuv1-dev libprotobuf-dev protobuf-compiler オプション2(不安定なため注意すること) : libopus-dev libvpx-dev |
|
アクセシビリティ | libatspi2.0-dev | |
SCTP | libsctp1 libsctp-dev | -sctp |
機能 | インストールするライブラリ | configureスクリプトのオプション |
---|---|---|
Bluetooth | bluez bluez-tools bluez-libs bluez-utils | |
画像 | openjpeg2 libjpeg-turbo libpng libtiff libmng libwebp | |
マルチメディア | libwmf gstreamer gstreamermm gst-plugins-base gst-plugins-base-libs gst-plugins-good gst-plugins-bad gst-plugins-bad-libs gst-plugins-ugly gst-libav gst-plugin-wpe gst-plugin-pipewire gst-plugin-gtk qt-gstreamer gst-plugin-qmlgl gst-plugin-opencv |
|
ALSAオーディオ | alsa-lib | |
Pulseオーディオ | pulseaudio-alsa | |
OpenAL | openal | |
Text to Speech | flite | |
シリアルポート | libserialport | |
センサ | sensorfw | |
データベース | postgresql-libs libpqxx (PostgreSQL) mariadb-clients mariadb-libs (MariaDB) unixodbc libiodbc (ODBC) |
|
プリンタ | libcups | |
Wayland (X11) | xorg-xwayland | |
X11 | ||
WebEngine | 必須 : flex bison gperf readline nss libdrm オプション1 : libxml2 libxml++ libxslt minizip jsoncpp lcms2 libevent protobuf protobuf-c オプション2(不安定なため注意すること) : opus libvpx |
|
アクセシビリティ | at-spi2-core at-spi2-atk | |
SCTP | lksctp-tools | -sctp |
- 上表のライブラリを全てインストールする場合
sudo pacman -S --needed bluez bluez-libs openjpeg2 libjpeg-turbo libpng libtiff libmng \ gstreamer gstreamermm gst-plugins-base gst-plugins-base-libs gst-plugins-good \ gst-plugins-bad gst-plugins-bad-libs gst-plugins-ugly gst-libav gst-plugin-wpe \ gst-plugin-pipewire gst-plugin-gtk qt-gstreamer gst-plugin-qmlgl gst-plugin-opencv \ alsa-lib pulseaudio-alsa openal \ flite libserialport sensorfw \ unixodbc sqlite libcups \ xorg-xwayland flex bison gperf readline nss libdrm libxml2 libxml++ libxslt minizip jsoncpp \ lcms2 libevent protobuf protobuf-c opus libvpx at-spi2-core at-spi2-atk lksctp-tools
次のセクションにおいて、rsyncコマンドを使用してLinux PCとPinePhoneのファイルを同期する。
しかし、同期するファイルには、スーパユーザ権限が必要なものがある。
そのため、一般ユーザでも全てのファイルを同期できるように、/etc/sudoersファイルに以下の設定を追記する。
以下の設定により、rsyncコマンドは、必要に応じてスーパユーザ権限で実行される。
echo "$USER ALL=NOPASSWD:$(which rsync)" | sudo tee --append /etc/sudoers
システムルートディレクトリの設定
Linux PCで、PinePhone向けのQtソフトウェアをクロスコンパイルできるように開発環境を設定する。
PinePhone上でネイティブにコンパイルすることもできるが、Linux PCの方がスループットが良い。
Linux PC上に開発用ディレクトリを作成する。
また、PinePhoneのいくつかのルートディレクトリと同期する必要があるため、システムルートディレクトリも作成する。
mkdir -p ~/Program/Qt_Embedded/sysroot \ ~/Program/Qt_Embedded/sysroot/usr \ ~/Program/Qt_Embedded/sysroot/usr/share
rsync
コマンドを使用して、Raspberry Piに存在するいくつかのディレクトリから、ファイルをダウンロードする。
rsync -avz --rsync-path="sudo rsync" --delete --rsh="ssh -p <ポート番号> -i <秘密鍵のフルパス>" <PinePhoneのユーザ名>@<PinePhoneのホスト名またはIPアドレス>:/lib ~/Program/Qt_Embedded/sysroot rsync -avz --rsync-path="sudo rsync" --delete --rsh="ssh -p <ポート番号> -i <秘密鍵のフルパス>" <PinePhoneのユーザ名>@<PinePhoneのホスト名またはIPアドレス>:/usr/include ~/Program/Qt_Embedded/sysroot/usr rsync -avz --rsync-path="sudo rsync" --delete --rsh="ssh -p <ポート番号> -i <秘密鍵のフルパス>" <PinePhoneのユーザ名>@<PinePhoneのホスト名またはIPアドレス>:/usr/lib ~/Program/Qt_Embedded/sysroot/usr rsync -avz --rsync-path="sudo rsync" --delete --rsh="ssh -p <ポート番号> -i <秘密鍵のフルパス>" <PinePhoneのユーザ名>@<PinePhoneのホスト名またはIPアドレス>:/usr/share/pkgconfig ~/Program/Qt_Embedded/sysroot/usr/share
Qtのソースコードのダウンロード
- Qt Everywhere (推奨)
- Qtの公式Webサイトにアクセスして、Qt 6のソースコードをダウンロードする。
wget https://download.qt.io/official_releases/qt/6.x/6.x.x/single/qt-everywhere-src-6.x.x.tar.xz
tar xf qt-everywhere-opensource-src-6.x.x.tar.gz
- Githubの使用
- GithubからQt 6のソースコードを個別にダウンロードする。
git clone https://github.com/qt/qt5.git qt6
- ダウンロードしたスーパーリポジトリに移動する。
cd qt6
git checkout <Qtのバージョン>
- または
git checkout <Qtのショートバージョン>
init-repository
コマンドは、Qtが提供する指定したモジュールのソースコードを取得するためのツールである。- スーパーリポジトリは小さく、全てのモジュール(ライブラリ)はgit submodulesとして保持されている。
- 利用可能な全てのモジュールについてはこちらのWebサイト、ツールについては
init-repository --help
コマンドまたはこちらのWebサイトを参照すること。 ./init-repository --module-subset=essential,qtsvg,qtvirtualkeyboard,qtquickcontrols
./init-repository -f --module-subset=qtquick3d,qtquicktimeline,qtwayland
# 必要な場合は個別に追加ダウンロードする
- GithubからQt 6のソースコードを個別にダウンロードする。
Qtの設定
Qtのソースコードがあるディレクトリにおいて、qtbase/mkspecs/devices/linux-pinephone-g++ディレクトリを作成する。
mkdir <Qtのソースコードがあるディレクトリ>/qtbase/mkspecs/devices/linux-pinephone-g++
次に、<Qtのソースコードがあるディレクトリ>/qtbase/mkspecs/devices/linux-pinephone-g++/qplatformdefs.hファイルを以下の内容で作成する。
vi <Qtのソースコードがあるディレクトリ>/qtbase/mkspecs/devices/linux-pinephone-g++/qplatformdefs.h
// qplatformdefs.hファイル
#include "../../linux-g++/qplatformdefs.h"
さらに、<Qtのソースコードがあるディレクトリ>/qtbase/mkspecs/devices/linux-pinephone-g++/qmake.confファイルを以下の内容で作成する。
vi <Qtのソースコードがあるディレクトリ>/qtbase/mkspecs/devices/linux-pinephone-g++/qmake.conf
# qmake.confファイル
# qmake configuration for the PinePhone(Based A20_OlinuxinO boards)
include(../common/linux_device_pre.conf)
#QT_QPA_DEFAULT_PLATFORM = eglfs # 不要の可能性があるため要調査
QT_QPA_DEFAULT_PLATFORM = wayland # 不要の可能性があるため要調査
SYSROOT_INC = $$[QT_SYSROOT]/usr/include
SYSROOT_LIB = $$[QT_SYSROOT]/usr/lib
# Extra stuff (OpenGL, DirectFB, ...)
QMAKE_INCDIR_EGL = $$[SYSROOT_INC] \
$$[SYSROOT_INC]/aarch64-linux-gnu \
$$[SYSROOT_INC]/GL \
$$[SYSROOT_INC]/EGL \
$$[SYSROOT_INC]/GLES \
$$[SYSROOT_INC]/GLES2 \
$$[SYSROOT_INC]/GLES3 \
$$[SYSROOT_INC]/GLFW
QMAKE_LIBDIR_EGL = $$[SYSROOT_LIB] \
$$[SYSROOT_LIB]/aarch64-linux-gnu
QMAKE_INCDIR_OPENGL_ES2 = $$[QMAKE_INCDIR_EGL]
QMAKE_LIBDIR_OPENGL_ES2 = $${QMAKE_LIBDIR_EGL}
QMAKE_INCDIR_OPENVG = $${QMAKE_INCDIR_EGL} # 不要の可能性があるため要調査
QMAKE_LIBDIR_OPENVG = $${QMAKE_LIBDIR_EGL} # 不要の可能性があるため要調査
QMAKE_LIBS_EGL = -lEGL
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 $${QMAKE_LIBS_EGL}
QMAKE_LIBS_OPENVG = -lOpenVG $${QMAKE_LIBS_EGL} # 不要の可能性があるため要調査
# modifications to gcc-base.conf
QMAKE_CFLAGS = -march=armv8-a -mtune=cortex-a53 # PinePhoneの場合
#QMAKE_CFLAGS = -march=armv8-a -mtune=cortex-a72 -lts # PinePhone Proの場合
QMAKE_CFLAGS_RELEASE += -O3
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
QMAKE_CXXFLAGS_RELEASE += -O3
QMAKE_LIBS += -lrt -lpthread -ldl -lz # Linaro GCC ARM 7.5 ツールチェーンを使用する場合
#QMAKE_LIBS += -lrt -lpthread -ldl # GCC ARM 8.3 以降のツールチェーンを使用する場合
DISTRO_OPTS += aarch64
DISTRO_OPTS += deb-multi-arch # Mobian OSを使用する場合は指定する
# 他のOSを使用する場合は、削除またはコメントアウトする
# Preferred eglfs backend
EGLFS_DEVICE_INTEGRATION = eglfs_mali
include(../common/linux_arm_device_post.conf)
load(qt_config)
CMakeツールチェーンファイルの作成
ターゲット向けQt 6ライブラリのビルドで使用するCMakeツールチェーンファイルを作成する。
vi ToolChain_for_PinePhone.cmake
# ToolChain_for_PinePhone.cmake
# Manjaro ARM向け
cmake_minimum_required(VERSION 3.18)
include_guard(GLOBAL)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
# Set path to System Root.
set(TARGET_SYSROOT <PinePhoneのシステムルートディレクトリ>)
set(CMAKE_SYSROOT ${TARGET_SYSROOT})
# Set path to package config.
#set(ENV{PKG_CONFIG_PATH} ${TARGET_SYSROOT}/usr/lib/pkgconfig)
#set(ENV{PKG_CONFIG_LIBDIR} ${TARGET_SYSROOT}/usr/lib/pkgconfig:${TARGET_SYSROOT}/usr/share/pkgconfig)
set(ENV{PKG_CONFIG_PATH} $PKG_CONFIG_PATH:${TARGET_SYSROOT}/usr/lib/pkgconfig)
set(ENV{PKG_CONFIG_LIBDIR} /usr/lib64/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig:${TARGET_SYSROOT}/usr/lib/pkgconfig:${TARGET_SYSROOT}/usr/share/pkgconfig)
set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})
# Set path to Cross Compiler.
set(CMAKE_C_COMPILER <クロスコンパイル向けGCCまたはClangのパス>)
set(CMAKE_CXX_COMPILER <クロスコンパイル向けG++またはClang++のパス>)
#set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wl,-rpath-link,${TARGET_SYSROOT}/usr/lib -L${TARGET_SYSROOT}/usr/lib")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wl,-rpath-link,${TARGET_SYSROOT}/usr/lib -L${TARGET_SYSROOT}/usr/lib")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${TARGET_SYSROOT}/usr/include")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")
set(QT_COMPILER_FLAGS "-march=armv8-a -mtune=cortex-a53")
#set(QT_COMPILER_FLAGS_RELEASE "-O2 -pipe")
set(QT_COMPILER_FLAGS_RELEASE "-O3")
set(QT_LINKER_FLAGS "-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_THREAD_LIBS_INIT "-lrt -lpthread -ldl")
set(CMAKE_HAVE_THREADS_LIBRARY 1)
set(CMAKE_USE_WIN32_THREADS_INIT 0)
set(CMAKE_USE_PTHREADS_INIT 1)
set(THREADS_PREFER_PTHREAD_FLAG ON)
# Set ODBC
set(ODBC_LIBRARY ${TARGET_SYSROOT}/usr/lib/libodbc.so)
# Set WMF
set(WMF_STRMIIDS_LIBRARY ${TARGET_SYSROOT}/usr/lib/libwmf.so)
set(WMF_AMSTRMID_LIBRARY ${TARGET_SYSROOT}/usr/lib/libwmf.so)
set(WMF_DMOGUIDS_LIBRARY ${TARGET_SYSROOT}/usr/lib/libwmf.so)
set(WMF_MSDMO_LIBRARY ${TARGET_SYSROOT}/usr/lib/libwmf.so)
set(WMF_OLE32_LIBRARY ${TARGET_SYSROOT}/usr/lib/libwmf.so)
set(WMF_OLEAUT32_LIBRARY ${TARGET_SYSROOT}/usr/lib/libwmf.so)
set(WMF_MF_LIBRARY ${TARGET_SYSROOT}/usr/lib/libwmf.so)
set(WMF_MFUUID_LIBRARY ${TARGET_SYSROOT}/usr/lib/libwmf.so)
set(WMF_MFPLAT_LIBRARY ${TARGET_SYSROOT}/usr/lib/libwmf.so)
set(WMF_MFCORE_LIBRARY ${TARGET_SYSROOT}/usr/lib/libwmf.so)
set(WMF_PROPSYS_LIBRARY ${TARGET_SYSROOT}/usr/lib/libwmf.so)
# Set AssImp
set(ASSIMP_LIBRARY ${TARGET_SYSROOT}/usr/lib/libassimp.so)
# ToolChain_for_PinePhone.cmake
# Mobian向け
cmake_minimum_required(VERSION 3.18)
include_guard(GLOBAL)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
# Set path to System Root.
set(TARGET_SYSROOT <PinePhoneのシステムルートディレクトリ>)
set(CMAKE_SYSROOT ${TARGET_SYSROOT})
# Set path to package config.
set(ENV{PKG_CONFIG_PATH} $PKG_CONFIG_PATH:${TARGET_SYSROOT}/usr/lib/pkgconfig:${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/pkgconfig)
set(ENV{PKG_CONFIG_LIBDIR} /usr/lib64/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig:${TARGET_SYSROOT}/usr/lib/pkgconfig:${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/pkgconfig:${TARGET_SYSROOT}/usr/share/pkgconfig)
set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})
# Set path to Cross Compiler.
set(CMAKE_C_COMPILER <クロスコンパイル向けGCCまたはClangのパス>)
set(CMAKE_CXX_COMPILER <クロスコンパイル向けG++またはClang++のパス>)
# Set Linker Flags for GCC.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${TARGET_SYSROOT}/usr/include")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_INIT "-Wl,-rpath-link,${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu")
set(CMAKE_MODULE_LINKER_FLAGS_INIT "-Wl,-rpath-link,${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu")
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-Wl,-rpath-link,${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu")
# Set Compiler Flags.
set(QT_COMPILER_FLAGS "-march=armv8-a -mtune=cortex-a53")
set(QT_COMPILER_FLAGS_RELEASE "-O3")
#set(QT_COMPILER_FLAGS_RELEASE "-O2 -pipe")
set(QT_LINKER_FLAGS "-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed")
set(CMAKE_THREAD_LIBS_INIT "-lrt -lpthread -ldl")
set(CMAKE_HAVE_THREADS_LIBRARY 1)
set(CMAKE_USE_WIN32_THREADS_INIT 0)
set(CMAKE_USE_PTHREADS_INIT 1)
set(THREADS_PREFER_PTHREAD_FLAG ON)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
# Set GL, EGL, GLESv2
set(GL_INC_DIR ${TARGET_SYSROOT}/usr/include)
set(GL_LIB_DIR ${TARGET_SYSROOT}:${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/:${TARGET_SYSROOT}/usr:${TARGET_SYSROOT}/usr/lib)
set(OPENGL_INCLUDE_DIR ${TARGET_SYSROOT}/usr/include)
set(OPENGL_opengl_LIBRARY ${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/libOpenGL.so)
set(EGL_INCLUDE_DIR ${TARGET_SYSROOT}/usr/include)
set(EGL_LIBRARY ${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/libEGL.so)
set(GLESv2_INCLUDE_DIR ${TARGET_SYSROOT}/usr/include)
set(GLESv2_LIBRARY ${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/libGLESv2.so)
set(gbm_INCLUDE_DIR ${TARGET_SYSROOT}/usr/include)
set(gbm_LIBRARY ${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/libgbm.so)
set(Libdrm_INCLUDE_DIR ${TARGET_SYSROOT}/usr/include)
set(Libdrm_LIBRARY ${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/libdrm.so)
#set(XCB_XCB_INCLUDE_DIR ${TARGET_SYSROOT}/usr/include)
#set(XCB_XCB_LIBRARY ${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/libxcb.so)
# Set ODBC
set(ODBC_LIBRARY ${TARGET_SYSROOT}/usr/lib/libodbc.so)
# Set WMF
set(WMF_STRMIIDS_LIBRARY ${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/libwmf.so)
set(WMF_AMSTRMID_LIBRARY ${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/libwmf.so)
set(WMF_DMOGUIDS_LIBRARY ${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/libwmf.so)
set(WMF_MSDMO_LIBRARY ${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/libwmf.so)
set(WMF_OLE32_LIBRARY ${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/libwmf.so)
set(WMF_OLEAUT32_LIBRARY ${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/libwmf.so)
set(WMF_MF_LIBRARY ${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/libwmf.so)
set(WMF_MFUUID_LIBRARY ${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/libwmf.so)
set(WMF_MFPLAT_LIBRARY ${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/libwmf.so)
set(WMF_MFCORE_LIBRARY ${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/libwmf.so)
set(WMF_PROPSYS_LIBRARY ${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/libwmf.so)
Qtのクロスビルド
Qt 6をクロスビルドするため、クロスビルド向けディレクトリを作成する。
mkdir build && cd build
Qt 6のクロスビルド向けの設定を行う。
# Manjaro ARM向け
# Wayland Scannerのパスを設定
export PATH="/<Wayland Scannerのインストールディレクトリ>/bin:$PATH"
export LD_LIBRARY_PATH="/<Wayland Scannerのインストールディレクトリ>/lib64:$LD_LIBRARY_PATH"
# PinePhoneのシステムルートディレクトリを設定
export SYSROOT=<PinePhoneのシステムルートディレクトリ>
# Pkg-Configの設定
export PKG_CONFIG_PATH="$SYSROOT/usr/lib/pkgconfig:$SYSROOT/usr/lib/aarch64-linux-gnu/pkgconfig"
export PKG_CONFIG_LIBDIR="$SYSROOT/usr/lib/pkgconfig:$SYSROOT/usr/lib/aarch64-linux-gnu/pkgconfig:$SYSROOT/usr/share/pkgconfig"
# コンパイラの設定
export CROSS_COMPILER="/<GCC ARMツールチェーンのインストールディレクトリ>/bin/aarch64-linux-gnu-"
# または
# export CROSS_COMPILER="/<GCC ARMツールチェーンのインストールディレクトリ>/bin/aarch64-unknown-linux-gnu-"
cmake -G Ninja \
<Qt 6のソースコードがあるディレクトリ> \
-DCMAKE_BUILD_TYPE=Release \
-DINPUT_opengl=es2 \
-DQT_FEATURE_opengles2=ON \
-DQT_FEATURE_opengles3=ON \
-DCMAKE_TOOLCHAIN_FILE=<CMakeデバイスファイルのパス> \
-DQT_BUILD_TOOLS_WHEN_CROSSCOMPILING=ON \
-DQT_QMAKE_TARGET_MKSPEC=devices/linux-pinephone-g++ \
-DQT_QMAKE_DEVICE_OPTIONS=CROSS_COMPILE=$CROSS_COMPILER \
-DQT_BUILD_EXAMPLES=OFF \
-DQT_BUILD_TESTS=OFF \
-DBUILD_qtdoc=OFF \ # QtDocをインストールしない場合
-DBUILD_qtwebengine=OFF \ # QtWebEngineをインストールしない場合
-DBUILD_qtwebview=OFF \ # QtWebViewをインストールしない場合
-DBUILD_qtwebchannel=OFF \ # QtWebChannelをインストールしない場合
-DFEATURE_clang=ON \ # QtDocをインストールする場合
-DFEATURE_clangcpp=ON \ # QtDocをインストールする場合
-DCMAKE_SYSROOT=$SYSROOT \
-DQT_HOST_PATH=<x86 64向けQt 6のパスのトップディレクトリ 例: /home/user/Qt/6.x.x/gcc_64> \
-DQT_HOST_PATH_CMAKE_DIR=/<x86 64向けQt 6のパスのcmakeディレクトリ 例: /home/user/Qt/6.x.x/gcc_64/lib/cmake> \
-DCMAKE_STAGING_PREFIX=<PinePhone向けQt 6ライブラリを配置するディレクトリ> \
-DCMAKE_INSTALL_PREFIX=<Qtソフトウェアを配置するディレクトリ> \
-DCMAKE_PREFIX_PATH=$SYSROOT/usr/lib
# Mobian向け
# Wayland Scannerのパスを設定
export PATH="/<Wayland Scannerのインストールディレクトリ>/bin:$PATH"
export LD_LIBRARY_PATH="/<Wayland Scannerのインストールディレクトリ>/lib64:$LD_LIBRARY_PATH"
# PinePhoneのシステムルートディレクトリを設定
export SYSROOT=<PinePhoneのシステムルートディレクトリ>
# コンパイラの設定
export CROSS_COMPILER="/<GCC ARMツールチェーンのインストールディレクトリ>/bin/aarch64-linux-gnu-"
cmake -G Ninja \
<Qt 6のソースコードがあるディレクトリ> \
-DCMAKE_BUILD_TYPE=Release \
-DINPUT_opengl=es2 \
-DQT_FEATURE_opengles2=ON \
-DQT_FEATURE_opengles3=ON \
-DQT_QPA_DEFAULT_PLATFORM=wayland \
-DCMAKE_TOOLCHAIN_FILE=<CMakeデバイスファイルのパス> \
-DQT_BUILD_TOOLS_WHEN_CROSSCOMPILING=ON \
-DQT_QMAKE_TARGET_MKSPEC=devices/linux-pinephone-g++ \
-DQT_QMAKE_DEVICE_OPTIONS=CROSS_COMPILE=$CROSS_COMPILER \
-DQT_BUILD_EXAMPLES=OFF \
-DQT_BUILD_TESTS=OFF \
-DBUILD_qtdoc=OFF \ # QtDocをインストールしない場合
-DBUILD_qtwebengine=OFF \ # QtWebEngineをインストールしない場合
-DBUILD_qtwebview=OFF \ # QtWebViewをインストールしない場合
-DBUILD_qtwebchannel=OFF \ # QtWebChannelをインストールしない場合
-DFEATURE_clang=ON \ # QtDocをインストールする場合
-DFEATURE_clangcpp=ON \ # QtDocをインストールする場合
-DCMAKE_SYSROOT=$SYSROOT \
-DQT_HOST_PATH=<x86 64向けQt 6のパスのトップディレクトリ 例: /home/user/Qt/6.x.x/gcc_64> \
-DQT_HOST_PATH_CMAKE_DIR=/<x86 64向けQt 6のパスのcmakeディレクトリ 例: /home/user/Qt/6.x.x/gcc_64/lib/cmake> \
-DCMAKE_STAGING_PREFIX=<PinePhone向けQt 6ライブラリを配置するディレクトリ> \
-DCMAKE_INSTALL_PREFIX=<Qtソフトウェアを配置するディレクトリ> \
-DCMAKE_PREFIX_PATH=$SYSROOT/usr/lib/aarch64-linux-gnu
Qt 6をクロスビルドおよびインストールする。
また、Ninjaのビルドエラーの出力は、後方で起きている可能性があるため、テキストファイル等に一時的に出力した方がよい。
cmake --build . --parallel $(nproc) または cmake --build . --parallel $(nproc) > compile.txt 2>&1 cmake --install .
ビルドエラー関連
ビルドエラー : GCC 13を使用する場合
GCC 13を使用してQt 6をビルドする場合、以下に示すようなエラーが出力される場合がある。
バグレポートURL : https://bugreports.qt.io/browse/QTBUG-111604?focusedCommentId=718489
# エラー出力 1 error: 'uint32_t' is not a member of 'std'; did you mean 'wint_t'? # エラー出力 2 error: 'FeatureType' does not name a type; did you mean 'ToFeatureType'?
この時、以下に示すファイルを編集する。
// qt-everywhere-src-6.x.x/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cppファイル
// 53行目
// 変更前
#include <stdint.h>
// 変更後
#include <cstdint>
// qt-everywhere-src-6.x.x/qtquick3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cppファイル
// 53行目
// 変更前
#include <stdint.h>
// 変更後
#include <cstdint>
// qt-everywhere-src-6.x.x/qtquick3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXTokenizer.cppファイル
// 58行目
// 変更前
#include <stdint.h>
// 変更後
#include <cstdint>
ビルドエラー関連 : X Keyboardに関するエラー
コンパイル時において、以下に示すようなエラーが出力される場合がある。
error: XKB_KEY_dead_lowline was not declared in this scope; did you mean XKB_KEY_dead_belowring? または error: 'XKB_KEY_dead_lowline' was not declared in this scope; did you mean 'XKB_KEY_dead_belowring'?
この時、cmake
コマンドの実行時において、-DFEATURE_xkbcommon=OFF
オプションを付加する。
ビルドエラー関連 : Qt Toolのqhelpgeneratorに関するエラー 1
cmake
コマンドの実行時において、以下に示すようなエラーが出力される場合がある。
-- Configuring submodule 'qttools' CMake Error at qttools/src/assistant/qhelpgenerator/CMakeLists.txt:66 (add_dependencies): Cannot add target-level dependencies to non-existent target "qhelpgenerator". The add_dependencies works for top-level logical targets created by the add_executable, add_library, or add_custom_target commands. If you want to add file-level dependencies see the DEPENDS option of the add_custom_target and add_custom_command commands.
この時、以下に示すファイルを編集する。
vi /<Qt 6のソースコードがあるディレクトリ>/qttools/src/assistant/qhelpgenerator/CMakeLists.txt
# /<Qt 6のソースコードがあるディレクトリ>/qttools/src/assistant/qhelpgenerator/CMakeLists.txtファイル 66行目
# 編集前
add_dependencies(qhelpgenerator ${needed_plugins})
# 編集後
#add_dependencies(qhelpgenerator ${needed_plugins})
ビルドエラー関連 : Qt Toolのqhelpgeneratorに関するエラー 2
ビルド時において、以下に示すようなエラーが出力される場合がある。
error: 'google::protobuf::FileDescriptor::Syntax google::protobuf::FileDescriptor::syntax() const'
この時、以下に示すcmake
コマンドのオプションを付加する。
cmake -G Ninja \ # ...略 -DBUILD_qtgrpc # ...略
Qt 6ライブラリのアップロード
クロスビルドしたQtライブラリを、PinePhoneにデプロイする。
まず、PinePhone向けQt 6ライブラリのインストールディレクトリに存在する全てのファイルを、PinePhoneの任意のディレクトリ(例. ~/InstallSoftware/Qt_6_x_xディレクトリ)に同期させる。
rsync -avz --rsh="ssh -p <ポート番号> -i <秘密鍵のフルパス>" \ <PinePhone向けQt 6ライブラリのインストールディレクトリ> <PinePhoneのユーザ名>@<PinePhoneのホスト名またはIPアドレス>:/home/<PinePhoneのユーザ名>/InstallSoftware/Qt_6_x_x
※注意
PinePhoneにアップロードしたQtライブラリの所有者がrootになっている場合があるため、
以下のコマンドを実行して、所有者をローカルユーザに変更する必要がある。
sudo chown -R <ユーザ名>:<グループ名> ~/InstallSoftware/Qt_6_x_x
Qt Creatorの設定
キットの設定
Qt Creatorを起動して、キットの設定を行う。
- QMakeの設定
- クロスコンパイルしたQt 6のインストールディレクトリに移動する。
- binディレクトリにあるhost-qmakeファイルのシンボリックファイル(ここでは、qmake-hostファイルとする)を作成する。
ln -s host-qmake qmake-host
- キットの作成
- [編集] - [設定]を選択して、[設定]画面を開く。
- [設定]画面左にある[キット] - [設定]画面右の[Qtバージョン]タブから[追加]ボタンを押下する。
- 上記で作成したシンボリックファイルを選択する。
- [設定]画面左にある[キット] - [設定]画面右の[キット]タブから[追加]ボタンを押下する。
- [デバイスの種類]プルダウンから、[Remote Linux Device]を選択する。
- [デバイス]プルダウンから、[設定]画面左にある[デバイス]で作成したターゲットを選択する。
- [ビルドデバイス]プルダウンから、[ローカルPC]を選択する。
- [Sysroot]項目に、PinePhoneのシステムルートディレクトリのパスを入力する。
- [コンパイラ]項目の[C]プルダウンから、C向けのクロスコンパイラを選択する。
- [コンパイラ]項目の[C++]プルダウンから、C++向けのクロスコンパイラを選択する。
- [GDB]プルダウンから、クロスコンパイラ向けGDBを選択する。
- [Qtバージョン]プルダウンから、上記で設定した[Qtバージョン]を選択する。
- [Qt mkspec]項目から、/<クロスコンパイルしたQt 6のインストールディレクトリ>/mkspecs/devices/linux-pinephone-g++ファイルのパスを入力する。
- [CMake Tool]プルダウンから、クロスコンパイルで使用したCMakeを選択する。
- [CMakeの設定]項目の[変更...]ボタンを押下して、
-DCMAKE_TOOLCHAIN_FILE:UNINITIALIZED=/<クロスコンパイルしたQt 6のインストールディレクトリ>/lib/cmake/Qt6/qt.toolchain.cmake
と入力する。- [適用]ボタンを押下する。
- ただし、この設定は、Qt Creatorの左サイド画面にある[プロジェクト] - [キット名] - [ビルド]を選択して、
- Qt Creatorメイン画面右ペインの[ビルド設定]にある
CMAKE_TOOLCHAIN_FILE
の値を編集することにより、プロジェクトごとに設定することができる。
Qtプロジェクトの設定
次に、Qt Creatorでソフトウェアを開発する時の環境設定を行う。
まず、プロジェクトの環境変数の設定を行う。
Qt Creatorを起動して、Qt Creatorメイン画面左の[プロジェクト] - 左ペインの[Run] - 右ペインの[ビルド設定] - [Environment]項目 - [詳細]プルダウンを開く。
[詳細]プルダウンから[追加]ボタンを押下して、以下の項目を設定する。
Qtプロジェクトをデバッグする場合は、必ず[デバイス環境の取得]ボタンを押下すること。
- Variable - QT_QPA_PLATFORMTHEME
- Value - qt6ct
- Variable - DISPLAY
- Value - :0 または :0.0
- Variable : PATH
- Value : /home/<PinePhoneのユーザ名>/InstallSoftware/Qt_6_x_x/bin ※PATHの設定が既に存在する場合は、追記する
- Variable : LD_LIBRARY_PATH (PinePhoneの~/.profileファイルに環境変数LD_LIBRARY_PATHを設定している場合)
- Value : /home/<PinePhoneのユーザ名>/InstallSoftware/Qt_6_x_x/lib:/home/<PinePhone's User Name>/InstallSoftware/Qt_6_x_x/plugins/qmltooling
- Variable : QML_IMPORT_PATH
- Value : /home/<PinePhoneのユーザ名>/InstallSoftware/Qt_6_x_x/qml
- Variable : QML2_IMPORT_PATH
- Value : /home/<PinePhoneのユーザ名>/InstallSoftware/Qt_6_x_x/qml
- Variable : QT_PLUGIN_PATH
- Value : /home/<PinePhoneのユーザ名>/InstallSoftware/Qt_6_x_x/plugins
- Variable : QT_QPA_PLATFORM_PLUGIN_PATH
- Value : /home/<PinePhoneのユーザ名>/InstallSoftware/Qt_6_x_x/plugins/platforms
また、上記の設定を簡潔に行う場合、Qtプロジェクトのディレクトリにある.pro.userファイルにおいて、
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">〜</valuemap>
要素内に、以下の設定を追記する。
以下の設定を追記する場合、必ず、Qtプロジェクトを閉じた状態で行うこと。
# .pro.userファイル
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<!-- ...略 -->
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes">
<value type="QString">QT_QPA_PLATFORMTHEME=qt6ct</value>
<value type="QString">DISPLAY=:0</value>
<value type="QString">PATH=/home/<PinePhoneのユーザ名>/InstallSoftware/Qt_6_x_x/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games</value>
<value type="QString">LD_LIBRARY_PATH=/home/<PinePhoneのユーザ名>/InstallSoftware/Qt_6_x_x/lib:/home/<PinePhoneのユーザ名>/InstallSoftware/Qt_6_x_x/plugins/qmltooling</value>
<value type="QString">QML_IMPORT_PATH=/home/<PinePhoneのユーザ名>/InstallSoftware/Qt_6_x_x/qml</value>
<value type="QString">QML2_IMPORT_PATH=/home/<PinePhoneのユーザ名>/InstallSoftware/Qt_6_x_x/qml</value>
<value type="QString">QT_PLUGIN_PATH=/home/<PinePhoneのユーザ名>/InstallSoftware/Qt_6_x_x/plugins</value>
<value type="QString">QT_QPA_PLATFORM_PLUGIN_PATH=/home/<PinePhoneのユーザ名>/InstallSoftware/Qt_6_x_x/plugins/platforms</value>
</valuelist>
<!-- ...略 -->
</valuemap>
もし、デバッグにおいて、以下のようなエラーが出力される場合は、
Qt Creatorのサイドメニューから、[プロジェクト] - [Build & Run] - [Run] - [コマンドライン引数:]項目に、-platform wayland
を記述する。
# エラー内容 Failed to create wl_display (No such file or directory) ... error: XDG_RUNTIME_DIR not set in the environment ... qt.qpa.plugin: Could not load the Qt platform plugin "wayland"
GDBの設定
次に、GDBデバッガの設定を行う。
リモートターゲットをデバッグする時、GDBは、Linux PC側にダウンロードしているPinePhoneのシステムルートディレクトリを検索する。
そのため、GDBにターゲット側のPinePhoneのシステムルートディレクトリを検索するように設定する必要がある。
これは、Qt Creatorメイン画面から、[ツール]メニューバー - [オプション] - [デバッガ] - [GDB]タブ - [追加の起動コマンド]に、以下の内容を設定する。
ただし、この設定はQt Quickを使用する時のみである。(Qt Widgetを使用する場合は設定不要)
set sysroot target:/
しかし、上記の[追加の起動コマンド]において、set sysroot target:/
オプションを使用する場合、デバッグの開始に時間が掛かる。
そのため、以下のように、[追加の起動コマンド]を記述して、
システムルートディレクトリに対して、Qtライブラリのインストールディレクトリのシンボリックリンクを作成することを推奨する。
システムルートディレクトリに対して、Linux PCに保存したPinePhone向けのQtライブラリがあるディレクトリのシンボクリックリンクを作成する。
mkdir -p /<PinePhoneのシステムルートディレクトリ>/home/mobian/InstallSoftware ln -s /<Qtライブラリのインストールディレクトリ> /<PinePhoneのシステムルートディレクトリ>/home/mobian/InstallSoftware # シンボリックリンク名の変更 mv /<PinePhoneのシステムルートディレクトリ>/home/mobian/InstallSoftware/<Qtライブラリのインストールディレクトリ> \ /<PinePhoneのシステムルートディレクトリ>/home/mobian/InstallSoftware/Qt_6_x_x
Qt Creatorメイン画面から、[ツール]メニューバー - [オプション] - [デバッガ] - [GDB]タブ - [追加の起動コマンド]に、以下の内容を設定する。
# Kit名に"PinePhone"という文字列が入っている場合のみ、PinePhoneのシステムルートディレクトリを参照する # x86 / x64のKitを使用する場合は、PinePhoneのシステムルートディレクトリを参照しない [ -n $(grep -i PinePhone %{ActiveProject:Kit:Name}) ] && set sysroot /<PinePhoneのシステムルートディレクトリ> # または set sysroot /<PinePhoneのシステムルートディレクトリ>
これにより、PinePhoneでQtライブラリが使用できる。
CLion / Qt 6との連携
ツールチェーンの設定
[ファイル]メニューバー - [設定]を選択する。
[設定]画面の左ペインにある[ビルド、実行、デプロイ] - [ツールチェーン]を選択する。
[設定]画面の右ペインにある[+]アイコンを選択して、[システム]を選択する。
- ツールチェーンの設定項目
- [名前]
- 任意の名前を入力する。
- [CMake:]
- PinePhone向けQtライブラリのビルドに使用したCMakeファイルのパスを入力する。
- [ビルドツール:]
- PinePhone向けQtライブラリのビルドに使用したNinjaファイルのパスを入力する。
- [C コンパイラー:]
- PinePhone向けQtライブラリのビルドに使用したGCCファイルのパスを入力する。
- 例: /<GCCツールチェーンのインストールディレクトリ>/bin/aarch64-linux-gnu-gcc
- [C++ コンパイラー:]
- PinePhone向けQtライブラリのビルドに使用したG++ファイルのパスを入力する。
- 例: /<GCCツールチェーンのインストールディレクトリ>/bin/aarch64-linux-gnu-g++
- [デバッガー:]
- GCCツールチェーンのGDBファイルのパスを入力する。
- 例: /<GCCツールチェーンのインストールディレクトリ>/bin/aarch64-linux-gnu-gdb
- [名前]
[設定]画面の右ペイン下部にある[適用]ボタンを押下する。
CMakeの設定
[ファイル]メニューバー - [設定]を選択する。
[設定]画面の左ペインにある[ビルド、実行、デプロイ] - [CMake]を選択する。
[設定]画面の右ペインにある[+]アイコンを選択する。
- CMakeの設定項目
- [名前]
- 任意の名前を入力する。
- [ビルドタイプ:]プルダウン
- [Debug]または[Release]を選択する。
- [ツールチェーン:]プルダウン
- 上記で設定したツールチェーン名を選択する。
- [ジェネレーター:]プルダウン
- [デフォルトを使用する]を選択する。
- 例: /<GCCツールチェーンのインストールディレクトリ>/bin/aarch64-linux-gnu-gcc
- [環境:]
[環境:]のテキストアイコンを選択して、[環境設定]画面を開く。
画面右上の[+]ボタンを押下して、各環境変数を設定する。- CMAKE_C_COMPILER
- PinePhone向けQtライブラリのビルドに使用したGCCファイルのパスを入力する。
- 例: /<GCCツールチェーンのインストールディレクトリ>/bin/aarch64-linux-gnu-gcc
- CMAKE_CXX_COMPILER
- PinePhone向けQtライブラリのビルドに使用したG++ファイルのパスを入力する。
- 例: /<GCCツールチェーンのインストールディレクトリ>/bin/aarch64-linux-gnu-g++
- CMAKE_PREFIX_PATH
- PinePhone向けQtライブラリのインストールディレクトリのパスを入力する。
- 例: <PinePhone向けQtライブラリのインストールディレクトリ>
- CMAKE_TOOLCHAIN_FILE
- PinePhone向けQtライブラリのインストールディレクトリにあるビルド向けツールチェーンファイルのパスを入力する。
- 例: /<PinePhone向けQtライブラリのインストールディレクトリ>/lib/cmake/Qt6/qt.toolchain.cmake
- QT_QMAKE_EXECUTABLE
- PinePhone向けQtライブラリのインストールディレクトリにあるqmakeファイルのパスを入力する。
- 例: /<PinePhone向けQtライブラリのインストールディレクトリ>/bin/qmake-host
- CMAKE_C_COMPILER
- [名前]
[設定]画面の右ペイン下部にある[適用]ボタンを押下する。
SSHの設定
[ファイル]メニューバー - [設定]を選択する。
[設定]画面の左ペインにある[ツール] - [SSH 構成]を選択する。
[設定]画面の右ペインにある[+]アイコンを選択する。
- SSH構成の設定項目
- [ホスト:]
- PinePhoneのIPアドレスまたはホスト名を入力する。
- [ユーザー名:]
- PinePhoneのユーザ名を入力する。
- [認証タイプ:]プルダウン
- [パスワード]または[キーペア]を選択する。
- [秘密鍵ファイル:] (キーペアを選択した場合)
- 秘密鍵ファイルのパスを入力する。
- [パスフレーズ:] (キーペアを選択した場合、かつ、パスフレーズを設定した場合)
- 秘密鍵のパスフレーズを入力する。
- [構成ファイル ~/.ssh/configの構文解析]チェックボックス
- 任意
- [ホスト:]
[接続テスト]ボタンを押下して、PinePhoneにSSH接続する。
[設定]画面の右ペイン右下にある[適用]ボタンを押下する。
各プロジェクトの設定
CLionを起動して、[ファイル]メニューバー - [新規] - [プロジェクト...]を選択する。
[新規プロジェクト]画面から、[Qt Console 実行可能ファイル]または[Qt Widgets 実行可能ファイル]を選択する。
新規プロジェクトの作成後、[実行]メニューバー - [実行構成の編集...]を選択する。
[実行/デバッグ構成]画面が開くので、画面左上にある[+]ボタンを押下して、[リモート GDB サーバー]を選択する。
画面左ペインに[リモート GDB サーバー]が追加される。
画面左ペインに[リモート GDB サーバー]を選択して、各種設定を行う。
- [ターゲット:]プルダウン
- プロジェクト名を選択する。
- [実行可能ファイル:]プルダウン
- プロジェクト名を選択する。
- [GDB:]プルダウン
- 上記のツールチェーンの作成セクションで設定したGDBを選択する。
- [資格情報:]プルダウン
- 上記のSSHの設定セクションで設定したSSHを選択する。
- [実行可能ファイル...]ラジオボタン
- 任意
- [アップロードパス:]
- 実行可能バイナリが配置されるPinePhone上のディレクトリを入力する。
- 例: /home/<PinePhoneのユーザ名>/CLion/Sample1/debug
- ['target remote' ...]
- 自動的に入力される。
- 例: <IPアドレスまたはホスト名>:1234
- [GDB サーバー引数:]
- Qt WidgetsまたはQMLを使用するプロジェクトの場合、デバッグまたは実行時において、実行可能バイナリに
-platform wayland
オプションを付加する必要がある。 - 例:
:<GDBサーバのポート番号 例: 1234> /<実行可能バイナリが配置されるPinePhone上のディレクトリ>/debug/<実行バイナリのファイル名> -platform wayland
- Qt WidgetsまたはQMLを使用するプロジェクトの場合、デバッグまたは実行時において、実行可能バイナリに
次に、[拡張 GDB サーバーオプション]項目を設定する。
この設定は、PinePhoneにアップロードしたQtライブラリにおいて、デバッグまたは実行に関する設定を行う。
- [作業ディレクトリ:]
- 何も入力しない。
- [環境変数:]
[環境変数:]項目の右にあるテキストアイコンを選択する。
[環境変数]画面が開くので、画面左上にある[+]ボタンを押下して各種設定を入力する。- DISPLAY
- :0
- QT_QPA_PLATFORMTHEME
- Qt 6の場合 : qt6ct
- PATH
- PinePhone上のQt6ライブラリをアップロードしたbinディレクトリのパスを入力する。
- 例: /<Qt6ライブラリをアップロードしたディレクトリ>/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
- LD_LIBRARY_PATH
- PinePhone上のQt6ライブラリをアップロードしたlibディレクトリのパスを入力する。
- 例: /<Qt6ライブラリをアップロードしたディレクトリ>/lib:/<Qt6ライブラリをアップロードしたディレクトリ>/plugins/qmltooling
- QT_PLUGIN_PATH
- /<Qt6ライブラリをアップロードしたディレクトリ>/plugins
- QT_QPA_PLATFORM_PLUGIN_PATH
- /<Qt6ライブラリをアップロードしたディレクトリ>/plugins/platforms
- QML_IMPORT_PATH
- /<Qt6ライブラリをアップロードしたディレクトリ>/qml
- QML2_IMPORT_PATH
- /<Qt6ライブラリをアップロードしたディレクトリ>/qml
- QT_DEBUG_PLUGINS
- 0または1を入力する。
- LANG
- 日本語を設定する場合は、
ja_JP.UTF-8
と入力する。
- 日本語を設定する場合は、
- DISPLAY
また、[拡張 GDB サーバーオプション]項目の設定は、プロジェクトディレクトリ内の.idea/runConfigurations/<プロジェクト名>.xmlファイルに保存されている。
このファイルを直接編集することにより、上記の設定を行うこともできる。
CLion上で上記の設定を行うには煩雑なため、ファイルを直接編集することを推奨する。
cd <プロジェクトディレクトリ> vi .idea/runConfigurations/<プロジェクト名>.xml
<!-- .idea/runConfigurations/<プロジェクト名>.xml -->
<component name="ProjectRunConfigurationManager">
<configuration ...略>
<envs>
<env name="DISPLAY" value=":0" />
<env name="LANG" value="ja_JP.UTF-8" />
<env name="QML2_IMPORT_PATH" value="/<Qt6ライブラリをアップロードしたディレクトリ>/qml" />
<env name="QML_IMPORT_PATH" value="/<Qt6ライブラリをアップロードしたディレクトリ>/qml" />
<env name="QT_DEBUG_PLUGINS" value="0" />
<env name="QT_PLUGIN_PATH" value="/<Qt6ライブラリをアップロードしたディレクトリ>/plugins" />
<env name="QT_QPA_PLATFORM_PLUGIN_PATH" value="/<Qt6ライブラリをアップロードしたディレクトリ>/plugins/platforms" />
<env name="QT_QPA_PLATFORMTHEME" value="qt6ct" />
<env name="LD_LIBRARY_PATH" value="/<Qt6ライブラリをアップロードしたディレクトリ>/lib:/<Qt6ライブラリをアップロードしたディレクトリ>/plugins/qmltooling" />
<env name="PATH" value="/<Qt6ライブラリをアップロードしたディレクトリ>/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games" />
</envs>
<!-- ...略 -->
</configuration>
</component>
GDBの設定
プロジェクトにデバッグのためのより多くの設定が必要な場合、デバッガの初期化ファイル (GDBの場合は.gdbinit、LLDBの場合は.lldbinit) をプロジェクトディレクトリ直下に作成する。
このファイルは、他のプロジェクトと一緒にVCSで共有することもできる。
一般的に、GDB / LLDBは起動時に初期化ファイルを一定の順序で読み込む。
まず、デバッガはユーザのホームディレクトリにある初期化ファイルを探して、次に、現在のプロジェクトディレクトリ直下にある初期化ファイルを探す。
ただし、デフォルトの設定では、セキュリティ上の理由から、プロジェクト固有の初期化ファイルからのコマンドは実行されない。
そのため、ホームディレクトリの初期化ファイルである~/.gdbinitファイルまたは~/.lldbinitファイルを、以下に示すように編集する。
vi ~/.gdbinit または vi ~/.lldbinit
# ~/.gdbinitファイル または ~/.lldbinitファイル
set auto-load safe-path /
# または
set auto-load local-gdbinit on
add-auto-load-safe-path /
次に、プロジェクトディレクトリの直下に.gdbinitファイルを作成する。
cd <プロジェクトディレクトリ> vi .gdbinit または vi .lldbinit
# /<プロジェクトディレクトリ>/.gdbinitファイル または /<プロジェクトディレクトリ>/.lldbinitファイル
set sysroot <PinePhoneのシステムルートディレクトリ>
CLionを起動して、任意のプロジェクトを開く。
CLionのメイン画面左にあるプロジェクトに.gdbinitファイル、または、.lldbinitファイルが追加されているかどうかを確認する。
エラー関連
libdbusに関する問題
以下に示すようなlibdbusに関するコンパイルエラーが発生する場合がある。
# ...略 /<GCCクロスコンパイラのパス>/bin/ld: /<PinePhoneのシステムルート>/usr/lib/aarch64-linux-gnu/libdbus-1.a(libdbus_1_la-dbus-message.o): relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol `dbus_message_unref' which may bind externally can not be used when making a shared object; recompile with -fPIC # ...略
これは、システムルート内にあるlibdbusが動的共有オブジェクトでない場合に発生する可能性がある。
これは通常、Mobian / Manjaro ARMの再インストールすることで解決できる。
別の方法としては、libdbus-1-devパッケージを再インストールすることである。
しかし、この問題が解決せず、D-Busが不要の場合は-DFEATURE_dbus=OFF
オプションを付加することにより、D-Bus機能を無効にすることができる。
さらに別の方法として、set(QT_LINKER_FLAGS "-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed")
の行を、
set(QT_LINKER_FLAGS "-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -ldbus-1")
に変更する。
この場合、/<PinePhoneのシステムルート>/usr/lib/aarch64-linux-gnu/libdbus-1.soへのリンクが有効であることを確認する。
(同階層のディレクトリのlibdbus-1.so.X.XX.XXにリンクされているはずである)
※注意
Bluetoothモジュールを動作させるにはD-Bus機能が必要である。
libstdc++のエラー
デバッグ時において、以下に示すようなエラーが出力される場合はある。
/Path/to/<Project Name>/bin/<Binary Name>: /lib/aarch64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.XX' not found (required by /Path/to/Qt6 Library/lib/libQt6Qml.so.6)
クロスコンパイラのlibstdc++.so.6ファイルにおいて、ターゲットとなるOSのlibstdc++.so.6ファイルのバージョンと同等または古いものを使用する必要がある。
例えば、Debian 12 (Mobian 12)はGLIBCXX_3.4.30であるため、GCC 12.2ツールチェーン以前のものを使用する。
以下に示すコマンドを実行して、GLIBCXXのバージョンを確認することができる。
# クロスコンパイラ strings /<クロスコンパイラのインストールディレクトリ>/<アーキテクチャ名 例: aarch64-linux-gnu>/lib64/libstdc++.so.6 | grep -E '^GLIBCXX' # Manjaro strings /usr/lib/libstdc++.so.6 | grep -E '^GLIBCXX' # Mobian strings /usr/lib/aarch64-linux-gnu/libstdc++.so.6 | grep -E '^GLIBCXX'
AT-SPI2の警告
Qt6ライブラリを使用してプロジェクトをクロスコンパイルして実行する時、以下に示すようなAT-SPI2に関するエラーが出力される場合がある。
qt.accessibility.atspi Error Not connected to D-Bus server
もし、アクセシビリティが不要な場合、Qt6ライブラリのコンパイルにおいて、cmake
コマンドにアクセシビリティを無効にするオプションを付加する。
-DQT_FEATURE_accessibility=OFF -DQT_FEATURE_accessibility_atspi_bridge=OFF
GDBデバッグ実行時におけるキャッシュファイルの警告
デバッグ実行時において、以下に示すような警告が非常に多く出力される場合がある。
index cache: could not make cache directory: Permission denied
この警告は、デバッグ実行時のターゲットデバイスのディレクトリが存在しない場合、または、該当ディレクトリに書き込み権限が無い場合に出力される。
この警告を抑制する場合は、以下に示す設定を行う。
- Qt Creatorの[編集]メニューバー - [Preferences...]を選択する。
- [設定]ダイアログが開くので、画面左ペインにある[デバッガ] - 画面右ペインにある[GDB]タブ - [追加の起動コマンド]に、以下に示す設定を入力する。
set index-cache directory /tmp/GDB
この設定により、/tmp/GDBディレクトリにデバッグ関連のログファイルが出力されるようになる。