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

ament_cmake: Confused about ament_export_dependencies and ament_export_interfaces

asked 2019-08-21 14:26:21 -0600

DanRose gravatar image

I'm programming on ROS2 Dashing and trying to port some packages, but the ament_cmake docs haven't answered my questions

What does ament_export_dependencies(my_target ...) actually do? Why is it needed if I already declared my dependencies with ament_target_dependencies(my_target ...) or target_link_libraries(my_target PUBLIC ...)?

Finally, why do I hardly see ament_export_interfaces(${PROJECT_NAME} HAS_LIBRARY_TARGET) in the ROS2 codebase if that's the recommended way to expose library projects for downstream consumption?

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2019-08-21 15:59:02 -0600

sloretz gravatar image

In your example you have ament_export_dependencies(my_target), but that's incorrect. ament_export_dependencies() takes only package names.

In short, ament_target_dependencies() sets up stuff for your package, ament_export_dependencies() and ament_export_interfaces() set up stuff for packages that depend on your package.

When a package calls find_package(MyDependency), CMake looks for a file called mydependency-config.cmake or MyDependency-config.cmake. CMake documentation calls this a ProjectConfig.cmake file. The ProjectConfig.cmake sets up everything another project would need to depend on this one. It sets variables like MyDependency_INCLUDE_DIRS, creates imported targets like MyDependency::somelibrary, and finds packages MyDependency depends on.

First your package needs to use MyDependency when it's being built. ament_target_dependencies(my_target MyDependency) is a helper function that makes sure your executable or library has everything it needs to use MyDependency. It will call target_link_libraries(my_target ${MyDependency_LIBRARIES}), target_include_directories(my_target PUBLIC ${MyDependency_INCLUDE_DIRS}), etc.

Once your package is built/installed, other packages might need MyDependency too. For example, if your package includes <my_depdenency/something.hpp> in a header it installs, then packages that include your header will need to know where MyDependency's headers are too. This is where ament_export_dependencies() comes in . Calling ament_export_dependencies(MyDependency) will make your package's ProjectConfig.cmake contain a find_package(MyDependency) call plus logic to combine CMake variables from MyDependency into your package's CMake variables. For example, it will make YourPackage_INCLUDE_DIRS contain everything in MyDependency_INCLUDE_DIRS. The purpose is so packages don't have to find your dependencies. Use ament_export_dependencies() on all dependencies of yours that downstream packages also need.

ament_export_interfaces() is a little different. This creates imported targets, which is a replacement for CMake standard variables in a ProjectConfig.cmake. It will likely be used more in the future, but for now there is at least one issue with it that needs to be fixed. It won't replace ament_export_dependencies(), but it will change how information like include directories and libraries are communicated between packages.

edit flag offensive delete link more


Thank you! So what about the PUBLIC/PRIVATE/INTERFACE specifiers on target_link_libraries and target_include_directories? What effect (if any) do these have on consumers of my package/library?

DanRose gravatar image DanRose  ( 2019-08-21 16:22:39 -0600 )edit

My understanding of those is lacking. On consumers of your package? I think the keywords only have an effect on consumers if your package export targets. They do have an effect within targets of your package, but the CMake documentation for target_include_directories() and probably explains better than I can.

sloretz gravatar image sloretz  ( 2019-08-21 16:38:11 -0600 )edit

I submitted an issue, as this seems like a bug that it affects people who link to my library via ament_target_dependencies but not via target_link_libraries.

DanRose gravatar image DanRose  ( 2019-08-21 17:30:27 -0600 )edit

when you say ament_export_dependencies takes only package names, does it only take ros package names or can it take system installed dependencies such Eigen, OpenCV, or my own custom non-ros2 libraries?

strike_eagle_iii gravatar image strike_eagle_iii  ( 2022-05-27 18:21:59 -0600 )edit

Question Tools



Asked: 2019-08-21 14:26:21 -0600

Seen: 2,262 times

Last updated: Aug 21 '19