CMakeLists.txt 和 package.xml 重要内容详解

边学边看,学到什么分享什么

  1. CMakeLists.txt → 构建配置文件
  2. package.xml → 功能包配置文件

上面的意思个人理解就是功能包本身如果要在别处运行,需要什么样的条件在xml文件中看
功能包自身,各个功能运行,需要什么条件,在txt文件中看

CMakeList内容

Catkin is a collection of cmake macros and associated python code used to build some parts of ROS

pakeage.xml内容

<!-- ****-->           这是相当于注释,可以根据这个来对xml文件进行说明。
<?xml *** ?>           这是定义文档语法的语句,上面内容表示内容遵循xml的1.0版本。
<package>              这个语句到</package>的部分是ROS功能包的配置部分。
<name>                 功能包名称,默认为创建时的名称,可以随时更改。
<version>              功能包的版本可以自由指定。
<description>          功能包的简要说明。
<maintainer>           功能包维护者的姓名和电子邮建地址。
<license>              记录版权许可证。
<url>                  记录描述功能包的说明,如网页、错误管理、存储库的地址等。
<author>               记录参与功能包开发的开发人员的姓名和电子邮件地址。

<build_depend>          构建依赖关系,使用某种特定的依赖关系来构建包。
<build_export_depend>   构建导出依赖关系,如果功能包导出头文件,则其他包可能需要这个包,就应该使用这个标签,用来传递声明。
<exec_depend>           执行依赖关系指定在此程序包中运行代码所需的软件包。如动态链接库、可执行文件、Python模块、脚本文件等。
<depend>                等于以上三种depend的合集,通常使用它添加ROS功能包,是常用而简便的方法。
<buildtool_depend>      构建工具依赖关系指定此软件包需要构建自身的构建系统工具。通常唯一的构建工具是catkin。
<test_depend>           测试依赖关系仅指定单元测试的附加依赖项
<doc_depend>            文档工具依赖关系指定此软件包需要生成文档的文档工具。 

举例分析

以ROS基本的话题通讯为例,如果要运行功能包里的cpp文件,需要对cmakelist文件进行注释修改

add_executable(Hello_pub
  src/Hello_pub.cpp
)
target_link_libraries(Hello_pub
  ${catkin_LIBRARIES}
)

其中add_executable
就是添加可执行文件,会生成一个执行文件 也就是上面设置的 hello_pub 也可以理解为 turtlesim_node 这个肯定不陌生 。
target_link_libraries
目标连接库,指定可执行文件去链接那些库。就是生成上面所说的hello_pub所需要的库,一般来说,都是这个默认的库${catkin_LIBRARIES}(个人对这个的理解不到位,不知道这个库包含啥)初步理解就是包含创建功能包时候加载的库 例如roscpp rospy std_msgs
(2020/4/23更新)
参考LinkLink
其实所谓的链接库,find_package 就是去找cmake文件,(怪不得我在安装什么包的时候,说缺少这个cmake,缺少那个,原来这个在添加依赖), ${catkin_LIBRARIES}就是之前添加的所有依赖库,也就是我之前的猜测,

find_package(love)
target_link_libraries(${PROJECT_NAME} love)

写成这样就可以理解了,就是find的文件要是很多 咱也不能一个个加 ,所以就有个${catkin_LIBRARIES}这个参数代表所有的链接库。

之后如果自己设置msg信息的话,相信大概都知道调节什么参数
<build_depend>message_generation</build_depend>   
<exec_depend>message_runtime</exec_depend>   
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
# 需要加入 message_generation,必须有 std_msgs

## 配置 msg 源文件
add_message_files(
    FILES
    Person.msg
)
# 生成消息时依赖于 std_msgs
generate_messages(
  DEPENDENCIES
  std_msgs
)
#执行时依赖
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES my_package
  CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
#  DEPENDS system_lib
)

message_generation **包建模构建时依赖项以生成消息的语言绑定(谷歌翻译)**Package modeling the build-time dependencies for generating language bindings of messages.
官网:Link
message_runtime 是用来生成ros-msg消息代码的python文件。**包对消息的语言绑定的运行时依赖项进行建模。**Package modeling the run-time dependencies for language bindings of messages.
官网:Link
个人理解,这俩包只不过是分开了,但是作用是普通包的作用,一个在构建时用,一个在运行时用。
自定义的msg文件可以使用的字段类型有:

  • int8, int16, int32, int64 (或者无符号类型: uint*)
  • float32, float64
  • string
  • time, duration
  • other msg files
  • variable-length array[] and fixed-length array[C]

ROS中还有一种特殊类型:Header,标头包含时间戳和ROS中常用的坐标帧信息。会经常看到msg文件的第一行具有Header标头。
这就说明必须得有个包帮助他们去识别去构建,这里的类型也不仅仅是c中的类型,所以个人理解这个就是官方人员对这个的特殊对待。
也就能理解generate_message那块依赖于std_msgs 因为例子是使用的其中的数据类型,依赖这一个就够了。之后如果复杂的话,就可能依赖更多的模块
最后的理解就是,用就完了。

写完代码后再次修改cmakelist
add_executable(person_talker src/person_talker.cpp)
add_executable(person_listener src/person_listener.cpp)

add_dependencies(person_talker ${PROJECT_NAME}_generate_messages_cpp)
add_dependencies(person_listener ${PROJECT_NAME}_generate_messages_cpp)

target_link_libraries(person_talker
  ${catkin_LIBRARIES}
)
target_link_libraries(person_listener
  ${catkin_LIBRARIES}
)

这里需要重点注意的是add_dependencies的作用
个人理解
dependencies 这一块之前不需要配置,查阅资料,分析如下
add_dependencies(person_listener ${PROJECT_NAME}_generate_messages_cpp)
这个赵虚左说 是 如果不加正常都可以运行,存在种情况,例如现在咱们自定义msg ,需要提前执行一下,然后进行下一步,如果做得很熟练的话,就不执行,直接往下写,最后一起执行,如果不添加这句,他会先执行main.cpp文件,但这个文件依赖的头文件并没有生成,所以会报错,加上这句,就是会分析你这个主文件需要啥,先把你需要的东西生成了,然后再执行你的主文件。
其他解释如下LinkLink
进而有个问题就是_generate_messages_cpp的含义是什么
还得是国外,看完理解就是在运行节点之前,生成消息头文件,这就对应了之前自定义msg之后我们编译就会生成头文件,也就对应了为什么之前编译之后我们可以不加上面这句的含义。
KaTeX parse error: Expected '}', got 'EOF' at end of input: {{PROJECT_NAME}_EXPORTED_TARGETS}
初步看这个可以完全代替上面的特殊指令,因为这个是什么都包括的大指令,也就是在运行该程序之前所有需要的本功能包里的依赖都给你生成完。(一会测试一下)
测试结果
image.png
没有加上add_dependencies 是上面的结果,
居然,还可以,我之前没有主动编译msg的生成,但是他自动生成了,估计指定生成之后,他就只会生成_generate_messages_cpp的形式了,可能更快一点,应该是这样。
image.png
image.png
这是我解开注释运行的,发现扫描了好多依赖,之前默认的就是std_msgs和当前包的依赖,这个就像之前说的所有的依赖都执行,所以没毛病,可以用。不用改成…cpp的形式
image.png
这是我删掉catkin_EXPORTED_TARGETS之后运行的相当之流畅,也就是非常基本的生成,也就可以理解为默认的生成。也就跟第一种情况一样。
image.png
改成_generate_messages_cpp 依然是上面的样子,可能是一个包运行多次没反应过来,我重新测试一下

image.pngimage.pngimage.png

测试结果如下
其实跟默认情况下不解开注释的结果是一样的。但是解开符合程序流程,这个测试主要目的就是解开的意义和改变后缀的意义,目前来说,解开删掉catkin_exported_targets是最合理的。

_generate_messages_cpp和gen_cpp 那个对?

gen_cpp是在生成service通信消息时候用的,这到底都是用来干什么的
Link(外网访问)
解释:两个都对,后者已经弃用
Link (这个网页解释的及其细致)
_EXPORTED_TARGETS is the recommended way to do it. The user does not need to think about which targets it might contain and does not need to check if the targets actually exist or if the variable is empty.
_generate_messages_LANG can still be used (those are the actually values of the above list variable). But then the user is responsible to check if the target name actually exists. This approach will provide better compilation performance since if you only rely on the C++ header being generated you won’t wait for Python/Lisp/whatever messages have been generated.

下面这个没看懂,以后再说
https://zhuanlan.zhihu.com/p/344560680

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值