一.CMake中常用预定义变量
1.CMake的预定义变量
- PROJECT_SOURCE_DIR:⼯程根⽬录;
- PROJECT_BINARY_DIR:运⾏cmake命令的⽬录。笔者建议定义为${PROJECT_SOURCE_DIR}/build下。具体原因见后⽂外部编译部分;
- CMAKE_INCLUDE_PATH:环境变量,⾮cmake变量;
- CMAKE_LIBRARY_PATH:环境变量;
- CMAKE_CURRENT_SOURCE_DIR:当前处理的CMakeLists.txt⽂件所在路径;
- CMAKE_CURRENT_BINARY_DIR:target编译⽬录;
- 使⽤ADD_SURDIRECTORY指令可以更改该变量的值;
- SET(EXECUTABLE_OUTPUT_PATH < dir >) 指令不会对该变量有影响,但改变了最终⽬标⽂件的存储路径;
- CMAKE_CURRENT_LIST_FILE:输出调⽤该变量的CMakeLists.txt的完整路径;
- CMAKE_CURRENT_LIST_LINE:输出该变量所在的⾏;
- CMAKE_MODULE_PATH:定义⾃⼰的cmake模块所在路径;
- EXECUTABLE_OUTPUT_PATH:重新定义⽬标⼆进制可执⾏⽂件的存放位置;
- LIBRARY_OUTPUT_PATH:重新定义⽬标链接库⽂件的存放位置;
- PROJECT_NAME:返回由PROJECT指令定义的项⽬名称;
- CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS:⽤来控制IF…ELSE…语句的书写⽅式;
2.系统信息预定义的变量
- CMAKE_MAJOR_VERSION cmake主版本号,如2.8.6中的2
- CMAKE_MINOR_VERSION cmake次版本号,如2.8.6中的8
- CMAKE_PATCH_VERSION cmake补丁等级,如2.8.6中的6
- CMAKE_SYSTEM 系统名称,例如Linux-2.6.22
- CMAKE_SYSTEM_NAME 不包含版本的系统名,如Linux
- CMAKE_SYSTEM_VERSION 系统版本,如2.6.22
- CMAKE_SYSTEM_PROCESSOR 处理器名称,如i686
- UNIX 在所有的类UNIX平台为TRUE,包括OS X和cygwin
- WIN32 在所有的win32平台为TRUE,包括cygwin
3.开关选项变量
- BUILD_SHARED_LIBS 控制默认的库编译⽅式。
- 注:如果未进⾏设置,使⽤ADD_LIBRARY时⼜没有指定库类型,默认编译⽣成的库都是静态库。
- CMAKE_C_FLAGS 设置C编译选项
- CMAKE_CXX_FLAGS 设置C++编译选项
二.CMake常用语法
-
CMAKE_MINIMUM_REQUIRED
# cmake的最低版本⾄少为2.6。 cmake_minimum_required (VERSION 2.6)
该语句⼀般都可以放置在CMakeLists.txt的开头,⽤于说明CMake最低版本要求。
这⾏命令是可选的,我们可以不写这句话,但在有些情况下,如果CMakeLists.txt⽂件中使⽤了⼀些⾼版本cmake特有的⼀些命令的时候,就需要加上这样⼀⾏,提醒⽤户升级到该版本之后再执⾏cmake。 -
PROJECT
该指令⼀般置于CMakeLists.txt的开头,定义了⼯程的名称。执⾏了该条指令之后,将会⾃动创建两个变量:
-
< projectname >_BINARY_DIR:⼆进制⽂件保存路径;
-
< projectname >_SOURCE_DIR:源代码路径;
project(CRNode) # 执⾏了上⼀条指令,即定义了⼀个项⽬名称CRNode, # 相应的会⽣成两个变量:CRNode_BINARY_DIR, CRNode_SOURCE_DIR
cmake中预定义了两个变量:PROJECT_BINARY_DIR与PROJECT_SOURCE_DIR。
在这个例⼦中:- PROJECT_BINARY_DIR = CRNode_BINARY_DIR
- PROJECT_SOURCE_DIR = CRNode_SOURCE_DIR
笔者强烈推荐直接使⽤PROJECT_BINARY_DIR与PROJECT_SOURCE_DIR,这样及时项⽬名称发⽣了变化,也不会影响CMakeLists.txt⽂件。
关于上⾯两个变量是否相同的问题,涉及到编译⽅法是内部编译还是外部编译。如果是内部编译,则上⾯两个变量相同;如果是外部编译,则两个变量不同。此处对内部编译与外部编译做出介绍:
(1) 外部构建与内部构建
假设此时已经完成了CMakeLists.txt的编写,在CMakeLists.txt所在⽬录下,有两种执⾏cmake的⽅法:
cmake ./ make
以及:
mkdir build cd ./build cmake ../ make
第⼀种⽅法是内部构建,第⼆种⽅法是外部构建。上述两种⽅法中,最⼤不同在于cmake与make的⼯作路径不同。
内部构建⽅法中,cmake⽣成的中间⽂件和可执⾏⽂件都会存放在项⽬⽬录中;外部构建⽅法中,中间⽂件与可执⾏⽂件都存放在build⽬录中。
笔者强烈建议使⽤外部构建⽅法。优点显⽽易见:最⼤限度的保持了代码⽬录的整洁,⽣成、编译与安装是不同于项⽬⽬录的其他⽬录中,在外部构建⽅法下,PROJECT_SOURCE_DIR指向⽬录与内部构建相同,为CMakeLists.txt所在根⽬录;⽽PROJECT_BINARY_DIR不同,它指向CMakeLists.txt所在根⽬录下的build⽬录。 -
-
SET(<变量名> <变量值>)
SET(VAR [VALUE] [CACHE TYPEDOCSTRING [FORCE]])
该例程中,我们显式的将CMAKE_INSTALL_PREFIX的值定义为/usr/local,如此在外部构建情况下执⾏make install命令时,make会将⽣成的可执⾏⽂件拷贝到/usr/local/bin⽬录下。
-
ADD_SUBDIRECTORY
这个指令⽤于向当前⼯程添加存放源⽂件的⼦⽬录,并可以指定中间⼆进制和⽬标⼆进制存放的位置。EXCLUDE_FROM_ALL 参数的含义是将这个⽬录从编译过程中排除。⽐如,⼯程有时候存在example,可能就需要⼯程构建完成后,再进⼊example⽬录单独进⾏构建。
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
- source_dir:源⽂件路径;
- [binary_dir]:中间⼆进制与⽬标⼆进制存放路径;
- [EXECLUDE_FROM_ALL]:将这个⽬录从编译过程中排除;
-
file()
用于文件的操作
# 读取文件 file(READ <filename> <out-var> [...]) file(STRINGS <filename> <out-var> [...]) file(<HASH> <filename> <out-var>) file(TIMESTAMP <filename> <out-var> [...]) # 写文件 file({ WRITE | APPEND} <filename> <content>...) file({ TOUCH | TOUCH_NOCREATE} [<file>...]) file(GENERATE OUTPUT <output-file> [...]) # 文件系统 file({ GLOB | GLOB_RECURSE} <out-var> [...] [<globbing-expr>...]) file(RENAME <oldname> <newname>) file({ REMOVE | REMOVE_RECURSE } [<files>...]) file(MAKE_DIRECTORY [<dir>...]) file({ COPY | INSTALL} <file>... DESTINATION <dir> [...]) file(SIZE <filename> <out-var>) file(READ_SYMLINK <linkname> <out-var>) file(CREATE_LINK <original> <linkname> [...]) # 路径转换 file(RELATIVE_PATH <out-var> <directory> <file>) file({ TO_CMAKE_PATH | TO_NATIVE_PATH} <path> <out-var>) # 上传下载 file(DOWNLOAD <url> <file> [...]) file(UPLOAD <file> <url> [...]) # 查找 file(LOCK <path> [...])
-
list()
用于对列表的操作
# 返回list的长度 list(LENGTH <list><output variable>) # 返回list中index的element到value中 list(GET <list> <elementindex> [<element index> ...]<output variable>) # 添加新element到list中 list(APPEND <list><element> [<element> ...]) # 返回list中element的index,没有找到返回-1 list(FIND <list> <value><output variable>) # 将新element插入到list中index的位置 list(INSERT <list><element_index> <element> [<element> ...]) # 从list中删除某个element list(REMOVE_ITEM <list> <value>[<value> ...]) # 从list中删除指定index的element list(REMOVE_AT <list><index> [<index> ...]) # 从list中删除重复的element list(REMOVE_DUPLICATES <list>) # 将list的内容反转 list(REVERSE <list>) # 将list按字母顺序排序 list(SORT <list>)
-
option()
option用于控制编译流程,相当于C语言中的宏条件编译
option(<variable> "<help_text>" [value]) variable:定义选项名称 help_text:说明选项的含义 value:定义选项默认状态,一般是OFF或者ON,除去ON之外,其他所有值都为认为是OFF
-
configure_package_config_file()
该命令用于生成xxxCionfig.cmake文件的,其使用方式如下:
configure_package_config_file( <input> <output> INSTALL_DESTINATION <path> [PATH_VARS <var1> <var2> ... <varN>] [NO_SET_AND_CHECK_MACRO] [NO_CHECK_REQUIRED_COMPONENTS_MACRO] [INSTALL_PREFIX <path>] )
- input:文件名,一般为xxxConfig.cmake.in文件,需要自己提供
- output:文件名,一般为xxConfig.cmake文件。其会通过input中的文件进行生成
- INSTALL_DESTINATION:改参数后跟绝对或相对路径,表示output中的文件在install的时候会被装载到那个位置。如果使用相对路径,则其相对于INSTALL_PREFIX所表示的路径
- PATH_VARS:其后跟这变量的名字,这些变量需要在xxxConfig.cmake.in文件中出现。例如变量名 A,则在xxxConfig.cmake.in中要以 @PACKAGE_A@的形式出现。这些变量的作用一般是在xxxConfig.cmake.in生成xxxConfig.cmake的时候进行对应的变量替换
- INSTALL_PREFIX:install时候的prefix path
-
install()
install用于指定在安装时运行的规则。它可以用来安装很多内容,可以包括目标二进制、动态库、静态库以及文件、目录、脚本等
三.常用函数
- find_path 从默认⽬录和指定⽬录查找头⽂件,并返回结果
- find_library 从默认⽬录和指定⽬录查找库⽂件,并返回结果
四.
-
输出所有定义的变量
get_cmake_property(_variableNames VARIABLES) foreach (_variableName ${_variableNames}) message(STATUS "${_variableName}=${${_variableName}}") endforeach()