概要

Raspberry Piにおいて、一般的なデスクトップソフトウェアのクロスコンパイルおよび組み込み / デバイス作成のユースケースのクロスコンパイルを行う手順を記載する。

組み込み / デバイス作成とは、デスクトップソフトウェアをX11の下で実行するためのものではなく、
ソフトウェアがBroadcomドライバを使用して、dispmanx / EGLの上でフルスクリーンで実行するというユースケースのことである。

EGLを使用する場合、Qtソフトウェアはフルスクリーンでのみ動作する。
一般的なデスクトップウインドウで起動する場合はXCBを使用する必要があるが、XCBはOpenGLやQt Quickは動作しないことに注意すること。

このページでは、Raspberry Pi OS Bullseye / Bookwormをインストールしていることを想定している。

参考書
 
Introducing Qt 6
C++でモバイルとデスクトップ向けのアプリとゲームを作ることを学ぶ
 
Cross-Platform Development with Qt 6 and Modern C++
プラットフォーム依存性を気にすることなく、
モダンなグラフィカルユーザーインターフェースを持つアプリケーションを設計・構築する
 
A Guide to Qt 6
Qt 6の初心者向けガイド



ホストPCの設定

ホストPCにおいて、クロスコンパイルに必要なライブラリをインストールする。
(Texinfoは、GNU公式Webサイトにアクセスして、ソースコードからインストールすることを推奨する)

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

                    libicu-devel libopus-devel openjpeg2-devel pciutils-devel libpciaccess-devel libxshmfence-devel python3-html5lib \  # QtWebEngineをインストールする場合
                    libvpx-devel                                                                                                        # QtWebEngineをインストールする場合

                    ffmpeg-4-libavcodec-devel ffmpeg-4-libavdevice-devel ffmpeg-4-libavfilter-devel ffmpeg-4-libavformat-devel       \  # QtWebEngineをインストールする場合 (デフォルトパッケージ)
                    ffmpeg-4-libavresample-devel ffmpeg-4-libavutil-devel ffmpeg-4-libpostproc-devel ffmpeg-4-libswresample-devel    \  # QtWebEngineをインストールする場合 (デフォルトパッケージ)
                    ffmpeg-4-libswscale-devel ffmpeg-4-private-devel                                                                    # QtWebEngineをインストールする場合 (デフォルトパッケージ)

                    ffmpeg-6-libavcodec-devel ffmpeg-6-libavdevice-devel ffmpeg-6-libavfilter-devel ffmpeg-6-libavformat-devel       \  # QtWebEngineをインストールする場合 (Packmanパッケージ)
                    ffmpeg-6-libavresample-devel ffmpeg-6-libavutil-devel ffmpeg-6-libpostproc-devel ffmpeg-6-libswresample-devel    \  # QtWebEngineをインストールする場合 (Packmanパッケージ)
                    ffmpeg-6-libswscale-devel ffmpeg-6-private-devel                                                                    # QtWebEngineをインストールする場合 (Packmanパッケージ)


GCC ARMツールチェーンにおいて、GCC 8以降が必要である
Linaroは、アップストリームビルドのスナップショットをユーザに提供するGNUツールチェーン・インテグレーションビルドを毎月提供している。
これらのビルドにより、開発者はビルド済みバイナリの機能をアップストリームですぐにテストすることができる。

Linero社が提供しているGCC ARMツールチェーンをダウンロードする。

※注意
クロスコンパイラのlibstdc++.so.6ファイルにおいて、Raspberry Pi OSのlibstdc++.so.6ファイルのバージョンと同等または古いものを使用する必要がある。
例えば、Raspberry Pi OS Bullseyeのlibstdc++.so.6ファイルはGLIBCXX_3.4.28までであるため、GCC 10ツールチェーン、または、それ以前のものを使用する。


# 32ビット向け
tar xf gcc-linaro-<バージョン>-x86_64_arm-linux-gnueabihf.tar.xz

# 64ビット向け
tar xf gcc-linaro-<バージョン>-x86_64_aarch64-linux-gnu.tar.xz


また、開発者がGCC ARMツールチェーンを作成する場合、インストール - GCC#クロスコンパイラ向けGCCツールチェーンのインストールを参照すること。

GCC ARMツールチェーンは、システム固有のLTO(Link Time Optimization)フラグを使用して構築されているため、
ソフトウェアをコンパイルする時、これらのツールチェーンを使用することで、Raspberry PiのSoC固有の機能を簡単に利用することができる。

Raspberry Pi 4のSoCはBroadcom BCM2711 SoC(Cortex-A72 64bit)を採用しており、Raspberry Pi 3B / 3B+と同様、ARMv8-aアーキテクチャを採用している。

表. Raspberry PiとLTO(Link Time Optimization)フラグの関係
Raspberry Piの種類 LTO(Link Time Optimization)フラグ
Raspberry Pi Zero/W/WH
Raspberry Pi 1 Model A / B / A+ / B+
-march=armv6 -mfloat-abi=hard -mfpu=vfp
Raspberry Pi 2 Model A / B -march=armv7-a -mfloat-abi=hard -mfpu=neon-vfpv4
Raspberry Pi 3 Model A, A+ / B, B+ (32Bit)
Raspberry Pi 4 Model A+ / B+ (32Bit)
Raspberry Pi Compute 3 / 3lite / 3+ (32Bit)
-march=armv8-a -mfloat-abi=hard -mfpu=neon-fp-armv8
Raspberry Pi 3 Model A+ / B+ (64Bit)
Raspberry Pi 4 Model A+ / B+ (64Bit)
Raspberry Pi Compute 3 / 3lite / 3+ (64Bit)
-march=armv8-a+fp+simd



Raspberry Piの設定

描画処理に時間が掛かる場合、Raspberry PiのVRAMを128[MB]や256[MB]程度に変更する。

  • VRAMを変更する手順
    sudo raspi-config
    次に、[Performance Options] - [GPU Memory]を選択して、任意の数値を入力する。
    最後に、[Finish]を選択して終了する。


