Apalis iMX8
Ixora Carrier Board V1.2
TorizonCore with evaluation Containers
I am evaluating using Flutter on an i.MX 8QM embedded device. My development machine is a virtualbox ubuntu guest. The i.MX is running TorizonCore with evaluation containers and I am able to run docker containers both on my host/dev machine and target.
I tried following the instructions in blog post Flutter on Torizon - A PoC Setup for i.MX8M Plus, but am unable to, because I could not find the referenced code. Is there a git repo where I can find the following:
1. The flutter_build_env container: Is there a container on dockerhub, or a Dockerfile available where I can build my own container with everything needed to cross-compile a flutter application?
2. The source for the internet radio application so that I can build the bundle? This is less important, because I can just use any flutter example.
3. docker_compose_flutter.yaml (only a portion was revealed in the post)
Is there an example elsewhere that has instructions for running Flutter on an IMX.8 on Torizon?
Hi @dawnhowe_alten , that blog came from our partner Crossware.io. You may have to approach them for the resources. We have another blog about bringing up a flutter demo on Torizon and everything is open. Unfortunately, it is now only in Chinese. Google Translate or ChatGPT may help. Let me know if any help is needed.
I am trying to replicate what this blog does as well since we cannot access the source (I tried the chinese blog but could not manage to make it work).
I am currently stuck on the docker compose file.
For the build environment container, I just made one and directly added a sample application to remove a step for this proof of concept. But you can just use it as a build environment anyway:
From an x86 host with docker engine
Enable Arm emulation (docker run --rm -it --privileged torizon/binfmt)
Build this dockerfile with docker buildx build --platform=linux/arm64 -t flutter-elinux:latest (or similar):
ARG BASE_NAME=ubuntu
ARG IMAGE_ARCH=linux/arm64/v8
ARG IMAGE_TAG=20.04
ARG DOCKER_REGISTRY=arm64v8
FROM --platform=$IMAGE_ARCH $DOCKER_REGISTRY/$BASE_NAME:$IMAGE_TAG
ARG IMAGE_ARCH
RUN apt-get -y update && apt-get install -y \
build-essential \
clang \
cmake \
curl \
git \
pkg-config \
ninja-build \
unzip \
wget \
libegl1-mesa-dev libxkbcommon-dev libgles2-mesa-dev \
libwayland-dev wayland-protocols
RUN groupadd -r -g 1441 flutter && useradd --no-log-init -r -u 1441 -g flutter -m flutter
USER flutter:flutter
WORKDIR /home/flutter
# Flutter 3.3.10 needs to be used (at this sha in particular) because 3.7 has this open issue:
# https://github.com/flutter/flutter/issues/116703 (as of 07.03.2023)
RUN git clone https://github.com/sony/flutter-elinux.git &&\
cd flutter-elinux &&\
git reset --hard 19a1b05ea20675c36c705955c4148ad40b205161 &&\
cd ..
ENV PATH="${PATH}:/home/flutter/flutter-elinux/bin"
RUN flutter-elinux devices
RUN flutter-elinux doctor
RUN flutter-elinux create sample &&\
cd sample &&\
flutter-elinux build elinux
From the x86 host: mkdir -p Flutter_torizon && cd Flutter_torizon and then, get the bundle that was built by the container with:
The Dockerfile that’s inside the Flutter_torizon folder is the exact same (minus the naming) as in the blog post.
That’s the bundle folder and the Dockerfile done. But now I have no idea what to put in the Docker compose file. The blog says that the docker compose “command will run two images torizon/weston-vivante:2 and flutter_test:radio” (on target of course) but how exactly to reproduce this in the file?
This file appears to bring up 2 containers a weston container and then a second container running the flutter demo/application. So if you have a container built with the flutter demo inside then you can probably adapt this to your needs.
In your case however it looks like you have just the flutter application compiled output from your build environment container. In which case I see in the blog post there’s a set of docker run commands halfway through the blog. These commands take the flutter output/bundle and bind mount it into a weston container then run the application manually from inside this container.
I did try with the docker-compose file you showed.
First, the dev environment container needed to use ARG IMAGE_TAG=20.04 instead of 22.04, to match libc6 and libstdc++6 versions with the runtime container.
However, running the docker-compose file on target (after loading the runtime container/image), I get this error:
torizon-flutter_demo-1 | embedder.cc (960): 'FlutterEngineCreateAOTData' returned 'kInvalidArguments'. Invalid ELF path specified.
torizon-flutter_demo-1 | Failed to create view controller.
torizon-flutter_demo-1 exited with code 0
I have no idea if this is the correct docker-compose file, but the line numbers line up with the post (put your image at line 47). Although this file ends at line 52, and the image in the blog has a couple more lines starting with “device_cgroup_rules:”
Looking again at the Chinese blog there’s a startup script that runs on startup for the Flutter container. I assume this is to launch/execute the Flutter application in a particular way. Did you include this in your setup?
You don’t need to run with a docker compose on the target. You can manually the 2 docker containers you need - one with the weston compositor, and a second one with your flutter app.
Then you can start your container. To do some debugging, you can just start it and enter it in on a bash shell and try running your flutter app by hand. I have a docker image with flutter I created on the imx8 (I can’t get a cross-compile to work) on docker hub. But I didn’t create it with a Dockerfile, I started with a docker image, and then ran a bunch of “apt” commands in the container, pulled in flutter-elinux, created a “hello_world” sample. Unfortunately, I can’t figure out exactly what I did. The docker container is on docker hub in Docker .
This flutter-demo:latest image (you can explore it with docker run --rm -it --platform=linux/arm64 --entrypoint bash flutter-demo:latest), should contain the flutter_app bundle and the flutter-client executable.
Send the image to the target (this could be through a docker registry technically):
Host:
docker save flutter-demo:latest > ./flutter-demo.tar
scp flutter-demo.tar torizon@target.ip:/home/torizon
Send the docker_compose_flutter.yaml as seen in the previous post to the target
In the target, load the flutter demo docker image and launch docker compose:
docker load < flutter-demo.tar
docker stop $(docker ps -a -q)
docker-compose -f docker_compose_flutter.yaml up
Current situation
With the flutter-elinux create sample to have a flutter application instead of copying a “flutter_app” from the host context, this method worked. It isn’t perfect but at least it is reproducible as opposed to the blog.
However, I still have a rather weird issue. For some reason, my flutter_app when compiled gives me a bundle that then launches the sample application. I do not know exactly the reason for this.
A second issue is that with the flutter gallery application, the assets are not loading (except the black and white animation for the flutter logo on top)
If I understood correctly then it sounds like you were able to work a method out, albeit with some minor issues. In which case that is good to hear. Unfortunately there’s not much I can help out with in terms of the specifics of Flutter since that is not something we have too much expertise with.
Unfortunately, I cannot recommend to our team to use Torizon until we can figure out a way to create a container in a CI pipeline, and this thread still hasn’t solved this. I am only able to create the container on the target and still need to figure out how to cross-compile everything on a dev machine. In addition, I need to figure out a dev workflow that allows development on a host machine using VsCode, which means that the functionality in the Toradex and Flutter extensions need to be merged. If these issues cannot be resolved, we will probably have to use a custom yocto build.
I have done much research in the flutter and flutter-elinux repos and have contacted Crossware.io. I did get an email a few weeks ago from Crossware.io indicating they would get back to me, but I have heard nothing since. The Toradex blog post this thread refers to does not display any of the comments I tried to make.
@dawnhowe_alten My last response was towards @mnano. I didn’t realize you had ongoing issues since you haven’t commented on this thread after our initial responses.
I am only able to create the container on the target and still need to figure out how to cross-compile everything on a dev machine.
This article uses C/C++ as an example but the concepts should generically apply to anything that needs to be cross-compiled. Furthermore our VSCode IDE extensions more or less automate the setup of this. Though we currently do not have a project template for Flutter however.
As for the Flutter specific issues as I said this is not our expertise, but I can try and see if we can facilitate communication between you and Crossware.io.
All that said, maybe you can open a separate thread for this discussion since the thread here is diverging in different directions and it’s difficult to maintain 2 different conversations here at once.
We both have the same objective and problem, I think it fits this discussion.
I did some small progress in the time I had:
In the Dockerfile I posted last time, a small edit needs to be made for the copying of the flutter app in the bundle stage. I was essentially not properly copying the elements of the application previously (difference is flutter_app/* vs flutter_app/):
# Add our application (folder in host context) and pass ownership of files to current user
RUN mkdir /home/flutter/flutter_app
COPY --chown=flutter flutter_app /home/flutter/flutter_app/
I can compile most flutter application, granted they are compatible with flutter 3.3.10.
Most application can run either by calling the executable in the bundle folder or by using the flutter-client executable
As far as problems, for me, it lies in the proper use of plugins. The gallery application for example shows nothing in release, but in a Debug build, it shows the red errors typical of flutter. For my application, there is an issue with the proper loading of the video player plugin (I make it work with the bundle application but can’t with the flutter-client).
I would like to be connected to Crossware.io since their radio application in the blog uses gstreamer and a plugin that is probably similar to my flutter application. If we had access to their sources from that blog, everything would be solved. Seems to me like a simple solution.
Edit: Locales
I added this to the bundle and runtime stage:
# Set the locale (Add "apt-get install locales" as well!)
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \
locale-gen
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
With locales, the gallery flutter application works perfectly!
My only remaining issue is gstreamer + flutter. Ideally we obtain Crossware.io code from the blog post.
@mnano I contacted our sales team in Europe and let them know about your request. They will reach out and see if they can facilitate contact between you and Crossware.io.
####################################################################################################################
FROM --platform=linux/arm64/v8 arm64v8/ubuntu:20.04 AS build
ARG DEBIAN_FRONTEND=noninteractive
# Build environment dependencies for flutter-elinux
RUN apt-get -y update && apt-get install -y \
build-essential clang cmake \
curl git pkg-config \
ninja-build unzip wget \
libgtk2.0-dev libglib2.0-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \
libegl1-mesa-dev libxkbcommon-dev libgles2-mesa-dev \
libwayland-dev wayland-protocols \
locales
# Set the locale
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \
locale-gen
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
# Non root user
RUN groupadd -r -g 1441 flutter && useradd --no-log-init -r -u 1441 -g flutter -m flutter
USER flutter:flutter
WORKDIR /home/flutter
# Flutter 3.3.10 needs to be used (at this sha in particular) because 3.7 has this open issue:
# https://github.com/flutter/flutter/issues/116703 (as of 07.03.2023)
RUN git clone https://github.com/sony/flutter-elinux.git &&\
cd flutter-elinux &&\
git reset --hard 19a1b05ea20675c36c705955c4148ad40b205161 &&\
cd ..
# Add flutter-elinux to the path
ENV PATH="${PATH}:/home/flutter/flutter-elinux/bin"
# While not necessary, running flutter-elinux for the first time builds it
RUN flutter-elinux devices
RUN flutter-elinux doctor
# Add our application (folder in host context) and pass ownership of files to current user
RUN mkdir /home/flutter/flutter_app
COPY --chown=flutter my_local_flutter_app /home/flutter/flutter_app/
# Get the Gallery Application
RUN cd flutter_app &&\
flutter-elinux create . &&\
flutter-elinux upgrade && flutter-elinux clean && flutter-elinux pub get &&\
flutter-elinux build elinux
###################################################################################################################
FROM --platform=linux/arm64/v8 torizon/weston-vivante:2 AS runtime
ARG IMAGE_ARCH
RUN mkdir -p /app/gui
RUN apt-get -y update && apt-get install -y \
alsa-utils \
libasound2 \
psmisc \
procps pciutils \
libgstreamer1.0-0 \
gstreamer1.0-plugins-base \
gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-ugly \
gstreamer1.0-libav \
gstreamer1.0-doc \
gstreamer1.0-tools \
gstreamer1.0-x \
gstreamer1.0-alsa \
gstreamer1.0-gl \
gstreamer1.0-gtk3 \
gstreamer1.0-pulseaudio \
v4l-utils \
locales
# Set the locale
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \
locale-gen
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
# Get the flutter bundle built in the build environment
COPY --from=build /home/flutter/flutter_app/build/elinux/arm64/release/bundle /app/gui/bundle
# The .so libraries (notably libflutter_engine.so) must be in the library path
# to properly execute the flutter_app. Some plugin (like the elinux video_player plugin)
# also generate a .so library, and NEED to be in the library path.
COPY --from=build /home/flutter/flutter_app/build/elinux/arm64/release/bundle/lib /lib/
WORKDIR /app/gui/bundle/
ENV PATH="/app/gui:${PATH}"
ENTRYPOINT ["./flutter_app"]
CMD [ "-f", "-b", "../bundle/"]
note: some packages/steps might not be necessary, so this can be cleaned up further
This should work for a good amount of Flutter application in a docker container on an iMX8 running TorizonCore (I tested the Flutter Gallery successfully). The steps to use this are the same as in my previous post.
My problem now requires another post I believe and seems purely related to gstreamer:
The sony video player plugin does not load in my flutter app before I call gstreamer at least once