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

How to create a ROS2 library

asked 2020-07-20 08:34:56 -0600

MrCheesecake gravatar image

Hey together,

I'm building some nodes and want to add a general logging function into my common package, which also contains my interface definitions.
Now I am wondering how to export a library in the ROS2 CMakeLists.txt because I couldn't find any example out there. Also how to use this library in another package?
This is what I tried, but doesn't work. I can't find the exported library nor include it:

add_library(common_log src/common.cpp)

target_include_directories(common_log
  PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>)

ament_export_interfaces(export_common_log HAS_LIBRARY_TARGET)

 install(
   DIRECTORY include/
   DESTINATION include
 )

 install(
   TARGETS common_log
   EXPORT export_common_log
   LIBRARY DESTINATION lib
   ARCHIVE DESTINATION lib
   RUNTIME DESTINATION bin
   INCLUDES DESTINATION include
 )

ament_export_include_directories(include)
ament_export_libraries(common_log)



I appreciate your help, thanks!

edit retag flag offensive close merge delete

Comments

With the above your library file should end up in ros_ws/install/common_log/lib and your includes should end up in ros_ws/install/common_log/include/common_log.

I am having a similar problem (https://answers.ros.org/question/3642...). My problem is my other projects cannot find my library or it's header files. Did you ever get this to work? If so can you let me know how?

Cheers Stew

stewart menday gravatar image stewart menday  ( 2020-10-28 19:30:14 -0600 )edit

2 Answers

Sort by ยป oldest newest most voted
3

answered 2021-08-27 08:20:58 -0600

SalahSoliman gravatar image

updated 2021-08-27 08:30:59 -0600

So, what I understand is that you want to export a library to be used by other packages, here's the answer for this. let's say you have a package called my_library that contains the library you want to export, and another package called lib_consumer which consumes that library.

The two packages structure:

my_library
   include
      the_library
           lib_header.hpp
   src
   CMakeLists.txt
consumer
   src
      consumer.cpp
   CMakeLists.txt

In the my_library package, your CMakeLists.txt should be as follows:

The following line makes you use direct inclusion in your package's (my_library src cpp files, if you have any) (i.e #include "lib_header.hpp")

include_directories(include/the_library)

You then add the library, the set is just for convenience if you have multiple header files, you can do the same if you have multiple cpp files. (the target name is my_lib)

set(HEADER_FILES include/the_library/lib_header.hpp)
add_library(my_lib src/lib_source.cpp ${HEADER_FILES})

This line to export the targets, in our case it's a library! (it passes the information to cmake to tell it that we want to export a library (more generally a target) to be used by some other package.

ament_export_targets(my_lib HAS_LIBRARY_TARGET)

Install the include/the_library directory to the install/include/the_library to be seen by the consumer target (we haven't talked about the consumer just yet)

install(
  DIRECTORY include/the_library
  DESTINATION include
)

Install and officially export the library, you may want to search a little bit more for this one

install(
  TARGETS my_lib
  EXPORT my_lib
  LIBRARY DESTINATION lib
  ARCHIVE DESTINATION lib
  RUNTIME DESTINATION bin
  INCLUDES DESTINATION include
)

In the consumer package, your CMakeLists.txt should be as follows:

find_package(the_library REQUIRED)
add_executable(consumer src/consumer.cpp)

You then want to link the consumer executable to the library called my_lib exported by the_library package, the syntax is as follows: package_name::exported_library_name

target_link_libraries(consumer the_library::my_lib)

You then may then want to install the consumer executable to be able to ros2 run it

install(TARGETS consumer
DESTINATION lib/${PROJECT_NAME}/)

Important note: in the consumer.cpp file you'd include the library as follows:

#include "the_library/lib_header.hpp"

If you'd like direct inclusion (#include "lib_header.hpp") then you need to modify the my_library CMakeLists as follows:

install(
  TARGETS my_lib
  EXPORT my_lib
  LIBRARY DESTINATION lib
  ARCHIVE DESTINATION lib
  RUNTIME DESTINATION bin
  INCLUDES DESTINATION include/the_library
)

Here's the complete code: google drive zip

Sorry for the long answer :)

edit flag offensive delete link more
0

answered 2021-04-12 13:24:28 -0600

flynneva gravatar image

I am also dealing with this type of problem and have found looking at how the transport_drivers repo is structured quite helpful. the io_context library is shared between the serial_driver and udp_driver and utilizes the ament_auto_add_library macro to auto-generate a shared library.

https://github.com/ros-drivers/transp...

have a look and let me know if this answers your question!

edit flag offensive delete link more

Question Tools

3 followers

Stats

Asked: 2020-07-20 08:34:56 -0600

Seen: 5,445 times

Last updated: Aug 27 '21