役魅肋 发表于 2025-8-7 17:52:38

CMake学习记录

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 123add_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> )

[*]描述:find_package 是 CMake 最重要、最常用的模块查找指令之一,用来在系统中“找到”某个第三方库或工具链,并自动为你设置头文件目录、库文件目录、库名称等变量,省去手动写 include_directories()、target_link_libraries() 的麻烦。
参数说明​​模块名,大小写不敏感,如 OpenSSL, Boost, Threads​​​可指定最低版本,如 3.1.0​​REQUIRED​找不到就报错,构建停止​COMPONENTS​只找其中某些组件,如 COMPONENTS system filesystem​模式描述文件来源Module 模式使用 CMake 自带的 Find.cmake <dir>脚本​/Modules/​Config 模式使用库自己提供的 Config.cmake <dir>或 -config.cmake​库安装目录的 lib/cmake//​

[*]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)
<p>target_include_directories(my_app PRIVATE ${GIO_INCLUDE_DIRS})

target_link_libraries   (my_app PRIVATE ${GIO_LIBRARIES})

</p>

[*]find_package(PkgConfig REQUIRED)​

[*]作用:让 CMake 先找到 pkg-config 这个 系统小工具(Linux 下通常是 /usr/bin/pkg-config)。
[*]​REQUIRED:如果系统没装 pkg-config,立即报错停止。
[*]成功后,PkgConfig 模块会提供 pkg_check_modules() 命令。

[*]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> DESTINATION <dir>)

[*]描述:将编译出来的可执行文件target安装到目录dir中
安装文件

install(FILES <file>... DESTINATION <dir>)

[*]将文件安装到目录中
安装目录

install(DIRECTORY <dir> DESTINATION <dir>
      
      
      )

[*]将整个目录安装到目标目录中,并【可选的】配置安装的目录文件访问权限
[*]如果只想装 .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>   ...)

[*]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>
<library1> )

[*]描述:将目标与所需的库进行链接
测试命令

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命令,即可在当前目录下生成可执行文件

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: CMake学习记录