CMake 基本使用方法--写CMakeList.txt,Compile ROS package

原文地址:CMake 基本使用方法--写CMakeList.txt 作者:raindy
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


ubuntu@tegra-ubuntu:~/dev/ros/move_base$ cmake ~/dev/ros/move_base
-- Using CATKIN_DEVEL_PREFIX: /home/ubuntu/dev/ros/move_base/devel
-- Using CMAKE_PREFIX_PATH: /opt/ros/indigo
-- This workspace overlays: /opt/ros/indigo
-- Using PYTHON_EXECUTABLE: /usr/bin/python
-- Using Debian Python package layout
-- Using empy: /usr/bin/empy
-- Using CATKIN_ENABLE_TESTING: ON
-- Call enable_testing()
-- Using CATKIN_TEST_RESULTS_DIR: /home/ubuntu/dev/ros/move_base/test_results
-- Found gtest sources under '/usr/src/gtest': gtests will be built
-- Using Python nosetests: /usr/bin/nosetests-2.7
-- catkin 0.6.16
-- Using these message generators: gencpp;genlisp;genpy
-- Eigen found (include: /usr/include/eigen3)
CMake Warning at /opt/ros/indigo/share/catkin/cmake/catkin_package.cmake:409 (message):
  catkin_package() include dir '/home/ubuntu/dev/ros/move_base/devel/include'
  should be placed in the devel space instead of the build space
Call Stack (most recent call first):
  /opt/ros/indigo/share/catkin/cmake/catkin_package.cmake:98 (_catkin_package)
  CMakeLists.txt:23 (catkin_package)


-- Configuring done
-- Generating done
-- Build files have been written to: /home/ubuntu/dev/ros/move_base
ubuntu@tegra-ubuntu:~/dev/ros/move_base$ make
[ 33%] Generating dynamic reconfigure files from cfg/MoveBase.cfg: /home/ubuntu/dev/ros/move_base/devel/include/move_base/MoveBaseConfig.h /home/ubuntu/dev/ros/move_base/devel/lib/python2.7/dist-packages/move_base/cfg/MoveBaseConfig.py
Generating reconfiguration files for MoveBase in move_base
Wrote header file in /home/ubuntu/dev/ros/move_base/devel/include/move_base/MoveBaseConfig.h
[ 33%] Built target move_base_gencfg
Scanning dependencies of target move_base
[ 33%] Building CXX object CMakeFiles/move_base.dir/src/move_base.cpp.o
Linking CXX shared library devel/lib/libmove_base.so
[ 33%] Built target move_base
Scanning dependencies of target move_base_node
[ 33%] Building CXX object CMakeFiles/move_base_node.dir/src/move_base_node.cpp.o
Linking CXX executable devel/lib/move_base/move_base
[ 33%] Built target move_base_node

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


http://techbase.kde.org/Development/Tutorials/CMake_(zh_CN)
http://www.cmake.org/Wiki/CMake

 

CMake简介

CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。

CMake 使用方法

   CMake的所有的语句都写在一个叫:CMakeLists.txt的文件中。当CMakeLists.txt文件确定后,可以用ccmake命令对相关的变量值进行配置。这个命令必须指向CMakeLists.txt所在的目录。配置完成之后,应用cmake命令生成相应的makefile(在Unixlike系统下)或者 project文件(指定用window下的相应编程工具编译时)。

   其基本操作流程为:

  1. $> ccmake directory
  2. $> cmake directory
  3. $> make

其中directory为CMakeList.txt所在目录;

  • 第一条语句用于配置编译选项,如VTK_DIR目录,一般这一步不需要配置,直接执行第二条语句即可,但当出现错误时,这里就需要认为配置了,这一步才真正派上用场;
  • 第二条命令用于根据CMakeLists.txt生成Makefile文件;
  • 第三条命令用于执行Makefile文件,编译程序,生成可执行文件;

