You're reading the documentation for an older, but still supported, version of ROS 2. For information on the latest version, please have a look at Iron.
Packaging your ROS 2 application as a snap [community-contributed]
Table of Contents
What are snaps?
Snaps are containers that bundle an application and all its dependencies. They offer several features that address important concerns as one gets closer to shipping a robotic platform:
Container solution: Snaps bundle your application along with all the necessary dependencies (including ROS 2) and assets in one package. Your application is then easily installable on dozens of Linux distributions and across distro versions.
Strict confinement: Snaps are designed to be secure and isolated from the underlying system and other applications, with dedicated interfaces to access the host machine.
Managing updates: Snaps can update automatically and transactionally, making sure your robot is never broken and always up-to-date.
Release management: Snaps’ multiple release channels allow you to have role-based access controls and application versioning, making A/B testing easy and releasing fixes faster.
Creating a snap
This tutorial will demonstrate how to use snapcraft to package your ROS 2 application as a 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
For your example, you will use the
demo_nodes_cpp package from the ros2_demos.
Initialize a new snapcraft project here:
mkdir ~/demo_nodes_cpp_snap cd ~/demo_nodes_cpp_snap snapcraft init
This will create a file in a subdirectory
The snapcraft file
Open the freshly created
snap/snapcraft.yaml file and copy over the following:
name: ros2-talker-listener version: '0.1' summary: ROS 2 Talker/Listener example description: | This example launches a ROS 2 talker and listener. confinement: devmode base: core20 parts: ros-demos: plugin: colcon source: https://github.com/ros2/demos.git source-branch: foxy colcon-packages: [demo_nodes_cpp] build-packages: [make, gcc, g++] stage-packages: [ros-foxy-ros2launch] apps: ros2-talker-listener: command: opt/ros/foxy/bin/ros2 launch demo_nodes_cpp talker_listener.launch.py extensions: [ros2-foxy]
Let’s break it down.
name: ros2-talker-listener version: '0.1' summary: ROS 2 Talker/Listener example description: | This example launches a ROS 2 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.
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 foxy.
To get started, you won’t confine this application.
Unconfined applications, specified with
can only be released to the
edge channel of the snapcraft store.
For more information about snaps Security model, please refer to the online documentation.
parts: ros-demos: plugin: colcon source: https://github.com/ros2/demos.git source-branch: foxy colcon-packages: [demo_nodes_cpp] build-packages: [make, gcc, g++] stage-packages: [ros-foxy-ros2launch]
Parts define how to build the app.
In this case, you have one:
Parts can point to local directories, remote git repositories, or tarballs.
Here, you specify your source as a GitHub repository at a specific branch.
You also specifically tell
Colcon to build the
Furthermore you tell snapcraft that packages such as
make are necessary at build time while the package
ros-foxy-ros2launch is necessary at run time.
For more information about the plugin and its options, please refer to the online documentation.
apps: ros2-talker-listener: command: opt/ros/foxy/bin/ros2 launch demo_nodes_cpp talker_listener.launch.py extensions: [ros2-foxy]
Apps are the commands exposed to end users.
Each key under apps is the command name that should be made available on users’ systems.
command keyword specifies the command to be run as its name suggests.
Finally, the extensions ros2-foxy essentially sets up the ROS 2 apt package repository together with the necessary environment variables.
Building the snap
Now that you are all set up, let’s build the snap:
cd ~/demo_nodes_cpp_snap snapcraft --enable-experimental-extensions
*EXPERIMENTAL* extensions enabled. Launching a VM. Launched: snapcraft-ros2-talker-listener [...] This part is missing libraries that cannot be satisfied with any available stage-packages known to snapcraft: libnddsc.so libnddscore.so libnddscpp.so librosidl_typesupport_connext_c.so librosidl_typesupport_connext_cpp.so librticonnextmsgcpp.so Snapped ros2-talker-listener_0.1_amd64.snap
The warnings regarding the missing libraries are false positives. These libraries are build time dependencies only. This will be fixed in a future release of
That will take a few minutes.
From the logs, and among other things, you can see snapcraft using rosdep to pull the dependencies for your example but also
Colcon building the application.
Testing the snap
This snap is completely standalone: it includes ROS 2 and your application, meaning that one doesn’t even need to install ROS 2 on the host system. Let’s test it out:
sudo snap install ros2-talker-listener_0.1_amd64.snap --devmode
Note that you use
--devmode here because the snap confinement is set as
The moment of truth, will it run?
[talker-1] [INFO] [1646934735.523191674] [talker]: Publishing: 'Hello World: 1' [listener-2] [INFO] [1646934735.524428480] [listener]: I heard: [Hello World: 1] [talker-1] [INFO] [1646934736.523025881] [talker]: Publishing: 'Hello World: 2' [listener-2] [INFO] [1646934736.523614075] [listener]: I heard: [Hello World: 2]
It does! You see the expected output!
You can find more information about snap on the snapcraft documentation and ROS 2 snap page.