打包(Linux)
Linux 上的分发有几种形式。 最容易上手的是 Flatpak,所以本指南介绍它。 Flatpak 是沙箱化的,可跨发行版工作,而且创建起来很直接。
需要的工具是 flatpak 和 flatpak-builder。
同时还要添加 Flathub 远程仓库。
你的应用程序所构建所依赖的运行时和 SDK 都来自那里:
flatpak remote-add --if-not-exists --user flathub https://dl.flathub.org/repo/flathub.flatpakrepo根据你使用的编程语言,你还需要一个工具,把构建工具的锁文件转换为 flatpak-builder 能够理解的依赖项。
构建过程与 Flatpak 本身一样是沙箱化的,其内部无法访问网络。
每一个原本需要下载的依赖项都必须事先声明。
Slint 支持的每种编程语言都有对应的锁文件转换脚本:
- Rust
- NodeJS
- Deno
- Python
C++ 没有标准的跨平台包管理器。 请改为将依赖项随项目一同提供。 Slint 支持 Bun,但 Flatpak 不支持。
创建构建文件
Section titled “创建构建文件”Flatpak 构建文件以包 ID 命名,包 ID 是一个你控制的、反向书写的域名。
本指南使用 com.yourorganization.YourApp,因此构建文件名为 com.yourorganization.YourApp.yml。
# The ID, explained above.id: com.yourorganization.YourApp
# The runtime your application runs againstruntime: org.freedesktop.Platform# A new major version comes out every August and is supported for two years.# See https://docs.flatpak.org/en/latest/available-runtimes.htmlruntime-version: '25.08'
# The command that starts your application, installed by the build belowcommand: your-app
# The matching SDK, which the build runs insdk: org.freedesktop.Sdk
# The set of permissions that this application requiresfinish-args: # OpenGL/Vulkan rendering - --device=dri # Allow use of IPC (required by Wayland and X11) - --share=ipc # Allow using Wayland via the Freedesktop sandbox protocol extensions - --socket=wayland # Use X11 as a fallback. There is also `--socket=x11` for applications # that require X11, but `--socket=fallback-x11` overrides it - --socket=fallback-x11这些权限是每个 Slint 应用程序所需的最低权限。
如果需要更多权限,请参见 Flatpak 的文档。
常见的额外权限有:用于网络访问的 --share=network、用于音频的 --socket=pulseaudio,以及用于蓝牙的 --allow=bluetooth。
指定构建过程
Section titled “指定构建过程”接下来是与你的语言相关的部分:依赖项和构建过程。
对锁文件运行上面提到的 flatpak-cargo-generator.py 脚本。
它会以内联方式声明自己的依赖项,因此 uv 无需虚拟环境即可运行它:
curl -O https://raw.githubusercontent.com/flatpak/flatpak-builder-tools/master/cargo/flatpak-cargo-generator.pyuv run flatpak-cargo-generator.py Cargo.lock -o cargo-sources.json传入 -o,否则脚本会改为写入 generated-sources.json。
如果要使用 python3 而不是 uv 运行它,请先安装它的 aiohttp 和 tomlkit 依赖项。
# ...
# This ensures that the Rust toolchain is installed inside the build environment.sdk-extensions: - org.freedesktop.Sdk.Extension.rust-stable
modules: # The module name is arbitrary, but Flatpak will create a `/run/build/your-module-name` # directory and build the package inside of it, so it should match any `/run/build/..` # paths in the build config. It does not need to match the command name. - name: your-app # This tells Flatpak that you will be writing the build commands out manually, in # `build-commands` (see below) buildsystem: simple build-options: # This adds the Rust SDK to your PATH append-path: /usr/lib/sdk/rust-stable/bin env: # Required to keep the Cargo build artifacts inside Flatpak's sandboxed build # directory CARGO_HOME: /run/build/your-app/cargo CARGO_NET_OFFLINE: 'true' build-commands: - cargo --offline fetch --manifest-path Cargo.toml --verbose # For the sake of this example, we assume that this build command produces a binary # named `your-app`. - cargo build --release --offline # The right-hand side of this must be `${FLATPAK_DEST}/bin/your-command`, where # `your-command` matches the top-level `command` field mentioned in the previous # section - install -Dm0755 target/release/your-app ${FLATPAK_DEST}/bin/your-app sources: - type: git # This assumes that this yaml file is in the root of your project path: ./ # `HEAD` builds the commit your checkout is on. Without a ref, # flatpak-builder builds the repository's default branch instead branch: HEAD # If you named your generated sources file something different, or put it somewhere # other than in the same directory as this file, you should specify the path to it # here - cargo-sources.json这涵盖了默认渲染器所需的一切。 正如下一节所解释的,Skia 渲染器需要更多内容。
Skia 渲染器
Section titled “Skia 渲染器”Skia 是一个用 C++ 编写的大型图形库。 通常,使用 Skia 渲染器构建 Slint 时会下载一份预编译的副本,但沙箱内无法访问网络,因此构建过程必须自行编译 Skia。 这意味着要在清单中声明 Skia 自身的源代码,足足有数百兆字节。
下面的脚本可以完成这件事。
它会查找你的 Slint 版本所期望的确切 Skia 修订版本,然后把 Skia 的依赖项列表转换为各自固定到某个提交的源代码。
把它保存到 flatpak-cargo-generator.py 旁边,并在依赖项发生变化时从项目根目录运行它:
python3 flatpak-skia-generator.py它只使用标准库,因此自身不需要任何依赖项。
#!/usr/bin/env python3# Copyright © SixtyFPS GmbH <info@slint.dev># SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
"""Turn the Skia revision that skia-bindings pins into flatpak-builder sources.
Usage: flatpak-skia-generator.py [-o skia-sources.json] [--dest deps/skia-src]"""
import jsonimport reimport subprocessimport sysimport urllib.request
flags = dict(zip(sys.argv[1::2], sys.argv[2::2]))output = flags.get("-o", "skia-sources.json")dest = flags.get("--dest", "deps/skia-src")
def fetch(url): return urllib.request.urlopen(url).read().decode()
cargo = ["cargo", "metadata", "--format-version", "1", "--locked"]packages = json.loads(subprocess.check_output(cargo))["packages"]bindings = [p for p in packages if p["name"] == "skia-bindings"]if not bindings: sys.exit("no skia-bindings; is the renderer-skia feature enabled?")tag = bindings[0]["metadata"]["skia"]print(f"skia-bindings {bindings[0]['version']}, skia fork tag {tag}", file=sys.stderr)
raw = f"https://raw.githubusercontent.com/rust-skia/skia/{tag}"
# Skia's DEPS is Python, listing every checkout its own build expectsns = {"Var": lambda name: ns["vars"][name]}exec(fetch(f"{raw}/DEPS"), ns) # noqa: S102 -- evaluating DEPS is the point
fork = "https://github.com/rust-skia/skia.git"sources = [{"type": "git", "url": fork, "tag": tag, "dest": dest}]for path, spec in sorted(ns["deps"].items()): if not isinstance(spec, str) or "emsdk" in path: continue # cipd packages and the wasm-only emsdk are not needed url, _, commit = spec.partition("@") assert commit, f"DEPS entry {path} has no pinned commit: {spec}" sources.append( { "type": "git", "url": url, "commit": commit, "dest": f"{dest}/{path}", "disable-submodules": True, } )
with open(output, "w") as f: json.dump(sources, f, indent=4) f.write("\n")print(f"wrote {output} ({len(sources)} sources)", file=sys.stderr)
# Skia records the gn revision its own CI builds with; print it so the gn# module in the manifest can follow along when the Skia pin movesgn = re.search(r"rev = '(\w{40})'", fetch(f"{raw}/bin/fetch-gn"))if gn: print(f"skia pins gn revision {gn.group(1)}", file=sys.stderr)Skia 使用 gn 进行配置,而 SDK 并不附带这个构建工具;它使用 clang 而不是 SDK 的 gcc 进行编译。
这给清单带来了四项新增内容:
# ...
sdk-extensions: - org.freedesktop.Sdk.Extension.rust-stable # clang, and the libclang that the bindings generator loads - org.freedesktop.Sdk.Extension.llvm20
# Applies to every module, unlike the build-options of a single module, so that# both gn and Skia find clangbuild-options: append-path: /usr/lib/sdk/rust-stable/bin:/usr/lib/sdk/llvm20/bin
# gn is only needed to build Skia, so keep it out of the finished applicationcleanup: - /bin/gn
modules: - name: gn buildsystem: simple build-commands: - python3 build/gen.py --out-path=out --allow-warnings - ninja -C out gn - install -Dm0755 out/gn ${FLATPAK_DEST}/bin/gn sources: - type: git url: https://gn.googlesource.com/gn.git # The generator prints the revision Skia itself uses commit: b2afae122eeb6ce09c52d63f67dc53fc517dbdc8 # gn stamps its version from a tag, which a shallow clone leaves behind disable-shallow-clone: true
- name: your-app # ... build-options: env: # ... # Points the build at the prepared Skia sources, which is what makes it # compile them instead of downloading anything SKIA_SOURCE_DIR: /run/build/your-app/deps/skia-src LIBCLANG_PATH: /usr/lib/sdk/llvm20/lib # Use the gn built above rather than the one Skia would fetch SKIA_GN_COMMAND: /app/bin/gn sources: # ... - skia-sources.json编译 Skia 需要一段时间,而且它的源代码很大。 每个输入都固定到某个提交,因此构建保持可复现、能在运行时支持的所有架构上工作,并且在你重新运行生成器时会跟随你的 Slint 版本。
从 Slint 模板创建的项目会调用 find_package(Slint),并在失败时回退到下载 Slint,而 Slint 又会下载 Corrosion。
沙箱对两者都没有网络,因此两者都成为清单中的源代码,而 Slint 会作为它自己的模块被构建,安装到 /app,供 find_package 拾取。
C++ 项目没有自己的锁文件,但 Slint 的 C++ 库是由 Rust 源代码构建的,因此还必须声明它的 crate。 在沙箱外配置一次你的项目,清单所需的一切就都在磁盘上了:
# Downloads Slint and Corrosion, as an ordinary build doescmake -B build
# The crates Slint needs, taken from the revision CMake just fetcheduv run flatpak-cargo-generator.py build/_deps/slint-src/Cargo.lock -o cargo-sources.json
# The revisions to pin belowgit -C build/_deps/slint-src rev-parse HEADgit -C build/_deps/corrosion-src rev-parse HEAD从同一次检出中获取锁文件和修订版本,可以让两者保持同步。
如果 crate 是从与你构建时不同的修订版本生成的,会导致 cargo 无法解析其依赖项,而且它会以存在差异的 crate 来表述,而不是直接说明不匹配本身。
# ...
# Slint's C++ library is built from Rust sourcessdk-extensions: - org.freedesktop.Sdk.Extension.rust-stable
build-options: append-path: /usr/lib/sdk/rust-stable/bin
modules: - name: slint-cpp buildsystem: cmake-ninja subdir: api/cpp build-options: env: CARGO_HOME: /run/build/slint-cpp/cargo CARGO_NET_OFFLINE: 'true' config-opts: - -DCMAKE_BUILD_TYPE=Release # The runtime searches /app/lib, while the SDK's CMake defaults to lib64 - -DCMAKE_INSTALL_LIBDIR=lib # Slint's own CMake downloads Corrosion unless it is already there - -DFETCHCONTENT_SOURCE_DIR_CORROSION=/run/build/slint-cpp/corrosion # Leave out what your application doesn't use, to shorten the build - -DSLINT_FEATURE_INTERPRETER=OFF - -DSLINT_FEATURE_TESTING=OFF sources: - type: git url: https://github.com/slint-ui/slint.git # The revisions printed above commit: <slint revision> - type: git url: https://github.com/corrosion-rs/corrosion.git commit: <corrosion revision> dest: corrosion - cargo-sources.json
- name: your-app buildsystem: simple build-commands: # find_package(Slint) picks up the library installed above, so the # FetchContent fallback never runs - cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=/app - cmake --build build # The template has no install rule, so place the binary by hand - install -Dm0755 build/your-app ${FLATPAK_DEST}/bin/your-app sources: - type: git path: ./ branch: HEAD该 C++ 库会使用 FemtoVG 渲染器构建,且不包含 Skia,这需要几分钟时间。
使用 Skia 渲染器
Section titled “使用 Skia 渲染器”Skia 是一个用 C++ 编写的大型图形库。 使用它构建 Slint 通常需要下载一份预编译副本,而由于沙箱内无法访问网络,构建过程会改为从源代码编译 Skia。 这会增加大约十五分钟,并意味着要在清单中声明 Skia 自身的源代码。
下面的脚本会把它们写入 skia-sources.json。
它会查找你的 Slint 版本所期望的 Skia 修订版本,然后把 Skia 的依赖项列表转换为各自固定到某个提交的源代码。
在 CMake 拉取的 Slint 检出目录中运行它,因为那才是正在构建的版本:
project=$PWD(cd build/_deps/slint-src && python3 "$project/flatpak-skia-generator.py" -o "$project/skia-sources.json")#!/usr/bin/env python3# Copyright © SixtyFPS GmbH <info@slint.dev># SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
"""Turn the Skia revision that skia-bindings pins into flatpak-builder sources.
Usage: flatpak-skia-generator.py [-o skia-sources.json] [--dest deps/skia-src]"""
import jsonimport reimport subprocessimport sysimport urllib.request
flags = dict(zip(sys.argv[1::2], sys.argv[2::2]))output = flags.get("-o", "skia-sources.json")dest = flags.get("--dest", "deps/skia-src")
def fetch(url): return urllib.request.urlopen(url).read().decode()
cargo = ["cargo", "metadata", "--format-version", "1", "--locked"]packages = json.loads(subprocess.check_output(cargo))["packages"]bindings = [p for p in packages if p["name"] == "skia-bindings"]if not bindings: sys.exit("no skia-bindings; is the renderer-skia feature enabled?")tag = bindings[0]["metadata"]["skia"]print(f"skia-bindings {bindings[0]['version']}, skia fork tag {tag}", file=sys.stderr)
raw = f"https://raw.githubusercontent.com/rust-skia/skia/{tag}"
# Skia's DEPS is Python, listing every checkout its own build expectsns = {"Var": lambda name: ns["vars"][name]}exec(fetch(f"{raw}/DEPS"), ns) # noqa: S102 -- evaluating DEPS is the point
fork = "https://github.com/rust-skia/skia.git"sources = [{"type": "git", "url": fork, "tag": tag, "dest": dest}]for path, spec in sorted(ns["deps"].items()): if not isinstance(spec, str) or "emsdk" in path: continue # cipd packages and the wasm-only emsdk are not needed url, _, commit = spec.partition("@") assert commit, f"DEPS entry {path} has no pinned commit: {spec}" sources.append( { "type": "git", "url": url, "commit": commit, "dest": f"{dest}/{path}", "disable-submodules": True, } )
with open(output, "w") as f: json.dump(sources, f, indent=4) f.write("\n")print(f"wrote {output} ({len(sources)} sources)", file=sys.stderr)
# Skia records the gn revision its own CI builds with; print it so the gn# module in the manifest can follow along when the Skia pin movesgn = re.search(r"rev = '(\w{40})'", fetch(f"{raw}/bin/fetch-gn"))if gn: print(f"skia pins gn revision {gn.group(1)}", file=sys.stderr)Skia 使用 gn 进行配置,而 SDK 并不附带这个构建工具;它使用 clang 而不是 SDK 的 gcc 进行编译:
# ...
sdk-extensions: - org.freedesktop.Sdk.Extension.rust-stable # clang, and the libclang that Skia's bindings generator loads - org.freedesktop.Sdk.Extension.llvm20
# Applies to every module, so that both gn and Skia find clangbuild-options: append-path: /usr/lib/sdk/rust-stable/bin:/usr/lib/sdk/llvm20/bin
# gn is only needed to build Skia, so keep it out of the finished applicationcleanup: - /bin/gn
modules: - name: gn buildsystem: simple build-commands: - python3 build/gen.py --out-path=out --allow-warnings - ninja -C out gn - install -Dm0755 out/gn ${FLATPAK_DEST}/bin/gn sources: - type: git url: https://gn.googlesource.com/gn.git # The generator prints the revision Skia itself uses commit: b2afae122eeb6ce09c52d63f67dc53fc517dbdc8 # gn stamps its version from a tag, which a shallow clone leaves behind disable-shallow-clone: true
- name: slint-cpp # ... config-opts: # ... - -DSLINT_FEATURE_RENDERER_SKIA=ON build-options: env: # ... # Pointing the build at the prepared Skia sources is what makes it # compile them instead of downloading anything SKIA_SOURCE_DIR: /run/build/slint-cpp/deps/skia-src LIBCLANG_PATH: /usr/lib/sdk/llvm20/lib # Use the gn built above rather than the one Skia would fetch SKIA_GN_COMMAND: /app/bin/gn sources: # ... - skia-sources.json这些环境和源代码属于构建 Slint 的模块,而不属于你的应用程序。
Slint 的 CMake 会在 llvm20 扩展添加的路径上找到 Skia 所需的 clang,因此不需要再额外指向它。
图标与桌面元数据
Section titled “图标与桌面元数据”要让你的应用程序出现在启动器中,请编写一个 .desktop 文件并提供图标。
在本例中,桌面条目如下所示:
[Desktop Entry]# The version of the desktop entry specification this file follows, not the# version of your applicationVersion=1.0Type=ApplicationTerminal=false# This should be the same as the binary specified in the `command` section# of your build `.yaml`Exec=your-app# This should be the human-readable name of your applicationName=Your App# This should be the same as your Flatpak package ID, see below for detailsIcon=com.yourorganization.YourApp使用 Freedesktop SDK 附带的 desktop-file-validate 检查该文件:
flatpak run --command=desktop-file-validate org.freedesktop.Sdk//25.08 com.yourorganization.YourApp.desktop从 build-commands 中安装它:
# ...build-commands: # ... - install -Dm0644 path/to/${FLATPAK_ID}.desktop ${FLATPAK_DEST}/share/applications/${FLATPAK_ID}.desktop # ...Flatpak 会在以下目录中查找图标:
${FLATPAK_DEST}/share/icons/hicolor/WIDTHxHEIGHT/apps/中的.png文件,其中WIDTHxHEIGHT与图像(最大 512)的宽高相匹配${FLATPAK_DEST}/share/icons/hicolor/scalable/apps/中的.svg文件
无论你选择哪种格式,都应按照你的 Flatpak 包 ID 命名文件,并从 build-commands 中安装它:
# ...build-commands: # ... # Replace 512x512 with the width and height of your icon - install -Dm0644 path/to/icon.png ${FLATPAK_DEST}/share/icons/hicolor/512x512/apps/${FLATPAK_ID}.png # ..or... - install -Dm0644 path/to/icon.svg ${FLATPAK_DEST}/share/icons/hicolor/scalable/apps/${FLATPAK_ID}.svg # ...元信息(Metainfo)
Section titled “元信息(Metainfo)”最后,你的包需要一个 .metainfo.xml 文件。
包管理器和 Flathub 会读取它来向用户描述你的应用程序。
完整规范不在本文范围内,因此下面是通过校验所需的最少字段:
<?xml version="1.0" encoding="UTF-8" ?><component type="desktop-application"> <!-- This must be the same as your Flatpak package ID --> <id>com.yourorganization.YourApp</id>
<name>Your App</name> <summary>A short line describing what your application does</summary>
<categories> <category>Development</category> </categories>
<keywords> <keyword>development</keyword> </keywords>
<developer id="com.yourorganization"> <name>Your Organization</name> </developer>
<icon type="stock">com.yourorganization.YourApp</icon>
<metadata_license>MIT</metadata_license> <project_license>MIT</project_license>
<description> <p> A paragraph about your application. Software centers show this underneath its name, so write a sentence or two rather than repeating the summary above. </p> </description>
<url type="homepage">https://slint.dev/</url>
<!-- The name of your .desktop file, including the extension --> <launchable type="desktop-id">com.yourorganization.YourApp.desktop</launchable>
<!-- Required by Flathub. `oars-1.1` with no attributes declares that your application has nothing to disclose --> <content_rating type="oars-1.1"/>
<releases> <release version="1.0" date="2026-07-07"/> </releases></component>在构建之前,使用 Freedesktop SDK 中的 appstreamcli 校验该文件:
flatpak run --command=appstreamcli org.freedesktop.Sdk//25.08 validate --no-net com.yourorganization.YourApp.metainfo.xml像桌面条目和图标一样,从 build-commands 中安装它:
# ...build-commands: # ... - install -Dm0644 path/to/${FLATPAK_ID}.metainfo.xml ${FLATPAK_DEST}/share/metainfo/${FLATPAK_ID}.metainfo.xml # ...构建文件是零散地逐步展开的,因此这里给出完整且不带注释的版本,可供复制和调整。
它假设桌面条目、图标和 metainfo 与清单一起位于项目根目录。
在构建之前提交它们:git 源代码打包的是仓库所保存的内容,而不是你的工作树。
id: com.yourorganization.YourApp
runtime: org.freedesktop.Platformruntime-version: '25.08'
command: your-app
sdk: org.freedesktop.Sdk
sdk-extensions: - org.freedesktop.Sdk.Extension.rust-stable - org.freedesktop.Sdk.Extension.llvm20
finish-args: - --device=dri - --share=ipc - --socket=wayland - --socket=fallback-x11
cleanup: - /bin/gn
build-options: append-path: /usr/lib/sdk/rust-stable/bin:/usr/lib/sdk/llvm20/bin
modules: - name: gn buildsystem: simple build-commands: - python3 build/gen.py --out-path=out --allow-warnings - ninja -C out gn - install -Dm0755 out/gn ${FLATPAK_DEST}/bin/gn sources: - type: git url: https://gn.googlesource.com/gn.git commit: b2afae122eeb6ce09c52d63f67dc53fc517dbdc8 disable-shallow-clone: true
- name: your-app buildsystem: simple build-options: env: CARGO_HOME: /run/build/your-app/cargo CARGO_NET_OFFLINE: 'true' SKIA_SOURCE_DIR: /run/build/your-app/deps/skia-src LIBCLANG_PATH: /usr/lib/sdk/llvm20/lib SKIA_GN_COMMAND: /app/bin/gn build-commands: - cargo --offline fetch --manifest-path Cargo.toml --verbose - cargo build --release --offline - install -Dm0755 target/release/your-app ${FLATPAK_DEST}/bin/your-app - install -Dm0644 ${FLATPAK_ID}.desktop ${FLATPAK_DEST}/share/applications/${FLATPAK_ID}.desktop - install -Dm0644 icon.png ${FLATPAK_DEST}/share/icons/hicolor/512x512/apps/${FLATPAK_ID}.png - install -Dm0644 ${FLATPAK_ID}.metainfo.xml ${FLATPAK_DEST}/share/metainfo/${FLATPAK_ID}.metainfo.xml sources: - type: git path: ./ branch: HEAD - cargo-sources.json - skia-sources.json对于 FemtoVG 渲染器,请去掉 llvm20 扩展、gn 模块、cleanup 条目、三个 Skia 环境变量,以及 skia-sources.json。
id: com.yourorganization.YourApp
runtime: org.freedesktop.Platformruntime-version: '25.08'sdk: org.freedesktop.Sdksdk-extensions: - org.freedesktop.Sdk.Extension.rust-stable
command: your-app
finish-args: - --device=dri - --share=ipc - --socket=wayland - --socket=fallback-x11
build-options: append-path: /usr/lib/sdk/rust-stable/bin
modules: - name: slint-cpp buildsystem: cmake-ninja subdir: api/cpp build-options: env: CARGO_HOME: /run/build/slint-cpp/cargo CARGO_NET_OFFLINE: 'true' config-opts: - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_INSTALL_LIBDIR=lib - -DFETCHCONTENT_SOURCE_DIR_CORROSION=/run/build/slint-cpp/corrosion - -DSLINT_FEATURE_INTERPRETER=OFF - -DSLINT_FEATURE_TESTING=OFF sources: - type: git url: https://github.com/slint-ui/slint.git # The revisions printed above commit: <slint revision> - type: git url: https://github.com/corrosion-rs/corrosion.git commit: <corrosion revision> dest: corrosion - cargo-sources.json
- name: your-app buildsystem: simple build-commands: - cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=/app - cmake --build build - install -Dm0755 build/your-app ${FLATPAK_DEST}/bin/your-app - install -Dm0644 ${FLATPAK_ID}.desktop ${FLATPAK_DEST}/share/applications/${FLATPAK_ID}.desktop - install -Dm0644 icon.png ${FLATPAK_DEST}/share/icons/hicolor/512x512/apps/${FLATPAK_ID}.png - install -Dm0644 ${FLATPAK_ID}.metainfo.xml ${FLATPAK_DEST}/share/metainfo/${FLATPAK_ID}.metainfo.xml sources: - type: git path: ./ branch: HEAD清单、桌面条目、图标和 metainfo 都就绪后, 构建包并为你自己的用户安装它:
flatpak-builder --user --install --force-clean --install-deps-from=flathub \ build-dir com.yourorganization.YourApp.ymlbuild-dir 是 flatpak-builder 填充的临时目录,
--force-clean 会先清空它。
--install-deps-from=flathub 会在运行时和 SDK 缺失时获取它们。
首次构建会下载几 GB 内容并编译每一个依赖项,
之后的构建会复用 .flatpak-builder 中的缓存。
请把该目录连同生成的源代码一起加入你的 .gitignore。
按照用户将采用的方式运行它:
flatpak run com.yourorganization.YourApp要把包交给别人, 可以将其导出到一个仓库,然后把该仓库转换为单个文件:
flatpak-builder --user --force-clean --repo=repo build-dir com.yourorganization.YourApp.ymlflatpak build-bundle repo com.yourorganization.YourApp.flatpak com.yourorganization.YourApp \ --runtime-repo=https://dl.flathub.org/repo/flathub.flatpakrepo使用 flatpak install ./com.yourorganization.YourApp.flatpak 安装结果。
一个 bundle 只包含你的应用程序本身,
因此 --runtime-repo 会告诉另一台机器到何处获取运行时。
它也是一份快照:flatpak update 无法更新从 bundle 安装的应用程序。
要发布更新,请通过 HTTPS 提供 repo 目录,并让你的用户将其添加为远程仓库。
© 2026 SixtyFPS GmbH