LoginSignup
3
2

Flutter:Flavorを使ってビルドを切り替える(alpha, product)

Last updated at Posted at 2023-08-07

前置き

  • Flutterにおけるビルド種類分け、切り替えについての説明です。
  • Mac / windowsを対象としたデスクトップ向けのアプリケーションを想定しています。
  • C++ & Dartで構成されたアプリケーションです。
  • 開発環境はvscodeです。

Flutterのビルドの仕組み

androidのビルドの仕組みと似ています。
ビルドタイプ x flavorの掛け合わせになっています。

Flavorとは?

androidには、ビルドバリアントという仕組みが存在します。

そこでは、ビルドタイプ x product flavorの掛け合わせがビルドの種類をさし示します。
Flutter関連の記事は未確認ですが、Flutterもこの流れを組んでいる、と思われます。
androidで言えば、

  • debug
  • release

という2つのビルドタイプが存在し、それに加えて、product flavorが存在します。
仮に

  • alpha
  • beta
  • product

という3つの product flavorが存在する時、それの掛け合わせとなるため、

  • debugalpha
  • debugbeta
  • debugproduct
  • releasealpha
  • releasebeta
  • releaseproduct

という6つのビルドの種類ができる、ということになります。

Flavorを使った場合、どのようなビルドになるか?

Flutterのビルドタイプは、3つ存在します。

  • debug mode
  • profile mode
  • release mode

profile modeは、debug <-> releaseの間に位置するタイプです。
ある程度ソースコードのデバッグは可能ですが、より release modeに近い環境でデバッグするのを目的としているように思います。

つまり、これら既存の3種類 x flavorとの掛け合わせとなるわけです。
本記事では、flavor typeに、

  • alpha
  • product

という2種類のタイプを定義して、それらをどのように切り分けるのかを書いていきます。
イメージとしては下記の整理としています。

ビルドタイプ Flavor 備考
debug alpha
profile product 場合によってはalphaでもいいかな?
release product

掛け合わせの最大数としてはもっと定義はできますが、今回は必要最低限の種類として考えました。

実際にビルドを分けていく

方法は色々ありますが、dart-define-from-fileを使ってビルド分けするのが妥当だと思います。
こちらの記事が参考になりました。

dart-define-from-fileはどのように使うか

タイトルそのままなのですが、ビルドのタイプに応じて、設定ファイルを切り替える、というふうに使います。
なので、from-fileなわけですね。

用意するファイル

ビルドの設定ファイルは、jsonで用意します。
そしてそれをビルド時に、引数として与えることでビルドの切り替えを行います。

flutterProject_Root
├──flavor
│   ├── alpha.json
│   └── product.json
....

ファイル名は、flavor名にしておくと良いでしょう。

alpha.json
{
    "flavor": "alpha",
    "appName": "sample-alpha",
    "appIdSuffix": ".alpha"
}
product.json
{
    "flavor": "product",
    "appName": "sample",
    "appIdSuffix": ""
}

基本はこれだけです。

コマンドでは実際にどのようにビルドするのか

ビルド

flutter build macos --dart-define-from-file=flavor/alpha.json

実行

flutter run --dart-define-from-file=flavor/alpha.json

合わせて、--debug or --release などを追加すると、より明確にビルドができます。

debug時、launch.jsonでの書き方

vscodeでのデバッグを想定して書いています。
vscode環境で、デバッグ実行するとき、launch.jsonでデバッグしますが、その記載例です。

launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      // mac向けデバッグ
      "name": "(lldb) Launch",
      "type": "cppdbg",
      "request": "launch",
      "osx" : {
        "program":"${workspaceFolder}/build/macos/Build/Products/Debug/hogehoge.app",
        "MIMode": "lldb"
      },
        "args": [],
        "stopAtEntry": false,
        "cwd": "${workspaceFolder}",
        "environment": [],
        "externalConsole": false,
    },
    {
      // dart debug
      "name": "hogehoge",
      "request": "launch",
      "type": "dart",
      "flutterMode": "debug",
      "args": [
        "--dart-define-from-file=flavor/alpha.json"
      ],
      "windows": {
        "env": { "FLUTTER_FLAVOR" : "alpha" },
      }
    },
    {
      // profile dart debug
      "name": "hogehoge (profile mode)",
      "request": "launch",
      "type": "dart",
      "flutterMode": "profile",
      "args": [
        "--dart-define-from-file=flavor/alpha.json"
      ],
      "windows": {
        "env": { "FLUTTER_FLAVOR" : "product" },
      }
    },
    {
      // release flutter run
      "name": "hogehoge (release mode)",
      "request": "launch",
      "type": "dart",
      "flutterMode": "release",
      "args": [
        "--dart-define-from-file=flavor/product.json"
      ],
      "windows": {
        "env": { "FLUTTER_FLAVOR" : "product" },
      }
    }
  ]
}

このように記載します。
windows版についての定義をここで先に見せていますが、次の項でどうしてこのような書き方をしているのか説明します。

windows版についてのビルドの仕方

windows 版の場合は、一工夫、必要になっています。

launch.json
...
"windows": {
        "env": { "FLUTTER_FLAVOR" : "product" },
      }
...

どうしてこのような定義が必要なのでしょうか?
これは、私が作ったプロジェクトの都合ですが、今作っているプロジェクトが、
C++ & Dartで構成されたプロジェクトであるためです。

windowsにおけるC++のビルド

windowsにおけるC++の呼び出し方法については、割愛します。
下記記事など参考にされると良いと思います。

Flutter におけるC++のビルドは、Macではそこまで問題がありません。

Flutterにおけるnative層は、ffiを使って呼び出します。
これは、web版では動作しませんが、macos、windowsでは動作することが可能です。

ライブラリとして呼び出すわけですが、windows版の場合は、dllのPathなどを指定して、開く必要があります。

....
static late DynamicLibrary hogeLib;
hogeLib = Platform.isWindows
        ? DynamicLibrary.open(windowsDLLPath)
        : DynamicLibrary.process();
....

そのため、C++のnative層は、dartでビルドする前に、用意しておく必要がある分けです。

windowsにおけるdart-define-from-fileの落とし穴

C++の部分は、DLLとして用意することにしました。

  1. Cmakeにてvisual studioのプロジェクトを生成し
  2. それをビルド(DLL生成)
  3. dartの部分をビルドして、Flutterをビルド

ただ、この工程での問題は、
dart-define-from-fileを使ってビルドする時に与える、

launc.json
"args": [
        "--dart-define-from-file=flavor/alpha.json"
      ],

このargsを渡せないことにあります。
CMakeでのビルド時に、alpha.jsonで定義している

"flavor": "alpha",

の要素を渡したいわけですが、これがCMake側で認識することができないのです。
そこで、flavorという値を渡すことを諦めることにしました。

代わりに、

  1. ビルド時に環境変数FLUTTER_FLAVORの値を定義
  2. CMakeで環境変数をチェック
  3. CMakeで環境変数でAlphaが立っていたら、マクロFLAVOR_ALPHA定義
  4. C++側では、定義されているマクロによってビルドを分ける

という流れにすることにしました。

CMakeLists.txt
if ($ENV{FLUTTER_FLAVOR} MATCHES "alpha")
  target_compile_definitions(${BINARY_NAME} PRIVATE "FLAVOR_ALPHA")
endif ()
hoge.h
#ifdef FLAVOR_ALPHA
#else
#endif

こんな感じで場合分けします。

まとめ

alpha or productにおけるビルド種類の切り替えについて紹介しました。
windows版のビルドが若干めんどくさいですが、ここら辺がより簡単になると良いかな〜と思います。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2