ROS编译系统

本文介绍了ROS中的两种编译系统——catkin_make和ament_cmake的使用方法。catkin_make重点讲解了如何编译库、调用库以及第三方库的调用,以及依赖其他功能包的msg targets。ament_cmake则围绕ament_package()展开,阐述添加依赖、构建库和管理编译器与链接器选项的方法。文章还提及了ament_index的查询和资源管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

catkin_make编译系统

编译库

项目名称为autodrive_common,对应头文件在include目录下,需要在catkin_package1中添加INCLUDE_DIRSLIBRARIES,表示当前package(autodrive_common)对外提供的库以及头文件。

project(autodrive_common)
catkin_package(INCLUDE_DIRS include
               LIBRARIES autodrive_common)

添加库编译,库由common_lib.cc源文件生成,最终生成libcomman_lib.so

add_library(common_lib SHARED src/common_lib.cc)

调用库

在需要调用库的包的package.xml中添加对autodrive_common包的编译和运行依赖:

<build_depend>autodrive_common</build_depend>
<run_depend>autodrive_common</run_depend>

在需要调用库的包中的CMakeLists.txt中用find_package将查找autodrive_common包作为catkin的components。autodrive_common对外export的头文件和库就会分别添加在变量${catkin_INCLUDE_DIRS}${catkin_LIBRARIES}中,之后在头文件目录设置include_directories和库链接设置target_link_libraries时就可以使用这两个变量。

find_package(catkin REQUIRED COMPONENTS
	autodrive_common
)
include_directories(
    include
    ${catkin_INCLUDE_DIRS}
)
target_link_libraries(planning_node ${catkin_LIBRARIES})

第三方库的调用

#设置头文件目录
include_directories(
 include
)
#指定库所在的目录
link_directories(lib)
#应用程序node链接library库
target_link_libraries(node library )

依赖其他功能包生成的msg targets

假如某功能包需要使用msgpackage包中定义的消息,则需要在构建任何依赖于该消息生成的目标文件的任何程序之前,编译消息并生成目标文件。这就需要使用add_dependencies()命令声明该程序所依赖的前置项。

#利用find_package将msgpackage设置为catkin的COMPONENTS
find_package(catkin REQUIRED COMPONENTS msgpackage)
#添加可执行程序的编译
add_executable(message_program src/main.cpp)
#设置message_program的依赖为${catkin_EXPORTED_TARGETS}
add_dependencies(message_program  ${catkin_EXPORTED_TARGETS})

那么${catkin_EXPORTED_TARGETS}是什么?在CMakeLists.txt中我们可以利用message()函数去debug,例如,

message("catkin_EXPORTED_TARGETS=${catkin_EXPORTED_TARGETS}")

都是些形如packagename_generate_messages_cpp的flag,所以对msg/service等的依赖,既可以使用packagename_generate_messages_cpp这种形式,也可以一劳永逸的通过find_packagecatkin_EXPORTED_TARGETS${PROJECT_NAME}_EXPORTED_TARGETS进行设置。

${PROJECT_NAME}_EXPORTED_TARGETS中存放的是PROJECT_NAME包所生成的目标文件的flag,而catkin_EXPORTED_TARGETS存放的是所有包生成的的目标文件的flag。

因为catkin会自动install message, service and action targets,并添加到 ${PROJECT_NAME}_EXPORTED_TARGETScatkin_EXPORTED_TARGETS,所以无需使用install()命令手动安装。

ament_cmake构建工具

ament_package()

项目设置由ament_package()完成,并且一个包必须且只能调用一次。ament_package()安装package.xml,为功能包注册ament index,并且为Cmake安装配置文件(和目标文件)以便被其他功能包使用find_package()发现。因为ament_package()CmakeLists.txt收集了大量信息,所以u它应该在最后被调用。

ament_package()有两个参数:

  • CONFIG_EXTRAS

    一系列应该被提供给该功能包的用户的Cmake文件(.cmake or .cmake.in模板被configure_file()扩充)

  • CONFIG_EXTRAS_POST:与CONFIG_EXTRAS相同,只是文件添加的顺序不同。CONFIG_EXTRAS files在ament_export_*生成的文件之前被include,而CONFIG_EXTRAS_POST在之后被include。

添加${PROJECT_NAME}_CONFIG_EXTRAS${PROJECT_NAME}_CONFIG_EXTRAS_POST有同样的效果。

文件被添加的全部顺序:

  • files added by CONFIG_EXTRAS
  • files added by appending to ${PROJECT_NAME}_CONFIG_EXTRAS
  • files added by appending to ${PROJECT_NAME}_CONFIG_EXTRAS_POST
  • files added by CONFIG_EXTRAS_POST

