CMake相关语法

Cmake相关语法

语法

  1. 变量使⽤${}⽅式取值,但是在IF 控制语句中是直接使⽤变量名。
  2. 指令(参数1 参数 2…),参数使⽤括弧括起,参数之间使⽤空格或分号分开。
  3. 指令是⼤⼩写⽆关的,参数和变量是⼤⼩写相关的。
  4. SET(SRC_LIST main.c)也可以写成 SET(SRC_LIST “main.c”) 是没有区别的,但是假设⼀个源⽂件的⽂件名是 fu nc.c(⽂件名中间包含了空格)。这时候就必须使⽤双引号。
  5. 可以忽略掉source 列表中的源⽂件后缀,⽐如可以写成 ADD_EXECUTABLE(t1 main),cmake 会⾃动的在本⽬录查找main.c 或者main.cpp等。
  6. 参数也可以使⽤分号来进⾏分割,ADD_EXECUTABLE(t1 main.c t1.c)可以写成ADD_EXECUTABLE(t1 main.c;t1.c)。
  7. cmake 并不⽀持 make distclean,因为CMakeLists.txt 可以执⾏脚本并通过脚本⽣成⼀些临时⽂件,但是却没有办法来跟踪这些临时⽂件到底是哪些。因此,没有办法提供⼀个可靠的 make distclean ⽅案。
  8. 内部构建与外部构建,内部构建⽣成了⼀些⽆法⾃动删除的中间⽂件,外部构建对于原有的⼯程没有任何影响,所有动作全部发⽣在编译⽬录。

变量

PROJECT_SOURCE_DIR | CMAKE_SOURCE_DIR

工程代码所在目录

PROJECT_BINARY_DIR | CMAKE_BINARY_DIR

编译发⽣的⽬录

CMAKE_CURRENT_SOURCE_DIR

指的是当前处理的CMakeLists.txt 所在的路径

CMAKE_CURRRENT_BINARY_DIR

如果是in-source 编译,它跟 CMAKE_CURRENT_SOURCE_DIR ⼀致,如果是out-of-source 编译, 他指的是target 编译⽬录。

EXECUTABLE_OUTPUT_PATH

⽬标⼆进制的位置

SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

LIBRARY_OUTPUT_PATH

共享库位置

SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

CMAKE_INSTALL_PREFIX

安装目录前缀

cmake -DCMAKE_INSTALL_PREFIX=/usr .

CMAKE_INSTALL_PREFIX 的默认定义 是/usr/local

CMAKE_CURRENT_LIST_FILE

输出调⽤这个变量的CMakeLists.txt 的完整路径

CMAKE_CURRENT_LIST_LINE

输出这个变量所在的⾏

CMAKE_MODULE_PATH

这个变量⽤来定义⾃⼰的cmake模块所在的路径。如果你的⼯程⽐较复杂,有可能会⾃⼰编写⼀些cmake 模块,这些cmake模块是随你的⼯程发布的,为了让cmake在处理CMakeLists.txt 时找到这些模块, 你需要通过SET 指令,将⾃⼰的cmake 模块路径设置⼀下。

指令

CMAKE_MINIMUM_REQUIRED

CMAKE_MINIMUM_REQUIRED(VERSION versionNumber [FATAL_ERROR])

⽐如CMAKE_MINIMUM_REQUIRED(VERSION 2.5 FATAL_ERROR)如果cmake版本⼩于2.5,则出现严重错误,整个过程中⽌。

PROJECT

PROJECT(projectname [CXX] [C] [Java])

指令定义⼯程名称,并可指定⼯程⽀持的语⾔,⽀持的语⾔列表是可以忽略的,默认情况表示⽀持所有语⾔。这个指令隐式的定义了两个cmake变量:_BINARY_DIR以及_SOURCE_DIR。同时cmake系统也帮助我们预定义了PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR变量,他们的值分别跟_BINARY_DIR以及_SOURCE_DIR ⼀致。

为了统⼀起⻅,建议以后直接使⽤PROJECT_BINARY_DIR,PROJECT_SOURCE_DIR,即使修改了⼯程名称,也不会影响这两个变量。如果使⽤了_SOURCE_DIR,修改⼯程名称后,需要同时修改这些变量。

SET

SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])

⽤来显式的定义变量,⽐如SET(SRC_LIST main.c),如果有多个源⽂件,也可以定义成: SET(SRC_LIST main.c t1.c t2.c)。

