0%

Flutter源码下载和编译

SDK下载和编译

目的:

  1. 学习源码
  2. 定制框架:如修改flutter_tools编译工具等

方法和搭建Flutter开发环境类似

  1. 直接clone或先fork到本地:git clone git@github.com:flutter/flutter.git

  2. 配置环境变量,或者直接进入bin目录执行flutter命令

  3. 安装依赖包:flutter update-packages

  4. 检查环境:flutter doctor

  5. Android Studio打开{flutter_framework}/packages/下的项目,默认会当做Android工程,IDE提示Dart SDK is not configured或者Dart support is not enabled for the module 'flutter_tools',如下

  6. 配置Flutter工程:直接点击上图的Open Dart Settings或者打开Prefereneces>Language>Dart/Flutter。配置Dart SDK和Flutter SDK路径,对照下Flutter应用项目的配置即可。如下

  7. 配置完之后即可在IDE查看和修改源码

  8. 编译源码

    1. 删除{flutter_framework}/bin/cache/flutter_tools.snapshot(Dart快照文件)和{flutter_framework}/bin/cache/flutter_tools.stamp(当前SDK的commit id文件)
    2. 运行flutter命令的时候会自动编译源码,重新生成dart快照文件。

Engine下载和编译

这里只演示了官方支持的平台编译,还不涉及嵌入层的定制和交叉编译(用于定制的嵌入式平台运行Engine)。

主要有几个目的

  1. 学习源码
  2. 定制引擎,使得Flutter能够在其他目标平台运行,例如树莓派,鸿蒙系统等
  3. 通过压缩、裁剪引擎优化包体积

源码下载

官方文档

depot_tools安装:参考depot_tools介绍

  1. clone仓库:git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
  2. 设置环境变量:.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
2
3
4
# commitId使用和当前Flutter SDK对应的版本:cat bin/internal/engine.version,如下图
git reset --hard <commiId>
# 再次同步代码:不同engine版本依赖的项目版本可能不同
gclient sync --with_branch_heads --with_tags --verbose

主机包含多个版本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_unoptios_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.snapshotgen_snapshot,手动进行前端编译和后端编译。

方式二:将引擎编译产物拷贝到Flutter SDK缓存路径下,替换官方默认引擎。

方式三:使用local-engine-src-path--local-engine选项。如下

1
2
# 指定的引擎需要与构建模式对应:debug版的引擎编译debug版的应用
flutter run --local-engine-src-path {path}/engine/src --local-engine={path}/engine/src/out/host_debug_unopt

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++】

  1. 安装cmake:brew install cmake

  2. 安装cquery或者ccls:brew install cquerybrew install ccls

    cquery已经不再维护,推荐clangdccls

    三者都是语言服务器,用于代码语义分析,通过插件与其他编辑器一起工作。可以给编辑器添加智能功能:代码提示和补全、格式化、代码跳转、编译错误提示等

    ccls源自cquery。clangd基于Clang C++编译器,属于LLVM项目

  3. 构建cquery或者构建ccls

  4. 安装VSCode插件,如VSCode-cqueryvscode-ccls,配置插件(参考上面cquery和ccls文档)

  5. 配置Intellisense文件:

    1. 将gn生成的compile_commands.json文件拷贝到要打开的项目根目录,如src/flutter下,打开项目
    2. 或者在c_cpp_properties.json文件中配置compile_commands.json的绝对路径

VSCode【Java】

对于Java项目,VSCode需要配置jar包依赖。

  1. 安装VSCode插件vscjava.vscode-java-packvscjava.vscode-java-dependency
  2. 添加文件夹路径,如shell/platform/android
  3. 打开Java Dependencies资源管理器窗口,或者使用命令打开”Explorer: Focus on Java Dependencies View”
  4. 刷新视图窗口
  5. 配置Referenced Libraries,添加src/third_party/android_embedding_dependencies文件夹。
1
2
3
4
//相当于配置settings.json如下
"java.project.referencedLibraries": [
"{path to engine}/src/third_party/android_embedding_dependencies/lib/**/*.jar"
]

结语

参考资料:

gclient使用可以参考chromium开发工具–gclientgclient 介绍

欢迎关注我的其它发布渠道