More Librem 5 apps! – A tutorial to compile Flutter apps for Librem 5 on x64 machine

As I got my Librem 5 a short time ago and I developed a few Flutter apps in the past, I thought they can be quite a good addition for the Librem 5 ecosystem and extend the list of mobile friendly apps.


Fast Shopping, an app we will compile for the Librem 5 in this tour.

What is Flutter?

Flutter is a cross platform open source app framework for building apps with a single codebase and bring them to Android, iOS, Desktop (Linux, Windows, Mac OS). Apps build with Flutter run quite well on the Librem 5.

What is this topic for?

Two things:

  1. A tutorial for setting up an aarch64 a.k.a. ARM64 Debian 11 machine with the necessary things to build Flutter apps for Linux. I will also give an example of how to give an existing Flutter app Linux support which is quite easy for basic apps. The aarch64 machine can also be used to compile other/native applications for the Librem 5.

  2. A hint to the purism developers: Maybe this topic helps to bring Flutter on your radar. There are many Open Source Flutter apps already present on F-Droid, an Android Open Source app store. With help of the upstream developers, maybe Linux support and Flathub can be added so that the Librem 5 can profit from more already existing apps.

Known limitations / problems

  • Scrolling in Flutter apps seems to be broken on Librem 5! Maybe some Purism dev like @dos can shed a light on that? I think this is because it’s not detected as scrolling but as mouse clicks instead but I don’t know how to verify that or workaround that behaviour Edit: Fixed with another code modification
  • Camera does not work yet I guess
  • GPS maybe does not work yet (However I will try that someday, because https://github.com/Baseflow/flutter-geolocator/pull/1049 indicates that it could work)

Let’s start!

This handles local install of a Debian 11 (Bullseye) arm64 dev machine. Local build will take time because of the emulation! Of course this could be done using a CI pipeline. Building on the Librem 5 itself also works (can confirm) but you don’t want to install all these things there and it also takes time, battery and produces a lot of heat…

Install Debian 11 AARCH64 on a x64 machine

based on: https://quantum5.ca/2022/03/19/how-to-make-better-arm-virtual-machine-armhf-aarch64-uefi/

Install necessary dependencies (on Fedora host):

sudo dnf install libvirt virt-install qemu-system-aarch64

I think on Debian based systems you need something like:

sudo apt install virtinst qemu-system-aarch64

Create the virtual disk:

sudo fallocate -l 10G /var/lib/libvirt/images/debian-11-arm64-vm.img

Download and install the vm:

sudo virt-install \
  --name debian-11-arm64-vm \
  --arch aarch64 \
  --machine virt \
  --os-variant debian11 \
  --ram 4096 \
  --vcpus 4 \
  --import \
  --disk /var/lib/libvirt/images/debian-11-arm64-vm.img,bus=virtio \
  --graphics none \
  --network user,model=virtio \
  --features acpi=off \
  --boot uefi \
  --location https://deb.debian.org/debian/dists/bullseye/main/installer-arm64/

Just go through the setup process. You don’t have to make special configurations.

After installation you can forward the guest ssh port to the host to access the vm via SSH:

sudo virsh qemu-monitor-command --hmp debian-11-arm64-vm 'hostfwd_add ::2222-:22'

Connect via SSH (Change username according to your installation, I ised debian):

ssh -p 2222 username@localhost

Install Flutter

In case help is needed: https://docs.flutter.dev/get-started/install/linux

Install necessary dependencies for Flutter development:

sudo apt install git curl unzip clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev

Create development directory:

mkdir development && cd development

Clone Flutter:

git clone https://github.com/flutter/flutter.git && cd flutter

Because the application in this example is a bit outdated and uses an old Flutter version we have to downgrade that:

git checkout 3.3.4 && cd ..

We could also update the codebase but that’s a bit too much for this topic.

Add Flutter to current PATH:

export PATH="$PATH:pwd/flutter/bin"

Fetch Flutter build dependencies and check what is missing for building Flutter apps for arm64. The important things should be installed by now so no further steps have to be done here. Just check that “Linux toolchain” has a checkmark:

flutter doctor

Disable analytics:

flutter config --no-analytics

Build example app (FastShopping by Albert221)

The example application does not have linux support yet. We will add that (to also show how easy it is to add linux support to very basic Flutter apps).

cd ~/development && git clone https://github.com/Albert221/FastShopping.git && cd FastShopping

Make changes to upstream code:

  1. Add linux support

flutter create --project-name="fast_shopping" --platforms=linux .

  1. Remove closed source crashlytics dependency

2.1) nano pubspec.yaml: Remove this:

