ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

How to cleanly handle dependencies in ament?

asked 2018-10-17 01:59:12 -0500

Martin-Idel gravatar image

If I build a library to be used by other ROS 2 developers, what is the way to make it easy to use for downstream packages?

In modern CMake one answer should be exporting targets. This would then allow downstream packages to easily use that target via e.g. find_package(some_dependency REQUIRED) and target_link_libraries(new_target [PUBLIC | PRIVATE | INTERFACE] some_dependency::some_dependency) and if the author of some_dependency has done things right, that's all I have to do as the author of my_target.

Ament_cmake provides help for the exporting mechanism using install(TARGETS my_dependency EXPORT some_dependency ...) and ament_export_interface(some_dependency) (which does the heavy lifting if I'm right). Now if some_dependency itself depends on some_other_dependency, it seems that this dependency must have been added to ament_export_dependencies() for the target some_dependency even if it is not used in any header and could be linked privately. Otherwise I would have to find_package(some_other_dependency) in the build of new_target, which is wrong. This might be an artifact of the problem that it seems impossible to use target_link_libraries together with keywords PUBLIC | PRIVATE | INTERFACE as they are not used internally in ament (at least that's what CMake tells me).

However, there is also ament_target_dependencies() and ament_export_dependencies() and they seem to provide another way of handling dependencies: If I have a ROS 2 package where the export target (if it exists) does not have the same name as the target (then, for some reason, it seems I have to use target_link_libraries, see below for an example), I can just use ament_target_dependencies(new_target some_dependency). If the dependency is used in a header and therefore needs to be linked publicly/by interface, I additionally have to add ament_export_dependency(some_dependency) (in contrast to how I have to use it with exported targets, see above).

What's the preferred way of doing things and how to do this way right?

Some real world examples:

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2018-10-17 12:23:32 -0500

Dirk Thomas gravatar image

ament_cmake_* offers two different approaches to export dependencies:

  • The "classic" CMake approach to export CMake variables like <pkgname>_INCLUDE_DIRECTORIES, <pkgname>_LIBRARIES, etc.

    Related functions are ament_cmake_export_definitions, ament_cmake_export_dependencies, ament_cmake_export_include_directories, ament_cmake_export_libraries. Helper functions like ament_target_dependencies make it easier to use the CMake variables and add "all" of them to a given target.

  • The "modern" CMake approach to export targets.

    The function ament_cmake_export_interfaces does the "heavy lifting" as you mentioned.

A package can decide to use either approach (or both) and downstream packages can use available information accordingly.

Atm almost all ROS 2 packages use the classic approach. The desire / goal would be to use the latter approach everywhere since it provides a cleaner and more precise way (hence it is the modern version).

The the latter approach isn't used much (I am only aware of ament_index_cpp) it might be that the API provided isn't sufficient yet. It seems a function like ament_export_dependency but for the exported target case is missing.

edit flag offensive delete link more


For anyone that finds this answer I just want to throw out there that ament_cmake_export_interfaces appears to now be deprecated and is replaced by ament_cmake_export_targets and ament_cmake_export_dependencies:

I really hope the classical cmake approach gets deprecated altogether (if it's not already) as the modern target based approach is significantly cleaner / easier to use / better in pretty much every way.

strike_eagle_iii gravatar image strike_eagle_iii  ( 2022-05-31 18:48:22 -0500 )edit

Question Tools



Asked: 2018-10-17 01:59:12 -0500

Seen: 3,917 times

Last updated: Oct 17 '18