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 の開発版をビルドし、それを利用した簡単なデモアプリを実機上で動かすことができました。