SDK下载和编译
目的:
- 学习源码
- 定制框架:如修改flutter_tools编译工具等
方法和搭建Flutter开发环境类似
- 直接clone或先fork到本地: - git clone git@github.com:flutter/flutter.git
- 配置环境变量,或者直接进入bin目录执行flutter命令 
- 安装依赖包: - flutter update-packages
- 检查环境: - flutter doctor
- Android Studio打开 - {flutter_framework}/packages/下的项目,默认会当做Android工程,IDE提示- Dart SDK is not configured或者- Dart support is not enabled for the module 'flutter_tools',如下 
- 配置Flutter工程:直接点击上图的 - Open Dart Settings或者打开- Prefereneces>Language>Dart/Flutter。配置Dart SDK和Flutter SDK路径,对照下Flutter应用项目的配置即可。如下   
- 配置完之后即可在IDE查看和修改源码 
- 编译源码 - 删除{flutter_framework}/bin/cache/flutter_tools.snapshot(Dart快照文件)和{flutter_framework}/bin/cache/flutter_tools.stamp(当前SDK的commit id文件)
- 运行flutter命令的时候会自动编译源码,重新生成dart快照文件。
 
- 删除
Engine下载和编译
这里只演示了官方支持的平台编译,还不涉及嵌入层的定制和交叉编译(用于定制的嵌入式平台运行Engine)。
主要有几个目的
- 学习源码
- 定制引擎,使得Flutter能够在其他目标平台运行,例如树莓派,鸿蒙系统等
- 通过压缩、裁剪引擎优化包体积
源码下载
depot_tools安装:参考depot_tools介绍
- clone仓库:git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
- 设置环境变量:.bash_profile文件中添加export PATH=$PATH:{your_path}/depot_tools/
生成.gclient文件:gclient config git@github.com:flutter/engine.git --unmanaged --name=src/flutter
也可以手动创建文件填写。这里直接使用官方仓库地址,如果要修改提交源码,则需要fork到自己的仓库下载。
下载源码和依赖项目(大概10个G,不要中断下载):gclient sync --verbose
依赖项目如glwf、skia、dart、android sdk等,一般不需要修改,只需要修改flutter engine项目
切换版本:默认获取master分支的版本,建议切换engine版本,与Flutter SDK保持一致,需要进入src/flutter目录执行以下命令
| 1 | commitId使用和当前Flutter SDK对应的版本:cat bin/internal/engine.version,如下图 | 

主机包含多个版本Dart SDK的时候。Dart编译前端、编译后端、以及Dart运行时的版本必须一致,否则会报错版本不匹配。建议切换engine版本,保持Dart SDK版本一致。否则需要进入对应路径下执行命令。
详情参考Dart的编译和执行
源码编译
使用gn生成ninja构建文件(参数参考官方文档):{engine_path}/src/flutter/tools/gn --unoptimized --android --runtime-mode debug --android-cpu arm
这里的gn只是一个shell脚本,内部调用
gn gen命令执行对应的构建产物会有多种组合:
- 平台:iOS, Android, macOS, Linux, Windows
- 构建模式:debug, release, profile
- 是否优化:opt, unopt
- cpu架构:arm、arm64、x86、x64
产物命名格式:
{android/ios/host}_{debug/profile/release}_{unoptimized/optimized}_{cpu架构}除此之外还可以根据图形后端进行编译:如OpenGL、Vulkan、software
构建完之后生成out目录,根据参数生成不同文件夹,如android_debug_unopt、ios_debug_unopt等。
内部包括ninja构建文件、compile_commands.json文件(Intellisense,用于编辑器索引)、xcode项目文件等
进入src目录,使用ninja编译:ninja -C out/android_debug_unopt
编译生成的文件在
out/android_debug_unopt目录下。
- Android引擎编译主要产物是
flutter.jar,其中包含libflutter.soFlutter引擎层代码、flutter_embedding_debug.jar嵌入层代码。- iOS引擎编译主要产物是
Flutter.framework,其中包含Flutter引擎层代码、FlutterEmbedder.framework嵌入层代码和icudtl.dat国际化数据文件。上述产物是Flutter框架本身编译出的目标代码,除此之外,还包括Dart SDK产物,如front_end和gen_snapshot编译工具等
替换Engine
Flutter默认会下载和使用官方构建好的engine,包括各种架构的版本,位于{flutter_sdk}/bin/cache/artifacts/engine下。要替换自己编译出来的引擎,有几种方式:
方式一:直接用引擎编译出来的frontend_server.dart.snapshot和gen_snapshot,手动进行前端编译和后端编译。
方式二:将引擎编译产物拷贝到Flutter SDK缓存路径下,替换官方默认引擎。
方式三:使用local-engine-src-path和--local-engine选项。如下
| 1 | # 指定的引擎需要与构建模式对应:debug版的引擎编译debug版的应用 | 
flutter引擎和sdk在同级目录下或者
-local-engine使用绝对路径,可以省略--local-engine-src-path参数。下面会分析
flutter_tools解析该参数过程
为Web应用构建,使用主机引擎即可:flutter run --local-engine=host_debug_unopt -d chrome
源码阅读
参考官方文档
Clion
将gn生成的compile_commands.json文件复制到src/flutter中,使用Clion打开,indexing之后就可以跟踪和跳转代码
JetBrains系列,需要激活
Xcode【Objective-C++】
Mac电脑上,对于Objective-C++项目,可以直接打开xcode工程文件open out/host_debug_unopt/flutter_engine.xcodeproj
VSCode【C/C++】
- 安装cmake: - brew install cmake
- 安装cquery或者ccls: - brew install cquery,- brew install ccls- 三者都是语言服务器,用于代码语义分析,通过插件与其他编辑器一起工作。可以给编辑器添加智能功能:代码提示和补全、格式化、代码跳转、编译错误提示等 - ccls源自cquery。clangd基于Clang C++编译器,属于LLVM项目 
- 安装VSCode插件,如 - VSCode-cquery或- vscode-ccls,配置插件(参考上面cquery和ccls文档)
- 配置Intellisense文件: - 将gn生成的compile_commands.json文件拷贝到要打开的项目根目录,如src/flutter下,打开项目
- 或者在c_cpp_properties.json文件中配置compile_commands.json的绝对路径
 
- 将gn生成的
VSCode【Java】
对于Java项目,VSCode需要配置jar包依赖。
- 安装VSCode插件vscjava.vscode-java-pack和vscjava.vscode-java-dependency
- 添加文件夹路径,如shell/platform/android
- 打开Java Dependencies资源管理器窗口,或者使用命令打开”Explorer: Focus on Java Dependencies View”
- 刷新视图窗口
- 配置Referenced Libraries,添加src/third_party/android_embedding_dependencies文件夹。
| 1 | //相当于配置settings.json如下 | 
结语
参考资料:
gclient使用可以参考chromium开发工具–gclient、gclient 介绍