---
title: How to build  ROS 2 Eloquent Snaps
description: 'The end of 2019 brings about the latest ROS 2 release – Eloquent Elusor.
  Despite an ever growing set of features and some changes throughout the ecosystem,
  packaging with snaps is as easy as always. Let’s go through a quick example! Prerequisites
  You’ll need two tools: “snapcraft,” the program that builds snaps, and “multipass,”
  the  […]'
url: https://canonical.com/blog/how-to-build-ros-2-eloquent-snaps?format=md
---

1. [Blog](https://canonical.com/blog)
2. Article

---

[Ted Kern](https://canonical.com/blog/author/tkern "More about Ted Kern")

14 December 2019

# How to build ROS 2 Eloquent Snaps

[robotics](https://canonical.com/blog/tag/robotics)
[ROS](https://canonical.com/blog/tag/ros)
[ROS2](https://canonical.com/blog/tag/ros2)
[snap development](https://canonical.com/blog/tag/snap-development)
[snap packages](https://canonical.com/blog/tag/snap-packages)
[snapcraft](https://canonical.com/blog/tag/snapcraft)
[snapcraft.io](https://canonical.com/blog/tag/snapcraft-io)
[Tutorial](https://canonical.com/blog/tag/tutorial)

---

Share the article
> Please note that this blog post has out technical information that may no longer be correct. For latest updated documentation about robotics in Canonical please visit <https://ubuntu.com/robotics/docs>.

The end of 2019 brings about the latest ROS 2 release – Eloquent Elusor. Despite an ever growing set of features and some changes throughout the ecosystem, packaging with snaps is as easy as always. Let’s go through a quick example!

## Prerequisites

You’ll need two tools: “snapcraft,” the program that builds snaps, and “multipass,” the VM management tool that is used by snapcraft to conduct snap builds without cluttering your development machine. You can get both of these from the snap store.

At the time of this writing, the latest stable release of snapcraft is version 3.8. Until the next release comes out, in order to build Eloquent snaps, you’ll need to grab it from edge.

```
$ snap install snapcraft --edge --classic
```

If you already have snapcraft stable installed, you can change to edge using:

```
$ snap refresh snapcraft --edge
```

Multipass is grabbed the same way, requiring the `--beta` flag since the version at the time of writing is 0.9.0

```
$ snap install multipass --classic --beta
```

## Getting Started

### Create the snapcraft.yaml

First of all, create a new workspace directory and add a `snapcraft.yaml`.

```
~$ mkdir eloquent-snap
~$ cd eloquent-snap/
~/eloquent-snap$ snapcraft init
Created snapcraft.yaml.
Go to https://docs.snapcraft.io/the-snapcraft-format/8337 for more information about the snapcraft.yaml format.
```

Open `snap/snapcraft.yaml`, and make the following changes:

```
name: eloquent-talker-listener-arnatious
version: "0.1"
summary: Eloquent ROS 2 Example
description: |
 A ROS 2 workspace containing a talker and a listener.

grade: devel
confinement: strict
base: core18

parts:
 colcon-part:
   plugin: colcon
   source: https://github.com/ros2/demos.git
   source-branch: eloquent
   colcon-rosdistro: eloquent
   colcon-source-space: demo_nodes_cpp
   build-packages: [make, gcc, g++]
   stage-packages: [ros-eloquent-ros2launch]

apps:
 eloquent-talker-listener-arnatious:
   command: opt/ros/eloquent/bin/ros2 launch demo_nodes_cpp talker_listener.launch.py
   plugs: [network, network-bind]
```

Let’s take an in depth look at this manifest.

```
name: eloquent-talker-listener
version: "0.1"
summary: Eloquent ROS 2 Example
description: |
 A ROS 2 workspace containing a talker and a listener.
```

This is the metadata any snap requires. The only caveat to this section is that the `name` must be unique on the snap store. Appending your developer name to the snap is an option to get around this (like I did).

```
grade: devel
confinement: strict
base: core18
```

`grade` should be either `stable` or `devel`, with `devel` locking out the ability to publish to the “stable” and “candidate” channels.

`confinement` can be `strict`, `devmode`, or `classic`. These are documented [in detail on snapcraft.io](https://snapcraft.io/docs/snap-confinement), but in short: `strict` enforces tight confinement, restricting access to the system for security; `devmode` allows full access without any restriction but logs all accesses that `strict` would prevent; `classic` is unconfined, without its own private namespace or other security features.

Generally, you should always target “strict” confinement unless there’s specific features that confinement will prevent. “Classic” snaps, like snapcraft itself or text editors like Visual Studio Code, have no containment and run without protection. Classic snaps need manual approval.

The `base` keyword specifies the special snap providing things like a minimal set of core libraries for our snap’s runtime environment. We’re just using the “core18” snap, which bundles a minimal rootfs based on Ubuntu Bionic (18.04).

```
parts:
 colcon-part:
   plugin: colcon
   source: https://github.com/ros2/demos.git
   source-branch: eloquent
   colcon-rosdistro: eloquent
   colcon-source-space: demo_nodes_cpp
   build-packages: [make, gcc, g++]
   stage-packages: [ros-eloquent-ros2launch]
```

Snapcraft builds packages piecemeal, in small parts that are combined together. These are reflected by the part entries in the snapcraft.yaml. `colcon-part` is specified here as pulling the source code from a remote Github repository, though it can just as easily pull source code from a local directory or any source control system.

The `colcon` plugin is used here to build the package, with the `colcon-rosdistro` argument specified as `eloquent`, the `colcon-source-space` specified as the `demo_nodes_cpp` directory containing just the talker/listener package we care about. We specify the packages that provide the commands we need to build the ROS nodes under `build-packages.` `stage-packages` contains `ros2launch`, as we’ll need the `launch` verb it provides as part of the entry point to our snap.

```
apps:
 eloquent-talker-listener-arnatious:
   command: opt/ros/eloquent/bin/ros2 launch demo_nodes_cpp talker_listener.launch.py
   plugs: [network, network-bind]
```

We need to express how users will interact with this package. Since we’re packaging ~our~ project, we want the snap to expose our project’s verbs. We define these user interactions as “apps” in the `apps`” section.

In general, these verbs are invoked using `<snap-name>.<app>`. An entry in `apps` with the same name as the snap, like “eloquent-talker-listener-arnatious” above, can be invoked with just the snap name. Calling this app invokes the script in the `command` field, in this case roslaunch-ing the talker/listener system out of the `demo_nodes_cpp` package.

Lastly, we specify the interfaces the snap needs access to outside of confinement – in this case `network` and `network-bind`. This allows the snap to access the network and be accessed from the network, respectively. You can read more about interfaces on the snapcraft site.
Build the Snap
Now that we’ve defined the snapcraft.yaml, we can build the snap itself. Make sure you’re in the correct directory (above the “snap/” directory containing the “snapcraft.yaml”) and invoke “snapcraft.”

```
~$ cd eloquent-snap
~/eloquent-snap$ snapcraft
<omitted for brevity>
Snapped colcon-talker-listener-arnatious_0.1_amd64.snap
```

If you neglected to install multipass earlier, `snapcraft` may prompt you to do so.

The build process may take several minutes. During that time, the colcon plugin will install rosdep and use it to determine the dependencies specified in the `package.xml` of the packages, fetching and unpacking them into your snap. At the end, the result is squashed into a .snap file.

## Test the Snap

To install the snap we just built before publishing it, we run

```
~/eloquent-snap$ sudo snap install --dangerous eloquent-talker-listener-arnatious_0.1_amd64.snap
eloquent-talker-listener-arnatious 0.1 installed
```

The `--dangerous` flag is required to install snaps from locations other than the store. The snapd daemon responsible for running snaps requires any snap to be cryptographically verified from the snap store, unless the `--dangerous` flag is used.

Finally, we invoke the snap:

```
$ eloquent-talker-listener-arnatious
[INFO] [launch]: All log files can be found below /home/arnatious/snap/eloquent-talker-listener-arnatious/x1/.ros/log/2019-12-11-07-56-04-973199-arnatious-ubuntu-1910
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [talker-1]: process started with pid [28330]
[INFO] [listener-2]: process started with pid [28331]
[talker-1] [INFO] [talker]: Publishing: 'Hello World: 1'
[listener-2] [INFO] [listener]: I heard: [Hello World: 1]
[talker-1] [INFO] [talker]: Publishing: 'Hello World: 2'
[listener-2] [INFO] [listener]: I heard: [Hello World: 2]
[talker-1] [INFO] [talker]: Publishing: 'Hello World: 3'
[listener-2] [INFO] [listener]: I heard: [Hello World: 3]
…
```

The snap runs without issue on the machine, regardless of linux distro or whether ROS is on the machine. You can now push to the the snap store – where anyone running snapd can install and run it.

I hope this gives you a good look at how to build ROS 2 Eloquent snaps! Feel free to ask questions on the [Snapcraft forums](https://forum.snapcraft.io/) or on the [ROS Forums](https://discourse.ros.org/).

[Get in touch

Interested in running Ubuntu in your organization?](https://ubuntu.com/about/contact-us/form)

## Sign up for our newsletter

Get the latest Canonical news and updates in your inbox.

Work email:

\*I agree to receive information about Canonical's
products and services.

By submitting this form, I confirm that I have read and agree to [Canonical's Privacy Policy](https://canonical.com/legal/dataprivacy).

Sign up

## Share on

---

## Related posts

[### TurtleBot3 OpenCR firmware update from a snap](https://canonical.com/blog/turtlebot3-opencr-firmware-update-from-a-snap)

The TurtleBot3 robot is a standard platform robot in the ROS community, and it’s a reference that Canonical knows well, since we’ve used it in our tutorials. As a matter of...

[gbeuzeboc](https://canonical.com/blog/author/gbeuzeboc)

25 September 2024

[### Extending ROS Noetic Support with ESM-Enabled Content Snaps](https://canonical.com/blog/extending-ros-noetic-support-with-esm-enabled-content-snaps)

Canonical has now extended its ESM (Expanded Security Maintenance) for ROS coverage to ROS Noetic content-sharing snaps. With ESM for ROS now available in both deb and snap...

[Florencia Cabral Berenfus](https://canonical.com/blog/author/flor-cabral)

17 December 2025

[### Discover your fully open source robotics observability at ROSCon 2025](https://canonical.com/blog/roscon-2025)

Another year, another ROSCon! This year we’re heading to Singapore, and Canonical is once again thrilled to sponsor this important community event. Just like last year in...

[Gabriel Aguiar Noury](https://canonical.com/blog/author/g-aguiar-noury)

22 October 2025

[### Canonical is now a platinum member in the Open Source Robotics Alliance](https://canonical.com/blog/osra-membership)

Ubuntu is the home of ROS. The very first ROS distribution, Box Turtle, launched on Ubuntu 8.04 LTS, Hardy Heron, and since then, Ubuntu and ROS have grown hand in hand. With...

[Gabriel Aguiar Noury](https://canonical.com/blog/author/g-aguiar-noury)

20 August 2025