CMake的执行就是这么简单,其难点在于如何编写CMakeLists.txt文件,下面结合例子简单介绍CMakeLists.txt的编写,看下面这个CMakeLists.txt

  1. #project name
  2. PROJECT (test_math )
  3. #head file path
  4. INCLUDE_DIRECTORIES (
  5. include
  6. )
  7. #source directory
  8. AUX_SOURCE_DIRECTORY (src DIR_SRCS )
  9. #set environmentvariable
  10. SET (TEST_MATH
  11. $ {DIR_SRCS }
  12. )
  13. #set externlibraries
  14. SET (LIBRARIES
  15. libm. so
  16. )
  17. #add executablefile
  18. ADD_EXECUTABLE (../bin/bin $ {TEST_MATH } )
  19. #add link library
  20. TARGET_LINK_LIBRARIES (../bin/bin $ {LIBRARIES } )

         或者用下面这个CMakeLists.txt

  1. #project name
  2. PROJECT (test_math )
  3. #head file path
  4. INCLUDE_DIRECTORIES (
  5. include
  6. )
  7. #source directory
  8. AUX_SOURCE_DIRECTORY (src DIR_SRCS )
  9. #set environmentvariable
  10. SET (TEST_MATH
  11. $ {DIR_SRCS }
  12. )
  13. #add executablefile
  14. ADD_EXECUTABLE (../bin/bin $ {TEST_MATH } )
  15. #add link library
  16. TARGET_LINK_LIBRARIES (../bin/bin m )

这是一个测试数学函数的程序的CMakeLists.txt,"#"后面为注释的内容,CMake的命令全部为大写

第2行指定生成的工程名为test_math

第4行指定头文件目录为include

第8行指定源文件目录为src,并将其赋值给环境变量DIR_SRCS

第10行设定环境变量TEST_MATH的值为环境变量DIR_SRCS的值,此处用于显示如何用环境变量对环境变量进行赋值

第14行将数学函数库赋值给环境变量LIBRARIES,当然,可以不用这个环境变量,而在后面直接使用该库名

第18行用于指定生成文件,将环境变量TEST_MATH目录下的所有文件编译生成../bin目录下的可执行文件bin

第20行指定../bin/bin执行时的链接库为环境变量LIBRARIES的值-libm.so

下面给出源文件
/src/main.c:

  1. #include
  2. #include"../include/a.h"
  3. int main ( )
  4. {
  5. double b= 25.0;
  6. double a= 0.0;
  7. a=get_sqrt (b );

  8. printf ( "a is %lf, b is %lfn",a,b );
  9. return 0;
  10. }

/src/a.c

  1. #include"../include/a.h"
  2. doubleget_sqrt ( double var1 )
  3. {
  4. return sqrt (var1 );
  5. }

 

/include/a.h

#ifndef A_FILE_HEADER_INC

  1. #defineA_FILE_HEADER_INC
  2. #include

  3. doubleget_sqrt ( double var1 );

  4. #endif

将CMakeLists.txt放在当前目录下,执行CMakeLists.txt

  1. $> cmake .
  2. $> make

即可生成可执行文件,在目录/bin下的bin文件,好了运行看其效果是否和所想一样。

 

 



这一章将从软件开发者的角度来描述如何实用CMake。也就是说,如果你的目标是用CMake来管理你的生成过程,请阅读这一章。

CMake的输入

COMMAND(args)

这里的 COMMAND是命令行的名称,args是用空格分割的参数列表。典型的,对与每一个项目的目录存在一个CMakeLists.txt。下面我们将从一个简单的Helloworld例子开始介绍, 它的源代码树形文件包含这些文件:

Hello.cCMakeLists.txt

CMakeLists.txt将包含下面两行:

PROJECT(Hello)
ADD_EXECUTABLE(HelloHello.c)

为了生成Hello的可执行程序,你只需依照上面CMake运行的过程描述来生成makefiles文件。 PROJECT命令表明了产生的工作空间的名称。ADD_EXECUTABLE命令添加可执行的目标到生成程序。这个简单的程序就只需要这些设置。如歌你的项目需要一些文件才能编译也很容易,只想修改ADD_EXECUTABLE命令行如下:

ADD_EXECUTABLE(Hello Hello.c File2.c File3.c File4.c)

ADD_EXECUTABLE只是很多CMake命令中的一种。比如更复杂的如下:

PROJECT(HELLO)
SET(HELLO_SRCS Hell.c File2.c File3.c)
IF(WIN32)
  SET(HELLO_SRCS ${HELLO_SRCS}WinSupport.c)
ELSE (WIN32)
  SET(HELLO_SRCS ${HELLO_SRCS}UnixSupport.c)
ENDIF (WIN32)

ADD_EXECUTABLE (Hello ${HELLO_SRCS})

#look for the Tcl library
FIND_LIBRARY(TCL_LIBRARY NAMES tcl tc184 tc183 tc 182 tc 180
  PATHS /usr/lib /usr/local/lib)
IF (TCL_LIBRARY)
  TARGET_ADD_LIBRARY (HelloTCL_LIBRARY)
ENDIF(TCL_LIBRARY)

