CMake笔记之ros的catkin_make中add_dependencies
用法对比:单一目标依赖 vs 多目标依赖
add_dependencies(publisher custom_msgs_pkg_generate_messages_cpp)
## 添加依赖,确保消息头文件生成后再编译
add_dependencies(publisher ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
这两段代码都涉及 CMake 中 add_dependencies
的使用,用于指定构建依赖关系,但它们的作用和适用场景有所不同。以下是详细的区别:
第一段代码
add_dependencies(publisher custom_msgs_pkg_generate_messages_cpp)
含义:
publisher
:目标(target),通常是一个可执行文件或库。custom_msgs_pkg_generate_messages_cpp
:这是一个生成消息和服务代码的目标,通常由catkin
自动生成,用于支持自定义消息类型(custom_msgs_pkg
是消息包名,generate_messages_cpp
是生成 C++ 消息代码的部分)。
功能:
- 这段代码指定了
publisher
依赖于custom_msgs_pkg_generate_messages_cpp
。 - 在构建
publisher
之前,custom_msgs_pkg_generate_messages_cpp
必须先完成。 - 适用场景:当你的节点(如
publisher
)依赖自定义消息,而这些消息是由custom_msgs_pkg
定义的,需要确保这些消息的生成代码(cpp
文件)在构建publisher
时已经可用。
第二段代码
add_dependencies(publisher ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
含义:
publisher
:同样是目标(目标节点或库)。${${PROJECT_NAME}_EXPORTED_TARGETS}
:- 这是当前项目(
PROJECT_NAME
)的导出目标,通常包括生成的消息、服务或其他依赖项。 - 由
catkin_package()
自动设置,用于关联当前项目的构建目标。
- 这是当前项目(
${catkin_EXPORTED_TARGETS}
:- 这是来自依赖包(
find_package(catkin REQUIRED COMPONENTS ...)
中指定的包)的导出目标。 - 包括其他依赖包的消息、服务或其他生成目标。
- 这是来自依赖包(
功能:
- 这段代码指定了
publisher
的依赖关系:- 当前项目的所有导出目标(
PROJECT_NAME
的生成目标)。 - 所有依赖包的导出目标(
catkin
中依赖的其他包)。
- 当前项目的所有导出目标(
- 适用场景:当
publisher
依赖多个目标,比如:- 本项目中生成的消息或服务。
- 其他包中生成的消息或服务,需要确保所有依赖目标都已构建。
区别总结
方面 | 第一段代码 | 第二段代码 |
---|---|---|
依赖范围 | 单一目标(custom_msgs_pkg_generate_messages_cpp ) | 当前项目导出的所有目标及依赖包的导出目标 |
适用场景 | 仅依赖某个特定的目标(如某个包的消息生成) | 依赖多个目标,通常是当前项目及依赖包的所有生成目标 |
灵活性 | 较低(仅关注单一目标) | 较高(涵盖当前项目及依赖包的所有导出目标) |
典型用途 | 用于单一消息包的生成依赖 | 用于复杂依赖场景,特别是包含多个消息、服务或自定义目标的项目 |
示例场景
-
第一段代码场景:
- 你的项目中只有一个单一的消息包
custom_msgs_pkg
,并且publisher
只依赖于custom_msgs_pkg
中的消息。 - 则可以简单地使用第一种写法,让
publisher
依赖于custom_msgs_pkg_generate_messages_cpp
。
- 你的项目中只有一个单一的消息包
-
第二段代码场景:
- 你的项目有多个消息包,或者依赖多个其他包的消息和服务(例如
std_msgs
、geometry_msgs
)。 - 你希望
publisher
自动依赖于所有相关生成目标,而无需手动指定每个目标。
- 你的项目有多个消息包,或者依赖多个其他包的消息和服务(例如
总结建议:
- 如果依赖简单(比如一个特定的消息包),可以用第一种方式。
- 如果依赖复杂,涉及多个包或多个消息/服务生成目标,推荐使用第二种方式,因为它更通用且易于维护。