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 定义宏 BAR123

相当于添加了:

#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})

  1. find_package(PkgConfig REQUIRED)

    • 作用:让 CMake 先找到 pkg-config 这个 系统小工具(Linux 下通常是 /usr/bin/pkg-config)。
    • REQUIRED:如果系统没装 pkg-config,立即报错停止。
    • 成功后,PkgConfig 模块会提供 pkg_check_modules() 命令。
  2. 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

© 版权声明
THE END
支持一下吧
点赞8 分享
评论 抢沙发
头像
请文明发言!
提交
头像

昵称

取消
昵称表情代码快捷回复

    暂无评论内容