MESSAGE

MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display" ...)

这个指令⽤于向终端输出⽤户定义的信息,包含了三种类型:

  • SEND_ERROR,产⽣错误,⽣成过程被跳过。
  • SATUS,输出前缀为—的信息。
  • FATAL_ERROR,⽴即终⽌所有cmake 过程.

ADD_EXECUTABLE

ADD_EXECUTABLE(NAME ${SRC_LIST})

定义了这个⼯程会⽣成⼀个⽂件名为NAME的可执⾏⽂件,相关的源⽂件是SRC_LIST中定义的源⽂件列表

ADD_DEFINITIONS

ADD_DEFINITIONS(-DENABLE_DEBUG -DABC),参数之间⽤空格分割

向C/C++编译器添加-D 定义

ADD_DEPENDENCIES

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

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

ENABLE_TESTING

ENABLE_TESTING 指令⽤来控制 Makefile 是否构建test ⽬标,涉及⼯程所有⽬录。语 法很简单,没有任何参数,ENABLE_TESTING(),⼀般情况这个指令放在⼯程的主 CMakeLists.txt 中.

ADD_TEST

ADD_TEST(testname Exename arg1 arg2 ...)

testname 是⾃定义的test名称,Exename可以是构建的⽬标⽂件也可以是外部脚本等等。后⾯连接传递给可执⾏⽂件的参数。如果没有在同⼀个CMakeLists.txt中打开ENABLE_TESTING()指令,任何 ADD_TEST 都是⽆效的。

AUX_SOURCE_DIRECTORY

AUX_SOURCE_DIRECTORY(dir VARIABLE)

作⽤是发现⼀个⽬录下所有的源代码⽂件并将列表存储在⼀个变量中,这个指令临时被⽤来⾃动构建源⽂ 件列表。因为⽬前cmake 还不能⾃动发现新添加的源⽂件。

ADD_SUBDIRECTORY

ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

这个指令⽤于向当前⼯程添加存放源⽂件的⼦⽬录,并可以指定中间⼆进制和⽬标⼆进制存放的位置。 EXCLUDE_FROM_ALL参数的含义是将这个⽬录从编译过程中排除,⽐如⼯程的example,可能就需 要⼯程构建完成后,再进⼊example⽬录单独进⾏构建(当然,你也可以通过定义依赖来解决此类问题)。

ADD_LIBRARY

ADD_LIBRARY(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN)

类型有三种:

  • SHARED,动态库
  • STATIC,静态库
  • MODULE,在使⽤ dyld 的系统有效,如果不⽀持dyld,则被当作SHARED 对待

EXCLUDE_FROM_ALL 参数的意思是这个库不会被默认构建,除⾮有其他的组件依赖或者⼿⼯构建。

SET_TARGET_PROPERTIES

SET_TARGET_PROPERTIES(target1 target2 ... 
    PROPERTIES prop1 value1 prop2 value2 ...)

这条指令可以⽤来设置输出的名称,对于动态库,还可以⽤来指定动态库版本和 API 版本

GET_TARGET_PROPERTY

GET_TARGET_PROPERTY(OUTPUT_VALUE target OUTPUT_NAME)

获取目标相关属性值

INSTALL

INSTALL 指令⽤于定义安装规则,安装的内容可以包括⽬标⼆进制、动态库、静态库以及⽂件、⽬录、脚本等。

目标文件安装
INSTALL(TARGETS targets... 
    [[ARCHIVE|LIBRARY|RUNTIME] 
    [DESTINATION <dir>] 
    [PERMISSIONS permissions...] 
    [CONFIGURATIONS [Debug|Release|...]] 
    [COMPONENT <component>] 
    [OPTIONAL] ] [...])
  1. 参数中的TARGETS 后⾯跟的就是我们通过ADD_EXECUTABLE或者ADD_LIBRARY定义的⽬标⽂件, 可能是可执⾏⼆进制、动态库、静态库。
  2. ⽬标类型相对应的有三种,ARCHIVE特指静态库,LIBRARY特指动态库,RUNTIME特指可执⾏⽬ 标⼆进制。
  3. DESTINATION 定义了安装的路径,如果路径以/开头,那么指的是绝对路径,这时候CMAKE_INSTALL_PREFIX 其实就⽆效了。如果你希望使⽤CMAKE_INSTALL_PREFIX来定义安装路径,就要写成相对路径,即不要以/开头,那么安装后的路径就是${CMAKE_INSTALL_PREFIX}/<DESTINATION 定义的路径>。
