注意点
1.cmake指令不区分大小写
2.变量使用${} 方式取值,但是在if控制语句中直接使用变量名
3.指令(参数1 参数2 ...),参数使用括号起,参数之间使用空格或者分号隔开
CMAKE_SOURCE_DIR
工程源代码所在根目录,主工程CMakeLists.txt所在目录
CMAK_BINARY_DIR
主工程编译发生的目录
include
加载和运行指定CMake文件/模块
格式:
include(<file|module> [OPTIONAL] [RESULT_VARIABLE <VAR>][NO_POLICY_SCOPE])
- OPTIONAL:如果设置,指定文件不存在也不会报错
- RESULT_VARIABLE <VAR> 如果指定文件存在,<VAR>的值指向文件完整文件名,如果不存在,值为NOTFOUND
set
设置变量
格式:
set(<variable> <value> [[CACHE <type> <docstring> [FORCE]] | PARENT_SCOPE])
configure_file
格式:
configure_file(<input> <output> [COPYONLY] [ESCAPE_QUOTES] [@ONLY] [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
- COPYONLY:仅拷贝<input>文件里的内容到<output>文件,不进行变量替换
- ESCAPE_QUOTES:使用反斜杠(C语言风格)来进行转义
- @ONLY:限制替换, 仅仅替换
@VAR@
变量, 不替换${VAR}
变量- NEWLINE_STYLE:指定输入文件的新行格式, 例如:Unix 中使用的是
\n
, windows 中使用的\r\n
COPYONLY
和NEWLINE_STYLE
是冲突的,不能同时使用将
<input>
文件里面的内容全部复制到<output>
文件中;根据参数规则,替换@VAR@
或${VAR}
变量;示例
add_definitions
向 C/C++编译器添加-D 定义,比如:
ADD_DEFINITIONS(-DENABLE_DEBUG -DABC),参数之间用空格分割。
add_compile_options
设置编译选项
在cmake脚本中,设置编译选项可以通过add_compile_options命令,也可以通过set命令修改CMAKE_CXX_FLAGS或CMAKE_C_FLAGS。
使用这两种方式在有的情况下效果是一样的,但请注意它们还是有区别的:
add_compile_options命令添加的编译选项是针对所有编译器的(包括c和c++编译器),而set命令设置CMAKE_C_FLAGS或CMAKE_CXX_FLAGS变量则是分别只针对c和c++编译器的。
option
格式:
option(<option_variable> "help string describing option" [initial value])
- option_variable:选项名
- help string describing option:描述
- initial value 选项初始化值(除ON外全为OFF)
option起到编译开关的作用,CMakeLists.txt中option以前的语句,变量按未定义处理,option之后的语句,变量才被定义。另外,注意,option命令定义的变量不影响c或c++源码中#ifdef或者#ifndef逻辑判断
file
格式:
file(WRITE filename "message to write"... )
file(APPEND filename "message to write"... )
file(READ filename variable [LIMIT numBytes] [OFFSET offset] [HEX]) file(<MD5|SHA1|SHA224|SHA256|SHA384|SHA512> filename variable)
file(STRINGS filename variable [LIMIT_COUNT num] [LIMIT_INPUT numBytes] [LIMIT_OUTPUT numBytes] [LENGTH_MINIMUM numBytes] [LENGTH_MAXIMUM numBytes] [NEWLINE_CONSUME] [REGEX regex] [NO_HEX_CONVERSION]) file(GLOB variable [RELATIVE path] [globbing expressions]...)
file(GLOB_RECURSE variable [RELATIVE path] [FOLLOW_SYMLINKS] [globbing expressions]...)
file(RENAME <oldname> <newname>)
file(REMOVE [file1 ...])
file(REMOVE_RECURSE [file1 ...])
file(MAKE_DIRECTORY [directory1 directory2 ...])
file(RELATIVE_PATH variable directory file)
file(TO_CMAKE_PATH path result)
file(TO_NATIVE_PATH path result)
file(DOWNLOAD url file [INACTIVITY_TIMEOUT timeout] [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS] [EXPECTED_HASH ALGO=value] [EXPECTED_MD5 sum] [TLS_VERIFY on|off] [TLS_CAINFO file])
file(UPLOAD filename url [INACTIVITY_TIMEOUT timeout] [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS])
file(TIMESTAMP filename variable [<format string>] [UTC])
file(GENERATE OUTPUT output_file <INPUT input_file|CONTENT input_content> [CONDITION expression])
GLOB 会产生一个由所有匹配globbing表达式的文件组成的列表,并将其保存到变量中。Globbing 表达式与正则表达式类似,但更简单。如果指定了RELATIVE 标记,返回的结果将是与指定的路径相对的路径构成的列表。 (通常不推荐使用GLOB命令来从源码树中收集源文件列表。原因是:如果CMakeLists.txt文件没有改变,即便在该源码树中添加或删除文件,产生的构建系统也不会知道何时该要求CMake重新产生构建文件。globbing 表达式包括:
*.cxx - match all files with extension cxx
*.vt? - match all files with extension vta,...,vtz
f[3-5].txt - match files f3.txt,f4.txt, f5.txt其他:
add_subdirectory
添加一个子目录并构建该子目录
格式:
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL]
- source_dir:必选参数,该参数指定一个子目录,子目录下应该包含
CMakeLists.txt
文件和代码文件。子目录可以是相对路径也可以是绝对路径,如果是相对路径,则是相对当前目录的一个相对路径;- [binary_dir]:可选参数,该参数指定一个目录,用于存放输出文件。可以是相对路径也可以是绝对路径,如果是相对路径,则是相对当前输出目录的一个相对路径。如果该参数没有指定,则默认的输出目录使用
source_dir;
- [EXECLUDE_FROM_ALL]:可选参数,当指定了该参数,则子目录下的目标不会被父目录下的目标文件包含进去,父目录的
CMakeLists.txt
不会构建子目录的目标文件,必须在子目录下显式去构建。例外情况:当父目录的目标依赖于子目录的目标,则子目录的目标仍然会被构建出来以满足依赖关系(例如使用了target_link_libraries)
include_directories
向工程添加多个特定的头文件搜索路径,路径之间用空格分隔。类似于gcc中的编译参数<code>-l</code>,即指定编译过程中编译器搜索头文件的路径。当项目需要的头文件不在系统默认的搜索路径时,则指定该路径。
格式:
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
- [AFTER|BEFORE]:追加标志,指定控制追加或置前,默认情况下,追加当前头文件搜索路径的后面。注:如果路径包含空格,可以使用双引号将它括起来。
- [SYSTEM]:如果设置,编辑器会把指定目录当成系统头文件搜索路径
- dir1, ..., dir n:添加的一系列头文件搜索路径;
find_library
查找库
格式:
find_library (<VAR> name1 [path1 path2 ...])
- <VAR>: 如果找到库,则结果存储在变量中,并且搜索不会重复,除非该变量被清除。如果没有找到,结果将是< VAR >-NOTFOUND
- name:库名字
- [path1 path2 ...]: 可选参数,查找路径
target_compile_options
给指定对象设置编译配置
格式:
target_compile_options(<target> [BEFORE] <INTERFACE|PUBLIC|PRIVATE> [items1...] [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
- <target>:指定对象,<target>必须是由add_executable() 或者add_library()创建
- <INTERFACE|PUBLIC|PRIVATE>:指定 [items...] 选项可以传播的范围, PUBLIC and INTERFACE 会传播 <target> 的 INTERFACE_COMPILE_DEFINITIONS 属性, PRIVATE and PUBLIC 会传播 <target> 的 COMPILE_DEFINITIONS 属性
add_library
格式:
add_library(<name> [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] [source1] [source2 ] [...])
构建库
- <name>:库文件名称
- [STATIC | SHARED | MODULE]:指定库类型:STATIC库是目标文件的归档文件,在链接其它目标的时候使用。SHARED库会被动态链接(动态链接库),在运行时会被加载。MODULE库是一种不会被链接到其它目标中的插件,但是可能会在运行时使用dlopen-系列的函数。
- [source1] [source2] [...]:源文件
add_library(<name> <SHARED|STATIC|MODULE|UNKNOWN> IMPORTED [GLOBAL])
导入预构建库
- <name>:库文件名称
- [STATIC | SHARED | MODULE]:指定库类型:STATIC库是目标文件的归档文件,在链接其它目标的时候使用。SHARED库会被动态链接(动态链接库),在运行时会被加载。MODULE库是一种不会被链接到其它目标中的插件,但是可能会在运行时使用dlopen-系列的函数
- IMPORTED:标识要导入库。导入路径可以由set_target_properties()指定。如
add_library( imported-lib SHARED IMPORTED )set_target_properties( # Specifies the target library. imported-lib # Specifies the parameter you want to define. PROPERTIES IMPORTED_LOCATION # Provides the path to the library you want to import. imported-lib/src/${ANDROID_ABI}/libimported-lib.so )- [GLOBAL]:指定库的查找范围为当前工程构建的的所有库
target_link_libraries
指定链接目标言论的需要链接的外部库
格式:
target_link_libraries(<target> [item1] [item2] [...] [[debug|optimized|general] <item>] ...)
- target:目标文件
- [item1][item2][...]:链接外部库文件