Flutter Engine环境搭建

5,245 阅读6分钟

对于深入学习Flutter来说,搭建一个Engine环境是很有必要的。EngineFlutter底层(C/C++)的实现,包含了Dart VM、Skia、vulkan等第三方库。

1、环境准备

由于需要访问谷歌去拉取源码,所以必须设置好代理,包括:

  • git的http/https代理
  • 终端的http/https代理

只有当代理设置成功后,后面的操作才会顺利,否则有可能因为网络原因从而导致失败。关于代理的具体设置可以去百度/谷歌搜一下。

在拉取代码前,需要先把依赖工具准备好。

  • Linux、macOS或Windows,最好macOS,因为MacOS同时支持Android和iOS的交叉编译功能。
  • git,版本控制。
  • IDE,官方建议Android Studio。
  • ssh client,用于Github的身份认证,具体配置参考Connecting to GitHub with SSH
  • depot_tools,该工具包含gclient命令。
  • Python及Java环境。

2、Engine源码下载

环境准备好后,就可以来下载Engine源码。首先来创建一个空文件夹——engine,当然也可以使用其他名称。然后在该文件夹中创建一个.gclient文件,内容如下:

solutions = [
  {
    "managed": False,
    "name": "src/flutter",
    "url": "git@github.com:<your_name_here>/engine.git",
    "custom_deps": {},
    "deps_file": "DEPS",
    "safesync_url": "",
  },
]

关于这里的url,需要注意一下,如果自己的GitHub账户没有forkhttps://github.com/flutter/engine,那么就需要先fork,然后用自己的账户名称替换<your_name_here>。如果不想fork,可以用flutter替换<your_name_here>。

注意: 创建的文件名称是.gclient,而不是文件的后缀为.gclient。创建成功后,不会在文件夹中显示,但可以通过vim来查看该文件。

.gclient文件创建成功后,进入engine这个空文件夹,然后运行gclient sync命令来下载Engine源码。这时候就需要拼网速或者访问谷歌是否稳定,如果一切顺利(可能几个小时),目录如下。

3、Engine编译

再看来Engine的编译。进入src目录,就可以通过一些命令来进行编译Engine,如下:

./flutter/tools/gn --android --runtime-mode=debug
ninja -C out/android_debug -j 6
./flutter/tools/gn --runtime-mode=debug
ninja -C out/host_debug -j 6

通过上面命令就可以编译能在Android上运行且cpu类型为armeabi_v7a的产物。

再通过./flutter/tools/gn --help命令来看一下其他参数。

usage: gn [-h] [--unoptimized]
          [--runtime-mode {debug,profile,release,jit_release}] [--interpreter]
          [--dart-debug] [--full-dart-debug]
          [--target-os {android,ios,linux,fuchsia}] [--android]
          [--android-cpu {arm,x64,x86,arm64}] [--ios] [--ios-cpu {arm,arm64}]
          [--simulator] [--fuchsia] [--linux-cpu {x64,x86,arm64,arm}]
          [--fuchsia-cpu {x64,arm64}] [--arm-float-abi {hard,soft,softfp}]
          [--goma] [--no-goma] [--lto] [--no-lto] [--clang] [--no-clang]
          [--clang-static-analyzer] [--no-clang-static-analyzer]
          [--target-sysroot TARGET_SYSROOT]
          [--target-toolchain TARGET_TOOLCHAIN]
          [--target-triple TARGET_TRIPLE]
          [--operator-new-alignment OPERATOR_NEW_ALIGNMENT] [--enable-vulkan]
          [--enable-metal] [--enable-fontconfig] [--enable-skshaper]
          [--enable-vulkan-validation-layers] [--embedder-for-target]
          [--coverage] [--out-dir OUT_DIR] [--full-dart-sdk]
          [--no-full-dart-sdk] [--ide IDE] [--build-glfw-shell] [--bitcode]
          [--stripped] [--no-stripped] [--asan] [--lsan] [--msan] [--tsan]
          [--ubsan]