在这个例子中 SET 命令用于将源文件组成一个列表。 IF命令用于增加WinSupport.c或者UnixSupport.c到列表中。 最后 ADD_EXECUTABLE命令用于采用源文件列表HELLO_SRCS中列出的文件生成可执行文件。FIND_LIBRARY命令用于寻找在一些指定目录下的特定的Tcl库文件。如果找到了,就将他们添加到Hello可执行程序的链接命令。#行为注释行。

CMake是会定义一些使用的变量在CMakeList文件中。比如,WIN32总是会在windows系统中被定义,而UNIX
总是在UNIX系统中被定义。

生成目标:(Build Targets)

SET()
SUBDIRS()
ADD_LIBRARY()
  这里生成静态链接文件,例如ADD_LIBRARY(Whole${HELLO_SRC}),就会生成一个libWhole.a可供链接

ADD_EXECUTABLE()
AUX_SOURCE_DIRECTORY()
PROJECT()

CMake会循环的查找从当前目录到SUBDIRS列出的任何子目录的文件。SET命令用于设定一个变量。ADD_LIBRARY将添加一个库到目标之中。ADD_EXECUTABLE添加一个可执行程序到目标列表中。(Note:编译器执行的顺序是先编译源文件,然后生成库文件,最后生成可执行文件)。AUX_SOURCE_DIRECTORY表示一个不在当前目录的包含源文件的目录。这些源代码将插入当前的库(LIBRARY)中。所有在AUX_SOURCE_DIRECTORY的文件将被编译(如,*.c,*.cxx,*.cpp等等)。PROJECT(ProjectName)是一个用在MSVC中的特殊变量,用于为编译器生成项目。他也为CMAKE定义连个有用的变量:ProjectName_SOURCE_DIR和ProjectName_BINARY_DIR.

编译的标示和选项。除了上面列出的命令外,CMakeLists.txt还包含如下的命令:
INCLUDE_DIRECTORIES()
LINK_DIRECTORIES()
LINK_LIBRARIES()
TARGET_LINK_LIBRARIES()

这些命令定义了用于编译源代码和生成可执行程序的目录和库。上面列出的目录的一个很重要的特性是它们会被任何子目录继承。也就是说,CMake依照目录的分层结构来承袭这些命令。在每次遇到对这些命令的描述的时候都会被展开一次。比如说,如果在顶层的CMakeLists文件中有定义INCLUDE_DIRECTORIES(/usr/include)和SUBDIRS(./subdir1),并且在./subdir1/CMakeLists.txt有INCLUDE_DIRECTORIES(/tmp/foobar),于是最后网状的结果是
INCLUDE_DIRECTORIES(/usr/include /tmp/foobar)

CMake会定义许多的模块来查找通常会用到的包,比如OpenGL或Java。这些模块为你节省了很多的时间来编写这些查找包。这些模块可以像这样加到你的CMakeList文件中,如下:

INCLUDE(${CMAKE_ROOT}/Modules/FindTCL.cmake)

CMAKE_ROOT总是定义在CMake中,用于指向CMake安装的路径。查看Modules子目录下的一些文件可以给你提供一些很好的idea关于怎样用这些CMake命令。

给项目文件添加一个新的目录
一个通用的方法来扩展一个项目文件是给他添加一个新的文件夹。这将包含三个步骤:
1.创建一个新的目录在你的源代码的分层目录中
2.将这个新的目录添加到SUBDIRS命令中
3.在这个新创建的目录中用适当的命令建立一个CMakeLists.txt文件

This section describes how to use CMake from the softwaredeveloper's point of view. That is, if your aim is to use CMake tomanage your build process, read this section first.
Input to CMake

COMMAND(args)
Where COMMAND is the name of the command, and args is a white-spaceseparated list of arguments to the command. (Arguments withembedded white-space should be quoted.) Typically there will be aCMakeLists.txt file for each directory of the project. Let's startwith a simple example. Consider building hello world. You wouldhave a source tree with the following files:
Hello.c  CMakeLists.txt
The CMakeLists.txt file would contain two lines:
PROJECT (Hello)
ADD_EXECUTABLE(Hello Hello.c)
To build the Hello executable you just follow the process describedin Running CMake above to generate the makefiles or Microsoftproject files. The PROJECT command indicates what the name of theresulting workspace should be and the ADD_EXECUTABLE command addsan executable target to the build process. That's all there is toit for this simple example. If your project requires a few files itis also quite easy, just modify the ADD_EXECUTABLE line as shownbelow.
ADD_EXECUTABLE(Hello Hello.c File2.c File3.c File4.c)

ADD_EXECUTABLE is just one of many commands available in CMake.Consider the more complicated example below.

