3

I am building a project using ROS and thus, catkin_make to build my ROS nodes and libraries.

The problem I'm facing is: I am using a git submodule in one package (package A) (and thus, I have a hierarchical include folder structure) and I have difficulties referencing a header file within that submodule.

In order to build the package B, which is dependent on package A, I have added the INCLUDE_DIRS statement to the catkin_package command in package A:

catkin_package(
  INCLUDE_DIRS my-submodule/include
  ...
)

The content of that directory is:

my-submodule/my-header.h

(I have put the header files under a folder, named after the submodule, as many tutorials stated that within ROS you should use this convention).

The include statement in a file from package-B reads like this:

...
#include <my-submodule/my-header.h>
...

This works fine - package B is being built (as I am using one combined workspace to build this).

But: When I switch to the target system, where I only install package A, and then try to build package B (on that target system), it does not build because the include paths are not setup correctly.

The INSTALL statement for package A looks like this

install(DIRECTORY my-submodule/include
  DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
  FILES_MATCHING PATTERN "*.h"
  PATTERN ".svn" EXCLUDE
)

This is mainly, because the installed folder structure on the target system looks like this:

.../ros/include/my-package-A/include/my-submodule/my-header.h

So, the install process actually puts that submodule's include-path under the package-A-include path (which is a different path structure compared to when I build the packages directly in one combined workspace).

And the CFLAGS for compilation only set the include directory to the folder:

.../ros/include

And thus, breaking my include statement in my package-B file:

#include <my-submodule/my-header.h>

Do you have any idea how to solve this? I am sure there are more people than me, trying to reference header files from a submodule within a package.

Kai Neumann
  • 351
  • 4
  • 8

1 Answers1

1

Assuming you have a file my-submodule/include/my-submodule/my-header.h inside your package A, then two small changes to your install() statement should fix this:

install(DIRECTORY my-submodule/include/
  DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION}
  FILES_MATCHING PATTERN "*.h"
  PATTERN ".svn" EXCLUDE
)

First, add a slash to the path (.../include/ instead of .../include), which causes the contents of the include folder to be installed instead of the include folder itself (Otherwise you'll end up with ../ros/install/include/include/my-submodule/my-header.h)

Secondly, use ${CATKIN_GLOBAL_INCLUDE_DESTINATION} (which points to .../ros/install/include/) instead of ${CATKIN_PACKAGE_INCLUDE_DESTINATION} (which points to .../ros/install/my-package-A/include/) as destination.


The alternative would be to fix catkin, as

catkin_package(
  INCLUDE_DIRS my-submodule/include
  ...
)

should theoretically already export my-submodule/include, so you can pick it up in package B with

find_package(catkin REQUIRED DEPENDS my-package-A)
catkin_package(
    CATKIN_DEPENDS my-package-A
)
include_directories(${catkin_INCLUDE_DIRS})

Unfortunately, for some reason this is explicitely not possible when using catkin config --install. See https://answers.ros.org/question/335846/install_dirs-not-working-as-expected-when-using-install/.

iliis
  • 878
  • 8
  • 19