参数众多,来看几个常用的。

  • --unoptimized,是否优化性能,默认优化。
  • --runtime-mode,flutter的运行模式,有debug,profile,release,jit_release四种选择。
  • --target-os,目标系统,有android,ios,linux,fuchsia四种选择。--target-os=android等同于--android命令,--target-os=ios等同于--ios命令,以此类推。
  • --android-cpu,Android所运行平台,有arm,x64,x86,arm64四种选择。如果要在Android模拟器上运行,则--android-cpu=x86。注意: 这里的arm其实对应的是armeabi_v7a。但如果要编译armeabi(Google目前已经不建议使用armeabi),可以参考Flutter Engine 编译指北这篇文章。
  • --simulator,iOS所运行平台为模拟器。
  • --ios-cpu,iOS所运行平台,有arm,arm64两种选择。

通过对上面命令的组合,就可以编译Android及iOS平台上不同CPU类型的产物。

例如,Android平台,cpu类型为arm64,运行模式为debug的产物。

./flutter/tools/gn --android --runtime-mode=debug --android-cpu=arm64 
ninja -C out/android_debug_arm64 -j 6
./flutter/tools/gn --runtime-mode=debug --android-cpu=arm64
ninja -C out/host_debug_arm64 -j 6

例如,iOS平台,cpu类型为arm64,运行模式为debug的产物。

./flutter/tools/gn --ios --runtime-mode=debug --ios-cpu=arm64 
ninja -C out/ios_debug_arm64 -j 6
./flutter/tools/gn --runtime-mode=debug --ios-cpu=arm64
ninja -C out/host_debug_arm64 -j 6

4、运行及IDE支持

编译成功后,就可以在运行flutter项目时使用编译成功的本地Engine,通过一下命令运行项目即可。

flutter run --local-engine-src-path <FLUTTER_ENGINE_ROOT>/engine/src --local-engine=android_debug

在这里要注意一点,--local-engine必须对应具体的CPU类型。如在模拟器上跑,就是--local-engine=android_debug_x86--local-engine=android_debug_x64,在cpu为arm64的手机上跑,就是--local-engine=android_debug_arm64,以此类推,示例如下。

flutter run --local-engine-src-path <FLUTTER_ENGINE_ROOT>/engine/src --local-engine=android_debug_arm64

当然也可以通过先打包APK,再安装APK的方式来运行。

正式环境APK

 flutter build apk --release --local-engine-src-path /Users/limeihong/Desktop/engine/src --local-engine=android_release

debug环境APK

 flutter build apk --debug --local-engine-src-path /Users/limeihong/Desktop/engine/src --local-engine=android_debug

但是,上面打包APK也是需要x64armarm_64三种平台都得支持。但如果仅编译了armx64arm_64中的任意一种或两种,就得在打包APK时显示的指定某一类型。

flutter build apk --target-platform android-arm --split-per-abi --debug --local-engine-src-path /Users/limeihong/Desktop/engine/src --local-engine=android_debug

上面是指定打包cpu类型为arm,如果要想其他类型的apk,则将android-arm替换即可,如替换成android-x64或android-arm_64。

打包成功后,apk默认在路径build/app/outputs/apk/debugbuild/app/outputs/apk/release下,然后通过通过以下命令安装即可。

flutter install build/app/outputs/apk/debug/xxxx.apk

这样就可以成功将编译的Engine打包仅APK并运行。

注意: 正式环境下的apk需要签名文件,默认的正式包是没有签名的,而没有签名的正式包在手机上是无法运行的。

再来看如何通过VS Code来查看源码,首先得配置VS Code的C/C++环境,然后再安装cquery

在macOS上可以通过下面一句命令来安装cquery

brew install --HEAD cquery

cquery安装成功后,VS Code还需要安装cquery插件支持,这很简单,直接去商店搜索cquery并安装即可。

IDE配置完成后。再把src/out/compile_commands.json文件移动到src/compile_commands.json

最后再用VS Code打开src目录就可以方便快捷的阅读源码。当然如果要对Engine做一些修改,也可以通过上面的方式来重新编译Engine并打包进安装包中。

注意: 由于Engine的东西非常多,所以每次用VS Code打开src都需要加载一段时间(好几分钟)。

【参考资料】

Setting up the Engine development environment

Compiling the engine

搭建Flutter Engine源码编译环境

Flutter Engine 编译指北