Neil's Blog.

Hello, Flatpak! A better* guide

This is a very simple and abridged guide for making Flatpak packages, with special focus towards developers without much packaging experience. This guide was also written from the complaints a friend and I had towards the existing introduction section of the Flatpak Documentation, which seems to skip over some things I deemed important.

This guide will assume you already have a working project on some git repository. The one used here will be based around this basic demo program.

This guide also assumes you have flatpak and flatpak-builder already installed, which are already available on most package managers.

1. Installing the SDK

Flatpak has "Platforms" or "Runtimes", which are a set of common libraries you link against. It also has the concept of SDKs which are a bunch of development files you might need to properly build your programs, such as headers and compilers.

In this example, we'll use the Freedesktop 22.08 Runtime and SDK:

flatpak install flathub org.freedesktop.Platform//22.08 org.freedesktop.Sdk//22.08

It contains all sorts of useful things (like SDL2 which is necessary for the provided demo program.) You can check what it includes here. There's also a couple more runtimes you probably should use if your program uses GTK or QT.

If you dont find the previous library list complete enough, you can check out the FAQ for some juicy valuable information around this ;)

2. Writing a manifest

Manifests are just files that specify what your program is, what it needs and how to build it. They can be written in JSON and YAML, but I'll be using JSON for this particular example.

> 1. Setting things up

Create a new folder, then a JSON file named as RDNN notation of your project, I'll be going with io.github.darltrash.demo.json. It has to contain something like:

{
    "id": "io.github.darltrash.demo",
    "runtime": "org.freedesktop.Platform",
    "runtime-version": "22.08",
    "sdk": "org.freedesktop.Sdk"
}

This will be our manifest.

> 2. Container permissions

Flatpak works with containers, which allow for programs to be sandboxed and benefit the user, but they require developers to handle the resources and explicitly tell Flatpak what host resources will their programs use.

Lets take a look at this snippet:

"finish-args": [
    "--device=dri",
    "--socket=x11",
    "--socket=wayland",
    "--share=ipc"
]

finish-args are just explicit definitions for container settings, just a way of telling the container to unlock certain things for the program to work properly.

There's some other permissions we can use, as provided here.

We will add this to our manifest and it should be enough for purely graphical, hardware accelerated programs.

> 3. Actually building the thing 👍

The Flatpak build system works with modules, which are simple build and setup instructions, for either your software or necessary dependencies.

We'll define our main module like this:

"modules": [
    {
        "name": "demo",
        "buildsystem": "simple",

        "sources": [
            {
                "type": "git",
                "url": "https://github.com/darltrash/sdl2-demo",
                "commit": "766db3652802e69fa8b8e33a42f5f30efcca37e6"
            }
        ],

        "build-commands": [
            "make release",
            "install -D demo /app/bin/demo"
        ]
    }
]

Now, I wont go into too much detail about the available build systems, nor the available source types, but can check them out here.

We're using the "simple" build system as it allows us to simply just tell the Flatpak builder to execute certain commands inside an isolated environment.

build-commands, in this example, contains two commands:

3. Running!

Now I'll one last line to my manifest file:

"command": "demo"

This will tell Flatpak to execute /app/bin/demo as the entry point for our program.

Now to actually build and run this thing, we need to run this:

flatpak-builder --user --install build-dir/ io.github.darltrash.demo.json --force-clean
flatpak run io.github.darltrash.demo

I'll go over those spooky commands and try to explain them:

If everything goes right, it should display a funky (and buggy) DVD screen-saver thing!! (trust me, the bugginess is because of my sheer incompetence towards creating basic demo examples...)

But... this project is missing something really important! It's missing a .desktop file, which means that our program will NOT show up on the programs menu, So we'll make one!

Create a new file, next to our manifest, named like io.github.darltrash.demo.desktop, like our manifest but with the .desktop extension instead, and make it look something like this:

[Desktop Entry]
Name=Flatpak Demo
Comment=A simple Flatpak demo.
Exec=demo
Type=Application

There's much more you can do with a .desktop file (ex. have icons) but I wont go too in depth for that, you can check the spec here.

Now we'll change our manifest's main module to include our new file and "install" it in it's right place.

"sources": [
    ...
    {
        "type": "file",
        "path": "io.github.darltrash.demo.desktop"
    }
],

"build-commands": [
    ...
    "install -D io.github.darltrash.demo.desktop /app/share/applications/io.github.darltrash.demo.desktop"
]

