首页
/ Flutter Installation Bundles:为 Flutter 仓库构建可离线使用的预缓存安装包

Flutter Installation Bundles:为 Flutter 仓库构建可离线使用的预缓存安装包

2026-09-06 18:26:25作者:邬祺芯Juliet

导读

本文以 Flutter 仓库 infra 文档《Flutter-Installation-Bundles》为骨架,系统讲解 Flutter 官方"安装包(Installation Bundle)"的用途、手动构建的完整 10 步流程,以及官方发布所依赖的一键脚本 prepare_package.dart 及其背后的源码实现。读完本文,你将掌握在任意分支(如 master)上从零制作一个预缓存好工具链、pub 依赖与二进制产物的 Flutter 开发环境归档包,并可自行离线解压使用。

什么是 Flutter Installation Bundle

Flutter 官方会针对 beta 频道提供可直接下载安装的"安装包"(此前 dev 频道也提供,但该频道已被并入 master/main 而退休)。这类安装包的设计初衷是:让用户获得一个"完全填充就绪"的 Flutter 环境,而不必先下载 Git 仓库、再现场编译 flutter 工具等

也就是说,普通从源码搭建 Flutter 环境需要经历"克隆仓库 → 下载 Dart SDK → 构建 flutter 工具快照 → 拉取各包依赖 → 预缓存引擎产物"等一系列联网且耗时的步骤;而安装包把这些步骤全部预先完成并把结果打进归档包,使用者下载解压后即可直接投入离线开发。

从源码结构看,安装包的正式生产工具集中在 dev/bots/prepare_package.dart 及其子模块(common.dartarchive_creator.dartarchive_publisher.dart)中——它就是官方 CI 生成安装包所用的同一套脚本。

手动构建安装包:完整 10 步流程

下面的步骤可在任意 Git 与网络环境可达的机器上执行,官方亦明确表示可以照此流程为 master 分支制作安装包。所有命令的"离线预缓存"意图贯穿始终。

第 0 步(可选):预先决定 pub 缓存位置

PUB_CACHE 环境变量决定 pub 全局缓存放哪。若不设置,pub 会使用默认位置(随操作系统不同而变化,通常在你的主目录下)。

另一种方式:在任意调用 pub 的命令(例如 flutter packages)之前,先创建好 flutter/.pub-cache 目录——flutter 工具会自动探测并使用该目录,这样你就不必在环境中手动导出 PUB_CACHE

需要说明的是,手动构建流程里 pub 缓存面向"构建方",而面向最终使用者的 pub 依赖预缓存则是安装包内的 .pub-preload-cache 目录(详见下文"源码揭秘")。

Windows 专属:安装命令行版 Git

Windows 不自带 Git,请先自行下载并安装一个命令行版 Git,后续的 git clonegit reset 等操作依赖它。

克隆仓库并进入目录

git clone -b master https://github.com/flutter/flutter.git
cd flutter

这会以 master 分支克隆 Flutter Git 仓库到当前目录下的 flutter/ 子目录并进入其中。

将 Flutter 的 bin 目录加入 PATH

  • Windows(CMD):

    set PATH="%PATH%;%CD%\bin\flutter"
    

    注意此写法把 bin 追加进了 PATH,示例字符串本身带 \flutter 字样属文档原文,实际关键是把仓库内 bin 目录加入 PATH。

  • 其他平台(Linux/macOS):

    export PATH="$PATH:$PWD/flutter"
    

运行 flutter doctor

flutter doctor

它完成两件事:校验安装是否健康,以及构建 flutter 工具的初始快照(首次运行 flutter 命令会下载 Dart SDK 并编译工具自身)。如果它提示缺失 Android SDK、Xcode 工具链等,请按其指示补齐后再继续。

运行 flutter update-packages

flutter update-packages

