有很多 的时候我们使用别人的程序包。然后添加东西的时候缺少什么东西,会使程序编译不过去,甚至无法运行,接下来介绍一下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 的编写教程的更多相关文章

  1. ROS知识(8)----CMakeLists.txt文件编写的理解

    ROS(Indigo)编程必须要理解CMakeList.txt的编写规则,教程地址:catkin/CMakeLists.txt,官网有相关的教程,中文的翻译版本写的很不错,教程地址:ROS中的CMak ...

  2. CMake 使用方法 & CMakeList.txt<转>

    CMake 使用方法 & CMakeList.txt cmake 简介 CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程).他能够输出各种各样的make ...

  3. rhel7 编写CMakeList.txt编译运行MySQL官方例子代码

    注:若需要参考rhel7上安装MySQL 请 点击此处 1.下面MySQL链接库版本用到了boost(若需要请到官网下载最新链接库和文档和C++连接数据库操作示例) Red Hat Enterpris ...

  4. 单个源文件下CmakeList.txt

    单个源文件下CmakeList.txt 1. main.c代码 & CmakeLists.txt 文件内容 在任意自己选定的目录下(t1/)编写main.c 与 CmakeLists.txt ...

  5. make Makefile 与 cmake CMakeLists.txt

    make Makefile 与 cmake CMakeLists.txt 大家都知道,写程序大体步骤为: 1.用编辑器编写源代码,如.c文件. 2.用编译器编译代码生成目标文件,如.o. 3.用链接器 ...

  6. 一个很不错的bash脚本编写教程

    转自 http://blog.chinaunix.net/uid-20328094-id-95121.html 一个很不错的bash脚本编写教程,至少没接触过BASH的也能看懂! 建立一个脚本 Lin ...

  7. CMakeList.txt设置OpenCv路径

    源文件imageBasics.cpp #include <iostream> #include <chrono> using namespace std; #include & ...

  8. BAT脚本编写教程(比较易懂和全面)

    这篇文章主要介绍了BAT脚本编写教程,比较易懂和全面.适合有一定编程基础的人   作者不详.敬意! echo.@.call.pause.rem(小技巧:用::代替rem)是批处理文件最常用的几个命令, ...

  9. BAT脚本编写教程简单入门篇

    BAT脚本编写教程简单入门篇 批处理文件最常用的几个命令: echo表示显示此命令后的字符 echo on  表示在此语句后所有运行的命令都显示命令行本身 echo off 表示在此语句后所有运行的命 ...

随机推荐

  1. 【代码笔记】iOS-增加右侧按钮

    一,工程图. 二,代码. ViewController.m - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup ...

  2. 前端js获取checkbox的值

    1. var old = $("#old").val(); if (old != null && old != 'undefined' && old ...

  3. <Android 应用 之路> 一个类似今日头条的APP

    简介 最近花了一两天的时间完成一个简易的新闻头条客户端的应用,引用到了SwipeRefreshLayout,CircleImageView,RxAndroid,Picasso,PhotoPicker等 ...

  4. iOS设计模式-原型模式

    | 导语 定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. 通过深复制(克隆.拷贝)一个指定类型的对象来创建更多同类型的对象.这个指定的对象可被称为“原型”对象,也就是通过复制原型 ...

  5. postman和接口自动化测试

    1.postman测试接口 (1)首先安装postman 下载地址:https://www.getpostman.com/apps 选择对应版本下载,然后安装即可 (2)使用postman发送请求 比 ...

  6. Fit项目分页组件的编写

    项目中涉及列表显示的地方都会用到分页控件,为了能更好地与当前网站的样式匹配,这次要自己实现一个. 所以选择了模板中提供的分页样式,基于模板改造以能够动态生成: 一 控件的行为规则 a) 可设置显示几个 ...

  7. 使用托管快照创建作为 Azure 托管磁盘存储的 VHD 的副本

    创建快照 创建 OS 或数据磁盘 VHD 的快照,以便将其用作备份或用于排查 VM 问题. 快照是 VHD 的完整只读副本. 使用 Azure 门户创建快照 登录到 Azure 门户. 首先在左上角单 ...

  8. Oracle EBS OPM update material txn

    --update_material_txn --created by jenrry DECLARE p_mmti_rec mtl_transactions_interface%ROWTYPE; p_m ...

  9. SQL Server中ORDER BY后面可以是表达式和子查询

    假如SQL Server数据库中现在有Book表如下 CREATE TABLE [dbo].[Book]( ,) NOT NULL, ) NULL, ) NULL, ) NULL, [CreateTi ...

  10. Jboss7.1 local EJB lookup problem

    We are trying to lookup for an Local EJB in JBoss7.1, but we get an ClassCast Exception. This local ...