fpack is a packaging tool, not a build system. It drives the tools you already use (flutter, Gradle, Xcode, signtool,
dpkg-deb, …) in the right order, adds signing, notarization and packaging, and collects the results. This page explains the few ideas the rest of the documentation relies on.
Targets and artifacts#
A target is one kind of file you want to ship. You name targets on the command line:
fpack build apk aab # two targets
fpack build macos dmg pkg # three targets
| Platform | Targets | What you get |
|---|---|---|
| Android | apk, aab |
APK (universal and/or per ABI), Android App Bundle |
| iOS | ipa |
IPA for App Store Connect, ad hoc, enterprise, or unsigned |
| macOS | macos, dmg, pkg |
zipped .app, disk image, installer package (signed, notarized) |
| Windows | windows, exe, msix |
portable zip, Inno Setup installer, MSIX |
| Linux | linux, deb, rpm, appimage, snap |
tar.gz, Debian package, RPM, AppImage, Snap |
| Web | web | zip of the deployable site |
An artifact is a file a target produced. Details of every target are on Targets.
Note
Flutter cannot cross-compile desktop and iOS apps. You build iOS and macOS on a Mac, Windows targets on Windows and Linux targets on Linux. Android and web build anywhere.
fpack build --all builds everything this machine can build and skips the rest with a reason; naming a target the machine cannot build is an error that points you to a CI runner of that OS.
The build pipeline#
For every run fpack does the same steps, so failures happen early and are easy to place:
-
Read the project (
pubspec.yaml,android/app/build.gradle, the Xcode project) andfpack.yamlif there is one. Invalid configuration stops here, with the line and a suggestion. -
Check each target (the same checks as
fpack doctor): tools, SDKs, certificates, keystore passwords, flavors. Targets that cannot be built are reported before anything slow starts. -
Build with Flutter once per platform.
macos+dmg+pkgshare oneflutter build macos;linux+deb+rpm+appimage+snapshare oneflutter build linux. - Package and sign each target: copy or repack, sign, notarize, verify.
-
Checksum and summarize: write
SHA256SUMSnext to the artifacts and print a table of what was produced.
--dry-run stops after step 2 and prints the exact commands steps 3 and 4 would run.
Where files go#
my_app/
dist/1.0.0+1/ artifacts and SHA256SUMS (output.dir)
build/fpack/logs/ full log of every command
build/fpack/secrets/ temporary key material, mode 0600, deleted after the build
build/fpack/… generated ExportOptions.plist, snapcraft.yaml, …
-
Artifacts go to
dist/<version>+<build>/. File names follow a template (names and output). Existing artifacts are never overwritten unless you pass--force: bump the version, pass--build-number N, or force it. -
Everything else fpack creates is under
build/fpack/and can be deleted withfpack clean. -
Your sources are read-only. fpack does not edit Gradle files, Xcode projects,
pubspec.yaml, icon or splash configs. Adddist/to.gitignore.
Configuration: flags, variables, file#
fpack needs no configuration. When you add some, it comes from four places; the first one that sets a value wins:
- command-line flags (
--flavor prod) FPACK_*environment variables (FPACK_FLAVOR=prod)fpack.yamlin the project root (build.flavor: prod)- defaults (read from your project, or fpack's own)
fpack init writes an fpack.yaml that lists every key, commented out, with explanations; uncomment what you need. Inside the file,
${VAR} and ${VAR:-default} read environment variables, which is how secrets stay out of the file (Secrets and variables).
Safety nets#
| You want to know | Run |
|---|---|
| What can this machine build, and what is missing? | fpack doctor (or fpack list) |
| Which commands will run? | fpack build … --dry-run |
| Why did it fail? |
read the excerpt and fix fpack prints; the full log path is shown; add
-v
to stream tool output
|
| What exactly was produced? | dist/<version>/SHA256SUMS, or --json |
Vocabulary#
| Term | Meaning |
|---|---|
| target | a kind of artifact: apk, dmg, deb, … |
| flavor | an Android productFlavor / Xcode scheme (Flavors) |
| mode | release (default), profile or debug |
| launcher / core | the small Dart program you install, and the native binary it downloads and runs ( Installation ) |
| notarization | Apple's malware scan for macOS software distributed outside the App Store ( macOS ) |
Next#
Install fpack on the next page, then follow your first build.
fpack 是打包工具,不是构建系统。它按正确的顺序驱动你已经在用的工具(flutter、Gradle、Xcode、signtool、dpkg-deb
等),补上签名、公证和打包,并把结果收集起来。本页解释后面文档会反复用到的几个概念。
目标与产物#
**目标(target)**是你想发布的一种文件。在命令行里写出目标名:
fpack build apk aab # 两个目标
fpack build macos dmg pkg # 三个目标
| 平台 | 目标 | 得到什么 |
|---|---|---|
| Android | apk、aab |
APK(通用和/或按 ABI 拆分)、Android App Bundle |
| iOS | ipa | 用于 App Store Connect、Ad Hoc、企业分发或未签名的 IPA |
| macOS | macos、dmg、pkg |
压缩的 .app、磁盘映像、安装包(已签名、已公证) |
| Windows | windows、exe、msix |
便携 zip、Inno Setup 安装程序、MSIX |
| Linux | linux、deb、rpm、appimage、snap |
tar.gz、Debian 包、RPM、AppImage、Snap |
| Web | web | 可部署站点的 zip |
**产物(artifact)**是目标生成的文件。每个目标的详细信息见目标与产物。
说明
Flutter 不能交叉编译桌面和 iOS 应用:iOS 和 macOS 要在 Mac 上构建,Windows 目标要在 Windows 上构建,Linux 目标要在 Linux 上构建;Android 和 Web 在哪里都能构建。fpack build --all
会构建这台机器能构建的全部目标,其余的注明原因并跳过;明确指定一个本机无法构建的目标会报错,并指引你使用对应系统的 CI 机器。
构建流程#
每次运行 fpack 都执行同样的步骤,所以失败总是发生得早、也容易定位:
-
读取项目(
pubspec.yaml、android/app/build.gradle、Xcode 工程)和fpack.yaml(如果有)。配置无效会在这里停下,并给出行号和建议。 -
检查每个目标(与
fpack doctor相同):工具、SDK、证书、密钥库密码、flavor。无法构建的目标会在任何耗时步骤开始之前报告。 -
构建:每个平台只运行一次 Flutter 构建。
macos+dmg+pkg共用一次flutter build macos;linux+deb+rpm+appimage+snap共用一次flutter build linux。 - 打包与签名每个目标:复制或重新打包、签名、公证、验证。
- 校验和与汇总:在产物旁写入
SHA256SUMS,并打印产出文件的表格。
--dry-run 在第 2 步之后停下,打印第 3、4 步将运行的确切命令。
文件放在哪里#
my_app/
dist/1.0.0+1/ 产物和 SHA256SUMS(output.dir)
build/fpack/logs/ 每条命令的完整日志
build/fpack/secrets/ 临时密钥文件,权限 0600,构建后删除
build/fpack/… 生成的 ExportOptions.plist、snapcraft.yaml 等
-
产物放在
dist/<版本>+<构建号>/。文件名遵循模板(名称与输出)。默认绝不覆盖已有产物:提高版本号、传--build-number N,或者用--force。 -
fpack 创建的其他一切都在
build/fpack/下,可以用fpack clean删除。 -
你的源码是只读的。 fpack 不会修改 Gradle 文件、Xcode 工程、
pubspec.yaml、图标或启动页配置。建议把dist/加入.gitignore。
配置:参数、变量、文件#
fpack 不需要配置。需要时,配置有四个来源,先设置了值的那个生效:
- 命令行参数(
--flavor prod) FPACK_*环境变量(FPACK_FLAVOR=prod)- 项目根目录的
fpack.yaml(build.flavor: prod) - 默认值(从你的项目读取,或使用 fpack 自己的默认)
fpack init 会写出一个列出所有键的 fpack.yaml,全部注释掉并带说明,需要什么就取消注释什么。文件里的
${VAR} 和 ${VAR:-默认值} 会读取环境变量,密钥就是这样不进文件的(密钥与环境变量)。
安全网#
| 你想知道 | 运行 |
|---|---|
| 这台机器能构建什么?缺什么? | fpack doctor(或 fpack list) |
| 会运行哪些命令? | fpack build … --dry-run |
| 为什么失败? | 看 fpack 打印的错误摘要和修复建议;会显示完整日志路径;加 -v 查看工具的完整输出 |
| 到底产出了什么? | dist/<版本>/SHA256SUMS,或 --json |
术语#
| 术语 | 含义 |
|---|---|
| 目标 | 一种产物:apk、dmg、deb 等 |
| flavor | Android productFlavor / Xcode scheme(Flavor) |
| 模式 | release(默认)、profile 或 debug |
| 启动器 / 核心 | 你安装的小型 Dart 程序,以及它下载并运行的原生二进制(安装) |
| 公证 | Apple 对在 App Store 之外分发的 macOS 软件做的恶意软件扫描(macOS) |