3

我正在使用 ROS 构建一个项目,因此 catkin_make 来构建我的 ROS 节点和库。

我面临的问题是:我在一个包(包 A)中使用了一个 git 子模块(因此,我有一个分层的包含文件夹结构)并且我在引用该子模块中的头文件时遇到了困难。

为了构建依赖包 A 的包 B,我在包 A 的 catkin_package 命令中添加了 INCLUDE_DIRS 语句:

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

该目录的内容是:

my-submodule/my-header.h

(我已将头文件放在一个以子模块命名的文件夹下,因为许多教程指出在 ROS 中您应该使用此约定)。

package-B 文件中的 include 语句如下所示:

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

这很好用 - 正在构建包 B(因为我正在使用一个组合工作区来构建它)。

但是:当我切换到目标系统时,我只安装包 A,然后尝试构建包 B(在该目标系统上),它不会构建,因为包含路径设置不正确。

包 A 的 INSTALL 语句如下所示

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

这主要是因为目标系统上安装的文件夹结构是这样的:

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

因此,安装过程实际上将该子模块的包含路径放在 package-A-include 路径下(与我直接在一个组合工作区中构建包时相比,这是一种不同的路径结构)。

而编译用的 CFLAGS 只将包含目录设置为文件夹:

.../ros/include

因此,在我的 package-B 文件中破坏了我的 include 语句:

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

你知道如何解决这个问题吗?我相信有比我更多的人,试图从包中的子模块引用头文件。

4

1 回答 1

1

假设你my-submodule/include/my-submodule/my-header.h的包 A 中有一个文件,那么你的 install() 语句的两个小改动应该可以解决这个问题:

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

首先,在路径中添加一个斜杠(.../include/而不是.../include),这会导致安装文件夹的内容include不是include文件夹本身(否则您最终会得到../ros/install/include/include/my-submodule/my-header.h

其次,使用${CATKIN_GLOBAL_INCLUDE_DESTINATION}(指向.../ros/install/include/)而不是${CATKIN_PACKAGE_INCLUDE_DESTINATION}(指向.../ros/install/my-package-A/include/)作为目的地。


另一种方法是修复柳絮,如

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

理论上应该已经导出my-submodule/include,所以你可以在包 B 中使用

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

不幸的是,由于某种原因,这在使用catkin config --install. 请参阅https://answers.ros.org/question/335846/install_dirs-not-working-as-expected-when-using-install/

于 2019-10-21T18:27:08.030 回答