【ROS】 CMakeLists 文件详解

news2025/4/6 15:11:15

【ROS】 CMakeLists文件详解

  • 前言
  • 标准的CMAKELIST.TXT文件的组成部分
    • CMake 版本要求和项目名称
    • 指定编译器和设置构建规则
    • 查找 ROS 依赖
    • 消息和服务文件
    • catkin_package
    • 设置头文件目录路径
    • 添加可执行文件的构建规则
    • 设置编译依赖关系(构建顺序)
    • 设置目标文件的链接库
    • 其他规则
  • 示例文件

前言

在 ROS 的学习过程中,即使主要使用 Python 进行开发,仍然会频繁涉及 CMakeLists.txt 文件。因此,本文将简要介绍 CMakeLists.txt 的相关知识,并通过示例加以说明。

在深入了解 CMakeLists.txt 之前,我们首先需要理解它与 CMake、Make、GCC、G++、NVCC 之间的关系,以及 .c.cpp.o.so.a 等文件的作用。此外,还需掌握 编译、链接、构建、目标文件和可执行文件 等相关概念,以便更好地理解 CMakeLists.txt 的作用和使用方式。

有关这些概念的详细介绍,可以参考以下文章:

  • 【编译、链接与构建详解】Makefile 与 CMakeLists 的作用。

标准的CMAKELIST.TXT文件的组成部分

一个标准的 ROS CMakeLists.txt 文件通常包含以下几个部分,每个部分负责不同的配置和设置:

CMake 版本要求和项目名称

  • 指定 CMake 的最低版本要求
  • 定义项目的名称
# 指定所需的 CMake 最低版本(>=2.8.3)
cmake_minimum_required(VERSION 2.8.3)

# 定义项目名称为 'xf_mic_asr_offline'
project(xf_mic_asr_offline)

指定编译器和设置构建规则

  • 指定编译器版本
  • 设置构建规则
# 启用 C++11 标准支持
# 说明:指定编译器使用 C++11 标准进行代码编译
add_compile_options(-std=c++11)

# 配置 C++ 编译器标志
# 说明:在现有的编译标志基础上添加 -g 选项,支持调试信息的生成
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")

# 开启详细构建输出
# 说明:设置 CMake 在构建过程中显示完整的编译和链接命令
set(CMAKE_VERBOSE_MAKEFILE ON)

查找 ROS 依赖

  • 使用 find_package 查找并加载 ROS 依赖包。如果缺少必要的依赖包,构建过程将报错。
# 查找并加载项目依赖的外部包
# find_package 命令格式:find_package(<包名> [REQUIRED] [[COMPONENTS] [组件1] [组件2] ...])
# 参数说明:
# - REQUIRED:表示该包是必需的,若找不到将导致编译失败
# - COMPONENTS:用于指定需要加载的具体组件

find_package(catkin REQUIRED COMPONENTS
  roscpp          # ROS 的 C++ 客户端库
  rospy           # ROS 的 Python 客户端库
  std_msgs        # ROS 标准消息库
  message_generation  # ROS 消息生成工具
)

