This section explains how to build a workspace for
maliput development. You’ll learn how to work with
delphyne repositories in a multi-repository workspace.
Docker containerized workspaces (recommended): A docker image is provided in order to show the steps needed to set up the environment in a containerized workspace. When setting up docker, do not add yourself to the “docker” group since that represents a security risk (it is equivalent to password-less sudo). As a workaround, the instructions below use
sudofor building the image and running the container.
Non-containerized workspaces: Ubuntu Focal Fossa 20.04 LTS only.
To get all the necessary tools, clone
git clone firstname.lastname@example.org:maliput/maliput_infrastructure.git
To pull private repositories, the current user default SSH keys will be used (and thus assumed as both necessary and sufficient for the purpose).
The following assumes that you want to create a workspace containing all of Maliput’s repositories, with a focus on
Maliput and Malidrive development. As such, it uses a workspace directory named
maliput_ws and pulls
sources from foxy/maliput.repos.
The instructions also cover how to optionally add
delphyne repositories into your
workspace. These repositories include a simulator and visualizer useful when working with Maliput road networks.
The instructions below first cover how to create a non-containerized workspace, followed by a containerized workspace. Note that using a containerized workspace is recommended.
The following creates a non-containerized workspace. Follow it if you are willing to install Maliput and its dependencies directly in your base operating system. Bear in mind that using a non-containerized workspace makes reproducing and troubleshooting issues harder for others. If in doubt, install your workspace within a container by following the instructions in the subsequent “Option 2” section.
These instructions assume
maliput_ws is at the same level as
maliput_ws. It will be used to add the Maliput-related repositories to the workspace.
cp maliput_infrastructure/repos_index/foxy/maliput.repos maliput_ws/
You can optionally add Delphyne-related repositories to your workspace:
cp maliput_infrastructure/repos_index/foxy/delphyne.repos maliput_ws/
Bring all the repositories listed in
cd maliput_ws mkdir src vcs import src < maliput.repos # clone and/or checkout # Optionally, run: # vcs import src < delphyne.repos vcs pull src # fetch and merge (usually fast-forward)
This will clone repositories and/or checkout branches, tags or commits as necessary,
followed by fetching and (likely) fast-forward merging to get branches up to date with
their upstream counterpart. No merging takes place when a repository is at a given tag
or commit. Note that you can continue to bring other repositories into your workspace by repeating
pull operation using additional
First update the
ROS_DISTRO environment variable with your
ros2 version, e.g.:
rosdep update --include-eol-distros rosdep install -i -y --rosdistro $ROS_DISTRO --skip-keys "pybind11" --from-paths src
Package dependencies are installed system wide.
rosdep does not provide any support to remove the dependencies it
brings. In this regard, disposable containerized workspaces help keep development environments clean (as system wide
installations within a container are limited to that container).
Installing drake is only necessary when working with
delphyne.repos, otherwise it will fail because
drake_vendor is not in the workspace.
The following creates a containerized workspace. Maliput and its dependencies remain in the container and do not impact your operating system. Likewise, packages installed on your operating system do not impact the container. The uniformity of the container’s environment makes it easier for other developers to reproduce and resolve problems you may encounter.
Configuring a containerized workspace is similar to that of a non-containerized workspace. When the steps are identical,
links to the non-containerized setup instructions are used. Machinery is provided to
run a docker
image and container for Maliput workspace development:
If you are using nvidia-docker2 add the
build.sh --help for more options:
--image_nameName of the image to be built (default maliput_ws_ubuntu_focal).
--workspace_nameName of the workspace folder (default maliput_ws).
If you are using nvidia-docker2 add the
run.sh --help for more options:
--image_nameName of the image to be run (default maliput_ws_ubuntu_focal).
--container_nameName of the container (default maliput_ws_focal).
--workspaceRelative or absolute path to the workspace you want to bind (default to location of maliput_infrastructure folder).
During docker build stage a script is copied into the container at
Once you finish your setup and tried the workspace, you might want to stage it. You can achieve that
exit-ing the container and accepting to commit the changes.
user@a3b6a70d7b7d:~/maliput_ws$ exit exit access control enabled, only authorized clients can connect Do you want to overwrite the image called 'maliput_ws_ubuntu' with the current changes? [y/n]: y Overwriting docker image... [sudo] password for user: sha256:9fdf391051f702f6b3fcd9c7ab258e5e014361bf18918b86155db3acda355147
Workspace state as a whole encompasses both current local repositories’ state plus the state of the filesystem that hosts it. However, if a workspace is containerized and not customized, repositories alone carry the source code and state the list of system dependencies necessary to build and execute. And we can easily inspect repositories.
To check repositories’ status, run:
vcs status src
To see changes in the repositories’ working tree, run:
vcs diff src
To see if (most of) our versioned packages’ dependencies have been met, run:
rosdep check --rosdistro $ROS_DISTRO --skip-keys "pybind11" --from-paths src
Note: not all workspace prerequisites are handled using
rosdep check may fall short. For example,
pure binary dependencies like
drake‘s binary tarball is not handled by
rosdep. Another example is
In any given case, one can always resort to the specific tool used for repository versioning (e.g.
vcs isn’t enough or to the specific package managers (e.g.
rosdep isn’t enough.
Change the directory to
To build all packages:
To build some packages, use
--packages-up-to. For example, to build
colcon build --packages-up-to maliput maliput_malidrive
To build some packages and only those packages (i.e. without their dependencies),
colcon build --packages-select maliput maliput_malidrive
Note that if dependencies cannot be met, regardless of whether it’s because they are not installed or not built, the build will fail. Thus, this flag is usually helpful only to quickly rebuild a package after building it along with its dependencies.
If you are building
drake from source as well, make sure
--cmake-args -DWITH_PYTHON_VERSION=3 is
colcon. Otherwise, python packages and scripts in
To build with debug symbols, and given that we use CMake packages only, just make sure
CMAKE_BUILD_TYPE=Debug. You can force it by passing
If you want to build with
clang-8, run the following:
LDFLAGS="-fuse-ld=lld-8" CC=clang-8 CXX=clang++-8 colcon build --packages-up-to maliput maliput_malidrive
delphyne is available, run
delphyne-mali to see if everything is working.
See colcon build documentation for further reference on
In a built workspace, run:
colcon test --event-handlers=console_direct+ --return-code-on-test-failure --packages-skip pybind11
See colcon test documentation
for further reference on
To verify your code, run the Clang Static Analyzer.
A useful script called
run_scan_build is located in
.github in every repository.
The script will forward arguments to
colcon build so you can use Colcon’s CLI machinery to choose which packages to
scan-build on all packages in the workspace:
To run scan-build up to
./src/maliput/.github/run_scan_build --packages-up-to maliput_malidrive
Build the workspace. In particular, we are interested in compiling
cd ~/maliput_ws colcon build --packages-up-to dsim_docs_bundler
Open the documentation with your favorite browser. If Google Chrome is available, you can run:
Containerized workspace could be deleted simply deleting the docker image:
docker rmi maliput_ws_ubuntu_focal
maliput_ws_ubuntu_focal by your image name when using a custom one.
Ours is similar to ROS2’s development workflow, and thus many of their tools and practices apply equally.
Workspaces are managed via vcs , a tool that helps in dealing with
sources distributed across multiple repositories, not necessarily versioned with the same tool (support for
bazaar is readily available).
.repos files for a listing of version pinned sources.
Dependency management is taken care of by rosdep,
a tool that can crawl
package.xml files and resolve dependencies into a call to the appropriate package
manager for the current platform by means of a public database known as rosdistro.
To build and test packages, colcon abstracts away the details of the specific build system and testing tools in use and arbitrates these operations to take place in topological order. Operations will be run in parallel by default.
In all three cases above, the tools delegate the actual work to the right tool for each package and
focus instead on bridging the gap between them. Thus, for instance,
colcon builds interdependent
CMake packages by running
make in the right order and setting up the environment for
the artifacts to be available. Same applies for
These tools do not strive to act like a proxy for every configuration setting or command line option
that underlying tools they delegate work to may have. Thus, it may be necessary to configure the underlying
tool in addition to the configuration for these tools to attain a desired behavior. For instance, limiting
colcon parallelism with the
--parallel-workers switch has no impact on
make parallelization settings
if this tool is being used.
In ROS 2 workspace parlance, an overlay workspace is a workspace that builds on top of another, previously built workspace i.e. the underlay workspace. A binary underlay is thus the install space of a pre-built workspace, that packages in downstream workspaces can use to meet their dependencies. As a result, the amount of code that needs to be compiled when building downstream workspaces gets reduced, enabling faster builds. You may refer to colcon documentation and tutorials for further details.
Several binary underlays are available for download and installation:
Built nightly, targeting Ubuntu Focal 20.04 LTS. Contains all known packages in all our repositories as of the specified date (DD/MM/YYYY). To be found at
Built nightly, targeting Ubuntu Focal 20.04 LTS. Contains the most recent versions of all packages known in all our repositories. To be found at
In the following, it is assumed that you want to use a full
dsim-desktop underlay for working on a
downstream package of your own. As such, it suggests the installation of a
dsim-desktop binary underlay,
that brings all known packages in all our repositories. You should choose an underlay that is appropriate for
your intended purpose.
aws s3 cp s3://driving-sim/projects/maliput/packages/nightlies/dsim-desktop-latest-focal.tar.gz \ /path/to/workspace/dsim-desktop-latest-focal.tar.gz
It is assumed that you have the right AWS credentials configured in your system. See AWS CLI user guide to configuration for further reference.
sudo mkdir -p /opt/dsim-desktop sudo tar -zxvf dsim-desktop-latest-focal.tar.gz -C /opt/dsim-desktop --strip 1
echo "deb http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" | \ sudo tee --append /etc/apt/sources.list.d/ros2-latest.list sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 sudo apt update sudo apt install -y python3-rosdep sudo rosdep init
export ROS_DISTRO=foxy rosdep update --include-eol-distros rosdep install -i -y --rosdistro $ROS_DISTRO --skip-keys "pybind11" --from-paths /opt/dsim-desktop/*
cd /opt/dsim-desktop ./drake_vendor/bin/drake_installer -f drake_vendor/share/VERSION.TXT
From then on, before building the workspace, you must source the underlay as follows:
Having an underlay around does not make it a requirement for all workspace builds, but only for those that rely on that underlay to get their dependencies met.
CI jobs build and test relevant packages for each repository on every PR. Being a multi-repository project,
patches that are not limited to a single repository must be separately PR’d but built and tested together.
To that end, make sure that all PR’d branches that are part of the same patch have the same name
Fork based development is currently not supported. All PRs must come from origin and not a fork.
When reproducing issues, either related to the codebase or to the infrastructure that supports it, recreating the environment in which these issues arose is crucial.