Guidelines and HOWTOs/Snap
Want to run your application binaries on any Linux distribution? Snap makes that possible.
For general purpose information about snap, snapcraft and how to use them please have a look at their documentation https://docs.snapcraft.io
Building a snap we'll lovingly call "snapping". At the time of writing you can snapcraft on two core systems: one is Ubuntu 16.04, the other is Ubuntu 18.04. Both of them are the LTS version of Ubuntu and therefore supported for what seems like forever. Snapcraft has native support to pull binary packages (i.e. debs) into the snap so that you might build against them without having to build the binaries yourselves. For example you could use Qt from Ubuntu directly without the need to build it in your snap. However, since the base systems are LTS the software is usually very dated. Seeing as you may need newer dependencies there's a bunch of ways you can get them besides pre-built Ubuntu debs:
You can add any number of additional parts that build dependencies. For example you might build your own qtbase as part of snap. How much work this is can be vastly different between software. Building all of Qt can get quick old, at the same time relying on an ancient Qt may not be practical either.
From KDE neon
We are in luck and KDE neon already builds packages for Ubuntu LTS, so you may choose to simply use neon debs on top of Ubuntu debs. This gives access to the latest Qt, KDE frameworks and other related libraries. This can be a huge time saver. Unfortunately Snapcraft's support for adding additional repositories is non-existent and so if you choose to go this route you may need to somewhat manually manage the build environment yourself e.g. using a specially prepared LXD container.
Much like KDE neon, this too will require you to manage the build environment manually. Also, when using PPAs beware that they may not be compatible with neon (so, ideally you should use either-or) and that many of them are not particularly trustworthy or well maintained (important vis-a-vis security).
Types of Snap
With a broad overview of abilities and shortcomings let's dive right in and look at types of snaps we might build.
A standalone snap is a snap which solely relies on a "core" but no other snaps. This is generally speaking the most reliable type of snap as everything the snap needs is inside the snap (except libc and friends which are in the core).
It is also the best supported way of building a snap since it's been around since the very beginning.
- Very reliable
- Easy to build and test
- You are always on your own and unrelated changes rarely if ever can impair your snap
- Huge in size (each standalone snap needs to ship their own Qt/l10n and necessary kf5 and other dependencies)
- You need to take care of setting up your execution environment yourself.
- You are always on your own and unrelated changes rarely if ever can improve your snap
A snap may also choose to use one or more Content Snaps (see glossary) to share part of the binaries or UI assets with other snaps. As shared content will generally be in the content snap, the ultimate size of the snap can be fairly small. Think of this as an approach more akin to how traditional binary package dependencies work. Albeit with many of the same complexities surrounding it.
For example KDE neon builds the kde-frameworks-5 content snap. It contains all of Qt and all (not-deprecated) KDE frameworks along with Plasma integration rigging.
- Application snap is super small
- You don't need to care of setting up the execution environment
- Integration and international improvements are all in one place (shared environment setup etc)
- Generally speaking when using the KF5 content snap SDK you can get access to KDE neon's Qt and Frameworks without having to actually add the deb sources.
- Up-front "cost" of a single application may be higher. e.g. if the application only uses QtCore, the content snap will still bring in all of Qt and all of KF5 through the content snap. It's like a shared library, the more it is used the smaller the cost per-user.
- Somewhat harder to build and test because of added complexity. Also managing deb build dependencies in addition to content snap SDKs is problematic TBD link to forum post
- Unrelated changes in the content snaps may impair your snap
- Since this type was introduced a while after snap initially came into being you still can feel rough edges when working with content snaps.
Words you'll hear and not know what they mean:
- snap: The actual bundle format.
- snapd: The daemon that manages snap on a system.
- snapcraft: The build tool for building a snap.
- 'app: In the context of snapcraft/snapd this is the (portable) description of an 'exectuable' exposed to the outside (i.e. something snapd knows how to run).
- parts: In the context of snapcraft a part refers to one build entity. They describe where to get the source of the entity, how to build it, how to stage it into the final snap and which other parts are a dependency and need to be built first. A part is much like a "makefile" target.
- interfaces: A way for a snap to talk to the outside world (or another snaps). Split into slots and plugs. Each of which has their own security permissions as a client may need to be able to do different things from a server. https://docs.snapcraft.io/interface-management
- slot: The provider part of an interface. e.g. a kwin snap might have a wayland-client slot which exposes a way for clients to talk to kwin.
- plug: The client part of an interface. e.g. an application may plug into the wayland-client slot of kwin to talk to it.
- Core: A special snap containing the core aspects of any Linux OS (libc/libpthread/...). All snaps depend on exactly one core which provides the snap's understanding of what will be in "/" from the snap's POV. The core does not include a kernel! Kernels may be snaps.
- Content Snap: Special kind of snap that implements the "content" interface. It's kind of like a shared dependency between snaps allowing one snap to be bound into the scope of another snap. For example the KF5 content snap may be used to share all of KF5 across multiple snaps.
- Build Snap: Also a special kind of snap, it's the build-time variant of the Content Snap and contains header files etc. necessary to build against a Content Snap.