ament_target_dependencies doesn't include library during build but target_link_libraries does
I'm not sure if this is an issue that I should raise at the ament_cmake
GitHub page or here, so feel free to provide suggestions on that front.
I'm observing a difference in behaviors between ament_target_dependencies
and target_link_libraries
despite having (almost) identical arguments when running colcon build
. My distro is ROS2 Foxy on Ubuntu 20.04.
Ideally I'd like to use the ament_target_dependencies
as recommended in the ROS2 tutorials, so I'd like to know if this is an instance mentioned in the Ament CMake Documentation:
Sometimes it will be necessary to call the targetlinklibaries CMake function
Otherwise, I would like to be able to stick with ament_target_dependencies
if possible.
An example case would look like the following.
# CMakeLists.txt
...
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(MyLib1 CONFIG REQUIRED)
find_package(MyLib2 CONFIG REQUIRED)
add_executable(example_node example_node.cpp)
### Block 1 ###
ament_target_dependencies(example_node
rclcpp
${MyLib1_LIBRARIES}
${MyLib2_LIBRARIES}
)
##############
### Block 2 ###
target_link_libraries(example_node PRIVATE
${rclcpp_LIBRARIES}
${MyLib1_LIBRARIES}
${MyLib2_LIBRARIES}
)
##############
...
In the above CMakeLists.txt
, MyLib1
and MyLib2
are non-ROS CMake projects that are installed locally. I am able to verify that ${MyLib1_LIBRARIES}
and ${MyLib2_LIBRARIES}
exists (and so do the *_INCLUDE_DIRS
variables).
Block 1
If I use Block 1 (and comment out Block 2), I get an error about missing header files which are supposed to be provided by MyLib2
. If I add an include_directories
line that points to the header files at /usr/include/MyLib2/
, I was able to progress further in the build but would get linker errors: /usr/bin/ld: /lib/libMyLib2.so: error adding symbols: DSO missing from command line
.
I also tried running colcon build
verbosely and noticed that the include path for MyLib2
was missing in the make step but not MyLib1
.
/usr/bin/c++ -DDEFAULT_RMW_IMPLEMENTATION=rmw_fastrtps_cpp ... -isystem /usr/include/vtk-7.1 -isystem /usr/include/freetype2 -isystem /opt/ros/foxy/include -isystem /usr/include/MyLib1 -isystem /usr/include/eigen3 -isystem /usr/include/pcl-1.10 -isystem /usr/include/ni -isystem /usr/include/openni2 -Wall -Wextra -Wpedantic -std=gnu++14 ...
I was also unable to find libMyLib2.so
(but libMyLib1.so
can be found) in the build.make
file for this package, which seemed all the more mysterious to me.
Block 2
By commenting Block 1 and uncommenting Block 2, there were no issues building and installing with colcon build
. The package also worked as expected.
Some final notes
In the example above, I maintain both MyLib1
and MyLib2
, so I am able to make changes to those libraries (particularly their *Config.cmake
files) at will, as deemed necessary. Thus the point of this entire question is to find out if there seems to be an issue with my configuration and installation of the two libraries, or if such a difference in behaviors when building for ROS2 is expected.
Asked by khaiyichin on 2021-04-30 13:42:36 UTC
Comments
in short,
ament_target_dependencies
andtarget_link_libraries
really don't do the same thing. The former does more than the latter. In general, you should useament_target_dependencies
unless you know you need to usetarget_link_libraries
. As for your question about block 1, if you follow theament_cmake
documentation you linked to, you should writeament_target_dependencies(example_node rclcpp MyLib1 MyLib2)
. Does that work?Asked by christophebedard on 2021-04-30 15:11:55 UTC
@christophebedard I tried what you suggested, but it had the same behavior as Block 1: it complains about missing header files from
MyLib2
but is able to detectMyLib1
.Asked by khaiyichin on 2021-04-30 15:48:22 UTC
I see. Maybe
ament_target_dependencies
expects something fromMyLib1
/MyLib2
which just isn't there. This would "make sense" ifMyLib1
/MyLib2
are pure CMake and not ROS/ament
packages. Can you just useament_target_dependencies
forrclcpp
andtarget_link_libraries
forMyLib1
/MyLib2
? I think this is usually how it's done, e.g. https://github.com/ros2/rclcpp/blob/d051b8aa20fa263b1480945aebd1a8e5df315b67/rclcpp/CMakeLists.txt#L189-L204Asked by christophebedard on 2021-05-01 09:04:08 UTC
@christophebedard Yes, you're right that
MyLib1
andMyLib2
are pure CMake packages. I looked at the link and that's about the way I'm doing it, so thanks for that!Asked by khaiyichin on 2021-05-11 09:17:16 UTC