Clean build - using LXC

Build on LXD

Currently snapcraft doesn’t protect your host system from being polluted during the snapcraft build process. Your host can also potentially pollute your snap by providing libraries from the wrong OS image.

Snapcraft currently requires that you only build on an Ubuntu 16.04 installation so that installed libraries and executables reference the versions of libraries that are shipped in the core snap. If you install on a different host you are almost certain to receive errors when you run the snap with messages indicating GLIBC version mismatch (among others).

To overcome these problems you can use LXD to build the snap. LXD is a container implementation that can run different Linux Distributions similar to a virtual machine hypervisor. This allows you to build against Ubuntu 16.04 on any variant of Linux that supports LXD. You can even install LXD using snap!

Install LXD using snap

$ sudo snap install lxd

Wait 30 seconds for the lxd service to start up then run lxd init and accept all of the default choices.

Note: if the system you are installing LXD onto is using a network with a 10.x.x.x subnet then network create may fail. See below on how to resolve this.

$ sudo lxd init

If you want to use snapcraft as a non-root user, which is advised, then you need to add your user account to the lxd group:

$ sudo usermod -g lxd ${USER}

Now you will need to either restart your session, reboot your computer, or use newgrp to acquire the new group assignment:

$ newgrp lxd

Note: the newgrp command will start a new sub-shell (shell within a shell) with the new lxd group assigned.

Manually create network on 10.x.x.x subnet

If you try to run lxd init on a system that is connected to a network with a 10.x.x.x subnet then the final step of the init may fail with the error:

Error: Failed to create network 'lxdbr0': Failed to automatically find an unused IPv4 subnet, manual configuration required

To resolve this issue you must manually create the network by running:

$ sudo lxc network create lxdbr0 ipv4.address=10.0.3.1/24 ipv4.nat=true

You then must re-run lxd init, but when you are prompted to create a new network bridge you must respond no.

Would you like to create a new network bridge (yes/no) [default=yes]? no

Install snapcraft

If you do not currently have snapcraft installed then install it with:

$ sudo snap install snapcraft --classic

Building

To build your project using lxd run:

$ cd $HOME/my-snap-project
$ snapcraft cleanbuild

If you add the option --debug to the snapcraft cleanbuild command and the build fails you will be left in an LXD shell which allows you to explore what occurred during the build by looking at what files were created.

Experimental

The current issue with LXD is that it does a complete build by creating a snap and then discarding the container and the intermediate build files. This is fine for a ‘final’ build before doing a release but is problematic (slow) during development.

During development you would normally use:

$ snapcraft
$ snap try prime

The ‘try’ method allows you to directly edit files in the prime directory without having to re-install or re build after each change. However, cleanbuild builds do not currently offer this fast turn around feature.

There is an experimental feature that uses LXD in a different way to allow retaining intermediate files and the container:

$ export SNAPCRAFT_BUILD_ENVIRONMENT=lxd 
$ snapcraft

Now install the snap from the container:

$ snap try prime

The environment variable SNAPCRAFT_BUILD_ENVIRONMENT instructs snapcraft to use the experimental LXD integration that builds the snap in a persistent LXD container, that remains after the build has finished, and keeps the intermediate build files to speed up rebuilds.

Last updated 14 hours ago. Help improve this document in the forum.