Creating a snap

This tutorial will demonstrate how to use Snapcraft to create a new snap, and then how to use it.

First, let us install Snapcraft.

$ sudo snap install --classic snapcraft

(Note that the snapcraft Debian package from the apt repositories is largely deprecated. One should use the snap package.)

Snapcraft has built-in support for Catkin. In order for it to know which project components to include, you must ensure that your projects have install rules.

For our example, we will use roscpp_tutorials from the ros_tutorials.

Initialize a new Snapcraft project here:

$ mkdir ~/roscpp_tutorials_snap
$ cd ~/roscpp_tutorials_snap
$ snapcraft init

This will create a file in a subdirectory snap/snapcraft.yaml

The snapcraft file

Open that snap/snapcraft.yaml file and make copy over the following:

name: ros-talker-listener
version: '0.1'
summary: ROS Talker/Listener Example
description: |
 This example launches a ROS talker and listener.
 
confinement: devmode
base: core20
 
parts:
 ros-tutorials:
   plugin: catkin
   source: https://github.com/ros/ros_tutorials.git
   source-branch: noetic-devel
   source-subdir: roscpp_tutorials
   stage-packages:
       - ros-noetic-roslaunch
 
apps:
 ros-talker-listener:
   command: opt/ros/noetic/bin/roslaunch roscpp_tutorials talker_listener.launch
   extensions: [ros1-noetic]

Don’t worry, we will break it down together.

Metadata

name: ros-talker-listener
version: '0.1'
summary: ROS Talker/Listener Example
description: |
 This example launches a ROS talker and listener.

This is the basic metadata that all snaps require. These fields are fairly self-explanatory but note that the name must be globally unique across all snaps.

Base

base: core20

The base keyword defines a special kind of snap that provides a run-time environment with a minimal set of libraries that are common to most applications. Core20 is the current standard base for snap building and is based on Ubuntu 20.04 LTS. It is, therefore, the base used for Noetic.

Security model

confinement: devmode

To get started, we won’t confine this application. Unconfined applications, specified with devmode, can only be released to the edge channel of the snapcraft store.

Parts

parts:
 ros-tutorials:
   plugin: catkin
   source: https://github.com/ros/ros_tutorials.git
   source-branch: noetic-devel
   source-subdir: roscpp_tutorials
   stage-packages:
       - ros-noetic-roslaunch

Parts define how to build your app. In this case, we have one: ros-tutorials. Parts can point to local directories, remote git repositories, or tarballs. Here, we specify our source as a GitHub repository at a specific branch. We also specifically tell Catkin to build the roscpp_tutorials subdirectory. Furthermore, we tell snapcraft that packages such as make are necessary at build time while the package ros-noetic-roslaunch is necessary at build time. For more information about the plugin and it options, please refer to the online documentation.

The Catkin packages you’re building must have install rules, or the snapcraft CLI won’t know which components to place into the snap. Make sure you install binaries, libraries, header files, launch files, etc.

Apps

apps:
 ros-talker-listener:
   command: opt/ros/noetic/bin/roslaunch roscpp_tutorials talker_listener.launch
   extensions: [ros1-noetic]

Apps are the commands exposed to end users. Each key under apps is the command name that should be made available on users’ systems. The command keyword specifies the command to be run, as its name suggests. Finally, the extensions ros1-noetic essentially sets up the ROS2 apt package repository together with the necessary environment variables.

Building the snap

Now that we are all set up, let’s build the snap:

$ cd ~/roscpp_tutorials_snap
$ snapcraft --enable-experimental-extensions
*EXPERIMENTAL* extensions enabled.
Launching a VM.
Launched: snapcraft-ros-talker-listener
[...]
Snapped ros-talker-listener_0.1_amd64.snap

That will take a few minutes. From the logs, and among other things, you will see Snapcraft using rosdep to pull the dependencies of your package but also Catkin building your application. That is because internally, Snapcraft relies on the familiar ROS tool.

Testing the snap

This snap is completely standalone: it includes ROS and your application, meaning that you don’t even need to install ROS on your system. Let’s test it out:

$ sudo snap install ros-talker-listener_0.1_amd64.snap --devmode

Note that we use --devmode here because the snap is devmode confinement.

The moment of truth, will it run?

$ ros-talker-listener

[ INFO] [1497643945.491444894]: hello world 0
[ INFO] [1497643945.495444894]: I heard: [hello world 0]
[ INFO] [1497643945.591430533]: hello world 1
[ INFO] [1497643945.595430533]: I heard: [hello world 1]
[ INFO] [1497643945.691426519]: hello world 2
[ INFO] [1497643945.695426519]: I heard: [hello world 2]
[ INFO] [1497643945.791444793]: hello world 3
[ INFO] [1497643945.795444793]: I heard: [hello world 3]

It does! We see the expected output!

You can find more information about snap on the snapcraft documentation and ROS snap page.

Wiki: ROS/Tutorials/Packaging your ROS project as a snap/noetic (last edited 2022-03-25 11:26:18 by GuillaumeBeuzeboc)