ros的CMakeLists详解

文件结构

CMakeListx.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())

catkin_make默认的路径信息

在catkin_make运行后终端输出文件部分解析
 
#基本路径
Base path: /home/user/catkin_ws
Source space: /home/user/catkin_ws/src
Build space: /home/user/catkin_ws/build
Devel space: /home/user/catkin_ws/devel
Install space: /home/user/catkin_ws/install
 
 
#catkin_make 封装运行中cmake运行的情况
Running command: "cmake /home/user/catkin_ws/src -DCATKIN_DEVEL_PREFIX=/home/user/catkin_ws/devel 
-DCMAKE_INSTALL_PREFIX=/home/user/catkin_ws/install" in "/home/user/catkin_ws/build"  
 
#编译工具查找
-- Using CATKIN_DEVEL_PREFIX: /tmp/catkin_ws/devel
-- Using CMAKE_PREFIX_PATH: /opt/ros/groovy
-- This workspace overlays: /opt/ros/groovy
 
#编译的包
#catkin_make 封装运行中make运行的情况

catkin_make 编译指定的包

$ catkin_make -DCATKIN_WHITELIST_PACKAGES=“package1;package2”

恢复编译所有的包

$ catkin_make -DCATKIN_WHITELIST_PACKAGES=""

标准内容

find_package

如果一个软件包被CMake通过find_package函数找到,那么系统会自动的生成一系列描述软件包的CMake 环境变量。这些环境变量会稍后被CMake脚本使用。与此同时,这些环境变量描述了软件包会把头文件导出到了那里,以及哪些被软件包依赖的库和这些库的路径。环境变量的命名通常是:_ :

_ FOUND 当库被找到的时候,被设置为true;否则,设置为false;

_ INCLUDE_DIRS 或者 _ INCLUDES 包含了软件包导出的路径

_ LIBRARIES 或者 _ LIBS 被软件包导出的库

_ DEFINITIONS- ?

例如:

#查找OpenCV是否安装
find_package(OpenCV REQUIRED core highgui imgproc imgcodecs)
if (OPENCV_FOUND)
    message(STATUS "找到OpenCV:\"${OpenCV_INCLUDE_DIRS}\",ENABLE_OPENCV宏已打开")
    message(STATUS "找到OpenCV:\"${OpenCV_LIBS}\"")
    include_directories(${OpenCV_INCLUDE_DIRS})
    add_definitions(-DENABLE_OPENCV)
    list(APPEND LINK_LIB_LIST ${OpenCV_LIBS})
endif (OPENCV_FOUND)

其中REQUIRED表示要寻找的依赖包对我来说很重要,如果找不到就不编译了。COMPONENTS它表示我们要找的包需要后面的这些库或者包。

自定义引入相应opencv版本

如果你有很多的opencv版本,尤其是一个是opencv2.x.x一个是opencv3.x.x,因为2和3在数据结构上有相对较大的变化,所以如果引入错误的版本可能导致程序的无法运行。因为find_package找默认路径下的OpenCV,但是很多时候安装多个版本的库的时候都会make install在opt目录下。安装在opt的文件中会有share文件夹,这里面就有咱们需要的OpenCV文件夹,所以如果要自己有选择的控制版本,则在find_package这句话前面去设置opencv的OpenCV文件夹在哪里,添加set(OpenCV_DIR /opt/opencv-2.4.11/share/OpenCV)这句话。因为我的opencv2.4.11版本install在/opt/opencv-2.4.11文件夹下。这个可以根据你install的位置去变化。
使用Set增加搜索目录

catkin_package

catkin_package()是一个catkin_provided 的CMake macro文件。构建系统必须要指定catkin特定的信息,而系统又用于生成类pkg-config和CMake文件。

在使用add_library()和add_executable()函数声明目标之前,必须的调用这个函数。这个函数有5个可选的参数。

INCLUDE_DIRS - 包含了导出软件包头文件的路径

LIBRARIES - 项目导出的库

CATKIN_DEPENDS - 这个项目依赖的其他catkin项目

DEPENDS - 这个项目依赖的其他non-catkin项目。

CFG_EXTRAS - 其他额外的一些配置选择

catkin_package(
   INCLUDE_DIRS include
   LIBRARIES ${PROJECT_NAME}
   CATKIN_DEPENDS roscpp nodelet
   DEPENDS eigen opencv)

set_target_properties

非常重要的是需要注意,catkin中构建目标的名称必须是唯一的,不管它们是构建/安装到哪个文件夹。这是CMake的要求。但是,目标的名称仅在CMake内部是必需的。可以使用set_target_properties()函数将目标重命名为其他目标:

set_target_properties(rviz_image_view
                      PROPERTIES OUTPUT_NAME image_view
                      PREFIX "")

虽然可执行文件和库的默认输出目录通常被设置为合理的值,但在某些情况下必须自定义。比如,包含Python绑定的库必须放在不同的文件夹中,以便可以在Python中导入,如下:

set_target_properties(python_module_library
  PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_PYTHON_DESTINATION})

python模块支持

如果你的ROS包提供了一些Python模块,你应该创建一个setup.py文件并调用

catkin_python_setup()

http://docs.ros.org/api/catkin/html/user_guide/setup_dot_py.html
http://docs.ros.org/api/catkin/html/howto/format2/installing_python.html

根目录下建立setup.py文件

from distutils.core import setup
from catkin_pkg.python_setup import generate_distutils_setup

d = generate_distutils_setup(
    packages=['mypkg'],
    scripts=['bin/myscript'],
    package_dir={'': 'src'}
)

setup(**d)
catkin_install_python(PROGRAMS scripts/myscript
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})

使用上述函数需要在调用generate_messages()和catkin_package()之前

消息,服务和动作

ROS中的messages(.msg),services(.srv)和action(.action)文件在构建和使用ROS包之前,需要进行特殊的预处理器构建步骤。这些宏是生成指定编程语言的文件的关键,以便可以使用所选编程语言中的消息,服务和操作。构建系统可以使用所有可用的生成(例如gencpp,genpy,genlisp等)。

提供了三个宏来分别处理消息,服务和操作:

add_message_files

add_service_files

add_action_files

必须在调用生成的宏之后调用这些宏以生成对应的.h文件:

 generate_messages()

add_executable(生成可执行目标)

要指定必须构建的可执行目标,我们使用add_executable()这个CMake函数。

add_executable(does_not_use_local_messages_program src/main.cpp)

include_directories(头文件)/link_directories

include_directories(include ${Boost_INCLUDE_DIRS} ${catkin_INCLUDE_DIRS})
link_directories(${catkin_LIB_DIRS} lib)

link_directories(~/my_libs)

其中 ,catkin_LIB_DIRS 表示创建的环境变量(必须要有,可以是任意名称,但建议此名方便理解),${catkin_LIB_DIRS} 为取该环境变量的值,lib 是相对于当前功能包所在路径的相对路径,此法默认以 当前功能包路径为基准添加额外的库路径。

该指令的作用主要是指定要链接的库文件的路径,该指令有时候不一定需要。因为find_package和find_library指令可以得到库文件的绝对路径。不过你自己写的动态库文件放在自己新建的目录下时,可以用该指令指定该目录的路径以便工程能够找到。

add_library(库目标)/target_link_libraries

add_library()这个 Make函数用来指定库来构建,将功能包的cpp生成一个库给别人用。默认情况下,catkin会构建共享库

add_library( [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            [source1] [source2] [...])

其中表示库文件的名字,该库文件会根据命令里列出的源文件来创建。而STATIC、SHARED和MODULE的作用是指定生成的库文件的类型。STATIC库是目标文件的归档文件,在链接其它目标的时候使用。SHARED库会被动态链接(动态链接库),在运行时会被加载。MODULE库是一种不会被链接到其它目标中的插件,但是可能会在运行时使用dlopen-系列的函数。默认状态下,库文件将会在于源文件目录树的构建目录树的位置被创建,该命令也会在这里被调用。

target_link_libraries(, , , ... )

例如:

add_executable(foo src/foo.cpp)
add_library(moo src/moo.cpp)
target_link_libraries(foo moo)  -- This links foo against libmoo.so

add_dependencies(依赖)

如果你有一个包编译.msg .srv,并且可执行文件要使用他们,那么你就需要创建一个显式的依赖项,自动生成message的target。这里的some_target是add_executable()设置的target的名字。

add_dependencies(some_target ${PROJECT_NAME}_generate_messages_cpp)

Boost依赖

find_package(Boost REQUIRED)

但boost thread 运行时需要库,必须指出组件thread .

find_package(Boost REQUIRED COMPONENTS thread)

find_package()之后就可以用此编译和连接了.  命名规则基本是这样: ${name}_INCLUDE_DIRS and${name}_LIBRARIES 

文件安装

经过构建之后,需要将目标放置到catkin工作空间的开发空间中。但是,我们通常希望在系统中安装目标(有关安装路径的信息可以在REP 122中找到 ),以便其他人或本地文件夹可以使用它们来测试系统级安装。换句话说,如果您希望能够对代码进行“make install”,则需要指定目标应该结束的位置。

这是由CMake install()函数完成的,该函数有下面的几个参数:

TARGETS - 那个被安装的目标

ARCHIVE DESTINATION - 静态库和DLL(Windows).lib存根

LIBRARY DESTINATION - 非DLL共享库和模块

RUNTIME DESTINATION - 可执行目标和DLL(Windows)样式共享库
install(DIRECTORY include/${PROJECT_NAME}/
  DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
  PATTERN ".svn" EXCLUDE
)
install(DIRECTORY launch/
  DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch
  PATTERN ".svn" EXCLUDE)

模板文件

 cmake_minimum_required(VERSION 2.8.3)

 project(robot)
 # 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})

http://wiki.ros.org/catkin/CMakeLists.txt

你可能感兴趣的:(ros)