当前位置:网站首页>(ROS) (03) CMakeLists. TXT, rounding

(ROS) (03) CMakeLists. TXT, rounding

2022-08-02 14:18:00 CynalFly

  文章只是个人学习过程中学习笔记,主要参考ROS教程1.


1、概述

  CMakeLists.txtis used to compile packagesCMakeThe input file for the build system,Editing can be done in almost any text editor.This file describes how to compile the code and where to install it.用于catkin项目的CMakeLists.txtThe file is a standard with some additional constraintsvanillaCMakeLists.txt文件.

  catkin是ROSOfficial custom build system,Its principle and process andCMake很相似,和老版本rosbuild相比,Support better portability(catkinCombined with good portabilityCMake和python)以及交叉编译.(在ROS2使用的编译工具是ament,它是由catkinOptimized iterative version)

  CMake语言由 注释(comments)命令(commands)变量(variables)组成.
  CMake相关文档:https://cmake.org/documentation/

2、CMakeLists.txt文件

2.1 The format and sequence to follow

  CMakeLists.txtThe file must follow the format below,Otherwise the package will not build correctly.The order in the configuration does matter.CMakeLists.txtThe basic syntax remains the sameCMake,而catkinAdded a few macros to it(见new).

顺序语法功能备注
1cmake_minimum_required所需的 CMake 版本
2project() 包名
3find_package()Find what else is needed for compilation CMake/Catkin 包
4catkin_python_setup() 启用 Python 模块支持new
5add_message_files()添加在msg文件夹中自定义的*.msg消息文件new
add_service_files()添加在srv文件夹中自定义的*.srv服务文件new
add_action_files()添加在avtion文件夹中自定义的*.action动作文件new
6generate_messages() 调用消息/服务/动作Generate language-specific interface filesnew
7catkin_package()Specifies export of package build informationnew
8add_library() 生成库文件
add_dependencies()Define object files that depend on other files,确保其他目标已被构建
add_executable()生成可执行的二进制文件
target_link_libraries()指定可执行目标链接的库
9catkin_add_gtest()The test to compilenew
10 install()安装规则

2.2 文件解析

# 1 -- 项目所需要的CMake版本,向后兼容 
cmake_minimum_required(VERSION 3.0.2)

# 2 -- 使用CMake project(package-name)Declare the package name 
# 可以通过使用变量 ${PROJECT_NAME} 在CMakeThe project name is referenced anywhere after the script.
project(beginner_tutorials)

# 3 -- CMake宏,Find what else is needed for compilation CMake/Catkin 包(Please see the detailed analysis below2.3小节)
# [REQUIRED]:when the conditions are not metpackage时(For example, the specified component was not found, etc),
# 会终止CMake执行过程,并输出一条错误信息,反之,CMake会继续执行.
# [COMPONENTS]:The component to look for(components),通常一个pakcage可能包含多个组件.
# roscpp、rospy...就是catkin的组件. 
# If any of them are not found, it will fail,会终止CMake执行过程. 
# Make sure all these dependenciespackage也在package.xml中,使用<depend>或<build_denpend>标记.
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
)

## 查找 PythonLibs 库
# find_package(PythonLibs REQUIRED)

## 查找C++ BoostThe library's component librarysystem、thread
# find_package(Boost REQUIRED COMPONENTS system thread)

## 4 -- 启用 Python 模块支持 
## 如果这个package有setup.py,则取消对此的注释.
## This macro ensures that modules and global scripts declared in it are installed 
# catkin_python_setup()

################################################
## Declare ROS messages, services and actions ##
## 声明 ROS 消息、服务和动作 ## 
################################################

## 5 -- 添加在`msg`文件夹中自定义的`*.msg`文件
## 将Message*.msg替换成你的.msg文件,
# add_message_files(
# FILES
# Message1.msg
# Message2.msg
# )

## 5 -- 添加在`srv`文件夹中自定义的`*.srv`文件
## 将Service*.msg替换成你的.srv文件
# add_service_files(
# FILES
# Service1.srv
# Service2.srv
# )

## 5 -- 添加在`action`文件夹中自定义的`*.action`文件
## 将Action*.action替换成你的.action文件
# add_action_files(
# FILES
# Action1.action
# Action2.action
# )

