Skip to content

Building flutter apps

Hidenori Matsubayashi edited this page Aug 14, 2023 · 60 revisions

Self-building

Use --target-backend-type option to select display backends. Default is Wayland.

Note:

  • We do not expect to use x11 in embedded products, it is just for debugging and development on Linux desktop PCs.
  • In general, few devices support EGLStream (NVIDIA only?). Check it is supported or not before using it on your target devices.
  • gbm and eglstream will basically work but they are still development phase (have some issues).
Build mode Target backend Command
release wayland flutter-elinux build elinux
x11 flutter-elinux build elinux --target-backend-type=x11
gbm flutter-elinux build elinux --target-backend-type=gbm
eglstream flutter-elinux build elinux --target-backend-type=eglstream
debug wayland flutter-elinux build elinux --debug
x11 flutter-elinux build elinux --debug --target-backend-type=x11
gbm flutter-elinux build elinux --debug --target-backend-type=gbm
eglstream flutter-elinux build elinux --debug --target-backend-type=eglstream
profile wayland flutter-elinux build elinux --profile
x11 flutter-elinux build elinux --profile --target-backend-type=x11
gbm flutter-elinux build elinux --profile --target-backend-type=gbm
eglstream flutter-elinux build elinux --profile --target-backend-type=eglstream

Build artifacts

The artifacts will be put in your project under ./build/<target_arch>/<build_mode>/bundle. Alongside your executable binary in the bundle directory there are two directories:

  • lib/ contains the required .so library files
  • data/ contains the application’s data assets, such as fonts or images

artifacts

Pre-built images

flutter-elinux download the Flutter engine artifacts such as libflutter_engine.so and libflutter_elinux_wayland.so to <flutter-elinux_install_path>/flutter/bin/cache/artifacts/engine directory automatically when you build your Flutter app. These .so files are download from sony/flutter-embedded-linux/releases built with a specific toolchain. Therefore, if you want to use your toolchain, you need to build it yourself.

For reference, the toolchain that the current .so files are built is below.

.so file toolchain sysroot glibc
libflutter_engine.so clang/llvm (Google Chromium) Google Chromium 2.29
libflutter_elinux_*.so clang/llvm (Ubuntu 18.04) Ubuntu 18.04 for arm64 2.27

How to build libflutter_engine.so and libflutter_elinux_*.so

See the following links.

Cross-building from x64 to arm64

Cross-building requires knowledge (Not easy, you might get build errors). You need to prepare your sysroot which is for cross-building for your target device by using --target-sysroot. Also, you can use the following options.

build command options description default
--target-arch specify arm64 targets current host CPU architecture (self builds)
--target-toolchain specify custom toolchain path null ('/')
$ flutter-elinux build elinux --target-arch=arm64 --target-sysroot=<path_to_target's_sysroot>

Use cases

There are some ways to cross-build, and are some ways to create a sysroot like Yocto, buildroot, and so on.

  1. Use Docker + QEMU
  2. Use Yocto SDK
  3. Use Buildroot Toolchain

Case 1: Use Docker + QEMU

Here, we show an example using a sysroot for arm64v8/ubuntu:18.04 docker image and a host's toolchain, but using sysroot and toolchain for your target device is better.

Install cross-build tools

$ sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
$ sudo apt install libstdc++-8-dev-arm64-cross

Create sysroot for arm64

First, install Docker by following Install Docker Engine on Ubuntu.

S sudo apt install qemu-user-static

Note that you have to choose a docker image/OS version that matches your target machine. Here, we will use Ubuntu 18.04 as an example.

$ sudo docker run -it arm64v8/ubuntu:18.04

In docker:

apt update
apt install clang cmake build-essential \
            pkg-config libegl1-mesa-dev \
            libxkbcommon-dev libgles2-mesa-dev
apt install libwayland-dev wayland-protocols
apt install libdrm-dev libgbm-dev libinput-dev libudev-dev libsystemd-dev
exit

Copy sysroot from the container to host:

$ sudo docker ps -a
CONTAINER ID   IMAGE                 COMMAND   CREATED       STATUS                   PORTS     NAMES
f367a6b0316f   arm64v8/ubuntu:18.04  "bash"    4 hours ago   Exited (0) 4 hours ago   interesting_knuth
$ mkdir ubuntu18-arm64-sysroot
$ sudo docker cp f367a6b0316f:/ ubuntu18-arm64-sysroot

Build flutter apps

$ flutter-elinux build elinux \
     --target-arch=arm64 \
     --target-compiler-triple=aarch64-linux-gnu \
     --target-sysroot=<Absolute_path_to>/ubuntu18-arm64-sysroot

Troubleshooting

If you get the following error, use --system-include-directories option.

/usr/bin/../lib/gcc-cross/aarch64-linux-gnu/9/../../../../include/c++/9/casse
rt:43:10: fatal error: 'bits/c++config.h' file not found
#include <bits/c++config.h>
         ^~~~~~~~~~~~~~~~~~
$ flutter-elinux build elinux --target-arch=arm64 \
     --target-sysroot=<Absolute_path_to>/ubuntu18-arm64-sysroot \
     --system-include-directories=/usr/aarch64-linux-gnu/include/c++/${version}/aarch64-linux-gnu

Case 2: Use Yocto SDK

Setup Yocto SDK environment.

See: Cross-building using Yocto SDK

$ source /opt/poky/3.1.15/environment-setup-aarch64-poky-linux
$ export CC=${CLANGCC}
$ export CXX=${CLANGCXX}

See: https://github.com/sony/flutter-embedded-linux/issues/4#issuecomment-1090157925

$ sudo mv /opt/poky/3.1.16/sysroots/x86_64-pokysdk-linux/usr/bin/ld \
          /opt/poky/3.1.16/sysroots/x86_64-pokysdk-linux/usr/bin/ld.x86_64
$ sudo cp -a /opt/poky/3.1.16/sysroots/x86_64-pokysdk-linux/usr/bin/aarch64-poky-linux/aarch64-poky-linux-ld \
             /opt/poky/3.1.16/sysroots/x86_64-pokysdk-linux/usr/bin/ld

Use target-compiler-triple option to set CMAKE_C_COMPILER_TARGET and CMAKE_CXX_COMPILER_TARGET in the toolchain cmake configuration file make it use the right compiler path and filename.

Cross-building on x64 for arm64

$ flutter-elinux build elinux --target-arch=arm64 \
     --target-compiler-triple=aarch64-poky-linux \
     --target-sysroot=/opt/poky/3.1.16/sysroots/aarch64-poky-linux

Case 3: Use Buildroot Toolchain

As Buildroot doesn't come with clang tool, you should install it yourself. In the command below, clang will use aarch64-buildroot-linux-gnu-ld, which comes with your buildroot, as the linker.

sudo apt install clang
sudo apt install wayland-protocols libwayland-bin # host tools needed to build wayland backend

export PATH=$PATH:~/buildroot/output/host/bin # add aarch64-buildroot-linux-gnu-ld to PATH

~/flutter-elinux/bin/flutter-elinux build elinux --target-arch=arm64 \
                                                 --target-compiler-triple=aarch64-buildroot-linux-gnu \
                                                 --target-sysroot=~/buildroot/output/staging \
                                                 --target-compiler-flags=--gcc-toolchain=~/buildroot/output/host