欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ROS:catkin/CMakeLists.txt

程序员文章站 2022-03-10 22:08:38
...

1. 简介

文件CMakeLists.txt是CMake build系统用来构建软件包的输入。任意的CMake-compliant包包含一个或多个CMakeLists.txt文件描述代码该如何构建以及在哪里安装。

2. 完整的结构和顺序

CMakeLists.txt文件必须遵循以下格式,不然安装包不会被正确的搭建:

  1. Required CMake Version (cmake_minimum_required)
  2. Package Name (project())
  3. Find other CMake/Catkin packages needed for build (find_package())
  4. Enable Python module support (catkin_python_setup())
  5. Message/Service/Action Generators (add_message_files(), add_service_files(), add_action_files())
  6. Invoke message/service/action generation (generate_messages())
  7. Specify package build info export (catkin_package())
  8. Libraries/Executables to build (add_library()/add_executable()/target_link_libraries())
  9. Tests to build (catkin_add_gtest())
  10. Install rules (install())

2.1 CMake版本

每一个catkin CmakeLists.txt文件必须由所需的Cmake版本开头。Catkin需要2.8.3即以上的版本:

cmake_minimum_required(VERSION 2.8.3)

2.2 功能包名

第二项为功能包的名字,它由CMake的Project函数所指定。当我们制作一个叫做robot_brain的功能包时:

project(robot_brain)

注意在CMake中,通过使用变量${PROJECT_NAME},你可以在后面的CMake脚本中的任何需要的地方使用该项目名。

2.3 寻找依赖CMake功能包

之后,我们需要使用CMake find_package 函数来指定需要找到哪些其他的CMake功能包来构建我们的项目。在catkin中,总是至少有一项依赖项:

find_package(catkin REQUIRED)

如果您的项目依赖于其他的wet packages(基于catkin编写的package叫做wet package,基于rosbuild编写的package叫做dry package),则它们会自动转换为catkin的components(根据CMake)。如果您将它们指定为components,而不是在这些包上使用find_package,这将使工作变得更容易。例如,如果您使用功能包nodelet:

find_package(catkin REQUIRED COMPONENTS nodelet)

还需要包含:

find_package(catkin REQUIRED)
find_package(nodelet REQUIRED)

然而,你会发现这是一种不方便的做事方式。

2.3.1 find_package() 是做什么的

如果CMake通过find_package找到了一个功能包,它将会创建几个CMake环境变量,这些变量提供了关于所找到的功能包的信息。这些环境变量可以在稍后的CMake脚本中使用。环境变量描述了功能包导出的头文件的位置、源文件的位置、包依赖的库以及这些库的路径。名称始终遵循<PACKAGENAME>_<PROPETRY>的惯例:

  • <NAME>_FOUND - Set to true if the library is found, otherwise false
  • <NAME>_INCLUDE_DIRS or <NAME>_INCLUDES - The include paths exported by the package
  • <NAME>_LIBRARIES or <NAME>_LIBS - The libraries exported by the package
  • <NAME>_DEFINITIONS - ?

2.3.2 为什么Catkin功能包被指定为了Components

2.3.3 Boost

如果使用C++和Boost,你需要在Boost上调用find_package(),并指定使用Boost的哪些方面作为components。比如说,如果你想要使用Boost threads,你会说:

find_package(Boost REQUIRED COMPONENTS thread)

2.4 catkin_package()

catkin_package()是一个由catkin提供的CMake宏。这是为构建系统指定的catkin-specific信息所必需的,而构建的系统又用于生成pkg-config和CMake文件。

在使用add_library()或add_executable()声明任何目标之前,必须调用此函数。函数有五个可选参数;

  • INCLUDE_DIRS - 导出的包含功能包的路径(也就是cflags)
  • LIBRARIES - 从项目导出的库
  • CATKIN_DEPENDS - 这个项目依赖的其他catkin项目
  • DEPENDS - 这个项目依赖的非catkin CMake项目
  • CFG_EXTRAS - 额外的配置选项