## 6 -- 调用`消息`/`服务`/`动作`Generate language-specific interface files
## 用于生成所有定义的message、service、action文件,需要添加本文件需要依赖的packages.
## 其实就是告诉编译器,编译 *.msg *.srv *.action 等文件时,需要依赖的库或package.
## Generate added messages and services with any dependencies listed here
# generate_messages(
# DEPENDENCIES
# std_msgs # Or other packages containing msgs
# )

################################################
## Declare ROS dynamic reconfigure parameters ##
################################################
## To declare and build dynamic reconfigure parameters within this
## package, follow these steps:
## * In the file package.xml:
## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
## * In this file (CMakeLists.txt):
## * add "dynamic_reconfigure" to
## find_package(catkin REQUIRED COMPONENTS ...)
## * uncomment the "generate_dynamic_reconfigure_options" section below
## and list every .cfg file to be processed

## Generate dynamic reconfigure parameters in the 'cfg' folder
# generate_dynamic_reconfigure_options(
# cfg/DynReconf1.cfg
# cfg/DynReconf2.cfg
# )

###################################
## catkin specific configuration ##
###################################
## 7 -- catkin_package() (Please see the detailed analysis below2.3小节)
## 由catkin_packageThe resulting files will eventually be installed into devel和build文件夹下.
## INCLUDE_DIRS: 如果package包含头文件,then uncomment this line
## LIBRARIES: Libraries exported by the project
## CATKIN_DEPENDS: The rest of the project's dependenciescatkin项目
## DEPENDS: The rest of the project's dependencies are notcatkin项目
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES beginner_tutorials
# CATKIN_DEPENDS roscpp rospy std_msg
# DEPENDS system_lib
)

###########
## Build ##
###########
## 
## 第一个参数“include”表示包中的include/目录也是路径的一部分.
## catkin_INCLUDE_DIRS:Represents an established environment variable
include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)

## 8 -- add_library() 生成库文件${PROJECT_NAME}
# add_library(${PROJECT_NAME}
# src/${PROJECT_NAME}/beginner_tutorials.cpp
# )

## 8 -- 定义target依赖的其他target
## add_dependencies(target-name depend-target1 depend-target2 ...)
# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

## 8 -- 生成可执行的二进制文件 
## add_executable(<生成> <源文件>)
## 使用${PROJECT_NAME}引用变量,生成一个名为beginner_tutorials_node的可执行文件.
# add_executable(${PROJECT_NAME}_node src/beginner_tutorials_node.cpp)

## Rename C++ executable without prefix
## The above recommended prefix causes long target names, the following renames the
## target back to the shorter version for ease of user use
## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")

## Add cmake target dependencies of the executable
## same as for the library above
# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) 

## 8 -- 指定可执行目标链接的库
# target_link_libraries(${PROJECT_NAME}_node
# ${catkin_LIBRARIES}
# )

#############
## Install ##
#############

## 安装python可执行脚本
# catkin_install_python(PROGRAMS
# scripts/my_python_script
# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )

## 9 -- 安装规则 -- 目标文件的安装
## DESTINATION:定义了安装的路径
## 可执行二进制文件beginner_tutorials_node 安装到 ${CATKIN_PACKAGE_BIN_DESTINATION}目录
# install(TARGETS ${PROJECT_NAME}_node
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )

## ARCHIVE:静态库
## LIBRARY:动态库
## RUNTIME:Executable target binary
# install(TARGETS ${PROJECT_NAME}
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
# )

## 9 -- 安装规则 -- 目录的安装
## 如果目录以“/”结尾,Indicates to install the contents of the directory to the target path
## If the directory does not end with “/”结尾,Indicates to install the directory as a directory under the target path
## PATTERN:用于使用正则表达式进行过滤
# install(DIRECTORY include/${PROJECT_NAME}/
# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
# FILES_MATCHING PATTERN "*.h"
# PATTERN ".svn" EXCLUDE 
# )

## 9 -- 安装规则 -- 普通文件的安装
# install(FILES
# # myfile1
# # myfile2
# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
# )

#############
## Testing ##
#############

