diff --git a/source/Tutorials/Intermediate/Rosdep.rst b/source/Tutorials/Intermediate/Rosdep.rst index a6ffdd5d1b..10cbb6490c 100644 --- a/source/Tutorials/Intermediate/Rosdep.rst +++ b/source/Tutorials/Intermediate/Rosdep.rst @@ -2,54 +2,86 @@ Tutorials/Rosdep -.. _rosdep: - Managing Dependencies with rosdep ================================= +.. contents:: Table of Contents + :depth: 2 + :local: + **Goal:** Manage external dependencies using ``rosdep``. **Tutorial level:** Intermediate **Time:** 5 minutes -.. contents:: Contents - :depth: 2 - :local: - -Author: Steve Macenski - This tutorial will explain how to manage external dependencies using ``rosdep``. What is rosdep? --------------- -``rosdep`` is ROS's dependency management utility that can work with ROS packages and external libraries. -``rosdep`` is a command-line utility for identifying and installing dependencies to build or install a package. -It can be or is invoked when: +``rosdep`` is a dependency management utility that can work with packages and external libraries. +It is a command-line utility for identifying and installing dependencies to build or install a package. +``rosdep`` is *not* a package manager in its own right; it is a meta-package manager that uses its own knowledge of the system and the dependencies to find the appropriate package to install on a particular platform. +The actual installation is done using the system package manager (e.g. ``apt`` on Debian/Ubuntu, ``dnf`` on Fedora/RHEL, etc). -- Building a workspace and needing appropriate dependencies to build the packages within -- Install packages (e.g. ``sudo apt install ros-{DISTRO}-demo-nodes-cpp``) to check the dependencies needed for it to execute -- and more! +It is most often invoked before building a workspace, where it is used to install the dependencies of the packages within that workspace. It has the ability to work over a single package or over a directory of packages (e.g. workspace). +.. note:: + + While the name suggests it is for ROS, ``rosdep`` is semi-agnostic to ROS. + You can utilize this powerful tool in non-ROS software projects by installing it as a standalone Python package. + Successfully running ``rosdep`` relies on ``rosdep keys`` to be available, which can be downloaded from a public git repository with a few simple commands. + A little about package.xml files -------------------------------- -A package's ``package.xml`` file contains a set of dependencies. -The dependencies in this file are generally referred to as "rosdep keys". -These are represented in the tags ````, ````, ````, ````, and ````. -They specify in what situation each of the dependencies are required in. - -- For dependencies only used in testing the code (e.g. ``gtest``), use ``test_depend``. -- For dependencies only used in building the code, use ``build_depend``. -- For dependencies needed by headers the code exports, use ``build_export_depend``. -- For dependencies only used when running the code, use ``exec_depend``. -- For mixed purposes, use ``depend``, which covers build, export, and execution time dependencies. +The ``package.xml`` is the file in your software where ``rosdep`` finds the set of dependencies. +It is important that the list of dependencies in the ``package.xml`` is complete and correct, which allows all of the tooling to determine the packages dependencies. +Missing or incorrect dependencies can lead to users not being able to use your package, to packages in a workspace being built out-of-order, and to packages not being able to be released. +The dependencies in the ``package.xml`` file are generally referred to as "rosdep keys". These dependencies are manually populated in the ``package.xml`` file by the package's creators and should be an exhaustive list of any non-builtin libraries and packages it requires. +These are represented in the following tags (see `REP-149 `__ for the full specification): + +```` +^^^^^^^^^^^^ + +These are dependencies that should be provided at both build time and run time for your package. +For C++ packages, if in doubt, use this tag. +Pure Python packages generally don't have a build phase, so should never use this and should use ```` instead. + +```` +^^^^^^^^^^^^^^^^^^ + +If you only use a particular dependency for building your package, and not at execution time, you can use the ```` tag. + +With this type of dependency, an installed binary of your package does not require that particular package to be installed. + +However, that can create a problem if your package exports a header that includes a header from this dependency. +In that case you also need a ````. + +```` +^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you export a header that includes a header from a dependency, it will be needed by other packages that ```` on yours. +This mainly applies to headers and CMake configuration files. +Library packages referenced by libraries you export should normally specify ````, because they are also needed at execution time. + +```` +^^^^^^^^^^^^^^^^^ + +This tag declares dependencies for shared libraries, executables, Python modules, launch scripts and other files required when running your package. + +```` +^^^^^^^^^^^^^^^^^ + +This tag declares dependencies needed only by tests. +Dependencies here should *not* be duplicated with keys specified by ````, ````, or ````. + How does rosdep work? --------------------- @@ -57,7 +89,9 @@ How does rosdep work? These keys are then cross-referenced against a central index to find the appropriate ROS package or software library in various package managers. Finally, once the packages are found, they are installed and ready to go! -The central index is known as ``rosdistro``, which `may be found here `_. +``rosdep`` works by retrieving the central index on to your local machine so that it doesn't have to access the network every time it runs (on Debian/Ubuntu the configuration for it is stored in ``/etc/ros/rosdep/sources.list.d/20-default.list``). + +The central index is known as ``rosdistro``, which `may be found online `_. We'll explore that more in the next section. How do I know what keys to put in my package.xml? @@ -65,19 +99,17 @@ How do I know what keys to put in my package.xml? Great question, I'm glad you asked! -For ROS packages (e.g. ``nav2_bt_navigator``), you may simply place the name of the package. -You can find a list of all released ROS packages in ``rosdistro`` at ``/distribution.yaml`` for your given ROS distribution. +* If the package you want to depend in your package is ROS-based, AND has been released into the ROS ecosystem [1]_, e.g. ``nav2_bt_navigator``, you may simply use the name of the package. You can find a list of all released ROS packages in https://github.com/ros/rosdistro at ``/distribution.yaml`` (e.g. ``humble/distribution.yaml``) for your given ROS distribution. +* If you want to depend on a non-ROS package, something often called "system dependencies", you will need to find the keys for a particular library. In general, there are two files of interest: -For non-ROS package system dependencies, we will need to find the keys for a particular library. -In general, there are two files of interest: ``rosdep/base.yaml`` and ``rosdep/python.yaml``. -``base.yaml`` in general contains the ``apt`` system dependencies. -``python.yaml`` in general contains the ``pip`` python dependencies. + * `rosdep/base.yaml `_ contains the ``apt`` system dependencies + * `rosdep/python.yaml `_ contains the Python dependencies -To find a key, search for your library in this file and find the name in ``yaml`` that contains it. +To find a key, search for your library in these files and find the name. This is the key to put in a ``package.xml`` file. For example, imagine a package had a dependency on ``doxygen`` because it is a great piece of software that cares about quality documentation (hint hint). -We would search ``base.yaml`` for ``doxygen`` and come across: +We would search ``rosdep/base.yaml`` for ``doxygen`` and come across: .. code-block:: yaml @@ -105,10 +137,35 @@ Pull requests for rosdistro are typically merged well within a week. `Detailed instructions may be found here `_ for how to contribute new rosdep keys. If for some reason these may not be contributed openly, it is possible to fork rosdistro and maintain a alternate index for use. - How do I use the rosdep tool? ----------------------------- +rosdep installation +^^^^^^^^^^^^^^^^^^^ + +If you are using ``rosdep`` with ROS, it is conveniently packaged along with the ROS distribution. +This is the recommended way to get ``rosdep``. +You can install it with: + +.. code-block:: bash + + apt-get install python3-rosdep + +.. note:: + + On Debian and Ubuntu, there is another, similarly named package called ``python3-rosdep2``. + If that package is installed, make sure to remove it before installing ``python3-rosdep``. + +If you are using ``rosdep`` outside of ROS, the system package may not be available. +In that case, you can install it directly from https://pypi.org: + +.. code-block:: bash + + pip install rosdep + +rosdep operation +^^^^^^^^^^^^^^^^ + Now that we have some understanding of ``rosdep``, ``package.xml``, and ``rosdistro``, we're ready to use the utility itself! Firstly, if this is the first time using ``rosdep``, it must be initialized via: @@ -135,4 +192,6 @@ Breaking that down: - ``--ignore-src`` means to ignore installing dependencies, even if a rosdep key exists, if the package itself is also in the workspace. There are additional arguments and options available. -Use ``rosdep -h`` to see them. +Use ``rosdep -h`` to see them, or look at the more complete documentation for rosdep at http://docs.ros.org/en/independent/api/rosdep/html/ . + +.. [1] "released into the ROS ecosystem" means the package is listed in one or more of the ``/distribution.yaml`` directories in the `rosdistro database `_.