举个栗子:

catkin_package(
   INCLUDE_DIRS include
   LIBRARIES ${PROJECT_NAME}
   CATKIN_DEPENDS roscpp nodelet
   DEPENDS eigen opencv)

这表明文件夹中的“include"文件夹是导出头文件的位置(应该不是src每个项目中创建的include,而是devel里面的)。CMake环境变量${PROJECT_NAME}评估的是之前传递给project()函数的内容。在本例中它是”robot_brain"。“roscpp”+"nodelet"是构建/运行这个包需要出现的包,“eigen”+"opencv"是构建/运行这个包需要出现的系统依赖项。

2.5 指定搭建目标

构建目标可以采取多种形式,但通常它们代表两种可能性之一:

  • Executable Target-我们可以运行的程序
  • Library Target-可被executable targets在构建和/或运行时使用的库

2.6 Messages, Services, 和Action Targets

ROS中的messages(.msg),services(.srv)和actions(.action)文件在被ROS包构建和使用之前需要一个特殊的预处理器构建步骤。这些宏的作用是生成特定于编程语言的文件,以便可以使用所选编程语言的messages,services和actions。构建系统将使用所有可用的生成器(例如gencpp、genpy、genlisp等)生成绑定。

有三个宏被提供来分别处理messages, services和actions:

  • add_message_files
  • add_service_files
  • add_action_files
    这些宏之后必须再接上上述宏的调用来调用generation:
 generate_messages()

2.6.1 重要的先决条件/约束

  • 这些宏必须出现在catkin_package()宏之前,以便generation能够正确工作。
 find_package(catkin REQUIRED COMPONENTS ...)
 add_message_files(...)
 add_service_files(...)
 add_action_files(...)
 generate_messages(...)
 catkin_package(...)
 ...
  • catkin_package()宏必须在message_runtime有一个CATKIN_DEPENDS依赖项。
catkin_package(
 ...
 CATKIN_DEPENDS message_runtime ...
 ...)
  • 对于功能包message_generation,必须使用find_package()。可以单独使用,或者作为catkin的一个component:
find_package(catkin REQUIRED COMPONENTS message_generation)
  • 在package.xml文件必须包含对message_generation的构建依赖项和对message_runtime的运行时依赖项。如果依赖项是从其他包中传递过来的,则没有必要。

2.6.2 实栗

如果你的功能包中有两个在目录“msg”的messages,被称作"MyMessage1.msg和"MyMessage2.msg",这些messages依赖std_msgs和sensor_msgs;有一个在目录“srv”的service,被称作"MyService.srv",可执行的does_not_use_local_messages_program使用ROS的某些部分,而不是在这个包中定义的消息/服务,那么您将需要在您的CMakeLists.txt中使用以下内容:

  # Get the information about this package's buildtime dependencies
  find_package(catkin REQUIRED
    COMPONENTS message_generation std_msgs sensor_msgs)

  # Declare the message files to be built
  add_message_files(FILES
    MyMessage1.msg
    MyMessage2.msg
  )

  # Declare the service files to be built
  add_service_files(FILES
    MyService.srv
  )

  # Actually generate the language-specific message and service files
  generate_messages(DEPENDENCIES std_msgs sensor_msgs)

  # Declare that this catkin package's runtime dependencies
  catkin_package(
   CATKIN_DEPENDS message_runtime std_msgs sensor_msgs
  )

  # define executable using MyMessage1 etc.
  add_executable(message_program src/main.cpp)
  add_dependencies(message_program ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

  # define executable not using any messages/services provided by this package
  add_executable(does_not_use_local_messages_program src/main.cpp)
  add_dependencies(does_not_use_local_messages_program ${catkin_EXPORTED_TARGETS})

施工中的第n个坑

ROS:catkin/CMakeLists.txt