Windows
Flutter
FlutterDesctopEmbedding

Flutter desktop embedding を Windows で試す

この記事を見て 『すげぇ、Android エミュレータ要らないじゃん』と感動したので、ちょっとやってみた。


Desktop Embedding for Flutter

https://github.com/google/flutter-desktop-embedding

Flutter で Windows/macOS/Linux 向けのアプリケーションが作れるようになった。

とりあえずよくわからないので、やってみる。


環境構築 ~ サンプル実行

まとまった情報が見つけられなかったので、以下を参考に進める。


Flutter SDK

まずは、Flutter と Flutter-desktop-embedding を取ってきて置く必要があるらしい。

既に Flutter 環境はあったが、何されるか分からないし汚染されても面倒なので改めて取ってくる。

PS> mkdir test; cd test

PS
> mkdir sdk; cd sdk
PS> git clone https://github.com/flutter/flutter
PS> git clone https://github.com/google/flutter-desktop-embedding
PS> ls
# drwxrwxrwx - user 30 Jan 22:02 flutter
# drwxrwxrwx - user 30 Jan 22:05 flutter-desktop-embedding


Flutter-desktop-embedding Library の Build

次に、Flutter-desktop-embedding の Library をビルドする必要がある。

Visual Studio Community でのビルドを押しているが、もし仕事で使うなら無料で使えないケースもあるので今回は BuildTools を使ってやってみる。


Visual Studio BuildTools

ここから、Build Tools for Visual Studio 2017 をダウンロードしてインストールする。

https://visualstudio.microsoft.com/ja/downloads/

インストールが終わると、ビルドツールが C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\ 以下に配置されるので、必要な場所にパスを通しておく。


  • C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin

  • C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build

パスが通っていれば、以下が動くはず。

PS> MSBuild.exe /version

# .NET Framework 向け Microsoft (R) Build Engine バージョン 15.9.21+g9802d43bc3
# Copyright (C) Microsoft Corporation.All rights reserved.
#
# 15.9.21.664

PS> vcvars64.bat
# **********************************************************************
# ** Visual Studio 2017 Developer Command Prompt v15.0
# ** Copyright (c) 2017 Microsoft Corporation
# **********************************************************************
# [vcvarsall.bat] Environment initialized for: 'x64'

● Windows SDK

実際にビルドしようとすると、以下のようなエラーが出ることがある。

2019-01-30_23h01_36.png

Windows SDK の Windows 10 SDK Version 1803 が足りないということなので、以下からダウンロードし、インストールする必要がある。

https://developer.microsoft.com/ja-jp/windows/downloads/sdk-archive



インストールが完了したら、ビルドを行う。

PS> cd sdk\flutter-desktop-embedding\library\windows

PS> MSBuild.exe '.\Flutter Windows Embedder.sln'

正常にビルドが完了すると、bin\x64\Debug Dynamic Library\GLFW Library 以下に flutter_embedder.dllflutter_engine.dll が生成されている。


サンプル実行

ということで、ここで一度サンプルを実行してみる。

PS> cd sdk\flutter-desktop-embedding\example\windows_fde

PS> MSBuild.exe '.\Example Embedder.sln'

正常にビルドが完了すると、bin\x64\Debug Dynamic Library\GLFW Example 以下に GLFW Example.exe が生成されるので、起動してみる ( 起動は Working Directory を windows_fde にして実行する必要がある )。

PS> & '.\bin\x64\Debug Dynamic Library\GLFW Example\GLFW Example.exe'

# flutter: Observatory listening on http://127.0.0.1:57524/

起動はとても早い。

メモリ使用量もとても低く、Android エミュレータとは比べ物にならない。

ただ、リサイズに関しては、元記事のように滑らかにはならず、一瞬黒い画面になる。


デバッグ

デバッグ環境も構築する。

今回は、 VS Code から attach する。

Dart のソースコードは flutter-desktop-embedding\example\lib 以下にある。

まずは、Flutter Plugin を導入する。

次に、Debug 設定を行う。

VS Code のサイドバーで Debug を選択して、Add Configuration で雛形を生成する。

2019-01-31_06h19_58.png

出来た雛形を、以下のように書き換える

  {

"name": "Flutter",
"request": "attach",
"deviceId": "flutter-tester",
"observatoryUri": "http://127.0.0.1:<<さっき起動した時の Port>>/",
"type": "dart"
}

flutter.gif


リリース

リリースビルドもやってみる。

PS> cd sdk\flutter-desktop-embedding\example\windows_fde

PS> MSBuild.exe '.\Example Embedder.sln' /p:Configuration="Release Dynamic Library"

image.png


中身を見てみる

そもそも alpha ですらないので、詳しく調べてもしょうがない気もするが、ちょっと調べてみた。


Embedder

これが、Flutter を Desktop Application に埋め込む機能を持つライブラリ。flutter-desktop-embedding\library 以下にソースがある。

Pre-Build なバイナリが提供されていないのは、ビルド生成物と flutter_assets のバージョンが合わないと動かなくなるかららしい。

Windows 版のビルド過程を見ていくと、

1. PreBuild