PROJECT (HELLO)
SET(HELLO_SRCS Hello.c File2.c File3.c)
IF (WIN32)
  SET(HELLO_SRCS ${HELLO_SRCS}WinSupport.c)
ELSE (WIN32)
  SET(HELLO_SRCS ${HELLO_SRCS}UnixSupport.c)
ENDIF (WIN32)
ADD_EXECUTABLE (Hello ${HELLO_SRCS})

# look for the Tcl library
FIND_LIBRARY(TCL_LIBRARY NAMES tcl tcl84 tcl83 tcl82 tcl80
  PATHS  /usr/lib/usr/local/lib)
IF (TCL_LIBRARY)
  TARGET_ADD_LIBRARY (HelloTCL_LIBRARY)
ENDIF (TCL_LIBRARY)
In this example the SET command is used to group together sourcefiles into a list. The IF command is used to add eitherWinSupport.c or UnixSupport.c to this list. And finally theADD_EXECUTABLE command is used to build the executable with thefiles listed in the source list HELLO_SRCS. The FIND_LIBRARYcommand looks for the Tcl library under a few different names andin a few different paths, and if it is found adds it to the linkline for the Hello executable target. Note the use of the #character to denote a comment line.
CMake always defines some variables for use within CMakeList files.For example, WIN32 is always defined on windows systems and UNIX isalways defined for UNIX systems. CMake defines a number ofcommands. A brief summary of the most commonly used commandsfollows here. Later in the document an exhaustive list of allpre-defined commands is presented. (You may also add your owncommands, see the Extension Guide for more information.)

Build Targets:


SET()
SUBDIRS()
ADD_LIBRARY()
 这里生成静态链接文件,例如ADD_LIBRARY(Whole${HELLO_SRC}),就会生成一个libWhole.a,可供链接。

ADD_EXECUTABLE()
AUX_SOURCE_DIRECTORY()
PROJECT()
CMake works recursively, descending from the current directory intoany subdirectories listed in the SUBDIRS command. The command SETis used for setting a variable, in this case to a list of sourcefiles. (Note: currently only C and C++ code can be compiled.)ADD_LIBRARY adds a library to the list of targets this makefilewill produce. ADD_EXECUTABLE adds an executable to the list oftargets this makefile will produce. (Note: source code is compiledfirst, then libraries are built, and then executables are created.)The AUX_SOURCE_DIRECTORY is a directory where other source code,not in this directory, whose object code is to be inserted into thecurrent LIBRARY. All source files in the AUX_SOURCE_DIRECTORY arecompiled (e.g. *.c, *.cxx, *.cpp, etc.). PROJECT (PojectName) is aspecial variable used in the MSVC to create the project for thecompiler, it also defines two useful variables for CMAKE:ProjectName_SOURCE_DIR and ProjectName_BINARY_DIR.

Build flags and options. In addition to the commands listed above,CMakeLists.txt often contain the following commands:

INCLUDE_DIRECTORIES()
LINK_DIRECTORIES()
LINK_LIBRARIES()
TARGET_LINK_LIBRARIES()
These commands define directories and libraries used to compilesource code and build executables. An important feature of thecommands listed above is that are inherited by any subdirectories.That is, as CMake descends through a directory hierarchy (definedby SUBDIRS()) these commands are expanded each time a definitionfor a command is encountered. For example, if in the top-levelCMakeLists file has INCLUDE_DIRECTORIES(/usr/include), withSUBDIRS(./subdir1), and the file ./subdir1/CMakeLists.txt hasINCLUDE_DIRECTORIES(/tmp/foobar), then the net result is
INCLUDE_DIRECTORIES(/usr/include /tmp/foobar)
CMake comes with a number of modules that look for commonly usedpackages such as OpenGL or Java. These modules save you from havingto write all the CMake code to find these packages yourself.Modules can be used by including them into your CMakeList file asshown below.

  INCLUDE(${CMAKE_ROOT}/Modules/FindTCL.cmake)
CMAKE_ROOT is always defined in CMake and can be used to point towhere CMake was installed. Looking through some of the files in theModules subdirectory can provide good ideas on how to use some ofthe CMake commands.

Adding A New Directory to a project

A common way to extend a project is to add a new directory. Thisinvolves three steps:
 Create the new directory somewhere in yoursource directory hierarchy.
 Add the new directory to the SUBDIRScommand in the parent directories CMakeLists.txt
 Create a CMakeLists.txt in the newdirectory with the appropriate commands

你可能感兴趣的:(ROS,C++,Ubuntu)