CMakeList.txt的基本语法规则
CmakeLists.txt书写规范


catkin_make如何编译整个工作空间的软件包呢?

  • CmakeLists.txt,大家应该比较熟悉了,就是我们借助Cmake自动帮我们按照规则生成的makefile文件,来完成工程的编译、链接工作.
  • catkin_make是将cmake与make的编译方式做了一个封装的指令工具, 规范了工作路径与生成文件路径,而且在新建个工作空间时就帮我们创建了一个顶层的CMakeLists.txt文件,它会递归的寻找到当前工作空间下的所有软件包内的CMakeLists.txt依次来编译每一个软件包。(src的每个包里都有CmakeLists.txt的)
  • 这就是为什么catkin_make命令在 ror_ws的工作空间目录下,src目录之上执行

ROS下的CmakeList基本与之前的CmakeList.txt一致,仅仅添加了一些ROS相关的内容

#最顶端
cmake_minimum_required(VERSION 2.8.3)
project(gscam)  //表示当前软件包的名称

如何查找链接库

  • find_package(PkgConfig)
  • pkg_check_modules

他们的语法规则

find_package( <name>[version] [EXACT] [QUIET] [NO_MODULE] [ [ REQUIRED | COMPONENTS ] [ componets… ] ] )

name 和version是库的名称和版本
后面的参数
EXACT  要求版本号必须精确匹配
QUIET  没有找到也不会有警告信息,会禁掉包没有被发现时的警告信息
REQUIRED 如果报没有找到的话,cmake的过程会终止,并输出警告信息(说明这个module是工程必须有的)
COMPONENTS  COMPONENTS选项之后,可以列出一些与包相关(依赖)的部件清单(components list)

例如
find_package(PkgConfig)  #查找PkgConfig所指向库文件和头文件

find_package(catkin REQUIRED
COMPONENTS roscpp image_transport sensor_msgs nodelet
camera_calibration_parsers camera_info_manager
)

pkg_check_modules(<PREFIX>[QUIET] [REQUIRED] <MODULE> )

检测所有给出的modules

PREFIX 自定义的前缀,查找到之后,可以用这个前缀来代表相应的module
QUIET/ REQUIRED 和前面的类似

QUIET/ REQUIRED的区别,
如果没找到,一个不会报错,接着继续进行,一个会警告,并终止Cmake
如果找的话,无论是哪一种模式,都可以使用下面这些变量

<NAME>_FOUND
<NAME>_INCLUDE_DIRS or <NAME>_INCLUDES   //头文件
<NAME>_LIBRARIES or <NAME>_LIBRARIES or <NAME>_LIBS //库文件
<NAME>_DEFINITIONS

看一个比较典型的例子
实现的功能就是在ROS工程中,使用gstreamer库
首先考虑gstreamer-1.0,其次考虑gstreamer-0.10,如果都没有,Cmake就进行不下去,
无论有哪一个下面的
后面的
catkin_package 可以DEPENDS GSTREAMER GST_APP
include_directories 可以包含 ${GST_APP_INCLUDE_DIRS}
add_library   可以包含 ${GSTREAMER_LIBRARIES}  ${GST_APP_LIBRARIES}

# System Dependencies
find_package(PkgConfig)  #查找PkgConfig所指向库文件和头文件
#通过PkgConfig的环境变量下配置的 ××.pc  管理了很多软件的库文件和头文件

pkg_check_modules(GSTREAMER QUIET gstreamer-0.10)
# 查找gstreamer-0.10模组 ,并且自定义前缀GSTREAMER

if(NOT GSTREAMER_FOUND)  
#如果找的了,当然可以使用GSTREAMER_FOUND,甚至后面的_INCLUDE_DIRS, 没找到当然就是 NOT GSTREAMER_FOUND 
  set(GSTREAMER_VERSION_1_x TRUE)  #设置一个变量GSTREAMER_VERSION_1_x = 1
endif()


if(GSTREAMER_VERSION_1_x)  #GSTREAMER_VERSION_1_x为真,说明没有gstreamer-0.10
  message(STATUS "gst 1.0")  #暂且先把消息类型为STATUS类型的消息设置为 "gst 1.0"
  pkg_check_modules(GSTREAMER REQUIRED gstreamer-1.0)
  pkg_check_modules(GST_APP REQUIRED gstreamer-app-1.0)
  #再查找一下gstreamer-1.0,gstreamer-app-1.0 这回查找的条件是REQUIRED的
else()                      #GSTREAMER_VERSION_1_x为假,说明有gstreamer-0.10
  message(STATUS "gst 0.1")
  pkg_check_modules(GSTREAMER REQUIRED gstreamer-0.10)
  pkg_check_modules(GST_APP REQUIRED gstreamer-app-0.10)
  #再查找一下gstreamer-0.10,gstreamer-app-0.10 这回查找的条件是REQUIRED的
endif()

添加依赖库

  • find_package
  • catkin_package

The find_package command is common cmake and is needed to load the catkin macros and specify dependencies to other ROS packages.

find_package(catkin REQUIRED 
    COMPONENTS roscpp image_transport sensor_msgs nodelet
    camera_calibration_parsers camera_info_manager
    )
###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if your package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES gstcamera
#  CATKIN_DEPENDS other_catkin_pkg
#  DEPENDS system_lib
)
catkin_package(
    INCLUDE_DIRS include
    LIBRARIES gscam
    CATKIN_DEPENDS roscpp nodelet image_transport sensor_msgs
    camera_calibration_parsers camera_info_manager
    DEPENDS GSTREAMER GST_APP
    )

catkin_package的一些参数
macro defined in catkin_package.cmake
Parameters
INCLUDE_DIRS 当前工程下的include  
– CMAKE_CURRENT_SOURCE_DIR-relative paths to C/C++ includes

LIBRARIES 和find_package同样的 ros内部依赖的库
– names of library targets that will appear in the catkin_LIBRARIES and ${PROJECT_NAME}_LIBRARIES of other projects that search for you via find_package. #CATKIN_DEPENDS – a list of catkin projects which this project depends on.

DEPENDS 工程依赖的外部库
– a list of CMake projects which this project depends on.


在工程中添加 头文件、库文件、可执行文件

头文件

include_directories(
    include     #当前工程下的include
    ${catkin_INCLUDE_DIRS}  #<name_INCLUDE_DIRS>
    ${GLIB_INCLUDE_DIRS}
    ${GST_APP_INCLUDE_DIRS})

库文件

add a library to the project using the specified source files.

Link a target to given libraries. 一般在add_library,add_executable之后

add_library(gscam src/gscam.cpp)
  target_link_libraries(gscam
    ${catkin_LIBRARIES}
    ${GSTREAMER_LIBRARIES}
    ${GST_APP_LIBRARIES})

可执行文件

add_executable(gscam_node src/gscam_node.cpp)
  target_link_libraries(gscam_node gscam
    ${catkin_LIBRARIES}
    ${GSTREAMER_LIBRARIES}
    ${GST_APP_LIBRARIES})
  set_target_properties(gscam_node PROPERTIES OUTPUT_NAME gscam)
  #变更target的属性  这里是改它的名字

Install