文章目录
前言
刚开始学Flutter开发时搭建过,没有记录。现在有需要时又忘了,果然好记性不如烂笔头。
注意,调试环境搭建会占用较大硬盘空间。粗略统计,Flutter引擎项目(包含依赖的第三方库)约20GB,host_debug_unopt
构建编译后约16GB,ios_debug_xxx
构建编译后约5GB。所以如果想搭建成功,至少需要准备41GB的剩余硬盘空间。
开发环境
- macOS: 13.3.1
- Flutter: 3.7.12
- Xcode: 14.3
安装依赖环境
1. python3
后续很多工具依赖python
环境,如果执行python3
命令失败,那么需要先安装python3
。可以通过官网下载安装或brew
命令安装:
brew install python
安装过程可能会遇到这样的问题:
Error: python@3.11: the bottle needs the Apple Command Line Tools to be installed.
You can install them, if desired, with:
xcode-select --install
执行xcode-select --install
命令安装Xcode命令行工具解决。
2. depot_tools
depot_tools
是Chromium的源码管理工具,后续获取源码和构建编译都需要用到。
安装流程:
- 切换到想要存放的路径执行
clone
命令(需要代理)
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
- 配置环境变量
在~/.bashrc
或~/.zshrc
文件中加上:
export PATH=[存放的路径]/depot_tools:$PATH
参考文档:
获取引擎项目
按Flutter的文档应先fork项目,不过那是针对贡献者的流程,如果你只是调试,可以跳过这一流程。
1. 创建engine空目录
切换到想要存放Flutter引擎源码的位置新建engine
目录:
mkdir engine
2. 创建.gclient文件并配置
切换到engine
目录下执行:
touch .gclient
配置.gclient
文件:
solutions = [{
"managed": False,
"name": "src/flutter",
"url": "git@github.com:<your_name_here>/engine.git",
"custom_deps": {},
"deps_file": "DEPS",
"safesync_url": "",
}, ]
<your_name_here>
请按需替换,如果没有fork引擎项目,可以替换为flutter
,如果有fork,可以替换为自己的Github账户名。
如果想了解这些配置的作用,参考官方文档:gclient file。
3. 指定引擎版本
前面的配置获取的是最新的Flutter引擎源码,但是Flutter引擎的调试离不开Flutter框架,如果版本不匹配可能会遇到一些问题,所以最好指定Flutter引擎版本为当前Flutter框架所需要的版本。那么这个版本怎么指定呢?
Flutter引擎版本其实就是commit id
,可以在Flutter SDK目录/bin/internal/engine.version
文件中获得。例如我当前电脑的Flutter版本是3.7.12
,engine.version
文件位于/opt/homebrew/Caskroom/flutter/3.7.12/flutter/bin/internal/
目录,引擎版本是:
1a65d409c7a1438a34d21b60bf30a6fd5db59314
既然Flutter引擎版本是commit id
,那么就可以通过修改前面的配置指定版本。修改后:
solutions = [{
"managed": False,
"name": "src/flutter",
"url": "git@github.com:<your_name_here>/engine.git@1a65d409c7a1438a34d21b60bf30a6fd5db59314",
"custom_deps": {},
"deps_file": "DEPS",
"safesync_url": "",
}, ]
4. 同步引擎源码
在engine
目录下执行(需要代理):
gclient sync
项目有点大,大概需要下载10GB,其中很大一部分是在下载依赖的第三方库,后续编译也相当耗时。
同步成功后,engine
目录下会有一个src
目录,如果在这个路径下执行git log
,会发现commit id
好像有点不对:
commit 8747bce41d0dc6d9dc45c4d1b46d2100bb9ee688 (HEAD)
Author: Jenn Magder <magder@google.com>
Date: Wed Nov 30 14:05:32 2022 -0800
Sort macOS SDK paths to keep order stable between runs (#652)
...
别急,真正的引擎项目在src
目录下的flutter
目录。src
目录中的项目是这个buildroot,用于搭建Flutter引擎的构建环境。
5. 切换引擎版本
如果后续需要切换其他版本,请按以下步骤操作:
- 切换到
engine/src/flutter
目录路径下 - 指定新版本的
commit id
git reset --hard [commit id]
- 同步新版本的引擎源码
gclient sync -D --with_branch_heads --with_tags
参考文档:
搭建调试环境
1. 构建编译
注意,以下所有命令都在engine/src
目录路径下运行。
1.1 生成构建所需文件
1.1.1 主机端
flutter/tools/gn --unoptimized
生成的文件存放于engine/src/out/host_debug_unopt
目录。
1.1.2 iOS端
- 真机调试
flutter/tools/gn --ios --unoptimized
生成的文件存放于engine/src/out/ios_debug_unopt
目录。
- 模拟器调试
flutter/tools/gn --ios --simulator --unoptimized
# 如果是M系列芯片电脑,建议加上--simulator-cpu=arm64参数,用于支持arm64架构的模拟器
flutter/tools/gn --ios --simulator --simulator-cpu=arm64 --unoptimized
生成的文件存放于engine/src/out/ios_debug_sim_unopt
或engine/src/out/ios_debug_sim_unopt_arm64
目录。
如果是M系列芯片电脑,没有加上--simulator-cpu=arm64
参数,后续Xcode模拟器调试可能会遇到没有iOS设备可选择的情况:
解决方法:按这个步骤[Xcode菜单栏] -> [Product] -> [Destination] -> [Destination Architectures] -> [Show Both]操作,显示全部iOS模拟器。
以上只生成了Debug模式相关的文件用于后续调试,如果需要更多模式(Profile/Release等),可以参考文档Flutter’s modes或通过flutter/tools/gn -h
命令了解更多用法。
1.2 完成构建编译
- 真机调试
ninja -C out/ios_debug_unopt && ninja -C out/host_debug_unopt
- 模拟器调试
ninja -C out/ios_debug_sim_unopt && ninja -C out/host_debug_unopt
# 如果前面使用了--simulator-cpu=arm64参数
ninja -C out/ios_debug_sim_unopt_arm64 && ninja -C out/host_debug_unopt
首次构建编译比较耗时,CPU会满载(电脑买来这么久一直没转过的风扇终于了有表现的机会😂)。后面调试过程中,如果修改了源码需要重新执行构建编译命令。如果文件有增删,需要重新执行前面生成构建所需文件的命令。
参考文档:
2. Xcode调试
准备一个用于调试的Flutter项目,以下命令都在该项目目录路径下执行。
2.1 设置本地引擎
官方文档Debugging iOS builds with Xcode是通过flutter build
命令设置:
flutter build ios --local-engine ios_debug_unopt --config-only
这种方式对于模拟器调试不是那么好用,所以我选择flutter run
命令,设置项目本地引擎后还会运行一遍项目,在后续用Xcode调试时还能提前避免一些问题。
flutter run --local-engine=ios_debug_xxx --local-engine-src-path=/xxx/engine/src -d xxx
--local-engine
:设置本地引擎名称,例如真机调试为ios_debug_unopt
,模拟器调试为ios_debug_sim_unopt
或ios_debug_sim_unopt_arm64
--local-engine-src-path
:设置本地引擎源路径,engine/src
目录所在的绝对路径-d
:指定要运行的设备名称,例如模拟器iPhone\ 8
(名称有空格时需要转义或加单/双引号)
如果Flutter项目的入口文件路径不是默认的,需要追加-t xxx
参数;如果有使用多环境配置,那可能需要追加--flavor xxx
参数。
设置成功后,Flutter项目下的ios/Flutter/Generated.xcconfig
文件会增加以下设置:
FLUTTER_ENGINE=/xxx/engine/src
LOCAL_ENGINE=ios_debug_xxx
2.2 导入引擎项目
- 检查Xcode项目是否存在工作空间
如果用于调试的Flutter项目不存在ios/Runner.xcworkspace
文件,可以先随意依赖一个Flutter插件库,然后执行前面的flutter run ...
命令快速创建工作空间。注意,不能用Android Studio直接运行Flutter项目,否则项目本地引擎设置会被重置。
- 导入引擎项目到工作空间(任选一种方式)
- 简单拖拽
用Xcode打开用于调试的Flutter项目(打开ios/Runner.xcworkspace
文件),将ios_debug_xxx
目录下的flutter_engine.xcodeproj
文件拖到Xcode的左侧项目导航区:
- 修改配置
选中ios/Runner.xcworkspace
文件,右键显示包内容即可找到contents.xcworkspacedata
配置文件。打开后增加一条FileRef
配置:
<?xml version="1.0" encoding="UTF-8"?>
<Workspace version = "1.0">
...
<FileRef
location = "group:/xxx/engine/src/out/ios_debug_xxx/flutter_engine.xcodeproj">
</FileRef>
</Workspace>
以上两种方式本质是一样的。到此,准备工作都做完了,可以开始调试啦🎉!
2.3 测试调试功能
先找个地方打断点,从AppDelegate.swift
文件的FlutterAppDelegate
可以来到引擎项目,在这打断点肯定会进到调试:
使用Xcode运行项目一切正常,成功进入调试:
如果调试过程中发现变量列表显示不全,可以将左下角的筛选项Auto
改为All
:
最后
如果这篇文章对你有所帮助,请不要吝啬你的点赞👍加星🌟,谢谢~