找回密码
 立即注册
首页 业界区 业界 CMake学习记录

CMake学习记录

役魅肋 2025-8-7 17:52:38
CMake学习记录


  1. macro (do_test arg1 arg2 result)
  2.   add_test (test_${arg1}_${arg2} Demo ${arg1} ${arg2})
  3.   set_tests_properties (test_${arg1}_${arg2}
  4.     PROPERTIES PASS_REGULAR_EXPRESSION ${result})
  5. endmacro (do_test)
复制代码

  • 描述:macro(宏名 参数列表)可以定义一个宏
  • 第一个参数:宏名
  • 其余参数:在宏当中使用的变量名
  • 示例作用:定义一个宏简化测试代码的编写,add_test用于添加一个测试
条件语句

if语句
  1. if(condition)
  2. Tab...
  3. else()
  4. Tab...
  5. endif(condition)
复制代码
常用指令

add_definitions
  1. add_definitions(-DFOO -DBAR=123)
复制代码

  • 描述:add_definitions 是 CMake 中用来 **批量向所有目标(可执行文件、库)添加编译宏定义(**​ ​-D​ 选项)  的命令。
实际传给编译器含义​-DFOO​定义宏 FOO(空值)​-DBAR=123​定义宏 BAR 为 123​相当于添加了:
  1. #define FOO
  2. #define BAR 123
复制代码
add_library
  1. add_library(function STATIC
  2.         src/hello.cpp
  3.         )
复制代码

  • 描述:使用一些源文件生成库
  • 第一个参数:库名,实际生成的名字为libfunction.xxx​
  • 第二个参数:决定生成的库是动态库还是静态库,没有则默认静态
  • 第三个参数:生成库的源文件
add_excutable
  1. add_executable(Demo ${DIR_SRCS})
复制代码

  • 描述:使用一些源文件编译并链接成一个可执行程序
add_subdirectory
  1. add_subdirectory(math)
复制代码

  • 描述:将一个子目录添加到构建系统中
  • 参数:子目录名称
  • 示例代码作用:将math子目录中的CMakeLists.txt文件解析并加入到构建系统中
aux_source_directory
  1. aux_source_directory(<dir> <variable>)
复制代码

  • 描述:自动获取指定目录中的所有源文件,并将这些文件存储到一个变量中
configure_file
  1. configure_file(
  2.   "${PROJECT_SOURCE_DIR}/config.h.in"
  3.   "${PROJECT_BINARY_DIR}/config.h"
  4. )
复制代码

  • 描述:将一个输入文件(通常是模板文件)配置为输出文件,它会根据CMake变量的值替换输入文件(模板文件)中的占位符,生成最终的配置文件
  • 第一个参数:模板文件,通常以.in为后缀
  • 第二个参数:输出的配置文件
  • 注意点:

    • 模版文件后缀并非强制要求in,只是一种约定
    • 模版文件需要我们自己预先定义好
    • 生成的文件可以是源文件(如.h、.c、.cpp等),是也可以其他类型的文件(如配置文件等)

execute_process
  1. execute_process(
  2.     COMMAND git rev-parse HEAD
  3.     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
  4.     OUTPUT_VARIABLE FULL_SHA
  5.     OUTPUT_STRIP_TRAILING_WHITESPACE
  6. )
复制代码
关键字 / 参数含义​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
  1. find_package(<PackageName> [version] [REQUIRED] [COMPONENTS <c1> <c2>...])
复制代码

  • 描述:find_package 是 CMake 最重要、最常用的模块查找指令之一,用来在系统中“找到”某个第三方库或工具链,并自动为你设置头文件目录、库文件目录、库名称等变量,省去手动写 include_directories()、target_link_libraries() 的麻烦。
参数说明​​模块名,大小写不敏感,如 OpenSSL, Boost, Threads​​[version]​可指定最低版本,如 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​你可以直接用:
  1. target_include_directories(myapp PRIVATE ${OPENSSL_INCLUDE_DIR})
  2. target_link_libraries(myapp PRIVATE ${OPENSSL_LIBRARIES})
复制代码
一个典型用法示例
  1. find_package(PkgConfig REQUIRED)
  2. pkg_check_modules(GIO REQUIRED gio-unix-2.0)
  3. <p>target_include_directories(my_app PRIVATE ${GIO_INCLUDE_DIRS})
  4. target_link_libraries     (my_app PRIVATE ${GIO_LIBRARIES})
  5. </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