以下 Script を順次実行していく。



  • library\windows\scripts\update_flutter_engine.bat


    • Flutter Engine ( flutter_engine.dll ) の取得・更新




  • library\windows\scripts\get_engine_artifacts.bat


    • Flutter Project から ICU Data ( icudtl.dat ) をコピー




  • library\windows\scripts\get_GLFW.bat



    • http://github.com/glfw/glfw から Dll ( glfw3.dll ) とヘッダファイルを取得




  • library\windows\scripts\build_jsonlib.bat



    • https://github.com/open-source-parsers/jsoncpp からソースファイルとヘッダファイル取得、ビルド



これらバッチファイルの実態は、flutter-desktop-embedding\tools 以下のバッチファイルや flutter-desktop-embedding\tools\dart_tools 以下の Dart ファイルを呼び出しているだけ。

2. Build

flutter-desktop-embedding\library\include と PreBuild で取得したヘッダファイルを Include し、flutter-desktop-embedding\library\common にあるソースをビルドして flutter_embedder.dll を生成する。

3. PreLink

ビルド後に、1. で取得した flutter_engine.dllflutter_embedder.dll と同じ出力先にコピー。

これで、Embedder ライブラリ作成は完了。

以降はこれを使い回すこともできるだろうが、flutter_assets のバージョンが上がったらそれに合わせてリビルドする必要はありそうだ。


Flutter Project

flutter-desktop-embedding\example が Flutter プロジェクトの構成をしている。

以下が標準的な Flutter プロジェクトに含まれるフォルダ・ファイルとなる。

# .

# └── example
# ├── android\
# ├── build\
# ├── fonts\
# ├── ios\
# ├── lib\
# ├── test\
# ├── .gitignore
# ├── .metadata
# ├── .packages
# ├── pubspec.lock
# ├── pubspec.yaml
# └── README.md

flutter-desktop-embedding\example では、そこに linux_fde macos_fde windows_fde が新たに追加されている。 ( _fde [ flutter desktop embedding ] が付くのは、本家 Flutter がこれら Platform に対応した際、名前がバッティングする可能性がある為 )

Dart の設定ファイルである pubspec.yaml を見てみると、


pubspec.yaml

name: example_flutter

description: An example project for flutter-desktop-embedding.

dependencies:
flutter:
sdk: flutter

cupertino_icons: ^0.1.0

# Desktop embedder plugins.
# Note: In an actual project, these paths would include the
# path from your application to the flutter_desktop_embedding
# checkout.
color_panel:
path: ../plugins/color_panel
file_chooser:
path: ../plugins/file_chooser
menubar:
path: ../plugins/menubar

dev_dependencies:
flutter_test:
sdk: flutter

flutter:
uses-material-design: true

fonts:
- family: Roboto
fonts:
- asset: fonts/Roboto/Roboto-Thin.ttf
weight: 100
- asset: fonts/Roboto/Roboto-Light.ttf
weight: 300
- asset: fonts/Roboto/Roboto-Regular.ttf
weight: 400
- asset: fonts/Roboto/Roboto-Medium.ttf
weight: 500
- asset: fonts/Roboto/Roboto-Bold.ttf
weight: 700
- asset: fonts/Roboto/Roboto-Black.ttf
weight: 900


一つ上の階層にある flutter-desktop-embedding\plugins と、同階層にある flutter-desktop-embedding\example\fonts を参照している。


XXXX_fde Project

実際に Emmbed するプロジェクトである windows_fde がビルド時に何をしているかを見ていくと、

1. PreBuild

flutter build bundle で、flutter-desktop-embedding\example\build\ 以下 assets を生成

2. Build

Embeddr が生成した Dll をリンクし、flutter-desktop-embedding\example\windows_fde\flutter_embedder_example.cpp をビルドして GLFW Example.exe を生成する

3. PreLink, PostBuild

GLFW Example.exe の隣に flutter_embedder.dll, flutter_engine.dll をコピーする。

これで、ビルドは完了。

ちなみに flutter_embedder_example.cpp の中身を見てみると、


flutter_embedder_example.cpp

...

#include "flutter_desktop_embedding/glfw/flutter_window_controller.h"

int main(int argc, char **argv) {
// TODO: Make paths relative to the executable so it can be run from anywhere.
std::string assets_path = "..\\build\\flutter_assets";
std::string icu_data_path = "..\\..\\library\\windows\\dependencies\\engine\\icudtl.dat";
...

flutter_desktop_embedding::FlutterWindowController flutter_controller(icu_data_path);

// Start the engine.
if (!flutter_controller.CreateWindow(640, 480, assets_path, arguments)) {
return EXIT_FAILURE;
}

// Run until the window is closed.
flutter_controller.RunEventLoop();
return EXIT_SUCCESS;
}


とてもシンプルで、flutter_controller を icu_data 付きで初期化して、CreateWindow に flutter_assets を渡して Application を表示させている。

asset_path が相対パスで指定されていて、起動した時に asset ファイルを読み込んでるのかと思ったが、書き換えても内容が変更しないのはちょっと不思議。


感想

とりあえず、GLFW ( OpenGL ) を使って GUI 作ってるってのは分かった。

SAVE ボタンを押すとエラーが起きたり、突然の死も多く、まだまだ安定しているとは言えない。

もう少し様子見。