CMake常用指令结合PCL 的顶层CMake文件的解释

基本指令

(1)ADD_DEFINITIONS 向 C/C++编译器添加-D 定义,比如:
ADD_DEFINITIONS(-DENABLE_DEBUG -DABC),参数之间用空格分割。
如果你的代码中定义了#ifdef ENABLE_DEBUG #endif,这个代码块就会生效。
如果要添加其他的编译器开关,可以通过 CMAKE_C_FLAGS 变量和 CMAKE_CXX_FLAGS 变
量设置。

在PCL中有

add_definitions("-DBOOST_DISABLE_ASSERTS -DEIGEN_NO_DEBUG")

这句话的意思就是如果定义了#ifdef BOOST_DISABLE_ASSERTS #endif  和

#ifdef EIGEN_NO_DEBUG #endif的话中间的代码就会有效

(2)ADD_DEPENDENCIES 定义 target 依赖的其他 target,确保在编译本 target 之前,其他的 target 已经被构建。

ADD_DEPENDENCIES(target-name depend-target1 depend-target2 ...)

(3)ADD_TEST 与 ENABLE_TESTING 指令。 ENABLE_TESTING 指令用来控制 Makefile 是否构建 test 目标,涉及工程所有目录。语法很简单,没有任何参数,ENABLE_TESTING(),一般情况这个指令放在工程的主
CMakeLists.txt 中.  PCL 中是有test的模块的所以在主cmakelists.txt中是有这句话的

### ---[ Set up for tests
enable_testing()

ADD_TEST 指令的语法是:
ADD_TEST(testname Exename arg1 arg2 ...) testname 是自定义的 test 名称,Exename 可以是构建的目标文件也可以是外部脚本等等。后面连接传递给可执行文件的参数。如果没有在同一个 CMakeLists.txt 中打开 ENABLE_TESTING()指令,任何 ADD_TEST 都是无效的。

(4)AUX_SOURCE_DIRECTORY
基本语法是:
AUX_SOURCE_DIRECTORY(dir VARIABLE) 作用是发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指令临时被用来 自动构建源文件列表。因为目前 cmake 还不能自动发现新添加的源文件。

(5)CMAKE_MINIMUM_REQUIRED
其语法为 CMAKE_MINIMUM_REQUIRED(VERSION versionNumber [FATAL_ERROR])
比如 CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
如果 cmake 版本小与 2.8 则出现严重错误,整个过程中止。

(6)FIND_指令
FIND_系列指令主要包含一下指令:      FIND_FILE(<VAR> name1 path1 path2 ...)
                                                                         VAR 变量代表找到的文件全路径,包含文件名
FIND_LIBRARY(<VAR> name1 path1 path2 ...)
                                                                        VAR 变量表示找到的库全路径,包含库文件名
FIND_PATH(<VAR> name1 path1 path2 ...)
                                                                        VAR 变量代表包含这个文件的路径。
FIND_PROGRAM(<VAR> name1 path1 path2 ...)
                                                                       VAR 变量代表包含这个程序的全路径。
FIND_PACKAGE(<name> [major.minor] [QUIET] [NO_MODULE]
 [[REQUIRED|COMPONENTS] [componets...]])
用来调用预定义在 CMAKE_MODULE_PATH 下的 Find<name>.cmake 模块,你也可以自己
定义 Find<name>模块,通过 SET(CMAKE_MODULE_PATH dir)将其放入工程的某个目录
中供工程使用,我们在后面的章节会详细介绍 FIND_PACKAGE 的使用方法和 Find 模块的
编写  FIND_LIBRARY 示例: FIND_LIBRARY(libX X11 /usr/lib)

(6)IF 指令,基本语法为:

IF(expression)
# THEN section.
COMMAND1(ARGS ...)COMMAND2(ARGS ...)
...
ELSE(expression)
# ELSE section.
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
ENDIF(expression)

另外一个指令是 ELSEIF,总体把握一个原则,凡是出现 IF 的地方一定要有对应的
ENDIF.出现 ELSEIF 的地方,ENDIF 是可选的。

表达式的使用方式有:

IF(var),如果变量不是:空,,N, NO, OFF, FALSE, NOTFOUND 或
<var>_NOTFOUND 时,表达式为真。
IF(NOT var ),与上述条件相反。
IF(var1 AND var2),当两个变量都为真是为真。
IF(var1 OR var2),当两个变量其中一个为真时为真。
IF(COMMAND cmd),当给定的 cmd 确实是命令并可以调用是为真。
IF(EXISTS dir)或者 IF(EXISTS file),当目录名或者文件名存在时为真。
IF(file1 IS_NEWER_THAN file2),当 file1 比 file2 新,或者 file1/file2 其
中有一个不存在时为真,文件名请使用完整路径。
IF(IS_DIRECTORY dirname),当 dirname 是目录时,为真。
IF(variable MATCHES regex)
IF(string MATCHES regex)
当给定的变量或者字符串能够匹配正则表达式 regex 时为真。

一个小例子,用来判断平台差异:

IF(WIN32)
MESSAGE(STATUS “This is windows.”)
#作一些 Windows 相关的操作
ELSE(WIN32)
MESSAGE(STATUS “This is not windows”)
#作一些非 Windows 相关的操作
ENDIF(WIN32)

上述代码用来控制在不同的平台进行不同的控制,但是,阅读起来却并不是那么舒服,
ELSE(WIN32)之类的语句很容易引起歧义。

以上内容是从http://sewm.pku.edu.cn/src/paradise/reference/CMake%20Practice.pdf该书籍总结而得

05-11 13:06