http://blog.csdn.net/wzzfeitian/article/details/40963457/
系统信息
CMAKE_MAJOR_VERSION cmake主版本号,如2.8.6中的2CMAKE_MINOR_VERSION cmake次版本号,如2.8.6中的8CMAKE_PATCH_VERSION cmake补丁等级,如2.8.6中的6CMAKE_SYSTEM 系统名称,例如Linux-2.6.22CAMKE_SYSTEM_NAME 不包含版本的系统名,如LinuxCMAKE_SYSTEM_VERSION 系统版本,如2.6.22CMAKE_SYSTEM_PROCESSOR 处理器名称,如i686UNIX 在所有的类UNIX平台为TRUE,包括OS X和cygwinWIN32 在所有的win32平台为TRUE,包括cygwin开关选项
BUILD_SHARED_LIBS 控制默认的库编译方式。如果未进行设置,使用ADD_LIBRARY时又没有指定库类型,默认编译生成的库都是静态库 (可在t3中稍加修改进行验证)CMAKE_C_FLAGS 设置C编译选项CMAKE_CXX_FLAGS 设置C++编译选项指令(参数1 参数2…) 参数使用括弧括起,参数之间使用空格或分号分开。
以ADD_EXECUTABLE指令为例: ADD_EXECUTABLE(hello main.c func.c)或者 ADD_EXECUTABLE(hello main.c;func.c)指令是大小写无关的,参数和变量是大小写相关的。推荐你全部使用大写指令。
EXEC_PROGRAM EXEC_PROGRAM(Executable [dir where to run] [ARGS <args>][OUTPUT_VARIABLE <var>] [RETURN_VALUE <value>]) 用于在指定目录运行某个程序(默认为当前CMakeLists.txt所在目录),通过ARGS添加参数,通过OUTPUT_VARIABLE和RETURN_VALUE获取输出和返回值,如下示例
# 在src中运行ls命令,在src/CMakeLists.txt添加 EXEC_PROGRAM(ls ARGS "*.c" OUTPUT_VARIABLE LS_OUTPUT RETURN_VALUE LS_RVALUE) IF (not LS_RVALUE) MESSAGE(STATUS "ls result: " ${LS_OUTPUT}) # 缩进仅为美观,语法无要求 ENDIF(not LS_RVALUE)INCLUDE INCLUDE(file [OPTIONAL]) 用来载入CMakeLists.txt文件 INCLUDE(module [OPTIONAL])用来载入预定义的cmake模块 OPTIONAL参数的左右是文件不存在也不会产生错误 可以载入一个文件,也可以载入预定义模块(模块会在CMAKE_MODULE_PATH指定的路径进行搜索) 载入的内容将在处理到INCLUDE语句时直接执行
FIND_
FIND_FILE(<VAR> name path1 path2 …) VAR变量代表找到的文件全路径,包含文件名FIND_LIBRARY(<VAR> name path1 path2 …) VAR变量代表找到的库全路径,包含库文件名
FIND_LIBRARY(libX X11 /usr/lib) IF (NOT libx) MESSAGE(FATAL_ERROR "libX not found") ENDIF(NOT libX)FIND_PATH(<VAR> name path1 path2 …) VAR变量代表包含这个文件的路径
FIND_PROGRAM(<VAR> name 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)将其放入工程的某个目录供工程使用IF 语法:
IF (expression) COMMAND1(ARGS ...) COMMAND2(ARGS ...) ... ELSE (expression) COMMAND1(ARGS ...) COMMAND2(ARGS ...) ... ENDIF (expression) # 一定要有ENDIF与IF对应IF (expression), expression不为:空,0,N,NO,OFF,FALSE,NOTFOUND或<var>_NOTFOUND,为真 IF (not exp), 与上面相反 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 dir) 当dir是目录时,为真 IF (DEFINED var) 如果变量被定义,为真 IF (var MATCHES regex) 此处var可以用var名,也可以用${var} IF (string MATCHES regex)
当给定的变量或者字符串能够匹配正则表达式regex时为真。比如: IF ("hello" MATCHES "ell") MESSAGE("true") ENDIF ("hello" MATCHES "ell")数字比较表达式 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 (WIN32) MESSAGE(STATUS “This is windows.”) ELSE (WIN32) MESSAGE(STATUS “This is not windows”) ENDIF (WIN32) 上述代码用来控制在不同的平台进行不同的控制,但是,阅读起来却并不是那么舒服,ELSE(WIN32)之类的语句很容易引起歧义。 可以SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) 这时候就可以写成: IF (WIN32) ELSE () ENDIF () 配合ELSEIF使用,可能的写法是这样: IF (WIN32) #do something related to WIN32 ELSEIF (UNIX) #do something related to UNIX ELSEIF(APPLE) #do something related to APPLE ENDIF (WIN32)WHILE 语法:
WHILE(condition) COMMAND1(ARGS ...) COMMAND2(ARGS ...) ... ENDWHILE(condition)其真假判断条件可以参考IF指令
FOREACH FOREACH指令的使用方法有三种形式: 列表 语法: FOREACH(loop_var arg1 arg2 ...) COMMAND1(ARGS ...) COMMAND2(ARGS ...) ... ENDFOREACH(loop_var) 示例: AUX_SOURCE_DIRECTORY(. SRC_LIST) FOREACH(F ${SRC_LIST}) MESSAGE(${F}) ENDFOREACH(F) 范围 语法: FOREACH(loop_var RANGE total) COMMAND1(ARGS ...) COMMAND2(ARGS ...) ... ENDFOREACH(loop_var) 示例: 从0到total以1为步进 FOREACH(VAR RANGE 10) MESSAGE(${VAR}) ENDFOREACH(VAR) 输出: 012345678910 范围和步进 语法: FOREACH(loop_var RANGE start stop [step]) COMMAND1(ARGS ...) COMMAND2(ARGS ...) ... ENDFOREACH(loop_var) 从start开始到stop结束,以step为步进, 注意:直到遇到ENDFOREACH指令,整个语句块才会得到真正的执行。 FOREACH(A RANGE 5 15 3) MESSAGE(${A}) ENDFOREACH(A) 输出: 581114参考ADD_LIBRARY和SET_TARGET_PROPERTIES用法 t3示例
参考INCLUDE_DIRECTORIES, LINK_DIRECTORIES, TARGET_LINK_LIBRARIES用法 t4示例使用动态库或静态库 t5示例如何使用cmake预定义的cmake模块(以FindCURL.cmake为例演示) t6示例如何使用自定义的cmake模块(编写了自定义的FindHELLO.cmake) 注意读t5和t6的CMakeLists.txt和FindHELLO.cmake中的注释部分
使用变量CMAKE_C_FLAGS添加C编译选项 使用变量CMAKE_CXX_FLAGS添加C++编译选项 使用ADD_DEFINITION添加
参考INCLUDE_DIRECTORIES命令用法
参考MESSAGE用法
参考SET和AUX_SOURCE_DIRECTORY用法
建议:在Project根目录先建立build,然后在build文件夹内运行cmake ..,这样就不会污染源代码, 如果不想要这些自动生成的文件了,只要简单的删除build文件夹就可以