/app/share/applications/ (analog to /usr/share/applications) being a folder that contains .desktop files that must be shown in the form of programs to the user, in their programs menu.

And there we have it! Now a program named "Flatpak Demo" should show up on your program menu!

4. Meet the .flatpak file!

.flatpak files (Also called Single File Bundles) are similar to what a zipped program would be in Windows, except that Flatpak gets to handle all the rough details, like dependencies and installation

.flatpak files are nice because they are:

Now, let's make one!

flatpak-builder --user --install build-dir/ io.github.darltrash.demo.json --force-clean
flatpak build-export export/ build-dir/
flatpak build-bundle export/ our-file.flatpak io.github.darltrash.demo

Let's go over some of those commands:

Now you should have a file named our-file.flatpak which you can install like:

flatpak install our-file.flatpak

or by using a GUI Flatpak client, such as Gnome Software which comes preinstalled in all major GNOME-based distros, such as Ubuntu and Fedora.

And that's it! We've done it! Now you can share this .flatpak file anywhere you want; through email, an instant chat messenger, on an USB drive, some game publishing platform, by pigeon, you name it!

If you're interested on reading more about Single File Bundles, check out the official documentation.

I've published all this cool stuff in a repo, here, so you can check it out by yourself :)

FAQ:

Can I make the manifest just build local files?

Yes! In the same way you pulled the .desktop file, you can pull an entire folder if necessary, You would only need to add something like this to your sources:

{
    "type": "dir",
    "path": "whatever/directory/you/like"
}

TIP: If your local file or directory is an archive, you can replace type by archive instead of dir so Flatpak can handle the decompression for you.

This is only advised for local development, Because Flathub will require your manifest to have it's own repository, as they will need to clone it for them to be able to publish it.

Can I use an URL instead of a GIT repository?

Yes! You can include something like this in your sources:

{
    "type": "file",
    "url": "https://whatever.weird.url.you.have.com/",
    "sha256": "766db3652802e69fa8b8e33a42f5f30efcca37e6"
}

Which will download whatever file is at URL, and check it's checksum.

The sha256 part is necessary to ensure that the file being obtained is 100% legitimate, you can also use sha1 or sha512.

TIP: Again, you can also get it to download and automatically decompress archives, by replacing type by archive instead of file.

How can I get a more detailed list of what's inside the SDK?

You will need to install it first, then you'll have to run this command

flatpak info -l org.freedesktop.Sdk//22.08

It will give you the exact location of all the files that our SDK contains, you can change the SDK by anything you'd like, this also works for Platforms, Runtimes, Applications, you name it!

Inside of said folder, you'll find a folder aptly named files which contains a semi-traditional linux filesystem structure, specifically mimicking /usr/.

Can my entry point be a script that runs something else?

Yes, easily, you can add something like this to your sources:

{
    "type": "script",
    
    "commands": [
        "/app/bin/your_program --here"
    ],

    "dest-filename": "your_entry_point_here"
}

You can also just include a simple script as a file, and set that as your entry point.

TIP: Remember that your .desktop file will have to reflect this!

Why doesn't my program show up in the programs menu, but runs in the terminal?

A big possible reason is that you have a malformed .desktop file, where it either has the wrong setup and/or syntax, or it's trying to call your entry point incorrectly (or straight up calling something else); In that case, try out desktop-file-validate.

Another reason is that you did not put the file where it belongs, which is /app/share/applications/ and not /usr/share/applications since Flatpak replaces /usr with /app.

SDL2 won't work because it needs pulseaudio or something like that?:

That's because SDL2 by default also has an audio module that uses the Pulseaudio protocol, you can add the following to your finish-args:

"--socket=pulseaudio"

This will enable Pulseaudio on your program's container/sandbox, and thus, also Pipewire.

I recommend also checking out the other options if you have any other issues with either devices or necessary permissions not being granted.

How can I publish my programs on Flathub?

Sadly, I haven't written that part yet! But you can check the official documentation for that.

If you found this guide valuable on it's contents, you might be interested on a posible guide coming for that in the future! (No promises, though.)

Thanks for reading! ✨

I hope this has helped you! because I wrote this document purely because I also tried to make a Flatpak package once, and I only found disdain and suffering.

Huge thanks to the following people:

(Please, do not contact those people online, they have their own problems lol)

#flatpak #linux #packaging