Building an xdg-app – part 3

Welcome back to this multi-part tutorial in how to create xdg-app applications. In part 2 we built a an xdg-app for gnome-dictionary. However, if you look closely at the commands we used you will set not much what we did was specific to this application.

In fact, the only things related to gnome-dictionary are the:

  • application id
  • source url
  • binary name
  • necessary permissions

Why is this?

It turns out that most open source applications are built in very similar ways. One can even consider this an API for building modules. And if some module does not conform to this API, then it is easy to change the upstream to conform, or if upstream is not interested, apply a local patch.

The xdg-app-builder tool that ships with xdg-app is based on this idea. You describe your application, and the modules you want to build into it, and then xdg-app-builder takes care of calling the lower-level xdg-app build commands for you.

The equivalent of what we did in part 2 is this json:

{
  "app-id": "org.gnome.Dictionary",
  "runtime": "org.gnome.Platform",
  "runtime-version": "3.20",
  "sdk": "org.gnome.Sdk",
  "command": "gnome-dictionary",
  "finish-args": [ 
     "--socket=x11", 
     "--share=network"  
  ],
  "modules": [
    {
      "name": "gnome-dictionary",
      "sources": [
        {
          "type": "archive",
          "url": "https://download.gnome.org/sources/gnome-dictionary/3.20/gnome-dictionary-3.20.0.tar.xz",
          "sha256": "efb36377d46eff9291d3b8fec37baab2355f9dc8bc7edb791b6a625574716121"
        }
      ]
    }
  ]
}

If you put this in a file called org.gnome.Dictionary.json you can build and export the app using:

$ xdg-app-builder --repo=repo appdir3 org.gnome.Dictionary.json

And to test this you use:

$ xdg-app --user update org.gnome.Dictionary
$ xdg-app run org.gnome.Dictionary

So the above commands downloaded the files, initialized the build dir, built the modules, finished the app and exported it to the repo. Just like we did before.

However, even for this simple file it did a lot of other nice things too.

  • It verified the sha256 checksum of the downloaded tarball
  • It built all sources in a fixed location (in /run/build) to ensure more repeatable builds.
  • It ran the builds without access to any part of the host filesystem, other than the directory with the extracted sources. This means less chance of the build machine details affecting the build.
  • It automatically extracted all the debug information from the installed binaries into separate files, and these were commited to a separately installable runtime called org.gnome.Dictionary.Debug.
  • Translations were also extracted to separately installable runtimes called org.gnome.Dictionary.Locale.$lang
  • It cached each stage of the build, so that if you need to rebuild the app only the modules that have changed will be rebuilt.

Other than this xdg-app-builder has a lot of useful features. The obvious one is that you can build multiple modules into the application, and you can have multiple sources for each module. Sources can be of several types. Currently it supports: archive (.tar, .zip), git, bzr, patch files, and just running shell commands.

There is also a cleanup phase that happens after the build. This phase lets you remove things that was added during the build, that will not be needed during runtime. For instance, you can remove headers, development docs and similar things here. xdg-app-builder supports two properties for this. First a list of filename patterns, and secondly a list of commands to run during the cleanup phase.

"cleanup": [ "/include", "/bin/foo-*", "*.a" ]
"cleanup-commands": [ "sed s/foo/bar/ /bin/app.sh" ]

Additionally, the cleanup property can be set on a per-module basis, and will then only match filenames that were created by that particular module.

Another special feature is the rename-icon, rename-desktop-file and rename-appdata properties which lets you rename these kinds of files to match the application id. You have to do this because upstream files don’t use the application id in the name, which is not allowed by xdg-app during export.

The nightly build of the gnome applications all are built using xdg-app-builder, and you can get a lot of example json files there, for instance a complete version of gnome-dictionary built from git.  I also have a few more examples here.

For detailed documentations on all xdg-app-builder properties. See the man page for xdg-app builder.

That is it for today. Next time we will take a look at some details about the xdg-app sandbox.

4 thoughts on “Building an xdg-app – part 3”

  1. Have you considered to create a Tutorial to create new Runtimes and its SDK?

    This is because, I have a set of libraries not included in org.gnome.Sdk, but required by may application.

    First I tried to create a bundle using JSON file with the sources of my libraries but I found libgee failing to be build runtime with following message:

    stripping /home/despinosa/Proyectos/PKG/pwmc-cfdi/sdk/usr/lib/libgee-0.8.so.2.5.1 to /home/despinosa/Proyectos/PKG/pwmc-cfdi/sdk/usr/lib/debug/usr/lib/libgee-0.8.so.2.5.1.debug
    error: Fails to execute child process «eu-strip» (No file or directory exists)

    1. Daniel: At some point I will probably talk about creating runtimes, but at the moment I’d rather not for exactly this reason. The first idea you had when you had any issue with building your app is to create a new runtime. But that is wrong, as an app developer you should never ever create your own runtime. Its like having a package dependency issue and then choosing to build your own distro to fix it.

      Runtimes are *not* the same as package dependencies. You should only create a runtime if your idea of fun is to stay up all weekend doing glibc security errata.

      xdg-app is a bundling system. If you need anything not in the runtime you should bundle it, not create a different runtime. Having a custom runtime for your app, or just having more than a few runtimes in the entire linux echosystem breaks the entire idea of the app/runtime split, which is that a few core people maintain the runtime, and the apps are independent of that.

      Now, as to your actual build failure. You just need to install whatever package has eu-strip in it on your system. On fedora this is elfutils.

      1. Thanks for your reply. I’ve installed elfutils and it works!

        But I think this should be a dependency when building, or at least point in a message that issue to help others to use xdg-app-builder at first shot!

        Many thanks for your effort.

Leave a Reply to alexl Cancel reply

Your email address will not be published. Required fields are marked *