下载构建 Flutter 主发行版中所有 package 所需的 pub 依赖。其命令实现在 packages/flutter_tools/lib/src/commands/update_packages.dart 中(UpdatePackagesCommand),会自动解析 packages/*dev/* 等各包的 pubspec.yaml 并统一执行依赖更新。

运行 flutter precache

flutter precache

确保 flutter 工具缓存的二进制产物(引擎 artifacts 等)为最新。flutter doctor 与后续 flutter create 都会触发引擎产物下载,precache 把该做的一次性做全,避免解包后被使用者触发联网下载。

可选:生成 IDE 配置文件

flutter ide-config --overwrite

仅当你要用 IntelliJ、VS Code 等 IDE 打开 Flutter 仓库时才有必要。它会生成/刷新仓库内的 IDE 配置。

预热工程模板(三个模板各建一次)

flutter create --template=app app_sample
flutter create --template=package package_sample
flutter create --template=plugin plugin_sample

临时目录中分别以 apppackageplugin 三种模板创建示例项目,之后即可删除这些目录。flutter create 会对其自身执行 pub get,从而把"创建新 Flutter 项目"所需的额外依赖也一并预热进 pub 缓存——这正是让解包后的使用者能离线 flutter create 的关键一环。

官方一键方案:直接运行 prepare_package.dart

官方制作安装包并非逐条手工执行上述 10 步,而是运行 dev/bots/prepare_package.dart 脚本自动完成。任何人都可以调用它:

  1. 先推进到上文"flutter doctor"那一步(如果已有一个可用的 Flutter 仓库,可以跳过——它来自其他频道也可以,但建议用较新版本以保证兼容);

  2. flutter 仓库根目录执行:

    ./bin/cache/dart-sdk/bin/dart ./dev/bots/prepare_package.dart --temp_dir $TMPDIR --revision $REVISION --branch master --output $PWD
    

    其中:

    • TMPDIR 指向一个有数 GB 空闲空间的目录(构建过程会写入几 GiB 临时数据);
    • REVISION 是你要构建的目标修订版的 40 位完整 Git hash

执行完毕后,当前目录会生成一个已经完成上述所有预热步骤、且包含 master 分支内容的归档包。

prepare_package.dart 全部命令行参数

结合 dev/bots/prepare_package.dart 的源码,脚本支持的参数如下:

参数 类型 说明 默认值 / 约束
--temp_dir 选项 临时文件写入位置,会写入数 GiB 数据,需足够空闲空间 系统临时目录,用后自动创建并删除
--revision 选项 要打包的 Git 修订版 hash 必填;必须是完整 40 位 hash,不接受前缀
--branch 选项 要打包的分支 必填;取值限于 Branch 枚举:betastablemastermain
--output 选项 归档包输出目录,不存在会自动递归创建 当前目录
--publish 标志 成功后把归档上传到 Google Cloud Storage 默认关闭
--target_arch 选项 目标 CPU 架构 默认取构建机本机架构;取值 x64arm64
--force / -f 标志 覆盖云端已存在的同名归档 默认关闭
--dry_run 标志 只打印 gsutil 命令而不真正执行上传 默认关闭
--help 标志 打印帮助后退出

BranchTargetArch 枚举定义在 dev/bots/prepare_package/common.dart。注意:虽然安装包当前只针对 beta 频道发布,但脚本本身对 stablemastermain 同样可用——文档明确说明可以照此流程为 master 分支构建。

脚本内部的工作流程

dev/bots/prepare_package.dartmain() 构造 ArchiveCreator 并依次调用:

  1. creator.initializeRepo():克隆并准备仓库(见下文);
  2. creator.createArchive():填缓存、校验、打归档包;
  3. 若指定 --publish,构造 ArchivePublisher 上传并更新发布元数据,否则调用 generateLocalMetadata() 生成本地元数据文件。

每一步若抛 PreparePackageException 都会以非零码退出并打印友好错误,随后按需清理临时目录。

源码级揭秘:安装包是怎么"预热"出来的

仓库初始化:clone → reset → 换源 → gc

ArchiveCreator._checkoutFlutter()(见 archive_creator.dart)执行:

  • git clone -b <branch> https://flutter.googlesource.com/mirrors/flutter:从 Chromium 镜像克隆指定分支(比 GitHub 更快更稳);
  • git reset --hard <revision>:把工作区精确复位到目标 40 位 hash,保证归档内容与修订版一一对应;
  • git remote set-url origin https://github.com/flutter/flutter.git:把 origin 改回 GitHub,方便解包者日后 flutter upgrade/push;
  • git gc --prune=now --aggressive:精简 .git 体积(源码注释指出约可省 100 MB)。

此外在 _populateCaches() 末尾,还会用 git clean -f -x 清掉各项目的 .packages.dart_tool/(已 check-in 的除外),并删除 .pub-cache/git 下的 git 依赖缓存——保证归档内缓存干净、体积可控。

缓存预热命令序列

_populateCaches()archive_creator.dart)内部实际执行的命令与手动 10 步一一对应:

  • flutter doctor
  • flutter update-packages
  • flutter precache(若指定 --target_arch 会追加 --host-arch=<arch>);
  • flutter ide-config
  • apppackageplugin 三个模板分别执行 flutter create --template=...(在临时目录执行,避免把嵌套 git 仓库打进归档);
  • _downloadPubPackageArchives():把当前 pub 缓存里每个 package 的 .tar.gz 归档下载到 $flutterRoot/.pub-preload-cache,供解包后首次使用时自动装入用户级缓存。下载带 SHA-256 校验、并发 10、单包最多重试 7 次(archive_creator.dart)。

--target_arch 的跨架构打包原理:通过设置 FLUTTER_HOST_ARCH 环境变量,让 bin/internal/update_dart_sdk.sh/.ps1(打的是被打包分支中的脚本)下载对应架构的 Dart SDK,进而让 flutter 命令缓存对应架构的引擎产物。脚本会做"paranoid check":比对实际下载的 Dart SDK 架构与请求的 target_arch 是否一致,不一致直接抛错(archive_creator.dart)。这正是 CI 上"在 arm64 主机交叉打包 x64 归档"的实现基础。

版本信息与命名规则

_getVersion()archive_creator.dart)通过 git describe 找版本 tag(strict 模式下要求 revision 恰好命中 tag),再以 flutter --version --machine 取 JSON 版本信息,合并进 frameworkVersionFromGitdartSdkVersiondartTargetArch 等字段。

归档文件名由 _archiveName 生成(archive_creator.dart),形如 flutter_<os>_<version>-<branch>.<suffix>,其中:

  • x64 架构文件名不带架构后缀,arm64 等则以 arm64_ 前缀标注;
  • macOS 用 .zipArchive Utility 双击解压 .tar.xz 的行为异常),Linux 用 .tar.xz
  • Windows 归档打包含额外步骤:先下载 MinGit 到 bin/mingit,压缩时先 attrib -h .git 再以 7za 极值压缩(-mx=9)。

发布流程(可选)

ArchivePublisherarchive_publisher.dart)在 --publish 时把归档上传到 gs://flutter_infra_release/releases/<branch>/<os>/...,并通过 transactionalUpdate 以"读-改-写"事务方式更新发布元数据 JSON(releases_<os>.json)。每条发布记录包含 hashchannelversiondart_sdk_versiondart_sdk_archrelease_datearchivesha256archive_publisher.dart);无 --publish 时则把同样的元数据写到本地文件便于人工检查。上传与元数据更新前会先 rm 目标(失败可容忍)并用正确 MIME 头与 Cache-Control 控制缓存。

质量门禁

strict 模式(即 --publish 且非 --dry_run)下,在 macOS 打包会执行 codesign -vvvv --check-notarization 校验 Dart 二进制已签名(archive_creator.dart),不通过则拒绝出包。测试覆盖见 dev/bots/test/prepare_package_test.dart

与发布频道的对应关系

安装包按频道发布,而 Flutter 官方渠道定义在 docs/releases/Flutter-build-release-channels.md,按稳定性递增依次为 master(别名 main,tip-of-tree)、beta(最新稳定候选)、stable(面向生产)。当前安装包面向 beta 频道发布,而脚本与文档均支持你为任意分支自行构建——若你以 flutter channel 查看,通常看到的就是 master/beta/stable 三个分支的切换。

实践建议与注意事项

  • 磁盘空间:无论手动流程还是 prepare_package.dart,预热过程会占用数 GiB 临时空间,请为临时目录预留充足容量;
  • revision 必须完整--revision 只接受 40 位完整 hash,用短 hash 或分支名会直接报错退出;
  • Windows 前置:Windows 需先装命令行 Git;打包 Windows 归档时脚本会自动下载并嵌入 MinGit;
  • 离线使用:解包后首次运行 flutter 命令会把 .pub-preload-cache 中的依赖自动装入用户级缓存,因此尽量在联网状态正常的机器上执行构建,以获得真正"开箱即用"的离线包;
  • 本机跑通验证:若对产出物不放心,可参考 dev/bots/test/prepare_package_test.dart 了解脚本的测试注入点(如假 HttpReader、假 ProcessManager),理解各阶段行为后再做定制。

通过本文,你既掌握了逐条手工预热 Flutter 仓库的完整命令序列,也理解了官方 prepare_package.dart 的内部机理与全部参数,足以在本地复刻一条可靠的 Flutter 安装包生产线。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391