ROS初级教程 cmake cmakelist.txt 的编写教程
有很多 的时候我们使用别人的程序包。然后添加东西的时候缺少什么东西,会使程序编译不过去,甚至无法运行,接下来介绍一下cmakelist.txt 的每一行的作用。为了以后添加和修改方便。
2.整体结构和订购
您的CMakeLists.txt文件必须遵循此格式,否则您的包将无法正确构建。 配置中的顺序计数。
所需CMake版本(cmake_minimum_required)
软件包名称(project())
查找构建所需的其他CMake / Catkin软件包(find_package())
启用Python模块支持(catkin_python_setup())
消息/服务/动作生成器(add_message_files(),add_service_files(),add_action_files())
调用消息/服务/动作生成(generate_messages())
指定package build info export(catkin_package())
要建立的库/可执行文件(add_library()/ add_executable()/ target_link_libraries())
测试建立(catkin_add_gtest())
安装规则(install())
3.CMake版本
每个catkin CMakeLists.txt文件必须以需要的CMake版本开始。 Catkin需要2.8.3或更高版本。
cmake_minimum_required(VERSION 2.8.)
4.软件包名称
下一个项目是由CMake项目功能指定的包的名称。 让我们说我们正在制作一个名为robot_brain的软件包。
project(robot_brain)
请注意,在CMake中,您可以随时在CMake脚本中随时使用变量$ {PROJECT_NAME}来引用项目名称。
5.查找相关的CMake包
我们需要使用CMake find_package函数指定需要找到哪些其他CMake包来构建我们的项目。 总是至少有一个依赖于catkin:
find_package(catkin REQUIRED)
如果您的项目依赖于其他湿式包装,它们将自动变成catkin的组件(以CMake为单位)。 而不是在这些软件包上使用find_package,如果您将它们指定为组件,它将使生活更轻松。 例如,如果您使用package nodelet。
find_package(catkin REQUIRED COMPONENTS nodelet)
注意:您应该只需要find_package组件来构建标志。 您不应添加运行时依赖关系。
find_package(catkin REQUIRED)
find_package(nodelet REQUIRED)
但是,你会看到这是一个不方便的事情。
5.1find_package()做什么?
如果CMake通过find_package找到一个包,则会导致创建几个提供有关找到的包的信息的CMake环境变量。 这些环境变量可以在CMake脚本中稍后使用。 环境变量描述了包导出的头文件的位置,源文件的位置,包所依赖的库以及这些库的路径。 名称总是符合<PACKAGE NAME> _ <PROPERTY>的惯例:
<NAME> _FOUND - 如果找到库,则设置为true,否则为false
<NAME> _INCLUDE_DIRS或<NAME> _INCLUDES - 包导出的包含路径
<NAME> _LIBRARIES或<NAME> _LIBS - 由包导出的库
<NAME> _DEFINITIONS - ?
5.2为什么Catkin包被指定为组件?
Catkin包不是catkin的真正组成部分。相反,CMake的组件功能被用于catkin的设计,从而为您节省打字时间。
对于catkin包,如果find_package它们作为catkin的组件,这是有利的,因为使用catkin_前缀创建了一组环境变量。例如,让我们说您在代码中使用package nodelet。查找包的推荐方法是:
find_package(catkin REQUIRED COMPONENTS nodelet)
这意味着由nodelet导出的include路径,库等也附加到catkin_变量。例如,catkin_INCLUDE_DIRS不仅包含catkin的include路径,还包含了nodelet,这将在以后派上用场。
我们可以自己选择find_package nodelet:
find_package(nodelet)
这意味着nodelet路径,库等不会被添加到catkin_变量中。
这将导致nodelet_INCLUDE_DIRS,nodelet_LIBRARIES等。也使用相同的变量创建
find_package(catkin REQUIRED COMPONENTS nodelet)
5.3促进
如果使用C ++和Boost,您需要在Boost上调用find_package(),并指定用作组件的Boost的哪些方面。 例如,如果你想使用Boost线程,你会说:
find_package(Boost REQUIRED COMPONENTS thread)
6.0catkin_package()
catkin_package()是一个catkin提供的CMake宏。这是为构建系统指定catkin特定信息所必需的,后者又用于生成pkg-config和CMake文件。
在使用add_library()或add_executable()声明任何目标之前,必须调用此函数。该函数有5个可选参数:
INCLUDE_DIRS - 包的导出包含路径(即cflags)
图书馆 - 从项目导出的图书馆
CATKIN_DEPENDS - 该项目依赖的其他catkin项目
DEPENDS - 该项目所依赖的非catkin CMake项目。为了更好的理解,请看这个解释。
CFG_EXTRAS - 其他配置选项
完整的宏文档可以在这里找到。
举个例子:
catkin_package(
INCLUDE_DIRS include
LIBRARIES ${PROJECT_NAME}
CATKIN_DEPENDS roscpp nodelet
DEPENDS eigen opencv)
这表示包文件夹中的文件夹“include”是导出标题的地方。 CMake环境变量$ {PROJECT_NAME}评估到之前传给project()函数的任何东西,在这种情况下它将是“robot_brain”。 “roscpp”+“nodelet”是需要存在来构建/运行此程序包的软件包,“eigen”+“opencv”是需要存在的用于构建/运行此程序包的系统依赖项。
7.0指定构建目标
构建目标可以有多种形式,但通常它们代表两种可能之一:
可执行目标 - 我们可以运行的程序
库目标 - 可在构建和/或运行时由可执行目标使用的库
7.1目标命名
非常重要的是注意,catkin中的构建目标的名称必须是唯一的,而不管它们被构建/安装到哪个文件夹。 这是CMake的要求。 但是,目标的唯一名称只能在CMake内部进行。 可以使用set_target_properties()函数将目标重命名为其他目标:
例:
set_target_properties(rviz_image_view
PROPERTIES OUTPUT_NAME image_view
PREFIX "")
这将在构建和安装输出中将目标rviz_image_view的名称更改为image_view。
7.2自定义输出目录
虽然可执行文件和库的默认输出目录通常设置为合理的值,但在某些情况下必须进行自定义。即 一个包含Python绑定的库必须放在不同的文件夹中才能在Python中导入:
例:
set_target_properties(python_module_library
PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_PYTHON_DESTINATION})
7.3包括路径和库路径
在指定目标之前,您需要指定可以为所述目标找到资源的位置,特别是头文件和库:
包括路径 - 在哪里可以找到代码(最常见于C / C ++)的头文件
库路径 - 哪些库位于该可执行目标建立对象?
include_directories(<dir1>,<dir2>,...,<dirN>)
link_directories(<dir1>,<dir2>,...,<dirN>)
7.3.1include_directories()
include_directories的参数应该是find_package调用和需要包含的任何其他目录生成的* _INCLUDE_DIRS变量。 如果您使用catkin和Boost,您的include_directories()调用应该如下所示:
include_directories(include ${Boost_INCLUDE_DIRS} ${catkin_INCLUDE_DIRS})
第一个参数“include”表示包中的include /目录也是路径的一部分。
7.3.2link_directories()
CMake link_directories()函数可用于添加额外的库路径,但是不推荐这样做。 所有catkin和CMake软件包在find_packaged时都会自动添加链接信息。 只需链接到target_link_libraries()中的库
例:
link_directories(~/my_libs)
请参阅这个cmake线程以查看关于在link_directories()上使用target_link_libraries()的详细示例。
7.4可执行目标
要指定必须构建的可执行目标,我们必须使用add_executable()CMake函数。
add_executable(myProgram src/main.cpp src/some_file.cpp src/another_file.cpp)
这将构建一个名为myProgram的目标可执行文件,它由3个源文件构建:src / main.cpp,src / some_file.cpp和src / another_file.cpp。
7.5 图书馆目标
add_library()CMake函数用于指定要构建的库。 默认情况下,catkin构建共享库。
add_library(${PROJECT_NAME} ${${PROJECT_NAME}_SRCS})
7.6target_link_libraries
使用target_link_libraries()函数来指定可执行目标链接的库。 这通常在add_executable()调用之后完成。 如果找不到ros,则添加$ {catkin_LIBRARIES}。
句法:
target_link_libraries(<executableTargetName>, <lib1>, <lib2>, ... <libN>)
例
add_executable(foo src/foo.cpp)
add_library(moo src/moo.cpp)
target_link_libraries(foo moo) -- This links foo against libmoo.so
请注意,在大多数用例中不需要使用link_directories(),因为信息通过find_package()自动拉入。
8.0消息,服务和行动目标
消息(.msg),服务(.srv)和动作(.action)文件在ROS包构建和使用之前需要一个特殊的预处理器构建步骤。 这些宏的要点是生成编程语言特定的文件,以便可以利用其选择的编程语言中的消息,服务和动作。 构建系统将使用所有可用的生成器(例如gencpp,genpy,genlisp等)生成绑定。
提供了三个宏来分别处理消息,服务和动作:
add_message_files
add_service_files
add_action_files
这些宏之后必须跟随调用生成的宏:
generate_messages()
8.1重要先决条件/限制
这些宏必须在catkin_package()宏之前,以便生成才能正常工作。
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的组件:
find_package(catkin REQUIRED COMPONENTS message_generation)
您的package.xml文件必须包含对message_generation的构建依赖关系以及message_runtime上的运行时依赖关系。 如果依赖关系从其他软件包中过渡拉出来,则不需要这样做。
如果您有一个目标(即使是过渡性的)依赖于需要构建消息/服务/操作的其他一些目标,则需要向目标catkin_EXPORTED_TARGETS添加明确的依赖关系,以便它们以正确的顺序构建。 这种情况几乎总是适用,除非您的包真的不使用ROS的任何部分。 不幸的是,这种依赖关系不能自动传播。 (some_target是由add_executable()设置的目标的名称):
add_dependencies(some_target ${catkin_EXPORTED_TARGETS})
如果您有一个构建消息和/或服务的包以及使用这些消息和/或服务的可执行文件,则需要为自动生成的消息目标创建明确的依赖关系,以便以正确的顺序构建它们。 (some_target是由add_executable()设置的目标的名称):
add_dependencies(some_target ${${PROJECT_NAME}_EXPORTED_TARGETS})
如果您的包装满足上述两个条件,则需要添加以下两个依赖关系,即:
add_dependencies(some_target ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
8.2 例子
如果您的包在名为“MyMessage1.msg”和“MyMessage2.msg”的名为“msg”的目录中有两条消息,这些消息依赖于std_msgs和sensor_msgs,名为“srv”的名为“MyService.srv”的目录中的服务, 定义使用这些消息和服务的可执行的message_program,并且使用ROS的某些部分的可执行的do_not_use_local_messages_program,而不是此包中定义的消息/服务,那么在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})
另外,如果要构建actionlib操作,并且在“action”目录中有一个名为“MyAction.action”的操作规范文件,则必须将actionlib_msgs添加到使用catkin进行find_package的组件列表中,然后添加以下调用 对generate_messages(...)的调用:
add_action_files(FILES
MyAction.action
)
此外,该包必须具有对actionlib_msgs的构建依赖。
9.0启用Python模块支持
如果您的ROS包提供了一些Python模块,您应该创建一个setup.py文件并调用
catkin_python_setup()
之前调用generate_messages()和catkin_package()。
10.0 单位测试
有一个catkin-specific宏用于处理名为catkin_add_gtest()的基于gtest的单元测试。
catkin_add_gtest(myUnitTest test / utest.cpp)
11.0可选步骤:指定可安装的目标
构建时间之后,目标被放置在catkin工作区的开发空间中。但是,通常我们希望将目标安装到系统中(有关安装路径的信息可以在REP 122中找到),以便其他人或本地文件夹可以使用它们来测试系统级安装。换句话说,如果你想要做一个“make install”的代码,你需要指定目标应该在哪里。
这是使用CMake install()函数作为参数完成的:
目标 - 目标是安装
ARCHIVE DESTINATION - 静态库和DLL(Windows).lib存根
LIBRARY DESTINATION - 非DLL共享库和模块
RUNTIME DESTINATION - 可执行目标和DLL(Windows)样式共享库
举一个例子:
install(TARGETS ${PROJECT_NAME}
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
除了这些标准目标,一些文件必须安装到特殊文件夹。即一个包含Python绑定的库必须安装到不同的文件夹中才能在Python中导入:
install(TARGETS python_module_library
ARCHIVE DESTINATION ${CATKIN_PACKAGE_PYTHON_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_PYTHON_DESTINATION}
)
11.1安装Python可执行脚本
对于Python代码,安装规则看起来是不同的,因为没有使用add_library()和add_executable()函数,以便CMake确定哪些文件是目标以及它们是什么类型的目标。 而是在您的CMakeLists.txt文件中使用以下内容:
catkin_install_python(PROGRAMS scripts/myscript
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
有关安装python脚本和模块的详细信息以及文件夹布局的最佳做法,请参见catkin手册。
如果您只安装Python脚本并且不提供任何模块,则不需要创建上述setup.py文件,也不需要调用catkin_python_setup()。
11.2安装头文件
标题文件也必须安装到“include”文件夹中,这通常是通过安装整个文件夹的文件来完成的(可选地,按文件名模式过滤,不包括SVN子文件夹)。 这可以通过如下所示的安装规则完成:
install(DIRECTORY include/${PROJECT_NAME}/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
PATTERN ".svn" EXCLUDE
)
或者如果包含的子文件夹与包名称不匹配:
install(DIRECTORY include/
DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION}
PATTERN ".svn" EXCLUDE
)
11.3安装roslaunch文件或其他资源
其他资源(如启动文件)可以安装到$ {CATKIN_PACKAGE_SHARE_DESTINATION
install(DIRECTORY launch/
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch
PATTERN ".svn" EXCLUDE)
ROS初级教程 cmake cmakelist.txt 的编写教程的更多相关文章
- ROS知识(8)----CMakeLists.txt文件编写的理解
ROS(Indigo)编程必须要理解CMakeList.txt的编写规则,教程地址:catkin/CMakeLists.txt,官网有相关的教程,中文的翻译版本写的很不错,教程地址:ROS中的CMak ...
- CMake 使用方法 & CMakeList.txt<转>
CMake 使用方法 & CMakeList.txt cmake 简介 CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程).他能够输出各种各样的make ...
- rhel7 编写CMakeList.txt编译运行MySQL官方例子代码
注:若需要参考rhel7上安装MySQL 请 点击此处 1.下面MySQL链接库版本用到了boost(若需要请到官网下载最新链接库和文档和C++连接数据库操作示例) Red Hat Enterpris ...
- 单个源文件下CmakeList.txt
单个源文件下CmakeList.txt 1. main.c代码 & CmakeLists.txt 文件内容 在任意自己选定的目录下(t1/)编写main.c 与 CmakeLists.txt ...
- make Makefile 与 cmake CMakeLists.txt
make Makefile 与 cmake CMakeLists.txt 大家都知道,写程序大体步骤为: 1.用编辑器编写源代码,如.c文件. 2.用编译器编译代码生成目标文件,如.o. 3.用链接器 ...
- 一个很不错的bash脚本编写教程
转自 http://blog.chinaunix.net/uid-20328094-id-95121.html 一个很不错的bash脚本编写教程,至少没接触过BASH的也能看懂! 建立一个脚本 Lin ...
- CMakeList.txt设置OpenCv路径
源文件imageBasics.cpp #include <iostream> #include <chrono> using namespace std; #include & ...
- BAT脚本编写教程(比较易懂和全面)
这篇文章主要介绍了BAT脚本编写教程,比较易懂和全面.适合有一定编程基础的人 作者不详.敬意! echo.@.call.pause.rem(小技巧:用::代替rem)是批处理文件最常用的几个命令, ...
- BAT脚本编写教程简单入门篇
BAT脚本编写教程简单入门篇 批处理文件最常用的几个命令: echo表示显示此命令后的字符 echo on 表示在此语句后所有运行的命令都显示命令行本身 echo off 表示在此语句后所有运行的命 ...
随机推荐
- C++ 的那些坑 (Day 1)
永远的溢出 运算溢出 溢出是一个永恒的话题. int a = 0xf000; int b = 0xff000; long c = a * b; 此时c = -251658240,以为已经使用了long ...
- 微信小程序 引入公共页面的几种情况
1.不带参数 首先在pages文件夹中新建一个template文件夹,文件夹中新建一个template.wxml文件,代码如下 <!--template.wxml--> <templ ...
- 【代码笔记】iOS-MBProgressHUD
一,工程图. 二,代码. AppDelegate.h #import <UIKit/UIKit.h> #import "MBProgressHUD.h" @interf ...
- drupal7 覆写node-type.tpl.php获取字段值的两种方式
字段的机读名称为:field_publication_date <!-- 下面两种方式都可以获取node字段的值--> 出版时间: <?php print date('Y-m-d', ...
- CSS实现英文或拼音单词首字母大写
CSS实现英文或拼音单词首字母大写,只需要在css样式中加入: text-transform: capitalize 即可. 测试代码如下: <!doctype html> <htm ...
- Windows应用程序进程级别统一监控实践
一般的系统级别指标监控,更多关注CPU.内存.磁盘.网络等运行情况,对应用程序运行时的进程指标关注不够,导致不能深入了解系统运行状态.本文根据笔者应用实践,探讨一下进程级别监控涉及到的监控内容以及监控 ...
- [Android] TableLayout
public class TableLayout extends LinearLayout 查过文档,整理下要点: 一个 TableLayout 包含一些 TableRow 对象,每个对象代表一行.除 ...
- LeetCode题解之Convert Sorted List to Binary Search Tree
1.题目描述 2.题目描述 使用快慢指针寻找链表中间值. 3.代码 TreeNode* sortedListToBST(ListNode* head) { if (head == NULL) retu ...
- M5加密字符串
private string GetMD5str(string oldStr) { //将输入转换为ASCII 字符编码 ASCIIEncoding enc = new ASCIIEncoding() ...
- 如何从 Windows 虚拟机分离数据磁盘
当不再需要附加到虚拟机的数据磁盘时,可以轻松地分离它. 这会从虚拟机中删除该磁盘,但不会从存储中删除它. Warning 如果用户分离磁盘,它不会自动删除. 如果订阅了高级存储,则将继续承担该磁盘的存 ...