普通文件安装
INSTALL(FILES files... DESTINATION <dir> 
    [PERMISSIONS permissions...] 
    [CONFIGURATIONS [Debug|Release|...]] 
    [COMPONENT <component>] 
    [RENAME <name>] 
    [OPTIONAL])

可⽤于安装⼀般⽂件,并可以指定访问权限,⽂件名是此指令所在路径下的相对路径。如果默认不定义权 限PERMISSIONS,安装后的权限为:OWNER_WRITE,OWNER_READ,GROUP_READ,和WORLD_READ,即 644 权限。

⾮⽬标⽂件的可执⾏程序安装(⽐如脚本之类)

INSTALL(PROGRAMS files... DESTINATION <dir> 
    [PERMISSIONS permissions...] 
    [CONFIGURATIONS [Debug|Release|...]] 
    [COMPONENT <component>] 
    [RENAME <name>] 
    [OPTIONAL])

跟上⾯的FILES 指令使⽤⽅法⼀样,唯⼀的不同是安装后权限为:OWNER_EXECUTE,GROUP_EXECUTE, 和WORLD_EXECUTE,即755权限。

⽬录的安装
INSTALL(DIRECTORY dirs... DESTINATION <dir> 
    [FILE_PERMISSIONS permissions...] 
    [DIRECTORY_PERMISSIONS permissions...] 
    [USE_SOURCE_PERMISSIONS] [CONFIGURATIONS [Debug|Release|...]] 
    [COMPONENT <component>] [[PATTERN <pattern> | REGEX <regex>] 
    [EXCLUDE] [PERMISSIONS permissions...]] [...])

DIRECTORY 后⾯连接的是所在Source⽬录的相对路径,但务必注意:abc和abc/有很⼤的区别。 如果⽬录名不以/结尾,那么这个⽬录将被安装为⽬标路径下的abc,如果⽬录名以/结尾,代表将这个⽬录 中的内容安装到⽬标路径,但不包括这个⽬录本身。

PATTERN ⽤于使⽤正则表达式进⾏过滤。

PERMISSIONS ⽤于指定PATTERN 过滤后的⽂件权限。

如:

INSTALL(DIRECTORY icons scripts/ DESTINATION 
    share/myproj PATTERN "CVS" EXCLUDE PATTERN "scripts/*" 
    PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ)