## 添加基于gtest的cpp测试目标和链接库
# catkin_add_gtest(${PROJECT_NAME}-test test/test_beginner_tutorials.cpp)
# if(TARGET ${PROJECT_NAME}-test)
# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
# endif()

## Add folders to be run by python nosetests
# catkin_add_nosetests(test)

2.3 find_package()

  如果 CMake 通过find_package()2 找到一个package,will create several CMake 环境变量,These variables provide information about the findpackage的信息.这些环境变量可以稍后在 CMake 脚本中使用.Environment variables are describedpackageWhere are the exported header files、源文件在哪里、包依赖的库以及这些库的路径.名称始终遵循 <PACKAGE NAME>_<PROPERTY> 的约定:

  • <NAME>_FOUND -:如果找到库,则设置为 true,否则设置为 false
  • <NAME>_INCLUDE_DIRS<NAME>_INCLUDESpackage导出的include路径
  • <NAME>_LIBRARIES<NAME>_LIBSpackage导出的库
  • <NAME>_DEFINITIONS:?

  Find what else is needed for compilation CMake/Catkin 包:

find_package(<package-name> REQUIRED COMPONENTS component1commponent2 …)

  例如:New package dependenciesroscpp、rospy、std_msgs

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
)

  for this new onecatkin软件包,Others that will depend on itcatkin packages(roscpp、rospy、std_msgs)指定为catin的组件,这是最推荐的方法,Doing so will make theminclude路径libraries路径wait for attachmentcatkin_variables中.例如,catkin_INCLUDE_DIRS 不仅包含了catkin package自己的include路径,Also contains components(例如上面的roscpp、rospy、std_msgs)的include路径,It will be very convenient in subsequent use!

include_directories(${catkin_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME}_node ${catkin_LIBRARIES})

既然有这么多好处,为什么不能把find_package(PythonLibs REQUIRED)整合到一起呢?
这是因为find_package()Look up only one at a timepackage,catkin是指ROS工程中使用catkin工具编译的packages,And wherever there iscatkinCompiled packages are available as catkin的组件,也可以作为单独的package,但PythonLibs 不行,因为它不是ros系统的package,属于第三方package.

2.4 catkin_package()

  catkin_package()2 is to depend on thispackage的package使用的.可以向其他package导出依赖,These dependencies may include header files、库,或者本package依赖的其他package.
  必须在使用add_library()或add_executable()Call this function before declaring any targets.该函数有 5 个可选参数:

  • INCLUDE_DIRS - The include path of the exported package(即 cflags)
  • LIBRARIES - Libraries exported from the project
  • CATKIN_DEPENDS - Others that this project depends oncatkin项目
  • DEPENDS - This project depends on not catkin CMake 项目
  • CFG_EXTRAS - Additional configuration options

