ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Flutter Engine 编译指南:从 GN 配置到多平台构建的完整实战手册

Flutter Engine 编译指南:从 GN 配置到多平台构建的完整实战手册 跨平台图形学前端【免费下载链接】engineThe Flutter engine项目地址https://gitcode.com/gh_mirrors/eng/engine点击查看免费下载导读本文是 Flutter 引擎The Flutter engine官方编译指南的中文深度解读围绕 docs/contributing/Compiling-the-engine.md 的核心流程逐平台拆解 Android、iOS、macOS/Linux、Windows、Fuchsia 与 Web 的完整构建命令并结合仓库中 tools/gn 的源码实现解释输出目录命名规则、--unoptimized与 LTO 的关系、预编译 Dart SDK 的选择逻辑等底层原理。阅读完本文你将掌握如何从零配置引擎开发环境、如何为每个目标平台生成 GN 构建文件并用 ninja 完成编译、如何选择 debug/profile/release 与 opt/unopt 组合、如何运行 Dart 与 Web 引擎测试以及如何排查常见的版本求解失败等编译错误。如果你还没有搭建过引擎开发环境请先阅读 Setting up the Engine development environment本文默认你已经完成了fetch flutter与gclient sync工作目录为引擎源码仓库的src目录。目录通用编译建议使用自定义 Dart SDK为 Android 编译macOS 或 Linux 主机为 iOS 编译macOS 主机为 macOS 或 Linux 编译为 Windows 编译为 Fuchsia 编译为 Web 编译为测试编译编译错误排查通用编译建议优先使用--unopt构建进行本地开发对于本地开发与调试引擎官方建议使用--unoptimized简写--unopt构建。这类构建会额外启用日志与断言检查debug 模式的特性使用更快的编译与链接参数保留更好的调试符号macOS 上输出的二进制不剥离符号Linux 上未剥离的二进制输出到构建目录下的exe.unstripped子目录。但需要注意如果要做性能测试不要使用--unopt此时应使用默认的优化构建。从 tools/gn 的源码可以看到--unoptimized与 debug 模式的直接对应关系在to_gn_args()中gn_args[is_debug] args.unoptimizedtools/gn而--runtime-mode的默认值就是debugtools/gn。也就是说--unoptimized会把整个构建切到 debug 语义Dart 以 checked 模式运行全部断言生效。Link Time OptimizationLTO优化构建会对所有二进制执行链接期优化LTO这会让链接器花费大量时间与内存。如果确实需要优化二进制但不想做 LTO请在gn命令后追加--no-lto标志。源码实现上enable_lto args.lto默认开启--lto默认值为True见 tools/gn但当--unoptimized时会被强制关闭——在 unoptimized 构建中启用 LTO 没有意义tools/gn。此外 Windows 工具链下该 GN 参数不可用因此非 Windows 平台才会写入gn_args[enable_lto]。host 构建与目标构建的配对关系Android 与 iOS 构建同时需要host与android或ios两套构建产物。在升级 Dart SDK 后例如合并到 HEAD 后执行gclient sync必须重编 host 构建因为 host 构建产生的工件必须与 Android/iOS 构建的工件版本严格匹配。Web、Desktop 与 Fuchsia 构建只有单一构建目标即host或fuchsia。备份脚本中务必排除out目录因为其中会生成大量大型二进制工件engine/src/flutter目录之外的所有目录也建议排除。关于输出目录的命名可以结合 tools/gn_test.py 中的单元测试来理解get_out_dir()会按target_os、runtime_mode、simulator、unoptimized、CPU 等参数拼接目录名。例如--runtime-mode debug得到out/host_debug--android --runtime-mode release得到out/android_releasetools/gn_test.py。目录名的组合规则是out/target_runtime_mode[_sim][_unopt][_cpu]。使用自定义 Dart SDK在构建 host 与桌面目标时CI 默认使用 Dart 团队提供的预编译 Dart SDK。如果你修改了gclient sync下载的 Dart 源码并希望从源码构建使用 SDK请在gn命令中追加--no-prebuilt-dart-sdk标志./flutter/tools/gn --no-prebuilt-dart-sdk源码层面该标志对应--prebuilt-dart-sdk参数默认True见 tools/gn。can_use_prebuilt_dart()会判断目标平台是否已有对应的预编译 SDKhost 构建或目标是 android/ios/fuchsia 时会按当前主机系统选择windows-x64、macos-x64或linux-x64的预编译 SDKtools/gn找到时设置gn_args[flutter_prebuilt_dart_sdk] True找不到时会提示手动运行flutter/tools/download_dart_sdk.py或改用--no-prebuilt-dart-sdk从源码编译tools/gn。另外注意当目标是 host 构建且不使用预编译 Dart SDK 时gn会设置dart_platform_sdk not args.full_dart_sdk即默认排除 dart2js、dartdevc、Web SDK kernel 等 Web 相关文件只有通过--full-dart-sdk才包含这些tools/gn。这正是后续 Web 引擎构建中使用--full-dart-sdk的原因之一。为 Android 编译macOS 或 Linux 主机以下步骤构建flutter run在 Android 设备上使用的引擎。请在环境搭建阶段创建的src目录下执行参见 Setting up the Engine development environment在src/flutter中执行git pull upstream main更新 Flutter Engine 仓库。执行gclient sync更新依赖。生成构建文件./flutter/tools/gn --android --unoptimized设备端可执行文件32 位 arm。./flutter/tools/gn --android --android-cpu arm64 --unoptimized新版 64 位 Android 设备。./flutter/tools/gn --android --android-cpu x86 --unoptimizedx86 模拟器。./flutter/tools/gn --android --android-cpu x64 --unoptimizedx64 模拟器。./flutter/tools/gn --unoptimizedhost 端可执行文件编译代码所需。在 Apple SiliconM 芯片上追加--mac-cpu arm64以避免模拟执行这会生成host_debug_unopt_arm64。提示在 ARM 架构 MacM 系列 CPU上开发时优先使用host_debug_unopt_arm64。Intel Mac 仍可使用host_debug_unopt但引擎会在 Rosetta 下运行速度可能更慢。构建可执行文件ninja -C out/android_debug_unopt设备端可执行文件。ninja -C out/android_debug_unopt_arm64新版 64 位 Android 设备。ninja -C out/android_debug_unopt_x86x86 模拟器。ninja -C out/android_debug_unopt_x64x64 模拟器。ninja -C out/host_debug_unopt或ninja -C out/host_debug_unopt_arm64见上host 端可执行文件。命令可以组合例如ninja -C out/android_debug_unopt ninja -C out/host_debug_unopt。macOS 上编译android_debug_unopt与android_debug_unopt_x86需要较旧版本的 Xcode9.4 或以下如果只关注 x64 可以忽略此条。注意--android-cpu的默认值是armtools/gn这解释了为什么--android --unoptimized会生成out/android_debug_unopt而不是带 CPU 后缀的目录——只有当 CPU 不是默认值时目录名才会追加 CPU 标识tools/gn。此外Android 的 64 位目标x64/arm64会自动启用 Dart 压缩指针dart_use_compressed_pointers见 tools/gn而--android --unoptimized --android-cpu arm64会自动开启 Vulkan 校验层tools/gn。构建模式说明以上构建产出一个 debug 使能unoptimized的二进制配置 Dart 以 checked 模式debug运行。引擎还有其他模式详见 Flutters modesdebug / profile / release 三个运行时模式 × opt / unopt 两个优化维度其中--runtime-mode的合法取值为debug、profile、release、jit_release默认debugtools/gn。调试与使用本地引擎如果要在 Flutter 应用中调试引擎崩溃请在被测 Flutter 应用的android/AndroidManifest.xml中给application元素加上android:debuggabletrue。flutter工具使用本地引擎的方法参见 flutter 官方文档The flutter tool。通常用android_debug_unopt构建在真机上调试引擎用android_debug_unopt_x64在模拟器上调试。修改引擎中的 Dart 源码时需要在应用的pubspec.yaml中添加dependency_override一节来指向本地引擎。构建配对规则与 x86 的特别说明使用某个 Android/iOS 引擎构建时旁边必须有对应的 host 构建android_debug_unopt需要host_debug_unoptandroid_profile需要host_profile依此类推。一个特例是 CPU 风味的构建例如android_debug_unopt_x86无法构建host_debug_unopt_x86该配置不受支持。正确做法是构建host_debug_unopt然后把host_debug_unopt_x86符号链接到它。在 Linux 上编译所有关键目标的脚本以下脚本适用于在 Linux 上开发、并在 Android 上测试、且.gclient文件创建在~/dev/engine的场景它会更新所有关键构建set -ex cd ~/dev/engine/src/flutter git fetch upstream git rebase upstream/main gclient sync cd .. flutter/tools/gn --unoptimized --runtime-modedebug flutter/tools/gn --android --unoptimized --runtime-modedebug flutter/tools/gn --android --runtime-modeprofile flutter/tools/gn --android --runtime-moderelease cd out find . -mindepth 1 -maxdepth 1 -type d | xargs -n 1 sh -c ninja -C $0 || exit 255对于--runtime-modeprofile构建建议在gn命令中追加--no-lto链接速度会大幅提升代价是二进制体积与内存占用略有增加对调试与性能基准测试场景通常无影响。为 iOS 编译macOS 主机以下步骤构建flutter run在 iOS 设备上使用的引擎。请在src目录下执行在src/flutter中执行git pull upstream main更新 Flutter Engine 仓库。执行gclient sync更新依赖。./flutter/tools/gn --ios --unoptimized生成设备端可执行文件的构建文件模拟器则用--ios --simulator --unoptimized。该命令同时会在out/ios_debug_unopt/flutter_engine.xcodeproj生成一个用于在引擎源码上工作的 Xcode 工程。关于各种标志与模式的讨论参见 Flutters modes。追加--simulator-cpuarm64参数可在 arm64 Mac 模拟器上构建输出到out/ios_debug_sim_unopt_arm64。./flutter/tools/gn --unoptimized生成 host 端可执行文件的构建文件。在 Apple SiliconM 芯片上追加--mac-cpu arm64以避免模拟执行这会生成host_debug_unopt_arm64。ninja -C out/ios_debug_unopt ninja -C out/host_debug_unopt构建全部工件模拟器使用out/ios_debug_sim_unopt。关于使用flutter工具加载本地引擎的说明与 Android 一节相同真机调试用ios_debug_unopt模拟器调试用ios_debug_sim_unopt修改引擎 Dart 源码需要为应用配置dependency_override。补充从 tools/gn 的源码可见iOS 构建默认关闭 GL、启用 Metalshell_enable_gl False、skia_use_gl False、shell_enable_metal True、skia_use_metal True见 tools/gn并且--simulator仅对 iOS 有效tools/gn。在 Xcode 中调试引擎的进一步说明见 Debugging the engine 中的 Debugging iOS builds with Xcode 一节。为 macOS 或 Linux 编译以下步骤构建桌面嵌入层desktop embedding以及flutter test在 host 工作站上使用的引擎在src/flutter中执行git pull upstream main更新 Flutter Engine 仓库。执行gclient sync更新依赖。./flutter/tools/gn --unoptimized生成构建文件。--unoptimized关闭 C 编译器优化macOS 上二进制以未剥离符号形式输出Linux 上未剥离的二进制输出到构建目录下的exe.unstripped子目录。ninja -C out/host_debug_unopt构建桌面 unoptimized 二进制。如果跳过了--unoptimized则改用ninja -C out/host_debug。桌面嵌入层可能引入比引擎库更多的依赖例如 Linux 上在生成阶段就会引入 pkg-config 依赖因此gn提供了--disable-desktop-embeddings标志用于在特定构建环境中把这些目标排除在构建树之外tools/gn。为 Windows 编译警告Windows 上只能构建选定的二进制主要是gen_snapshot与桌面嵌入层。在 Windows 上请确保引擎 checkout 的目录层级不要太深以避免构建脚本遇到过长的路径。安装 Visual Studio非 Google 员工需要与 Debugging Tools for Windows 10。在src/flutter中执行git pull upstream main更新 Flutter Engine 仓库。启用系统长路径支持以管理员身份启动 PowerShell 并运行Set-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem -Name LongPathsEnabled -Value 1 -Force非 Google 员工必须设置以下环境变量让 depot tools 指向 Visual StudioDEPOT_TOOLS_WIN_TOOLCHAIN0 GYP_MSVS_OVERRIDE_PATHC:\Program Files (x86)\Microsoft Visual Studio\2019\Community # 或你的 Visual Studio 安装位置 WINDOWSSDKDIRC:\Program Files (x86)\Windows Kits\10 # 或你的 Windows Kits 位置同时确保 Python27 在Path中排在所有其他 Python 之前。执行gclient sync更新依赖。切换到src/目录。python .\flutter\tools\gn --unoptimized生成构建文件。如果只构建gen_snapshotpython .\flutter\tools\gn [--unoptimized] --runtime-mode[debug|profile|release] [--android]。ninja -C .\out\上一步生成的目录开始构建。如果使用了非 debug 配置使用ninja -C .\out\目录 gen_snapshot。桌面 shell 暂不支持 release 与 profile 模式。从源码看Windows 是唯一无法在 Android 交叉编译 32 位 arm 的平台tools/gn会将current_cpu硬编码为主机架构、host_cpu设为 x86以避免 GN 去寻找不存在的 Windows arm 工具链tools/gn。另外Windows 上--unoptimized不会写入enable_ltoWindows 工具链无此 GN 参数见 tools/gn。为 Fuchsia 编译Fuchsia 构建只在 Linux 上受支持。构建 Fuchsia 组件修改engine/.gclient如果当前目录是engine/src则是../.gclient添加custom_varssolutions [ { # ... custom_vars: { download_fuchsia_deps: True, run_fuchsia_emu: True, }, }, ]如果不在本地运行测试可以忽略run_fuchsia_emu: True。然后运行gclient sync。警告本地运行测试时还需要启用 kvm或在 gcloud 虚拟机上启用嵌套虚拟化。Fuchsia 及其测试都会在 qemu 上执行。生成并构建./flutter/tools/gn --fuchsia --no-lto这会创建out/fuchsia_debug_x64。使用--fuchsia-cpu arm64为 arm64 构建组件输出到out/fuchsia_debug_arm64。与其他平台一样使用--runtime-moderelease或--runtime-modeprofile选择其他配置。去掉--no-lto则启用 LTO。ninja -C out/fuchsia_debug_x64 -k 0该命令构建全部目标但忽略已知错误。或者指定以下目标避免使用-k 0flutter/shell/platform/fuchsia:fuchsia \ flutter/shell/platform/fuchsia/dart_runner:dart_runner_tests \ fuchsia_tests如果autoninja可用优先使用它。release 构建使用-C out/fuchsia_release_x64其他配置类似只是out/下的目录名不同。本地运行全部测试python3 flutter/tools/fuchsia/with_envs.py flutter/testing/fuchsia/run_tests.py默认在out/fuchsia_debug_x64中运行测试。根据配置不同常规 gtest 输出到终端大约需要 5 分钟。在命令末尾追加fuchsia_release_x64进行 release 构建的测试其他配置类似python3 flutter/tools/fuchsia/with_envs.py flutter/testing/fuchsia/run_tests.py fuchsia_release_x64为 Web 编译Web 引擎的构建使用felt工具Flutter Engine Local Tester其完整说明见 lib/web_ui/README.md。felt位于lib/web_ui/dev目录下Windows 上为felt_windows.bat将其加入PATH即可随处调用。要使用本地构建的 Web 引擎测试 Flutter 应用在flutter命令中追加--local-web-sdkwasm_release例如flutter run --local-web-sdkwasm_release -d chrome flutter test --local-web-sdkwasm_release test/path/to/your_test.dart在 Windows 上为 Web 编译Windows 上编译 Web 引擎需要额外的几个步骤。请使用 cmd.exe 并以管理员身份运行。安装 Visual Studio并设置以下环境变量Visual Studio 使用你实际安装版本的路径GYP_MSVS_OVERRIDE_PATH C:\Program Files (x86)\Microsoft Visual Studio\2019\CommunityGYP_MSVS_VERSION 2017确保 depot_tools、ninja 和 python 已安装并加入Path同时为 depot tools 设置DEPOT_TOOLS_WIN_TOOLCHAIN 0提示如果遇到 python 报错尝试使用 Python 2 而非 Python 3。在src/flutter中执行git pull upstream main更新 Flutter Engine 仓库。执行gclient sync更新依赖。提示如果此步骤遇到 git 认证错误尝试改用 Git Bash。python .\flutter\tools\gn --unoptimized --full-dart-sdk生成构建文件。ninja -C .\out\上一步生成的目录开始构建。使用本地 Web 引擎测试 Flutter 应用的方法同上--local-web-sdkwasm_release。测试引擎则再次使用felt这次用felt_windows.batfelt_windows.bat test说明Web 引擎的构建还依赖 Emscripten SDK 工具链需要在.gclient的custom_vars中添加download_emsdk: True并在gclient sync时拉取lib/web_ui/README.md。Web 构建走的是to_gn_wasm_args()分支输出目录为out/wasm_*target_os与target_cpu均为wasmtools/gn。为测试编译Dart 测试先构建引擎flutter/tools/gn --unoptimized ninja -C out/host_debug_unopt/然后执行run_tests运行 native 测试python3 flutter/testing/run_tests.py --type dartWeb 端使用feltcd flutter/lib/web_ui dev/felt test [test file]felt test支持丰富的过滤与执行参数--compile/--run/--copy-artifacts控制测试流水线的动作--browser chrome|firefox|safari|edge、--compiler dart2js|dart2wasm、--renderer html|canvakit|skwasm、--suite、--bundle等过滤器可以精确圈定测试范围lib/web_ui/README.md。例如只跑 dart2wasm 编译的测试套件felt test --compiler dart2wasm。单元测试与--enable-unittests如果需要构建引擎的 C 单元测试二进制可以在 host 构建中追加--enable-unitteststools/gn。但请注意约束--enable-unittests不能与--android或--ios组合使用tools/gn如果你想创建一个用于 clangdVSCode 集成的输出目录请改用 host 构建而不是 Android/iOS 构建。编译错误排查Version Solving Failed版本求解失败随着 Dart 版本不断升级你偶尔会遇到如下依赖错误The current Dart SDK version is 2.7.0-dev.0.0.flutter-1ef444139c. Because ui depends on a pub package 1.0.0 which requires SDK version 2.7.0 3.0.0, version solving failed.gclient sync默认不会更新 git tags因此有两种解决办法在engine/src/third_party/dart下运行git fetch --tags origin或者带 tags 参数运行gclient sync --with_tags。延伸阅读环境搭建的完整步骤依赖清单、fetch flutter、remote 配置Setting up the Engine development environmentdebug / profile / release 模式的定义、工件差异与 84 种模式矩阵Flutters modes用本地引擎运行 Flutter 应用、在 Xcode 中调试 iOS 构建Debugging the enginegn工具的完整参数表与底层实现tools/gn输出目录命名规则的单元测试tools/gn_test.pyWeb 引擎的felt构建与测试工具lib/web_ui/README.mdCI 中各平台的引擎构建配置示例ci/builders/linux_host_engine.json、ci/builders/mac_ios_engine.json赞分享跨平台图形学前端【免费下载链接】engineThe Flutter engine项目地址https://gitcode.com/gh_mirrors/eng/engine点击查看免费下载相关推荐Skia 构建指南从 GN 参数配置到多平台交叉编译实战Skia 构建指南从 GN 参数配置到多平台交叉编译实战 本文以 site/docs/user/build.md https://link.gitcode.c图形学图像处理Skia 构建完全指南从 GN 参数到多平台交叉编译Skia 构建完全指南从 GN 参数到多平台交叉编译 本文以官方构建文档 site/docs/user/build.md https://link.gitco图形学Flutter Engine编译系统终极指南GN构建与依赖管理实战解析Flutter Engine编译系统终极指南GN构建与依赖管理实战解析 Flutter Engine作为Flutter框架的核心引擎其编译系统采用Googl跨平台图形学前端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表