FlutterをRaspberry Pi 3 Bで動かそうとする
動くのかはしらん。
とりあえず手元にある機材がこれなので試してみる。
使うのは埃をかぶっていたRaspberry Pi 3B
OSインストール
に書いてる通り、Flutterは64bitのOSでしか動作しない。
そのためRaspberry OSは64bitのものを使用。
Raspberry Pi Imagerを使ってSDカードに書き込めばおしまい。
:gear: マークからSSHやWifiの設定をしておくと、後の作業を母艦のマシンからできるのでとてもラクになる。
ちなみに、最初はけちってRaspberry Piと一緒に埃をかぶっていた2GBのmicro SDを使おうとした。
2GBしか空きがないと、デスクトップ環境なしのRaspberry Pi OS Lite(1.8GBくらい)しかインストールできない。
空き領域にも余裕がないので、X window系のライブラリがインストールできずに詰む。
仕方ないので16GBのmicro SDを引っ張り出してきた 。
Flutterインストール
Flutterのインストールにはsnapというパッケージマネージャーを使うのが一番簡単らしい。
ので、まずはsnapからインストール。
マニュアル通りにやればインストールできる。
Flutterもマニュアル通りにインストール。インストールが済んだら一度シェルからログアウトしたほうがよい。再ログインしたらちゃんとPathが通った。
インストールできたらおもむろに flutter doctor
で必要な依存関係を取得する。
が、
/home/pi/snap/flutter/common/flutter/bin/internal/shared.sh: line 165: 3860 Killed "$DART" --verbosity=error --disable-dart-dev $FLUTTER_TOOL_ARGS --snapshot="$SNAPSHOT_PATH" --packages="$FLUTTER_TOOLS_DIR/.dart_tool/package_config.json" --no-enable-mirrors "$SCRIPT_PATH"
で停止してしまう。
エラーメッセージでググると出てくるissue
It seems, I had insufficient RAM during the building process on my server, I put up a swapfile to solve it.
I am closing this.
どうやらメモリ不足らしい。
Swapを増やして試してみる。
とりあえず2GBまで増やしてみることにした。元が100MBとかだったので、とりあえずこれでなんとかなるんじゃないだろうか?
CONF_SWAPSIZE=2048
もう一度 flutter doctor
する
Downloading Material fonts... 5.0s
Downloading Gradle Wrapper... 140ms
Downloading package sky_engine... 1,600ms
Downloading flutter_patched_sdk tools... 4.0s
Downloading flutter_patched_sdk_product tools... 2,081ms
Downloading linux-arm64 tools... 12.7s
Downloading linux-arm64/font-subset tools... 1,782ms
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel master, 3.4.0-19.0.pre.221, on Debian GNU/Linux 11
(bullseye) 5.15.61-v8+, locale en_GB.UTF-8)
[✗] Chrome - develop for the web (Cannot find Chrome executable at
google-chrome)
! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[✓] Linux toolchain - develop for Linux desktop
[!] Flutter IDE Support (No supported IDEs installed)
[✓] Connected device (1 available)
[✓] HTTP Host Availability
! Doctor found issues in 2 categories.
今度こそ成功した!
実現方針
- Raspberry Pi上にFlutterをビルド&実行できる環境を用意する
- GPIOとかいじる上でhot reloadを使った開発体験をしたい
- Raspberry Pi上にFlutterアプリケーションを実行だけできる環境を用意する(with X window)
- ビルドしたものを持ってくる。コードを書いてから実行までのイテレーションが長くなるのが欠点
- 母艦で画面表示を確認できる。モニターが一枚しかないので、Raspberry Piにあまりゴテゴテと繋がなくて良いのは助かる
- Raspberry Pi上にFlutterアプリケーションを実行だけできる環境を用意する(without X window)
- できるらしい。これもビルドしたものを持ってくる感じ。
- どちらかと言えばデジタルサイネージ用とかに使うイメージだが。
https://github.com/ardera/flutter-pi
Flutterアプリを動かす
$ flutter create --platforms linux hello
$ cd hello
$ flutter run
Launching lib/main.dart on Linux in debug mode...
Building Linux application...
(hello:4738): Gtk-WARNING **: 23:05:54.934: Locale not supported by C library.
Using the fallback 'C' locale.
libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
** (hello:4738): WARNING **: 23:12:32.110: Failed to start Flutter renderer: Unable to create a GL context
ファイルIOが死ぬほど遅いからか、立ち上がるまで死ぬほど時間がかかった末にこれ。
X windowの転送は成功しているらしく、ちゃんとXQuartzのウィンドウはでてきた。
とりあえずOpenGL系の何かが足りない様子ではある。
明日はOpenGL入れてみる。
母艦でビルドしたバイナリを持ち込めないかなぁ。
macで flutter build linux
すると "build linux" only supported on Linux hosts.
と怒られてしまった。
少なくとも64bit CPUのLinuxが必要みたい。
できればQEMUとかでGPIO含めエミュレートできると良いんだけど。
以前にQEMUでraspberrypi3bのマシンを動かしてみたけどログインできなかったんだよなぁ。どうやらディスプレイを繋げられればユーザーを作るプロンプトが出るらしいんだが、ディスプレイ表示ができなかった記憶。
OpenGLをインストールする
$glxinfo
とか叩いてもコマンドが見つからないので、OpenGLのインストールが必要そう。
https://www.fabshop.jp/opengl_gpumemory/ にしたがって一旦OpenGLの有効化を試す。
これで何も新しいものをインストールしなくても良いならそれに越したことはないんだけど・・・だめだった。
軽くググってみたところ、Desktop版のRaspberry Pi OSにはあらかじめOpenGLが入っている模様。
SDカードの容量も当初の予定より大きいし、デスクトップ版のimage焼き直して作り直してみようかな…
(寄り道)QEMUでRaspberryPiをエミュレートする
やるなら、手元の実機がRaspberry Pi 3Bなので、 raspi3b
のマシンでOSが立ち上がれば嬉しい。
Raspberry Pi OSは2022年にリリースされたものからは、おなじみの pi/raspberry
ではログインできなくなっている。
最新は2022年9月6日リリースのバージョン。
とりあえず最新のOSをQEMUで立ち上げてみる。
ttyは生きている。
そのためユーザー設定のスクリプトにアクセスできず、永遠にログインできない。
2021年のOSイメージではお馴染みのデフォルトユーザーでログインできるため、ディスプレイが立ち上がらなくてもttyでなんとかできる。
が、Debianのバージョンが少々古く、FlutterインストールのためにSnapのセットアップをしようとしたところエラーが。
pi@raspberrypi:~$ sudo apt install snapd
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following package was automatically installed and is no longer required:
libfuse2
Use 'sudo apt autoremove' to remove it.
The following additional packages will be installed:
apparmor squashfs-tools
Suggested packages:
apparmor-profiles-extra apparmor-utils
The following NEW packages will be installed:
apparmor snapd squashfs-tools
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
Need to get 12.3 MB of archives.
After this operation, 55.4 MB of additional disk space will be used.
Do you want to continue? [Y/n]
Get:1 http://deb.debian.org/debian bullseye/main arm64 apparmor arm64 2.13.6-10 [601 kB]
Get:2 http://security.debian.org/debian-security bullseye-security/main arm64 squashfs-tools arm64 1:4.4-2+deb11u2 [128 kB]
Err:2 http://security.debian.org/debian-security bullseye-security/main arm64 squashfs-tools arm64 1:4.4-2+deb11u2
Connection timed out [IP: 151.101.110.132 80]
Err:3 http://deb.debian.org/debian bullseye/main arm64 snapd arm64 2.49-1+b5
404 Not Found [IP: 151.101.110.132 80]
Fetched 601 kB in 1min 14s (8,164 B/s)
E: Failed to fetch http://security.debian.org/debian-security/pool/updates/main/s/squashfs-tools/squashfs-tools_4.4-2%2bdeb11u2_arm64.deb Connection timed out [IP: 151.101.110.132 80]
E: Failed to fetch http://deb.debian.org/debian/pool/main/s/snapd/snapd_2.49-1%2bb5_arm64.deb 404 Not Found [IP: 151.101.110.132 80]
E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?
どうも古いOSだとインストールうまくいかない予感
(再出発)RaspberryPi OS (Desktop)でFllutterを動かす
- Paspberry Pi OS ImagerでSDカードにDesktopのOSを焼く。64bitを選択の上、SSH用のデフォルトユーザーを設定しておくこと
- Raspberry Piを起動
- snapdをインストール
- flutterをインストール
- swapサイズを100MBから2GBに拡大
- flutter doctorを叩いて依存関係をインストール
- flutter create -> flutter runで動作確認
flutter runは無茶苦茶時間かかる。測っていないが数時間単位で時間がかかる。CPUのパワーが足りないのか、メモリが足りなくてswapファイルにアクセスしまくって遅くなっているのかは不明。
Raspberry Pi 3Bにモニターをつないで表示させている。
無事カウンターアプリが起動。動作はもっさりしているものの、カウントアップもできる。
なおmacからsshでXをforwardingすると、Xのウィンドウは立ち上がるものの、やはりレンダラーが起動しない模様。
Launching lib/main.dart on Linux in debug mode...
Building Linux application...
(hello:1906): Gtk-WARNING **: 15:50:26.748: Locale not supported by C library.
Using the fallback 'C' locale.
libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
** (hello:1906): WARNING **: 15:51:13.610: Failed to start Flutter renderer: Unable to create a GL context
** (hello:1906): WARNING **: 15:51:13.907: Unable to retrieve framework response: No engine to send to
** (hello:1906): WARNING **: 15:51:13.913: Unable to retrieve framework response: No engine to send to
XQuartzにforwardingしているFlutterアプリケーションが動作しない問題
どうやらRaspberry Pi側の問題ではなく、sshで接続している元の問題らしい?
母艦のX Window環境はmacOS + XQuartzなので、XQuartzの設定を変更してみる。
defaults write org.xquartz.X11 enable_iglx -bool true
こちらのPDFの8ページ目にある設定をたたいてXQuartzを再起動した上で、再度sshでRaspberry Piに入って flutter run
する。
Launching lib/main.dart on Linux in debug mode...
Building Linux application...
(hello:2736): Gtk-WARNING **: 16:16:16.089: Locale not supported by C library.
Using the fallback 'C' locale.
libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
[ERROR:flutter/shell/gpu/gpu_surface_gl_delegate.cc(96)] Could not create a valid GL interface.
[ERROR:flutter/shell/platform/embedder/embedder_surface_gl.cc(111)] Internal error: Resource context available but could not create a compatible Skia context.
[ERROR:flutter/shell/gpu/gpu_surface_gl_delegate.cc(96)] Could not create a valid GL interface.
[ERROR:flutter/shell/gpu/gpu_surface_gl_skia.cc(54)] Failed to set up Skia Gr context.
[ERROR:flutter/shell/common/platform_view.cc(76)] Failed to create platform view rendering surface
No provider of glGenVertexArrays found. Requires one of:
Desktop OpenGL 3.0
GL_ARB_vertex_array_object
OpenGL ES 3.0
GL_APPLE_vertex_array_object
GL_OES_vertex_array_object
Error waiting for a debug connection: The log reader stopped unexpectedly, or
never started.
Error launching application on Linux.
ちょっとエラー変わった。
母艦macの glxinfo
の結果を見ると
OpenGL vendor string: Apple Inc.
OpenGL renderer string: Apple Software Renderer
OpenGL version string: 2.1 APPLE-19.5.1
OpenGL shading language version string: 1.20
3.0使えないんかい!!
どうやらmacOSというよりはXQuartzの問題らしい?
ということでFlutterのlinuxアプリケーションを、sshで接続してきたmacのX forwardingで表示するのは現時点では無理っぽい。
VNCとか何かでレンダリング結果を転送してもらう他にないかもしれない。
GLXとは
よく知らなかった。
Xサーバが動いているものと同じマシンでOpenGLアプリケーションを実行するとき、このアプリケーションはXクライアントとしてウィンドウの「枠だけ」はXサーバに管理してもらいつつ*1、その「枠」の中に表示する絵(つまり3D CG)はGPUに直接(X Window Systemを介さず)描画命令を送ってレンダリングする。これをdirect renderingと呼ぶ。
なーるほど、だから母艦のmac + XQuartzの方にOpenGL 3.0が必要だったのか。
(グラフィックボードがOpenGL 3.0対応してるのが前提だけど)Windowマシンが母艦なら行けたりするのかも。
(おまけ)Raspberry Pi 3 Bよりもう少し強力でARM64な仮想マシンでFlutterアプリバイナリをプレビルドする
Raspberry Pi 3 B上ではflutter runするだけでとんでもなく時間がかかってしまうため、もっと強力なマシンでビルド済みのバイナリを作り、ラズパイに転送するとかして開発の効率を上げたい。
残念ながらFlutter Desktopアプリのクロスコンパイルはまだできないっぽいため、母艦のmacOSではコードを書くのが限界。dartプロジェクトを転送して、実機でビルドするしかない。
というわけで、QEMUなど使って(多少でも)強力なARM64なマシンでアプリをビルドできないかという試み。
macにはUTMという良い感じのQEMUのGUIフロントエンドがあるので、これを使わせていただく。
出来合いのGarralyにDebianがあるものの、最新のDebian 11ではないので、自力でインストールからやることにした。
まずはここからDebian 11のインストールディスクを入手。もちろんARM64用のものを選択。
UTMではホストマシンのCPUをそのまま使うVirtualizationと、CPUもエミュレートするEmurationが選べる。
今回の母艦macはintel macなのでEnumationを選択。M1 macならVirtualizationで良いはず。
あとはboot imageに先ほどのisoファイルを選択して仮想マシンを作成、Diaplayの設定だけ Emulated Display Card
を virtio-ramfb
に変更しておく
(デフォルトの virtio-ramfb-gl
では画面が表示されなかった)。
あとは半日近くかけてOSをインストール。
Graphicalでなくてもインストールはできるので、テキストのインターフェイスでサクサク進める。途中でconfirmがちょいちょい入るので、マシンを離れているとインストールが止まっていることがあって時間がかかってしまった。
デスクトップ環境は適当にLXDEを選択。軽けりゃなんでも良い。
再起動前にインストールディスクのisoをアンマウントしておく。
あとは普通に再起動。snapdとflutterをインストール。
標準ユーザーをsudoersに入れてからsnapをインストールすべきだった。
rootでsnapをインストールしてしまうと、標準ユーザーに戻ってもパスが通ってなかった。
(なおsnapでインストールしたbinは /snap/bin
に入っている)
ビルドも実行もできたが、flutter run
にはかなり時間がかかった。
raspberry piでhot reloadを駆使しながらなんとかするのとそんなに変わらないかも。GPIOないし。