ROS:catkin/CMakeLists.txt
ROS:catkin/CMakeLists.txt
1. 简介
文件CMakeLists.txt是CMake build系统用来构建软件包的输入。任意的CMake-compliant包包含一个或多个CMakeLists.txt文件描述代码该如何构建以及在哪里安装。
2. 完整的结构和顺序
CMakeLists.txt文件必须遵循以下格式,不然安装包不会被正确的搭建:
- Required CMake Version (cmake_minimum_required)
- Package Name (project())
- Find other CMake/Catkin packages needed for build (find_package())
- Enable Python module support (catkin_python_setup())
- Message/Service/Action Generators (add_message_files(), add_service_files(), add_action_files())
- Invoke message/service/action generation (generate_messages())
- Specify package build info export (catkin_package())
- Libraries/Executables to build (add_library()/add_executable()/target_link_libraries())
- Tests to build (catkin_add_gtest())
- 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个坑
下一篇: CTabCtrl控件从零开始自绘