Cmake编译方式内容很多,下面仅仅粗略介绍,最好参照官网文档: https://cmake.org/cmake/help/v3.3/manual/cmake-commands.7.html#id2
 

1.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/Service/Action文件
add_service_files()
add_action_files()
generate_message() #catkin新加宏,生成不同语言版本的msg/srv/action接口
catkin_package() #catkin新加宏,生成当前package的cmake配置,供依赖本包的其他软件包调用
add_library() #生成库
add_executable() #生成可执行二进制文件
add_dependencies() #定义目标文件依赖于其他目标文件,确保其他目标已被构建
target_link_libraries() #链接
catkin_add_gtest() #catkin新加宏,生成测试
install() #安装至本机
 
为了详细的解释 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 

find_package(
catkin REQUIRED COMPONENTS 
geometry_msgs 
message_generation 
rosconsole 
ro 
scpp 
roscpp_serialization 
roslib 
rostime 
std_msgs 
std_srvs
) 
#cmake宏,指定依赖的其他pacakge,实际是生成了一些环境变量,如<NAME>_FOUND, <NAME>_INCLUDE_DIRS , <NAME>_LIBRARYIS 
此处catkin是必备依赖 其余的geometry_msgs、message_generation ...被依赖组件 

find_package(Qt5Widgets REQUIRED) 
find_package(Boost REQUIRED COMPONENTS thread) 

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头文件/module,生成的文件位于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")

下面进行解读:

1)首先第一行,cmake_minimum_required(VERSION 2.8.3) ,定义了Cmake的版本,我们知道catkin_make就是基于Cmake的,查看系统的Cmake版本命令如下:

cmake -version

2)project(turtlesim) ,定义此package的名称,在后续文件中可使用变量${PROJECT_NAME}来引用该项目名称

3)find_package(catkin REQUIRED COMPONENTS geometry_msgs ...),定义此package关于catkin所依赖的package,注意:是关于catkin。REQUIRED为可选字段。表示一定要找到包,找不到的话就立即停掉整个cmake;COMPONENTS 为可选字段,表示查找的包中必须要找到的组件(components),如果有任何一个找不到就算失败,类似于REQUIRED,导致cmake停止执行。

4)include_directories(include ${catkin_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})。定义C++头文件的路径,Boost_INCLUDE_DIRS和catkin_INCLUDE_DIRS环境变量在上面find_package中加载。在有的时候会出现find_package找不到 __Config.cmake, _-config.cmake的情况,解决办法非常简单,因为这两个文件都是包含了package所需的所有路径变量,非常重要,没有它们find_package不会起效果,所以直接去根目录下搜到这两个文件,路径复制后,直接设置,如$set(Boost /opt/ros/kinetic/share/Boost)

5)link_directories(${catkin_LIBRARY_DIRS})。定义链接库catkin的路径

6)add_message_files(DIRECTORY msg FILES  Color.msg Pose.msg)。引入自定义的msg,DIRECTORY为目录msg,FILES 文件为Color.mgs和Pose.msg

7)add_service_files() 同add_messges_files

8)generate_messages(DEPENDENCIES geometry_msgs std_msgs std_srvs)。在add_message_filesadd_service_files宏之后必须加上这句话,用于生成srv msg头文件/module,生 成的文件位于devel/include

9)catkin_package(CATKIN_DEPENDS geometry_msgs message_runtime std_msgs std_srvs) 。声明依赖于此包的包的依赖关系,意思是当别的包想依赖此包时,不仅需要当前包,还需要依赖catkin_package定义的包。注意:catkin_package与find_package正好相反,前者是把依赖项声明出去,而后者是声明进来

10)set(turtlesim_node_SRCS src/turtlesim.cpp ...)。定义CmakeLists的内部变量,turtlesim_node_SRCS可以被后面引用,方式是${turtlesim_node_SRCS}

11)add_executable(turtlesim_node ${turtlesim_node_SRCS} ${turtlesim_node_MOCS})。它的作用是添加一个可执行文件构建目标,这里面引用了set标签设置的内部变量,实际上也可以直接写链接地址src/turtlesim.cpp ...

12)target_link_libraries(turtlesim_node Qt5::Widgets ${catkin_LIBRARIES} ${Boost_LIBRARIE S})。该指令的作用为将目标文件与库文件进行链接,保证当前目标文件可以访问到库,与add_executable连用,并且必须在其后。

13)add_dependencies(..)。对于编译时遇到的依赖问题,很多时候我们只需要一句target_link_libraries就可以搞定。一般来说用不到。用到的情况就是两个targets有依赖关系(通过target_link_libraries解决)并且依赖库也是通过编译源码产生的。这时候一句add_dependencies可以在直接编译上层target时,自动检查下层依赖库是否已经生成。没有的话先编译下层依赖库,然后再编译上层target,最后link depend target。

14)install(TARGETS ...)将目录文件保存到某个地址,install(DIRECTORY...)将某个目录保存到某个地址

 

2.package.xml

package.xml 也是一个catkinpackage必备文件,它是这个软件包的描述文件,pacakge.xml 包含了package的名称、版本号、内容描述、维护人员、软件许可、编译构建工 具、编译依赖、运行依赖等信息。

实际上 rospack find rosdep 等命令之所以能快速定位和分析出package的依赖项信息,就是直接读取了每一个pacakge中的 package.xml 文件。它为用户提供了快速了解一个pacakge 的渠道。

 

package的写法

pacakge.xml 遵循xml标签文本的写法,包含的标签为:

<pacakge> 根标记文件
<name> 包名
<version> 版本号
<description> 内容描述
<maintainer> 维护者
<license> 软件许可证
<buildtool_depend> 编译构建工具,通常为 catkin
<depend> 指定依赖项为编译、导出、运行需要的依赖,最常用
<build_depend> 编译依赖项
<build_export_depend> 导出依赖项
<exec_depend> 运行依赖项
<test_depend> 测试用例依赖项
<doc_depend> 文档依赖项
 
为了说明 pacakge.xml 写法,以 turtlesim 软件包为例,其 pacakge.xml 文件内容如下:
 
<?xml version="1.0"?> 
<package format="2"> <!--在声明pacakge时指定format2,为新版格式-->
<name>turtlesim</name> 
<version>0.8.1</version> 

<description> 
turtlesim is a tool made for teaching ROS and ROS packages. 
</description> 

<maintainer email="dthomas@osrfoundation.org">Dirk Thomas</maintainer> 

<license>BSD</license> 

<url type="website">http://www.ros.org/wiki/turtlesim</url> 
<url type="bugtracker">https://github.com/ros/ros_tutorials/issues</url> 
<url type="repository">https://github.com/ros/ros_tutorials</url> 

<author>Josh Faust</author> <!--编译工具为catkin--> 

<buildtool_depend>catkin</buildtool_depend> <!--用depend来整合build_depend和run_depend--> 

<depend>geometry_msgs</depend> 
<depend>rosconsole</depend> 
<depend>roscpp</depend> 
<depend>roscpp_serialization</depend> 
<depend>roslib</depend> 
<depend>rostime</depend> 
<depend>std_msgs</depend> 
<depend>std_srvs</depend>  

<build_depend>qtbase5-dev</build_depend> 
<build_depend>message_generation</build_depend> 
<build_depend>qt5-qmake</build_depend> 

<exec_depend>libqt5-core</exec_depend> 
<exec_depend>libqt5-gui</exec_depend> 
<exec_depend>message_runtime</exec_depend> 
</package>

pacakge.xml比CmakeLists.txt好理解。三个标签使用比较频繁,分别是<depend>、 <build_depend>和<exec_depend>

 
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