-
Notifications
You must be signed in to change notification settings - Fork 945
Linux packaging docs #12670
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Linux packaging docs #12670
Changes from 4 commits
6ada603
65735b3
4569f04
1421ee2
6496575
421142e
3b7dd8f
d6560a6
1e1bcd9
afc4c71
241b720
382f473
d61a06c
91db72e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,302 @@ | ||
| --- | ||
| title: Linux | ||
| description: Package a desktop Slint app for distribution on Linux, using Flatpak | ||
| --- | ||
|
|
||
| {/* cSpell: ignore Flatpaks yourorganization pulseaudio jpegd jpege Metainfo metainfo Flathub launchable */} | ||
|
|
||
| import { Aside } from '@astrojs/starlight/components'; | ||
| import { Tabs, TabItem } from '@astrojs/starlight/components'; | ||
|
|
||
| Linux, unlike other platforms, has countless ways to distribute applications. Each of these has its own pros and cons, different supported distros, etc. For this article, we will focus on [Flatpak](https://flatpak.org/). Here is an incomplete list of the alternatives, with the reason that we think they are less well-suited to our purposes here than Flatpak: | ||
|
|
||
| - Distro-native package managers (`pacman`, `apt`, `dnf`, etc) | ||
| - Requires building and testing your application on many different systems, in particular different versions of host packages such as glibc | ||
| - [Snap](https://snapcraft.io/) | ||
| - Tied to the Canonical ecosystem, usually the best option when distributing a GUI application for Ubuntu and derivatives but far less popular on other distros | ||
| - [AppImage](https://appimage.org/) | ||
| - Less well-supported than Snap and Flatpak, the runtime is not shared between applications so the package size is larger compared to Flatpak and Snap. Additionally, AppImage does not provide sandboxing. Since Slint applications can run seamlessly inside Flatpak/Snap's sandbox, so the increased security of a sandbox doesn't require any tradeoff | ||
|
|
||
| Flatpaks are sandboxed, cross-platform, and they are relatively straightforward to create. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a positive key phrase :) |
||
|
|
||
| <Aside type="note"> | ||
| Your application may come with different trade-offs, and so you may want to make another choice. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could be the box where you could very briefly mention alternatives IMO. |
||
| </Aside> | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| The tools needed are the `flatpak` and `flatpak-builder` tools. Additionally, depending on language, you may need a tool which converts your package manager's lockfile into a set of dependencies that `flatpak-builder` understands. The Flatpak build process is sandboxed, just like Flatpaks themselves, and any tools running inside the build environment do not have network access. Any dependencies that need to be downloaded via the network need to be specified in the Flatpak dependency format. | ||
|
eira-fransham marked this conversation as resolved.
Outdated
|
||
|
|
||
| Lockfile conversion scripts are available for all languages supported by Slint: | ||
|
eira-fransham marked this conversation as resolved.
Outdated
|
||
|
|
||
| - Rust | ||
| - [`cargo`](https://github.com/flatpak/flatpak-builder-tools/tree/master/cargo) | ||
| - NodeJS | ||
| - [`node`](https://github.com/flatpak/flatpak-builder-tools/tree/master/node) - this is the recommended method, supporting `npm`, `yarn` and `pnpm` | ||
| - [`npm`](https://github.com/flatpak/flatpak-builder-tools/tree/master/npm) (if the `node` script does not work) | ||
| - [`yarn`](https://github.com/flatpak/flatpak-builder-tools/tree/master/yarn) (if the `node` script does not work) | ||
| - Deno | ||
| - [`deno`](https://github.com/flatpak/flatpak-builder-tools/tree/master/deno) | ||
| - Python | ||
| - [`pip`](https://github.com/flatpak/flatpak-builder-tools/tree/master/pip) | ||
| - [`poetry`](https://github.com/flatpak/flatpak-builder-tools/tree/master/poetry) | ||
|
|
||
| C++ has no standard, cross-platform package manager, and for C++ projects the only officially-supported method of including dependencies is via vendoring. Bun is supported by Slint, but not by Flatpak. | ||
|
|
||
| ## Creating a build file | ||
|
|
||
| Flatpak build files are named after the package ID. For most projects, the package ID will be `com.yourorganization.YourProject`. For this example, we'll use `com.slint.TestPackage`, meaning that the build script will be named `com.slint.TestPackage.yml`. | ||
|
|
||
| ```yaml | ||
| # The ID, explained above. | ||
| id: com.slint.TestPackage | ||
|
|
||
| # The "runtime" to use. For desktop applications, this will almost always be | ||
| # `org.freedesktop.Platform` | ||
|
Comment on lines
+57
to
+58
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If there's doubt, then I think there's value in explaining it. Otherwise, I think it's better to just state the fact to avoid leaving the reader hanging. Here, I'd just stick to A comment on the version might be more relevant, perhaps with a link where readers can find out what versions exists and if it's worth upgrading.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This remains an open point. |
||
| runtime: org.freedesktop.Platform | ||
| runtime-version: "25.08" | ||
|
|
||
| # This will be explained below | ||
| command: slint-test-package | ||
|
|
||
| # The "sdk" to use. Again, this will almost always be `org.freedesktop.Sdk` | ||
| sdk: org.freedesktop.Sdk | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also needed this:
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I meant to mention that below in the Rust section. Good catch.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On second thought, don't we always need this? For C++ we surely do. For Python and Node.js what's in this template is incomplete. |
||
|
|
||
| # The set of permissions that this application requires | ||
| finish-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 | ||
| ``` | ||
|
|
||
| The permissions specified above are the minimum required for all Slint applications, but in case you require further permissions you can check [Flatpak's official documentation](https://docs.flatpak.org/en/latest/sandbox-permissions.html). Notable permissions are `--share=network` for network access, `--socket=pulseaudio` for audio I/O, and `--allow=bluetooth` for Bluetooth connectivity. | ||
|
|
||
| ## Specifying the build process | ||
|
|
||
| Along with the basic metadata, you will then need to specify your dependencies and build process. This will depend on the language used. | ||
|
|
||
| <Tabs syncKey="dev-language"> | ||
| <TabItem label="Rust" icon="seti:rust"> | ||
|
|
||
| First, you need to run the [`flatpak-cargo-generator.py`](https://github.com/flatpak/flatpak-builder-tools/tree/master/cargo) script, mentioned above. This will create a file named `cargo-sources.json`. | ||
|
|
||
| ```yaml | ||
| 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: slint-test-package | ||
| # 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/slint-test-package/cargo | ||
| CARGO_NET_OFFLINE: "true" | ||
| # This is required for Slint's Skia backend, and should match the source below. | ||
| # With the FemtoVG backend, you can remove this line and the relevant source. | ||
| SKIA_BINARIES_URL: file:///run/build/slint-visual-editor/deps/vendor/skia/skia-binaries-a25a0fdb7d90429aa2d1-x86_64-unknown-linux-gnu-gl-jpegd-jpege-pdf-textlayout-vulkan.tar.gz | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This refers to the visual editor. Subsequent for all the skia related bits, I strongly suggest to leave those out of these instructions for now. There's value in supporting Skia here, but I think that could almost go into a separate section. That said, it's in our interest to support Skia (for our own needs), and for Linux then alternative that I think is easier to support, without the need to hard-code URLs like the above), is to build skia from sources. I think automating that will be easier because instead of the user having to figure out I tried a local build with skia sources (by setting So I see three paths forward:
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My preferred path would be 3, although personally I think this is fine. I give instructions on how to figure out which URL to include. Not that you're suggesting this, but I definitely don't think that leaving it out is an option since Skia is the best-supported renderer. All of those options are viable though, I wouldn't be unhappy with any of them.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've included my instructions, so you get to choose :) |
||
| 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 `slint-test-package`. If you do not need the Skia renderer, you can use | ||
| # `--features backend-winit,renderer-femtovg` and remove the lines related to Skia | ||
| # binaries | ||
| - cargo build --release --offline --features backend-winit,renderer-skia | ||
|
tronical marked this conversation as resolved.
Outdated
|
||
| # 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/slint-test-package ${FLATPAK_DEST}/bin/slint-test-package | ||
| sources: | ||
| - type: git | ||
| # This assumes that this yaml file is in the root of your project. This may not | ||
| # be what you want, see below for some other options. | ||
| path: ./ | ||
| # This should be the current git commit hash, or the git commit hash that you | ||
| # want to build | ||
| commit: 1234deadbeef | ||
| # 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 | ||
| # The below lines (and the `SKIA_BINARIES_URL` environment variable, specified above) | ||
| # are required to use the `renderer-skia` feature. If your application uses | ||
| # `renderer-femtovg`, you can remove it | ||
| - type: file | ||
| url: https://github.com/rust-skia/skia-binaries/releases/download/0.99.0/skia-binaries-a25a0fdb7d90429aa2d1-x86_64-unknown-linux-gnu-gl-jpegd-jpege-pdf-textlayout-vulkan.tar.gz | ||
| dest: deps/vendor/skia | ||
| sha256: 097e78d775c9156dc4b070b9cca7008dbab587513ecb1924baf4cf9620f3119b | ||
| ``` | ||
|
|
||
| As mentioned in the comments above, to use `renderer-skia` you must include the relevant Skia binaries as an explicit dependency. At the time of writing, this is `0.99.0`. You can use the following command to check the version of `skia-safe` in use (requires `jq` to be installed): | ||
|
|
||
| ```bash | ||
| cargo metadata --format-version 1 | jq -er '.packages | .[] | select(.name == "skia-safe").version' | ||
| ``` | ||
|
|
||
| If this is not `0.99.0`, check [the releases page](https://github.com/rust-skia/skia-binaries/tags) for `rust-skia/skia-binaries`, finding the one that has the `x86_64-unknown-linux-gnu` target triple and the `gl-jpegd-jpege-pdf-textlayout-vulkan` feature set. You can also copy the hash and put it in the `sha256` field, mentioned above. | ||
|
|
||
| </TabItem> | ||
| </Tabs> | ||
|
|
||
| ## Icons and desktop metadata | ||
|
|
||
| To ensure that your application shows up in the launcher, you need to create a `.desktop` file, along with an icon file. In our case, this will look like so: | ||
|
eira-fransham marked this conversation as resolved.
Outdated
|
||
|
|
||
| ```ini | ||
| [Desktop Entry] | ||
| Encoding=UTF-8 | ||
| Version=1.0 | ||
| Type=Application | ||
| Terminal=false | ||
| # This should be the same as the binary specified in the `command` section | ||
| # of your build `.yaml` | ||
| Exec=/app/bin/slint-test-package | ||
| # This should be the human-readable name of your application | ||
| Name=Slint Test Package | ||
| # This should be the same as your Flatpak package ID, see below for details | ||
| Icon=com.slint.TestPackage | ||
| ``` | ||
|
|
||
| You then need to add a command that puts this in the correct place to your `build-commands`, like so: | ||
|
tronical marked this conversation as resolved.
|
||
|
|
||
| ```yaml | ||
| # ... | ||
| build-commands: | ||
| # ... | ||
| - install -Dm0644 path/to/${FLATPAK_ID}.desktop ${FLATPAK_DEST}/share/applications/${FLATPAK_ID}.desktop | ||
| # ... | ||
| ``` | ||
|
|
||
| For the icon, you have a few options. Flatpak will search the following folders (here specified as you would in the build script): | ||
|
|
||
| - `.png` files in `${FLATPAK_DEST}/share/icons/hicolor/WIDTHxHEIGHT/apps/`, where `WIDTHxHEIGHT` matches the width and height of your image (up to 512) | ||
| - `.svg` files in `${FLATPAK_DEST}/share/icons/hicolor/scalable/apps/` | ||
|
|
||
| Whether your choose `.png` or `.svg`, the file should be named the same as your Flatpak package ID, and you should add an `install` command to `build-commands` that outputs the file to the correct directory, with the same name as your Flatpak package ID. For example: | ||
|
|
||
| ```yaml | ||
| # ... | ||
| 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 | ||
|
|
||
| Finally, Flatpak expects your package to include a `.metainfo.xml` file, which specifies some Flatpak-specific metadata used by the package manager and by Flathub. The [full specification of this file](https://docs.flathub.org/docs/for-app-authors/metainfo-guidelines) is out of scope for this document, but below is the minimum required fields that must be specified in order for validation to succeed: | ||
|
|
||
| ```xml | ||
| <?xml version="1.0" encoding="UTF-8" ?> | ||
| <component type="desktop-application"> | ||
| <id>com.slint.TestPackage</id> | ||
|
|
||
| <name>Slint Test Package</name> | ||
| <summary>Example package to explain how to create a Flatpak for a Slint project</summary> | ||
|
|
||
| <categories> | ||
| <category>Development</category> | ||
| </categories> | ||
|
|
||
| <keywords> | ||
| <keyword>development</keyword> | ||
| </keywords> | ||
|
|
||
| <developer id="com.slint"> | ||
| <name>Slint</name> | ||
| </developer> | ||
|
|
||
| <icon type="stock">com.slint.TestPackage</icon> | ||
|
|
||
| <metadata_license>MIT</metadata_license> | ||
| <project_license>MIT</project_license> | ||
|
|
||
| <description> | ||
| <p>Example package to explain how to create a Flatpak for a Slint project</p> | ||
| </description> | ||
|
|
||
| <url type="homepage">https://slint.dev/</url> | ||
|
|
||
| <launchable | ||
| type="desktop-id" | ||
| >com.slint.TestPackage</launchable> | ||
|
|
||
| <screenshots> | ||
| <!-- | ||
| Flathub requires at least one screenshot, but an empty screenshot section | ||
| is allowed when building locally. | ||
| --> | ||
| </screenshots> | ||
|
|
||
| <releases> | ||
| <release version="1.0" date="2026-07-07"> | ||
| <description translatable="no"> | ||
| </description> | ||
| </release> | ||
| </releases> | ||
| </component> | ||
| ``` | ||
|
|
||
| ## Putting it all together | ||
|
|
||
| The build `.yaml` was specified in fragments, so below is a complete example package manifest with the annotations removed, that you can copy and modify for your own project. | ||
|
|
||
| <Tabs syncKey="dev-language"> | ||
| <TabItem label="Rust" icon="seti:rust"> | ||
|
|
||
| ```yaml | ||
| id: com.slint.TestPackage | ||
|
|
||
| runtime: org.freedesktop.Platform | ||
| runtime-version: "25.08" | ||
|
|
||
| command: slint-test-package | ||
|
|
||
| sdk: org.freedesktop.Sdk | ||
|
|
||
| finish-args: | ||
| - --device=dri | ||
| - --share=ipc | ||
| - --socket=wayland | ||
| - --socket=fallback-x11 | ||
|
|
||
| modules: | ||
| - name: slint-test-package | ||
| buildsystem: simple | ||
| build-options: | ||
| append-path: /usr/lib/sdk/rust-stable/bin | ||
| env: | ||
| CARGO_HOME: /run/build/slint-test-package/cargo | ||
| CARGO_NET_OFFLINE: "true" | ||
| SKIA_BINARIES_URL: file:///run/build/slint-visual-editor/deps/vendor/skia/skia-binaries-a25a0fdb7d90429aa2d1-x86_64-unknown-linux-gnu-gl-jpegd-jpege-pdf-textlayout-vulkan.tar.gz | ||
| build-commands: | ||
| - cargo --offline fetch --manifest-path Cargo.toml --verbose | ||
| - cargo build --release --offline --features backend-winit,renderer-skia | ||
| - install -Dm0755 target/release/slint-test-package ${FLATPAK_DEST}/bin/slint-test-package | ||
| sources: | ||
| - type: git | ||
| path: ./ | ||
| commit: 1234deadbeef | ||
| - cargo-sources.json | ||
| - type: file | ||
| url: https://github.com/rust-skia/skia-binaries/releases/download/0.99.0/skia-binaries-a25a0fdb7d90429aa2d1-x86_64-unknown-linux-gnu-gl-jpegd-jpege-pdf-textlayout-vulkan.tar.gz | ||
| dest: deps/vendor/skia | ||
| sha256: 097e78d775c9156dc4b070b9cca7008dbab587513ecb1924baf4cf9620f3119b | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| </Tabs> | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're in the guide section, I don't think it's really necessary to justify our choice of Flatpak. A short reference to the alternatives is fine IMO. We're not competing with anyone here :)