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

Add a shared library to a catkin package

asked 2016-10-19 12:13:07 -0600

OMC gravatar image

Hello,

I have compiled a third-party library from a non-catkin package and I would like to use this library in my project. I have already seen how to link a library against an executable as explained here and here, but there is still something I do not quite understand. As far as I know, in order to use the shared library in my nodes, I need the header files, so I can "#include" them in my .cpp file. But none of the mentioned sources seem to take care of that.

Should I add all the headers to the include_directories() macro in the CMakeLists?

i.e: The library I intend to use is libLanelet, so I compiled it using SCons and I obtained the library libLanelet.so. I copied this library into "package_path/libs". In my CMakeLists I have

target_link_libraries(node ${catkin_LIBRARIES} ${PROJECT_SOURCE_DIR}/libs/libLanelet.so)

Should I copy all .hpp files inside, say, "package_path/include" and then in the CMakeLists add

include_directories(${PROJECT_SOURCE_DIR}/include) ?

In case this is right is this the proper way to do it?

I have just started to "get my hands dirty" writing ROS code and I recently started learning C++, so many concepts are still unclear to me.

Regards

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
5

answered 2016-10-20 05:05:31 -0600

gvdhoorn gravatar image

updated 2020-09-08 04:39:53 -0600

Update 2020-09-08: please note the answer below was written in 2016, before "modern CMake" really became a thing.

These days, while the ideas are similar, you'd probably use target_link_libraries(..) with a properly setup and exported (INTERFACE) target or an IMPORTED library and other targets.

You could still use those with target_link_libraries(..) as below, but writing a Find*.cmake script may not be the go-to approach any more these days.


In a nutshell:

  1. install your third-party library as you would normally do this (ie: to /usr/local or some other location)
  2. either write a CMake FindYourLibrary.cmake script (the correct way), or hard-code locations of libraries and header files in CMake variables (ie: lanelet_LIBRARIES, lanelet_INCLUDE_DIRS, etc)
  3. now use those as you would any other CMake compatible library:

    include_directories(
      [..]
      ${lanelet_INCLUDE_DIRS}
      [..]
    )
    
    target_link_libraries(node
      ${catkin_LIBRARIES}
      [..]
      ${lanelet_LIBRARIES}
      [..]
    )
    

So:

Should I add all the headers to the include_directories() macro in the CMakeLists?

No, you should only use include_directories(..) to tell CMake which path it should add to the compiler's include search path (see above).

Should I copy all .hpp files inside, say, "package_path/include" and then in the CMakeLists add

No, unless you want to create a wrapper package for the library. As I wrote above: install the library "system-wide" as you would normally do, and make your Catkin package (really: CMake) find it using the normal means.

I have just started to "get my hands dirty" writing ROS code and I recently started learning C++, so many concepts are still unclear to me.

Then please understand that Catkin is basically a bunch of CMake macros and functions that make it easier to work with in a ROS context, but that it is really CMake doing all the work. Whenever you think you should search for "how does catkin do ..", first try "how does cmake do ..", especially when dealing with headers, libraries and finding dependencies.

Also: check out the catkin documentation, especially the How to do common tasks.

edit flag offensive delete link more

Comments

Thank you very much for your answer. I wanted my package to have all necessary files to work by itself (not sure if that's exactly a wrapper). I think I can include the headers and the library and in the CMakeLists add the headers' path and link the executable against the library. It seems to work

OMC gravatar image OMC  ( 2016-10-20 05:37:40 -0600 )edit
1

I wanted my package to have all necessary files to work by itself

That can work, but you need to understand that you're now responsible for keeping track of upstream changes / bug fixes.

gvdhoorn gravatar image gvdhoorn  ( 2016-10-20 06:11:21 -0600 )edit
1

(not sure if that's exactly a wrapper).

well, it is a wrapper combined with your own package. Not something I'd recommend (as it's not exactly proper separation of concerns), but it will work.

gvdhoorn gravatar image gvdhoorn  ( 2016-10-20 06:11:52 -0600 )edit

Ok, I understand why it might be a good idea let the final user of my package take care of external libraries. I will decide how to handle it with my colleges when I have the chance.

Thanks for the explanations.

OMC gravatar image OMC  ( 2016-10-20 08:05:27 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2016-10-19 12:13:07 -0600

Seen: 6,160 times

Last updated: Sep 08 '20