catkin / ROS:如何在使用子模块时正确指定包含路径

Posted

技术标签:

【中文标题】catkin / ROS:如何在使用子模块时正确指定包含路径【英文标题】:catkin / ROS: How-to specify include path correctly when using submodules 【发布时间】:2018-04-24 19:05:09 【问题描述】:

我正在使用 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只设置了include目录到文件夹:

.../ros/include

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

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

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

【问题讨论】:

【参考方案1】:

假设您的包 A 中有一个文件 my-submodule/include/my-submodule/my-header.h,那么您的 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,因为

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/。

【讨论】:

以上是关于catkin / ROS:如何在使用子模块时正确指定包含路径的主要内容,如果未能解决你的问题,请参考以下文章

在 ROS 工作空间中使用 catkin_make 时 Qt 出现的问题

创建一个catkin工作空间

ROS 工作空间、package 及 catkin 编译系统

c++的程序在ros下怎么运行

c++的程序在ros下怎么运行

设置 ROS catkin/rosbuild