0
$\begingroup$

Rosanswers logo

It is common practice to place header files in a subdirectory of the package's include folder which has the same name as the package. The package exposes theses header files via its catkin_package() macro for dependent packages as it can be found in many catkin examples:

catkin_package(
   INCLUDE_DIRS include
   ...
)

Other packages will include these headers using the #include <package/header.h> directive.

On the other side, catkin documentation at ros.org proposes the following cmake code to install header files contained in a package:

install(DIRECTORY include/
   DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
   FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp"
)

With this command header files are installed to ${CATKIN_PACKAGE_INCLUDE_DESTINATION}/package/header.h which resolves to ${CMAKE_INSTALL_PREFIX}/include/package/package/header.h.

  1. Is there a mechanism in the generated cmake/pkg-config files that add ${CMAKE_INSTALL_PREFIX}/include/package as an include directory if another package depends on my package, so that the #include <package/header.h> directive will continue to work in install space? As far as I can see, this is not the case and all packages installed in /opt/ros/groovy only expose /opt/ros/groovy/include as include directory and not /opt/ros/groovy/include/package.

  2. Should the example at ros.org changed to

  install(DIRECTORY include/${PROJECT_NAME}/
 DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
     FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp"
  )
  

? This is also the cmake fragment in the install section of the CMakeLists.txt generated by catkin_create_pkg.

  1. Header files could be installed to CATKIN_GLOBAL_INCLUDE_DESTINATION instead:

     install(DIRECTORY include/
        DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION}
        FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp"
     )
     

Which of the three above "solutions" is the correct/preferred way to install header files in catkin packages or did I miss something here?


Originally posted by Johannes Meyer on ROS Answers with karma: 1266 on 2013-06-22

Post score: 5

$\endgroup$

2 Answers 2

0
$\begingroup$

Rosanswers logo

Here is the currently recommended solution from the Catkin API docs:

install(DIRECTORY include/${PROJECT_NAME}/
        DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION})

It pretty closely matches your option 2. The pattern matching is not needed unless you have non-header files in your include/${PROJECT_NAME} tree, but avoiding any .svn subdirectories is needed with SVN repositories.


Originally posted by joq with karma: 25443 on 2013-06-22

This answer was ACCEPTED on the original site

Post score: 2


Original comments

Comment by Carter12s on 2014-08-11:
Link is broken, can you fix?

Comment by Dirk Thomas on 2014-08-11:
https://docs.ros.org/en/melodic/api/catkin/html/howto/format2/building_libraries.html

$\endgroup$
0
$\begingroup$

Rosanswers logo

Regarding question 1.:

You should always install all your headers to the destination "include" - everything else would be not FHS compliant.

In your source space you could have your headers in (multiple) different locations. It is highly recommended to put them under "include" though.

You have to add them with include_directories() to make them usable for building targets in your own CMakeLists.txt file.

For other packages in the same workspace you "export" the same directories via catkin_package(INCLUDE_DIRS ...).

After being installed catkin expects that if you have listed any folder as INCLUDE_DIRS that you have installed all files to "include". Any package depending on your package should then use include_directories(${catkin_INCLUDE_DIRS}) or include_directories(${yourpkgname_INCLUDE_DIRS}) to add these include directories.

Generally you should always place your headers into a subfolder named after your package to avoid naming collisions. But the include_directories() always only point to "include" - not to "include/yourpkgname". That way you always import your code with the namespace prefix: #include <yourpkgname/myheader.h>.


Originally posted by Dirk Thomas with karma: 16276 on 2013-06-22

This answer was NOT ACCEPTED on the original site

Post score: 6


Original comments

Comment by Johannes Meyer on 2013-06-22:
Thanks, Dirk. I think I understand the semantics of catkin_package(INCLUDE_DIRS...) and include_directories() in devel-space. The only problem is that the documentation in http://ros.org/wiki/catkin/CMakeLists.txt seems to be wrong as the header files end up in the wrong directory. See joq's answer.

Comment by Dirk Thomas on 2013-06-22:
I have updated the Wiki page to reflect the correct install calls for headers as mentioned in your question as 2. and 3.: http://ros.org/wiki/catkin/CMakeLists.txt#Installing_header_files I would prefer the first as long as the subfolder equals the package name (which is highly recommended).

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.