解释:将 icons ⽬录安装到/share/myproj,将scripts/中的内容安装到/share/myproj 不包含⽬录名为 CVS 的⽬录,对于scripts/*⽂件指定权限为OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ

安装时执行脚本
INSTALL([[SCRIPT <file>] [CODE <code>]] [...])

SCRIPT 参数⽤于在安装时调⽤cmake 脚本⽂件(也就是.cmake ⽂件)

CODE 参数⽤于执⾏CMAKE 指令,必须以双引号括起来。

INCLUDE_DIRECTORIES

INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)

这条指令可以⽤来向⼯程添加多个特定的头⽂件搜索路径,路径之间⽤空格分割,如果路径中包含了空 格,可以使⽤双引号将它括起来,默认的⾏为是追加到当前的头⽂件搜索路径的后⾯,你可以通过两种⽅ 式来进⾏控制搜索路径添加的⽅式:

  1. CMAKE_INCLUDE_DIRECTORIES_BEFORE,通过SET 这个cmake变量为on,可以将添加的头⽂ 件搜索路径放在已有路径的前⾯。
  2. 通过AFTER 或者BEFORE 参数,也可以控制是追加还是置前。

LINK_DIRECTORIES

LINK_DIRECTORIES(directory1 directory2 ...)

添加⾮标准的共享库搜索路径,⽐如,在⼯程内部同时存在共享库和可执⾏⼆进制, 在编译时就需要指定⼀下这些共享库的路径。

TARGET_LINK_LIBRARIES

TARGET_LINK_LIBRARIES(target library1 <debug | optimized> library2 ...)

这个指令可以⽤来为target添加需要链接的共享库.

EXEC_PROGRAM

EXEC_PROGRAM(Executable 
    [directory in which to run] 
    [ARGS <arguments to executable>] 
    [OUTPUT_VARIABLE <var>] 
    [RETURN_VALUE <var>])

⽤于在指定的⽬录运⾏某个程序,通过ARGS添加参数,如果要获取输出和返回值,可通过OUTPUT_VARIABLE 和RETURN_VALUE 分别定义两个变量.

FILE

FILE(WRITE filename "message to write"... )
FILE(APPEND filename "message to write"... )
FILE(READ filename variable)
FILE(GLOB variable [RELATIVE path] [globbing expressions]...)
FILE(GLOB_RECURSE variable [RELATIVE path] [globbing expressions]...)
FILE(REMOVE [directory]...)
FILE(REMOVE_RECURSE [directory]...)
FILE(MAKE_DIRECTORY [directory]...)
FILE(RELATIVE_PATH variable directory file)
FILE(TO_CMAKE_PATH path result)
FILE(TO_NATIVE_PATH path result)

INCLUDE

INCLUDE(file1 [OPTIONAL])

⽤来载⼊CMakeLists.txt ⽂件,也⽤于载⼊预定义的cmake 模块

$ENV{NAME}

调⽤系统的环境变量

如:

MESSAGE(STATUS “HOME dir: $ENV{HOME}”)

SET(ENV{变量名} 值)

设置环境变量

FIND_

FIND_FILE(<VAR> name1 path1 path2 ...)
FIND_LIBRARY(<VAR> name1 path1 path2 ...)
FIND_PATH(<VAR> name1 path1 path2 ...)
FIND_PROGRAM(<VAR> name1 path1 path2 ...)
FIND_PACKAGE(<name> [major.minor] [QUIET] [NO_MODULE] [[REQUIRED|COMPONENTS] [componets...]])

系统信息

  1. CMAKE_MAJOR_VERSION,CMAKE 主版本号,⽐如2.4.6 中的2
  2. CMAKE_MINOR_VERSION,CMAKE 次版本号,⽐如2.4.6 中的4
  3. CMAKE_PATCH_VERSION,CMAKE 补丁等级,⽐如2.4.6 中的6
  4. CMAKE_SYSTEM,系统名称,⽐如Linux-2.6.22
  5. CMAKE_SYSTEM_NAME,不包含版本的系统名,⽐如Linux
  6. CMAKE_SYSTEM_VERSION,系统版本,⽐如 2.6.22
  7. CMAKE_SYSTEM_PROCESSOR,处理器名称,⽐如i686. 8,UNIX,在所有的类 UNIX 平台为 TRUE,包括OS X 和cygwin 9,WIN32,在所有的 win32 平台为 TRUE,包括cygwin

开关选项

CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS

⽤来控制IF ELSE 语句的书写⽅式

BUILD_SHARED_LIBS

⽤来控制默认的库编译⽅式,如果不进⾏设置,使⽤ ADD_LIBRARY并没有指定库类型的情况 下,默认编译⽣成的库都是静态库。如果SET(BUILD_SHARED_LIBS ON)后,默认⽣成的为动态库。

CMAKE_C_FLAGS

设置C 编译选项,也可以通过指令 ADD_DEFINITIONS()添加。

CMAKE_CXX_FLAGS

设置C++编译选项,也可以通过指令 ADD_DEFINITIONS()添加。

控制指令

IF ELSEIF

IF(expression) 
# THEN section. COMMAND1(ARGS ...) 
COMMAND2(ARGS ...) 
... 
ELSE(expression) 
# ELSE section. COMMAND1(ARGS ...) COMMAND2(ARGS ...) 
...
ENDIF(expression)
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),当给定的变量或者字符串能够匹配正则表达式 regex 时为真

IF(variable LESS number),小于

IF(variable GREATER number),大于

IF(variable EQUAL number),等于

IF(variable STRLESS string),字符串小于

IF(variable STRGREATER string),字符串大于

IF(variable STREQUAL string),字符串等于

IF(DEFINED variable),如果变量被定义

WHILE

WHILE(condition)
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
ENDWHILE(condition)

FOREACH

列表
FOREACH(loop_var arg1 arg2 ...)
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
ENDFOREACH(loop_var)
范围
FOREACH(loop_var RANGE total)
ENDFOREACH(loop_var)
范围和步进
FOREACH(loop_var RANGE start stop [step])
ENDFOREACH(loop_var)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

果丶果

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值