Raspberry Pi 向けの Buildroot で Qt5 をカスタムビルドする方法
【令和元年版】Raspberry Pi 3 で Qt 5 をビルドして動かす方法 という記事で、Rasbpian を使って Qt 5 のアプリケーションを動かす環境を整えましたが、主にクロスコンパイラのバージョンが古いという理由で、別の環境が欲しくなったため、Buildroot を試してみることにしました。
Buildroot 自体でも Qt 5 を提供していて、カスタマイズも可能そうですが、それは今度試すことにして、今回は Qt は自分でビルドするようにしましょう。
Buildroot のビルド
https://buildroot.org/ から最新のパッケージをダウンロードします。

それでは、ビルドをしてみましょう。
$ mkdir -p ~/org/buildroot/ $ cd $_ $ mv ~/Downloads/buildroot-2019.05.tar.bz2 . $ tar xf buildroot-2019.05.tar.bz2 $ ls buildroot-2019.05 $ mkdir raspberry-pi3 $ cd $_ $ make O=$PWD -C ../buildroot-2019.05 raspberrypi3_defconfig $ make
しばらく待つと、デバイス向けのOSイメージとツールチェイン、rootfs が生成されます。
$ ls images bcm2710-rpi-3-b-plus.dtb bcm2710-rpi-3-b.dtb bcm2710-rpi-cm3.dtb boot.vfat rootfs.ext2 rootfs.ext4 rpi-firmware sdcard.img zImage $ ls host/bin/arm-buildroot-linux-uclibcgnueabihf-* host/bin/arm-buildroot-linux-uclibcgnueabihf-* host/bin/arm-buildroot-linux-uclibcgnueabihf-addr2line host/bin/arm-buildroot-linux-uclibcgnueabihf-ar host/bin/arm-buildroot-linux-uclibcgnueabihf-as host/bin/arm-buildroot-linux-uclibcgnueabihf-c++ host/bin/arm-buildroot-linux-uclibcgnueabihf-c++.br_real host/bin/arm-buildroot-linux-uclibcgnueabihf-c++filt host/bin/arm-buildroot-linux-uclibcgnueabihf-cc host/bin/arm-buildroot-linux-uclibcgnueabihf-cc.br_real host/bin/arm-buildroot-linux-uclibcgnueabihf-cpp host/bin/arm-buildroot-linux-uclibcgnueabihf-cpp.br_real host/bin/arm-buildroot-linux-uclibcgnueabihf-elfedit host/bin/arm-buildroot-linux-uclibcgnueabihf-g++ host/bin/arm-buildroot-linux-uclibcgnueabihf-g++.br_real host/bin/arm-buildroot-linux-uclibcgnueabihf-gcc host/bin/arm-buildroot-linux-uclibcgnueabihf-gcc-7.4.0 host/bin/arm-buildroot-linux-uclibcgnueabihf-gcc-7.4.0.br_real host/bin/arm-buildroot-linux-uclibcgnueabihf-gcc-ar host/bin/arm-buildroot-linux-uclibcgnueabihf-gcc-nm host/bin/arm-buildroot-linux-uclibcgnueabihf-gcc-ranlib host/bin/arm-buildroot-linux-uclibcgnueabihf-gcc.br_real host/bin/arm-buildroot-linux-uclibcgnueabihf-gcov host/bin/arm-buildroot-linux-uclibcgnueabihf-gcov-dump host/bin/arm-buildroot-linux-uclibcgnueabihf-gcov-tool host/bin/arm-buildroot-linux-uclibcgnueabihf-gprof host/bin/arm-buildroot-linux-uclibcgnueabihf-ld host/bin/arm-buildroot-linux-uclibcgnueabihf-ld.bfd host/bin/arm-buildroot-linux-uclibcgnueabihf-ldconfig host/bin/arm-buildroot-linux-uclibcgnueabihf-ldd host/bin/arm-buildroot-linux-uclibcgnueabihf-nm host/bin/arm-buildroot-linux-uclibcgnueabihf-objcopy host/bin/arm-buildroot-linux-uclibcgnueabihf-objdump host/bin/arm-buildroot-linux-uclibcgnueabihf-ranlib host/bin/arm-buildroot-linux-uclibcgnueabihf-readelf host/bin/arm-buildroot-linux-uclibcgnueabihf-size host/bin/arm-buildroot-linux-uclibcgnueabihf-strings host/bin/arm-buildroot-linux-uclibcgnueabihf-strip $ ls host/arm-buildroot-linux-uclibcgnueabihf/sysroot/ bin dev etc lib lib32 media mnt opt proc root run sbin sys tmp usr
Raspberry Pi3 上での動作確認
$ dd if=images/sdcard.img of=/dev/sdb bs=16M
実機上で起動が確認できました。
ただし、USB のキーボードの挿抜は検知しているものの、有効なデバイスとして使えないので、ログインができませんでした。
USB キーボードを使えるようにする
$ make menuconfig ToolChain ---> [*] Enable WCHAR support System configuration ---> /dev management (Dynamic using devtmpfs + eudev) ---> (Save) $ make $ dd if=images/sdcard.img of=/dev/sdb bs=16M
これで、キーボードが使えるようになり、root でログインできました。
ネットワークケーブルを接続するとネットワークにもつながりました。
Qt のビルド
開発版のダウンロード
$ mkdir -p ~/io/qt/code/qt/dev/ $ cd $_ $ git clone git://code.qt.io/qt/qt5/ --branch dev $ cd qt5 $ ./init-repository -f --module-subset=qtbase,qtdeclarative
Raspberry PI3 向けのビルド
$ mkdir -p ~/io/qt/code/qt/dev/shared $ cd $_ $ ../qt5/configure -opensource -confirm-license -release -make libs -no-widgets -no-pch -prefix /opt/qt --hostprefix $PWD/root -ccache -opengl es2 -device linux-rasp-pi3-g++ -device-option CROSS_COMPILE=~/org/buildroot/raspberry-pi3/host/bin/arm-buildroot-linux-uclibcgnueabihf- -sysroot ~/org/buildroot/raspberry-pi3/host/arm-buildroot-linux-uclibcgnueabihf/sysroot/ ... ERROR: Feature 'opengles2' was enabled, but the pre-condition '(config.win32 && !features.opengl-dynamic) || (!config.watchos && !features.opengl-desktop && libs.opengl_es2)' failed. ERROR: The OpenGL functionality tests failed! You might need to modify the include and library search paths by editing QMAKE_INCDIR_OPENGL[_ES2], QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your platform. Check config.log for details.
OpenGL ES 2 でエラーになっています。
Buildroot で OpenGL ES 2 を有効にする
ちょっと分かりにくいですけれど以下のオプションを有効にしましょう。
$ cd ~/org/buildroot/raspberry-pi3
$ make clean; make menuconfig
Target packages --->
Hardware handling --->
Firmware --->
[*] rpi-firmware
[*] rpi-userland
(Save)
$ make
Qt 側にも以下のパッチが必要です。
$ cd ~/io/qt/code/qt/dev/shared
$ rm config.cache
$ ./config.status
$ cat config.summary
Building on: linux-g++ (x86_64, CPU features: mmx sse sse2)
Building for: devices/linux-rasp-pi3-g++ (arm, CPU features: neon)
Target compiler: gcc 7.4.0
Configuration: cross_compile ccache compile_examples enable_new_dtags largefile neon shared rpath release c++11 c++14 c++1z concurrent dbus reduce_exports stl no-widgets
Build options:
Mode ................................... release
Optimize release build for size ........ no
Building shared libraries .............. yes
Using C standard ....................... C11
Using C++ standard ..................... C++17
Using ccache ........................... yes
Using new DTAGS ........................ yes
Using precompiled headers .............. no
Using LTCG ............................. no
Target compiler supports:
NEON ................................. yes
Build parts ............................ libs
Qt modules and options:
Qt Concurrent .......................... yes
Qt D-Bus ............................... yes
Qt D-Bus directly linked to libdbus .... no
Qt Gui ................................. yes
Qt Network ............................. yes
Qt Sql ................................. yes
Qt Testlib ............................. yes
Qt Widgets ............................. no
Qt Xml ................................. yes
Support enabled for:
Using pkg-config ....................... yes
udev ................................... yes
Using system zlib ...................... no
Zstandard support ...................... no
Qt Core:
DoubleConversion ....................... yes
Using system DoubleConversion ........ no
GLib ................................... no
iconv .................................. no
ICU .................................... no
Built-in copy of the MIME database ..... yes
Tracing backend ........................ <none>
Logging backends:
journald ............................. no
syslog ............................... no
slog2 ................................ no
PCRE2 .................................. yes
Using system PCRE2 ................... no
Qt Network:
getifaddrs() ........................... yes
IPv6 ifname ............................ yes
libproxy ............................... no
Linux AF_NETLINK ....................... yes
OpenSSL ................................ no
Qt directly linked to OpenSSL ........ no
OpenSSL 1.1 ............................ no
DTLS ................................... no
OCSP-stapling .......................... no
SCTP ................................... no
Use system proxies ..................... yes
GSSAPI ................................. no
Qt Gui:
Accessibility .......................... yes
FreeType ............................... yes
Using system FreeType ................ no
HarfBuzz ............................... yes
Using system HarfBuzz ................ no
Fontconfig ............................. no
Image formats:
GIF .................................. yes
ICO .................................. yes
JPEG ................................. yes
Using system libjpeg ............... no
PNG .................................. yes
Using system libpng ................ no
Text formats:
HtmlParser ........................... yes
CssParser ............................ yes
OdfWriter ............................ yes
MarkdownReader ....................... yes
Using system libmd4c ............... no
MarkdownWriter ....................... yes
EGL .................................... yes
OpenVG ................................. no
OpenGL:
Desktop OpenGL ....................... no
OpenGL ES 2.0 ........................ yes
OpenGL ES 3.0 ........................ no
OpenGL ES 3.1 ........................ no
OpenGL ES 3.2 ........................ no
Vulkan ................................. no
Session Management ..................... yes
Features used by QPA backends:
evdev .................................. yes
libinput ............................... no
INTEGRITY HID .......................... no
mtdev .................................. no
tslib .................................. no
xkbcommon .............................. no
X11 specific:
XLib ................................. no
XCB Xlib ............................. no
EGL on X11 ........................... no
QPA backends:
DirectFB ............................... no
EGLFS .................................. yes
EGLFS details:
EGLFS OpenWFD ........................ no
EGLFS i.Mx6 .......................... no
EGLFS i.Mx6 Wayland .................. no
EGLFS RCAR ........................... no
EGLFS EGLDevice ...................... no
EGLFS GBM ............................ no
EGLFS VSP2 ........................... no
EGLFS Mali ........................... no
EGLFS Raspberry Pi ................... yes
EGLFS X11 ............................ no
LinuxFB ................................ yes
VNC .................................... yes
Qt Sql:
SQL item models ........................ yes
Qt Widgets:
GTK+ ................................... no
Styles ................................. Fusion Windows
Qt PrintSupport:
CUPS ................................... no
Qt Sql Drivers:
DB2 (IBM) .............................. no
InterBase .............................. no
MySql .................................. no
OCI (Oracle) ........................... no
ODBC ................................... no
PostgreSQL ............................. no
SQLite2 ................................ no
SQLite ................................. yes
Using system provided SQLite ......... no
TDS (Sybase) ........................... no
Qt Testlib:
Tester for item models ................. yes
Qt QML:
QML network support .................... yes
QML debugging and profiling support .... yes
QML just-in-time compiler .............. yes
QML sequence object .................... yes
QML XML http request ................... yes
QML Locale ............................. yes
Qt QML Models:
QML list model ......................... yes
QML delegate model ..................... yes
Qt Quick:
Direct3D 12 ............................ no
AnimatedImage item ..................... yes
Canvas item ............................ yes
Support for Qt Quick Designer .......... yes
Flipable item .......................... yes
GridView item .......................... yes
ListView item .......................... yes
TableView item ......................... yes
Path support ........................... yes
PathView item .......................... yes
Positioner items ....................... yes
Repeater item .......................... yes
ShaderEffect item ...................... yes
Sprite item ............................ yes
Note: Also available for Linux: linux-clang linux-icc
Note: PKG_CONFIG_LIBDIR automatically set to ~/org/buildroot/raspberry-pi3/host/arm-buildroot-linux-uclibcgnueabihf/sysroot/usr/lib/pkgconfig:~/org/buildroot/raspberry-pi3/host/arm-buildroot-linux-uclibcgnueabihf/sysroot/usr/share/pkgconfig:~/org/buildroot/raspberry-pi3/host/arm-buildroot-linux-uclibcgnueabihf/sysroot/usr/lib/arm-buildroot-linux-uclibcgnueabihf/pkgconfig
Note: PKG_CONFIG_SYSROOT_DIR automatically set to ~/org/buildroot/raspberry-pi3/host/arm-buildroot-linux-uclibcgnueabihf/sysroot
$ make -j4
$ make install
Buildroot のファイルシステムのサイズを拡張する
デフォルトで120MB。素敵だけど今回は少し足りない。
$ cd ~/org/buildroot/raspberry-pi3 $ make clean; make menuconfig Filesystem images ---> (512M) exact size (Save) $ make $ dd if=images/sdcard.img of=/dev/sdb bs=16M
Qt のライブラリを SD カードにコピーする
$ cd ~/org/buildroot/raspberry-pi3 $ mkdir sdcard $ sudo mount /dev/sdb2 sdcard $ sudo cp -r host/arm-buildroot-linux-uclibcgnueabihf/sysroot/opt/qt sdcard/opt/ $ sync $ sudo umount sdcard
Qt アプリケーションのクロスコンパイル
Qt Quickで天気予報を表示するアプリ で開発した weather を利用します。
$ mkdir -p ~/com/github/task-jp/weather/ $ cd $_ $ git clone https://github.com/task-jp/weather.git $ mkdir build $ cd build $ ~/io/qt/code/qt/dev/shared/root/opt/qt/bin/qmake -r ../weather $ make -j4 $ make install $ sudo cp -r ~/org/buildroot/raspberry-pi3/host/arm-buildroot-linux-uclibcgnueabihf/sysroot/opt/weather ~/org/buildroot/raspberry-pi3/sdcard/opt/
実機上で動作確認

# /opt/weather/bin/weather
まとめ
Buildroot を利用して、Raspberry Pi 3 向けに Qt の開発版をビルドし、それを利用した簡単なデモアプリを実機上で動かすことができました。