catkin_package()是在/opt/ros/melodic/share/catkin/cmake/catkin_package.cmake文件定义的.调用 catkin_package()之后,会在/devel/share/<package-name>/cmake目录下生成CMake config模式的查找文件:<package-name>Config.cmake<package-name>Config-version.cmake.这样,其他软件包package使用`find_package(…)The configuration file will be loaded,thereby getting the dependencies.
在这里插入图片描述

   Then we are looking at oneROS Answers上的问答:What is the purpose of CATKIN_DEPENDS?.
https://answers.ros.org/question/58498/what-is-the-purpose-of-catkin_depends/

   DEPENDSCATKIN_DEPENDSis to tellcatkinPass your package's dependencies to usefind_package(…)Find your packagepackage的软件包package.
  
   例如:假设你(调用)find_package(Boost REQUIRED),and in your installed header files(包含)#include <boost/function.hpp>.In order to make a dependent packagepackage(other software packagespackage)Build and link your header files,They need to be in theirsinclude路径中有 Boost 的include目录,And they need to be linked to Boost 的库.Since you already use it in your header file,Then they should be able to get that dependency from you.换言之,Precisely because they depend on your packagepackage构建的,So they don't need to find_package(Boost REQUIRED)了,and not otherwise usedBoost.
  
  your packagepackage依赖于Boost这一事实是一个实现细节.So when some(软件包package)通过find_package(...)Find your packagepackage时,They can obtain pairs indirectlyBoost的依赖.The way it works is incatkin_package(…)put in the callDEPENDS Boost.在内部,catkin将通过find_package(Boost)获取路径,并且向 ${your_pkg_LIBRARIES} 添加${Boost_LIBRARIES},向${your_pkg_INCLUDE_DIRS}添加${Boost_INCLUDE_DIRS} .
  
  我应该注意,catkin Will get exactly what you give it and try 通过find_package(...) (查找)该软件包package,然后尝试使用该包的_LIBRARIES_INCLUDE_DIRS变量.这个关于find_package(…)The assumptions about the layout don't always hold,因为CMakeThere is no mandate to do so.
  例如:当find_package(…)ing Python时:
  find_package(PythonLibs REQUIRED)The result is a variable like PYTHON_INCLUDE_PATH,
  find_package(OpenGL REQUIRED) 结果为OPENGL_INCLUDE_DIR.
  Except for the case of variable prefixes,The actual prefix is ​​also different(PythonLibs -> PYTHON),And this suffix is ​​also non-standard(PYTHON_INCLUDE_PATH and OPENGL_INCLUDE_DIR vs *_INCLUDE_DIRS).
  在这种情况下,You will need to useINCLUDE_DIRS选项的include dirs变量和使用LIBRARIES The library of options is explicitly passed tocatkin_package(…).
  
  虽然CATKIN_DEPENDS选项和DEPENDS选项非常相似,但是你必须把catkin packagesJust put thislist中.对你的 catkin The benefit of categorizing is relying on a single option,catkinAbility to perform additional checks and warn you of potentially incorrect practices.
  
  最后,一个简单的例子CMakeLists.txt:

cmake_minimum_required(VERSION 2.8.3)
project(foo)

find_package(Boost REQUIRED
  COMPONENTS
  system
  thread
)

find_package(PythonLibs REQUIRED)
find_package(OpenGL REQUIRED)

find_package(catkin REQUIRED
  COMPONENTS
  rosconsole
  roscpp
)

include_directories(
  include
  ${
    catkin_INCLUDE_DIRS}
  ${
    OPENGL_INCLUDE_DIR}
  ${
    PYTHON_INCLUDE_PATH}
)

catkin_package(
  INCLUDE_DIRS include ${
    OPENGL_INCLUDE_DIR}
  LIBRARIES foo ${
    OPENGL_LIBRARIES}
  CATKIN_DEPENDS roscpp
  DEPENDS Boost
)

..

  在这个例子中,你可以看到我(调用了)find_package(Boost...),并在DEPENDS partially passed it,Because it produces compatibleCMake变量.虽然我(调用了)find_package(PythonLibs...)and used it internally,But since it's not in any header file I expose,All need not be passed together.虽然我(调用了) find_package(OpenGL...),But because it creates incompatibilityCMake变量,So I pass it explicitly to INCLUDE_DIRSLIBRARIES.最后,我(调用了)find_package(catkin...rosconsole roscpp),并在内部使用,But maybe I'm only on mine.c*文件使用了rosconsole,So I don't need to pass it,所以在CATKIN_DEPENDSI just put in the variableroscpp.
  
  最后一个例子,如果一个packageUse an image directlyBoost这样的依赖,They should make sure to passfind_package(...)Look for it explicitly,And they cannot pass otherpackageimplicitly depends on it.
  
  发生这种情况的一个例子是,If a packagepackagefoo将Boost作为依赖项导出,还有一个依赖于foo的软件包packagebar,但也在内部使用Boost,那么barwill show no dependenciesBoostIt also compiles normally.但是后来fooMight decide to refactor and remove it right Boost 的依赖.此刻bar将无法编译,因为它不再具有通过foo对 Boost 的隐式依赖.


  1. ROS.org. ROS教程[EB/OL]. 2020-12-22[2022-7-5].
    http://wiki.ros.org/cn/ROS/Tutorials.

  2. ROS.org. CMakeLists.txt[EB/OL]. 2019-07-25[2022-07-05].
    http://wiki.ros.org/catkin/CMakeLists.txt.

原网站

版权声明
本文为[CynalFly]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/214/202208021400564684.html