ROS入门之Cmakelist说明

Cmakelist

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

1 Overall Structure and Ordering

Your CMakeLists.txt file MUST follow this format otherwise your packages will not build correctly. The order in the configuration DOES count. 加*号不在这里详细说明。

  1. *Required CMake Version (cmake_minimum_required)

  2. *Package Name (project())

  3. Find other CMake/Catkin packages needed for build (find_package())

  4. Enable Python module support (catkin_python_setup())

  5. Message/Service/Action Generators (add_message_files(), add_service_files(), add_action_files())

  6. Invoke message/service/action generation (generate_messages())  (generate_messages这个包在find_package中找到)

  7. Specify package build info export (catkin_package()) 指明目标文件的输出位置以及所依赖的包(Cmake与其他非编译包)

  8. Libraries/Executables to build (add_library()/add_executable()/target_link_libraries())

  9. *Tests to build (catkin_add_gtest())    :Unit Tests,a catkin-specific macro for handling gtest-based unit tests

  10. *Install rules (install())                         :Specifying Installable Targets

2 Finding Dependent CMake Packages

Find_package的作用:我们需要指定用来编译我们项目的编译工具(即Cmake Package)。通过find_package会自动找到的编译工具包(即Cmake Package)并为工具包生成Cmake的环境变量。这些环境变量说明了包的输出头文件、源文件、所依赖的库的路径。

We need to then specify which other CMake packages that need to be found to build our project using the CMake find_package function. There is always at least one dependency on catkin:

find_package(catkin REQUIRED)

If your project depends on other wet packages, they are automatically turned into components (in terms of CMake) of catkin. Instead of using find_package on those packages, if you specify them as components, it will make life easier. For example, if you use the package nodelet.

find_package(catkin REQUIRED COMPONENTS nodelet)

NB: You should only find_package components for which you want build flags. You should not add runtime dependencies

If a package is found by CMake through find_package, it results in the creation of several CMake environment variables that give information about the found package. These environment variables can be utilized later in the CMake script. The environment variables describe where the packages exported header files are, where source files are, what libraries the package depends on, and the paths of those libraries.

3 catkin_package()

catkin_package根据find_package中找到的包来编译。因此后者是搜寻定位编译工具包的过程,前者是利用包、指明包该如何编译的过程,并且前者的包除了编译工具包还有其他依赖包(项目)。

catkin_package() is a catkin-provided CMake macro. This is required to specify catkin-specific information to the build system which in turn is used to generate pkg-config and CMake files.

This function must be called before declaring any targets with add_library() or add_executable(). The function has 5 optional arguments:

  • INCLUDE_DIRS - The exported include paths (i.e. cflags) for the package(指明目标包的输出头文件的保存路径)

  • LIBRARIES - The exported libraries from the project

  • CATKIN_DEPENDS - Other catkin projects that this project depends on(Cmake的依赖项)

  • DEPENDS - Non-catkin CMake projects that this project depends on. (项目的依赖项(非Cmake依赖项,因为再上一个argument已经包含了Catkin depend。))

  • CFG_EXTRAS - Additional configuration options

Full macro documentation can be found here.

As an example:

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

This indicates that the folder "include" within the package folder is where exported headers go. The CMake environment variable ${PROJECT_NAME} evaluates to whatever you passed to the project() function earlier, in this case it will be "robot_brain". "roscpp" + "nodelet" are packages that need to be present to build/run this package, and "eigen" + "opencv" are system dependencies that need to be present to build/run this package.

4  Specifying Build Targets

两种编译目标文件:执行文件和库文件

Build targets can take many forms, but usually they represent one of two possibilties:

  • Executable Target - programs we can run
  • Library Target - libraries that can be used by executable targets at build and/or runtime

4.1 Target Naming

无论在构建或安装的文件夹中,生成的目标都必须是唯一的。无论在构建或安装的文件夹中,生成的目标都必须是唯一的。

It is very important to note that the names of build targets in catkin must be unique regardless of the folders they are built/installed to. This is a requirement of CMake. However, unique names of targets are only necessary internally to CMake. One can have a target renamed to something else using the set_target_properties() function:

Example:

set_target_properties(rviz_image_view
                      PROPERTIES OUTPUT_NAME image_view
                      PREFIX "")

This will change the name of the target rviz_image_view to image_view in the build and install outputs.

4.2 Include Paths and Library Paths

在指定编译目标之前,需要指定用哪些资源(包括头文件和库)的路径,来编译目标文件。可看做是Catkin_package的补充。

