The Expandables – snapcraft extensions and the secret code
by Igor Ljubuncic on 18 September 2020
If you’re a snap developer, you know that snap development is terribly easy. Or rather complex and difficult. Depending on your application code and requirements, it can take a lot of effort putting together the snapcraft.yaml file from which you will build your snap. One of our goals is to make snap development practically easier and more predictable for everyone. To that end, we created a framework of snap extensions, designed to make the snap journey simpler and more fun.
In a nutshell, extensions abstract away a range of common code declarations you would normally put in your snapcraft.yaml file. They help developers avoid repetitive tasks, reduce the knowledge barrier needed to successfully build snaps, offer a common template for application builds, and most importantly, save time and effort. But what if you want – or need – to know what is behind the abstraction?
Expand your horizons, expand your extensions
Let’s examine a real-life example. Just a few weeks ago, Jonathan Riddell and I did a workshop on how to build snaps during KDE Akademy. We demonstrated with KBlocks, and the snapcraft.yaml file references the kde neon extension, which makes the latest Qt5 and KDE Frameworks libraries available to KBlocks at runtime. The necessary code block [sic] is as follows:
…
adopt-info: kblocks
apps:
kblocks:
extensions:
- kde-neon
common-id: org.kde.kblocks.desktop
...
But we need to see what happens behind the scenes.
You can expand an extension declaration in any snapcraft.yaml file by running:
snapcraft expand-extensions
This command will look for the snapcraft.yaml file in the current directory or snap subdirectory, and print to the standard output the expanded version of the YAML file. You can redirect the output into a separate file, and then compare the two to understand what gives.
The diff is greener on the other side
The expand-extensions command does quite a bit. First, we can see that the declaration of the extension for the kblocks app in the YAML has been removed. Then, we can also see that the expanded file has several additional plugs declared, namely desktop, desktop-legacy, wayland, and x11. Another important element is the desktop-launch command, which contains a number of common environment configurations to make sure the application runs correctly.
The biggest difference is an entire new block of code at the bottom of the YAML – not visible in the screenshot above, but you can just grab the KBlocks snapcraft.yaml file we used in the workshop, and try for yourself:
- It compiles the kde-neon-extension part using a pre-existing source available in the snapcraft build environment.
- It defines several plugs – icon and sound themes as well KDE Frameworks libraries available in the existing gtk-common-themes and kde-frameworks-5-core18 content snaps. This way, you do not need to worry or manually satisfy the various components required to make your application behave and look as intended. All of these dependencies are satisfied automagically.
- It defines the runtime environment that ensures the snap will function correctly.
kde-neon-extension:
build-packages:
- g++
plugin: make
source: $SNAPCRAFT_EXTENSIONS_DIR/desktop
source-subdir: kde-neon
plugs:
icon-themes:
default-provider: gtk-common-themes
interface: content
target: $SNAP/data-dir/icons
kde-frameworks-5-plug:
content: kde-frameworks-5-core18-all
default-provider: kde-frameworks-5-core18
interface: content
target: $SNAP/kf5
sound-themes:
default-provider: gtk-common-themes
interface: content
target: $SNAP/data-dir/sounds
environment:
SNAP_DESKTOP_RUNTIME: $SNAP/kf5
As you can see from the example above, extensions not only save time, they also ensure your snaps use a consistent structure, containing all the required assets to look and run correctly. You also end up with smaller snaps, because the common components and libraries are already included in the content snaps. This can be quite useful, especially if you develop multiple applications that share common code, as is the case with the KDE software.
What’s next?
Now, you may actually have a use case that only requires a portion of the code shown above, or you want to understand how extensions work behind the scenes. You can expand existing YAML files, and then use the relevant snippets as you sit. Overall, the use of extensions, in full or in part, should help you make snaps with a more consistent theming, smaller size, and more predictable behavior, as you baseline against a well-tested set of packages used across a large number of applications.
Summary
Extensions and the associated expand command allow you to make best use of the snapcraft.yaml files, whether to learn new things, or to adopt existing code for your own needs. You may already have snaps published in the Snap Store, and you would like to improve your code. Indeed, we encourage developers to use the extensions, as they can help avoid various papercut issues in the look & feel of their applications, as well as reduce the development burden, as they need to maintain a smaller, more compact, more precise code base.
If you have any questions or suggestions on this topic, please join our forum for a discussion. In particular, if you can think of practical use cases that would warrant a creation of new extensions, we’d definitely like to hear from you.
Photo by Charlie Seaman on Unsplash.