<NME> 100_ament.md
<BEF> ---
layout: default
title: The build system "ament_cmake" and the meta build tool "ament_tools"
permalink: articles/ament.html
abstract:
  This article describes the build system "ament_cmake" and the meta build tool "ament_tools".
published: true
author: '[Dirk Thomas](https://github.com/dirk-thomas)'
date_written: 2015-07
last_modified: 2018-06
categories: Overview
---

{:toc}

# {{ page.title }}

<div class="abstract" markdown="1">
{{ page.abstract }}
</div>

Authors: {{ page.author }}

Date Written: {{ page.date_written }}

Last Modified: {% if page.last_modified %}{{ page.last_modified }}{% else %}{{ page.date_written }}{% endif %}

<div class="alert alert-warning" markdown="1">
When this article was originally written `ament_tools` was the ROS 2 specific build tool.
The reason was that it needed to be side-by-side installable with existing ROS 1 packages which was a problem due to different targeted Python versions.
In the meantime the problem due to different Python versions has been addressed in shared dependencies like `catkin_pkg`.
As of ROS 2 Bouncy `ament_tools` has been superseded by `colcon` as described in the [universal build tool](http://design.ros2.org/articles/build_tool.html) article.
</div>

## Preface

ROS is developed with a federated model.
While this comes with a lot of advantages it makes the process of building several interdependent packages more complex.

In order to build a set of interdependent packages the user must build them in the correct topological order.
The user must look at the documentation of each package to determine the dependencies, being careful to build those packages before hand, and to determine the instructions for building that package.
Finally the user must build and install each package and do any environment configuration before proceeding to build the next package.

ROS mitigates that complexity with package and build system conventions as well as tools to automate the build process.
Wherever possible ROS uses standard tools, e.g. CMake and Python setuptools.
Where these tools lack built-in support for what ROS needs to do, the additional functionality is provided by ROS.

### Origin of ament

ament is an evolution of [catkin](http://wiki.ros.org/catkin).
The word *ament* is actually a synonym of *catkin*.
For more information about the differences please read [below](#how-is-ament-different-from-catkin).

## ament

ament is a meta build system to improve building applications which are split into separate packages.
It consists of two major parts:

- a *build system* (e.g. CMake, Python setuptools) to configure, build, and install a single package
- a *tool* to invoke the build of individual packages in their topological order

The tool relies on meta information about the packages to determine their dependencies and their build type.
This meta information is defined in a manifest file called `package.xml` which is specified in [REP 140](http://www.ros.org/reps/rep-0140.html).

Each package is built separately with its own build system.
In order to make the output of one package available to other packages each package can extend the environment in a way that downstream packages can find and use its artifacts and resources.
If the resulting artifacts are installed into `/usr`, for example, it might not be necessary to alter the environment at all since these folders are commonly being searched by various tools.

### The ament command line tool

[ament_tools](https://github.com/ament/ament_tools) is a Python package which provides the command line tool `ament` to build, test, install, and uninstall packages.
It is similar to [catkin_tools](https://github.com/catkin/catkin_tools) and builds each package in a workspace in topological order.
Support for different build systems is integrated through extension points which allows support for other build types to be added without changing the ament tool itself.

While it currently does not build packages in parallel that feature will be added in the future to speed up the build process.
The goal is to reuse common functionality from catkin_tools by making it available through a third package which can be used by both tools.

### Integrate arbitrary build systems

Each package can utilize a different build system to perform the steps of configuring, building, and installing.
The build type is defined in each package manifest using the [build_type](http://www.ros.org/reps/rep-0140.html#build-type) tag in the export section.

Currently supported are CMake and Python but support for others (e.g. autotools, plain Makefiles) will likely be added in the future.
For each build system the native steps are being applied separately by the ament tool.

#### Build type: ament_cmake

The CMake package `ament_cmake` provides several convenience functions to make it easier to write CMake-based packages:

- It generates a CMake config file for the package.
  That allows passing information (e.g. about include directories and libraries) to downstream packages.
  Additionally it makes it easy to pass along information from recursive dependencies (and e.g. takes care about the ordering of include directories).

- It provides an easy interface to register tests and ensure that JUnit-compatible result files are generated for those.
  Currently it supports a few different testing frameworks like `nosetests`, `gtest`, and `gmock`.

- It allows a package to generate environment hooks to extend the environment e.g. by extending the `PATH`.

- It provides a CMake API to read and write [ament resource index](https://github.com/ament/ament_cmake/blob/master/ament_cmake_core/doc/resource_index.md) entries.
  The index is built at build time and provides efficient access to information like the available packages, messages, etc.

- It provides an uninstall target for convenience.

Most of these features are implemented in separate packages.
The CMake code uses an extension point system to foster modularity of the code.
This enables others to add further features without requiring to alter existing functionality in the core of ament_cmake.

#### Build type: cmake

The CMake build type uses plain CMake and gives all the flexibility as well as responsibility to the developer.

#### Build type: ament_python

The Python build type allows packages to use setuptools with only a `setup.py` file.
It uses the standard Python work flow to build Python packages.

The ament tool will copy the package manifest into the install location.
It will also extend the environment variables `PYTHONPATH` and `PATH` to include the Python modules and executables provided by the package.

### Environment creation

Commonly the install space should follow the [Filesystem Hierarchy Standard (FHS)](http://www.pathname.com/fhs/).
But that is just a recommendation and not enforced by ament.
### Optional symlinked install

It is very important to maximize the efficiency of the development cycle of changing code, building, and installing it and then run it to confirm the changes.
Commonly the installation steps involves copying some resources from the source space to their final destination in the install location.
ament provides an option to use symbolic links instead (if the platform supports that).
This enables the developer to change the resources in the source space and skipping the installation step in many situations.

Even when the package is built without the ament tool these setup files are being generated.

The different shell scripts in the root of the install space are generated by the ament tool.
The `local_setup.*` files only iterate over all packages in the install space (by reading the list of `packages` in the ament index) and source their package specific setup files.
The `setup.*` files also consider workspaces outside of this install space (by reading the list of `parent_prefixp_path` in the ament index) and source them before the `local_setup.*` files.

### Optional symlinked install

It is very important to maximize the efficiency of the development cycle of changing code, building, and installing it and then run it to confirm the changes.
Commonly the installation steps involve copying some resources from the source space to their final destination in the install location.
ament provides an option to use symbolic links instead (if the platform supports that).
This enables the developer to change the resources in the source space and skipping the installation step in many situations.


ament_auto is similar to catkin_simple.
It aims to simplify writing CMake code for an ament package.
It avoid repetition of dependencies by extracting them from the manifest.
Additionally it automates several steps by relying on conventions, e.g.:

- all information from dependencies are used for compiling and linking of all target
The usage of these linters is optional but it is very easy to integrate them as part of the automated tests of a package.

Linters can also check non-style related criteria.
E.g. [cppcheck](http://cppcheck.sourceforge.net/) is used to statically analyze C / C++ code and check for semantic bugs.

### ament_auto

ament_auto is similar to catkin_simple.
It aims to simplify writing CMake code for an ament package.
It avoids repetition of dependencies by extracting them from the manifest.
Additionally it automates several steps by relying on conventions, e.g.:

- all information from dependencies are used for compiling and linking of all target
- if a package has an `include` folder it adds that folder to the include directories, installs all headers from this folder, and exports the include folder to downstream packages
- if the package contains interface definitions in the `msg` and / or `srv` subfolder they will be processed automatically
- all libraries and executables are being installed to default locations

For an example see [below](#how-is-ament-different-from-catkin).

### Additional resources

The implementation of ament is spread across several repositories:

- [ament_package](https://github.com/ament/ament_package) is a Python package providing an API to parse the files containing the meta information.

- [ament_cmake](https://github.com/ament/ament_cmake) contains a set of packages which provide CMake based functionality.
  The features are split across several packages in order to ensure that they are cleanly separated from each other.

- [ament_lint](https://github.com/ament/ament_lint) contains a set of packages which perform linting tasks.
  For a set of linters a ROS 2 specific configuration is provided which can be used via the command line as well as from within CMake (commonly as a CTest).

- [ament_tools](https://github.com/ament/ament_tools) is a Python package which provides command line tools to build, test, install, and uninstall packages.

- [ament_index](https://github.com/ament/ament_index) contains a set of packages which provide API to access the [ament resource index](https://github.com/ament/ament_cmake/blob/master/ament_cmake_core/doc/resource_index.md).
  Currently it only contains a Python implementation but other languages like C++ should follow.

## How is *ament* different from *catkin*

catkin has been used for ROS 1 since ROS Groovy.
It was developed as a replacement for [rosbuild](http://wiki.ros.org/rosbuild) which was used from the beginning of ROS.
Therefore various features of catkin have been designed to be similar to rosbuild.

### Why not continue to use *catkin*

catkin has many advantages over rosbuild.
Those cover out-of-source builds, automatic CMake config file generation, an installation target and many more.

Over time, however, feedback about the shortcomings of catkin has been collected.
Also additional tools have been developed (like catkin_simple and catkin_tools) to improve the user / developer experience.

This feedback was used to develop the next iteration of catkin which was then called ament.
A few of these cases are mentioned below and all addressed by ament:

#### CMake centric

catkin is based around CMake and even packages only containing Python code are being processed via CMake.
Because of that a setup.py file in a catkin package can only utilize a small subset of features from setuptools.
Common features like extension points are not supported which makes it more difficult to deploy a package on Windows.

#### *Devel space*

catkin has the feature to provide a so called [devel space](http://wiki.ros.org/catkin/workspaces#Development_.28Devel.29_Space) after building a set of packages.
That folder is providing a fully working ROS environment without the need to install the packages.
Avoiding copying any files allows users to e.g. edit Python code and immediately try running the code.

While this is a very convenient feature and speeds up the development process it comes at a cost.
The necessary logic in catkin increases its complexity significantly.
Additionally the CMake code in every ROS package has to make sure to handle the *devel space* correctly which puts an extra effort on every ROS developer.

ament provides the same advantage using the optional feature of *symlinked installs* without the extra complexity for each ROS package.

#### *CMAKE_PREFIX_PATH*

catkin relies directly on the `CMAKE_PREFIX_PATH` environment variable to store the prefixes of multiple workspaces.
This has been considered not a good approach since it interferes with other values set in the variable and is a CMake specific build variable.
Therefore ament uses a separate environment variable (`AMENT_PREFIX_PATH`) for that purpose which is used at runtime.
At build time of CMake packages the CMake specific variable can be derived from the generic ament variable.

#### catkin_simple

The ROS package [catkin_simple](https://github.com/catkin/catkin_simple) was the attempt to make the common cases of developing ROS packages easier.
While it is able to reduce the complexity of the CMake code in some ROS packages it fails conceptually in other cases.
Some of the limitations were due to core catkin design decisions like the order and position of calling certain CMake functions etc.

E.g. the function `catkin_package()` must be invoked *before* any target in order to setup the appropriate location for the build targets in the devel space.
But in order to automatically perform several tasks in the code generation step this functionality needs to happen *after* all target have been defined.

With the different design of ament it becomes possible to implement a package similar to catkin_simple which can actually work reliably in all the cases where catkin_simple fails.

#### Building within a single CMake context

catkin allows users to build multiple packages within a single CMake context (using `catkin_make`).
While this significantly speeds up the process it has several drawbacks.
Since all packages within a workspace share the same CMake context all targets are within the same namespace and must therefore be unique across all packages.
The same applies to global variables, functions, macros, tests, etc.
Furthermore a package might need to declare target level dependencies to targets in other packages to avoid CMake targets being parallelized when they ought to be sequential (but only when being built in the same CMake context).
This requires internal knowledge about the build structure of other packages and subverts the goal of decoupling packages.
ament does not provide that feature due to these drawbacks.

### Additional improvements in ament over catkin

catkin is a single monolithic package providing various features and functionalities.
E.g. it integrates support for `gtest` which makes it very difficult to also optionally support `gmock` since only one tool can be selected at a time.

ament on the other hand is designed to be very modular.
Almost every feature is provided by a separate package and can be optionally used.
The CMake part of ament also features an extension point system to extend it with further functionality (see above).

### Why not evolve *catkin* with the necessary features

One important goal of ROS 2 is to [*not* disrupt ROS 1](http://design.ros2.org/articles/why_ros2.html) in any way.
Any changes to catkin would potentially introduce regressions into ROS 1 which is undesired.

Additionally some necessary changes would require a different usage of catkin in every ROS package.
Releasing such a change into ROS 1 in a future distribution would imply a significant effort for each developer which should also be avoided.
Not to mention the effort to update the documentation and tutorials and making the users aware of the subtle changes.

### Why use a new name instead of continuing to call it *catkin*

For the use case of building a bridge between ROS 1 and ROS 2 it must be possible to access both code bases in a single project.
With both build systems having the same name they would not be distinguishable on a CMake level (which of the two packages is found with `find_package(catkin)`?).
Therefore the package names of both build system must be different.

The newly developed build system has similar CMake functions but they have partly different arguments and / or are being called in different locations.
With both system called the same (or even very similar) a significant user confusion was expected.
Naming the new build system `catkin2` was considered, but the similarity would still have led to user confusion.
Therefore a different name has been selected to clarify the different context and behavior.

### Why has *catkin_pkg* been forked to *ament_package*

ament as well as ROS 2 in general is using Python 3 exclusively.
`catkin_pkg` as well as many other ROS 1 Python packages cannot be side-by-side installed for Python 2 and Python 3 at the same time.
So requiring python3-catkin-pkg for ROS 2 would collide with python-catkin-pkg for ROS 1 and would make both ROS versions not installable at the same time.

ament_package only implements the specification [REP 140](http://www.ros.org/reps/rep-0140.html).
It does not support *package.xml* files with an older format.

Additionally it does provide the templates for all the environment hooks so that each package can generate its own environment and does not rely on an external tool to setup the environment.
Beside that the package provides none of the additional functionalities of catkin_pkg (no crawling, no topological ordering, etc.).

### Example CMakeLists.txt files

The following CMake files are examples showing the similarities and differences between catkin and ament:

- [CMakeLists.txt](https://gist.github.com/dirk-thomas/596a53bbb922c4d6988a) using catkin
- [CMakeLists.txt](https://gist.github.com/dirk-thomas/83ae6bfbfc94e06cd519) using ament
- [CMakeLists.txt](https://gist.github.com/dirk-thomas/a76f952d05e7b21b0128) using ament_auto

<MSG> Fix some typos.
<DFF> @@ -124,7 +124,7 @@ The `setup.*` files also consider workspaces outside of this install space (by r
 ### Optional symlinked install
 
 It is very important to maximize the efficiency of the development cycle of changing code, building, and installing it and then run it to confirm the changes.
-Commonly the installation steps involves copying some resources from the source space to their final destination in the install location.
+Commonly the installation steps involve copying some resources from the source space to their final destination in the install location.
 ament provides an option to use symbolic links instead (if the platform supports that).
 This enables the developer to change the resources in the source space and skipping the installation step in many situations.
 
@@ -144,7 +144,7 @@ E.g. [cppcheck](http://cppcheck.sourceforge.net/) is used to statically analyze
 
 ament_auto is similar to catkin_simple.
 It aims to simplify writing CMake code for an ament package.
-It avoid repetition of dependencies by extracting them from the manifest.
+It avoids repetition of dependencies by extracting them from the manifest.
 Additionally it automates several steps by relying on conventions, e.g.:
 
 - all information from dependencies are used for compiling and linking of all target

{'commit': 'diff --git a/articles/100_ament.md b/articles/100_ament.md\nindex a6adce6..18002a1 100644\n--- a/articles/100_ament.md\n+++ b/articles/100_ament.md\n@@ -124,7 +124,7 @@ The `setup.*` files also consider workspaces outside of this install space (by r\n ### Optional symlinked install\n \n It is very important to maximize the efficiency of the development cycle of changing code, building, and installing it and then run it to confirm the changes.\n-Commonly the installation steps involves copying some resources from the source space to their final destination in the install location.\n+Commonly the installation steps involve copying some resources from the source space to their final destination in the install location.\n ament provides an option to use symbolic links instead (if the platform supports that).\n This enables the developer to change the resources in the source space and skipping the installation step in many situations.\n \n@@ -144,7 +144,7 @@ E.g. [cppcheck](http://cppcheck.sourceforge.net/) is used to statically analyze\n \n ament_auto is similar to catkin_simple.\n It aims to simplify writing CMake code for an ament package.\n-It avoid repetition of dependencies by extracting them from the manifest.\n+It avoids repetition of dependencies by extracting them from the manifest.\n Additionally it automates several steps by relying on conventions, e.g.:\n \n - all information from dependencies are used for compiling and linking of all target\n', 'commit_subject': 'Fix some typos.', 'repo_name': 'ros2/design', 'committer': {'name': 'GitHub', 'email': '1505422b2465e9a84f6fdfaa161078890c593f06@github.com', 'time_sec': '1504451145', 'tz_offset': '120', 'date': {'seconds': '1504451145'}}, 'commit_tree': '58270e7585d108f487409e412c5ad317c20be6df', 'commit_message': 'Fix some typos.', 'language_name': 'Shell', 'license': 'apache-2.0', 'hunks': '@@ -124,7 +124,7 @@ The `setup.*` files also consider workspaces outside of this install space (by r\n ### Optional symlinked install\n \n It is very important to maximize the efficiency of the development cycle of changing code, building, and installing it and then run it to confirm the changes.\n-Commonly the installation steps involves copying some resources from the source space to their final destination in the install location.\n+Commonly the installation steps involve copying some resources from the source space to their final destination in the install location.\n ament provides an option to use symbolic links instead (if the platform supports that).\n This enables the developer to change the resources in the source space and skipping the installation step in many situations.\n \n@@ -144,7 +144,7 @@ E.g. [cppcheck](http://cppcheck.sourceforge.net/) is used to statically analyze\n \n ament_auto is similar to catkin_simple.\n It aims to simplify writing CMake code for an ament package.\n-It avoid repetition of dependencies by extracting them from the manifest.\n+It avoids repetition of dependencies by extracting them from the manifest.\n Additionally it automates several steps by relying on conventions, e.g.:\n \n - all information from dependencies are used for compiling and linking of all target\n', 'addition_count': 2, 'deletion_count': 2, 'src_file': 'a/articles/100_ament.md', 'tgt_file': 'b/articles/100_ament.md', 'file_extension': '.md', 'before_file': '---\nlayout: default\ntitle: The build system "ament_cmake" and the meta build tool "ament_tools"\npermalink: articles/ament.html\nabstract:\n  This article describes the build system "ament_cmake" and the meta build tool "ament_tools".\npublished: true\nauthor: \'[Dirk Thomas](https://github.com/dirk-thomas)\'\ndate_written: 2015-07\nlast_modified: 2018-06\ncategories: Overview\n---\n\n{:toc}\n\n# {{ page.title }}\n\n<div class="abstract" markdown="1">\n{{ page.abstract }}\n</div>\n\nAuthors: {{ page.author }}\n\nDate Written: {{ page.date_written }}\n\nLast Modified: {% if page.last_modified %}{{ page.last_modified }}{% else %}{{ page.date_written }}{% endif %}\n\n<div class="alert alert-warning" markdown="1">\nWhen this article was originally written `ament_tools` was the ROS 2 specific build tool.\nThe reason was that it needed to be side-by-side installable with existing ROS 1 packages which was a problem due to different targeted Python versions.\nIn the meantime the problem due to different Python versions has been addressed in shared dependencies like `catkin_pkg`.\nAs of ROS 2 Bouncy `ament_tools` has been superseded by `colcon` as described in the [universal build tool](http://design.ros2.org/articles/build_tool.html) article.\n</div>\n\n## Preface\n\nROS is developed with a federated model.\nWhile this comes with a lot of advantages it makes the process of building several interdependent packages more complex.\n\nIn order to build a set of interdependent packages the user must build them in the correct topological order.\nThe user must look at the documentation of each package to determine the dependencies, being careful to build those packages before hand, and to determine the instructions for building that package.\nFinally the user must build and install each package and do any environment configuration before proceeding to build the next package.\n\nROS mitigates that complexity with package and build system conventions as well as tools to automate the build process.\nWherever possible ROS uses standard tools, e.g. CMake and Python setuptools.\nWhere these tools lack built-in support for what ROS needs to do, the additional functionality is provided by ROS.\n\n### Origin of ament\n\nament is an evolution of [catkin](http://wiki.ros.org/catkin).\nThe word *ament* is actually a synonym of *catkin*.\nFor more information about the differences please read [below](#how-is-ament-different-from-catkin).\n\n## ament\n\nament is a meta build system to improve building applications which are split into separate packages.\nIt consists of two major parts:\n\n- a *build system* (e.g. CMake, Python setuptools) to configure, build, and install a single package\n- a *tool* to invoke the build of individual packages in their topological order\n\nThe tool relies on meta information about the packages to determine their dependencies and their build type.\nThis meta information is defined in a manifest file called `package.xml` which is specified in [REP 140](http://www.ros.org/reps/rep-0140.html).\n\nEach package is built separately with its own build system.\nIn order to make the output of one package available to other packages each package can extend the environment in a way that downstream packages can find and use its artifacts and resources.\nIf the resulting artifacts are installed into `/usr`, for example, it might not be necessary to alter the environment at all since these folders are commonly being searched by various tools.\n\n### The ament command line tool\n\n[ament_tools](https://github.com/ament/ament_tools) is a Python package which provides the command line tool `ament` to build, test, install, and uninstall packages.\nIt is similar to [catkin_tools](https://github.com/catkin/catkin_tools) and builds each package in a workspace in topological order.\nSupport for different build systems is integrated through extension points which allows support for other build types to be added without changing the ament tool itself.\n\nWhile it currently does not build packages in parallel that feature will be added in the future to speed up the build process.\nThe goal is to reuse common functionality from catkin_tools by making it available through a third package which can be used by both tools.\n\n### Integrate arbitrary build systems\n\nEach package can utilize a different build system to perform the steps of configuring, building, and installing.\nThe build type is defined in each package manifest using the [build_type](http://www.ros.org/reps/rep-0140.html#build-type) tag in the export section.\n\nCurrently supported are CMake and Python but support for others (e.g. autotools, plain Makefiles) will likely be added in the future.\nFor each build system the native steps are being applied separately by the ament tool.\n\n#### Build type: ament_cmake\n\nThe CMake package `ament_cmake` provides several convenience functions to make it easier to write CMake-based packages:\n\n- It generates a CMake config file for the package.\n  That allows passing information (e.g. about include directories and libraries) to downstream packages.\n  Additionally it makes it easy to pass along information from recursive dependencies (and e.g. takes care about the ordering of include directories).\n\n- It provides an easy interface to register tests and ensure that JUnit-compatible result files are generated for those.\n  Currently it supports a few different testing frameworks like `nosetests`, `gtest`, and `gmock`.\n\n- It allows a package to generate environment hooks to extend the environment e.g. by extending the `PATH`.\n\n- It provides a CMake API to read and write [ament resource index](https://github.com/ament/ament_cmake/blob/master/ament_cmake_core/doc/resource_index.md) entries.\n  The index is built at build time and provides efficient access to information like the available packages, messages, etc.\n\n- It provides an uninstall target for convenience.\n\nMost of these features are implemented in separate packages.\nThe CMake code uses an extension point system to foster modularity of the code.\nThis enables others to add further features without requiring to alter existing functionality in the core of ament_cmake.\n\n#### Build type: cmake\n\nThe CMake build type uses plain CMake and gives all the flexibility as well as responsibility to the developer.\n\n#### Build type: ament_python\n\nThe Python build type allows packages to use setuptools with only a `setup.py` file.\nIt uses the standard Python work flow to build Python packages.\n\nThe ament tool will copy the package manifest into the install location.\nIt will also extend the environment variables `PYTHONPATH` and `PATH` to include the Python modules and executables provided by the package.\n\n### Environment creation\n\nCommonly the install space should follow the [Filesystem Hierarchy Standard (FHS)](http://www.pathname.com/fhs/).\nBut that is just a recommendation and not enforced by ament.\n### Optional symlinked install\n\nIt is very important to maximize the efficiency of the development cycle of changing code, building, and installing it and then run it to confirm the changes.\nCommonly the installation steps involves copying some resources from the source space to their final destination in the install location.\nament provides an option to use symbolic links instead (if the platform supports that).\nThis enables the developer to change the resources in the source space and skipping the installation step in many situations.\n\nEven when the package is built without the ament tool these setup files are being generated.\n\nThe different shell scripts in the root of the install space are generated by the ament tool.\nThe `local_setup.*` files only iterate over all packages in the install space (by reading the list of `packages` in the ament index) and source their package specific setup files.\nThe `setup.*` files also consider workspaces outside of this install space (by reading the list of `parent_prefixp_path` in the ament index) and source them before the `local_setup.*` files.\n\n### Optional symlinked install\n\nIt is very important to maximize the efficiency of the development cycle of changing code, building, and installing it and then run it to confirm the changes.\nCommonly the installation steps involve copying some resources from the source space to their final destination in the install location.\nament provides an option to use symbolic links instead (if the platform supports that).\nThis enables the developer to change the resources in the source space and skipping the installation step in many situations.\n\n\nament_auto is similar to catkin_simple.\nIt aims to simplify writing CMake code for an ament package.\nIt avoid repetition of dependencies by extracting them from the manifest.\nAdditionally it automates several steps by relying on conventions, e.g.:\n\n- all information from dependencies are used for compiling and linking of all target\nThe usage of these linters is optional but it is very easy to integrate them as part of the automated tests of a package.\n\nLinters can also check non-style related criteria.\nE.g. [cppcheck](http://cppcheck.sourceforge.net/) is used to statically analyze C / C++ code and check for semantic bugs.\n\n### ament_auto\n\nament_auto is similar to catkin_simple.\nIt aims to simplify writing CMake code for an ament package.\nIt avoids repetition of dependencies by extracting them from the manifest.\nAdditionally it automates several steps by relying on conventions, e.g.:\n\n- all information from dependencies are used for compiling and linking of all target\n- if a package has an `include` folder it adds that folder to the include directories, installs all headers from this folder, and exports the include folder to downstream packages\n- if the package contains interface definitions in the `msg` and / or `srv` subfolder they will be processed automatically\n- all libraries and executables are being installed to default locations\n\nFor an example see [below](#how-is-ament-different-from-catkin).\n\n### Additional resources\n\nThe implementation of ament is spread across several repositories:\n\n- [ament_package](https://github.com/ament/ament_package) is a Python package providing an API to parse the files containing the meta information.\n\n- [ament_cmake](https://github.com/ament/ament_cmake) contains a set of packages which provide CMake based functionality.\n  The features are split across several packages in order to ensure that they are cleanly separated from each other.\n\n- [ament_lint](https://github.com/ament/ament_lint) contains a set of packages which perform linting tasks.\n  For a set of linters a ROS 2 specific configuration is provided which can be used via the command line as well as from within CMake (commonly as a CTest).\n\n- [ament_tools](https://github.com/ament/ament_tools) is a Python package which provides command line tools to build, test, install, and uninstall packages.\n\n- [ament_index](https://github.com/ament/ament_index) contains a set of packages which provide API to access the [ament resource index](https://github.com/ament/ament_cmake/blob/master/ament_cmake_core/doc/resource_index.md).\n  Currently it only contains a Python implementation but other languages like C++ should follow.\n\n## How is *ament* different from *catkin*\n\ncatkin has been used for ROS 1 since ROS Groovy.\nIt was developed as a replacement for [rosbuild](http://wiki.ros.org/rosbuild) which was used from the beginning of ROS.\nTherefore various features of catkin have been designed to be similar to rosbuild.\n\n### Why not continue to use *catkin*\n\ncatkin has many advantages over rosbuild.\nThose cover out-of-source builds, automatic CMake config file generation, an installation target and many more.\n\nOver time, however, feedback about the shortcomings of catkin has been collected.\nAlso additional tools have been developed (like catkin_simple and catkin_tools) to improve the user / developer experience.\n\nThis feedback was used to develop the next iteration of catkin which was then called ament.\nA few of these cases are mentioned below and all addressed by ament:\n\n#### CMake centric\n\ncatkin is based around CMake and even packages only containing Python code are being processed via CMake.\nBecause of that a setup.py file in a catkin package can only utilize a small subset of features from setuptools.\nCommon features like extension points are not supported which makes it more difficult to deploy a package on Windows.\n\n#### *Devel space*\n\ncatkin has the feature to provide a so called [devel space](http://wiki.ros.org/catkin/workspaces#Development_.28Devel.29_Space) after building a set of packages.\nThat folder is providing a fully working ROS environment without the need to install the packages.\nAvoiding copying any files allows users to e.g. edit Python code and immediately try running the code.\n\nWhile this is a very convenient feature and speeds up the development process it comes at a cost.\nThe necessary logic in catkin increases its complexity significantly.\nAdditionally the CMake code in every ROS package has to make sure to handle the *devel space* correctly which puts an extra effort on every ROS developer.\n\nament provides the same advantage using the optional feature of *symlinked installs* without the extra complexity for each ROS package.\n\n#### *CMAKE_PREFIX_PATH*\n\ncatkin relies directly on the `CMAKE_PREFIX_PATH` environment variable to store the prefixes of multiple workspaces.\nThis has been considered not a good approach since it interferes with other values set in the variable and is a CMake specific build variable.\nTherefore ament uses a separate environment variable (`AMENT_PREFIX_PATH`) for that purpose which is used at runtime.\nAt build time of CMake packages the CMake specific variable can be derived from the generic ament variable.\n\n#### catkin_simple\n\nThe ROS package [catkin_simple](https://github.com/catkin/catkin_simple) was the attempt to make the common cases of developing ROS packages easier.\nWhile it is able to reduce the complexity of the CMake code in some ROS packages it fails conceptually in other cases.\nSome of the limitations were due to core catkin design decisions like the order and position of calling certain CMake functions etc.\n\nE.g. the function `catkin_package()` must be invoked *before* any target in order to setup the appropriate location for the build targets in the devel space.\nBut in order to automatically perform several tasks in the code generation step this functionality needs to happen *after* all target have been defined.\n\nWith the different design of ament it becomes possible to implement a package similar to catkin_simple which can actually work reliably in all the cases where catkin_simple fails.\n\n#### Building within a single CMake context\n\ncatkin allows users to build multiple packages within a single CMake context (using `catkin_make`).\nWhile this significantly speeds up the process it has several drawbacks.\nSince all packages within a workspace share the same CMake context all targets are within the same namespace and must therefore be unique across all packages.\nThe same applies to global variables, functions, macros, tests, etc.\nFurthermore a package might need to declare target level dependencies to targets in other packages to avoid CMake targets being parallelized when they ought to be sequential (but only when being built in the same CMake context).\nThis requires internal knowledge about the build structure of other packages and subverts the goal of decoupling packages.\nament does not provide that feature due to these drawbacks.\n\n### Additional improvements in ament over catkin\n\ncatkin is a single monolithic package providing various features and functionalities.\nE.g. it integrates support for `gtest` which makes it very difficult to also optionally support `gmock` since only one tool can be selected at a time.\n\nament on the other hand is designed to be very modular.\nAlmost every feature is provided by a separate package and can be optionally used.\nThe CMake part of ament also features an extension point system to extend it with further functionality (see above).\n\n### Why not evolve *catkin* with the necessary features\n\nOne important goal of ROS 2 is to [*not* disrupt ROS 1](http://design.ros2.org/articles/why_ros2.html) in any way.\nAny changes to catkin would potentially introduce regressions into ROS 1 which is undesired.\n\nAdditionally some necessary changes would require a different usage of catkin in every ROS package.\nReleasing such a change into ROS 1 in a future distribution would imply a significant effort for each developer which should also be avoided.\nNot to mention the effort to update the documentation and tutorials and making the users aware of the subtle changes.\n\n### Why use a new name instead of continuing to call it *catkin*\n\nFor the use case of building a bridge between ROS 1 and ROS 2 it must be possible to access both code bases in a single project.\nWith both build systems having the same name they would not be distinguishable on a CMake level (which of the two packages is found with `find_package(catkin)`?).\nTherefore the package names of both build system must be different.\n\nThe newly developed build system has similar CMake functions but they have partly different arguments and / or are being called in different locations.\nWith both system called the same (or even very similar) a significant user confusion was expected.\nNaming the new build system `catkin2` was considered, but the similarity would still have led to user confusion.\nTherefore a different name has been selected to clarify the different context and behavior.\n\n### Why has *catkin_pkg* been forked to *ament_package*\n\nament as well as ROS 2 in general is using Python 3 exclusively.\n`catkin_pkg` as well as many other ROS 1 Python packages cannot be side-by-side installed for Python 2 and Python 3 at the same time.\nSo requiring python3-catkin-pkg for ROS 2 would collide with python-catkin-pkg for ROS 1 and would make both ROS versions not installable at the same time.\n\nament_package only implements the specification [REP 140](http://www.ros.org/reps/rep-0140.html).\nIt does not support *package.xml* files with an older format.\n\nAdditionally it does provide the templates for all the environment hooks so that each package can generate its own environment and does not rely on an external tool to setup the environment.\nBeside that the package provides none of the additional functionalities of catkin_pkg (no crawling, no topological ordering, etc.).\n\n### Example CMakeLists.txt files\n\nThe following CMake files are examples showing the similarities and differences between catkin and ament:\n\n- [CMakeLists.txt](https://gist.github.com/dirk-thomas/596a53bbb922c4d6988a) using catkin\n- [CMakeLists.txt](https://gist.github.com/dirk-thomas/83ae6bfbfc94e06cd519) using ament\n- [CMakeLists.txt](https://gist.github.com/dirk-thomas/a76f952d05e7b21b0128) using ament_auto\n', 'message': 'Fix some typos.', 'author_name': 'GitHub', 'lang': 'md'}