ros下package中CMakelists的编写

一、package自动生成的Cmakelists

1. 指定cmake版本

cmake_minimum_required

示例:

Cmake_minimum_required(version 2.8.3)

2. 项目名字

project()

示例:

project(robot_brain)

3. 寻找构建所需依赖包

find_package

build的时候至少需要一个依赖包:
find_package(catkin REQUIRED)
如果有其他依赖包,可以有如下两种写法:
第一种:

find_package(catkin REQUIRED COMPONENTS ***)

第二种:

扫描二维码关注公众号,回复: 12417302 查看本文章
find_package(catkin REQUIRED)
find_package(*** REQUIRED)

ros建议使用第一种,通过组件的形式添加依赖库

4. 启用python模块依赖

catkin_python_setup()

很少用到

5. Message/Service/Action 生成文件

add_message_files()
add_service_files()
add_action_files()

6. 启动 message/services/action生成器

generate_messages()

示例:

 find_package(catkin REQUIRED COMPONENTS ...)
 add_message_files(...)
 add_service_files(...)
 add_action_files(...)
 generate_messages(...)
 catkin_package(...)
 ...

7. 指定构建包时的信息输出

catkin_package()

8. 生成库或者可执行文件

add_library() #生成库
add_executable() #生成可执行文件
target_link_libraries()

9. 测试构建

catkin_add_gtest()

10. 安装

install()

二、关于find_package

  1. 使用find_package后,他会构建对应包的cmake环境变量。这些环境变量在后续cmake脚本中会用到。

    这些环境变量包括:头文件路径,源文件路径,依赖库,以及依赖库的路径,命名方法通常如下:

    • _FOUND : bool变量,如果找到该library,设置为true
    • _INCLUDE_DIRS 或者 _INCLUDES : 对应包的头文件路径
    • _LIBRARIES 或者 _LIBS : 对应包的库文件
  2. 使用COMPONENTS 的好处

    在前文中,我们有介绍在出现其他依赖包的时候,如何使用find_package():

    如果有其他依赖包,可以有如下两种写法:
    第一种:
    find_package(catkin REQUIRED COMPONENTS ***)
    第二种:
    find_package(catkin REQUIRED)
    

    第一种写法的好处:

    我们可以将作为COMPONENTS 组件形式添加涛find_package中的所有包的环境变量都依附在catkin包上。这样使得我们后续进行include或者target的时候,只需要写一个catkin_includes 或者 catkin_LIBS就可以,避免了可执行文件或者库文件后面跟一大串的名字,使整个项目架构不清晰。

  3. BOOST

    如果使用boost以及boost中的一些组件的话,我们需要单独指定:

    find_package(Boost REQUIRED COMPONENTS thread XXX)

三、关于catkin_package

catkin_package命令下所有的参数都是面向当前写的这个包的使用者而言。为他使用find_package()命令找到的有关我当前包的所有变量而服务。

catkin提供的cmake宏定义。

必须在 add_library 或者 add_executable()之前调用。

函数有五个可选参数:

  • INCLUDE_DIRS: 输出头文件的目录
  • LIBRARIES: 指定输出lib
  • CATKIN_DEPENDS: 该项目依赖的其他catkin项目
  • DEPENDS: 该项目依赖的其他非catkin项目
  • CFG_EXTRAS: 基本用不到

举个例子:

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

上述脚本的含义:

指定当前包文件夹下的include文件夹为输出头文件的地方,后面depends的表示:其他程序使用find_package找到我写的这个程序包的时候, 在include_dir 和library变量中附加上了depands包对应的头文件变量和库文件变量。

建议尽量不要使用这种隐式依赖。

需要注意:catkin_package必须写在生成可执行文件和库文件之前

关于其中DEPENDS部分详细的介绍,可以查询链接

有人给做了翻译,更好理解一些:

四、关于输出可执行文件和库文件

  1. include paths and library paths

    # 头文件
    include_directories()
    # 库文件
    link_directories()
    
    # 举例:
    include_directories(include ${Boost_INCLUDE_DIRS} ${catkin_INCLUDE_DIRS})
    link_directories(~/my_libs)
    

    不建议使用link_directories来链接库文件,在find_package之后,完全可以直接在对应的target处通过target_link_libraries实现对应链接。

  2. add_library , add_executable, target_link_libraries

    这三部分我们不在详细说了,比较基本的操作。

五、关于add_dependencies

首先说明:

add_dependencies面向的是msg,service或者dynamic reconfigure

他存在的意义是:在我们生成可执行文件或者动态链接库之前,将所使用的msg,service,dynamic reconfigure编译好,供target使用。否则可能会出现找不到对应msg等定义的错误。

所以add_dependencies出现在add_librarytarget_link_librariesadd_executabletarget_link_libraries之间。

所以建议,如果代码中自定义了上述类型,就直接在对应位置添加这句话
add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

  1. 注意事项

    1. 必须在catkin_package() 前出现,可以保证生成msg正常工作。

    2. 在catkin_package()中必须有message_runtime的dependency

      catkin_package(
       ...
       CATKIN_DEPENDS message_runtime ...
       ...)
      
    3. find_package必须加入对应包信息

      find_package(catkin REQUIRED COMPONENTS message_generation)
      
    4. Package.xml中必须包含:

      • build dependency: message_generation
      • Runtime dependency: message_runtime
    5. 如果你的target依赖的其他target需要生成构建msg,那么需要显式使用catkin_EXPORTED_TARGETS,这样才能按照正确构建顺序执行程序。

      add_dependencies(some_target ${catkin_EXPORTED_TARGETS})
      
    6. 如果我的target本身在使用这些message,我需要做如下操作:

      add_dependencies(some_target ${${PROJECT_NAME}_EXPORTED_TARGETS})
      
    7. 如果这个target同时满足第五项,第六项:

      add_dependencies(some_target ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
      
  2. example

      # 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})
    

六、关于python 模块支持

catkin_python_setup()

注意: 在调用generate_messages() 和 catkin_package() 前使用。

猜你喜欢

转载自blog.csdn.net/allenhsu6/article/details/112345029