CMake学习记录
宏
macro (do_test arg1 arg2 result)
add_test (test_${arg1}_${arg2} Demo ${arg1} ${arg2})
set_tests_properties (test_${arg1}_${arg2}
PROPERTIES PASS_REGULAR_EXPRESSION ${result})
endmacro (do_test)
- 描述:
macro(宏名 参数列表)
可以定义一个宏 - 第一个参数:宏名
- 其余参数:在宏当中使用的变量名
- 示例作用:定义一个宏简化测试代码的编写,
add_test
用于添加一个测试
条件语句
if语句
if(condition)
Tab...
else()
Tab...
endif(condition)
常用指令
add_definitions
add_definitions(-DFOO -DBAR=123)
- 描述:
add_definitions
是 CMake 中用来 **批量向所有目标(可执行文件、库)添加编译宏定义(** -D
选项) 的命令。
实际传给编译器 | 含义 |
---|---|
-DFOO |
定义宏 FOO (空值) |
-DBAR=123 |
定义宏 BAR 为 123 |
相当于添加了:
#define FOO
#define BAR 123
add_library
add_library(function STATIC
src/hello.cpp
)
-
描述:使用一些源文件生成库
-
第一个参数:库名,实际生成的名字为
libfunction.xxx
-
第二个参数:决定生成的库是动态库还是静态库,没有则默认静态
-
第三个参数:生成库的源文件
add_excutable
add_executable(Demo ${DIR_SRCS})
- 描述:使用一些源文件编译并链接成一个可执行程序
add_subdirectory
add_subdirectory(math)
- 描述:将一个子目录添加到构建系统中
- 参数:子目录名称
- 示例代码作用:将math子目录中的CMakeLists.txt文件解析并加入到构建系统中
aux_source_directory
aux_source_directory(<dir> <variable>)
- 描述:自动获取指定目录中的所有源文件,并将这些文件存储到一个变量中
configure_file
configure_file(
"${PROJECT_SOURCE_DIR}/config.h.in"
"${PROJECT_BINARY_DIR}/config.h"
)
-
描述:将一个输入文件(通常是模板文件)配置为输出文件,它会根据CMake变量的值替换输入文件(模板文件)中的占位符,生成最终的配置文件
-
第一个参数:模板文件,通常以
.in
为后缀 -
第二个参数:输出的配置文件
-
注意点:
- 模版文件后缀并非强制要求
in
,只是一种约定 - 模版文件需要我们自己预先定义好
- 生成的文件可以是源文件(如.h、.c、.cpp等),是也可以其他类型的文件(如配置文件等)
- 模版文件后缀并非强制要求
execute_process
execute_process(
COMMAND git rev-parse HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE FULL_SHA
OUTPUT_STRIP_TRAILING_WHITESPACE
)
关键字 / 参数 | 含义 |
---|---|
execute_process |
CMake 提供的命令,用于 在配置阶段执行一条或多条外部命令。 |
COMMAND git rev-parse HEAD |
要执行的命令:运行 git rev-parse HEAD ,获取当前 Git 仓库的 完整 SHA 哈希值。 |
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} |
指定命令的运行目录为项目根目录${CMAKE_SOURCE_DIR} 。 |
OUTPUT_VARIABLE FULL_SHA |
把命令的标准输出(stdout)保存到 CMake 变量 FULL_SHA 。 |
OUTPUT_STRIP_TRAILING_WHITESPACE |
自动去掉输出FULL_SHA 末尾的换行符或空格,避免后面使用时出现 \n 。 |
find_package
find_package(<PackageName> [version] [REQUIRED] [COMPONENTS <c1> <c2>...])
- 描述:
find_package
是 CMake 最重要、最常用的模块查找指令之一,用来在系统中“找到”某个第三方库或工具链,并自动为你设置头文件目录、库文件目录、库名称等变量,省去手动写include_directories()
、target_link_libraries()
的麻烦。
参数 | 说明 |
---|---|
<PackageName> |
模块名,大小写不敏感,如 OpenSSL , Boost , Threads |
[version] |
可指定最低版本,如 3.1.0 |
REQUIRED |
找不到就报错,构建停止 |
COMPONENTS |
只找其中某些组件,如 COMPONENTS system filesystem |
模式 | 描述 | 文件来源 |
---|---|---|
Module 模式 | 使用 CMake 自带的 Find<PackageName>.cmake 脚本 |
<cmake prefix>/Modules/ |
Config 模式 | 使用库自己提供的 <PackageName>Config.cmake 或 <PackageName>-config.cmake |
库安装目录的 lib/cmake/<PackageName>/ |
- CMake 先尝试 Module,再尝试 Config。
成功后会生成哪些变量?
以 find_package(OpenSSL REQUIRED)
为例:
变量 | 内容 |
---|---|
OPENSSL_FOUND |
TRUE |
OPENSSL_INCLUDE_DIR |
/usr/include/openssl |
OPENSSL_LIBRARIES |
/usr/lib/libssl.so;/usr/lib/libcrypto.so |
OPENSSL_VERSION |
1.1.1w |
你可以直接用:
target_include_directories(myapp PRIVATE ${OPENSSL_INCLUDE_DIR})
target_link_libraries(myapp PRIVATE ${OPENSSL_LIBRARIES})
一个典型用法示例
find_package(PkgConfig REQUIRED) pkg_check_modules(GIO REQUIRED gio-unix-2.0)
target_include_directories(my_app PRIVATE ${GIO_INCLUDE_DIRS})
target_link_libraries (my_app PRIVATE ${GIO_LIBRARIES})
-
find_package(PkgConfig REQUIRED)
- 作用:让 CMake 先找到
pkg-config
这个 系统小工具(Linux 下通常是/usr/bin/pkg-config
)。 -
REQUIRED
:如果系统没装pkg-config
,立即报错停止。 - 成功后,
PkgConfig
模块会提供pkg_check_modules()
命令。
- 作用:让 CMake 先找到
-
pkg_check_modules(GIO REQUIRED gio-unix-2.0)
-
作用:等价于在终端执行
pkg-config --cflags --libs gio-unix-2.0
。 -
结果(自动生成以下变量):
变量名 内容示例(Linux) GIO_FOUND
1
GIO_INCLUDE_DIRS
/usr/include/gio-unix-2.0;/usr/include/glib-2.0;...
GIO_LIBRARY_DIRS
/usr/lib/x86_64-linux-gnu
GIO_LIBRARIES
gio-2.0;gobject-2.0;glib-2.0
GIO_CFLAGS_OTHER
-DGLIB_VERSION_...
等额外编译标志
-
install
安装可执行文件
install(TARGETS <target> [CONFIGURATIONS <config>...] DESTINATION <dir>)
- 描述:将编译出来的可执行文件target安装到目录dir中
安装文件
install(FILES <file>... DESTINATION <dir>)
- 将文件安装到目录中
安装目录
install(DIRECTORY <dir> DESTINATION <dir>
[FILE_PERMISSIONS ...]
[DIRECTORY_PERMISSIONS ...]
[PATTERN ... EXCLUDE/INCLUDE])
- 将整个目录安装到目标目录中,并【可选的】配置安装的目录文件访问权限
- 如果只想装
.so
,加FILES_MATCHING PATTERN "*.so*"
。 - 目录末尾加
/
表示只装目录里的内容;不加会把目录本身也复制过去。
include_directories
include_directories("${PROJECT_SOURCE_DIR}/math")
- 描述:用于将指定的目录添加到编译器的头文件搜索路径中
- 参数:路径
- 示例代码作用:告诉编译器在编译时,将
${PROJECT_SOURCE_DIR}/math
目录中的头文件包含进来。
option
option(USE_MYMATH "Use provided math implementation" ON)
- 描述:定义一个布尔值配置选项
- 第一个参数:选项的名称,可以通过命令行来设置它的值
- 第二个参数:选项的描述信息
- 第三个参数:选项的默认值,
ON
表示默认启用,OFF
表示禁用 - 补充说明:可以通过
ccmake
命令进入配置界面,按c
可以配置相关选项,option
定义的变量可以在此配置选项
set
set(EXTRA_LIB ${EXTRA_LIBS} MathFunctions)
-
描述:这种三参数写法是追加设置变量的值。
- 它可以用来创建新变量,也可以修改现有变量的值。
-
第一个参数:要设置的变量,如果没有则创建
-
第二个参数:引用要设置的变量,将给该变量赋值,若是该变量已有值,则追加赋值
-
第三个参数:要赋给变量的值
set(variable value)
-
描述:给变量赋值
- 它可以用来创建新变量,也可以修改现有变量的值
string
string(<SUBCOMMAND> <arg1> <arg2> ...)
-
string是CMake的字符串处理命令,它有许多子命令,用来完成查找、替换、截取、正则、大小写转换等操作
-
子命令开头决定功能,倒数第二个变量是输出变量,倒数第一个变量是输入变量
-
子命令一览
子命令 | 作用 | 示例 |
---|---|---|
REGEX MATCH | 正则匹配一次 | string(REGEX MATCH "pat" out "${str}") |
REGEX MATCHALL | 正则匹配所有 | string(REGEX MATCHALL "pat" out "${str}") |
REGEX REPLACE | 正则替换 | string(REGEX REPLACE "pat" "repl" out "${str}") |
REPLACE | 普通字符串替换 | string(REPLACE "old" "new" out "${str}") |
SUBSTRING | 截取子串 | string(SUBSTRING "${str}" 0 3 out) |
STRIP | 去掉首尾空格 | string(STRIP "${str}" out) |
TOLOWER / TOUPPER | 大小写转换 | string(TOLOWER "${str}" out) |
COMPARE EQUAL / LESS / GREATER | 字典序比较 | string(COMPARE EQUAL "${a}" "${b}" result) |
LENGTH | 取字符串长度 | string(LENGTH "${str}" len) |
target_link_libraries
target_link_libraries(<target>
[PRIVATE|PUBLIC|INTERFACE ...] <library1> [library2 ...])
- 描述:将目标与所需的库进行链接
测试命令
add_test与set_tests_properties
要启用测试,需在测试用例代码前添加enable_testing()
启用测试功能。
add_test(test_5_2 Demo 5 2)
set_tests_properties(test_5_2 PROPERTIES PASS_REGULAR_EXPRESSION
"is 25")
-
add_test
- 描述:add_test用于添加一个测试用例
- 第一个参数:测试用例名称
- 第二个参数:可执行文件名称
- 第三个参数:传递给第二个参数的参数列表
-
set_tests_properties
-
描述:用于设置测试用例的属性。它允许你为测试用例配置各种属性,例如预期输出、超时时间等。
-
第一个参数:测试用例名称,必须是已经被
add_test
定义的 -
PROPERTIES
关键字:表示接下来是属性的设置。 -
常见属性:
-
PASS_REGULAR_EXPRESSION
:测试通过时输出必须匹配的正则表达式。 -
FAIL_REGULAR_EXPRESSION
:测试失败时输出必须匹配的正则表达式。 -
TIMEOUT
:测试超时时间(秒)。 -
WILL_FAIL
:测试是否预期失败。 -
RUN_SERIAL
:测试是否需要串行运行。
-
-
跟在属性后面的参数:类型为字符串或数字,表示属性的值
-
内置变量
my_project/
├── CMakeLists.txt
├── src/
│ ├── main.cpp
│ └── ...
├── include/
│ └── ...
└── ...
${PROJECT_SOURCE_DIR}
- 这个变量表示当前项目的源代码目录的路径。如上目录结构中,
${PROJECT_SOURCE_DIR}
就是my_project
的绝对地址 - 它是由 CMake 在解析
CMakeLists.txt
文件时自动设置的,不需要用户手动定义。 - 它的值是项目根目录的绝对路径,即包含顶级
CMakeLists.txt
文件的目录。
${PROJECT_BINARY_DIR}
-
${PROJECT_BINARY_DIR}
是CMake变量,表示项目的构建目录。 - 通常表示的是源文件编译输出的文件目录
${CMAKE_SOURCE_DIR}
- 与
${PROJECT_SOURCE_DIR}
类似,但更通用。它表示最顶层CMakeLists.txt
文件所在的目录。 - 大多数时候,
${PROJECT_SOURCE_DIR}
与${CMAKE_SOURCE_DIR}
表示相同的路径,如上所示目录结构中,两者就是等价的。
${CMAKE_BINARY_DIR}
- 与
${PROJECT_BINARY_DIR}
类似,表示最顶层构建目录的路径。
$ENV{VAR_NAME}
- 描述:读取当前进程的系统环境变量
VAR_NAME
的值 - 单独的
$ENV
在CMAKE中是无意义的,带花括号的$ENV{VAR_NAME}
用来读取环境变量的值 - 示例:
$ENV{HOME}
读取当前系统环境变量HOME
的值,该值一般为用户主目录
环境 | Shell 写法 | CMake 写法 | 典型值 |
---|---|---|---|
Linux/macOS | $HOME |
$ENV{HOME} |
/home/alice |
Windows (PowerShell) | $env:USERPROFILE |
$ENV{USERPROFILE} |
C:\Users\alice |
编译
cmake <dir>
-
dir
指包含CMakeLists.txt
的目录,执行完会在当前目录(执行cmake
命令时所在目录)生成makefile
和一系列缓存文件 - 然后执行
make
命令,即可在当前目录下生成可执行文件
来源链接:https://www.cnblogs.com/xue3z/p/19018798/cmakexue-xi-ji-lu-17b6xo
如有侵犯您的版权,请及时联系3500663466#qq.com(#换@),我们将第一时间删除本站数据。
暂无评论内容