Prior to specifying targets, you need to specify where resources can be found for said targets, specifically header files and libraries:

  • Include Paths - Where can header files be found for the code (most common in C/C++) being built
  • Library Paths - Where are libraries located that executable target build against?
  • include_directories(<dir1>, <dir2>, ..., <dirN>)

  • link_directories(<dir1>, <dir2>, ..., <dirN>)

  1. include_directories():

    The argument to include_directories should be the *_INCLUDE_DIRS variables generated by your find_package calls and any additional directories that need to be included. If you are using catkin and Boost, your include_directories() call should look like:(_INCLUDE_DIRS由find_package生成,因此在这里可以很方便地包含所有编译工具包的资源(头文件和库))

    include_directories(include ${Boost_INCLUDE_DIRS} ${catkin_INCLUDE_DIRS})
  2. link_directories():

The CMake link_directories() function can be used to add additional library paths, however, this is not recommended. All catkin and CMake packages automatically have their link information added when they are find_packaged.

4.3 Executable Targets

指定所需生成的目标执行文件

To specify an executable target that must be built, we must use the add_executable() CMake function.

add_executable(myProgram src/main.cpp src/some_file.cpp src/another_file.cpp)

This will build a target executable called myProgram which is built from 3 source files: src/main.cpp, src/some_file.cpp and src/another_file.cpp.

4.4 Library Targets

指定所需生成的目标库文件

The add_library() CMake function is used to specify libraries to build. By default catkin builds shared libraries.

add_library(${PROJECT_NAME} ${${PROJECT_NAME}_SRCS})

指定所需生成的目标执行文件

Use the target_link_libraries() function to specify which libraries an executable target links against. This is done typically after an add_executable() call. Add ${catkin_LIBRARIES} if ros is not found.

Syntax:

target_link_libraries(<executableTargetName>, <lib1>, <lib2>, ... <libN>)

Example:

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

or:

add_executable(foo src/foo.cpp)
target_link_libraries(foo ${catkin_LIBRARIES})  省略了add_library(moo src/moo.cpp)

Note that there is no need to use link_directories() in most use cases as that information is automatically pulled in via find_package().

5 Messages, Services, and Action Targets

Messages (.msg), services (.srv), and actions (.action) files in ROS require a special preprocessor build step before being built and used by ROS packages. The point of these macros is to generate programming language-specific files so that one can utilize messages, services, and actions in their programming language of choice.(这些macros通过生成msg、srv、action的相关编程语言文件来给编译应用这三者) The build system will generate bindings using all available generators (e.g. gencpp, genpy, genlisp, etc).

There are three macros provided to handle messages, services, and actions respectively:

  • add_message_files

  • add_service_files

  • add_action_files

These macros must then be followed by a call to the macro that invokes generation:

 generate_messages() (括号中添加msg、srv、action所需要的依赖)

5.1 Important Prerequisites/Constraints

  • These macros must come BEFORE the catkin_package() macro in order for generation to work correctly.

          在宏catkin_package利用外加的massage/service/action之前,首先添加这些相关文件。

 find_package(catkin REQUIRED COMPONENTS ...)
 add_message_files(...)
 add_service_files(...)
 add_action_files(...)
 generate_messages(...)
 catkin_package(...)
 ...
  • You must use find_package() for the package message_generation, either alone or as a component of catkin:

find_package(catkin REQUIRED COMPONENTS message_generation)
  • Your catkin_package() macro must have a CATKIN_DEPENDS dependency on message_runtime.

catkin_package(
 ...
 CATKIN_DEPENDS message_runtime ...
 ...)

message_runtime 来自包message_generation

  • Your package.xml file must contain a build dependency on message_generation and a runtime dependency on message_runtime. This is not necessary if the dependencies are pulled in transitively from other packages.

  • If you have a target which (even transitively) depends on some other target that needs messages/services/actions to be built, you need to add an explicit dependency on target catkin_EXPORTED_TARGETS, so that they are built in the correct order. This case applies almost always, unless your package really doesn't use any part of ROS. Unfortunately, this dependency cannot be automatically propagated. (some_target is the name of the target set by add_executable()):

      dd_dependencies(some_target ${catkin_EXPORTED_TARGETS})
  • If you have a package which builds messages and/or services as well as executables that use these, you need to create an explicit dependency on the automatically-generated message target so that they are built in the correct order. (some_target is the name of the target set by add_executable()):

  • 如果在编译包或者执行文件时,需要用到msg和srv,就要显示调用由message_generation自动生成的message target依赖项${${PROJECT_NAME}_EXPORTED_TARGETS}。

      add_dependencies(some_target ${${PROJECT_NAME}_EXPORTED_TARGETS})

(其中,${PROJECT_NAME}是目标包的项目名称,在CMakelist中的前面已声明)

  • If you your package satisfies both of the above conditions, you need to add both dependencies, i.e.:

  •   add_dependencies(some_target ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

具体例子可到官网查看

猜你喜欢

转载自blog.csdn.net/linyijiong/article/details/81452119
今日推荐