Flutter engine编译&调试

概念

Flutter Engine使用GN和Ninja进行编译,GN编译后生成Ninja的构建文件,Ninja将输入文件编译成最终产物。

  • depot_tools:一个工具包,包含gclient,gn和ninja等工具
  • ninja:是google推出的注重速度的构建工具,将编译任务并行组织,大大提高构建速度
  • gclient:代码获取工具,是google推出的用于管理多源项目所编写的脚本,可以将多个源码管理系统中的代码放在一起管理。甚至包括将git和svn代码放在一起管理。
  • .gclient文件是gclient的控制文件,是一个pythone脚本,格式如下:
solutions = [
{ 
//checkout出源码的名字
"name"        : "src",
//源码所在的目录
"url"         : "svn://svnserver/component/trunk/src",
//这是一个文件名(不包括路径),指在工程目录中包含依赖列表的文件,该项为可选,默认值为"DEPS"
"deps_file" :"DEPS"
//这是一个可选的字典对象,会覆盖工程的"DEPS"文件定义的条目
"custom_deps" : {
# To use the trunk of a component instead of what's in DEPS:
#"component": "https://svnserver/component/trunk/",
# To exclude a component from your working copy:
#"data/really_large_component": None,
  }
 },
]

工具准备

  • git
  • ssh
  • curl , unzip (gclient sync需要)
  • xcode
  • python --version 2.7版本
  • depot_tools
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH=$PATH:/path/to/depot_tools

工程准备

solutions = [
  {
    "managed": False,
    "name": "src/flutter",
    "url": "git@github.com:<your_name_here>/engine.git",
    "custom_deps": {},
    "deps_file": "DEPS",
    "safesync_url": "",
  },
]
  • engine目录下 gclient sync 获取Flutter依赖的所有源代码
  • 进入src/flutter目录
cd src/flutter
git remote add upstream git@github.com:flutter/engine.git
//关联到`flutter/engine`以获取master更新
git pull upstream master

版本匹配

  • 找到当前flutter对应的engine版本
cat /Users/heq/flutter/bin/internal/engine.version

我这里显示的是b863200c37df4ed378042de11c4e9ff34e4e58c9

  • 进入engine/src/flutter目录,将这里的flutter版本跟上一步的版本保持一致
git reset --hard b863200

当前环境查看

heq-Mac:flutter heq$ git rev-parse HEAD
b863200c37df4ed378042de11c4e9ff34e4e58c9
heq-Mac:flutter heq$ flutter --version
Flutter 1.9.1+hotfix.2 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 2d2a1ffec9 (3 months ago) • 2019-09-06 18:39:49 -0700
Engine • revision b863200c37
Tools • Dart 2.5.0
  • 拉取数据

Checkout all the submodules at their branch DEPS revisions.

gclient sync --with_branch_heads --with_tags

编译构建

切换到engine/src目录

usage: gn [-h] [--unoptimized] [--runtime-mode {debug,profile,release}]
          [--dynamic] [--interpreter] [--dart-debug]
          [--target-os {android,ios,linux}] [--android]
          [--android-cpu {arm,x64,x86,arm64}] [--ios] [--ios-cpu {arm,arm64}]
          [--simulator] [--linux-cpu {x64,x86,arm64,arm}]
          [--arm-float-abi {hard,soft,softfp}] [--goma] [--no-goma] [--lto]
          [--no-lto] [--clang] [--no-clang] [--target-sysroot TARGET_SYSROOT]
          [--target-toolchain TARGET_TOOLCHAIN]
          [--target-triple TARGET_TRIPLE]
          [--toolchain-prefix TOOLCHAIN_PREFIX]
          [--operator-new-alignment OPERATOR_NEW_ALIGNMENT] [--enable-vulkan]
          [--embedder-for-target] [--coverage] [--out-dir OUT_DIR]

通过GN进行的预编译生成Ninja的构建文件,除了预编译指定平台的构建文件之外,还需要预编译Host的构建文件(即PC编译平台的),当通过Ninja进行最终产物的编译时,会用到指定平台的构建文件和Host的构建文件进行编译

# unopt-debug
# prepare build files for device-side executables.
./flutter/tools/gn --unoptimized --android --runtime-mode debug --android-cpu arm
./flutter/tools/gn --unoptimized --android --runtime-mode debug --android-cpu arm64
./flutter/tools/gn --unoptimized --android --runtime-mode debug --android-cpu x64
# prepare the build files for host-side executables.
./flutter/tools/gn --unoptimized --runtime-mode debug --android-cpu arm 
./flutter/tools/gn --unoptimized --runtime-mode debug --android-cpu arm64
./flutter/tools/gn --unoptimized --runtime-mode debug --android-cpu x64
ninja -C out/android_debug_unopt
ninja -C out/android_debug_unopt_arm64
ninja -C out/android_debug_unopt_x64
ninja -C out/host_debug_unopt
ninja -C out/host_debug_unopt_arm64
ninja -C out/host_debug_unopt_x64

# unopt-profile
./flutter/tools/gn --unoptimized --android --runtime-mode profile --android-cpu arm
./flutter/tools/gn --unoptimized --android --runtime-mode profile --android-cpu arm64
./flutter/tools/gn --unoptimized --android --runtime-mode profile --android-cpu x64
./flutter/tools/gn --unoptimized --runtime-mode profile --android-cpu arm
./flutter/tools/gn --unoptimized --runtime-mode profile --android-cpu arm64
./flutter/tools/gn --unoptimized --runtime-mode profile --android-cpu x64
ninja -C out/android_profile_unopt
ninja -C out/android_profile_unopt_arm64
ninja -C out/android_profile_unopt_x64
ninja -C out/host_profile_unopt
ninja -C out/host_profile_unopt_arm64
ninja -C out/host_profile_unopt_x64