消息和服务文件

  • 定义自定义的消息和服务文件的位置。(官方提供的消息和服务文件无需添加,如 std_msgs
  • 定义自定义消息和服务所依赖的 ROS 官方消息包(例如,自定义的消息文件如果依赖于 std_msgs.msg,则需要在 generate_messages 中添加 std_msgs)。
# 添加自定义消息文件
# 说明:指定项目中需要编译的自定义消息文件 (.msg)
# 注意:仅需添加在 msg 目录下的自定义消息文件,无需添加 ROS 自带的消息文件
add_message_files(
  FILES
  Pcm_Msg.msg    # PCM 音频数据消息
)

# 添加自定义服务文件
# 说明:指定项目中需要编译的自定义服务文件 (.srv)
# 注意:仅需添加在 srv 目录下的自定义服务文件,无需添加 ROS 自带的服务文件
add_service_files(
  FILES
  Get_Offline_Result_srv.srv    # 获取离线识别结果服务
  Set_Major_Mic_srv.srv         # 设置主麦克风服务
  Get_Major_Mic_srv.srv         # 获取主麦克风服务
  Start_Record_srv.srv          # 开始录音服务
  Set_Awake_Word_srv.srv        # 设置唤醒词服务
  Set_Led_On_srv.srv            # 设置 LED 开关服务
  Get_Awake_Angle_srv.srv       # 获取唤醒角度服务
)

# 生成消息和服务的接口代码
# 说明:根据上述定义的消息和服务文件生成对应的代码实现
# 参数说明:
# DEPENDENCIES:指定消息生成时依赖的其他消息包
# std_msgs:标准消息包,提供基础数据类型的消息定义
generate_messages(
  DEPENDENCIES
  std_msgs
)

catkin_package

  • catkin_package 用于配置当前 ROS 功能包的依赖关系及导出项,声明当前包所依赖的其他功能包以及需要导出的文件(如头文件、库文件等),供其他功能包使用。
# catkin_package 函数用于配置当前 ROS 功能包的依赖和导出项
# 函数格式说明:
# catkin_package(CATKIN_DEPENDS [依赖的 ROS 包...] DEPENDS [依赖的系统库...] INCLUDE_DIRS [导出的头文件路径...] LIBRARIES [导出的库文件...])

# 参数说明:
# CATKIN_DEPENDS:声明对其他 ROS 包的依赖
# DEPENDS:声明对系统库或非 catkin 包的依赖
# INCLUDE_DIRS:声明本包导出的头文件路径
# LIBRARIES:声明本包导出的库文件路径

catkin_package(
  CATKIN_DEPENDS message_runtime    # 依赖 message_runtime 包用于消息运行时支持
  LIBRARIES libmsc.so              # 导出 libmsc.so 库
  # INCLUDE_DIRS include          # 此行被注释,不导出头文件
  # CATKIN_DEPENDS roscpp rospy sensor_msgs std_msgs  # 此行被注释,不使用这些 ROS 包依赖
  # DEPENDS system_lib           # 此行被注释,不使用系统库依赖
)

设置头文件目录路径

  • 使用 include_directories 函数来指定编译时的头文件搜索路径。
# include_directories 用于指定编译时的头文件搜索路径
# 函数格式:include_directories([AFTER|BEFORE] [SYSTEM] <目录1> <目录2> ...)
# 参数说明:
# AFTER|BEFORE:可选参数,指定新路径在系统默认搜索路径前还是后添加
# SYSTEM:可选参数,将目录标记为系统目录,编译器会优先搜索
# 目录路径说明:
# include:项目本地头文件目录,通常指向项目的 include 目录
# ${catkin_INCLUDE_DIRS}:ROS 依赖包的头文件目录,包含所有 CATKIN_DEPENDS 声明的包

include_directories(
  include                    # 本项目的本地头文件目录
  ${catkin_INCLUDE_DIRS}     # ROS 依赖包的头文件目录
)

添加可执行文件的构建规则

  • 使用 add_executable 函数定义源文件和生成的可执行文件。
# add_executable 用于生成可执行文件
# 函数格式:add_executable(<可执行文件名> [源文件1 源文件2 ...])
# 本例说明:
# 将 src/hid_test_auto.cpp 编译为可执行文件 xf_asr_offline_node
# 该 cpp 文件包含 main 函数入口,是 ROS 节点的主程序文件

add_executable(xf_asr_offline_node src/hid_test_auto.cpp)

设置编译依赖关系(构建顺序)

  • 设置编译依赖关系有助于确保构建顺序的正确性,自动确定各个目标文件的构建顺序。
# add_dependencies 用于设置目标文件的编译依赖关系
# 函数格式:add_dependencies(<目标文件> <依赖项1> <依赖项2> ...)
# 参数说明:
# 目标文件:可以是可执行文件、动态库、静态库等
# 依赖项:指定目标文件依赖的其他目标,如其他库文件、自动生成的消息代码等

add_dependencies(
  xf_asr_offline_node                    # 目标文件:语音识别节点的可执行文件
  ${xf_mic_package_EXPORTED_TARGETS}     # 依赖项:导出的目标文件
  xf_mic_asr_offline_gencpp             # 依赖项:自动生成的 C++ 消息代码
)

设置目标文件的链接库

  • 通过设置目标文件的链接库,可以指定目标文件链接的 .o 目标文件以及静态或动态库,提高代码复用性。
# target_link_libraries 用于设置目标文件的链接库
# 函数格式:target_link_libraries(<目标文件> [库1 库2 ...])
# 链接库分类:
# - ROS 依赖库:${catkin_LIBRARIES}    # ROS 相关的库文件
# - 自定义动态库:
#   - msc                            # 语音识别库 libmsc.so
#   - offline_record_lib            # 离线录音库 liboffline_record_lib.so
#   - hid_lib                       # HID 设备库 libhidapi.so
# - 系统动态库:
#   - rt                             # 实时库
#   - dl                             # 动态链接库
#   - pthread                        # POSIX 线程库
#   - stdc++                         # C++ 标准库

target_link_libraries(xf_asr_offline_node 
  ${catkin_LIBRARIES}          # ROS 库
  msc                         # 语音识别库
  offline_record_lib          # 离线录音库
  hid_lib                     # HID 设备库
  rt                          # 实时库
  dl                          # 动态链接库
  pthread                     # 线程库
  stdc++                      # C++ 标准库
)

其他规则

在 ROS 中,诸如安装规则、版本控制、单元测试配置等其他构建规则使用较少,因此本文将不再详细讨论。

示例文件

#指定CMake最低版本要求
cmake_minimum_required(VERSION 2.8.3)
#定义项目名称
project(xf_mic_asr_offline)

#设置编译选项
add_compile_options(-std=c++11)    #使用C++11标准
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")    #添加调试信息
set(CMAKE_VERBOSE_MAKEFILE ON)    #显示详细的构建信息

#查找所需的功能包
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)

