snapserviceupdatetemplate_web_logo

SnapServiceUpdateTemplate

v1.0.0

Table of Contents

Overview

This document provides a step-by-step guide on how to create a snap package for a CMake project using Snapcraft, as well as instructions for setting up a systemd service for the snap application. Snap packages allow you to update an executable on a target machine by bundling all required packages into a single file. This feature makes it easy to distribute and install applications on a target machine without an internet connection. The single .snap file can be copied and installed on the target system, complete with all necessary dependencies. Additionally, the document explains how to create a systemd service for the snap application, enabling it to run continuously in the background or to start automatically on boot.

Versions

Table 1 - Library versions.

Version Release date What’s new
1.0.0 24.03.2025 - First version.

How to prepare target machine

In order to use snap packages, the target machine must have the snap package manager installed. The following steps will guide you through the installation process:

  1. Install snapd using the following command:
     sudo apt install snapd
    
  2. Install all snap cores snap using the following command:
     sudo snap install core core18 core20 core22 core24 bare
    

How to prepare host machine

Snapcraft is a tool for building and packaging applications as snap packages. It should be installed on the host machine where the snap package will be built. Snapcraft itself is a snap package, so it can be installed using the snap package manager. The following steps will guide you through the installation process:

  1. Install snapcraft using the following command:
     sudo snap install snapcraft --classic
    
  2. Install LXD using the following command:
     sudo snap install lxd
    
  3. Add your user to the lxd group:
     sudo usermod -aG lxd $USER
    
  4. Log out and log back in to apply the group changes.

  5. Initialize LXD:
     lxd init --minimal
    

Snapping a CMake project and deploying it on a target machine

How to prepare a snap package from cmake project on host machine

Assuming you have a cmake project as follows:

myCmakeProject ---------- Root folder of the project.
    CMakeLists.txt ------ Main CMake file.
    3rdparty ------------ Folder with third-party libraries.
        CMakeLists.txt -- CMake file to include third-party libraries.
        Some3rdParty ---- Source code of Some3rdParty library.
    src ----------------- Folder with application source code.
        CMakeLists.txt -- CMake file.
        main.cpp -------- Application source code file.
  1. Direct to folder with your project:
     cd myCmakeProject
    
  2. Initiate the snapcraft if snapcraft.yml does not exist :
     snapcraft init
    

Step 2 is optional. If you already have a snapcraft.yaml file, you can skip this step. It will create a default snapcraft.yaml file in the current directory.

After running the above command, project structure will look like this:

myCmakeProject ---------- Root folder of the project.
    CMakeLists.txt ------ Main CMake file.
    3rdparty ------------ Folder with third-party libraries.
        CMakeLists.txt -- CMake file to include third-party libraries.
        Some3rdParty ---- Source code of Some3rdParty library.
    src ----------------- Folder with application source code.
        CMakeLists.txt -- CMake file.
        main.cpp -------- Application source code file.
    snap ---------------- Folder with snapcraft files.
        snapcraft.yaml -- Snapcraft configuration file.
  1. Template the snapcraft.yaml file for cmake project:
     name: mycmakeproject # Snap name must be lowercase
     base: core24
     version: '0.1'
     summary: Simple C++ App
     description: |
     A minimal example of packaging a C++ application using CMake in Snapcraft.
    
     grade: devel
     confinement: classic
    
     apps:
     myCmakeProject:
         command: myCmakeProject
         environment:
         LD_LIBRARY_PATH: $SNAP/usr/lib/x86_64-linux-gnu/blas:$SNAP/usr/lib/x86_64-linux-gnu:$SNAP/usr/lib/x86_64-linux-gnu/lapack:$SNAP/usr/lib:$LD_LIBRARY_PATH
    
     parts:
     myCmakeProject:
         plugin: cmake
         source: .
         build-packages:
         - libopencv-dev
         stage-packages:
         - libopencv-dev
         override-build: |
         cmake -S $SNAPCRAFT_PART_SRC -B $SNAPCRAFT_PART_BUILD
         cmake --build $SNAPCRAFT_PART_BUILD
         cp $SNAPCRAFT_PART_BUILD/bin/* $SNAPCRAFT_PART_INSTALL/
    
  2. Build the snap package:
     snapcraft
    

    Snapcraft will build the cmake project and create a snap package of it in the current directory.

How to install the snap package on target machine

Snap package is prepared on the host machine. The generated .snap file that is self-contained and includes all the necessary dependencies. This means that the snap package can be installed on target machine without needing to install any additional packages or dependencies.

after .snap file is copied to the target machine, you can install it using the following command:

sudo snap install mycmakeproject_0.1_amd64.snap --classic --dangerous

The --classic flag is used to allow the snap package to access the system resources. The --dangerous flag is used to install the snap package without verifying the signature. This is useful for local development. Also snap may require the internet connection to download the base snap if it is not already installed on the target machine. If you do not have internet connection ont the target machine, prepare the snap package with the base snap target has. See snapcraft.yml file base section.

Snap application will be available in the system. You can run it using the following command:

myCmakeProject

or with the full path:

/snap/bin/myCmakeProject

snapcraft.yaml file explanation

The snapcraft.yaml file is the configuration file for the snap package. It contains all the information needed to build and install the snap package. See the snapcraft .yml schema for more information. Some of the important fields in the snapcraft.yaml file are:

  • name: The name of the snap package. The name must be lowercase.
  • base: The base snap to use. Use core22 for Ubuntu 22, core20 for Ubuntu 20, and core18 for Ubuntu 18 and so on. core24 is the latest version of the base snap. It is recommended to use it.
  • version: The version of the snap package.
  • summary: A short summary of the snap package.
  • description: A longer description of the snap package.
  • grade: The grade of the snap package. Use devel for development and stable for production.
  • confinement: The confinement level of the snap package. Use classic for classic confinement and strict for strict confinement. Classic confinement is recommended because it allows the snap package to access the system resources. Strict confinement isolates the snap package from the system more. For more information on confinement levels, see the snapcraft documentation.

  • apps: The applications that are included in the snap package. Each application has a name and a command to run it. It is important to set environment variables for the application to run correctly. In this case, we set the LD_LIBRARY_PATH environment variable to include the libraries that are needed for the application to run. The LD_LIBRARY_PATH variable is used by the dynamic linker to find shared libraries at runtime. It is important to set this variable correctly so that the application can find the libraries it needs. See the Build and staging dependencies.

  • parts: The parts of the snap package. Each part has a name and a plugin to use.

    • The plugin is set to cmake to use the CMake plugin. See Cmake plugin.
    • The source is set to . to use the current directory as the source. If your source code is in a different directory, you can set the source to that directory.
    • The build-packages are the packages that are needed to build the application. See the Build and staging dependencies.
    • The stage-packages are the packages that are needed to run the application. See the Build and staging dependencies.
    • The override-build is used to override the default build command because snapcraft cmake build command by defaults requires install. In this case, we use CMake to build the application and move the binary to the install directory. If your cmake has install target, override-build is not needed.

Systemd service for snap application

How to create systemd service for snap application

  1. Create a systemd service file in the /etc/systemd/system directory:
     sudo nano /etc/systemd/system/myCmakeProject.service
    
  2. Add the following content to the service file:
     [Unit]
     Description=My CMake Project Service
     After=syslog.target  # And other services that your service depends on
     Wants=network.target # If your service needs network access
     [Service]
     Type=simple
     ExecStart=/snap/bin/myCmakeProject # Proper name of your snap application
     WorkingDirectory=</path/to/your/project> # Path desired directory incase there are files to be created.
     Restart=on-failure
     RestartSec=5
     [Install]
     WantedBy=multi-user.target # Or other target that your service should start with
    
  3. Save and exit the file.

  4. Reload the systemd daemon to apply the changes:
     sudo systemctl daemon-reload
    
  5. Start the service:
     sudo systemctl start myCmakeProject.service
    
  6. Enable the service to start on boot:
     sudo systemctl enable myCmakeProject.service
    
  7. Check the status of the service:
     sudo systemctl status myCmakeProject.service
    
  8. Stop the service:
     sudo systemctl stop myCmakeProject.service
    
  9. Disable the service from starting on boot:
     sudo systemctl disable myCmakeProject.service
    

How to update snap application

Assuming you have new version of your application and you want to update the snap package.

  1. Stop the systemd service if it is running:
     sudo systemctl stop myCmakeProject.service
    
  2. Install the new version of the snap package:
     sudo snap install myCmakeProject_0.2_amd64.snap --classic --dangerous
    

    After installing you will have multiple version of your snap package in /snap/myCmakeProject as follows:

     ls -l /snap/my-cpp-app/
     total 0
     lrwxrwxrwx 1 root root 2 Mar 24 12:10 current -> x2
     drwxr-xr-x 7 root root 0 Mar 24 11:54 x1
     drwxr-xr-x 7 root root 0 Mar 24 12:08 x2
    

    The current link points to the latest version of the snap package. You can check the version of the snap package using the following command:

     snap list myCmakeProject
    

    if you want to roll back to the previous version, you can use the following command:

     sudo snap revert myCmakeProject
    

    Or if you want to roll back to a specific version, you can use the following command:

     sudo snap revert myCmakeProject --revision <revision_number>
    

    Note: The revision number can be found using the snap list command. The revision number is the number that appears in the Rev column of the output.

  3. Start the systemd service again:
     sudo systemctl start myCmakeProject.service
    

References


Table of contents