TOC
今年の7月にFlutterがデスクトップアプリの開発もできるようになりました。ステータスはアルファです。
🎉Canonical enables Linux desktop app support with Flutter!
— Flutter (@FlutterDev) July 8, 2020
Linux devs get Flutter support for their operating system of choice.
🚀Install the Flutter SDK via snap. Build and test on Linux using Visual Studio Code or Android Studio.
Learn more here ↓ https://t.co/vnciIcnruQ
現時点でのLinuxデスクトップ開発環境を構築しますが、LinuxでのAndroid向けのFlutter開発環境の構築を済ませている前提で作業します。確認環境はUbuntu MATE 20.04(amd64)です。
UbuntuでFlutter環境構築(2020年11月版) Android編
デスクトップ用の環境構築
必要なもの
- Flutter SDK
- (オプション)FlutterをサポートするIDE。Android Studio/IntelliJ IDEA, Visual Studio CodeとFlutter・Dartプラグインのインストール
- Flutter SDKに追加
- Clang
- CMake
- GTK development headers
- Ninja build
- pkg-config
- libblkid
- liblzma
Flutter SDKとIntelliJ IDEAは既にインストール済みなので、必要なコマンドをインストールします。
# apt-get install clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev
ここは大量にパッケージがインストールされます。
チャンネルをdevへ変更、デスクトップを有効化
$ flutter channel dev
$ flutter upgrade #177MBのダウンロード
$ flutter config --enable-linux-desktop
デバイスの生成
flutter devices
の実行でLinuxデバイスが1つ生成されます。
$ flutter devices
Downloading package sky_engine... 2,231ms
Downloading flutter_patched_sdk tools... 6.9s
Downloading flutter_patched_sdk_product tools... 4.7s
Downloading linux-x64 tools... 13.2s
Downloading linux-x64/font-subset tools... 1,780ms
1 connected device:
Linux (desktop) • linux • linux-x64 • Linux
この状態でflutter doctor
を実行するとデバイスが1つ接続されていると認識されています。
$ flutter doctor -v
[✓] Flutter (Channel dev, 1.24.0-10.2.pre, on Linux, locale ja_JP.UTF-8)
• Flutter version 1.24.0-10.2.pre at
/home/hogehoge/snap/flutter/common/flutter
• Framework revision 022b333a08 (30 hours ago), 2020-11-18 11:35:09 -0800
• Engine revision 07c1eed46b
• Dart version 2.12.0 (build 2.12.0-29.10.beta)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
• Android SDK at /home/hogehoge/AndroidSDK
• Platform android-30, build-tools 30.0.2
• ANDROID_SDK_ROOT = /home/hogehoge/AndroidSDK
• Java binary at: /usr/bin/java
• Java version OpenJDK Runtime Environment (build
1.8.0_275-8u275-b01-0ubuntu1~20.04-b01)
• All Android licenses accepted.
[✓] Linux toolchain - develop for Linux desktop
• clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
• cmake version 3.10.2
• ninja version 1.8.2
• pkg-config version 0.29.1
[!] Android Studio (not installed)
• Android Studio not found; download from
https://developer.android.com/studio/index.html
(or visit https://flutter.dev/docs/get-started/install/linux#android-setup
for detailed instructions).
[✓] IntelliJ IDEA Community Edition (version 2020.2)
• IntelliJ at /snap/intellij-idea-community/257
• Flutter plugin version 51.0.3
• Dart plugin version 202.8070
[✓] Connected device (1 available)
• Linux (desktop) • linux • linux-x64 • Linux
! Doctor found issues in 1 category.
デスクトップアプリの実行
既存アプリのデスクトップ対応追加
前回サンプルで作ったmyappというアプリをデスクトップアプリとしても使えるようにします。
場所を指定せずにプロジェクトを作成した場合は~/IdeaProjects/myapp
にプロジェクトが作られているので、プロジェクトルートに移動してflutter create .
を実行します。
$ cd ~/IdeaProjects/myapp
$ flutter create .
Recreating project ....
linux/flutter/CMakeLists.txt (created)
linux/.gitignore (created)
linux/CMakeLists.txt (created)
linux/my_application.h (created)
linux/main.cc (created)
linux/my_application.cc (created)
android/app/src/main/kotlin/com/example/myapp/MainActivity.kt (created)
android/app/src/main/res/drawable-v21/launch_background.xml (created)
android/app/src/main/res/values-night/styles.xml (created)
Running "flutter pub get" in myapp... 358ms
Wrote 12 files.
All done!
(snip)
In order to run your application, type:
$ cd .
$ flutter run
Your application code is in ./lib/main.dart.
ちなみに、これをせずにIDEAを起動してLinuxデバイスを接続して実行すると以下のエラーが発生します。
Downloading linux-x64/linux-x64-flutter-gtk tools...
Downloading linux-x64-profile/linux-x64-flutter-gtk tools...
Downloading linux-x64-release/linux-x64-flutter-gtk tools...
Running "flutter pub get" in myapp...
Launching lib/main.dart on Linux in debug mode...
Exception: No Linux desktop project configured. See https://flutter.dev/desktop#add-desktop-support-to-an-existing-app to learn about adding Linux support to a project.
Linuxデバイスを指定しての実行
IntelliJ IDEA Community Editionを起動すると、前回終了時に開いていたmyappプロジェクトがそのまま開かれて、デバイス欄から「Linux(desktop)」を選べるようになっています。
デバイスの右にある再生ボタンをクリックすると、デスクトップアプリとしてmyappが起動します。(えらい大画面で) ※リサイズ可能です。レイアウトは保たれます。
配布用のアプリを生成
現在まだステータスがstableではないので公式でも配布は推奨されていませんが、配布用のアプリをビルドしてみます。
プロジェクトルートでflutter build linux
を実行します。
$ flutter build linux
Running "flutter pub get" in myapp... 380ms
Building Linux application...
生成物は(おそらく)build/linux/release/bundle
の下に作られます。実行はそのままできます。右上のDEBUGが外れています。
依存ライブラリは以下の通りです。かなり多くのライブラリが実行時に必要に見えます。
$ ldd build/linux/release/bundle/myapp
linux-vdso.so.1 (0x00007fffc87da000)
libgtk-3.so.0 => /lib/x86_64-linux-gnu/libgtk-3.so.0 (0x00007f34f76d1000)
libgdk-3.so.0 => /lib/x86_64-linux-gnu/libgdk-3.so.0 (0x00007f34f75cc000)
libpangocairo-1.0.so.0 => /lib/x86_64-linux-gnu/libpangocairo-1.0.so.0 (0x00007f34f75ba000)
libpango-1.0.so.0 => /lib/x86_64-linux-gnu/libpango-1.0.so.0 (0x00007f34f756b000)
libatk-1.0.so.0 => /lib/x86_64-linux-gnu/libatk-1.0.so.0 (0x00007f34f7541000)
libcairo-gobject.so.2 => /lib/x86_64-linux-gnu/libcairo-gobject.so.2 (0x00007f34f7535000)
libcairo.so.2 => /lib/x86_64-linux-gnu/libcairo.so.2 (0x00007f34f7410000)
libgdk_pixbuf-2.0.so.0 => /lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0 (0x00007f34f73e8000)
libflutter_linux_gtk.so => /home/hogehoge/IdeaProjects/myapp/build/linux/release/bundle/lib/libflutter_linux_gtk.so (0x00007f34f682b000)
libgio-2.0.so.0 => /lib/x86_64-linux-gnu/libgio-2.0.so.0 (0x00007f34f664a000)
libgobject-2.0.so.0 => /lib/x86_64-linux-gnu/libgobject-2.0.so.0 (0x00007f34f65ea000)
libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007f34f64c1000)
libblkid.so.1 => /lib/x86_64-linux-gnu/libblkid.so.1 (0x00007f34f6468000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f34f6319000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f34f62fe000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f34f610c000)
libgmodule-2.0.so.0 => /lib/x86_64-linux-gnu/libgmodule-2.0.so.0 (0x00007f34f6106000)
libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6 (0x00007f34f5fc9000)
libXi.so.6 => /lib/x86_64-linux-gnu/libXi.so.6 (0x00007f34f5fb5000)
libXfixes.so.3 => /lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007f34f5fad000)
libatk-bridge-2.0.so.0 => /lib/x86_64-linux-gnu/libatk-bridge-2.0.so.0 (0x00007f34f5f76000)
libepoxy.so.0 => /lib/x86_64-linux-gnu/libepoxy.so.0 (0x00007f34f5e43000)
libfribidi.so.0 => /lib/x86_64-linux-gnu/libfribidi.so.0 (0x00007f34f5e26000)
libpangoft2-1.0.so.0 => /lib/x86_64-linux-gnu/libpangoft2-1.0.so.0 (0x00007f34f5e0d000)
libharfbuzz.so.0 => /lib/x86_64-linux-gnu/libharfbuzz.so.0 (0x00007f34f5d06000)
libfontconfig.so.1 => /lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007f34f5cbf000)
libfreetype.so.6 => /lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f34f5c00000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f34f5bdd000)
libXinerama.so.1 => /lib/x86_64-linux-gnu/libXinerama.so.1 (0x00007f34f5bd8000)
libXrandr.so.2 => /lib/x86_64-linux-gnu/libXrandr.so.2 (0x00007f34f5bc9000)
libXcursor.so.1 => /lib/x86_64-linux-gnu/libXcursor.so.1 (0x00007f34f5bbc000)
libXcomposite.so.1 => /lib/x86_64-linux-gnu/libXcomposite.so.1 (0x00007f34f5bb7000)
libXdamage.so.1 => /lib/x86_64-linux-gnu/libXdamage.so.1 (0x00007f34f5bb2000)
libxkbcommon.so.0 => /lib/x86_64-linux-gnu/libxkbcommon.so.0 (0x00007f34f5b70000)
libwayland-cursor.so.0 => /lib/x86_64-linux-gnu/libwayland-cursor.so.0 (0x00007f34f5b65000)
libwayland-egl.so.1 => /lib/x86_64-linux-gnu/libwayland-egl.so.1 (0x00007f34f5b60000)
libwayland-client.so.0 => /lib/x86_64-linux-gnu/libwayland-client.so.0 (0x00007f34f5b4d000)
libXext.so.6 => /lib/x86_64-linux-gnu/libXext.so.6 (0x00007f34f5b38000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f34f5b2d000)
libthai.so.0 => /lib/x86_64-linux-gnu/libthai.so.0 (0x00007f34f5b22000)
libpixman-1.so.0 => /lib/x86_64-linux-gnu/libpixman-1.so.0 (0x00007f34f5a7b000)
libpng16.so.16 => /lib/x86_64-linux-gnu/libpng16.so.16 (0x00007f34f5a41000)
libxcb-shm.so.0 => /lib/x86_64-linux-gnu/libxcb-shm.so.0 (0x00007f34f5a3c000)
libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f34f5a12000)
libxcb-render.so.0 => /lib/x86_64-linux-gnu/libxcb-render.so.0 (0x00007f34f5a03000)
libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1 (0x00007f34f57f9000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f34f57dd000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f34f57d5000)
libEGL.so.1 => /lib/x86_64-linux-gnu/libEGL.so.1 (0x00007f34f57c0000)
/lib64/ld-linux-x86-64.so.2 (0x00007f34f7ea6000)
libmount.so.1 => /lib/x86_64-linux-gnu/libmount.so.1 (0x00007f34f5760000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f34f5735000)
libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007f34f5719000)
libffi.so.7 => /lib/x86_64-linux-gnu/libffi.so.7 (0x00007f34f570d000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f34f5698000)
libdbus-1.so.3 => /lib/x86_64-linux-gnu/libdbus-1.so.3 (0x00007f34f5647000)
libatspi.so.0 => /lib/x86_64-linux-gnu/libatspi.so.0 (0x00007f34f5610000)
libgraphite2.so.3 => /lib/x86_64-linux-gnu/libgraphite2.so.3 (0x00007f34f55e3000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f34f55b5000)
libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1 (0x00007f34f55aa000)
libdatrie.so.1 => /lib/x86_64-linux-gnu/libdatrie.so.1 (0x00007f34f55a0000)
libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6 (0x00007f34f559a000)
libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f34f5592000)
libGLdispatch.so.0 => /lib/x86_64-linux-gnu/libGLdispatch.so.0 (0x00007f34f54da000)
libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007f34f5448000)
libsystemd.so.0 => /lib/x86_64-linux-gnu/libsystemd.so.0 (0x00007f34f5399000)
libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007f34f537f000)
liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f34f5356000)
liblz4.so.1 => /lib/x86_64-linux-gnu/liblz4.so.1 (0x00007f34f5335000)
libgcrypt.so.20 => /lib/x86_64-linux-gnu/libgcrypt.so.20 (0x00007f34f5215000)
libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0 (0x00007f34f51f2000)
相対パスで参照しているのはbuild/linux/release/bundle/lib/libflutter_linux_gtk.so
だけなので、そこを意識する必要はあるのかなと思います。配布時はbuild/linux/release/bundle/
以下をひとまとめにする必要がありそうです。
.
├── data
│ ├── flutter_assets
│ │ ├── AssetManifest.json
│ │ ├── FontManifest.json
│ │ ├── NOTICES
│ │ ├── fonts
│ │ │ └── MaterialIcons-Regular.otf
│ │ └── packages
│ │ └── cupertino_icons
│ │ └── assets
│ │ └── CupertinoIcons.ttf
│ └── icudtl.dat
├── lib
│ ├── libapp.so
│ └── libflutter_linux_gtk.so
└── myapp
7 directories, 9 files
(現時点では)クロスビルドはできない
試しにWindows用のバイナリをLinuxで生成できるのか、プロジェクトにWindowsデスクトップ対応を追加しました。
$ flutter config --enable-windows-desktop
Setting "enable-windows-desktop" value to "true".
You may need to restart any open editors for them to read new settings.
対応の追加はできました。ビルドしようとすると、
$ flutter build windows
Running "flutter pub get" in myapp... 368ms
"build windows" only supported on Windows hosts.
build windows
はWindows上でしか実行できない旨の表示がされました。ということで、少なくとも現時点では他プラットフォーム向けのビルドには該当プラットフォームが必要そうです。
公式ではLinux向けにはsnapパッケージを作って配布する案内がされています。
【追記】現時点では西洋言語以外の文字が豆腐になる
とっつき始めとして、以下のハンズオンをトレースしていました。
で、Flutterのライブラリがすげー膨大で何をするのにどうすればいいのか全くわからないままに見様見真似で作業をしていましたが、まずこのハンズオンを進めていくうちに日本語が豆腐になっていることに気付きます。
うーんこれは…仮想Androidデバイスで実行してみるとこう。
ということで、今の時点ではFlutter Desktop(Linux)1は本当にロジックのデバッグとかを効率よく進める以外の用途がないですね。
因みに、一応issueはあります。早いとこ治ってほしい。ちなみに、issueの中で--enable-fontconfig
引数を有効にすればfontconfigが動くようなのですが、FlutterSDKの中でビルド時に引数を指定できるような箇所がなかったので、IntelliJ IDEAを使う以上は指定する方法がなさそうです。
ついでにハンズオンしておかしかったところ
ハンズオンを最後までやったんですが、最後は商品をクリックすると詳細として画像、値段他色々表示されるはずなのですが、その前段階の中央に商品名が1行表示されるままだったのでコードを見てみると、lib/components/product_detail.dart
に書かれているProductDetail
クラスのWidget _body(BuildContext context, Product product) {}
を呼んでいる箇所がどこにもない為、ここに書かれている画像、値段他が表示されていないという状態です。
コードの意図としては、ProductDetail
クラスのWidget build(BuildContext context) {}
の中で
child: Text(
// とりあえず商品名でも表示してみる
product.title,
),
と書いているところのWidgetを_body()を呼ぶようにすれば良さそうなので、lib/components/product_detail.dart
のProductDetail
クラスのWidget build(BuildContext context) {}
をこんな風に直しました。
@override
Widget build(BuildContext context) {
final Product product = ModalRoute.of(context).settings.arguments;
return Scaffold(
appBar: AppBar(
title: Text("商品詳細"),
),
body: _body(context, product)
// body: Container(
// child: Center(
// child: Text(
// product.title,
// ),
// ),
// ),
);
}
結果、こうなります。(商品クリック時)
Linuxデスクトップ版はこう。
悲しき文字化け。
ロジックの開発・デバッグが効率的に
当初はiOS/Android用のDartの開発ライブラリとしてリリースされた印象の強いFlutterですが、Flutter for Webとともにデスクトップ用にも使えるようになっていることから、1つのアプリを複数のプラットフォーム向けに展開する可能性として、共通に開発できる部分やロジックの開発が簡単になることが期待できます。
デスクトップ用のプロジェクトはAndroidデバイスも必要がないため、ネイティブプログラムのデバッグと同じスピードで開発ができます。2デバッガによるブレークポイントの設定も可能です。
マルチプラットフォーム、マルチデバイスを実現できるプログラミング環境として発展していくといいなと個人的に思っています。
スポンサーリンク
comments powered by Disqus