#根据CPU架构选择对应的库文件目录
if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64")
  message("-- 当前cpu架构: ${CMAKE_HOST_SYSTEM_PROCESSOR}")
  message("-- 使用lib/x64/库")
  link_directories(lib/x64)
elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "aarch64")
  message("-- 当前cpu架构: ${CMAKE_HOST_SYSTEM_PROCESSOR}")
  message("-- 使用lib/arm64/库")
  link_directories(lib/arm64)
elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "aarch32")
  message("-- 当前cpu架构: ${CMAKE_HOST_SYSTEM_PROCESSOR}")
  message("-- 使用lib/arm32/库")
  link_directories(lib/arm32)
else()
  message("-- 当前cpu架构: ${CMAKE_HOST_SYSTEM_PROCESSOR}")
  message("-- 使用默认lib/x64/库,如不正确请修改xf_mic_asr_offline/CMakeLists.txt")
  link_directories(lib/x64)
endif()

#添加消息文件
add_message_files(
  FILES
  Pcm_Msg.msg
)

#添加服务文件
add_service_files(
  FILES
  Get_Offline_Result_srv.srv
  Set_Major_Mic_srv.srv
  Get_Major_Mic_srv.srv
  Start_Record_srv.srv
  Set_Awake_Word_srv.srv
  Set_Led_On_srv.srv
  Get_Awake_Angle_srv.srv
)

#生成消息和服务的依赖项
generate_messages(
  DEPENDENCIES
  std_msgs
)

#配置功能包
catkin_package(
  CATKIN_DEPENDS message_runtime
  LIBRARIES libmsc.so
)

#设置头文件目录
include_directories(
  include
  ${catkin_INCLUDE_DIRS}
)

#第一个节点的编译配置
#添加可执行文件
add_executable(xf_asr_offline_node src/hid_test_auto.cpp)
#添加依赖关系
add_dependencies(
  xf_asr_offline_node
  ${xf_mic_package_EXPORTED_TARGETS}
  xf_mic_asr_offline_gencpp
)
#添加链接库
target_link_libraries(xf_asr_offline_node 
  ${catkin_LIBRARIES} 
  msc 
  offline_record_lib 
  hid_lib 
  rt 
  dl 
  pthread 
  stdc++
)

#第二个节点的编译配置
#添加可执行文件
add_executable(client_node src/client.cpp)
#添加依赖关系
add_dependencies(
  client_node
  ${xf_mic_package_EXPORTED_TARGETS}
  xf_mic_asr_offline_gencpp
)
#添加链接库
target_link_libraries(client_node 
  ${catkin_LIBRARIES} 
  offline_record_lib 
  hid_lib 
  rt 
  dl  
  pthread 
  stdc++
)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2329293.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

