Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide documented CMake exported namespace targets for consuming generated packages without ament_target_dependencies #746

Open
Ryanf55 opened this issue May 25, 2023 · 1 comment
Labels
backlog help wanted Extra attention is needed

Comments

@Ryanf55
Copy link

Ryanf55 commented May 25, 2023

Feature request

Make it easier and more obvious how to consume targets from message packages with target_link_libraries.

Feature description

Using ament_target_dependences, you pass in the CMake project name, and it figures out all the targets for you, performing linking as well as sorting out include directories.

Alternatively, you can use a module-style option with raw CMake like so, where bar_msgs is the message package that calls rosidl_generate_interfaces and foo is the consuming package

find_package(bar_msgs CONFIG REQUIRED)
target_link_libraries(foo PUBLIC ${bar_msgs_TARGETS}

The bar_msgs_TARGETS variable is not a required variable to export according to CMake's find_package docs, however, it is being adopted as an alternative in packages for the time being.

Commonly, in other ROS libraries, in order to use the "modern" CMake targets, exported namespaced targets are provided like so:

find_package(rclcpp CONFIG REQUIRED)
target_link_libraries(foo PUBLIC rclcpp::rclcpp)

Exported namespace targets provide clear advantages in that the target_link_libraries fails if the target is not found. No more include errors or linker errors if you spelled bar_msgs_TARGETS wrong. It is thus desirable for packages generated with rosidl to supply a bar::bar target to consumers. For reference: ros2/rclcpp#2055

Thus, the desired usage to link everything:

find_package(bar_msgs CONFIG REQUIRED)
target_link_libraries(foo PUBLIC bar_msgs::bar_msgs)

OR, for as example, a C++ algorithm package that just needs the message definitions (currently works in humble):

find_package(bar_msgs CONFIG REQUIRED)
target_link_libraries(foo PUBLIC bar_msgs::bar_msgs__rosidl_generator_cpp)

While some of these ALIAS targets are exported, there are a few known issues:

  1. There are exported namespace targets for individual generated parts, but not a top level bar::bar target
  2. It is still desireable to provide the lower level generated targets for packages that just want message definitions, such as an algorithm package that doesn't want additional dependencies
  3. The ROS maintainers have indicated the ROS message generation is tricky, but acknowledge making them easier to consume in modern namespaced CMake target is desired.

Implementation considerations

The exported CMake target names are considered part of a package's public API. CMake lacks basic functionality for easy introspection of these target names. Thus, these targets should be documented as available for use.

For a further discussion, see ament/ament_cmake#292, or my example repo here:
https://github.com/Ryanf55/ryan_ros_mvp/tree/bug-cmake-target-link-libraries-msgs

@clalancette clalancette added backlog help wanted Extra attention is needed labels Jun 8, 2023
@asasine
Copy link

asasine commented Jun 14, 2023

On occasion, we've "solved" this in our CMake by making an imported interface library which links to the _TARGETS variable

find_package(bar_msgs CONFIG REQUIRED)
add_library(bar_msgs::bar_msgs INTERFACE IMPORTED)
target_link_libraries(bar_msgs::bar_msgs INTERFACE ${bar_msgs_TARGETS})

# ...
target_link_libraries(my_target
  PUBLIC
    bar_msgs::bar_msgs
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backlog help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants