跨平台图形学前端【免费下载链接】engineThe Flutter engine项目地址https://gitcode.com/gh_mirrors/eng/engine点击查看免费下载导读Flutter Engine 的 CI 构建体系以 engine_v2 构建配置文件为核心这些 JSON 文件存放在仓库的ci/builders/目录下描述了引擎如何被构建、测试、归档并上传到云端存储。本文围绕仓库中tools/pkg/engine_build_configs/README.md所描述的 Dart 工具包系统讲解如何使用该包解析这些配置、校验其合法性并在本地机器上复现某个 CI 构建任务。读完本文你将掌握 engine_v2 构建配置 JSON 的完整字段结构、run.dart与check.dart两个命令行工具的使用方法以及BuildConfigLoader、BuildRunner等核心 API 的底层执行原理。一、背景什么是 engine_v2 构建配置在 Flutter Engine 仓库中CI 的构建、测试、归档与上传行为不再散落在各个脚本里而是集中声明在ci/builders/目录下的 JSON 文件中如linux_unopt.json、mac_host_engine.json、local_engine.json等。这些文件被称为engine_v2 构建配置build config。engine_build_configs这个 Dart 包位于tools/pkg/engine_build_configs提供了三方面的能力对象化解析把 JSON 文件反序列化为强类型的 Dart 对象批量加载扫描一个目录树加载其中全部构建配置本地执行在开发机上按照配置真实运行 GN、Ninja 等构建步骤。需要特别说明的是这套库本身并不参与 CI 的实际执行。CI 上真正执行这些配置的是独立的 engine_v2 recipes属于仓库外部的 Flutter recipes 工程本库的价值在于让开发者可以在本地解析、校验并复现这些配置。包内代码注释明确写道“The code in this library isnotused by CI to run these configurations”见lib/engine_build_configs.dart。包的导出入口是lib/engine_build_configs.dart它统一导出了三个源码模块模块职责lib/src/build_config.dart构建配置 JSON 文件的 Dart 对象表示lib/src/build_config_loader.dart批量加载目录树中所有构建配置 JSON 的辅助类lib/src/build_config_runner.dart在本地机器上运行已加载构建配置的类此外包还包含lib/src/ci_yaml.dart解析仓库根目录.ci.yaml中与本地开发相关的字段与lib/src/merge_gn_args.dartGN 参数的合并工具以及bin/目录下的两个示例命令行程序。二、核心对象模型build_config.dartlib/src/build_config.dart是整个包的数据模型基础。它以BuildConfigBase为所有节点的基类每个节点在解析失败时会累积错误信息并通过valid属性与check(path)方法对外暴露校验结果。2.1 顶层结构BuilderConfig每个构建配置文件是一份 JSON 顶层 map对应 Dart 类BuilderConfig其字段定义见build_config.dart的注释{ builds: [], tests: [], generators: { tasks: [] }, archives: [] }各字段含义builds一组相互独立、没有依赖关系的构建必要时可以并行执行tests全局测试列表测试可能依赖一个或多个构建的输出generators产生额外产物的生成任务可能依赖一个或多个构建的输出顶层字段内嵌tasks列表archives对全局生成器产出物的上传说明。BuilderConfig.canRunOn(platform)用于判断其中是否存在能在给定平台上运行的构建。2.2 构建单元Buildbuilds列表中的每个元素是一个 map对应 Dart 类Build字段结构如下源码注释原样见build_config.dart{ name: , description: , gn: [], ninja: {}, tests: [], generators: { tasks: [] }, archives: [], drone_dimensions: [], gclient_variables: {} }各字段的精确语义name构建名称同时可被全局测试作为依赖引用description对该构建用途的人类可读描述gn传给flutter/tools/gn的参数列表用于配置构建ninja构成 ninja 命令的数据见下testsninja 构建完成后可运行的测试列表generatorsninja 构建完成后生成新产物的任务列表archives对构建产物的上传说明drone_dimensions一组keyvalue字符串用于选择运行该构建的 CI botgclient_variables在运行gclient sync之前注入.gclient文件custom_vars段的变量字典。其中ninja子对象BuildNinja包含configgn 生成的配置名称同时也是out/目录下构建输出所在的子目录名targets要构建的 ninja 目标列表。Build.canRunOn(platform)通过解析drone_dimensions中的os维度判断平台兼容性osLinux对应 LinuxosWindows*对应 WindowsosMac*对应 macOS见_canRunOn。2.3 测试、生成任务与归档builds→testsBuildTest字段{ language: , name: , parameters: [], script: , contexts: [] }language执行脚本的可执行程序名script脚本相对于 checkout 目录的路径parameters传给脚本的标志或参数。这里存在一种魔法环境变量机制目前仅支持${FLUTTER_LOGS_DIR}且必须单独占满一个参数字符串[${FLUTTER_LOGS_DIR}]合法而[path${FLUTTER_LOGS_DIR}]不合法contexts可用的测试执行上下文列表目前支持两种android_virtual_device与metric_center_token。builds→generatorsBuildTask字段{ name: , parameters: [], scripts: [], language: }其语义是列表中的每个脚本按顺序执行同一份parameters会被追加到每个脚本后面。language为空时默认视为 bash。builds→archivesBuildArchive字段{ name: , base_path: , type: , include_paths: [], realm: }type存储类型当前仅支持gcs与casbase_path上传前要从完整路径中移除的部分路径realmproduction生产或experimental实验include_paths要上传到目标位置的路径列表。2.4 全局测试与全局归档顶层testsGlobalTest字段{ name: , recipe: , drone_dimensions: [], dependencies: [], tasks: [] }recipe与默认tester不同的 recipe 名称dependencies测试所需的构建输出列表test_dependencies测试运行所需的依赖TestDependency含dependency与 CIPDversion两个字段tasks脚本及其参数列表TestTask。TestTask额外支持max_attempts字段表示可容忍的最大失败次数默认值为 1见intOfJson的 fallback 机制。顶层archivesGlobalArchive字段{ source: out/debug/artifacts.zip, destination: ios/artifacts.zip, realm: production }source产物相对于引擎 checkout 的路径destination存储桶中的目标文件夹realm目标路径相对于哪个存储桶production或experimental。三、批量加载器build_config_loader.dartBuildConfigLoader是一个简单的工具类见build_config_loader.dart构造时传入buildConfigsDir目录随后递归扫描目录下所有.json文件以文件名去掉.json后缀作为配置名例如linux_unopt.json对应配置名linux_unopt逐个jsonDecode并调用BuilderConfig.fromJson解析任何解析错误JSON 语法错误、顶层不是 map 等都会以字符串形式累积到errors列表中。使用时必须注意第一次访问configsgetter 之后一定要检查errors列表因为加载过程中的失败不会抛出异常而是静默记录。bin/check.dart与bin/run.dart都是先访问loader.configs再遍历loader.errors输出并置退出码为 1。四、本地执行器build_config_runner.dartbuild_config_runner.dart是整个包中逻辑最重的部分它定义了事件模型与三类 Runner。4.1 事件模型执行过程中的每一步都会产生一个RunnerEvent事件通过回调RunnerEventHandler派发给调用方RunnerStart命令开始RunnerProgress命令进行中含what、completed、total、percent、done字段例如 ninja 的[6232/6269]进度行会被解析并转换为进度事件见_ninjaProgressRunnerResult命令结束包含退出码、stdout、stderrRunnerError命令无法执行等错误。bin/run.dart中的handler展示了消费这些事件的典型写法RunnerProgress(done: false)时在终端用\r刷新单行进度条其余事件直接打印。4.2 BuildRunner 与执行顺序BuildRunner按固定顺序执行一个Build的四个阶段见run()方法GN运行flutter/tools/gn加合并后的 gn 参数产出构建配置ninja以ninja -C out/config targets...执行编译generators依次运行每个生成任务tests依次运行每个测试。关键构造参数concurrency并发 job 数对应 ninja 的-j参数默认0表示自动决定extraGnArgs/extraNinjaArgs/extraTestArgs分别追加到 GN、ninja、所有测试命令的参数runGn/runNinja/runGenerators/runTests四个布尔开关可跳过任意阶段dryRun为 true 时不真正产生子进程配合process_fakes用于测试rbeConfigRBE 远程执行配置。bin/run.dart中正是用runGenerators: false, runTests: false来满足 README 所述“不运行生成器与测试”的定位。4.3 RBE远程构建执行支持RbeConfig与RbeExecStrategy枚举封装了 reclient 的 RBE 行为策略行为local缓存未命中时全部在本地执行racing缓存未命中时本地与远端同时执行谁快用谁remote缓存未命中时全部在远端执行remoteLocalFallback远端延迟过高时回退本地执行RbeConfig的默认值是racing策略、racingBias0.95、localResourceFraction0.2并通过环境变量如RBE_exec_strategy、RBE_racing_bias、RBE_cas_concurrency100、RBE_enable_deps_cache1、RBE_deps_cache_max_mb1024传递给子进程见RbeConfig.environment。当 GN 参数中含有--rbe时_isRbe为真ninja 阶段前后会分别调用 reclient 的bootstrap启动与关闭 reproxy并用reproxystatus读取 RBE 统计信息。4.4 其他 Runner 与细节BuildTaskRunner按序执行生成任务中的每个脚本解释器通过_interpreter()解析——python*一律强制为python3dart使用当前运行本程序的 Dart 可执行文件其余语言原样使用BuildTestRunner执行单个测试命令支持追加extraTestArgsfixGccPaths把 ninja 输出中相对于out/的报错路径转换为相对于当前工作目录的路径并剥离 ANSI 颜色码方便 IDE 点击跳转。五、命令行工具使用指南5.1run.dart在本地运行一个构建bin/run.dart的用法与 README 一致$ dart bin/run.dart [build config name] [build name]示例$ dart bin/run.dart mac_unopt host_debug_unopt参数语义build config nameci/builders/下 JSON 文件的文件名不含.json后缀。注意 README 示例中的mac_unopt对应仓库中的ci/builders/mac_unopt.jsonbuild name该 JSON 中builds列表里某个 map 的name字段值例如mac_unopt.json中的ci/host_debug_arm64_tests、ci/mac_release_arm64_tests等。执行流程见run.dart源码依次为通过Engine.findWithin()定位引擎仓库要求当前工作目录位于 engine checkout 内构造BuildConfigLoader加载ci/builders下所有配置若没有找到任何配置或加载出错输出错误并置退出码 1按配置名取出目标BuilderConfig调用targetConfig.check(configName)做合法性检查在builds中按名称匹配目标Build检查flutter/build/rbe目录是否存在不存在则自动附加--no-rbeGN 参数构造BuildRunnerrunGenerators: false、runTests: false运行并打印进度。5.2check.dart校验全部构建配置bin/check.dart的用法与 README 一致$ dart bin/check.dart [/path/to/engine/src]当当前工作目录位于 engine checkout 内部时engine 源码路径参数可以省略当工作目录不在 checkout 内时必须显式传入 engine 源码根目录。该工具会依次执行三类检查见check.dart源码反序列化有效性检查checkForInvalidConfigs逐个对加载出的BuilderConfig调用check()任何字段类型错误、必填字段缺失都会在此暴露错误信息形如For field gn, expected type: list, actual type: String.重复名称检查checkForDuplicateConfigs要求同一配置文件内所有 build 的name唯一build 命名规范检查checkForInvalidBuildNames要求 build 名称以规定前缀开头——对local_engine.json允许的前缀是linux/、macos/、windows/正反斜杠均可因为该文件里的构建由et工具在开发机上运行对其他所有构建配置文件允许的前缀是ci/与web_tests/。任何一类检查失败都会在 stderr 输出具体错误并返回非零退出码从而让 CI 或本地脚本能够拦截配置错误。六、CI 集成check_build_configs.sh 与 linux_unopt.jsoncheck.dart在 CI 的 pre/post submit 中通过ci/check_build_configs.sh运行入口在ci/builders/linux_unopt.json的一个测试步骤里name: Check build configsscript 为flutter/ci/check_build_configs.sh。ci/check_build_configs.sh的核心逻辑是先定位引擎源码目录找到内置的 Dart SDK优先使用flutter/third_party/dart/tools/sdks/dart-sdk/bin否则回退到third_party/dart/...然后执行$DART $SRC_DIR/flutter/tools/pkg/engine_build_configs/bin/check.dart $SRC_DIR这印证了 README 中的描述该脚本在 CI 的 pre 与 post submit 阶段运行用于保证合入的构建配置 JSON 始终合法。七、真实配置示例解读以ci/builders/linux_unopt.json中的第一个 build 为例可以看到 engine_v2 配置的完整面貌{ drone_dimensions: [device_typenone, osLinux, cores32], gclient_variables: { use_rbe: true }, gn: [ --target-dir, ci/host_debug_unopt, --runtime-mode, debug, --unoptimized, --prebuilt-dart-sdk, --asan, --lsan, --dart-debug, --rbe, --no-goma ], name: ci/host_debug_unopt, description: Builds a debug mode unopt Linux engine. Builds and runs many tests and lints., ninja: { config: ci/host_debug_unopt, targets: [flutter/tools/font_subset, flutter:unittests, ...] }, tests: [ { name: test: Check formatting, script: flutter/bin/et, parameters: [format, --dry-run, --all] }, { language: python3, name: test: Host_Tests_for_host_debug_unopt, script: flutter/testing/run_tests.py, parameters: [--quiet, --logs-dir, ${FLUTTER_LOGS_DIR}, --variant, ci/host_debug_unopt, ...] }, { language: dart, name: test: observatory and service protocol, script: flutter/shell/testing/observatory/test.dart, ... }, { name: Check build configs, script: flutter/ci/check_build_configs.sh } ] }这段配置清晰展示了drone_dimensions指定了osLinux、cores32的 bot 选择条件而Build.canRunOn正是据此判断本地平台匹配性gn数组原样传递给flutter/tools/gn其中--target-dir ci/host_debug_unopt决定输出目录与ninja.config保持一致tests中出现了 bash默认 language、python3、dart三种执行方式并且--logs-dir ${FLUTTER_LOGS_DIR}演示了魔法环境变量的独立参数用法Check build configs测试步骤自身就是调用check.dart实现了“配置自检”。再对比ci/builders/local_engine.json中的构建如macos/ios_debug、linux/android_debug_arm64、windows/android_profile_arm64其名称统一采用os/平台_目标前缀这正是check.dart第三类检查要求的命名规范这类构建由et工具flutter/bin/et在开发机上直接运行与 CI 专用配置ci/前缀区分开来。八、GN 参数合并机制BuildRunner在拼装 GN 命令前会把构建配置中的build.gn参数与调用方传入的extraGnArgs通过mergeGnArgs合并。合并规则是extraArgs只接受形如--foo或--no-foo的布尔标志含或空格的参数会抛出ArgumentError若buildArgs中存在同名标志则用extraArgs中的值覆盖--foo可被--no-foo替换反之亦然未被覆盖的新标志追加到列表末尾非布尔参数如--runtime-modedebug原样保留。例如bin/run.dart在检测到本地没有 RBE 配置目录时附加--no-rbe若配置里已有--rbe合并结果就会把--rbe替换为--no-rbe从而在本地禁用远程执行。该行为有对应的单元测试merge_gn_args_test.dart覆盖。九、测试覆盖与验证包的test/目录提供了完整测试套件可作为 API 使用范本build_config_test.dart验证各类 JSON 节点对象化与check()校验逻辑build_config_loader_test.dart验证目录扫描、命名映射与错误累积build_config_runner_test.dart通过FakePlatform与 fake process manager 在dryRun模式下断言 GN/ninja/generator/test 各阶段发出的RunnerEvent序列与命令内容例如断言 GN 事件的首个命令包含flutter/tools/gn、生成任务命令包含python3与gen/script.py等ci_yaml_test.dart验证.ci.yaml解析merge_gn_args_test.dart验证参数覆盖与追加。十、使用注意事项小结加载后务必检查errorsBuildConfigLoader的解析错误不会抛出而是进入errors列表run.dart不运行生成器与测试它定位为“复现一次构建”README 明确说明 “It doesnt run generators or tests, and it isnt run on CI”实际使用时如需完整流程应直接使用BuildRunnerAPI 并显式开启runGenerators/runTestsRBE 依赖本地环境只有 GN 参数包含--rbe且本地存在flutter/build/rbe配置时才会启用 reclient否则自动附加--no-rbe命名规范是硬性约束新增或修改ci/builders/下的配置时build 名称必须符合ci/或local_engine.json中的linux/、macos/、windows/前缀否则无法通过check.dart进而被 CI 拦截平台匹配由drone_dimensions决定BuildRunner会在执行前调用build.canRunOn(platform)若本地平台与配置声明的os维度不符会直接产出RunnerError并失败这正是“在错误的平台上跑 CI 构建”的防御机制。赞分享跨平台图形学前端【免费下载链接】engineThe Flutter engine项目地址https://gitcode.com/gh_mirrors/eng/engine点击查看免费下载相关推荐深入解析 Flutter 引擎构建配置工具包 engine_build_configs从 JSON 配置到本地执行深入解析 Flutter 引擎构建配置工具包 engine_build_configs从 JSON 配置到本地执行 引擎的 CI 构建体系依赖一套以 JSON跨平台移动开发前端UI组件桌面应用Skia 的 Bazel 构建实战本地构建、.bazelrc 配置与 RBE 远程执行Skia 的 Bazel 构建实战本地构建、.bazelrc 配置与 RBE 远程执行 本文以 Skia 仓库中的开发者指南 site/docs/dev/co图形学图像处理Wazuh Engine Standalone 独立引擎本地打包、运行与配置全指南Wazuh Engine Standalone 独立引擎本地打包、运行与配置全指南 Wazuh Engine 是 Wazuh 5.x 中负责安全事件实时处理的网络安全IDS日志分析应用安全漏洞扫描上一篇ESP32-WiFi-Manager深度解析5步搭建ESP32智能WiFi配置门户下一篇如何快速上手 Cua让 AI 安全操作 macOS 桌面的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考