Packaging the Application

The app directory contains a com.example.simple_weather.json manifest file for use with Flatpak. This describes where the application source code can be obtained from, how the application is built, the dependencies that need to be built with it, and the permissions it needs when it is run.

Writing the Manifest

The manifest for this simple application is short, so we include the whole file here to provide an overview before looking at the details:

{
    "app-id": "com.example.simple_weather",
    "runtime": "org.gnome.Platform",
    "runtime-version": "3.34",
    "sdk": "org.gnome.Sdk",
    "command": "simple-weather",
    "finish-args": [
        "--socket=wayland",
        "--share=network"
    ],
    "modules": [
        {
            "name": "python3-setuptools",
            "buildsystem": "simple",
            "build-commands": [
                "pip3 install --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} setuptools"
            ],
            "sources": []
        },
        {
            "name": "python3-setuptools_scm",
            "buildsystem": "simple",
            "build-commands": [
                "pip3 install --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} setuptools_scm"
            ],
            "sources": [
                {
                    "type": "file",
                    "url": "https://files.pythonhosted.org/packages/54/85/514ba3ca2a022bddd68819f187ae826986051d130ec5b972076e4f58a9f3/setuptools_scm-3.2.0.tar.gz",
                    "sha256": "52ab47715fa0fc7d8e6cd15168d1a69ba995feb1505131c3e814eb7087b57358"
                }
            ]
        },
        {
            "name": "python3-python-dateutil",
            "buildsystem": "simple",
            "build-commands": [
                "tar zxf six-1.12.0.tar.gz",
                "cd six-1.12.0; python3 setup.py build; python3 setup.py install --prefix=${FLATPAK_DEST}",
                "tar zxf python-dateutil-2.8.0.tar.gz",
                "cd python-dateutil-2.8.0; python3 setup.py build; python3 setup.py install --prefix=${FLATPAK_DEST}"
            ],
            "sources": [
                {
                    "type": "file",
                    "url": "https://files.pythonhosted.org/packages/dd/bf/4138e7bfb757de47d1f4b6994648ec67a51efe58fa907c1e11e350cddfca/six-1.12.0.tar.gz",
                    "sha256": "d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
                },
                {
                    "type": "file",
                    "url": "https://files.pythonhosted.org/packages/ad/99/5b2e99737edeb28c71bcbec5b5dda19d0d9ef3ca3e92e3e925e7c0bb364c/python-dateutil-2.8.0.tar.gz",
                    "sha256": "c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e"
                }
            ]
        },
        {
            "name": "python3-requests",
            "buildsystem": "simple",
            "build-commands": [
                "pip3 install --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} requests"
            ],
            "sources": [
                {
                    "type": "file",
                    "url": "https://files.pythonhosted.org/packages/b1/53/37d82ab391393565f2f831b8eedbffd57db5a718216f82f1a8b4d381a1c1/urllib3-1.24.1.tar.gz",
                    "sha256": "de9529817c93f27c8ccbfead6985011db27bd0ddfcdb2d86f3f663385c6a9c22"
                },
                {
                    "type": "file",
                    "url": "https://files.pythonhosted.org/packages/52/2c/514e4ac25da2b08ca5a464c50463682126385c4272c18193876e91f4bc38/requests-2.21.0.tar.gz",
                    "sha256": "502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e"
                },
                {
                    "type": "file",
                    "url": "https://files.pythonhosted.org/packages/ad/13/eb56951b6f7950cadb579ca166e448ba77f9d24efc03edd7e55fa57d04b7/idna-2.8.tar.gz",
                    "sha256": "c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407"
                },
                {
                    "type": "file",
                    "url": "https://files.pythonhosted.org/packages/fc/bb/a5768c230f9ddb03acc9ef3f0d4a3cf93462473795d18e9535498c8f929d/chardet-3.0.4.tar.gz",
                    "sha256": "84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"
                },
                {
                    "type": "file",
                    "url": "https://files.pythonhosted.org/packages/55/54/3ce77783acba5979ce16674fc98b1920d00b01d337cfaaf5db22543505ed/certifi-2018.11.29.tar.gz",
                    "sha256": "47f9c83ef4c0c621eaef743f133f09fa8a74a9b75f037e8624f83bd1b6626cb7"
                }
            ]
        },
        {
            "name" : "libhandy",
            "buildsystem" : "meson",
	    "builddir": true,
	    "config-opts": [
		"-Dglade_catalog=disabled",
		"-Dexamples=false",
		"-Dtests=false",
		"-Dvapi=false"
	    ],
            "sources" : [
                {
                  "type" : "git",
                  "url" : "https://source.puri.sm/Librem5/libhandy.git"
                }
            ]
        },
        {
            "name": "simple_weather",
            "buildsystem": "meson",
            "builddir": true,
            "sources": [
                {
                    "type": "dir",
                    "path": "."
                }
            ]
        }
    ]
}

