ament / ament_cmake

Supporting CMake packages for working with ament
Apache License 2.0
100 stars 124 forks source link

Support creating a namespaced local alias of the exported target when using ament_cmake #351

Open traversaro opened 3 years ago

traversaro commented 3 years ago

See https://github.com/ament/ament_cmake/pull/349 for the original discussion. Here an extract:

A common practice in "modern" CMake development practices is to always add a namespaced ALIAS target for each library that is installed with a given namespace, to ensure that the library can be consumed as target_link([...] <pkg>::<target_name>) both if the project is used via find_package(<pkg>) or via FetchContent/add_subdirectory . For more details on this, see (among other resources):

I was trying to follow this practice in an existing project that was creating a type support library via rosidl, see https://github.com/robotology-playground/yarp-ros2/pull/10 . By doing so, I noticed that if I included the library via add_subdirectory the created target was named map2d_nws_ros2_msgs__rosidl_typesupport_cpp, while if I was including the project via find_package the target was named map2d_nws_ros2_msgs::map2d_nws_ros2_msgs__rosidl_typesupport_cpp. As a workaround, I simply added the alias myself, as in:

if(NOT TARGET map2d_nws_ros2_msgs::map2d_nws_ros2_msgs__rosidl_typesupport_cpp)
    add_library(map2d_nws_ros2_msgs::map2d_nws_ros2_msgs__rosidl_typesupport_cpp ALIAS map2d_nws_ros2_msgs__rosidl_typesupport_cpp)
  endif()

However, it would be great if we could avoid to have such boilerplate.

traversaro commented 3 years ago

@alsora you may be interested in this in the context of improving the usage of ROS2 when using plain CMake tools and conventions, see https://github.com/ros2/ros2_documentation/pull/1913 .

traversaro commented 2 years ago

A proposal was done in CMake upstream in https://gitlab.kitware.com/cmake/cmake/-/issues/22687, that if implemented would automatically solve this issue if a new enough CMake version is used. Solving the issue at the CMake level would be probably much more clean as well.

RFRIEDM-Trimble commented 2 years ago

As a workaround, I use standard CMake calls except for the following three calls:

find_package(ament_cmake REQUIRED)
ament_export_targets(...)
ament_package()

I then get full access to normal cmake commands supporting creating and usage of alias targets including:

project(proj)
add_library(A ...)
add_library(proj::A ALIAS A)
target_link_libraries(A PUBLIC B:b C:c PRIVATE D:d)

Then if you package uses CMakePackageConfigHelpers and installs, you can find it with both modern cmake as well as ament.