ROS本质上就是由一个又一个的package组成的,package可以说是ROS的细胞。在catkin_make的时候它会一个一个的去找package然后生成目标文件。一个package可以有多个节点。判断是否为Package :一个文件夹要被ROS认为是package的话,必须包含以下两个文件:CMakeList.txt和package.xml。
在一个ROS功能包中,CMakeList.txt和package.xml是不可缺少的两个文件。那么package.xml到底起到什么作用呢?
CMakeLists.txt规定catkin编译的规则。(例如:源文件,依赖项,目标文件)。而package.xml文件定义了package的属性。(例如:包名,版本号,作者,一来等等),相当于一个包的自我描述。
一、package.xml的写法
pacakge.xml 遵循xml标签文本的写法, 由于版本更迭原因, 现在有两种格式并存( format1与format2) , 不过区别不大。‘
1.1 旧版本(format1)
<package> <!--1. 根标签-->
<name> <!--2. 包名-->
<version> <!--3. 版本号-->
<description> <!--4. 包描述-->
<maintainer> <!--5. 维护者-->
<license> <!--6. 软件许可-->
<buildtool_depend> <!--7. 编译工具-->
<build_depend> <!--8. 编译时的依赖-->
<run_depend> <!--9. 运行时的依赖-->
</package> <!--根标签-->
PS:其中1-6为必备标签,1是根标签嵌套了其余所有标签,2-6是包的各种属性,7-9是编译相关信息。
1.2 新版本(format2)
<package> <!--1. 根标签-->
<name> <!--2. 包名-->
<version> <!--3. 版本号-->
<description> <!--4. 包描述-->
<maintainer> <!--5. 维护者-->
<license> <!--6. 软件许可-->
<buildtool_depend> <!--7. 编译构建工具,通常为catkin-->
<depend> <!--8. 指定依赖项为编译、 导出、 运行需要的依赖,最常用的依赖标记。-->
<build_depend> <!--9. 编译依赖项-->
<build_export_depend> <!--10. 导出依赖项-->
<exec_depend> <!--11. 运行依赖项-->
<test_depend> <!--12. 测试用例依赖项-->
<doc_depend> <!--13. 文档依赖项-->
</package> <!--根标签-->
1.3 新旧版本的区别
- 新增的标签
<depend> <!--8. 指定依赖项为编译、 导出、 运行需要的依赖,最常用的依赖标记。-->
<build_export_depend> <!--10. 导出依赖项-->
<test_depend> <!--12. 测试用例依赖项-->
<doc_depend> <!--13. 文档依赖项-->
- 更改的标签
- 运行依赖项由
<run_depend>
改为<exec_depend>
二、package.xml的作用
2.1 ros下创建包
首先在ros下创建一个名位beginner_tutorials的软件包:
$ cd ~/catkin_ws/src
$ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
2.2 packag.xml代码
<?xml version="1.0"?>//定义version为1.0
<package format="2">//定义format为2
<name>beginner_tutorials</name>//定义name为beginner_tutorials
<version>0.0.0</version>//定义version为0.0.0
<description>The beginner_tutorials package</description>//定义描述为The be...
<!-- One maintainer tag required, multiple allowed, one person per tag -->
<!-- Example: -->
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
<maintainer email="aoyin@todo.todo">aoyin</maintainer>//定义email
<!-- One license tag required, multiple allowed, one license per tag -->
<!-- Commonly used license strings: -->
<!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
<license>TODO</license>
<!-- Url tags are optional, but multiple are allowed, one per tag -->
<!-- Optional attribute type can be: website, bugtracker, or repository -->
<!-- Example: -->
<!-- <url type="website">http://wiki.ros.org/beginner_tutorials</url> -->
<!-- Author tags are optional, multiple are allowed, one per tag -->
<!-- Authors do not have to be maintainers, but could be -->
<!-- Example: -->
<!-- <author email="jane.doe@example.com">Jane Doe</author> -->
<!-- The *depend tags are used to specify dependencies -->
<!-- Dependencies can be catkin packages or system dependencies -->
<!-- Examples: -->
<!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
<!-- <depend>roscpp</depend> -->//定义depend为roscpp
<!-- Note that this is equivalent to the following: -->
<!-- <build_depend>roscpp</build_depend> -->//定义build_depend为roscpp
<!-- <exec_depend>roscpp</exec_depend> -->//定义exec_depend为roscpp
<!-- Use build_depend for packages you need at compile time: -->
<!-- <build_depend>message_generation</build_depend> -->
<!-- Use build_export_depend for packages you need in order to build against this package: -->
<!-- <build_export_depend>message_generation</build_export_depend> -->
<!-- Use buildtool_depend for build tool packages: -->
<!-- <buildtool_depend>catkin</buildtool_depend> -->//定义buildtool为catkin
<!-- Use exec_depend for packages you need at runtime: -->
<!-- <exec_depend>message_runtime</exec_depend> -->
<!-- Use test_depend for packages you need only for testing: -->
<!-- <test_depend>gtest</test_depend> -->
<!-- Use doc_depend for packages you need only for building documentation: -->
<!-- <doc_depend>doxygen</doc_depend> -->
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>rospy</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>std_msgs</exec_depend>
<!-- The export tag contains other, unspecified, tags -->
<export>
<!-- Other tools can request additional information be placed here -->
</export>
</package>
2.3 catkin编译过程
- 执行catkin_make。
- 执行catkin_workspace。解析catkin_make的参数同时遍历整个工作空间把所有的有package.xml的文件夹添加进软件包列表里面。对每个软件包执行add_subdirectory。
- 执行每个软件包内部的CMakeList.txt文件。
- 执行 catkin_package。解析package.xml文件,载入对应的参数。根据依赖参数,载入对应的软件包参数。根据载入参数生成当前软件包的配置文件。
发现package.xml在第二步和第四步将会用到。
2.4 package.xml的作用
(1) 把包里的xml文件直接删掉:
删掉之后进行catkin_make,通过,但cpp文件并没有被编译,看上去ROS系统并没有把它当作一个功能包。这证明了package.xml文件是功能包被ROS系统识别的前提。
(2) 在xml文件中把 <build_depend>roscpp</build_depend>
<build_depend>std_msgs</build_depend>
<run_depend>roscpp</run_depend>
<run_depend>std_msgs</run_depend>这几句删掉,并把devel和build文件夹删掉:
cpp文件被编译,整个catkin_make也能通过。
(3) 在xml文件中把<buildtool_depend>catkin</buildtool_depend>删掉,并把devel和build文件夹删掉:
catkin_make报错:
CMake Error at /opt/ros/kinetic/share/catkin/cmake/catkin_package.cmake:116 (message):
catkin_package() ‘catkin’ must be listed as a buildtool dependency in the
package.xml
说明**<buildtool_depend>必须包含**。
(4)删除0.0.0:
报错:
Error(s) in package ‘/home/ch/forTest/src/minimal_nodes/package.xml’:
The manifest must contain exactly one “version” tag
说明**必须包含**。
结论:删掉 <build_depend>和<run_depend>并没有影响catkin_make的通过,而删除其他tags就会导致功能包编译失败。
参考:
package.xml使用说明
ros程序包下的package.xml是干什么的?
对ROS功能包中package.xml文件的疑问
知乎问答