目录
- 1 概述
- 2 整体结构和顺序
- 3 CMake版本
- 4 功能包名称(package name)
- 5 发现CMake Packages
- 5.1 find_package()做了什么
- 5.2 为何将catkin packages指定为Components
- 5.3 Boost
- 6 catkin_package()
- 7 指定编译目标
- 7.1 目标命名
- 7.2 指定输出目录
- 7.3 包含路径和库路径
- 7.4 执行文件 executable
- 7.5 库 library
- 7.6 target_link_libraries
- 8 Messages, Services, Actions
-
- 9 Python模块支持
- 10 单元测试
1 概述
CMakeLists.txt文件是CMake编译系统的输入,描述如何编译代码和安装。用于catkin项目的CMakeLists.txt在原始的CMakeLists.txt基础上添加了一点额外约束。
2 整体结构和顺序
CMakeLists.txt文件的格式和顺序十分重要,包括如下:
- CMake版本 (cmake_minimum_required())
- 功能包名称 (project())
- 发现编译需要的CMake/Catkin包 (find_package())
- Python模块支持 (catkin_python_setup())
- 添加Message/Service/Action (add_message_files(), add_service_files(), add_action_files())
- 生成Message/Service/Action (generate_messages())
- 功能包编译信息导出 (catkin_package())
- 库/可执行文件 (add_library() / add_executable() / target_link_libraries())
- 测试 (catkin_add_gtest())
- 安装 (install())
3 CMake版本
catkin需要2.8.3+
cmake_minimum_required(VERSION 2.8.3)
4 功能包名称(package name)
通过CMake project
指定,
project(robot_brain)
在CMake中,可以通过${PROJECT_NAME}
引用这个package name。
5 发现CMake Packages
使用find_package
函数,发现编译该项目所依赖的CMake packages。至少有一个catkin依赖:
find_package(catkin REQUIRED)
如果该项目还依赖其他packages, 这些package会自动转变为catkin的components。如果直接指定这些packages作为components,而不是用find_package,会更为简单。比如,使用nodelet
find_package(catkin REQUIRED COMPONENTS nodelet)
注意:此处components只添加build dependencies, 而没有 runtime dependencies
也可以这样做,但是比较麻烦:
find_package(catkin REQURIED)
find_package(nodelet REQUIRED)
5.1 find_package()做了什么
当用find_package找到了一个package,会生成一些反映package信息的CMake环境变量,这些环境变量会在之后用到。这些环境变量描述了这些package的头文件、源文件位置,依赖库及其路径等。环境变量命名规则<PACKAGE_NAME>_<PROPERTY>
- _FOUND : 发现library,则为true
- _INCLUDE_DIRS or _INCLUDES : 包含目录
- _LIBRARY_DIRS or _LIBRARIES: 库目录
- _DEFINITIONS
5.2 为何将catkin packages指定为Components
Catkin package不是真正的Catkin components。而CMake的components特性被用于catkin的设计,从而节省了大量的打字时间。当find_package将catkin packages作为catkin的components时,会得到一个以catkin_为前缀的环境变量集合。比如,
find_package(catkin REQUIRED COMPONENTS nodelet)
nodelets导出的include paths, libraries等都会被添加到catkin_变量。catkin_INCLUDE_DIRS则不仅包含catkin的包含目录,还包含nodelet的包含目录。这在之后的使用中会非常方便。而直接find_package(nodelet) 会生成nodelet_INCLUDE_DIRS,nodelet_LIBRARIES等。
5.3 Boost
如果使用C++ / Boost, 需要调用find_package, 并指定使用Boost的哪些部分。比如,使用 Boost threads
find_package(Boost REQUIRED COMPONENTS thread)
6 catkin_package()
catkin_package是catkin提供的CMake macro,用来向编译系统指定catkin-specific的信息,编译系统会生成pkg-config和CMake文件。catkin_package需要在add_executable和add_library之前。该函数有五个optional arguments:
- INCLUDE_DIRS : the exported include paths (i.e. cflags) for the package
- LIBRARIES : The exported libraries from the project
- CATKIN_DEPENDS : Other catkin projects that this project depends on
- DEPENDS : Non-catkin CMake projects that this project depends on
- CFG_EXTRAS : Additional configuration options
An example:
catkin_package(
INCLUDE_DIRS include
LIBRARIES ${PROJECT_NAME}
CATKIN_DEPENDS roscpp nodelet
DEPENDS eigen opencv
)
7 指定编译目标
包含executable target和library target。
7.1 目标命名
编译目标的名称需要是唯一的。重命名:
set_target_properties(rviz_image_view
PROPERTIES OUTPUT_NAME image_view
PREFIX "")
7.2 指定输出目录
set_target_properties(python_module_library
PROPERTIES LIBRARY_OUTPUT_DIRECTORY &{CATKIN_DEVEL_PREFIX}/{CATKIN_PACKAGE_PYTHON_DESTINATION})
7.3 包含路径和库路径
include_directories(include ${Boost_INCLUDE_DIRS} ${catkin_INCLUDE_DIRS})
link_directory(~/my_lib) # 不常用
7.4 执行文件 executable
add_executable(myProgram src/main.cpp)
7.5 库 library
add_library(${PROJECT_NAME} ${${PROJECT_NAME}_SRCS})
7.6 target_link_libraries
target_link_libraries(<executableTargetName> , <lib1>, <lib2>)
example:
add_executable(foo src/foo.cpp)
add_library(moo src/moo.cpp)
target_link_libraries(foo moo) -- This links foo against libmoo.so
8 Messages, Services, Actions
在被ROS包编译使用前,message(.msg), service(.srv),actions(.action)需要一个预处理编译步骤,生成不同编程语言对应的文件。
# 添加
add_message_files
add_service_files()
add_action_files()
# 生成
generate_messages()
- 这些macros需要在catkin_package()之前。
- 在catkin_package()中添加CATKIN_DEPENDS依赖message_runtime
catkin_package(
...
CATKIN_DEPENDS message_runtime ...
...)
8.1 约束
- 在find_package()中添加message_generation
- package.xml中添加build dependency (message_generation),runtime dependency (message_runtime)
- 如果该package依赖的package需要编译messages/services/actions,则需要添加一个显式的依赖catkin_EXPORTED_TARGETS
add_dependencies(some_target ${catkin_EXPORTED_TARGETS})
- 如果某个package编译了message和executable,且executable需要使用message,需要添加以下依赖:
add_dependencies(some_target ${${PROJECT_NAME}_EXPORTED_TARGETS})
如果package满足以上两个条件,则
添加以上两个依赖
add_dependencies(some_target ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
8.2 例子
在/msg文件夹下有“MyMessage1.msg”和“MyMessage2.msg”,依赖std_msgs和sensor_msgs。/srv中包含“MyService.srv”。message_program使用这些message,does_not_use_local_message_program使用ROS一部分,但是不使用package中的message/service。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})
9 Python模块支持
catkin_python_setup()
10 单元测试
Unit Test: catkin_add_gtest()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)