7-1 素数求和(线性筛实现)

7-1 素数求和。 分数 10 中等 全屏浏览 切换布局 作者 魏英 单位 浙江科技大学 输入两个正整数m和n&#xff08;1<m<n<500&#xff09;统计并输出m和n之间的素数个数以及这些素数的和。 输入格式: 输入两个正整数m和n&#xff08;1<m<n<500&#xff0…

ZKmall开源商城多云高可用架构方案:AWS/Azure/阿里云全栈实践

随着企业数字化转型的加速&#xff0c;云计算服务已成为IT战略中的核心部分。ZKmall开源商城作为一款高性能的开源商城系统&#xff0c;其在多云环境下的高可用架构方案备受关注。下面将结合AWS、Azure和阿里云三大主流云平台&#xff0c;探讨ZKmall的多云高可用架构全栈实践。…

leetcode二叉树刷题调试不方便的解决办法

1. 二叉树不易构建 在leetcode中刷题时&#xff0c;如果没有会员就需要将代码拷贝到本地的编译器进行调试。但是leetcode中有一类题可谓是毒瘤&#xff0c;那就是二叉树的题。 要调试二叉树有关的题需要根据测试用例给出的前序遍历&#xff0c;自己构建一个二叉树&#xff0c;…

颜色性格测试:探索你的内在性格色彩

颜色性格测试&#xff1a;探索你的内在性格色彩 在我们的日常生活中&#xff0c;颜色无处不在&#xff0c;而我们对颜色的偏好往往能反映出我们内在的性格特质。今天我要分享一个有趣的在线工具 —— 颜色性格测试&#xff0c;它能通过你最喜欢的颜色来分析你的性格倾向。 &…

CMake学习--Window下VSCode 中 CMake C++ 代码调试操作方法

目录 一、背景知识二、使用方法&#xff08;一&#xff09;安装扩展&#xff08;二&#xff09;创建 CMake 项目&#xff08;三&#xff09;编写代码&#xff08;四&#xff09;配置 CMakeLists.txt&#xff08;五&#xff09;生成构建文件&#xff08;六&#xff09;开始调试 …

神经网络入门:生动解读机器学习的“神经元”

神经网络作为机器学习中的核心算法之一&#xff0c;其灵感来源于生物神经系统。在本文中&#xff0c;我们将带领大家手把手学习神经网络的基本原理、结构和训练过程&#xff0c;并通过详细的 Python 代码实例让理论与实践紧密结合。无论你是编程新手还是机器学习爱好者&#xf…

web漏洞靶场学习分享

靶场&#xff1a;pikachu靶场 pikachu漏洞靶场漏洞类型: Burt Force(暴力破解漏洞)XSS(跨站脚本漏洞)CSRF(跨站请求伪造)SQL-Inject(SQL注入漏洞)RCE(远程命令/代码执行)Files Inclusion(文件包含漏洞)Unsafe file downloads(不安全的文件下载)Unsafe file uploads(不安全的文…

MCP over MQTT:EMQX 开启物联网 Agentic 时代

前言 随着 DeepSeek 等大语言模型&#xff08;LLM&#xff09;的广泛应用&#xff0c;如何找到合适的场景&#xff0c;并基于这些大模型构建服务于各行各业的智能体成为关键课题。在社区中&#xff0c;支持智能体开发的基础设施和工具层出不穷&#xff0c;其中&#xff0c;Ant…

ACM代码模式笔记

系列博客目录 文章目录 系列博客目录1.换行符 1.换行符 nextInt()、nextDouble() 等不会消耗换行符&#xff1a; 当使用 nextInt() 或 nextDouble() 读取数字时&#xff0c;它只读取数字部分&#xff0c;不会消耗掉输入后的换行符。 nextLine() 会读取并消耗换行符&#xff1a…

[王阳明代数讲义]具身智能才气等级分评价排位系统领域投射模型讲义

具身智能才气等级分评价排位系统领域投射模型讲义 具身智能胆识曲线调查琴语言的行为主义特性与模式匹配琴语言的"气质邻域 "与气度&#xff0c;云藏山鹰符号约定 琴语言的"气质邻域 "与气度&#xff0c;一尚韬竹符号约定 琴语言的"气质邻域 "与…