安装可执行文件
  1. install(TARGETS <target> [CONFIGURATIONS <config>...] DESTINATION <dir>)
复制代码

  • 描述:将编译出来的可执行文件target安装到目录dir中
安装文件
  1. install(FILES <file>... DESTINATION <dir>)
复制代码

  • 将文件安装到目录中
安装目录
  1. install(DIRECTORY <dir> DESTINATION <dir>
  2.         [FILE_PERMISSIONS ...]
  3.         [DIRECTORY_PERMISSIONS ...]
  4.         [PATTERN ... EXCLUDE/INCLUDE])
复制代码

  • 将整个目录安装到目标目录中,并【可选的】配置安装的目录文件访问权限
  • 如果只想装 .so,加 FILES_MATCHING PATTERN "*.so*"。
  • 目录末尾加 / 表示只装目录里的内容;不加会把目录本身也复制过去。
include_directories
  1. include_directories("${PROJECT_SOURCE_DIR}/math")
复制代码

  • 描述:用于将指定的目录添加到编译器的头文件搜索路径
  • 参数:路径
  • 示例代码作用:告诉编译器在编译时,将${PROJECT_SOURCE_DIR}/math目录中的头文件包含进来。
option
  1. option(USE_MYMATH "Use provided math implementation" ON)
复制代码

  • 描述:定义一个布尔值配置选项
  • 第一个参数:选项的名称,可以通过命令行来设置它的值
  • 第二个参数:选项的描述信息
  • 第三个参数:选项的默认值,ON表示默认启用,OFF表示禁用
  • 补充说明:可以通过ccmake命令进入配置界面,按c可以配置相关选项,option定义的变量可以在此配置选项
set
  1. set(EXTRA_LIB ${EXTRA_LIBS} MathFunctions)
复制代码

  • 描述:这种三参数写法是追加设置变量的值。

    • 它可以用来创建新变量,也可以修改现有变量的值。

  • 第一个参数:要设置的变量,如果没有则创建
  • 第二个参数:引用要设置的变量,将给该变量赋值,若是该变量已有值,则追加赋值
  • 第三个参数:要赋给变量的值
  1. set(variable value)
复制代码

  • 描述:给变量赋值

    • 它可以用来创建新变量,也可以修改现有变量的值

string
  1. 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
  1. target_link_libraries(<target>
  2.   [PRIVATE|PUBLIC|INTERFACE ...] <library1> [library2 ...])
复制代码

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

add_test与set_tests_properties

要启用测试,需在测试用例代码前添加​enable_testing()​启用测试功能。
  1. add_test(test_5_2 Demo 5 2)
  2. set_tests_properties(test_5_2 PROPERTIES PASS_REGULAR_EXPRESSION
  3.     "is 25")
复制代码

  • ​add_test​

    • 描述:add_test用于添加一个测试用例
    • 第一个参数:测试用例名称
    • 第二个参数:可执行文件名称
    • 第三个参数:传递给第二个参数的参数列表

  • ​set_tests_properties​

    • 描述:用于设置测试用例的属性。它允许你为测试用例配置各种属性,例如预期输出、超时时间等。
    • 第一个参数:测试用例名称,必须是已经被add_test定义的
    • ​PROPERTIES​关键字:表示接下来是属性的设置。
    • 常见属性

      • ​PASS_REGULAR_EXPRESSION:测试通过时输出必须匹配的正则表达式。
      • ​FAIL_REGULAR_EXPRESSION:测试失败时输出必须匹配的正则表达式。
      • ​TIMEOUT:测试超时时间(秒)。
      • ​WILL_FAIL:测试是否预期失败。
      • ​RUN_SERIAL:测试是否需要串行运行。

    • 跟在属性后面的参数:类型为字符串或数字,表示属性的值

内置变量
  1. my_project/
  2. ├── CMakeLists.txt
  3. ├── src/
  4. │   ├── main.cpp
  5. │   └── ...
  6. ├── include/
  7. │   └── ...
  8. └── ...
复制代码
​${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​编译
  1. cmake <dir>
复制代码

  • ​dir指包含CMakeLists.txt的目录,执行完会在当前目录(执行cmake命令时所在目录)生成makefile和一系列缓存文件
  • 然后执行make命令,即可在当前目录下生成可执行文件

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册