Gotchas When Creating a Snap Package for Haskell (Stack) Program
Introduction
Building snap packages and publishing them on the Snapcraft Store is well documented by Canonical. For the most part, creating a snap package for a Haskell program (built with Stack) is the same as building any other Snap package. However, I did need to know a few things to successfully build my Snap package.
GHC Memory Requirements
GHC is a memory hog. Many libraries can take over 4 GB of memory to compile. By default, snapcraft will only allocate 2 GB of memory when building an application with multipass. Multipass gets used by snapcraft when core18 is specified in the snapcraft.yaml
as a base.
To change the memory allocated by multipass, use an snapcraft environment variable, when running snapcraft. The snapcraft command will look like, SNAPCRAFT_BUILD_ENVIRONMENT_MEMORY=4G snapcraft
, to allocate 4 GB. If snapcraft already ran with lower memory then you’ll need to rebuild the multipass VM by running snapcraft clean
first.
Using Stack tool in Snapcraft
Many Haskell applications build using the stack tool. There is not a snapcraft plugin available for the stack tool so a build override is needed. The following snippet will download and install stack. Next the snippet will build the program with stack.
override-build: |
if [ ! -x "$(command -v stack)" ]; then
curl -sSL https://get.haskellstack.org/ | sh
fi stack build --copy-bins
Use plugin: nil
for the part building the Haskell program.
Also, make sure curl
and any other build dependencies you need are in the build-packages
section.
Finding the binary
By default the binary will be stored in /root/.local/bin
from running stack buidl --copy-bins
. It is probably more convenient for the application to be in /bin
. Use organize
to move the binary were it is needed for the snap. For example:
organize:
/root/.local/bin/myapp: bin/myapp
Automatic Versioning
Snapcraft can use the same version specified in the package.yaml
like so:
override-pull: |
snapcraftctl pull snapcraftctl set-version "$(grep version package.yaml | awk '{ print $NF }')"
Use adopt-info
in the snapcraft.yaml
to select the part to use the version info from.
Example
For a working example, see my s17-turbo-switch snap configuration.
Modified: August 16, 2019 - 05:24:50 PM