# unopt-release
./flutter/tools/gn --unoptimized --android --runtime-mode release --android-cpu arm
./flutter/tools/gn --unoptimized --android --runtime-mode release --android-cpu arm64
./flutter/tools/gn --unoptimized --android --runtime-mode release --android-cpu x64
./flutter/tools/gn --unoptimized --runtime-mode release --android-cpu arm
./flutter/tools/gn --unoptimized --runtime-mode release --android-cpu arm64
./flutter/tools/gn --unoptimized --runtime-mode release --android-cpu x64
ninja -C out/android_release_unopt
ninja -C out/android_release_unopt_arm64
ninja -C out/android_release_unopt_x64
ninja -C out/host_release_unopt
ninja -C out/host_release_unopt_arm64
ninja -C out/host_release_unopt_x64

# opt-debug
./flutter/tools/gn --android --runtime-mode debug --android-cpu arm
./flutter/tools/gn --android --runtime-mode debug --android-cpu arm64
./flutter/tools/gn --android --runtime-mode debug --android-cpu x64
./flutter/tools/gn --runtime-mode debug --android-cpu arm
./flutter/tools/gn --runtime-mode debug --android-cpu arm64
./flutter/tools/gn --runtime-mode debug --android-cpu x64
ninja -C out/android_debug
ninja -C out/android_debug_arm64
ninja -C out/android_debug_x64
ninja -C out/host_debug
ninja -C out/host_debug_arm64
ninja -C out/host_debug_x64

# opt-profile
./flutter/tools/gn --android --runtime-mode profile --android-cpu arm
./flutter/tools/gn --android --runtime-mode profile --android-cpu arm64
./flutter/tools/gn --android --runtime-mode profile --android-cpu x64
./flutter/tools/gn --runtime-mode profile --android-cpu arm
./flutter/tools/gn --runtime-mode profile --android-cpu arm64
./flutter/tools/gn --runtime-mode profile --android-cpu x64
ninja -C out/android_profile
ninja -C out/android_profile_arm64
ninja -C out/android_profile_x64
ninja -C out/host_profile
ninja -C out/host_profile_arm64
ninja -C out/host_profile_x64

# opt-release
./flutter/tools/gn --android --runtime-mode release --android-cpu arm
./flutter/tools/gn --android --runtime-mode release --android-cpu arm64
./flutter/tools/gn --android --runtime-mode release --android-cpu x64
./flutter/tools/gn --runtime-mode release --android-cpu arm
./flutter/tools/gn --runtime-mode release --android-cpu arm64
./flutter/tools/gn --runtime-mode release --android-cpu x64
ninja -C out/android_release
ninja -C out/android_release_arm64
ninja -C out/android_release_x64
ninja -C out/host_release
ninja -C out/host_release_arm64
ninja -C out/host_release_x64

Tips: ninja 可使用&&,如:ninja -C out/android_release && ninja -C out/host_release

gn操作后目录结构:

image.png

nginx操作后内容:
image.png

This builds a debug-enabled ("unoptimized") binary configured to run Dart in checked mode ("debug"). There are other versions, see Flutter's modes.

官方wiki上给出的例子

set -ex

cd ~/dev/engine/src/flutter
git fetch upstream
git rebase upstream/master
gclient sync
cd ..

flutter/tools/gn --unoptimized --runtime-mode=debug
flutter/tools/gn --android --unoptimized --runtime-mode=debug
flutter/tools/gn --android --runtime-mode=profile
flutter/tools/gn --android --runtime-mode=release

cd out
find . -mindepth 1 -maxdepth 1 -type d | xargs -n 1 sh -c 'ninja -C $0 || exit 255'
heq-Mac:out heq$ find . -mindepth 1 -maxdepth 1 -type d
./host_debug_unopt
./android_profile
./android_debug_unopt
./android_release

find命令: -type d 表示目录
xargs命令:可以将管道或标准输入(stdin)数据转换成命令行参数,也能够从文件的输出中读取数据。-n num 后面加次数,表示命令在执行的时候一次用的argument的个数,默认是用所有的。

使用方式

  1. flutter run --local-engine-src-path /Users/heq/engine/src --local-engine=android_debug_unopt
  2. 替换掉flutter目录中的engine /Users/heq/flutter/bin/cache/artifacts/engine

使用校验

  • 修改/Users/heq/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterActivity.java部分代码:
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        System.out.println("FlutterActivity.onCreate in Engine!!");
        super.onCreate(savedInstanceState);
        eventDelegate.onCreate(savedInstanceState);
    }
  • 编译engine
  • 新建工程,然后使用flutter run --local-engine-src-path /Users/heq/engine/src --local-engine=android_debug_unopt 运行,每次启动FlutterActivity,logcat打印
com.example.t_flutter_app I/System.out: FlutterActivity.onCreate in Engine!!

证明engine中的修改生效了

调试engine中的Android代码

  • 导入engine/src/flutter/shell/platform/android作为新的工程
  • 确认Engine SDK Version和Java Version File > Project Structure > Project Settings > Project
    image.png
  • 可选:代码关联 File > Project Structure > Modules 消除Missing import错误提示。主要是关联engine/src/third_party/android_support
    image.png
  • 在engine android工程中所需位置设上断点


    image.png
  • 使用flutter run --local-engine-src-path /Users/heq/engine/src --local-engine=android_debug_unopt 运行项目工程
  • 在engine android工程中attach debugger对应的项目工程,即可断点成功


    image.png

    image.png

参考:手把手教你编译Flutter engine
Compiling the engine
Flutter Engine与SDK的定制化与编译
Contributing to the Flutter engine
Debugging the engine

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容