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

Revision history [back]

click to hide/show revision 1
initial version

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.

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})
    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.

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.