当前位置: 首页 > news >正文

【转载】ROS 中 CMakeLists.txt 文件使用的讲解与总结

本博客转载自:【阿里云开发者社区】ROS 中 CMakeLists.txt 文件使用讲解与总结

一、CMakeLists.txt 作用

ROS系统的功能包中要包含 CMakeLists.txt 与 package.xml 文件编译功能包的内容。

CMakeLists.txt 原本是 Cmake 编译系统的规则文件,而Catkin 编译系统基本沿用了 CMake 的编译风格,只是针对 ROS 工程添加了一些宏定义。所以在写法上,catkin 的 CMakeLists.txt 与 CMake 的基本一致。

catkin 的 CMakeLists.txt 文件直接规定了这个 package 要依赖哪些 package,要编译生成哪些目标,如何编译等等流程。

所以 ROS 中 CMakeLists.txt 非常重要,它指定了由源码到目标文件的规则,catkin 编译系统在工作时首先会找到每个 package 下的 CMakeLists.txt ,然后按照规则来编译构建


二、CMakeLists.txt 写法

CMakeLists.txt 的基本语法都还是按照 CMake,而 Catkin 在其中加入了少量的宏。

指令/方法作用/说明
cmake_minimum_required()CMake 的版本号
project()项目名称
find_package()找到编译需要的其他 CMake/Catkin package
catkin_python_setup()catkin 新加宏,打开 catkin 的 Python Module 的支持
add_message_files()catkin 新加宏,添加自定义 Message 文件
generate_message()catkin 新加宏,生成不同语言版本的 msg/srv/action 接口
add_service_files()catkin 新加宏,添加自定义 Service 文件
add_action_files()catkin 新加宏,添加自定义 Action 文件
catkin_package()catkin 新加宏,生成当前 package 的 cmake 配置,供依赖本包的其他软件包调用
catkin_add_gtest()catkin 新加宏,生成测试
add_library()生成库
add_executable()生成可执行二进制文件
add_dependencies()定义目标文件依赖于其他目标文件,确保其他目标已被构建
target_link_libraries()链接
install()安装至本机

三、CMakeLists.txt 实例

为了详细的解释 CMakeLists.txt 的写法,以 turtlesim 小海龟这个 pacakge 为例进行讲解。

可 roscd 到 tuetlesim 包下查看,

在 turtlesim/CMakeLists.txt 的写法如下:

cmake_minimum_required(VERSION 2.8.3) # CMake至少为2.8.3版 project(turtlesim) # 项目 (package) 名称为 turtlesim,在后续文件中可使用变量 ${PROJECT_NAME} 来引用项目名称 turltesim # 这两个是 通过ros 指令 创建包 中就自动生成好的 find_package(catkin REQUIRED COMPONENTS geometry_msgs message_generation rosconsole roscpp roscpp_serialization roslib rostime std_msgs std_srvs) # cmake 宏,指定依赖的其他 pacakge,实际是生成了一些环境变量,如 <NAME>_FOUND, <NAME>_INCLUDE_DIRS , <NAME>_LIBRARYIS # 此处catkin是必备依赖 其余的 geometry_msgs... 为组件 include_directories(include ${catkin_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) # 指定C++的头文件路径 link_directories(${catkin_LIBRARY_DIRS}) # 指定链接库的路径 add_message_files(DIRECTORY msg FILES Color.msg Pose.msg) #自定义msg文件 add_service_files(DIRECTORY srv FILES Kill.srv SetPen.srv Spawn.srv TeleportAbsolute.srv TeleportRelative.srv) #自定义srv文件 generate_messages(DEPENDENCIES geometry_msgs std_msgs std_srvs) # 在 add_message_files、add_service_files 宏之后必须加上这句话,用于生成 srv msg 头文件,生 成的文件位于 devel/include 中 catkin_package(CATKIN_DEPENDS geometry_msgs message_runtime std_msgs std_srvs) # catkin 宏命令,用于配置 ROS 的 package 配置文件和 CMake 文件 # 这个命令必须在 add_library() 或者 add_executable() 之前调用,该函数有 5 个可选参数: # (1) INCLUDE_DIRS - 导出包的include路径 # (2) LIBRARIES - 导出项目中的库 # (3) CATKIN_DEPENDS - 该项目依赖的其他catkin项目 # (4) DEPENDS - 该项目所依赖的非catkin CMake项目。 # (5) CFG_EXTRAS - 其他配置选 set(turtlesim_node_SRCS src/turtlesim.cpp src/turtle.cpp src/turtle_frame.cpp) set(turtlesim_node_HDRS include/turtlesim/turtle_frame.h ) # 指定 turtlesim_node_SRCS、turtlesim_node_HDRS 变量 qt5_wrap_cpp(turtlesim_node_MOCS ${turtlesim_node_HDRS}) add_executable(turtlesim_node ${turtlesim_node_SRCS} ${turtlesim_node_MOCS}) # 指定可执行文件目标turtlesim_node target_link_libraries(turtlesim_node Qt5::Widgets ${catkin_LIBRARIES} ${Boost_LIBRARIE S}) # 指定链接可执行文件 add_dependencies(turtlesim_node turtlesim_gencpp) add_executable(turtle_teleop_key tutorials/teleop_turtle_key.cpp) target_link_libraries(turtle_teleop_key ${catkin_LIBRARIES}) add_dependencies(turtle_teleop_key turtlesim_gencpp) add_executable(draw_square tutorials/draw_square.cpp) target_link_libraries(draw_square ${catkin_LIBRARIES} ${Boost_LIBRARIES}) add_dependencies(draw_square turtlesim_gencpp) add_executable(mimic tutorials/mimic.cpp) target_link_libraries(mimic ${catkin_LIBRARIES}) add_dependencies(mimic turtlesim_gencpp) # 同样指定可执行目标、链接、依赖 install(TARGETS turtlesim_node turtle_teleop_key draw_square mimic RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) # 安装目标文件到本地系统 install(DIRECTORY images DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} FILES_MATCHING PATTERN "*.png" PATTERN "*.svg")

