cmake学习记录

本文详细介绍了CMake的学习过程,包括关键指令的使用方法,如`include`、`set`、`configure_file`、`add_definitions`、`add_compile_options`、`option`、`file`等。同时,讲解了`add_subdirectory`、`include_directories`、`find_library`、`target_compile_options`、`add_library`和`target_link_libraries`等命令的用途,帮助读者深入理解CMake构建软件的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注意点

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} 变量;

示例

cmake学习之-configure_file - 洒水先生 - 博客园

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

其他:

CMakeFile命令之file_P.TAN的博客-优快云博客_cmake file

file — CMake 3.0.2 Documentation

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][...]:链接外部库文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值