文件CMakeLists.txt是CMake构建系统的输入,用于构建软件包。 任何兼容CMake的软件包都包含一个或多个CMakeLists.txt文件,这些文件描述了如何构建代码以及将代码安装到何处。 用于柳絮项目的CMakeLists.txt文件是标准的香草CMakeLists.txt文件,带有一些其他约束。
您的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())
常用变量
-
预定义变量
PROJECT_SOURCE_DIR:工程的根目录
PROJECT_BINARY_DIR:运行 cmake 命令的目录,通常是 ${PROJECT_SOURCE_DIR}/build
PROJECT_NAME:返回通过 project 命令定义的项目名称
CMAKE_CURRENT_SOURCE_DIR:当前处理的 CMakeLists.txt 所在的路径
CMAKE_CURRENT_BINARY_DIR:target 编译目录
CMAKE_CURRENT_LIST_DIR:CMakeLists.txt 的完整路径
CMAKE_CURRENT_LIST_LINE:当前所在的行
CMAKE_MODULE_PATH:定义自己的 cmake 模块所在的路径,SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),然后可以用INCLUDE命令来调用自己的模块
EXECUTABLE_OUTPUT_PATH:重新定义目标二进制可执行文件的存放位置
LIBRARY_OUTPUT_PATH:重新定义目标链接库文件的存放位置 -
环境变量
使用环境变量
$ENV{Name}
写入环境变量
set(ENV{Name} value) # 这里没有“$”符号
3. 系统信息
CMAKE_MAJOR_VERSION:cmake 主版本号,比如 3.4.1 中的 3
CMAKE_MINOR_VERSION:cmake 次版本号,比如 3.4.1 中的 4
CMAKE_PATCH_VERSION:cmake 补丁等级,比如 3.4.1 中的 1
CMAKE_SYSTEM:系统名称,比如 Linux-2.6.22
CMAKE_SYSTEM_NAME:不包含版本的系统名,比如 Linux
CMAKE_SYSTEM_VERSION:系统版本,比如 2.6.22
CMAKE_SYSTEM_PROCESSOR:处理器名称,比如 i686
UNIX:在所有的类 UNIX 平台下该值为 TRUE,包括 OS X 和 cygwin
WIN32:在所有的 win32 平台下该值为 TRUE,包括 cygwin
细节
-
makefile是有条理的gcc编译命令文件.利用make工具来执行Makefile的编译指令.一般利用cmake和autotools来自动生成cmake.
-
cmake用来读取Cmakelists.txt文件语句,最终生成Makefile文件.
当定义的target依赖另外一个target,确保在源码编译本target之前其他target已经构建,使用
ADD_DEPENDENCIES
说白了要说明白先编译谁再编译谁
-
INSTALL用于定义安装规则,安装的内容包括,目标二进制,动态库,静态库,文件,目录,脚本等.
-
静态库:在链接其他目标时候使用;动态库:运行时候加载
这两种库都发生在链接阶段:
(1)静态库,库中目标文件的所有将被程序使用的函数的机械码,被copy到最终可执行文件中;移植方便,运行效率高但占用内存空间大.对程序更新不太好.
(2)动态库:在程序运行时才被载入.可执行文件只是包含了它所需要函数的引用表,而不是函数代码.只有当程序执行的时候,那些需要的代码才会被拷贝到内存中.因为是在程序运行的时候被载入的,所有解决了静态库对程序的更新,部署和发布带来的麻烦.进程之间资源共享.但是依赖性强.(牺牲时间换取空间效率)
- 链接内部库
生成共享库,给自己和给别人用都很方便.
LIBRARY_OUTPUT_PATH 设置库文件输出路径
- 添加外部链接库
链接库导入的是,头文件和库文件. 顺序先头文件导入再库文件链接
导入库文件的几点尝试:
(1)利用绝对路径导入
(2)利用install导入 CMAKE_INSTALL_PREFIX 设置安装路径,安装库的位置,再分别导入库的头文件和库文件
(3)利用find_package的方式导入;camke要手动配置,有模块模式和配置模式.指令按照优先级在指定路径查找Findxxx.cmake和xxxConfig.cmake.
cmake能找到其中一个就能成功使用库
<NAME>_FOND | if(<NAME>_FOND) | 找到库的标志 |
---|---|---|
<NAME>_INCLUDE_DIR or <NAME> _INCLUDES | find_path(<NAME>_INCLUDES) | 库的头文件路径 |
<NAME> _LIBRARY <NAME> _LIBS | find_library(<NAME>_LIBS) | 库文件路径 |
REQUIRED选项,如果没有找到包的配置文件,Cmake将停止编译并且产生错误
QUIET选项,如果没有找到包的配置文件,Cmake会产生一个warning
-
catkin_package() 放到里面说明供外部使用 catkin是工具,catkin包
-
外部使用特别简单,直接在.xml中<depend>lib </depend>
-
当我们使用CMake
find_package(...)
命令roscpp
作为参数时一样,我们不仅将获得的构建标志roscpp
,而且还将获得其依赖项的所有标志。这大大简化了将依赖项合并到我们的程序中的过程。pkg-config
但是与find_package(...)
命令不同,该命令查找CMake配置文件,该文件包含与Pkg-Config.pc
文件在语义上相同的信息。也与Pkg-Config不同,此CMake命令不是特定于平台的。 -
运行
find_package(roscpp)
,自动定义了几个CMake的变量,包括但不限于${roscpp_INCLUDE_DIRS}
,${roscpp_LIBRARY_DIRS}
和${roscpp_LIBRARIES}
。这些变量遵循许多CMake配置文件使用的标准命名约定。然后可以将这些变量传递到标准CMake命令中,如CMakeLists.txt
上面的 文件所示。此外,通过将可选
REQUIRED
参数添加到中find_package(...)
,如果未找到该软件包,CMake将报告人类可读的错误。CMake需要知道在哪里可以找到软件包。在一些地方可以进行CMake搜索,但是这些软件包对CMake的暴露方式是通过
$CMAKE_PREFIX_PATH
环境变量进行的。对于ROS库,您可以(再次)确保您已经获得/opt/ros/hydro/setup.bash
,或者可以显式设置路径
export CMAKE_PREFIX_PATH=/opt/ros/hydro:$CMAKE_PREFIX_PATH
- 开始使用Catkin的最简单方法是将教程项目声明为“ catkin程序包”。这是通过
catkin_package()
CMake函数完成的(在此处进行了记录。catkin
通过CMake的标准find_package()
机制找到软件包后,该函数才可用.
踩过的坑
launch文件中的<node>元素pkg的值就是cmakelists.txt中project()的值.而不是文件名.