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

あわせて読みたい