crashlytics:
  path: crashlytics/full # CD changes me 🤖

2.2) nano lib/main.dart Comment out the following parts like this:

//import 'package:crashlytics/crashlytics.dart';

//await Crashlytics.initialize();

//runZonedGuarded(() {

//}, Crashlytics.recordError);
  1. Add dependency for hiding title bar

Add dependency: flutter pub add window_manager

Open the main.dart file: nano lib/main.dart

The whole file has to look like this:

import 'dart:async';

import 'package:window_manager/window_manager.dart';
import 'package:fast_shopping/app.dart';
import 'package:fast_shopping/data/app_settings_repository.dart';
import 'package:fast_shopping/data/migrators/v2_data_migrator.dart';
import 'package:fast_shopping/data/shopping_list_repository.dart';
import 'package:flutter/material.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await windowManager.ensureInitialized();

  await windowManager.setAsFrameless();
  await windowManager.show();

  final shoppingListsRepository = ShoppingListRepository();
  await V2DataMigrator.migrate(shoppingListsRepository);

  runApp(FastShoppingApp(
    appSettingsRepository: AppSettingsRepository(),
    shoppingListRepository: shoppingListsRepository,
  ));
}
  1. Fix scroll behavior

It seems that scrolling does work differently on the Librem 5 touchscreen than like scrolling with a mouse wheel, etc.

We can fix that behavior by:

nano lib/app.dart

and adding this on the first line:

import 'dart:ui';

and adding somewhere under return MaterialApp(:

scrollBehavior: const MaterialScrollBehavior().copyWith(dragDevices: {PointerDeviceKind.mouse, PointerDeviceKind.touch}),

Now the building part!

Clean previously fetched dependencies: flutter clean

Build app: flutter build linux --release

Build can be found under build/linux/arm64/release/bundle/

The binary files have to be copied to the Librem 5.

E.g. via SSH to host machine and copy it after that in your preferred way to the Librem 5 (Change username according to your installation):

scp -P 2222 -r username@localhost:~/development/FastShopping/build/linux/arm64/release/bundle/ ./FastShopping/

Also copy app icon from Android release:

scp -P 2222 -r debian@localhost:~/development/FastShopping/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png ./FastShopping/icon.png

After you copied the folder to the Librem 5 to ~/.local/share/fast_shopping/ go to the path via Terminal on the Librem 5 with cd ~/.local/share/fast_shopping/.

Make the app executable: chmod +x fast_shopping

The app can be started from the terminal: ./fast_shopping

Or by creating a desktop icon:

nano ~/.local/share/applications/fast_shopping.desktop

[Desktop Entry]
Version=1.0
Name=Fast Shopping
Comment=Shopping list
Exec=/home/purism/.local/share/fast_shopping/fast_shopping
Icon=/home/purism/.local/share/fast_shopping/icon.png
Terminal=false
Type=Application
Actions_new-window
NoDisplay=false
X-Purism-FormFactor=Workstation;Mobile;

The app can now be started via App icon! YEAH!

And now?

There are many Open Source Flutter apps. I will not mention them here to not put pressure on their devs. :stuck_out_tongue: Maybe you have time and are willing to search for them, try to compile them for Librem 5 or ask the developer about upstream Linux / Flathub support?

14 Likes

Edited topic. Fixed faulty scrolling. Flutter apps work just as fast as native apps! :slight_smile:

2 Likes

This is awesome! Thanks, will give this a go shortly. Double plus good for the Qemu instructions.

2 Likes

First of all thanks for the awesome writeup! I didn’t use my Pinephone much lately but when I did Fluffychat (Flutter) was my go to Matrix client despite some rather serious issues. As far as I undwrstand drom your post there is a way to get rid of the title bar and scrolling issues are fixed but what about the keyboard? My biggest issue with Flutter on Linux phones was that the keyboard bugged out every time the app wasn’t focused anymore (even the Phosh app switching thing triggered it), has that improved by any chance?

2 Likes

Yes, title bar and scrolling issues would have to be adressed in the Flutter code before compiling. I did not notice any keyboard issues so far! :slight_smile: Maybe that have been ironed out already?

1 Like