准备工作
本机环境: macos , Fluttr 2.5
代理配置
- Git代理配置
Git代理配置一般需要两种,第一种是走http协议的代理,第二种是走ssh协议代理
http代理(注意最后的1087端口,根据你的梯子的端口去配置)
git config --global http.proxy http://127.0.0.1:1087
git config --global https.proxy http://127.0.0.1:1087
如果要取消http代理
git config --global --unset http.proxy
git config --global --unset https.proxy
加上http代理后,内网很可能无法访问,加上如下配置
export no_proxy="127.0.0.1,localhost,xxxx"(xxx是内网git域名)
ssh代理
open ~/.ssh/config
文件里增加
Host github.com
HostName github.com
User git
# 注意这里的1080端口,如 Shadowsocks,v2ray,根据自己的梯子端口配置)
ProxyCommand nc -v -x 127.0.0.1:1080 %h %p
- 终端代理配置(这是临时配置)
export http_proxy=http://127.0.0.1:1087
export https_proxy=http://127.0.0.1:1087
depot_tools工具安装
windows或者Linux 参考官网
1. mac或者linux环境
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
配置环境变量
export PATH="$PATH:/path/to/depot_tools"
获取源码
构建前的配置
创建目录
mkdir -p flutter_engine/engine_251
cd flutter_engine/engine_251
创建gclient配置文件
[参考地址](https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/HEAD/README.gclient.md)
在上一步创建的目录中执行 touch .gclient
把以下的内容复制粘贴到.gclient文件中
solutions = [
{
"managed": False,
"name": "src/flutter",
"url": "git@github.com:flutter/engine.git",
"custom_deps": {},
"deps_file": "DEPS",
"safesync_url": "",
},
]
接着执行gclient sync
如果需要拉取指定版本的源码,例如文章中是Flutter 2.5.1版本,commitId是b3af521a050e6ef076778bcaf16e27b2521df8f8,那就参考下面的配置
引擎版本在这个文件:your_flutter_path/flutter/bin/internal/engine_version
solutions = [
{
"managed": False,
"name": "src/flutter",
"url": "git@github.com:flutter/engine.git@b3af521a050e6ef076778bcaf16e27b2521df8f8",
"custom_deps": {},
"deps_file": "DEPS",
"safesync_url": "",
},
]
如果之前已经同步过了,需要先回退到之前的提交,然后执行同步
//b3af521a050e6ef076778bcaf16e27b2521df8f8 就是flutter 2.5.1的版本
git reset --hard b3af521a050e6ef076778bcaf16e27b2521df8f8
gclient sync --with_branch_heads --with_tags --verbose
编译可debug的引擎产物
编译过程中如果出现类似的错误,TypeError: expected str, bytes or os.PathLike object, not NoneType 需要python3,本机环境是pyrhon 3.8.7
以Android arm64产物为例
cd your_local_engine_path/flutter_engine/engine_251/src
./flutter/tools/gn --android --android-cpu arm64 --unoptimized
ninja -C out/android_debug_unopt_arm64/ -j 8
./flutter/tools/gn --android-cpu arm64 --unoptimized
ninja -C out/host_debug_unopt_arm64/ -j 8
编译完成之后使用本地引擎的产物
flutter build apk --debug --target-platform=android-arm64
--local-engine-src-path=your_engine_path/engine/src
--local-engine=android_debug_unopt_arm64
或者直接使用flutter的build方式
flutter build apk --local-engine=android_debug_unopt --local-engine-src-path=/engine/src
gn的其他命令参考如下
gn -h 参数如下
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-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]
我们使用到的构建参数主要有以下几种
--android 指定android平台
--ios 指定ios平台
--runtime-mode debug,profile,release
--unoptimized 默认是optimized优化过的
--android-cpu {arm,x64,x86,arm64} 默认是arm(对应arm-v7)
--ios --ios-cpu {arm,arm64}
构建其他Android可debug产物
Android的arm的debug优化版
cd src/
./flutter/tools/gn --android
ninja -C out/android_debug -j 8
./flutter/tools/gn
ninja -C out/host_debug -j 8
Android x64的profile非优化版
cd src/
./flutter/tools/gn --android --android-cpu x64 --unoptimized --runtime-mode=profile
ninja -C out/android_profile_unopt_x64 -j 8
./flutter/tools/gn --android-cpu x64 --unoptimized --runtime-mode=profile
ninja -C out/host_profile_unopt_x64 -j 8
构建IOS可debug产物
iOS arm64未优化debug版本
cd /engine/src/
./flutter/tools/gn --ios --unoptimized --runtime-mode=debug
ninja -C out/ios_debug_unopt -j 8
./flutter/tools/gn --unoptimized --runtime-mode=debug
ninja -C out/host_debug_unopt -j 8
构建正式产物,替换本地引擎
第一步
cd your_local_engine_path/flutter_engine/engine_251/src
下面的步骤都不包含x86 第二步 调用gn生成ninjia配置文件
./flutter/tools/gn --runtime-mode=debug --android-cpu=arm --android --no-goma --no-dart-version-git-info
./flutter/tools/gn --runtime-mode=profile --android-cpu=arm --android --no-goma --no-dart-version-git-info
./flutter/tools/gn --runtime-mode=release --android-cpu=arm --android --no-goma --no-dart-version-git-info
./flutter/tools/gn --runtime-mode=debug --android-cpu=arm64 --android --no-goma --no-dart-version-git-info
./flutter/tools/gn --runtime-mode=profile --android-cpu=arm64 --android --no-goma --no-dart-version-git-info
./flutter/tools/gn --runtime-mode=release --android-cpu=arm64 --android --no-goma --no-dart-version-git-info
./flutter/tools/gn --runtime-mode=debug --android-cpu=x64 --android --no-goma --no-dart-version-git-info
./flutter/tools/gn --runtime-mode=profile --android-cpu=x64 --android --no-goma --no-dart-version-git-info
./flutter/tools/gn --runtime-mode=release --android-cpu=x64 --android --no-goma --no-dart-version-git-info
./flutter/tools/gn --runtime-mode=debug --android-cpu=x86 --android --no-goma --no-dart-version-git-info
./flutter/tools/gn --runtime-mode=jit_release --android-cpu=x86 --android --no-goma --no-dart-version-git-info
第三步,执行前最好先clean
ninja -C out/android_debug -t clean
ninja -C out/android_profile -t clean
ninja -C out/android_release -t clean
ninja -C out/android_debug_arm64 -t clean
ninja -C out/android_profile_arm64 -t clean
ninja -C out/android_release_arm64 -t clean
ninja -C out/android_debug_x64 -t clean
ninja -C out/android_profile_x64 -t clean
ninja -C out/android_release_x64 -t clean
ninja -C out/android_debug_x86 -t clean
ninja -C out/android_jit_release_x86 -t clean
第4步,执行具体的构建,这部分非常耗时,平均每个类型占用1.5G到2.3G左右,总共在16个G左右,所以预先留好磁盘空间
ninja -C out/android_debug -j 8
ninja -C out/android_profile -j 8
ninja -C out/android_release -j 8
ninja -C out/android_debug_arm64 -j 8
ninja -C out/android_profile_arm64 -j 8
ninja -C out/android_release_arm64 -j 8
ninja -C out/android_debug_x64 -j 8
ninja -C out/android_profile_x64 -j 8
ninja -C out/android_release_x64 -j 8
ninja -C out/android_debug_x86 -j 8
ninja -C out/android_jit_release_x86 -j 8
构建完后AOT产物截图如下
遗留问题,mac编译x86问题:github.com/flutter/flu…
简单解释下,从xcode10开始就放弃了 i386 toolchain,本机环境没有相关工具,解决方式是用windows或者linux编译,不过对于端上来说,基本上用不到x86了
产物归档和说明 官方文档
我们要收集哪些产物? 从架构模式分类看:
-
arm:arm,arm-profile,arm-release,arm64,arm64-profile,arm64-release(真机上跑必须的) -
x86:android-x86,android-x86-jit-release -
x64:android-x64,android-x64-profile,android-x64-release
其中arm是我们跑真机必须的,Android中armeabi-v7a对应的就是这里的arm,arm64-v8a对应的就是arm64,而debug、profile、release就是flutter编译对应的三种模式。 至于x86和x64主要是模拟器在使用,这个根据自己项目的情况选择
从具体的产物看,主要有以下几种:
- flutter.jar: 这个编译后最终的产物,其中包含引擎java代码的class文件和libflutter.so
- gen_snapshot: 宿主端产物,在mac上跑就要编译mac产物,在Linux上跑就要在Linux上编译产物,官方文档对其解释的是 将 Dart 代码转换为特定于架构的 AOT 指令的二进制文件称为 gen_snapshot,其实就是对应平台的二进制执行文件
- 符号表产物:libflutter.so和libflutter.so.TOC,注意和第一步提到的libflutter.so不一样,这里的libflutter.so是包含符号表的,主要用于还原线上引擎堆栈
收集的AOT产物如下
符号表
AOT产物归一,如果编译机不是mac,那么对应的darwin-x64需要换成linux-x64或者windows-x64
mkdir -p flutter-engine/artifacts/android-arm
mkdir -p flutter-engine/symbols/android-arm
cp flutter_engine/engine_251/src/out/android_debug/flutter.jar flutter-engine/artifacts/android-arm/flutter.jar
cp flutter_engine/engine_251/src/out/android_debug/libflutter.so flutter-engine/symbols/android-arm/libflutter.so
cp flutter_engine/engine_251/src/out/android_debug/libflutter.so.TOC flutter-engine/symbols/android-arm/libflutter.so.TOC
mkdir -p flutter-engine/artifacts/android-arm-profile
mkdir -p flutter-engine/artifacts/android-arm-profile/darwin-x64
mkdir -p flutter-engine/symbols/android-arm-profile
cp flutter_engine/engine_251/src/out/android_profile/flutter.jar flutter-engine/artifacts/android-arm-profile/flutter.jar
cp flutter_engine/engine_251/src/out/android_profile/clang_x64/gen_snapshot flutter-engine/artifacts/android-arm-profile/darwin-x64/gen_snapshot
cp flutter_engine/engine_251/src/out/android_profile/libflutter.so flutter-engine/symbols/android-arm-profile/libflutter.so
cp flutter_engine/engine_251/src/out/android_profile/libflutter.so.TOC flutter-engine/symbols/android-arm-profile/libflutter.so.TOC
mkdir -p flutter-engine/artifacts/android-arm-release
mkdir -p flutter-engine/artifacts/android-arm-release/darwin-x64
mkdir -p flutter-engine/symbols/android-arm-release
cp flutter_engine/engine_251/src/out/android_release/flutter.jar flutter-engine/artifacts/android-arm-release/flutter.jar
cp flutter_engine/engine_251/src/out/android_release/clang_x64/gen_snapshot flutter-engine/artifacts/android-arm-release/darwin-x64/gen_snapshot
cp flutter_engine/engine_251/src/out/android_release/libflutter.so flutter-engine/symbols/android-arm-release/libflutter.so
cp flutter_engine/engine_251/src/out/android_release/libflutter.so.TOC flutter-engine/symbols/android-arm-release/libflutter.so.TOC
mkdir -p flutter-engine/artifacts/android-arm64
mkdir -p flutter-engine/symbols/android-arm64
cp flutter_engine/engine_251/src/out/android_debug_arm64/flutter.jar flutter-engine/artifacts/android-arm64/flutter.jar
cp flutter_engine/engine_251/src/out/android_debug_arm64/libflutter.so flutter-engine/symbols/android-arm64/libflutter.so
cp flutter_engine/engine_251/src/out/android_debug_arm64/libflutter.so.TOC flutter-engine/symbols/android-arm64/libflutter.so.TOC
mkdir -p flutter-engine/artifacts/android-arm64-profile
mkdir -p flutter-engine/artifacts/android-arm64-profile/darwin-x64
mkdir -p flutter-engine/symbols/android-arm64-profile
cp flutter_engine/engine_251/src/out/android_profile_arm64/flutter.jar flutter-engine/artifacts/android-arm64-profile/flutter.jar
cp flutter_engine/engine_251/src/out/android_profile_arm64/clang_x64/gen_snapshot flutter-engine/artifacts/android-arm64-profile/darwin-x64/gen_snapshot
cp flutter_engine/engine_251/src/out/android_profile_arm64/libflutter.so flutter-engine/symbols/android-arm64-profile/libflutter.so
cp lutter_engine/engine_251/src/out/android_profile_arm64/libflutter.so.TOC flutter-engine/symbols/android-arm64-profile/libflutter.so.TOC
mkdir -p flutter-engine/artifacts/android-arm64-release
mkdir -p flutter-engine/artifacts/android-arm64-release/darwin-x64
mkdir -p flutter-engine/symbols/android-arm64-release
cp flutter_engine/engine_251/src/out/android_release_arm64/flutter.jar flutter-engine/artifacts/android-arm64-release/flutter.jar
cp flutter_engine/engine_251/src/out/android_release_arm64/clang_x64/gen_snapshot flutter-engine/artifacts/android-arm64-release/darwin-x64/gen_snapshot
cp flutter_engine/engine_251/src/out/android_release_arm64/libflutter.so flutter-engine/symbols/android-arm64-release/libflutter.so
cp flutter_engine/engine_251/src/out/android_release_arm64/libflutter.so.TOC flutter-engine/symbols/android-arm64-release/libflutter.so.TOC
mkdir -p flutter-engine/artifacts/android-x86
mkdir -p flutter-engine/symbols/android-x86
cp flutter_engine/engine_251/src/out/android_debug_x86/flutter.jar flutter-engine/artifacts/android-x86/flutter.jar
cp flutter_engine/engine_251/src/out/android_debug_x86/lib.stripped/libflutter.so flutter-engine/artifacts/android-x86/libflutter.so
cp flutter_engine/engine_251/src/out/android_debug_x86/libflutter.so flutter-engine/symbols/android-x86/libflutter.so
cp lutter_engine/engine_251/src/out/android_debug_x86/libflutter.so.TOC flutter-engine/symbols/android-x86/libflutter.so.TOC
mkdir -p flutter-engine/artifacts/android-x64
mkdir -p flutter-engine/symbols/android-x64
cp flutter_engine/engine_251/src/out/android_debug_x64/flutter.jar flutter-engine/artifacts/android-x64/flutter.jar
cp flutter_engine/engine_251/src/out/android_debug_x64/lib.stripped/libflutter.so flutter-engine/artifacts/android-x64/libflutter.so
cp flutter_engine/engine_251/src/out/android_debug_x64/libflutter.so flutter-engine/symbols/android-x64/libflutter.so
cp flutter_engine/engine_251/src/out/android_debug_x64/libflutter.so.TOC flutter-engine/symbols/android-x64/libflutter.so.TOC
mkdir -p flutter-engine/artifacts/android-x64-profile
mkdir -p flutter-engine/artifacts/android-x64-profile/darwin-x64
mkdir -p flutter-engine/symbols/android-x64-profile
cp /Users/yulun/flutter_engine/engine_251/src/out/android_profile_x64/flutter.jar flutter-engine/artifacts/android-x64-profile/flutter.jar
cp flutter_engine/engine_251/src/out/android_profile_x64/clang_x64/gen_snapshot flutter-engine/artifacts/android-x64-profile/darwin-x64/gen_snapshot
cp flutter_engine/engine_251/src/out/android_profile_x64/libflutter.so flutter-engine/symbols/android-x64-profile/libflutter.so
cp flutter_engine/engine_251/src/out/android_profile_x64/libflutter.so.TOC flutter-engine/symbols/android-x64-profile/libflutter.so.TOC
mkdir -p flutter-engine/artifacts/android-x64-release
mkdir -p flutter-engine/artifacts/android-x64-release/darwin-x64
mkdir -p flutter-engine/symbols/android-x64-release
cp flutter_engine/engine_251/src/out/android_release_x64/flutter.jar flutter-engine/artifacts/android-x64-release/flutter.jar
cp flutter_engine/engine_251/src/out/android_release_x64/clang_x64/gen_snapshot flutter-engine/artifacts/android-x64-release/darwin-x64/gen_snapshot
cp flutter_engine/engine_251/src/out/android_release_x64/libflutter.so flutter-engine/symbols/android-x64-release/libflutter.so
cp flutter_engine/engine_251/src/out/android_release_x64/libflutter.so.TOC flutter-engine/symbols/android-x64-release/libflutter.so.TOC
如何在正式环境使用自定义引擎的产物
大部分博客说的都是在本地使用debug产物,但如果要集成AOT产物需要改动源码。
真正要集成到环境中的其实就是flutter.jar和gen_snapshot,符号表文件可以单独存放。
在讨论如何集成时,我们要先看flutter是如何载入引擎产物的。 关键源码位置在yourflutterpath/flutter/packages/flutter_tools/gradle/flutter.gralde里 源码传送门
// 远程仓库依赖 flutter.jar
addApiDependencies(project, buildType.name,
"io.flutter:flutter_embedding_$flutterBuildMode:$engineVersion")
// Add the `libflutter.so` dependency. 远程依赖flutter.so
addApiDependencies(project, buildType.name,
"io.flutter:${arch}_$flutterBuildMode:$engineVersion")
// 仓库地址
https://storage.googleapis.com/download.flutter.io
可以看到官方把jar和so是分开的,和我们之前分离的产物还有一点差别,回头再看下引擎生成的产物,发现有个flutter_embedding_{buildType}-sources.jar,这个就是io.flutter:flutter_embedding_flutterBuildMode:$engineVersion的具体产物了。 这块逻辑实在1.12版本修改的,在1.12之前产物都是本地依赖,引擎产物放在yourflutterpath/flutter/bin/cache/artifacts/engine里,具体修改逻辑可以看这个提交git@github.com:flutter/flutter.git@242a4225a1bfc726360e7d0f26325d5ac4d30891
所以,在集成AOT产物的方案上就有了两种思路:
- 修改flutter.gradle源码,使其支持本地依赖,笔者采用的是这种
- 仿照官方,在自己的nexus仓库上新建22个产物,其中flutter.jar需要11个,flutter.so需要11个,当然如果只考虑arm,放弃x86,那12个就够了
首先要确保产物已经覆盖到yourflutterpath/flutter/bin/cache/artifacts/engine,然后我们通过开关判断当前是引用官方的远程产物还是本地产物(如何覆盖产物可以自己通过脚本实现,这里指说明flutter.gradle的修改逻辑),下面贴出关键代码
// 可以通过-p参数注入,判断自定义引擎开关
private boolean isAndroidCustomEngine() {
if (project.hasProperty("enableCustomEngine")) {
return project.property("enableCustomEngine").toBoolean()
}
return true
}
/引入flutter.jar,这里要注意,不仅仅是主工程,plugin工程需要编译依赖
private void apiFlutterJar(Project currentProject, boolean compileOnly) {
String basePlatformArch = getBasePlatform(project)
// This is meant to include the compiled classes only, however it will include `libflutter.so` as well.
Path baseEnginePath = Paths.get(flutterRoot.absolutePath, "bin", "cache", "artifacts", "engine")
File debugJar = baseEnginePath.resolve("${basePlatformArch}").resolve("flutter.jar").toFile()
baseJar["debug"] = debugJar
baseJar["profile"] = baseEnginePath.resolve("${basePlatformArch}-profile").resolve("flutter.jar").toFile()
baseJar["release"] = baseEnginePath.resolve("${basePlatformArch}-release").resolve("flutter.jar").toFile()
// Add flutter.jar dependencies to all <buildType>Api configurations, including custom ones
// added after applying the Flutter plugin.
currentProject.android.buildTypes.each {
def buildMode = buildModeFor(it)
if (compileOnly){
addCompileOnlyDependency(currentProject, it.name, project.files {
baseJar[buildMode]
})
}
else{
addApiDependencies(currentProject, it.name, project.files {
baseJar[buildMode]
})
}
}
currentProject.android.buildTypes.whenObjectAdded {
def buildMode = buildModeFor(it)
if (compileOnly){
addCompileOnlyDependency(currentProject, it.name, project.files {
baseJar[buildMode]
})
}
else{
addApiDependencies(currentProject, it.name, project.files {
baseJar[buildMode]
})
}
}
}
// 依赖libflutter.so,对源码中的packFlutterAppAotTask做点修改
// 增加一项,从flutter.jar中抽离出libflutter.so
libFlutterPlatforms.each { targetArch ->
if (!isAndroidCustomEngine()) {
return
}
// This check prevents including `libflutter.so` twice, since it's included in the base platform jar.
// Unfortunately, the `pickFirst` setting in `packagingOptions` does not work when the project `:flutter`
// is included as an implementation dependency, which causes duplicated `libflutter.so`.
if (getBasePlatform(project) == targetArch) {
return
}
// Don't include `libflutter.so` for other architectures when a local engine is specified.
if (useLocalEngine()) {
return
}
def engineArtifactSubdir = getEngineArtifactDirName(variant.buildType, targetArch);
// Include `libflutter.so`.
// TODO(blasten): The libs should be outside `flutter.jar` when the artifacts are downloaded.
from(project.zipTree("${flutterRoot}/bin/cache/artifacts/engine/${engineArtifactSubdir}/flutter.jar")) {
include 'lib/**'
}
}
addFlutterDependencies也要修改
/**
* Adds the dependencies required by the Flutter project.
* This includes:
* 1. The embedding
* 2. libflutter.so
*/
void addFlutterDependencies(buildType) {
//...省略其他代码
if (!isFlutterAppProject() || getPluginList().size() == 0 || isAndroidCustomEngine()) {
if (isAndroidCustomEngine()) {
// plugin项目需要引用
apiFlutterJar(project,false)
} else {
addApiDependencies(project, buildType.name,
"io.flutter:flutter_embedding_$flutterBuildMode:$engineVersion")
}
}
List<String> platforms = getTargetPlatforms().collect()
// Debug mode includes x86 and x64, which are commonly used in emulators.
if (flutterBuildMode == "debug" && !useLocalEngine()) {
platforms.add("android-x86")
platforms.add("android-x64")
}
// 不是自定义引擎是才引用官方仓库的libflutter.so
if (!isAndroidCustomEngine()) {
platforms.each { platform ->
String arch = PLATFORM_ARCH_MAP[platform].replace("-", "_")
// Add the `libflutter.so` dependency.
addApiDependencies(project, buildType.name,
"io.flutter:${arch}_$flutterBuildMode:$engineVersion")
}
}
}
configurePluginProject方法里的addEmbeddingDependencyToPlugin闭包适配
Closure addEmbeddingDependencyToPlugin = { buildType ->
String flutterBuildMode = buildModeFor(buildType)
// In AGP 3.5, the embedding must be added as an API implementation,
// so java8 features are desugared against the runtime classpath.
// For more, see https://github.com/flutter/flutter/issues/40126
if (!supportsBuildMode(flutterBuildMode)) {
return
}
if (!pluginProject.hasProperty('android')) {
return
}
// Copy build types from the app to the plugin.
// This allows to build apps with plugins and custom build types or flavors.
pluginProject.android.buildTypes {
"${buildType.name}" {}
}
// The embedding is API dependency of the plugin, so the AGP is able to desugar
// default method implementations when the interface is implemented by a plugin.
//
// See https://issuetracker.google.com/139821726, and
// https://github.com/flutter/flutter/issues/72185 for more details.
if (isAndroidCustomEngine()){
// 为每个plugin project添加 flutter.jar依赖
apiFlutterJar(pluginProject,true)
// 每个插件项目添加编译依赖 compileOnlyPluginProject(pluginProject, buildType.name)
}
else{
addApiDependencies(
pluginProject,
buildType.name,
"io.flutter:flutter_embedding_$flutterBuildMode:$engineVersion"
)
}
}
以上这几步参考的是1.9的源码,修改完成后会发现还有坑点。 远程的flutter产物会默认依赖几个Androidx的aar,依赖关系如下
+--- io.flutter:flutter_embedding_debug:1.0.0-b3af521a050e6ef076778bcaf16e27b2521df8f8
| +--- androidx.lifecycle:lifecycle-common:2.2.0
| | \--- androidx.annotation:annotation:1.1.0
| +--- androidx.lifecycle:lifecycle-common-java8:2.2.0
| | +--- androidx.lifecycle:lifecycle-common:2.2.0 (*)
| | \--- androidx.annotation:annotation:1.1.0
| +--- androidx.lifecycle:lifecycle-runtime:2.2.0
| | +--- androidx.lifecycle:lifecycle-common:2.2.0 (*)
| | +--- androidx.arch.core:core-common:2.1.0
| | | \--- androidx.annotation:annotation:1.1.0
| | \--- androidx.annotation:annotation:1.1.0
| +--- androidx.fragment:fragment:1.1.0
| | +--- androidx.annotation:annotation:1.1.0
| | +--- androidx.core:core:1.1.0
| | | +--- androidx.annotation:annotation:1.1.0
| | | +--- androidx.lifecycle:lifecycle-runtime:2.0.0 -> 2.2.0 (*)
| | | +--- androidx.versionedparcelable:versionedparcelable:1.1.0
| | | | \--- androidx.collection:collection:1.0.0 -> 1.1.0
| | | | \--- androidx.annotation:annotation:1.1.0
| | | \--- androidx.collection:collection:1.0.0 -> 1.1.0 (*)
| | +--- androidx.collection:collection:1.1.0 (*)
| | +--- androidx.viewpager:viewpager:1.0.0
| | | +--- androidx.annotation:annotation:1.0.0 -> 1.1.0
| | | +--- androidx.core:core:1.0.0 -> 1.1.0 (*)
| | | \--- androidx.customview:customview:1.0.0
| | | +--- androidx.annotation:annotation:1.0.0 -> 1.1.0
| | | \--- androidx.core:core:1.0.0 -> 1.1.0 (*)
| | +--- androidx.loader:loader:1.0.0
| | | +--- androidx.annotation:annotation:1.0.0 -> 1.1.0
| | | +--- androidx.core:core:1.0.0 -> 1.1.0 (*)
| | | +--- androidx.lifecycle:lifecycle-livedata:2.0.0
| | | | +--- androidx.arch.core:core-runtime:2.0.0
| | | | | +--- androidx.annotation:annotation:1.0.0 -> 1.1.0
| | | | | \--- androidx.arch.core:core-common:2.0.0 -> 2.1.0 (*)
| | | | +--- androidx.lifecycle:lifecycle-livedata-core:2.0.0
| | | | | +--- androidx.lifecycle:lifecycle-common:2.0.0 -> 2.2.0 (*)
| | | | | +--- androidx.arch.core:core-common:2.0.0 -> 2.1.0 (*)
| | | | | \--- androidx.arch.core:core-runtime:2.0.0 (*)
| | | | \--- androidx.arch.core:core-common:2.0.0 -> 2.1.0 (*)
| | | \--- androidx.lifecycle:lifecycle-viewmodel:2.0.0 -> 2.1.0
| | | \--- androidx.annotation:annotation:1.1.0
| | +--- androidx.activity:activity:1.0.0
| | | +--- androidx.annotation:annotation:1.1.0
| | | +--- androidx.core:core:1.1.0 (*)
| | | +--- androidx.lifecycle:lifecycle-runtime:2.1.0 -> 2.2.0 (*)
| | | +--- androidx.lifecycle:lifecycle-viewmodel:2.1.0 (*)
| | | \--- androidx.savedstate:savedstate:1.0.0
| | | +--- androidx.annotation:annotation:1.1.0
| | | +--- androidx.arch.core:core-common:2.0.1 -> 2.1.0 (*)
| | | \--- androidx.lifecycle:lifecycle-common:2.0.0 -> 2.2.0 (*)
| | \--- androidx.lifecycle:lifecycle-viewmodel:2.0.0 -> 2.1.0 (*)
| \--- androidx.annotation:annotation:1.1.0
+--- io.flutter:armeabi_v7a_debug:1.0.0-b3af521a050e6ef076778bcaf16e27b2521df8f8
+--- io.flutter:arm64_v8a_debug:1.0.0-b3af521a050e6ef076778bcaf16e27b2521df8f8
+--- io.flutter:x86_64_debug:1.0.0-b3af521a050e6ef076778bcaf16e27b2521df8f8
\--- io.flutter:x86_debug:1.0.0-b3af521a050e6ef076778bcaf16e27b2521df8f8
主要是远程产物默认带了androidx.annotation:annotation,但自定义AOT产物只有jar,因此在针对pluign-project时要做点改动
// 主要是为每个plugin-project工程添加compileOnly,避免编译失败,这部分代码挫后续要改进
//androidx.annotation:annotation:1.1.0
//只依赖jar的话,plugin-project不会依赖这几个aar,所以在本地依赖引擎产物的时候需要compileOnly这几个aar
private boolean compileOnlyPluginProject(Project pluginProject,String buildTypeName){
if (pluginProject == null){
return
}
List<String> flutterJarAPi = ["androidx.annotation:annotation:1.1.0"]
flutterJarAPi.each { jarAPi->
String[] abi = jarAPi.split(":")
def group = abi[0]
def name = abi[1]
def version = abi[2]
// 只判断implementation, api,compileOnly
pluginProject.configurations {
if (containsDependency("compileOnly",it,name,group)){
return
}else if (containsDependency("implementation",it,name,group)){
return
}else if (containsDependency("api",it,name,group)){
return
}else if (containsDependency("compile",it,name,group)){
return
}
addCompileOnlyDependency(pluginProject, buildTypeName, jarAPi)
}
}
}
private boolean containsDependency(String configuration, ConfigurationContainer configurationContainer, String name, String group) {
DependencySet setImplementation = configurationContainer.getByName(configuration).getAllDependencies()
Dependency dep = setImplementation.find {
it.name == name && it.group == group
}
return dep != null
}
至此,本地依赖自定义引擎产物完成。
依赖AOT产物个人认为后续改成远程方式比较好,尽量向官方的方案靠近,虽然也要修改源代码,但代码的入侵性相比第一种方式是更低的。
其他坑点
Linux 二进制执行文件
本地编译机的是mac,编译出的gen_snapshot只支持mac,所以要在Linux上再编译一次。具体编译过程还是参考官网。这里只是简单说下,Linux需要依赖以下几个工具,curl,unzip,git,python3 ,只要解决国内被墙的问题,过程和mac上基本一样
补充Linux编译过程中碰到的一些问题
depot_tools找不到python3
https://blog.csdn.net/u010164190/article/details/115101194
linux 安装python3
https://blog.csdn.net/zhuzuwei/article/details/105423370
libc.so.6: version `GLIBC_2.18' not found问题
https://www.jianshu.com/p/513e01fbd3e0
ModuleNotFoundError: No module named '_ctypes'的解决方案
https://www.cnblogs.com/fanbi/p/12375023.html