Troubleshoot snap building

When creating snapcraft.yaml and building a new snap, it’s not uncommon to encounter build issues when running snapcraft.

For this reason, it can be helpful to build the snap early, even before adding interfaces. It makes finding the culprit easier, and stops early issues affecting later stages of the build, complicating any debugging that needs to be done.

Iterating over a build

When building a snap, run snapcraft --debug rather than snapcraft.

With --debug, if snapcraft encounters an error it will open a shell within the virtualised build environment that snapcraft instantiates by default.

This enables you to view logs within the environment, check the value of environment variables, locate missing binaries and install missing dependencies. You can even edit snapcraft.yaml outside of the shell, and then run snapcraft within, to continue the build.

Build issues are linked to the stage that snapcraft is working through (see Snapcraft lifecycle) when it generates an error, and the most common problems associated with each step are outlined below.

1. Snapcraft.yaml

These errors typically occur early, before any processing, and they’re usually easy to resolve.

For example:

Issues while validating snapcraft.yaml: 'adopt-info' is a required 
property or 'version' is a required property:

The above issue is caused by a mandatory keyword, version, not being defined.

However, version isn’t actually mandatory when paired with adopt-info, because adopt-info pushes version details into snapcraft from its specified part. This isn’t processed until later in the build, which means any error in adopt-info isn’t generated until the ‘prime’ phase:

Failed to generate snap metadata: 'adopt-info' refers to part 'mypart',
but that part is lacking the 'parse-info' property. 

To resolve this, make sure your part includes parse-info or runs a command to define the version details (such as snapcraftctl set-version).

For more information on the keywords most affected by this error, see Adding global metadata.

2. Build phase

Errors in this phase are only generated by projects building their own binaries from source code.

Any issues that do occur are likely to be similar to those associated with compiling the project outside of snapcraft, and it can help to first build manually, or be familiar with the part that’s failing to build, before updating your snap.

For example:

Package ncursesw was not found in the pkg-config search path.
Perhaps you should add the directory containing `ncursesw.pc'
to the PKG_CONFIG_PATH environment variable
No package 'ncursesw' found
pkg-config: exit status 1

The above example is easily rectified by adding libncursesw5-dev under build-packages for the part that’s failing to build, as you would need to building outside of snapcraft.

build-packages:
   - libncursesw5-dev

For more details on package names and build dependencies, see Build and staging dependencies.

3. Staging phase

Errors in this phase are synonymous with missing dependencies in any run-time environment.

Missing elements are typically libraries, and sometimes binaries, that an application needs to run correctly. Errors manifest at run-time, or when a library should be accessed, and those errors are generated by the application rather than the snap.

A git client, for example, might not use the git command directly until it needs to. Only then will its absence become apparent (and only if git isn’t installed on the host system).

For example:

Unable to successfully call git binary. If git is not in $PATH then please 
set the config variable git-binary-file-path   

The solution is to add the packages for these missing dependencies under stage-packages within the affected part:

stage-packages:
- git

As with build dependencies, for more details on working out staging dependencies see Build and staging dependencies.

For further tips on common build issues, see Debugging building snaps.

(Action after the comment on the “Iterating over a build” page.)

After a bit of thought I realized that merging the two pages together would produce a very long one. Thus, it might be best to clarify the separation between the two topics. In my opinion, a good step forward (and one that could actually solve this problem) is removing the “Iterating over a build” section in this page as it is quite condensed and doesn’t actually help the reader in debugging the different phases that are explained later. The concern I have is that having a section with a header might disguise it as a complete topic while another broader page exists, as well as possibly inducing some confusion on people following the how-to and finding the same title in two back-to-back pages.

My suggestion for this page is removing the “Iterating over a build” section and replacing it with a sentence either at the end of the following paragraph “Build issues are linked to the stage that snapcraft is working through (see Snapcraft lifecycle) when it generates an error, and the most common problems associated with each step are outlined below.” or at the end of the page, saying:

" Troubleshooting each lifecycle step is made easier by the --debug, --shell and --shell-after options that can be passed to the snapcraft command. For details and other recommendations for a quicker development process, see Iterating over a build. "

This should provide both the separation in topics between the two pages and a clearer guide for a person that landed on this page to get more information on the debugging practices. (I am aware that “Iterating over a build” is linked in the references, but it might be missed since a similar section is already in this page.)