Rosanswers logo

From documentation, the catkin implementation and previous answers I conclude that it is intentional, that in a catkin package you cannot export any subdirectories of <INSTALL_SPACE>/install in the install space. Any such relative directories (passed to catkin_package with the INCLUDE_DIRS argument) are ignored.

This works fine if you follow the convention to install files into <INSTALL_SPACE>/install/package/ and always include headers with #include <package/header.h>.

However, I have a bunch of legacy code for which I added a bunch of interdependent catkin packages definitions that builds those libraries. It works fine with the devel space. The legacy code is broken up into different modules, but all modules include headers directly with foo.h, not <MODULE>/foo.h or similar. It relies on the build system to setup include paths correctly according to module dependencies. Working in the devel space I a achieve this by exporting the according subdirectory containing the header files as INCLUDE_DIRS. In the install space, I would still want to install the header files into a subdirectory <INSTALL_SPACE>/include/<package>, however I cannot export that subdirectory in catkin_package.

The solutions I see are:

  1. Place all headers in the toplevel <INSTALL_SPACE>/include/. This is undesirable for possible clashes with other pacakges.
  2. Add a cmake extras file to each package that amends the package_INCLUDE_DIRS variable (not sure if that works) or even directly calls include_directories(...) (which violates the apparent cmake convention that finding a package does not directly manipulate build configuration like include_directories). This seems a bit hacky, but might get the desired behaviour.
  3. Install all header files into a common subdirectory <INSTALL_SPACE>/include/foo-project and set that up as an include directory in a common cmake macro that is called by all CMakeLists.txt (I already have such a macro anyway). Again, not that elegant and not exactly what I want (all packages having their own include sub-folder the install space).

Any suggestions on how to do this properly?

EDIT: In response to @dirk-thomas's answer:

The INCLUDE in the original question was a typo. I meant INCLUDE_DIRS. Just fixed it.

And it is possible to pass any custom value there, e.g. catkin_package(INCLUDE_DIRS foo) if you want <CMAKE_INSTALL_PREFIX>/foo to end up in the include dirs list. There is no need to use a custom CMake extras file for this.

This is exactly what I want to do, but it does not seem to work for the install space. It seems that catkin is removing all relative paths that would add custom subfolders <CMAKE_INSTALL_PREFIX>/include/foo and adds just the default <CMAKE_INSTALL_PREFIX>/include. Absolute paths are not changed / filtered. The responsible code section seems to be here, which is exactly the else branch you linked to also, but as far as I can see, it does not actually use the relative_dir in that else branch (maybe that is a bug in catkin?).

2 As you already stated a CMake config file should not directly manipulate the build configuration.

This seems to do the right thing at least in my case, see the answer I added.

3 Setting the package specific subfolder as an include directory defeats the separation (same as 2.). Header files of multiple packages with the same relative paths still collide.

In general yes. In my case I know that the header files of different modules do actually not clash, so this is ok. I still don't like it much though.


Originally posted by demmeln on ROS Answers with karma: 4306 on 2016-04-25

Post score: 0

Original comments

Comment by ahendrix on 2016-04-25:
Setting up package_INCLUDE_DIRS is the cmake way to do this. You should be able to do it in catkin but I'm not quite sure if you can do it with the existing macros or if you have to use cmake_extras


1 Answer 1


Rosanswers logo

Thanks @ahendrix for you comment. For the record: appending to package_INCLUDE_DIRS in the cmake extras works as expected (it also ends up in catkin_INCLUDE_DIRS). The solution I went with for now is installing all headers into one common sub-directory as in my option 3 above. I append this to the INCLUDE_DIRS in the cmake extras of my one "common" pacakge, that all other packages depend on. This way I don't have to add cmake extras to every single package, but still stick with the cmake convention of having all include dirs on project_INCLUDE_DIRS (through the build-export-depends on the "common" pacakge). Any additional comments and insights are still welcome.

Edit: For future reference, I added a filter common_pkg-extras.cmake.installspace.in in the folder cmake of my common_pkg with content:


list(APPEND common_lib_INCLUDE_DIRS "${common_lib_DIR}/../../../@CATKIN_GLOBAL_INCLUDE_DESTINATION@/MyProjectSubfolder")

Edit2: As @dirk-thomas pointed out, the additions in cmake-extras will of course not be reflected in the generated .pc files. For me, this is not an issue currently.

Originally posted by demmeln with karma: 4306 on 2016-04-25

This answer was ACCEPTED on the original site

Post score: 0


Your Answer

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