We examine the three main parts of the manifest individually.

Application Information

In the manifest we record information about the application, including its ID and the command used to run it:

{
    "app-id": "com.example.simple_weather",
    "runtime": "org.gnome.Platform",
    "runtime-version": "3.34",
    "sdk": "org.gnome.Sdk",
    "command": "simple-weather",

The runtime and runtime-version values define precisely which collection of libraries the application needs to run. The corresponding sdk value tells Flatpak which SDK is needed to build the application. When building applications for a GNOME-based platform the corresponding SDK is required.

Permissions

The finish-args list is typically used to state which permissions the application needs. In this case it will need access to the Wayland display server to be able to show a window:

    "finish-args": [
        "--socket=wayland",
        "--share=network"
    ],

The applications also requires access to the network. Other permissions will be required if you want to store and modify settings for your application, access peripherals, and perform other tasks that require the user’s consent.

Modules

The modules list describes the application components (or modules), including any dependencies that need to be bundled with it, in a list of dictionaries. The application’s module follows the entries for the other dependencies:

            "name": "simple_weather",
            "buildsystem": "meson",
            "builddir": true,
            "sources": [
                {
                    "type": "dir",
                    "path": "."
                }
            ]

The name of the application should be unique in the list of modules but can be otherwise freely assigned. We indicate that we are using the Meson build system and instruct Flatpak to use a separate build directory.

After this, we describe where the sources of the application should be obtained from. For many applications we would describe the location of a repository. However, to make things simple, we indicate that the sources are in the same directory as the manifest.

Building the Application

Following the instructions in Cross-Building an Application, we use flatpak-builder to build a flatpak for the application. To do this we need to install the runtime and SDK that the application depends on. These are the same as those mentioned in Setting up Flatpak for GNOME Development except that we need the ones for the aarch64 architecture:

flatpak --user install flathub org.gnome.Platform/aarch64/40 org.gnome.Sdk/aarch64/40

After installing these, build the application with flatpak-builder:

flatpak-builder --arch=aarch64 --repo=myrepo _flatpak com.example.simple_weather.json

The result is stored in the myrepo directory, which is a local repository. It can be exported from the repository as a binary bundle for deployment on the target device. We do this by running flatpak with the build-bundle command, passing the repository, the name of the bundle to create and the application ID:

flatpak build-bundle --arch=aarch64 myrepo app.flatpak com.example.simple_weather

In this case the bundle is written to the app.flatpak file. This can be copied to the phone or development board for installation.

Installing the Application

One way to install the application is to use the flatpak tool on the command line to install the binary bundle. Other more user-friendly ways are also possible.

First of all, copy the bundle to the target device and make it readable by the purism user. Then, log in to the device and ensure that the flathub remote is registered for the user:

flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo

Assuming that the app.flatpak file is in the current directory, install it for the user by running the install command:

flatpak --user install app.flatpak

Flatpak will resolve the dependencies of the bundle using the remote we registered and ask you if you want to install them if they are not already present. It will then install the application itself.

You can run the application using flatpak in the usual way:

flatpak run com.example.simple_weather

When you are finished with the application and want to uninstall it, use the following command:

flatpak uninstall com.example.simple_weather

You can also uninstall the runtime needed by the application, but it may be useful to keep it installed for future use.