REP: 112 Title: Source Package Manager for Rosdep Author: Tully Foote Status: Final Type: Standards Track Content-Type: text/x-rst Created: 29-June-2011 ROS-Version: 1.6 Post-History: 05-Jul-2011
This REP defines a new "source" package manager for rosdep [1] that improves source-based installation of system dependencies. The new source package manager provides scripts for installing dependencies and verifying that they are present. This REP builds on the new rosdep syntax introduced in REP 111 [2].
The motivation for this REP is similar to REP 111 [2]. To quote from REP 111:
... the bash script specification was brittle and provided limited information to rosdep itself. The scripts were required to be idempotent because rosdep was unable to detect whether or not the dependency was already installed.
The goal of this REP is to make rosdep more robust and flexible, as well as enable better support of platforms other than Ubuntu.
This REP specifically introduces a custom rosdep package manager that provides a new mechanism for source-based installations of software libraries. The goals for this new package manager are:
- Reliable, source-based installation of thirdparty libraries for any ROS platform.
- Enable rosdep to check that source-based dependencies are present.
- Allow source rosdeps to have prerequisites, i.e. to depend on other rosdeps.
- Enable any community member to contribute rosdep-compatible packaging for libraries.
- Enable automated verification of source-based dependencies without superuser access.
- Reduce duplication in rosdep source installation rules.
There are several anticipated use cases for this new source-based package manager. The first is to provide generic scripts for POSIX-based systems for common thirdparty libraries. These generally can be improved by integrating the native package manager for that platform, but the source mechanism provides an initial working system.
A new, anticipated use case is improving support for ROS on platforms that lack official package managers. For example, support for ROS on Windows is improving and will soon require better infrastructure for satisfying rosdep dependencies. Similarly, although OS X users can use MacPorts for rosdep dependencies, this REP provides an alternative mechanism that is more stable and easier to lock to specific OS X versions.
According to REP 111 [2], the basic syntax for a rosdep.yaml rule is:
ROSDEP_NAME: OS_NAME1: PACKAGE_MANAGER1: PACKAGE_ARGUMENTS_A OS_NAME2: PACKAGE_MANAGER2: PACKAGE_ARGUMENTS_A
The source package manager defines the PACKAGE_MANAGER
and PACKAGE_ARGUMENTS
fields as follows:
PACKAGE_MANAGER
issource
PACKAGE_ARGUMENTS
: thesource
package manager accepts a dictionary with three possible keys:
uri
(string): the primary download uri for the rosdep manifest (required).alternate-uri
(string): a mirror download uri for the rosdep manifest (optional).md5sum
(string): md5sum hash of the rdmanifest for security and verification. (optional, recommended)
As defined by REP 111, the use of the source
package manager is
specific to a OS platform.
The use of the md5sum
field is strongly recommended. It
provides protection against thirdparty library installs being
compromised either due to corruption or malicious intent. It also
enables the downloaded file to be verified for completeness.
The following example is a plausible rosdep.yaml rule for installing the yaml-cpp library on an Ubuntu system. This rule references an external rosdep manifest file, as well as an mirror of this installation for additional robustness.
yaml-cpp: ubuntu: source: uri: 'https://kforge.ros.org/rosrelease/viewvc/sourcedeps/yaml-cpp/yaml-cpp-0.2.5.rdmanifest' alternate-uri: 'https://mirror-kforge.ros.org/rosrelease/viewvc/sourcedeps/yaml-cpp/yaml-cpp-0.2.5.rdmanifest' md5sum: 740a2193cea112f5ef682d9f69f9c7b1
The rosdep.yaml
rule for the source package manager points to an
external rosdep manifest (.rdmanifest
) file that provides the
necessary URLs and scripts for managing a system dependency.
There may one or more than one .rdmanifest
file for a given
software package dependencing on the installation and platforms needs
of the software. For example, a single .rdmanifest
file may be
sufficient for POSIX-based systems, but a separate .rdmanifest
may
be necessary for OS X systems. This choice is not enforced by this
REP and is up to the developer providing the integration.
The rosdep manifest (.rdmanifest
) file has 6 fields:
uri
(string): The uri of the tarball to download.md5sum
(string): The expected md5sum of the tarball (recommended)alternate-uri
(string): An optional alternate-uri for reliability (recommended)check-presence-script
(multi-line string): a script that exits with return code zero if a package is already present, non-zero otherwise. This script is downloaded to a temporary file and executed with the user's account.install-script
(multi-line string): a script that installs software library from tarball. The script is downloaded to a temporary file and executed with the user's account. The working directory set to theexec-path
, which is generally the directory where the unpacked tarball is located.exec-path
(string): relative path used to specify working directory of theinstall-script
(optional). The path is interpreted to be relative to the directory the tarball is downloaded and unpacked to.exec-path
is optional and defaults to '.', i.e. the directory of the tarball.depends
(string list): list of rosdep dependencies that must be installed before checking or installing this rosdep.
The check-presence-script
and install-script
are text-based
scripts that are downloaded and executed by rosdep. rosdep will
assign these scripts an executable permission and they may be written
in any executable text format supported by the target platform.
For example, on POSIX-based systems, scripts can use a shebang to
specify the desired interpreter of the script, such as #!/bin/sh
or #!/usr/bin/env python
.
The scripts are executed using the user's account. In the event that
a script requires superuser access, it must explicitly invokes
commands like sudo
on its own. It is strongly recommended that
the check-presence-script
not use any superuser privileges as this
interferes with automated verification of dependencies. This
recommendation is only for the check-presence-script
as it is
expected that an install-script
will need to use superuser
permissions for final install steps, e.g. make install
.
In the event that rosdep determines that the source package manager is responsible for a rosdep dependency, the following steps are taken by the source package manager to verify a system dependency is installed.
- Download the
.rdmanifset
file referenced by theuri
rule. If the primaryuri
is unavailable, attempt to download thealternate-uri
.- If md5sum is specified, validate the md5sum of the
.rdmanifest
file.- Verify that all rosdep dependencies specified in
depends
in the.rdmanifest
are installed.- Download the
check-presence-script
specified in the.rdmanifest
file.- Execute the
check-presence-script
with the current user's account.
If the script returns zero, the installation is assumed to be present. Otherwise, rosdep may determine that it is necessary to perform an installation of this dependency. If the source package manager is asked to install a dependency, the following steps are followed:
- Download the tarball specified in the
uri
rule. If the primaryuri
is unavailable, attempt to download thealternate-uri
.- If md5sum is specified, validate the md5sum of the tarball.
- Unpack the tarball.
- Download the
install-script
specified in the.rdmanifest
file. The working directory of theinstall-script
specified byexec-path
, which defaults to the directory the tarball is unpacked to.- Execute the
install-script
with the current user's account.
The following example demonstrates a plausible rosdep manifest file
for the yaml-cpp library. This particular rosdep manifest file
leverages the dpkg
tool and thus will only work on Debian-based
systems. A more generic rosdep manifest file could be written to work
on a greater variety of platforms, or different rosdep manifest files
could be written to support other platforms.
uri: 'https://kforge.ros.org/rosrelease/viewvc/sourcedeps/yaml-cpp/yaml-cpp-0.2.5.tar.gz' md5sum: b17dc36055cd2259c88b2602601415d9 install-script: | #!/bin/bash set -o errexit mkdir -p build cd build cmake .. make echo "About to run checkinstall make install" sudo checkinstall -y --nodoc --pkgname=yaml-cpp-sourcedep make install check-presence-script: | #!/bin/bash dpkg-query -W -f='${Package} ${Status}\n' yaml-cpp-sourcedep | awk '{\ if ($4 =="installed") exit 0 else print "yaml-cpp-sourcedep not installed" exit 1}' exec-path: yaml-cpp-0.2.5 depends: [checkinstall ]
The rosdep manifest file follows the recommendation of REP 111 and
provides a dependency specification. The depends
syntax in the
rosdep manifest provides greater flexibility when integrating software
packages. It functions similar to dpkg and rpm dependencies,
where it provides an ordering for installing a hierarchical set of
libraries. It also enables developers to use multiple package
managers to satisfy dependencies. For example, the library could
specify dependencies that resolve to apt
or yum
installations,
and then perform a source-based install on top.
The new rosdep manifest files provides for a separation of roles when
integrating libraries into rosdep: those that provide wrappers for
thirdparty libraries to be used in ROS, and those that integrate these
into rosdep.yaml
files in a ROS stack hierarchy. Authors of
thirdparty libraries can provide integration with rosdep without
having to release separate ROS stacks.
This approach does comes with some disadvantages. In the previous
implementation of source-based installs for rosdep, the entire
installation script was contained within the rosdep.yaml
rule.
This enabled the rosdep.yaml
file to be complete: no additional
specifications were necessary, other than implicit resources
referenced by the script. REP 111 instead requires developers to also
to create and host a separate rosdep manifest file.
Although this separation has additional overhead, it has benefits beyond the separation of roles described above. First, the inline syntax leads to more duplication. Two platforms wishing to both used a source-based install must repeat the entire rule separately, even if the rules are identical.
The old inline approach also led to repetition in cases where two ROS
stacks, without a common ancestor, wished to integrate the same rosdep
library. As these stacks do not have a common ancestor, each stack
must add the rosdep library in its own rosdep.yaml
file. This REP
reduces the duplication as each rosdep.yaml
file only needs to
point at the external rosdep manifest file.
Finally, the inline syntax of the old rosdep format decreased the
readability of the rosdep.yaml
files. which is an important
concern when maintaining these files over time.
[1] | rosdep documentation (http://www.ros.org/wiki/rosdep) |
[2] | (1, 2, 3) REP 111: Multiple Package Manager Support for Rosdep (http://www.ros.org/reps/rep-0111.html) |
[3] | rosdep.yaml format in ROS Diamondback (http://www.ros.org/wiki/rosdep/rosdep.yaml/diamondback) |
This document has been placed in the public domain.