对于深入学习Flutter
来说,搭建一个Engine
环境是很有必要的。Engine
是Flutter
底层(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也是需要x64
、arm
及arm_64
三种平台都得支持。但如果仅编译了arm
、x64
及arm_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/debug
或build/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
都需要加载一段时间(好几分钟)。
【参考资料】