For a while now we’ve been pondering how to best solve building snaps of Mir-based servers. This post aims at discussing where we are, and where we could go.
Mir is built in three PPAs: release, rc, dev - in increasing order of bleeding-edgedness. To build a Mir-based server (unity8, mir-kiosk, egmde, …), you need to somehow make its libraries available to your application. For a
deb-based distribution, you’d just get the PPA in and install the packages. With snaps, it’s more of a Bring Your Own Dependencies situation, and Mir falls into that category.
Some existing snaps use something of a workaround for
snapcraft's current lack of support for “additional archives” - they install the PPA in a part that other parts can depend on. Another approach, taken by
mate-wayland-snap is to build Mir as a part directly from source.
Both of those approaches have pros and cons and may be valid for some software regardless of the proposal below.
Enter framework snaps
The approach taken by other collections of libraries (GNOME, KDE to name two) are so called “framework snaps”. They’re collections of libraries encapsulated in snaps that can be shared with others via
content interface connections. Those snaps expose one or more slots in the form
gnome-3.28-1804. This allows the consuming snap to ensure that the features required are always available for it, and binary-compatible. It’s the framework snaps’ responsibility to ensure binary compatibility of the libraries they provide.
MirAL was created to ensure binary backwards-compatibility to servers consuming Mir through the Mir Abstraction Library. If you build a server against MirAL 2.* today, it will continue to work (without rebuilding) with any subsequent release of that major version. It doesn’t mean there can’t be features added to it, rather that we’ll not be removing anything or changing in an incompatible way.
miral-2-core18 snap could expose the following slots:
A new release of MirAL with added features would add a new slot with a new version, so consumers that want to use those new features can ensure that the snap version installed includes them. Other consumers might not even notice that there’s a new version and can remain on the previous version.
The consumer snaps would have a plug declaration similar to:
This would ensure that the MirAL framework snap is installed when you install the server snap and the correct minimal version of the libraries are available.
To be able to build a server using that framework snap, we’ll need to introduce a build-snap of MirAL as well. It would include all the headers and bits required to build your software. Depending on size, we may actually include it all in the framework snap itself.
To weigh whether this approach is valid, I’ll try and enumerate the advantages below:
- decoupling (Mir can be updated separately from the server)
- simplified build (servers don’t need the Mir PPAs installed, or build it from source)
- ensured compatibility (server snap won’t stop working if Mir introduces an incompatible change)
- security (new Mir builds will get to your devices unattended if you use a custom server)
- easier development (you can refresh
miral-2-core18 to the
candidate channel to ensure it works)
- lower memory and disk footprint (if more than one snap uses the MirAL framework, they share the libraries)
Devil’s advocate voices as follows:
- less control (Mir can be updated separately from the server)
- interface connections (the content interface may not be auto-connected, requiring manual intervention)
The PPAs will remain where they are, if your snap requires more than the framework snap, you can still use them when building your snap.
Building from source
Yes, source remains where it is, too - you can build it in your snap if required.
stage-snaps: now as well, so you could actually take the
miral snap and stage its contents into your snap.
Please reply below with your thoughts!