添加依赖

有两种方法将功能包和新的依赖链接起来

第一种方式也是推荐的方式是用ament宏ament_target_dependencies

第二种方式是使用target_link_libraries

现代CMake的推荐方法是仅使用targets,导出和与链接。CMake目标是包含命名空间的,类似于C ++。例如,Eigen3定义了目标Eigen3 :: Eigen。

构建库

当构建可重复使用的库时,需要将一些信息导出到下游包

ament_export_targets(my_libraryTargets HAS_LIBRARY_TARGET)
ament_export_dependencies(some_dependency)

install(
  DIRECTORY include/
  DESTINATION include
)

install(
  TARGETS my_library
  EXPORT my_libraryTargets
  LIBRARY DESTINATION lib
  ARCHIVE DESTINATION lib
  RUNTIME DESTINATION bin
  INCLUDES DESTINATION include
)
  • ament_export_targets宏为Cmake导出targets,这允许你的库的用户使用target_link_libraries(client my_library::my_library)ament_export_targets能列出一个名为EXPORT的目标列表在install调用中使用
    附加选项HAS_LIBRARY_TARGET:添加潜在的库到环境变量
  • ament_export_dependencis导出依赖到下游包。这使得该库的使用者对于这些依赖无需调用find_package()
  • 关于INCLUDES DESTINATION includeinstall命令仅将信息添加到CMake,实际上并未安装includes文件夹,这是通过install(DIRECTORY <dir> DESTINATION <dest>)命令来复制头文件。

还有两个附加函数,但对于基于目标的安装是多余的

  • ament_export_include_directories(include)

    标记导出的include目录,等同于install调用的INCLUDES DESTINATION

  • ament_export_libraries(my_library)

    标记安装的library的位置,这被ament_export_targets调用的HAS_LIBRARY_TARGET参数

Compiler and linker options

尽管现代CMake建议按目标添加complier flags

target_compile_options(my_target PRIVATE -Wall)

It is recommended to at least cover the following warning levels:

  • For Visual Studio, the default W1 warnings are kept
  • For GCC and Clang: -Wall -Wextra -Wpedantic are required and -Wshadow -Werror are advisable (the latter makes warnings errors).

但现在建议使用目录级函数add_compile_options(-Wall)

Adding resources

特别是在开发允许插件的插件或软件包时,通常必须从另一个ROS包中添加资源(例如插件)。

这可以使用ament index(也称为“resource index”)来实现。

通常,ament index包含在install/share/<your-package>目录下,包含获取资源的所需内容,比如resource的安装目录的相对路径。

当提供插件时,你需要提供一个plugin_description.xml文件,被pluginlib安装和使用 to load the plugins。为了实现这个目的,plugin_description.xml is registered as a resource in the resource _index 通过

pluginlib_export_plugin_description_file(plugin_name plugins_description.xml)

Querying the ament index

  • ament_index_has_resource:如果存在,获得资源的前缀路径
    • var: the output parameter: fill this variable with FALSE if the resource does not exist or the prefix path to the resource otherwise
    • resource_type: The type of the resource (e.g. rviz_common__pluginlib__plugin)
    • resource_name: The name of the resource which usually amounts to the name of the package having added the resource of type resource_type (e.g. rviz_default_plugins)
  • ament_index_get_resource:获取特定资源的内容,即ament index中标记文件的内容
    • var: the output parameter: filled with the content of the resource marker file if it exists.
    • resource_type: The type of the resource (e.g. rviz_common__pluginlib__plugin)
    • resource_name: The name of the resource which usually amounts to the name of the package having added the resource of type resource_type (e.g. rviz_default_plugins)
    • PREFIX_PATH: The prefix path to search for (usually, the default ament_index_get_prefix_path() will be enough).
  • ament_index_get_resources:获取所有从索引中注册特定类型的资源的软件包
    • var: Output parameter: filled with a list of names of all packages which registered a resource of resource_type
    • resource_type: The type of the resource (e.g. rviz_common__pluginlib__plugin)
    • PREFIX_PATH: The prefix path to search for (usually, the default ament_index_get_prefix_path() will be enough).

  1. catkin_package()
    [macro defined in catkin_package.cmake]
    该命令生成find_package 和pkg-config所需的代码,使得其他功能包可以获得该功能包的信息,包括该功能包的头文件目录、库、依赖和CMake变量。
    一个功能包中只能有一个catkin_package,一般放在较为靠前的位置,以使之后可以使用一些额外变量。 ↩︎