四、工程实践中遇到的问题总结

在一个功能包中,将类的函数定义与声明分开文件写,用 main.cpp 调用

类的声明和定义分开文件下,按之前那么处理、分布查看

只加这个,先生成 library


编译成功类的声明和函数定义分开写的

生成了这个文件

继续加 main.cpp 的
只加这个

报错,很多都没定义

加上这个

这一条最后去掉了编译也成功 ,在使用自己的 msg 头文件时,必须添加 add_dependencies,否则找不到自定义的 msg 产生的头文件!

报错一样
再加

报错变了 没有了 ros::init() 这种未定义了,说明必须要加上面的,是最基本的

现在的错误就是没有找到类的定义的函数

把这个库加上

还是没找到,和之前报错一样

给上面那个类的定义,那个库也加上 target_link_libraries

编译就通过了

target_link_libraries() 这个功能可能是让其它文件可以定用这个库

  • 那么还有个问题 ,要想用其它功能包的类的函数怎么办?

官网有详细的解释
CMakeLists.txt ROS 官网

http://www.jsqmd.com/news/608765/

相关文章:

  • Workstation 避坑指南:网络总连不上?深度解析常见网络配置故障与底层排错逻辑
  • 【计算机网络八股】【欧弟求职】TCP相关
  • 一台服务器跑4个独立站,我是怎么做到的?
  • 魔兽争霸III终极优化指南:免费解决老游戏在现代电脑的兼容性问题
  • RFID智能柜-RFID智能柜公司推荐 - 聚澜智能
  • 如何用 every 判断数组是否所有元素都满足特定条件
  • Spring AI 1.x 系列【25】结构化输出案例演示
  • XOutput完整指南:如何将旧游戏手柄转换为Xbox控制器
  • GeoAI赋能智慧城市:从交通优化到环境监测的实战解析
  • 别再只用‘auto’模式了!深入Halcon条码识别参数:手把手教你调优barcode_width_min与扫描线提升识别率
  • ZYNQ FPGA固化文件生成与烧录全流程详解
  • Springboot 实现多数据源(PostgreSQL 和 SQL Server)连接康
  • 基于改进A*算法与DWA融合策略的机器人路径规划仿真研究:全局规划与局部避障的综合性能分析
  • c++如何利用C++23的std--expected重构文件操作的错误检查代码【实战】
  • Node Modules Inspector:可视化你的Node.js依赖关系,5分钟快速上手指南
  • 电容滤波实战:如何为你的MCU电源选择100nf和1uf电容组合?
  • 企业级 Agent 治理平台:公司用数字帮手的必备管家
  • 三步解锁网易云加密音乐:ncmdump让NCM文件全设备自由播放
  • FanControl:三招告别电脑噪音,打造你的专属静音散热系统
  • uni-app动态修改tabbar uni-app如何根据权限显示不同的tab
  • 写段代码教会你什么是HOOK技术?HOOK技术能干什么?刎
  • 一文学习 Spring 声明式事务源码全流程总结勇
  • Android息屏后台任务保活实战:从定时器失效到厂商白名单破解
  • Build-A-Large-Language-Model-CN:大语言模型训练中的常见问题与解决方案
  • MVN--07
  • 金融系统的测试特殊性:安全、合规与性能
  • CyberpunkSaveEditor:革新性存档自定义工具完全指南 - 全方位掌控游戏体验
  • 自学渗透测试第12天(渗透测试流程与DVWA部署)
  • 5个实际场景,用Pix2Text高效解决图像转文本难题
  • IOFILE结构体的介绍与House of orange敦