知识分享 ros ROS1&2之CmakeList.txt与package.xml MGodmonkey 2023-07-26 2025-09-12 1. CMakeLists.txt与package.xml的作用 在ROS 系统的功能包中 要包含 CMakeLists.txt  与 package.xml  文件来编译功能包的内容
CMakeLists.txt 原本是Cmake 编译系统的规则文件,而Catkin 编译系统基本沿用了CMake 的编译风格,只是针对ROS 工程添加了一些宏定义。所以在写法上,catkin  的 CMakeLists.txt 与CMake 的基本一致。用cmake 命令创建功能包 时,会自动生成CMakeList.txt 文件,已配置了多数编译选项,且包含详细的注释,只需稍作修改便可编译自己的文件。
而package.xml 文件是描述功能包清单的文件,包括功能包的名称 、版本号 、作者信息 、许可信息 、编译依赖 和运行依赖 等。
所以 CMakeLists.txt  非常重要,它指定了由源码到目标文件的规则,catkin 编译系统在工作时首先会找到每个package 下的 CMakeLists.txt  ,然后按照规则来编译构建
2. 生成CMakeLists.txt 2.1 ROS1 ROS1 可通过用catkin_create_pkg 命令创建功能包 ,这会自动生成CMakeLists.txt 和package.xml 文件的。
1 2 3 4 5 6 7 8 9 10 mkdir  -p ~/catkin_ws/srccd  ~/catkin_ws/srccatkin_create_pkg test  std_msgs rospy roscpp tree 
通过上面的命令生成的工作空间 如下
include:存放**.h**的头文件
src:可同时存放**.cpp或 .py的源文件,但一般 .py**文件存放在scripts目录中
scripts:习惯存放**.py的 python**文件,需要自己创建
注:python代码和c++代码不分家,可同时存放在同一功能包中 
2.2 ROS2 ROS2 可通过如下的命令来创建功能包 以及必要的CMakeList.txt 和package.xml 文件
1 2 3 4 5 6 7 8 9 10 11 mkdir  -p ~/dev_ws/srccd  ~/dev_ws/srcros2 pkg create --build-type ament_cmake test_c ros2 pkg create --build-type ament_python test_python tree 
通过以上命令生成的工作空间如下:
test_c/include:存放**.h**的头文件
test_c/src:存放**.cpp的 C++**源文件
test_python/test_python:存放**.py的 python**文件
注:与ROS1不同,同一功能包内只能同时包含python文件或者C++文件中的一种 
3. CMakeLists.txt编写 3.1 ROS1 常用的ROS1 中CMakeLists.txt 架构如下 视频解析参考:中科院软件所-机器人操作系统入门(ROS入门教程) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 cmake_minimum_required ()	project ()					find_package ()				catkin_python_setup()		 add_message_files()			 add_service_files()          add_action_files()           generate_message()			 catkin_package()			 add_library ()				add_executable ()			add_dependencies ()			target_link_libraries ()		catkin_add_gtest()			 install ()					
需要自己配置的项目一般就下面几种:
CMakeLists.txt模板参考:CMakeLists.txt 
更多教程参考:catkin/CMakeLists.txt - ROS Wiki 
3.2 ROS2 常用的ROS2 中CMakeLists.txt 架构如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 cmake_minimum_required ()			project ()				  		   find_package ()   				    ament_target_dependencies()           add_executable ()				    install ()						   ament_package()						 rosidl_generate_interfaces()		 
示例模板如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 cmake_minimum_required (VERSION 3.5 )project (test_c)if (NOT  CMAKE_C_STANDARD)  set (CMAKE_C_STANDARD 99 ) endif ()if (NOT  CMAKE_CXX_STANDARD)  set (CMAKE_CXX_STANDARD 14 ) endif ()if (CMAKE_COMPILER_IS_GNUCXX OR  CMAKE_CXX_COMPILER_ID MATCHES  "Clang" )  add_compile_options (-Wall -Wextra -Wpedantic) endif ()find_package (ament_cmake REQUIRED)find_package (rclcpp REQUIRED)find_package (std_msgs REQUIRED)add_executable (talker src/publisher_member_function.cpp)	ament_target_dependencies(talker rclcpp std_msgs)			 install (TARGETS  talker												   DESTINATION lib/${PROJECT_NAME} ) if (BUILD_TESTING)  find_package (ament_lint_auto REQUIRED)                     ament_lint_auto_find_test_dependencies() endif ()find_package (geometry_msgs REQUIRED)find_package (rosidl_default_generators REQUIRED)rosidl_generate_interfaces(${PROJECT_NAME}    "msg/Num.msg" 				   "msg/Sphere.msg" 			   "srv/AddThreeInts.srv"         DEPENDENCIES geometry_msgs ) ament_package() 
相较于基于catkin 的CMake 文件,基于ament 的明显简洁很多
假设你编写了~/dev_ws/src/test.cpp文件后,需要修改的步骤如下:
链接源代码 1 2 add_executable (test  src/test .cpp)	ament_target_dependencies(test  rclcpp)	 
添加下面这两行代码的目的是让编译器编译~/dev_ws/src/test_c/test.cpp这个文件 1 2 3 4 install (TARGETS  test    DESTINATION lib/${PROJECT_NAME}  ) 
当你自定义消息类型时还需要消息类型文件
1 2 3 4 5 6 7 8 9 10 11 find_package (geometry_msgs REQUIRED)find_package (rosidl_default_generators REQUIRED)rosidl_generate_interfaces(${PROJECT_NAME}    "msg/Num.msg" 				   "msg/Sphere.msg" 			   "srv/AddThreeInts.srv"         DEPENDENCIES geometry_msgs ) 
4. package.xml编写 package.xml 的框架如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <package  format ="3" >   <name > ..</name >    <version > 0.0.0</version >    <description > ...</description >    <maintainer  email ="lanhanba@todo.todo" > ...</maintainer >    <license > ...</license >    <buildtool_depend > ...</buildtool_depend >    <exec_depend > ...</exec_depend >    <exec_depend > ...</exec_depend >    <export >      <build_type > ...</build_type >    </export >  </package > 
相较于CMakeList.txt ,package.xml 的语法就简单许多,且ROS1 和ROS2 的标签语法通用
<build_depend></build_depend> : 标签定义了功能包中代码编译时所依赖的其他功能包<exec_depend><exec_depend> : 标签定义了功能包中可执行程序运行时所依赖的其他功能包自定义数据类型 :话题消息msg 、服务数据srv 、动作数据action 模板如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 <?xml version="1.0" ?> <?xml-model href="http://download.ros.org/schema/package_format3.xsd"  schematypens="http://www.w3.org/2001/XMLSchema" ?> <package  format ="3" >   <name > test_c</name >    <version > 0.0.0</version >    <description > TODO: Package description</description >    <maintainer  email ="lanhanba@todo.todo" > lanhanba</maintainer >    <license > TODO: License declaration</license >       <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 >          <buildtool_depend > ament_cmake</buildtool_depend >    <test_depend > ament_lint_auto</test_depend >    <test_depend > ament_lint_common</test_depend >    <export >      <build_type > ament_cmake</build_type >    </export >            <test_depend > ament_copyright</test_depend >    <test_depend > ament_flake8</test_depend >    <test_depend > ament_pep257</test_depend >    <test_depend > python3-pytest</test_depend >    <export >      <build_type > ament_python</build_type >    </export >          <depend > rosidl_default_generators</depend >    <depend > geometry_msgs</depend >    <member_of_group > rosidl_interface_packages</member_of_group >       </package > 
5. 其他–Setup.py的修改 在ROS2-Python 功能包中,如果添加类似~/dev_ws/src/test_python/test.py的python 文件,则需要对功能包中的Setup.py  进行如下的修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 from  setuptools import  setuppackage_name = 'test_python'  setup(     name=package_name,     version='0.0.0' ,     packages=[package_name],     data_files=[         ('share/ament_index/resource_index/packages' ,             ['resource/'  + package_name]),         ('share/'  + package_name, ['package.xml' ]),     ],     install_requires=['setuptools' ],     zip_safe=True ,     maintainer='lanhanba' ,     maintainer_email='lanhanba@todo.todo' ,     description='TODO: Package description' ,     license='TODO: License declaration' ,     tests_require=['pytest' ],     entry_points={         'console_scripts' : [                                                    "test = test_python.test:main" ,             "test2 = test_python.test2:main"          ],     }, ) 
参考: