3. Flutter你想要的热更新之编译构建 engine
Flutter你想要的热更新之编译构建 engine
本章目的是构建获得一个上一章节中修改后的 Flutter.framework 。
1. Flutter.framework
在 iOS 的 Flutter 项目中 Flutter.framework 是 Flutter 应用执行的基础。
1.1 本地 Flutter.framework
通常情况下在创建 Flutter 项目不需要自己构建 Flutter.framework,因为 Flutter 环境中自带了各种模式(debug,release,profile)下需要的 Flutter.framework ,这些 framework 位于本地环境:
$FLUTTER_ROOT/bin/cache/artifacts/engine
在 iOS App 构建时,会执行 xcode_backend.sh 根据构建类型将对应的 framework 拷贝到当前工程。xcode_backend.sh 位于本地环境:
$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh。
1.2 构建 Flutter.framework
Flutter.framework 是通过构建 engine 后的生成的。但是普通 Flutter 项目是不包含 engine 构建部分的,两者是分开的,也就是说要获得修改后的 Flutter.framework,需要先自行构建 engine,然后再将其集成到现有的 Flutter 工程中。
2. engine 的构建
2.1 构建环境的搭建
Flutter 官方 wiki 提供了各个平台搭建构建 engine 环境的详细文档。
因为本文主题是 Flutter 在 iOS 上的热更新,所本节主要介绍在 Mac 上 engine 构建环境的搭建及常见的问题。
2.1.1 依赖工具
- git:源代码管理( 2.x.x 以上版本,gclient 源码同步工具中使用到的部分 git 命令 1.x.x 不支持 )。
- ssh:Mac 系统自带。
- Python:用于源码同步及构建( 作者使用 2.7.x )。
- unzip:解压工具。
- curl:文件下载工具。
- depot_tools:gclient 工具,安装方式:
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
echo 'export PATH=$PATH:"替换成本地克隆的depot_tools仓库路径"' >> ~/.bashrc
确认 depot_tools 环境:
gclient --version
- Xcode:最新版本的 Xcode
- IDE(可选):开发调试用,官方推荐 Android Studio with the Flutter plugin,或者其他 IDE(Emacs,Vim,Neovim,Visual Studio Code,Nuclide) + cquery 代码自动不全插件。
2.1.2 设置并同步构建环境
- fork engine 仓库: 在自己 github 账户中 fork https://github.com/flutter/engine ,如果自己的 github 仓库中已有 frok 的 engine 仓库,请确保主分支与官方同步。
- 配置 github ssh 访问: 配置自己 github 账户的 ssh 访问,确保自己的 github 账户及本地主机已经设置了 ssh 密钥。如果没有设置,参考 generating-ssh-keys 。
- 创建
engine文件夹: 创建一个空文件夹并命名为engine,用来存放下载的源码和工具仓库。为了简单起见,最好不要使用其他名称。 - 创建
.gclient文件: 在engine目录下创建一个.gclient文件:,.gclient文件内容如下:solutions = [ { "managed": False, "name": "src/flutter", "url": "git@github.com:替换成你的githua账户/engine.git", "custom_deps": {}, "deps_file": "DEPS", "safesync_url": "", }, ] - 执行
gclient sync: 在engine目录中(也就是.gclient文件所在的目录),执行gclient sync。- 整个源码体积很大,环境同步前磁盘剩余空间最好在 20G 以上。
- 官文提示:命令将获取 Flutter 依赖的所有源文件。避免中断这个命令,中断命令可能会使存储仓库处于一个不稳定的状态,清理这个不稳定状态会非常繁琐。(,这个过程会自动执行
git clone等操作)。作者中断了几次也没出现什么问题。
- (可选)本地 engine 添加 upstream 为官方仓库: 添加 upstream 为官方仓库后,通过
git fetch命令就会拉去官方最新版本代码,而不是自己 github 中 fork 的 engine 代码。在engine/src/flutter目录中执行:git remote add upstream git@github.com:flutter/engine.git - (可选)安装 Oracle 的 Java JDK:用于 Android Flutter engine 构建。
- (可选)安装 ant:用于 Android Flutter engine 构建。
brew install ant
2.1.3 构建环境目录说明
- engine/src:构建工具根路径,是一个 git 仓库,对应远程仓库
https://github.com/flutter/buildroot.git。 - engine/src/flutter:Flutter engine 源码仓库,对应自己 github 账户上 fork 的 engine 仓库。
这就是我们要修改并构建获得 Flutter.framework 的 engine 仓库。
2.2 本地构建 engine
- 切换 engine 版本:切换到 Flutter 1.0.0 对应的 engine 版本。
#进入 engine 仓库目录 cd engine/src/flutter #切换 engine 版本 git checkout 7375a0f414bde4bc941e623482221db2fc8c4ab5 - 同步构建环境
#进入构建环境目录 cd engine #同步构建环境 gclient sync - 生成构建文件
#进入 src 目录 cd engine/src #生成构建文件(分别生成真机构建文件,模拟器构建文件和服务端构建文件) ./flutter/tools/gn --ios --unoptimized && ./flutter/tools/gn --ios --simulator --unoptimized && ./flutter/tools/gn --unoptimized - 编译
#进入 src 目录 cd engine/src #编译(分别编译真机文件,模拟器文件和服务端文件) ninja -C out/ios_debug_unopt && ninja -C out/ios_debug_sim_unopt && ninja -C out/host_debug_unopt
3.使用本地构建的 engine
-
创建 Flutter App
flutter create myapp -
修改 myapp/pubspec.yaml 文件
在文件末尾追加:dependency_overrides: sky_engine: path: /path/to/flutter/engine/out/host_debug/gen/dart-pkg/sky_engine sky_services: path: /path/to/flutter/engine/out/host_debug/gen/dart-pkg/sky_services修改
path:为 ios_debug_sim_unopt (真机为 ios_debug_unopt) 中 sky_engine 和 sky_services 的路径,如:dependency_overrides: sky_engine: path: /Users/guhaijun/Desktop/flutter_engine/engine/src/out/ios_debug_sim_unopt/gen/dart-pkg/sky_engine sky_services: path: /Users/guhaijun/Desktop/flutter_engine/engine/src/out/ios_debug_sim_unopt/gen/dart-pkg/sky_services -
设置 FLUTTER_ENGINE 环境变量
在终端执行或修改XCode工程在XCode —> TARGETS -> Runner -> Build Phases -> Run Script的首行插入export FLUTTER_ENGINE=/path/to/engine/src环境变量 FLUTTER_ENGINE 为
engine/src路径,根据当前环境路径修改,如:export FLUTTER_ENGINE=/Users/guhaijun/Desktop/flutter_engine/engine/src -
运行 Flutter App
flutter run --local-engine-src-path=/path/to/engine/src --local-engine=ios_debug_sim_unopt--local-engine-src-path 为
engine/src路径,根据当前环境路径修改,如:flutter run --local-engine-src-path=/Users/guhaijun/Desktop/flutter_engine/engine/src --local-engine=ios_debug_sim_unopt