Logofpack

How fpack works

Targets, the build pipeline, where files go and what fpack never touches. Read this once; everything else builds on it.

fpack 如何工作

目标、构建流程、文件放在哪里,以及 fpack 绝不会动什么。先读一遍,后面的内容都建立在这里。

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
PlatformTargetsWhat 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
Webwebzip 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:

  1. Read the project (pubspec.yaml, android/app/build.gradle, the Xcode project) and fpack.yaml if there is one. Invalid configuration stops here, with the line and a suggestion.
  2. 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.
  3. Build with Flutter once per platform. macos + dmg + pkg share one flutter build macos; linux + deb + rpm + appimage + snap share one flutter build linux.
  4. Package and sign each target: copy or repack, sign, notarize, verify.
  5. Checksum and summarize: write SHA256SUMS next 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 with fpack clean.
  • Your sources are read-only. fpack does not edit Gradle files, Xcode projects, pubspec.yaml, icon or splash configs. Add dist/ 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:

  1. command-line flags (--flavor prod)
  2. FPACK_* environment variables (FPACK_FLAVOR=prod)
  3. fpack.yaml in the project root (build.flavor: prod)
  4. 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 knowRun
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#

TermMeaning
targeta kind of artifact: apk, dmg, deb, …
flavor an Android productFlavor / Xcode scheme (Flavors)
moderelease (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
iOSipa用于 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
Webweb可部署站点的 zip

**产物(artifact)**是目标生成的文件。每个目标的详细信息见目标与产物。

说明

Flutter 不能交叉编译桌面和 iOS 应用:iOS 和 macOS 要在 Mac 上构建,Windows 目标要在 Windows 上构建,Linux 目标要在 Linux 上构建;Android 和 Web 在哪里都能构建。fpack build --all 会构建这台机器能构建的全部目标,其余的注明原因并跳过;明确指定一个本机无法构建的目标会报错,并指引你使用对应系统的 CI 机器。

构建流程#

每次运行 fpack 都执行同样的步骤,所以失败总是发生得早、也容易定位:

  1. 读取项目(pubspec.yaml、android/app/build.gradle、Xcode 工程)和 fpack.yaml(如果有)。配置无效会在这里停下,并给出行号和建议。
  2. 检查每个目标(与 fpack doctor 相同):工具、SDK、证书、密钥库密码、flavor。无法构建的目标会在任何耗时步骤开始之前报告。
  3. 构建:每个平台只运行一次 Flutter 构建。macos + dmg + pkg 共用一次 flutter build macos;linux + deb + rpm + appimage + snap 共用一次 flutter build linux。
  4. 打包与签名每个目标:复制或重新打包、签名、公证、验证。
  5. 校验和与汇总:在产物旁写入 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 不需要配置。需要时,配置有四个来源,先设置了值的那个生效:

  1. 命令行参数(--flavor prod)
  2. FPACK_* 环境变量(FPACK_FLAVOR=prod)
  3. 项目根目录的 fpack.yaml(build.flavor: prod)
  4. 默认值(从你的项目读取,或使用 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)

下一步#

在下一页安装 fpack,然后进行第一次构建。