組み込み Linux デバイスの設定
Qt を特定のデバイス用にクロスコンパイルするには、ツールチェーンと sysroot が必要です。ツールチェーンには、gcc または他のコンパイラ、およびクロスコンパイル用に構築された関連ツールが含まれます。つまり、これらのツールはホスト・システム(通常はx64)上で動作し、ターゲット・アーキテクチャ(例えば32ビットまたは64ビットのARM)用のバイナリを生成する。sysrootには、ターゲット・システム用のヘッダーとライブラリーが含まれており、ホスト上でライブラリーやアプリケーションのコンパイルとリンクができます。
この概要ページでは、YoctoやBuildrootのようなディストリビューションのビルドシステムを使用しない、一般的なアプローチについて説明します。適切なツールチェーンと sysroot が利用可能であれば、Qt をクロスコンパイルしてデバイスにデプロイすることは常に可能です。
警告 このページは、一般的でハイレベルな概要しか提供できません。ビルド環境、ターゲットデバイス、ツールチェインによって、細部は大きく異なります。不明な点があれば、システム・インテグレーターにお問い合わせください。ビルド済みのリファレンス・イメージや SDK については、Boot to Qtを参照してください。
X11 や Wayland のようなウィンドウシステムなしで Qt ベースのアプリケーションを実行する場合、デバイスによっては EGL や OpenGL ES をサポートするためにベンダー固有のアダプテーションコードが必要になります。これはEGLFSプラットフォーム・プラグインのバックエンドという形で提供されます。これは、ソフトウェアベースのレンダリング専用である LinuxFB プラットフォームプラグインを使用するような、非アクセラレーションプラットフォームには関係ありません。Qt 6の時点で、多くの組み込みシステムはdrmを使用してビデオモードを設定し、ディスプレイコネクタとグラフィカルサーフェスを管理しています。例えば、NXP i.MX8ベースのデバイスやRaspberry Pi 4はこのアプローチを使用するため、EGLFSのバックエンドとして最もよく使用されるのはeglfs_kmsです。このバックエンドは、drm
、サーフェスとバッファの管理にgbm
を使用して、EGLとOpenGL ESベースのレンダリングを可能にします。NXP i.MX6のような古いデバイスでは、eglfs_viv
のような専用のeglfsバックエンドを使用して、EGLウィンドウサーフェスをフレームバッファに接続するレガシーなGPUベンダー固有のアプローチを使用し続けます。
注意: Qt は、組み込みデバイスのソフトウェアスタックの中の 1 つのコンポーネントに過ぎないことに注意してください。特にアクセラレーテッドグラフィックスが関係する場合、Qt はユーザ空間とカーネルコンポーネント、例えばディスプレイドライバのための適切な設定を持った、機能的なグラフィックススタックを期待します。これらのコンポーネントは Qt の領域外であり、アクセラレーテッドグラフィックスを含むベースシステムが完全に機能し、最適であることを保証するのはシステムインテグレータの責任です。
Embedded Linux システムのグラフィックスと入力設定に関する詳細は、Qt for Embedded Linux を参照してください。
ツールチェインファイルとデバイスマークスペック
Qt 5 では、qtbase/mkspecs/devicesディレクトリにあるデバイススペックを使用します。これらのファイルには、特定のデバイスのための適切なコンパイラとリンカのフラグが含まれており、また、正しいEGLとOpenGL ESライブラリがsysrootの標準的でない場所にある場合に、ピックアップされるようにします。
例えば、次のような configure コマンドで Raspberry Pi 2 用に Qt 5 のビルドを設定することができます:
./configure -release -opengl es2 -device linux-rasp-pi2-g++ -device-option CROSS_COMPILE=$TOOLCHAIN/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf- -sysroot $ROOTFS -prefix /usr/local/qt5
注意: ninja
の実行ファイルがある場合、configure は常にNinjaジェネレーターとビルドツールを使用します。Ninjaはクロスプラットフォームで、機能が豊富で、パフォーマンスが高く、すべてのプラットフォームで推奨されています。他のジェネレータを使用しても動作するかもしれませんが、公式にはサポートされていません。
Qt 6とCMakeでは、この方法ではもはや十分ではありません。むしろ、設定を行う前にCMakeツールチェインファイルを提供する必要があります。このファイルで、コンパイラやリンカのフラグ、ツールチェインやシスルート特有の癖をカスタマイズします。
以下のセクションでは、最小限のカスタマイズで多くの場合に使用できるツールチェーンファイルを紹介します。これは、このブログ記事で紹介したアプローチに基づいている。
注: 以下に紹介するツールチェーン・ファイルは一例であり、特定のデバイス用にさらなるカスタマイズが必要になることがよくあります。また、ユーザーやシステム・インテグレーターは、適切と思われる方法で独自のツールチェーン・ファイルを自由に作成することができます。
Qt 6.0 では、CMake が Qt 自体をビルドするための唯一のビルドシステムとしてサポートされていますが、qmake
を使用してアプリケーションをビルドすることもできます。クロスコンパイルで機能するqmake
のセットアップを行うには、CMake や configure にレガシーな引数を指定する必要があります。
ホストツール
Qt のクロスコンパイルには、Qt のホストビルドが必要です。ビルド中に、moc
、rcc
、qmlcachegen
、qsb
などのツールが呼び出されます。例えば、x64マシンでARM用にクロスコンパイルする場合、同じQtバージョンのローカルx64ビルドを最初に利用可能にする必要があります。このQtビルドへのパスは、configureやcmakeに渡されます。
Qtの設定
以下が利用可能であると仮定します:
$HOME/rpi-sdk
以下のツールチェインと sysroot、$HOME/qt-cross
にある Qt のホストビルド、$HOME/qt-host
にある Qt のホストビルド。
さらに、設定する前に以下のことを決めておく必要があります:
- Qt のビルドが完了したら、ローカルシステムのどこにインストールするか?この例では
$HOME/qt6-rpi
を使います。 - Qt のビルドはデバイスのどこに配置されますか?この例では
/usr/local/qt6
を使います。
この例では、Yocto 経由で生成された Raspberry Pi 4 SDK (toolchain+sysroot) を使用しますが、ここでの説明は完全に一般的なものであり、Yocto に依存するものではありません。ツールチェイン・ファイルを正しいクロス・コンパイラやその他のパスで更新すれば、他のツールチェインやsysrootでも手順は同じです。
build
:
$HOME/qt-cross/qtbase/configure -release -opengl es2 -nomake examples -nomake tests \ -qt-host-path $HOME/qt-host \ -extprefix $HOME/qt6-rpi \ -prefix /usr/local/qt6 \ -- -DCMAKE_TOOLCHAIN_FILE=$HOME/qt-cross/toolchain.cmake
実際には、このconfigureコマンドは、以下のCMakeの直接呼び出しと同等です:
cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DINPUT_opengl=es2 -DQT_BUILD_EXAMPLES=OFF -DQT_BUILD_TESTS=OFF \ -DQT_HOST_PATH=$HOME/qt-host \ -DCMAKE_STAGING_PREFIX=$HOME/qt6-rpi \ -DCMAKE_INSTALL_PREFIX=/usr/local/qt6 \ -DCMAKE_TOOLCHAIN_FILE=$HOME/qt-cross/toolchain.cmake \ $HOME/qt-cross/qtbase
適切なツールチェーンファイルがあれば、これだけでQtビルドが生成され、CMakeを使ってアプリケーションをビルドできるようになります。アプリケーションをqmake
でもビルドできるようにするには、上記のすべての引数に加え、Qt 5 スタイルのデバイス仕様とデバイス・オプションを指定する必要があります:
$HOME/qt-cross/qtbase/configure ... ... -device linux-rasp-pi4-v3d-g++ \ -device-option CROSS_COMPILE=$HOME/rpi_sdk/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi- \ -device-option DISTRO_OPTS="hard-float" \ ...
デフォルトでは、クロスコンパイル時に、ターゲットデバイス上で動作する予定の Qt ライブラリとツールだけがビルドされます。moc
やuic
のようなビルド関連ツールはビルドされません。このようなツールのビルドは、QT_FORCE_BUILD_TOOLS
をON
に設定することで有効にできます。
注: QT_FORCE_BUILD_TOOLS
を有効にすると、qmake
などのツールのターゲット・バイナリがステージング・ロケーションにインストールされます。したがって、アプリケーションのビルドにqmake
を使用する場合は、代わりにhost-qmake
スクリプトを呼び出してください。
コンフィギュレーションがエラーなしで完了したら、cmake --build . --parallel
を実行してビルドする。ビルドが完了したら、cmake --install .
を実行して、結果を$HOME/qt6-rpi
にインストールします。そこから、rsync、scp、または他の方法を使用して、Qt ビルドをデバイスにデプロイできます。
$HOME/qt6-rpi
個別の Qt モジュールをビルドする場合、ステージングロケーションのbin
ディレクトリからqt-configure-module
スクリプトを使用して、qtdeclarative や qtquick3d などの追加モジュールを設定できます。これらのモジュールはcmake --build .
を使ってビルドし、次のように実行してステージングロケーションにインストールします。cmake --install .
注意: ビルドを開始する前に、設定ステップの出力を常に注意深く調べてください。コンフィギュレーション時に必須機能が有効になっていなければ、ビルドしてデバイスにデプロイしても無駄です。
例えば、OpenGLによるグラフィックスの高速化が必要な場合は、以下の機能に特に注意してください:
EGL .................................... yes OpenGL: Desktop OpenGL ....................... no OpenGL ES 2.0 ........................ yes OpenGL ES 3.0 ........................ yes ... evdev .................................. yes libinput ............................... yes ... EGLFS .................................. yes EGLFS details: EGLFS OpenWFD ........................ no EGLFS i.Mx6 .......................... no EGLFS i.Mx6 Wayland .................. no EGLFS RCAR ........................... no EGLFS EGLDevice ...................... yes EGLFS GBM ............................ yes EGLFS VSP2 ........................... no EGLFS Mali ........................... no EGLFS Raspberry Pi ................... no EGLFS X11 ............................ no LinuxFB ................................ yes
Raspberry Pi 4 の例では、EGL、OpenGL ES、EGLFS GBM
がすべてyes
として報告されることを期待します。そうでなければ、EGLFS プラットフォーム・プラグインとそのeglfs_kmsバックエンドはデバイス上で機能しません。マウス、キーボード、およびタッチ入力を機能させるには、evdev
またはlibinput
のいずれかを有効にする必要があります。
同様に、X11 をデバイスのウィンドウ・システム(またはその 1 つ)として使用する場合は、xcb と X11 関連の機能がyes
としてマークされていることを確認してください。
ツールチェーン・ファイルの例
$HOME/rpi-sdk
の下に利用可能なsysrootとツールチェーンがあると仮定します。TARGET_SYSROOT
とCROSS_COMPILER
は、使用するツールチェーンとsysrootに合わせて調整する必要があります。ここでの例は、ある特定の、Yoctoが生成したSDKにのみ適しています。CMAKE_C_COMPILER
とCMAKE_CXX_COMPILER
についても同様である。
PKG_CONFIG_*のような環境変数を提供するラッパースクリプトには依存しない。むしろ、.pcファイルへのパスはツールチェーンファイルで指定される。別のsysrootでは、PKG_CONFIG_LIBDIR
の調整が必要になる可能性が高い。例えば、Raspberry Pi OS(旧Raspbian)イメージから生成されたsysrootでは、代わりに/usr/lib/arm-gnueabihf/pkgconfig
。
コンパイラーとリンカーのフラグは、この例では最適である必要はありません。ターゲット・デバイスに合わせて調整してください。
サンプルのツールチェーンファイルにおけるCMakeの詳細については、このブログ記事と CMakeのドキュメントを参照してください。
cmake_minimum_required(VERSION 3.18) include_guard(GLOBAL) set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR arm) set(TARGET_SYSROOT /home/user/rpi-sdk/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi) set(CROSS_COMPILER /home/user/rpi-sdk/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi) set(CMAKE_SYSROOT ${TARGET_SYSROOT}) set(ENV{PKG_CONFIG_PATH} "") set(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_SYSROOT}/usr/lib/pkgconfig:${CMAKE_SYSROOT}/usr/share/pkgconfig) set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT}) set(CMAKE_C_COMPILER ${CROSS_COMPILER}/arm-poky-linux-gnueabi-gcc) set(CMAKE_CXX_COMPILER ${CROSS_COMPILER}/arm-poky-linux-gnueabi-g++) set(QT_COMPILER_FLAGS "-march=armv7-a -mfpu=neon -mfloat-abi=hard") set(QT_COMPILER_FLAGS_RELEASE "-O2 -pipe") 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) include(CMakeInitializeConfigs) function(cmake_initialize_per_config_variable _PREFIX _DOCSTRING) if (_PREFIX MATCHES "CMAKE_(C|CXX|ASM)_FLAGS") set(CMAKE_${CMAKE_MATCH_1}_FLAGS_INIT "${QT_COMPILER_FLAGS}") foreach (config DEBUG RELEASE MINSIZEREL RELWITHDEBINFO) if (DEFINED QT_COMPILER_FLAGS_${config}) set(CMAKE_${CMAKE_MATCH_1}_FLAGS_${config}_INIT "${QT_COMPILER_FLAGS_${config}}") endif() endforeach() endif() if (_PREFIX MATCHES "CMAKE_(SHARED|MODULE|EXE)_LINKER_FLAGS") foreach (config SHARED MODULE EXE) set(CMAKE_${config}_LINKER_FLAGS_INIT "${QT_LINKER_FLAGS}") endforeach() endif() _cmake_initialize_per_config_variable(${ARGV}) endfunction()
ターゲットデバイス用にアプリケーションをビルドする
Qt のビルドが完了し、ステージングロケーションにインストールされたら、サンプルやアプリケーションをビルドすることができます。
CMakeを使用して、ステージングロケーションのbin
ディレクトリ(例では$HOME/qt6-rpi
)にある生成されたqt-cmake
スクリプトを使用して設定し、ninja
を実行します。例えば、次のようになります:
$HOME/qt6-rpi/bin/qt-cmake . cmake --build .
生成されたアプリケーション・バイナリをデバイスにデプロイできます。qt-cmake
ヘルパースクリプトを使用すると便利です。このスクリプトは、Qt のビルドに使用されたツールチェーンファイルが確実にロードされるので、アプリケーションごとに繰り返し指定する必要がありません。
Qt 自身とは異なり、qmake を使ったアプリケーションのビルドは、Qt 6.0 でも、適切なデバイス仕様が利用可能で、Qt を設定する際に CMake や configure に適切なレガシー引数が渡されている限り、サポートされています。これがすべて正しい場合、qmake
とmake
を実行すると、ターゲットデバイス用のアプリケーションバイナリも生成されます。
プラットフォーム・プラグインと EGLFS のデフォルト
いったん設定されると、デフォルトのプラットフォーム・プラグインが選択されます。これは、-platform
引数を指定せず、QT_QPA_PLATFORM
環境変数を設定せずにアプリケーションを起動するときに使用されます。
同様に、EGLFSプラットフォーム・プラグインには複数のバックエンドがある。デフォルトは、利用可能性と事前に定義された優先順位に基づいて選択される。drmとgbmが利用可能な場合、デフォルトはeglfs_kmsバックエンドになる。これは、QT_QPA_EGLFS_INTEGRATION
環境変数を設定することで、常に実行時に上書きすることができます。
実行時に特定の値を強制することなく、ビルド時のデフォルトを変更するには、CMakeを一度実行した後に、以下の2つのCMakeキャッシュ変数を使用します:
QT_QPA_DEFAULT_PLATFORM
( ) - デフォルトのプラットフォームプラグインの名前。STRING
QT_QPA_DEFAULT_EGLFS_INTEGRATION
( ) - デフォルトのEGLFSバックエンド。STRING
これらの変数は、ツールチェーンファイル内で設定することもできます。
Qt の設定の詳細については、Qt Configure Options を参照してください。
本ドキュメントに含まれる文書の著作権は、それぞれの所有者に帰属します。 ここで提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。