<think>嗯,用户想了解ROS的主流编译系统。首先,我需要确认自己对ROS编译系统的了解是否准确。ROS1主要使用catkin,而ROS2转向了colcon,对吧?还有早期的rosbuild,不过已经被淘汰了。可能需要对比一下catkin和colcon的区别,以及为什么ROS2要换编译系统。 用户可能是ROS的新手,或者有一定基础想深入了解。他们可能需要知道如何选择编译工具,或者在不同ROS版本中应该用什么。可能还需要提到ament,但ament是构建系统的一部分吗?或者它是ROS2的元构建系统?需要查证一下。 记得要解释编译系统的作用,比如管理依赖、构建包等。还要提到工具链,比如CMake的作用。用户可能对catkin_make、catkin_make_isolated和catkin_tools的区别不太清楚,需要简要说明。 另外,ROS2的colcon支持多包构建,支持并行编译,可能更高效。同时,colcon的设计更模块化,适合ROS2的分布式架构。这些优势需要提到。 有没有其他编译工具?比如bloom用于发布包,但不算编译系统。可能不需要深入,除非用户提到。 需要注意术语的准确性,比如catkin是构建系统还是元构建工具?可能catkin是基于CMake的,而colcon是一个元构建工具,调用不同的构建系统如CMake、ament等。 总结结构应该是:先介绍ROS1的catkin,再讲ROS2的colcon,最后提一下其他工具和注意事项。保持语言简洁,用中文,避免技术术语过多,必要时举例说明。</think>ROS(Robot Operating System)的编译系统主要用于管理代码的构建、依赖和打包。随着ROS版本的演进,其主流编译工具也发生了变化。以下是ROS 1和ROS 2中主流编译系统的介绍: --- ### **1. ROS 1 的编译系统** #### **(1) Catkin** - **定位**:ROS 1(如Noetic、Kinetic等)的标准编译系统,取代了早期的`rosbuild`。 - **核心机制**: - 基于**CMake**扩展,通过`CMakeLists.txt`和`package.xml`定义包的构建规则和依赖。 - 支持**多包联合编译**,通过`catkin_make`或`catkin build`一次性构建多个包。 - **工具链**: - **`catkin_make`**:基础命令,自动生成构建环境。 - **`catkin_make_isolated`**:改进版,支持隔离构建(避免包间干扰)。 - **`catkin_tools`**(推荐):更现代的CLI工具,提供`catkin build`命令,支持构建隔离、并行编译和可视化依赖。 #### **(2) 已被淘汰的rosbuild** - ROS早期版本使用,因依赖管理和扩展性差被Catkin取代。 --- ### **2. ROS 2 的编译系统** #### **(1) Colcon** - **定位**:ROS 2(如Humble、Foxy)的官方推荐编译工具,设计更模块化,支持多构建系统。 - **核心特性**: - **跨平台**:兼容Linux、Windows和macOS。 - **灵活性**:支持多种构建后端(如CMake、ament_cmake、纯Python包)。 - **高效性**:支持并行编译和增量构建。 - **使用方式**: - 常用命令:`colcon build`(支持`--packages-select`指定包,`--symlink-install`避免重复安装)。 - 生成环境配置:通过`source install/setup.bash`加载构建结果。 #### **(2) Ament** - **角色**:ROS 2的元构建系统(Meta Build System),定义标准工具链和接口。 - **与Colcon的关系**:Colcon调用Ament提供的工具(如`ament_cmake`)完成实际构建。 --- ### **3. 关键对比** | 特性 | ROS 1 (Catkin) | ROS 2 (Colcon) | |---------------------|-------------------------|-------------------------| | **构建工具** | `catkin_make`/`catkin build` | `colcon build` | | **依赖管理** | 基于`package.xml` | 基于`package.xml` + 更严格语义版本 | | **并行编译** | 有限支持 | 原生支持 | | **跨平台支持** | 主要Linux | Linux/Windows/macOS | | **构建隔离** | 需手动配置 | 默认隔离 | --- ### **4. 迁移与选择建议** - **ROS 1项目**:使用`catkin_tools`(功能更强大)。 - **ROS 2项目**:直接使用`colcon`,学习其扩展参数(如`--cmake-args`传递CMake选项)。 - **新用户**:推荐从ROS 2和Colcon入手,因其工具链更现代且社区支持更活跃。 --- ### **5. 示例命令** ```bash # ROS 1 (Catkin) cd ~/catkin_ws catkin build # 使用catkin_tools source devel/setup.bash # ROS 2 (Colcon) cd ~/colcon_ws colcon build --symlink-install source install/setup.bash ``` 如果需要进一步了解具体工具的使用细节,可以深入探讨某个部分!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shilong Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值