Cmake Practice 总结 常用指令

基本指令

add_definitions
向 C/C++ 编译器添加 -D 定义,比如:
add_definitions(-DENABLE_DEBUG -DABC),参数之间用空格分割。

如果你的代码中定义了

#ifdef ENABLE_DEBUG
... 
#endif

这个代码块就会生效。

如果要添加其他的编译器开关,可以通过 CMAKE_C_FLAGS 变量和 CMAKE_CXX_FLAGS 变量设置。

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

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

aux_source_directory
基本语法是:

aux_source_directory(dir VARIABLE)

作用是发现一个目录下所有的源代码文件并将列表存储在一个变量中

aux_source_directory(. SRC_LIST)
add_executable(main ${SRC_LIST})

cmake_minimum_required
用法:

cmake_minimum_required(VERSION 2.5 FATAL_ERROR)

如果 cmake 版本小与 2.5,则出现严重错误,整个过程中止。

install 指令
install系列指令已经在前面的章节有非常详细的说明,这里不在赘述,可参考前面的安装部分。

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)
if(NOT libX)
  message(FATAL_ERROR “libX not found”)
endif()

控制指令:

IF 指令,基本语法为:

if(expression1)
  COMMAND1(ARGS ...)
  COMMAND2(ARGS ...)
  ...
elseif(expression2)
  COMMAND3(ARGS ...)
  COMMAND4(ARGS ...)
  ...
else()
  COMMAND5(ARGS ...)
  COMMAND6(ARGS ...)
  ...
endif()

只出现 if 的地方一定要有对应的 endif.同时出现 elseif 的地方,endif 是可选的。

表达式的使用方法如下:
if(var), 如果变量不是:空,0,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("hello" MATCHES "ell")
message("true")
endif()

数字比较表达式

if(variable LESS number)
if(string LESS number)
if(variable GREATER number)
if(string GREATER number)
if(variable EQUAL number)
if(string EQUAL number)

按照字母序的排列进行比较.

if(variable STRLESS string)
if(string STRLESS string)
if(variable STRGREATER string)
if(string STRGREATER string)
if(variable STREQUAL string)
if(string STREQUAL string)

if(DEFINED variable),如果变量被定义,为真。

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

if(WIN32)
  MESSAGE(STATUS “This is windows.”)
  #作一些 Windows 相关的操作
else()
  MESSAGE(STATUS “This is not windows”)
  #作一些非 Windows 相关的操作
endif()

如果配合 elseif 使用,可能的写法是这样:

if(WIN32)
  #do something related to WIN32
elseif(UNIX)
  #do something related to UNIX
elseif(APPLE)
  #do something related to APPLE
endif()

while 指令的语法是:

while(condition)
  COMMAND1(ARGS ...)
  COMMAND2(ARGS ...)
  ...
endwhile()

其真假判断条件可以参考 if 指令。

foreach 指令的使用方法有三种形式:
1,列表

foreach(loop_var arg1 arg2 ...)
  COMMAND1(ARGS ...)
  COMMAND2(ARGS ...)
  ...
endforeach()

像我们前面使用的 aux_source_directory 的例子

aux_source_directory(. SRC_LIST)
foreach(F ${SRC_LIST})
  message(${F})
endforeach(F)

2,范围

foreach(loop_var RANGE total)
endforeach()

从 0 到 total 以1为步进

举例如下:

foreach(VAR RANGE 10)
  message(${VAR})
endforeach(VAR)

最终得到的输出是:

0
1
2
3
4
5
6
7
8
9
10

3,范围和步进

foreach(loop_var RANGE start stop [step])
endforeach()

从 start 开始到 stop 结束,以 step 为步进,
举例如下

foreach(A RANGE 5 15 3)
  message(${A})
endforeach(A)

最终得到的结果是:

5
8
11
14

这个指令需要注意的是,知道遇到 endforeach 指令,整个语句块才会得到真正的执行。

上一篇:Cmake Practice 总结 Project


下一篇:Leetcode 104 Maximum Depth of Binary Tree python