【Block总结】PlainUSR的局部注意力,即插即用|ACCV2024

论文信息 标题: PlainUSR: Chasing Faster ConvNet for Efficient Super-Resolution作者: Yan Wang, Yusen Li, Gang Wang, Xiaoguang Liu发表时间: 2024年会议/期刊: 亚洲计算机视觉会议&#xff08;ACCV 2024&#xff09;研究背景: 超分辨率&#xff08;Super-Resolution, S…

【C++】从零实现Json-Rpc框架(2)

目录 JsonCpp库 1.1- Json数据格式 1.2 - JsonCpp介绍 • 序列化接口 • 反序列化接口 1.3 - Json序列化实践 JsonCpp使用 Muduo库 2.1 - Muduo库是什么 2.2 - Muduo库常见接口介绍 TcpServer类基础介绍 EventLoop类基础介绍 TcpConnection类基础介绍 TcpClient…

FastAPI依赖注入:链式调用与多级参数传递

title: FastAPI依赖注入:链式调用与多级参数传递 date: 2025/04/05 18:43:12 updated: 2025/04/05 18:43:12 author: cmdragon excerpt: FastAPI的依赖注入系统通过链式调用和多级参数传递实现组件间的解耦和复用。核心特性包括解耦性、可复用性、可测试性和声明式依赖解析…

【STM32单片机】#5 定时中断

主要参考学习资料&#xff1a; B站江协科技 STM32入门教程-2023版 细致讲解 中文字幕 开发资料下载链接&#xff1a;https://pan.baidu.com/s/1h_UjuQKDX9IpP-U1Effbsw?pwddspb 单片机套装&#xff1a;STM32F103C8T6开发板单片机C6T6核心板 实验板最小系统板套件科协 实验&…

OrbStack 作为 Mac 用户的 Docker 替代方案

推荐使用 OrbStack 作为 Mac 用户的 Docker 替代方案 在现代开发环境中,容器化技术已经成为了软件开发的重要组成部分。对于 Mac 用户来说,Docker Desktop 是一个广泛使用的工具,但它并不是唯一的选择。本文将推荐 OrbStack 作为 Docker Desktop 的替代方案,并探讨其优势。…

运行小程序报错

[ app.json 文件内容错误] app.json: ["tabBar"]["list"] 不能超过 5 项(env: Windows,mp,1.06.2206090; lib: 3.7.12) 他的意思大概是&#xff0c;微信小程序 app.json 文件中的 tabBar.list 配置项超过了 5 项。这是微信小程序的限制&#xff0c;tabBar…

深入剖析丝杆升降机工作原理,解锁工业传动奥秘

丝杆升降机&#xff0c;在工业设备的大舞台上扮演着不可或缺的角色&#xff0c;被广泛应用于机械制造、自动化生产线、建筑施工等众多领域。它能够精准实现重物的升降、定位等操作&#xff0c;为各类工业生产提供了稳定可靠的支持。想要深入了解丝杆升降机&#xff0c;就必须探…

【51单片机】2-3【I/O口】震动传感器控制LED灯

1.硬件 51最小系统LED灯模块震动传感器模块 2.软件 #include "reg52.h"sbit led1 P3^7;//根据原理图&#xff08;电路图&#xff09;&#xff0c;设备变量led1指向P3组IO口的第7口 sbit vibrate P3^3;//震动传感器DO接P3.3口void Delay2000ms() //11.0592MHz {…

医疗思维图与数智云融合:从私有云到思维图的AI架构迭代(代码版)

医疗思维图作为AI架构演进的重要方向,其发展路径从传统云计算向融合时空智能、大模型及生态开放的“思维图”架构迭代,体现了技术与场景深度融合的趋势。 以下是其架构迭代的核心路径与关键特征分析: 一、从“智慧云”到“思维图”的架构演进逻辑 以下是针对医疗信息化领域…

【JS】接雨水题解

题目 思路 首先我们要明确如何计算每条柱子的接水量&#xff1a; 每条柱子对应接到的雨水量该柱子左边最大值和右边最大值中的较小值-该柱子本身的高度。举例&#xff1a;第二条柱子自身高度为0&#xff0c;左边最大值为1&#xff0c;右边最大值为3&#xff0c;取较小值1-自身…