[REP Index] [REP Source]
REP: | 111 |
---|---|
Title: | Multiple Package Manager Support for Rosdep |
Author: | Tully Foote, Dirk Thomas, Scott K Logan |
Status: | Final |
Type: | Standards Track |
Content-Type: | text/x-rst |
Created: | 28-June-2011 |
ROS-Version: | 1.6 |
Post-History: | 30-Jun-2011, 24-Jan-2018, 12-Nov-2021 |
Contents
This REP add support to the rosdep YAML format [1] to support multiple package managers on an individual platform. This includes a a new 'source' package manager that replacees the previous mechanisms for performing source-based installs.
Previously, the rosdep format has enabled two modes of installation of system dependencies: the platform's preferred package manager, or a custom bash script. Both of these installation mechanisms were limiting.
Using only a single package manager limits integration options on platforms like OS X, where there are multiple mechanisms available for installing system libraries (e.g. MacPorts, distribute/easy_install). For example, for Python libraries, it can be beneficial to use distribute, which works with the default Python installation on OS X 10.6, instead of using the MacPorts Python libraries, which require additional setup by the user.
Similarly, 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.
The current implementation of rosdep in ROS Diamondback [2] supports the following structures:
Simple
ROSDEP_NAME: OS_NAME1: PACKAGE_ARGUMENTS_A OS_NAME2: PACKAGE_ARGUMENTS_AVersioned
ROSDEP_NAME: OS_NAME1: OS_VERSION1: PACKAGE_ARGUMENTS_A OS_VERSION2: PACKAGE_ARGUMENTS_A2
The names above resolve as follows:
- ROSDEP_NAME is the name referred to by manifest files. Examples: log4cxx, gtest.
- OS_NAME is the name of an OS. Examples: ubuntu, fedora, debian, windows, macports.
- OS_VERSION (''optional'') is the name of specific versions in the OS. Examples: '10.04', squeeze. If no OS_VERSION is specified, the rule is assumed to apply to all versions.
- PACKAGE_ARGUMENT has two interpretations. If it is a single line, it is expected to be a list of packages to pass to the package manager for the OS. If this field is a multi-line script, it is an idempotent bash script that is executed to install the dependency.
Example:
python: ubuntu: python-dev fedora: python-devel macports: py26-scipy boost: ubuntu: '11.04': libboost.42-all-dev '10.10': libboost.42-all-dev
For many Linux-based platforms, there are dominant package managers that are the main mechanism for deploying software, such as deb/apt for Debian-based systems and rpm/yum for RedHat-based systems. However, for non-Linux platforms, as well as for cross-platform language environments (e.g. Python, Java, Ruby), there exist other software deployment mechanisms that are commonly used. There are also platforms like OS X and Windows, where no package manager has a dominant role.
On OS X, rosdep currently uses MacPorts as the default package manager. While MacPorts does provide most of the libraries necessary for integrating ROS on an OS X system, the current implementation limits the flexibility of integration options. One area of integration we wish to improve is Python. The MacPorts Python integration requires a separate Python tree from the default OS X Python interpreter. This has proven to be very brittle for users and a common are of misconfiguration. Now that OS X now deploys with a Python version that is compatible with ROS, we wish to explore using distribute/easy_install for Python libraries instead.
The current support for bash scripts requires these scripts to be idempotent: they must detect the presence of the required dependency and install it if it is not present. There is no mechanism for rosdep to determine for itself whether the required dependency is installed, nor is there any mechanism for removing dependencies installed via this mechanism. This creates confusion on the part of the user as there is no mechanism for analyzing whether or not these dependencies are installed correctly. Creating more structure for source-based installations will enable simpler installation scripts, better error reporting, and more advanced features (e.g. uninstall) in the future.
OS X dependencies are specified generally as macports and are not versioned to a particular OS X release. OS X releases frequently have significant differences as Apple does not maintain much backwards compatibility.
The current ROS OS X integration suffers from 32-bit/64-bit compatibility problems due to the OS X 10.6 release. The current rosdep specification also does not allow integrators to take advantage of the builtin Python 2.5+ interpeter that was introduced in the OS X 10.5 release.
Another limitation of the OS X integration is that the rosdep syntax did not allow for specification of MacPorts "variants" for individual packages. The rosdep syntax interpreted the package argument value as a list of packages, which was not flexible enough for specifying variants on specific packages.
The current OS version identifiers use the release number (e.g. 11.04) instead of the release codename (e.g. lucid). Using the release number has been a frequent source of bugs as YAML interprets 11.04 as a floating point number instead of a string. This requires explicit string escaping when specifying rules (e.g. '11.04').
The new specification for rosdep introduces a PACKAGE_MANAGER key in the YAML specification, which is a child key of the OS_NAME. rosdep no longer interprets the PACKAGE_MANAGER_ARGUMENTS and instead passes them to the specified PACKAGE_MANAGER handler.
- Simple
ROSDEP_NAME: OS_NAME1: PACKAGE_MANAGER1: PACKAGE_ARGUMENTS_A OS_NAME2: PACKAGE_MANAGER2: PACKAGE_ARGUMENTS_A
- Versioned
ROSDEP_NAME: OS_NAME1: OS_VERSION1: PACKAGE_MANAGER1: PACKAGE_ARGUMENTS_A OS_VERSION2: PACKAGE_MANAGER2: PACKAGE_ARGUMENTS_A2
The names above resolve as follows:
- ROSDEP_NAME is the name referred to by manifest files. Examples: log4cxx or gtest.
- OS_NAME is the name of an OS. Examples: ubuntu, osx, fedora, debian, or windows.
- OS_VERSION (optional) is the name of specific versions in the OS. Examples: lucid or squeeze. If no OS_VERSION is specified, the rule is assumed to apply to all versions.
- PACKAGE_MANAGER (optional in ROS Electric, required in ROS Fuerte) is a key to select which package manager to use for this rosdep. Examples: apt, easy_install, macports.
- PACKAGE_ARGUMENT is free-form YAML that is be passed to the handler for the specified PACKAGE_MANAGER.
For Ubuntu the default package manager is apt. The new syntax is:
rosdep_name: ubuntu: apt: packages: [ debian-package-name, other-debian-package-name]
or versioned as follows:
rosdep_name: ubuntu: lucid: apt: packages: [debian-package-name, other-debian-package-name]
OS version identifiers will be standardized onto one-word codenames for each distro.
For example:
- debian: squeeze
- ubuntu: lucid, maverick, natty, oneiric
- osx: snow, lion
The OS_NAME key for OS X will be changed to osx and will start including OS_VERSION keys that represent the version number of the OS X releases (e.g. lion). The default package is macports, which can be used as a PACKAGE_MANAGER field.
osx: lion: macports: bzip2
For backwards compatibility, the PACKAGE_MANAGER is allowed to be optional in the ROS Electric case. As both PACKAGE_MANAGER and OS_VERSION are optional, this creates an ambiguious case where either OS_VERSION or PACKAGE_MANAGER is specified, but not both.
In this ambiguous case, rosdep first interprets the key as a PACKAGE_MANAGER. If this test fails, it will be interpreted as an OS_VERSION. Developers should exercise caution in keeping OS_VERSION and PACKAGE_MANAGER keys globally distinct.
Many rosdep keys exist with a generic mapping independent of the OS version. This is great since the rule doesn't have to be updated for new OS versions as long as the system package name stays the same. But when at some point the system package name does change there are only two choices which are both not optimal:
To avoid either of these downsides the OS_VERSION can be specified as *. When a specific rule is being looked up and the desired OS version isn't in the dictionary but an OS_VERSION * is present it will be used as a fallback (instead of failing the lookup).
This allows "future proofing" rosdep rules and avoids the need to update them for every future OS version without requiring an order on those to be defined (which would need to be maintained too).
Since the wildcard matches every not explicitly defined OS_VERSION it is not usable as-is in the following example:
rosdep_name: debian: jessie: [other-name] wheezy: [some-name]
Using the wildcard to use other-name also for newer OS versions would look like this:
rosdep_name: debian: '*': [other-name] wheezy: [some-name]
While other-name will now also be used for newer OS versions like stretch the wildcard will also be used for older releases which are not explicitly defined, like squeeze.
In order to declare that there is no valid mapping for squeeze and still be able to use the wildcard OS version it is allowed to use null as a PACKAGE_ARGUMENT:
rosdep_name: debian: '*': [other-name] squeeze: null wheezy: [some-name]
Some package managers are supported and function on more than one platform, and the names of packages in those package managers are typically the same between platforms. To avoid duplicating the rules under several OS_NAME stanzas the OS_NAME can be specified as * as long as the rule under it specifies the PACKAGE_MANAGER explicitly.
Similar to rule lookups regarding a Wildcard OS_VERSION, an explicit OS_NAME entry will take precedence over * rules entirely and an explicitly null PACKAGE_ARGUMENT for an OS_NAME will omit it from the wildcard.
Although not specified in this REP, developers of new package managers for rosdep are encouraged to include a dependency specification in their PACKAGE_ARGUMENTS values. This dependency specification should enable rosdep rules to specify dependencies on other rosdep rules. This, for example, would enable an easy_install package to also depend on a apt-based install. One use case of this is rosinstall, which can be installed via easy_install, but also implicitly requires non-Python libraries for Git, Subversion, Mercurial, and other non-easy_install packages.
This advisory does not apply to package managers that are builtin to a particular platform, such as apt and yum.
Internally, the rosdep library will provide APIs for developers to trigger installation of these dependencies.
A new source-based package manager is discussed in the motivation for this REP. This specification of this new source-based package manager will be described in a separate forthcoming REP.
rosdep rules are only allowed to specify a single package manager to fulfill them.
All current rosdep.yaml files are compatible with the new proposed syntax, though some features will be deprecated and the files should be upgraded during the ROS Electric cycle to maintain compatibility.
If no package manager is specified, the previous default package manager will be used.
Defaults:
- ubuntu: apt
- debian: apt
- mint: apt
- osx: macports
- freebsd: port
Support for the default package manger will be maintained upto and including ROS Fuerte.
Multi-line values will still be treated as bash scripts in ROS Electric. Support for this will be removed in ROS Fuerte.
The macports rules will be supported during ROS Electric.
For the following codenames backwards compatabilty will be built into the tool to automatically translate rules:
- '10.04' -> lucid
- '10.10' -> maverick
- '11.04' -> natty
It is expected that all future releases will refer to the correct codename, e.g. 'oneiric'.
This will be supported through ROS Fuerte.
The section Wildcard OS_NAME has been added.
The sections Wildcard OS_VERSION and Allow PACKAGE_ARGUMENT to be explicitly null have been added.
[1] | rosdep documentation (http://www.ros.org/wiki/rosdep) |
[2] | rosdep.yaml format in ROS Diamondback (http://www.ros.org/wiki/rosdep/rosdep.yaml/diamondback) |
This document has been placed in the public domain.