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.so
Flutter引擎层代码、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 介绍