Raspberry Pi 4Bでは、Broadcom EGLはサポートされていないため、Qt 6を使用する場合は、KMSを有効にする必要がある。
また、KMSを有効にするには、libgles2-mesa-devライブラリとlibgbm-devライブラリをインストールする必要がある。

  • GL(FAKE KMS)を有効にする手順
    sudo raspi-config
    次に、[Advanced Options] - [A8 GL Driver] - [G2 GL (Fake KMS)]を選択することにより、KMSが有効になる。
    最後に、[Finish]を選択して終了する。
    (最小限のビルドを使用する場合、このオプションが利用可能になる前に、いくつかのアップデートを促される時はアップデートする。


次に、/etc/apt/sources.listファイルのdeb-srcから始まる行のコメントを外す。

sudo vi /etc/apt/sources.list


# /etc/apt/sources.listファイル

# Bullseyeの場合
## 編集前
#deb-src http://raspbian.raspberrypi.org/raspbian/ bullseye main contrib non-free rpi

## 編集後
deb-src http://raspbian.raspberrypi.org/raspbian/ bullseye main contrib non-free rpi


Raspbian Busterのソフトウェアをアップデートする。

sudo apt update
sudo apt dist-upgrade
sudo reboot


Raspberry Piのファームウェアをアップデートする。
ただし、不要の場合もあることに注意する。

sudo rpi-update
sudo reboot


Raspberry PiにQtライブラリをインストールする。
build-depコマンドとは、ビルドに必要なパッケージが全てインストールするコマンドである。
ビルド設定によっては、不要なパッケージも含まれている。

※注意
Raspberry Pi 4BでQt 6を実行するには、KMSを使用する必要がある。
libgles2-mesa-devおよびlibgbm-devがインストールされていることを確認すること。

  • Raspberry Pi OS Bullseye
## EGLを使用する場合
sudo apt install ccache libicu-dev icu-devtools libsctp1 libsctp-dev libzstd1 libzstd-dev libhidapi-dev \
                 libinput-bin libinput-dev libts0 libts-bin libts-dev libmtdev1 libmtdev-dev libevdev2 libevdev-dev \
                 libblkid-dev libffi-dev libglib2.0-dev libglib2.0-dev-bin libmount-dev \
                 libpcre16-3 libpcre3-dev libpcre32-3 libpcrecpp0v5 libselinux1-dev libsepol1-dev libwacom-dev \
                 libfontconfig1-dev libdbus-1-dev libnss3-dev libxkbcommon-dev libjpeg-dev libasound2-dev libudev-dev libgles2-mesa-dev \
                 libxcb-xinerama0 libxcb-xinerama0-dev gdbserver
                 python2 libpython2.7          # QtQuickを使用する場合
                 libgtk-3-dev                  # QtWidget向けにGTKネイティブテーマを使用する場合
                 libraspberrypi-dev            # Raspberry Pi 3B / 3B+の場合、かつ、Raspberry Pi OS 32ビットを使用する場合
                 libgles2-mesa-dev libgbm-dev  # Raspberry Pi 4Bを使用する場合

## XCBを使用する場合
sudo apt install ccache libicu-dev icu-devtools libsctp1 libsctp-dev libzstd1 libzstd-dev libhidapi-dev \
                 libinput-bin libinput-dev libts0 libts-bin libts-dev libmtdev1 libmtdev-dev libevdev2 libevdev-dev \
                 libblkid-dev libffi-dev libglib2.0-dev libglib2.0-dev-bin libmount-dev \
                 libpcre16-3 libpcre3-dev libpcre32-3 libpcrecpp0v5 libselinux1-dev libsepol1-dev libwacom-dev \
                 libfontconfig1-dev libdbus-1-dev libnss3-dev libxkbcommon-dev libjpeg-dev libasound2-dev libudev-dev libgles2-mesa-dev \
                 libxcb-xinerama0 libxcb-xinerama0-dev gdbserver \
                 libx11-dev libxcb1-dev libxext-dev libxi-dev libxcomposite-dev libxcursor-dev libxtst-dev libxrandr-dev \
                 libfreetype6-dev libx11-xcb-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-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-xkb-dev libxkbcommon-dev libxkbcommon-x11-dev libfontconfig1-dev 
                 python2 libpython2.7          # QtQuickを使用する場合
                 libgtk-3-dev                  # QtWidget向けにGTKネイティブテーマを使用する場合
                 libraspberrypi-dev            # Raspberry Pi 3B / 3B+の場合、かつ、Raspberry Pi OS 32ビットを使用する場合
                 libgles2-mesa-dev libgbm-dev  # Raspberry Pi 4Bを使用する場合


  • Raspberry Pi OS Bookworm
## EGLを使用する場合
sudo apt install ccache libicu-dev icu-devtools libsctp1 libsctp-dev libzstd1 libzstd-dev libhidapi-dev \
                 libinput-bin libinput-dev libts0 libts-bin libts-dev libmtdev1 libmtdev-dev libevdev2 libevdev-dev \
                 libblkid-dev libffi-dev libglib2.0-dev libglib2.0-dev-bin libmount-dev \
                 libpcre16-3 libpcre3-dev libpcre32-3 libpcrecpp0v5 libselinux1-dev libsepol-dev libwacom-dev \
                 libfontconfig1-dev libdbus-1-dev libnss3-dev libxkbcommon-dev libjpeg-dev libasound2-dev libudev-dev libgles2-mesa-dev \
                 libxcb-xinerama0 libxcb-xinerama0-dev gdbserver
                 libgtk-3-dev                  # QtWidget向けにGTKネイティブテーマを使用する場合
                 libraspberrypi-dev            # Raspberry Pi 3B / 3B+の場合、かつ、Raspberry Pi OS 32ビットを使用する場合
                 libgles2-mesa-dev libgbm-dev  # Raspberry Pi 4Bを使用する場合

## XCBを使用する場合
sudo apt install ccache libicu-dev icu-devtools libsctp1 libsctp-dev libzstd1 libzstd-dev libhidapi-dev \
                 libinput-bin libinput-dev libts0 libts-bin libts-dev libmtdev1 libmtdev-dev libevdev2 libevdev-dev \
                 libblkid-dev libffi-dev libglib2.0-dev libglib2.0-dev-bin libmount-dev \
                 libpcre16-3 libpcre3-dev libpcre32-3 libpcrecpp0v5 libselinux1-dev libsepol-dev libwacom-dev \
                 libfontconfig1-dev libdbus-1-dev libnss3-dev libxkbcommon-dev libjpeg-dev libasound2-dev libudev-dev libgles2-mesa-dev \
                 libxcb-xinerama0 libxcb-xinerama0-dev gdbserver \
                 libx11-dev libxcb1-dev libxext-dev libxi-dev libxcomposite-dev libxcursor-dev libxtst-dev libxrandr-dev \
                 libfreetype6-dev libx11-xcb-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-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-xkb-dev libxkbcommon-dev libxkbcommon-x11-dev libfontconfig1-dev 
                 libgtk-3-dev                  # QtWidget向けにGTKネイティブテーマを使用する場合
                 libraspberrypi-dev            # Raspberry Pi 3B / 3B+の場合、かつ、Raspberry Pi OS 32ビットを使用する場合
                 libgles2-mesa-dev libgbm-dev  # Raspberry Pi 4Bを使用する場合


# その他
sudo apt build-dep libqt6webengine-data  # WebEngineを使用する場合


マルチメディア関連やBluetooth等を使用する場合、下表に示す任意のパッケージをインストールする。

その他のライブラリ(オプション)
機能 インストールするライブラリ configureスクリプトのオプション
Bluetooth bluez bluez-tools libbluetooth-dev
画像 libjpeg-dev libpng-dev libtiff-dev libwebp-dev libmng-dev libjasper-dev
コーデック libavcodec-dev libavformat-dev libswscale-dev libv4l-dev libxvidcore-dev libx264-dev libx265-dev
マルチメディア libgstreamer1.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-pulseaudio
gstreamer1.0-tools gstreamer1.0-alsa
libwayland-dev (Wayland開発パッケージは、gstreamerヘッダで必要)
ALSAオーディオ libasound2-dev
Pulseオーディオ pulseaudio libpulse-dev
OpenALオーディオ libopenal-data libopenal1 libopenal-dev libsndio7.0 libsndio-dev
データベース unixodbc-dev (ODBC)
libsqlite3-dev (SQLite)
libpq-dev(PostgreSQL)
libmariadb-dev(MariaDB / MySQL)
プリンタ libcups2-dev
Qt Speech flite1-dev
Qt GamePad libsdl2-dev
Wayland libwayland-dev libwayland-dev libkwaylandserver-dev waylandpp-dev libwayland-egl-backend-dev
X11 libx11-dev libxcb1-dev libxext-dev libxi-dev libxcomposite-dev libxcursor-dev libxtst-dev libxrandr-dev
libfreetype6-dev libx11-xcb-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-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 libfontconfig1-dev

もし、xcbに関連するパッケージを全てインストールする場合は、sudo apt install "libxcb-*"を実行する。
WebEngine 必須 :
flex bison gperf libre2-dev libnss3-dev libdrm-dev

オプション1 :
libxml2-dev libxslt1-dev libminizip-dev libjsoncpp-dev liblcms2-dev libevent-dev libprotobuf-dev
protobuf-compiler

オプション2(不安定なため注意すること) :
libopus-dev libvpx-dev
アクセシビリティ at-spi2-core libatspi2.0-dev gir1.2-atspi-2.0
SCTP libsctp1 libsctp-dev -sctp
Broadcom EGLの代わりに
VC4ドライバを使用する場合

※Raspberry Pi 4では必須
libgles2-mesa-dev libgbm-dev -platform linux-rpi-vc4-g++


ビルドしたQtソフトウェアをRasberry Piにデプロイするためのディレクトリを作成する。
加えて、Qtライブラリを配置するディレクトリも作成する。

mkdir -p ~/InstallSoftware/QtApplication ~/InstallSoftware/Qt_6_x_x_EGL ~/InstallSoftware/Qt_6_x_x_XCB


次のセクションにおいて、rsyncコマンドを使用してLinux PCとRaspberry Piのファイルを同期する。
しかし、同期するファイルには、スーパユーザ権限が必要なものがある。

そのため、一般ユーザでも全てのファイルを同期できるように、/etc/sudoersファイルに以下の設定を追記する。
以下の設定により、rsyncコマンドは、必要に応じてスーパユーザ権限で実行される。

echo "$USER ALL=NOPASSWD:$(which rsync)" | sudo tee --append /etc/sudoers



EGLFSを使用する場合

この設定は不要の可能性が高い。

Raspberry Pi OS Bullseye以降、Broadcommグラフィックライブラリ (/opt/vcディレクトリ) は存在しない。
もし、brcmEGLライブラリ等が必要な場合は、手動でビルドおよびインストールする必要がある。

git clone https://github.com/raspberrypi/userland
cd userland


Broadcommグラフィックライブラリをビルドおよびインストールする。

./buildme


/opt/vcディレクトリにBroadcommグラフィックライブラリがインストールされているかどうかを確認する。


システムルートディレクトリの設定

Linux PCで、Raspberry Pi向けのQtソフトウェアをクロスコンパイルできるように開発環境を設定する。
Raspberry Pi上でネイティブにコンパイルすることもできるが、Linux PCの方がスループットが良い。

Linux PC上に開発用ディレクトリを作成する。
また、Raspberry Piのいくつかのルートディレクトリと同期する必要があるため、システムルートディレクトリも作成する。

mkdir -p ~/Program/Qt_Embedded/sysroot ~/Program/Qt_Embedded/sysroot/lib ~/Program/Qt_Embedded/sysroot/opt \
         ~/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 <秘密鍵のフルパス>" <Raspberry Piのユーザ名>@<Raspberry Piのホスト名またはIPアドレス>:/lib ~/Program/Qt_Embedded/sysroot
rsync -avz --rsync-path="sudo rsync" --delete --rsh="ssh -p <ポート番号> -i <秘密鍵のフルパス>" <Raspberry Piのユーザ名>@<Raspberry Piのホスト名またはIPアドレス>:/usr/include ~/Program/Qt_Embedded/sysroot/usr
rsync -avz --rsync-path="sudo rsync" --delete --rsh="ssh -p <ポート番号> -i <秘密鍵のフルパス>" <Raspberry Piのユーザ名>@<Raspberry Piのホスト名またはIPアドレス>:/usr/lib ~/Program/Qt_Embedded/sysroot/usr
rsync -avz --rsync-path="sudo rsync" --delete --rsh="ssh -p <ポート番号> -i <秘密鍵のフルパス>" <Raspberry Piのユーザ名>@<Raspberry Piのホスト名またはIPアドレス>:/usr/share/pkgconfig ~/Program/Qt_Embedded/sysroot/usr/share


ダウンロードしたファイルおよびディレクトリのシンボリックリンクを相対的に調整する。
fixQualifiedLibraryPathsが正常に動作しないため、提供されたスクリプトをダウンロードして実行する。

wget https://raw.githubusercontent.com/riscv/riscv-poky/master/scripts/sysroot-relativelinks.py
chmod +x sysroot-relativelinks.py
./sysroot-relativelinks.py ~/Program/Qt_Embedded/sysroot



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 # 必要な場合は個別に追加ダウンロードする



デバイス定義ファイルの作成

EGLFSを使用する場合

qmake.confを作成する。
qmake.confファイルは、ビルド時の設定を定義するものである。

cd /<Qtのソースコードが存在するディレクトリ>/qtbase/mkspecs/devices
mkdir linux-raspberrypi-new-g++ && cd linux-raspberrypi-new-g++
vi qmake.conf


 # qmake.confファイル
 
 include(../common/linux_device_pre.conf)
 
 SYSROOT_INC = $$[QT_SYSROOT]/usr/include
 SYSROOT_LIB = $$[QT_SYSROOT]/usr/lib
 
 # Extra stuff (OpenGL, DirectFB, ...)
 QMAKE_INCDIR_EGL        = $$[SYSROOT_INC]                     \
                           $$[SYSROOT_INC]/arm-linux-gnueabihf \
                           $$[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]/arm-linux-gnueabihf \
                           $$[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}
 
 # Raspberry Pi 3B / 3B+の場合
 QMAKE_CFLAGS             = -march=armv8-a -mtune=cortex-a53 -mfpu=crypto-neon-fp-armv8
 
 # Raspberry Pi 4B 32ビットOSを使用する場合
 QMAKE_CFLAGS             = -march=armv8-a -mtune=cortex-a72 -mfpu=crypto-neon-fp-armv8
 
 # Raspberry Pi 4B 64ビットOSを使用する場合
 QMAKE_CFLAGS             = -march=armv8-a -mtune=cortex-a72
 
 QMAKE_CFLAGS             = $${COMPILER_FLAGS}
 QMAKE_CXXFLAGS           = $${COMPILER_FLAGS}
 QMAKE_CXXFLAGS_RELEASE  += -O3
 
 QMAKE_LIBS              += -lrt -lpthread -ldl
 
 # Raspberry Pi OS 32ビットの場合
 # Raspberry Pi OS 64ビットの場合はコメントアウトする
 DISTRO_OPTS             += hard-float
 
 # Raspberry Pi OS 64ビットの場合はコメントを解除する
 #DISTRO_OPTS += aarch64
 
 # for Raspberry Pi OS
 DISTRO_OPTS             += deb-multi-arch
 
 # Preferred eglfs backend
 ## Raspberry Pi 3B / 3B+の場合
 EGLFS_DEVICE_INTEGRATION = eglfs_brcm
 
 ## Raspberry Pi 4Bの場合
 EGLFS_DEVICE_INTEGRATION = eglfs_kms
 
 include(../common/linux_arm_device_post.conf)
 
 load(qt_config)


次に、デバイス定義ファイルのヘッダファイルを作成する。

vi qplatformdefs.h


 # qplatformdefs.hファイル
 
 #include "../../linux-g++/qplatformdefs.h"


XCBを使用する場合

qmake.confを作成する。
qmake.confファイルは、ビルド時の設定を定義するものである。

cd /<Qtのソースコードが存在するディレクトリ>/qtbase/mkspecs/devices
mkdir linux-raspberrypi-new-g++ && cd linux-raspberrypi-new-g++
vi qmake.conf


 # qmake.confファイル
 
 include(../common/linux_device_pre.conf)
 
 SYSROOT_INC = $$[QT_SYSROOT]/usr/include
 SYSROOT_LIB = $$[QT_SYSROOT]/usr/lib
 
 # Extra stuff (OpenGL, DirectFB, ...)
 QMAKE_INCDIR_EGL        = $$[SYSROOT_INC]                     \
                           $$[SYSROOT_INC]/arm-linux-gnueabihf \
                           $$[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]/arm-linux-gnueabihf \
                           $$[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}
 
 # Raspberry Pi 3B / 3B+の場合
 QMAKE_CFLAGS             = -march=armv8-a -mtune=cortex-a53 -mfpu=crypto-neon-fp-armv8
 
 # Raspberry Pi 4B 32ビットOSを使用する場合
 QMAKE_CFLAGS             = -march=armv8-a -mtune=cortex-a72 -mfpu=crypto-neon-fp-armv8
 
 # Raspberry Pi 4B 64ビットOSを使用する場合
 QMAKE_CFLAGS             = -march=armv8-a -mtune=cortex-a72
 
 QMAKE_CFLAGS             = $${COMPILER_FLAGS}
 QMAKE_CXXFLAGS           = $${COMPILER_FLAGS}
 QMAKE_CXXFLAGS_RELEASE  += -O3
 
 QMAKE_LIBS              += -lrt -lpthread -ldl
 
 # Raspberry Pi OS 32ビットの場合
 # Raspberry Pi OS 64ビットの場合はコメントアウトする
 DISTRO_OPTS             += hard-float
 
 # Raspberry Pi OS 64ビットの場合はコメントを解除する
 #DISTRO_OPTS += aarch64
 
 # for Raspberry Pi OS
 DISTRO_OPTS             += deb-multi-arch
 
 # Preferred eglfs backend
 EGLFS_DEVICE_INTEGRATION = eglfs_kms
 
 include(../common/linux_arm_device_post.conf)
 
 load(qt_config)


次に、デバイス定義ファイルのヘッダファイルを作成する。

vi qplatformdefs.h


 # qplatformdefs.hファイル
 
 #include "../../linux-g++/qplatformdefs.h"



Qtライブラリのクロスビルド

Qt 6をクロスビルドおよびインストールする。

 # EGLFSの場合
 
 # ビルドディレクトリを作成
 mkdir /<Qtのソースコードがあるディレクトリ>/../build && cd /<Qtのソースコードがあるディレクトリ>/../build
 
 export CROSS_PI_PATH=/<GCC ARMツールチェインのインストールディレクトリ>
 
 # Raspberry Pi OS 32ビットの場合
 export CROSS_COMPILE=$CROSS_PI_PATH/bin/arm-linux-gnueabihf-
 
 # Raspberry Pi OS 64ビットの場合
 export CROSS_COMPILE=$CROSS_PI_PATH/bin/aarch64-linux-gnu-
 
 # システムルードディレクトリの指定
 export SYSTEMROOT=<Raspberry Pi OSのシステムルートディレクトリ>
 export PKG_CONFIG_SYSROOT_DIR=$SYSTEMROOT
 
 export PKG_CONFIG_PATH=$PKG_CONFIG_SYSROOT_DIR/usr/lib/pkgconfig:$PKG_CONFIG_SYSROOT_DIR/usr/lib/arm-linux-gnueabihf/pkgconfig
 export PKG_CONFIG_LIBDIR=$PKG_CONFIG_SYSROOT_DIR/usr/lib/pkgconfig:$PKG_CONFIG_SYSROOT_DIR/usr/lib/arm-linux-gnueabihf/pkgconfig:$PKG_CONFIG_SYSROOT_DIR/usr/share/pkgconfig
 
 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-raspberrypi-new-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をインストールする場合
 -DFEATURE_xcb_xlib=OFF   \  # EGLFSを使用する場合
 -DQT_FEATURE_xcb=OFF     \  # EGLFSを使用する場合
 -DQT_FEATURE_xlib=OFF    \  # EGLFSを使用する場合
 -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=<Raspberry Pi向けQt 6ライブラリを配置するディレクトリ>                                        \
 -DCMAKE_INSTALL_PREFIX=<Qtソフトウェアを配置するディレクトリ>                                                     \
 -DCMAKE_PREFIX_PATH=$SYSROOT/usr/lib/arm-linux-gnueabihf  # Raspberry Pi OS 32ビットの場合
 -DCMAKE_PREFIX_PATH=$SYSROOT/usr/lib/aarch64-linux-gnu    # Raspberry Pi OS 64ビットの場合


 # XCBの場合
 
 # ビルドディレクトリを作成
 mkdir /<Qtのソースコードがあるディレクトリ>/../build && cd /<Qtのソースコードがあるディレクトリ>/../build
 
 export CROSS_PI_PATH=/<GCC ARMツールチェインのインストールディレクトリ>
 
 # Raspberry Pi OS 32ビットの場合
 export CROSS_COMPILE=$CROSS_PI_PATH/bin/arm-linux-gnueabihf-
 
 # Raspberry Pi OS 64ビットの場合
 export CROSS_COMPILE=$CROSS_PI_PATH/bin/aarch64-linux-gnu-
 
 # システムルードディレクトリの指定
 export SYSTEMROOT=<Raspberry Pi OSのシステムルートディレクトリ>
 export PKG_CONFIG_SYSROOT_DIR=$SYSTEMROOT
 
 export PKG_CONFIG_PATH=$PKG_CONFIG_SYSROOT_DIR/usr/lib/pkgconfig:$PKG_CONFIG_SYSROOT_DIR/usr/lib/arm-linux-gnueabihf/pkgconfig
 export PKG_CONFIG_LIBDIR=$PKG_CONFIG_SYSROOT_DIR/usr/lib/pkgconfig:$PKG_CONFIG_SYSROOT_DIR/usr/lib/arm-linux-gnueabihf/pkgconfig:$PKG_CONFIG_SYSROOT_DIR/usr/share/pkgconfig
 
 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-raspberrypi-new-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をインストールする場合
 -DFEATURE_xcb_xlib=ON    \  # XCBを使用する場合
 -DQT_FEATURE_xcb=ON      \  # XCBを使用する場合
 -DQT_FEATURE_xlib=ON     \  # XCBを使用する場合
 -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=<Raspbeery Pi向けQt 6ライブラリを配置するディレクトリ>                                     \
 -DCMAKE_INSTALL_PREFIX=<Qtソフトウェアを配置するディレクトリ>                                                     \
 -DCMAKE_PREFIX_PATH=$SYSROOT/usr/lib/arm-linux-gnueabihf  # Raspberry Pi OS 32ビットの場合
 -DCMAKE_PREFIX_PATH=$SYSROOT/usr/lib/aarch64-linux-gnu    # Raspberry Pi OS 64ビットの場合


 # 共通
 cmake --build . --parallel $(nproc)  または  cmake --build . --parallel $(nproc) > compile.txt 2>&1
 cmake --install .


もし、Linux PCで使用するQtライブラリを配置するディレクトリにrccファイルが存在しない場合は、rccファイルをQtライブラリのbinディレクトリにコピーする。
これは、Qtライブラリを使用するプログラムをビルドする場合は、rccファイルが必要となるためである。

cp /<Qtのソースコードがあるディレクトリ>/qtbase/bin/rcc /<ホストPCで使用するQtライブラリを配置するディレクトリ>/bin



Qt 6ライブラリのアップロード

ビルドしたQtライブラリを、Raspberry Piにデプロイする。
~/Program/Qt_Embedded/Qt6ディレクトリに存在する全てのファイルを、Raspberry Piの/usr/localディレクトリに同期させる。

rsync -avz --rsh="ssh -p <ポート番号> -i <秘密鍵のフルパス>" \
~/Program/Qt_Embedded/Target <Raspberry Piのユーザ名>@<Raspberry Piのホスト名またはIPアドレス>:/home/<Raspberry Piのユーザ名>/InstallSoftware/Qt_6_x_x


※注意
Raspberry PiにアップロードしたQtライブラリの所有者がrootになっている場合があるため、
以下のコマンドを実行して、所有者をローカルユーザに変更する必要がある。

sudo chown -R <Raspberry Piのユーザ名>:<Raspberry Piのグループ名> ~/InstallSoftware/Qt_6_x_x


Raspberry PiのリンカがQtライブラリを読み込むようにするため、以下のコマンドを実行する。
/etc/ld.so.conf.dディレクトリに配置する場合、Raspberry Pi 2B / 3Bでは、ファイル名の先頭に"00"を付加すること。

# .profileファイルに設定する場合
export LD_LIBRARY_PATH="/home/<Raspberry Piのユーザ名>/InstallSoftware/Qt_6_x_x/lib:$LD_LIBRARY_PATH"

# /etc/ld.so.conf.dディレクトリに配置する場合
echo /home/<Raspberry Piのユーザ名>/InstallSoftware/Qt_6_x_x/lib | sudo tee /etc/ld.so.conf.d/00-Qt_6_x_x.conf
sudo ldconfig


これにより、Raspberry PiでQtライブラリが使用できる。


Qt Creatorの設定

キットの設定

Qt Creatorを起動して、キットの設定を行う。

  • QMakeの設定
    クロスコンパイルしたQt 6のインストールディレクトリに移動する。
    binディレクトリにあるhost-qmakeファイルのシンボリックファイル(ここでは、qmake-hostファイルとする)を作成する。
    ln -s host-qmake qmake-host

  • キットの作成
    [編集] - [設定]を選択して、[設定]画面を開く。
    [設定]画面左にある[キット] - [設定]画面右の[Qtバージョン]タブから[追加]ボタンを押下する。
    上記で作成したシンボリックファイルを選択する。

    [設定]画面左にある[キット] - [設定]画面右の[キット]タブから[追加]ボタンを押下する。
    [デバイスの種類]プルダウンから、[Remote Linux Device]を選択する。
    [デバイス]プルダウンから、[設定]画面左にある[デバイス]で作成したターゲットを選択する。
    [ビルドデバイス]プルダウンから、[ローカルPC]を選択する。
    [Sysroot]項目に、Raspberry Piのシステムルートディレクトリのパスを入力する。
    [コンパイラ]項目の[C]プルダウンから、C向けのクロスコンパイラを選択する。
    [コンパイラ]項目の[C++]プルダウンから、C++向けのクロスコンパイラを選択する。
    [GDB]プルダウンから、クロスコンパイラ向けGDBを選択する。
    [Qtバージョン]プルダウンから、上記で設定した[Qtバージョン]を選択する。
    [Qt mkspec]項目から、デバイス定義ファイル (/<クロスコンパイルしたQt 6のインストールディレクトリ>/mkspecs/devices/linux-raspberrypi-new-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/<Raspberry Piのユーザ名>/InstallSoftware/Qt_6_x_x/bin ※PATHの設定が既に存在する場合は、追記する
  • Variable : LD_LIBRARY_PATH (Raspberry Piの~/.profileファイルに環境変数LD_LIBRARY_PATHを設定している場合)
    Value : /home/<Raspberry Piのユーザ名>/InstallSoftware/Qt_6_x_x/lib:/home/<Raspberry Pi's User Name>/InstallSoftware/Qt_6_x_x/plugins/qmltooling
  • Variable : QML_IMPORT_PATH
    Value : /home/<Raspberry Piのユーザ名>/InstallSoftware/Qt_6_x_x/qml
  • Variable : QML2_IMPORT_PATH
    Value : /home/<Raspberry Piのユーザ名>/InstallSoftware/Qt_6_x_x/qml
  • Variable : QT_PLUGIN_PATH
    Value : /home/<Raspberry Piのユーザ名>/InstallSoftware/Qt_6_x_x/plugins
  • Variable : QT_QPA_PLATFORM_PLUGIN_PATH
    Value : /home/<Raspberry Piのユーザ名>/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/<Raspberry Piのユーザ名>/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/<Raspberry Piのユーザ名>/InstallSoftware/Qt_6_x_x/lib:/home/<Raspberry Piのユーザ名>/InstallSoftware/Qt_6_x_x/plugins/qmltooling</value>
     <value type="QString">QML_IMPORT_PATH=/home/<Raspberry Piのユーザ名>/InstallSoftware/Qt_6_x_x/qml</value>
     <value type="QString">QML2_IMPORT_PATH=/home/<Raspberry Piのユーザ名>/InstallSoftware/Qt_6_x_x/qml</value>
     <value type="QString">QT_PLUGIN_PATH=/home/<Raspberry Piのユーザ名>/InstallSoftware/Qt_6_x_x/plugins</value>
     <value type="QString">QT_QPA_PLATFORM_PLUGIN_PATH=/home/<Raspberry Piのユーザ名>/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側にダウンロードしているRaspberry Piのシステムルートディレクトリを検索する。
そのため、GDBにターゲット側のRaspberry Piのシステムルートディレクトリを検索するように設定する必要がある。

これは、Qt Creatorメイン画面から、[ツール]メニューバー - [オプション] - [デバッガ] - [GDB]タブ - [追加の起動コマンド]に、以下の内容を設定する。
ただし、この設定はQt Quickを使用する時のみである。(Qt Widgetを使用する場合は設定不要)

set sysroot target:/


しかし、上記の[追加の起動コマンド]において、set sysroot target:/オプションを使用する場合、デバッグの開始に時間が掛かる。
そのため、以下のように、[追加の起動コマンド]を記述して、
システムルートディレクトリに対して、Qtライブラリのインストールディレクトリのシンボリックリンクを作成することを推奨する。

システムルートディレクトリに対して、Linux PCに保存したRaspberry Pi向けのQtライブラリがあるディレクトリのシンボクリックリンクを作成する。

mkdir -p /<Raspberry Piのシステムルートディレクトリ>/home/mobian/InstallSoftware
ln -s /<Qtライブラリのインストールディレクトリ> /<Raspberry Piのシステムルートディレクトリ>/home/mobian/InstallSoftware

# シンボリックリンク名の変更
mv /<Raspberry Piのシステムルートディレクトリ>/home/mobian/InstallSoftware/<Qtライブラリのインストールディレクトリ> \
   /<Raspberry Piのシステムルートディレクトリ>/home/mobian/InstallSoftware/Qt_6_x_x


Qt Creatorメイン画面から、[ツール]メニューバー - [オプション] - [デバッガ] - [GDB]タブ - [追加の起動コマンド]に、以下の内容を設定する。

# Kit名に"RaspberryPi"という文字列が入っている場合のみ、Raspberry Piのシステムルートディレクトリを参照する
# x86 / x64のKitを使用する場合は、Raspberry Piのシステムルートディレクトリを参照しない
[ -n $(grep -i RaspberryPi %{ActiveProject:Kit:Name}) ] && set sysroot /<Raspberry Piのシステムルートディレクトリ>

# または

set sysroot /<Raspberry Piのシステムルートディレクトリ>


これにより、Raspberry PiでQtライブラリが使用できる。


Qtライブラリを個別にインストールする場合

Qtライブラリを個別にインストールする場合は、ライブラリを個別にダウンロードしてインストールする。
<Qtライブラリ>と<Qtのバージョン>は合致するものを指定すること。

git clone https://github.com/qt/<Qtライブラリ名>.git -b <Qtのバージョン>
# または
git clone https://code.qt.io/cgit/qt/<Qtライブラリ名>.git -b <Qtのバージョン>

cd <Qtライブラリ名>

~/Program/Qt_Embedded/Qt5/bin/qmake
make -j $(nproc)
make install


QtライブラリをRaspberry Piにデプロイする。

rsync -avz --rsh="ssh -p <ポート番号> -i <秘密鍵のフルパス>" /<Qtライブラリを配置するディレクトリ> \
      <Raspberry Piのユーザ名>@<Raspberry Piのホスト名またはIPアドレス>:/home/<Raspberry Piのユーザ名>/<Qtライブラリをインストールするディレクトリ>



ビルドエラー関連

ビルドエラー : 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に関するエラー

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に関するエラー

ビルド時において、以下に示すようなエラーが出力される場合がある。

error: 'google::protobuf::FileDescriptor::Syntax google::protobuf::FileDescriptor::syntax() const'


この時、以下に示すcmakeコマンドのオプションを付加する。

cmake -G Ninja \

# ...略

-DBUILD_qtgrpc

# ...略



CLion / Qt 6との連携

ツールチェーンの設定

CLionを起動する。
[ファイル]メニューバー - [設定]を選択する。
[設定]画面の左ペインにある[ビルド、実行、デプロイ] - [ツールチェーン]を選択する。
[設定]画面の右ペインにある[+]アイコンを選択して、[システム]を選択する。

  • ツールチェーンの設定項目
    • [名前]
      任意の名前を入力する。
    • [CMake:]
      Raspberry Pi向けQtライブラリのビルドに使用したCMakeファイルのパスを入力する。
    • [ビルドツール:]
      Raspberry Pi向けQtライブラリのビルドに使用したNinjaファイルのパスを入力する。
    • [C コンパイラー:]
      Raspberry Pi向けQtライブラリのビルドに使用したGCCファイルのパスを入力する。
      32ビット向けの例: /<GCCツールチェーンのインストールディレクトリ>/bin/arm-linux-gnueabihf-gcc
      64ビット向けの例: /<GCCツールチェーンのインストールディレクトリ>/bin/aarch64-linux-gnu-gcc
    • [C++ コンパイラー:]
      Raspberry Pi向けQtライブラリのビルドに使用したG++ファイルのパスを入力する。
      32ビット向けの例: /<GCCツールチェーンのインストールディレクトリ>/bin/arm-linux-gnueabihf-g++
      64ビット向けの例: /<GCCツールチェーンのインストールディレクトリ>/bin/aarch64-linux-gnu-g++
    • [デバッガー:]
      GCCツールチェーンのGDBファイルのパスを入力する。
      32ビット向けの例: /<GCCツールチェーンのインストールディレクトリ>/bin/arm-linux-gnueabihf-gdb
      64ビット向けの例: /<GCCツールチェーンのインストールディレクトリ>/bin/aarch64-linux-gnu-gdb


[設定]画面の右ペイン下部にある[適用]ボタンを押下する。

CMakeの設定

[ファイル]メニューバー - [設定]を選択する。
[設定]画面の左ペインにある[ビルド、実行、デプロイ] - [CMake]を選択する。
[設定]画面の右ペインにある[+]アイコンを選択する。

  • CMakeの設定項目
    • [名前]
      任意の名前を入力する。
    • [ビルドタイプ:]プルダウン
      [Debug]または[Release]を選択する。
    • [ツールチェーン:]プルダウン
      上記で設定したツールチェーン名を選択する。
    • [ジェネレーター:]プルダウン
      [デフォルトを使用する]を選択する。
      32ビット向けの例: /<GCCツールチェーンのインストールディレクトリ>/bin/arm-linux-gnueabihf-gcc
      64ビット向けの例: /<GCCツールチェーンのインストールディレクトリ>/bin/aarch64-linux-gnu-gcc
    • [環境:]
      [環境:]のテキストアイコンを選択して、[環境設定]画面を開く。
      画面右上の[+]ボタンを押下して、各環境変数を設定する。
      • CMAKE_C_COMPILER
        Raspberry Pi向けQtライブラリのビルドに使用したGCCファイルのパスを入力する。
        32ビット向けの例: /<GCCツールチェーンのインストールディレクトリ>/bin/arm-linux-gnueabihf-gcc
        64ビット向けの例: /<GCCツールチェーンのインストールディレクトリ>/bin/aarch64-linux-gnu-gcc
      • CMAKE_CXX_COMPILER
        Raspberry Pi向けQtライブラリのビルドに使用したG++ファイルのパスを入力する。
        32ビット向けの例: /<GCCツールチェーンのインストールディレクトリ>/bin/arm-linux-gnueabihf-g++
        64ビット向けの例: /<GCCツールチェーンのインストールディレクトリ>/bin/aarch64-linux-gnu-g++
      • CMAKE_PREFIX_PATH
        Raspberry Pi向けQtライブラリのインストールディレクトリのパスを入力する。
        例: <Raspberry Pi向けQtライブラリのインストールディレクトリ>
      • CMAKE_TOOLCHAIN_FILE
        Raspberry Pi向けQtライブラリのインストールディレクトリにあるビルド向けツールチェーンファイルのパスを入力する。
        例: /<Raspberry Pi向けQtライブラリのインストールディレクトリ>/lib/cmake/Qt6/qt.toolchain.cmake
      • QT_QMAKE_EXECUTABLE
        Raspberry Pi向けQtライブラリのインストールディレクトリにあるqmakeファイルのパスを入力する。
        例: /<Raspberry Pi向けQtライブラリのインストールディレクトリ>/bin/qmake-host


[設定]画面の右ペイン下部にある[適用]ボタンを押下する。

SSHの設定

[ファイル]メニューバー - [設定]を選択する。
[設定]画面の左ペインにある[ツール] - [SSH 構成]を選択する。
[設定]画面の右ペインにある[+]アイコンを選択する。

  • SSH構成の設定項目
    • [ホスト:]
      Raspberry PiのIPアドレスまたはホスト名を入力する。
    • [ユーザー名:]
      Raspberry Piのユーザ名を入力する。
    • [認証タイプ:]プルダウン
      [パスワード]または[キーペア]を選択する。
    • [秘密鍵ファイル:] (キーペアを選択した場合)
      秘密鍵ファイルのパスを入力する。
    • [パスフレーズ:] (キーペアを選択した場合、かつ、パスフレーズを設定した場合)
      秘密鍵のパスフレーズを入力する。
    • [構成ファイル ~/.ssh/configの構文解析]チェックボックス
      任意


[接続テスト]ボタンを押下して、Raspberry PiにSSH接続する。

[設定]画面の右ペイン右下にある[適用]ボタンを押下する。

各プロジェクトの設定

CLionを起動して、[ファイル]メニューバー - [新規] - [プロジェクト...]を選択する。
[新規プロジェクト]画面から、[Qt Console 実行可能ファイル]または[Qt Widgets 実行可能ファイル]を選択する。

新規プロジェクトの作成後、[実行]メニューバー - [実行構成の編集...]を選択する。
[実行/デバッグ構成]画面が開くので、画面左上にある[+]ボタンを押下して、[リモート GDB サーバー]を選択する。
画面左ペインに[リモート GDB サーバー]が追加される。
画面左ペインに[リモート GDB サーバー]を選択して、各種設定を行う。

  • [ターゲット:]プルダウン
    プロジェクト名を選択する。
  • [実行可能ファイル:]プルダウン
    プロジェクト名を選択する。
  • [GDB:]プルダウン
    上記のツールチェーンの作成セクションで設定したGDBを選択する。
  • [資格情報:]プルダウン
    上記のSSHの設定セクションで設定したSSHを選択する。
  • [実行可能ファイル...]ラジオボタン
    任意
  • [アップロードパス:]
    実行可能バイナリが配置されるRaspberry Pi上のディレクトリを入力する。
    例: /home/<Raspberry Piのユーザ名>/CLion/Sample1/debug
  • ['target remote' ...]
    自動的に入力される。
    例: <IPアドレスまたはホスト名>:1234
  • [GDB サーバー引数:]
    Qt WidgetsまたはQMLを使用するプロジェクトの場合、デバッグまたは実行時において、実行可能バイナリに-platform waylandオプションを付加する必要がある。
    例: :<GDBサーバのポート番号 例: 1234> /<実行可能バイナリが配置されるRaspberry Pi上のディレクトリ>/debug/<実行バイナリのファイル名> -platform wayland


次に、[拡張 GDB サーバーオプション]項目を設定する。
この設定は、Raspberry PiにアップロードしたQtライブラリにおいて、デバッグまたは実行に関する設定を行う。

  • [作業ディレクトリ:]
    何も入力しない。
  • [環境変数:]
    [環境変数:]項目の右にあるテキストアイコンを選択する。
    [環境変数]画面が開くので、画面左上にある[+]ボタンを押下して各種設定を入力する。
    • DISPLAY
      :0
    • QT_QPA_PLATFORMTHEME
      Qt 6の場合 : Qt6ct
    • PATH
      Raspberry Pi上のQt6ライブラリをアップロードしたbinディレクトリのパスを入力する。
      例: /<Qt6ライブラリをアップロードしたディレクトリ>/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
    • LD_LIBRARY_PATH
      Raspberry Pi上の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と入力する。


また、[拡張 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 <Raspberry Piのシステムルートディレクトリ>


CLionを起動して、任意のプロジェクトを開く。
CLionのメイン画面左にあるプロジェクトに.gdbinitファイル、または、.lldbinitファイルが追加されているかどうかを確認する。