在学习 cmake 之前,首先需要了解 cmake 的约定和基础语法

基本约定

  • cmake 的文件名为 CMakeLists.txt 。该文件名大小写敏感,且不能更改

  • cmake 的语句应当为小写

  • cmake 自带的宏应当全大写

  • 自行设置的变量名应当小写

数据类型、循环和条件语句

cmake 中的行注释为 # ,其用法与 C++ 中的 // 完全相同

使用 message(变量名或字符串) 可以向控制台输出信息

数据类型

对于 cmake 来说,数据类型只有三种: 字符串布尔值列表。 要设置一个变量,可以通过 set(变量名 …​) 的方式,要访问一个变量,可以直接使用 ${变量名} 的方式

使用 $变量名 也可以访问变量,但是在拼接字符串时会导致解析变量名错误,因此极度不推荐。

字符串

要设置一个 字符串 ,使用 set(变量名 字符串) 的方式。

  • cmake 中的字符串无需加单引号或双引号(也不能加)

    要拼接字符串,可以直接加到变量名后,例如:

    set(var1 hello)
    message(${var1}world) # 输出结果为 helloworld
  • 字符串中间的空格将被忽略。例如:

    set(var1 sd) # 相当于 C++ 中的 ``string var1 = "sd"``

布尔值

要设置一个 布尔值 , 使用 set(变量名 布尔值) 的方式。

  • 以下布尔值为真:1、ON、YES、Y、TURE。

  • 以下布尔值为假:0、OFF、NO、N、FALSE、IGNORE、NOTFOUND、空值、以 -NOTFOUND 为后缀的变量名

  • ''"" 在C++ 中被认为是 false,但是在 cmake 中被认为是字符串,为真值

  • -NOTFOUND 为后缀的变量名永远为假

  • 使用 NOT 可以对变量取反

列表

要设置一个 列表 , 使用 list(操作方式 变量名 字符串) 的方式。 例如:

list(APPEND var ss ss)
使用 set(变量名 值1 值2 值3) 得到的也是列表

条件语句

cmake 使用 if() elseif() else() endif() 控制整个条件语句

例如:

if(true)
    message(true)
elseif(false)
    message(false)
endif()
else() 和 endif() 用于指定指令的作用域

循环

cmake有两种控制循环的方式:

  1. foreach endforeach

  2. while endwhile

使用 break 可以跳出循环

例如:

list(APPEND var h e w o r d)

foreach(_li ${var})
    message(${_li})
endforeach()
输出结果为

h e w o r d

正确区分 Clang

Clang 的 API 有两种模式:

  • clang 模拟 GNU API

  • clang-cl 模拟 MSVC API

但无论是哪一种,都会导致 CMAKE_CXX_COMPILER_ID 被设置为 Clang。正确的方式为:

# Get compiler info
set(CXX_FLAGS_STYLE_GNU OFF)
set(CXX_FLAGS_STYLE_MSVC OFF)
set(CXX_FLAGS_STYLE_CLANGCL OFF)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL"GNU")
    set(CXX_FLAGS_STYLE_GNU ON)
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL"Clang")
    if ("${CMAKE_CXX_SIMULATE_ID}" STREQUAL"MSVC")
        set(CXX_FLAGS_STYLE_CLANGCL ON)
    else ()
        set(CXX_FLAGS_STYLE_GNU ON)
    endif ()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL"MSVC")
    set(CXX_FLAGS_STYLE_MSVC ON)
else ()
    message(FATAL_ERROR"Unsupported compiler!")
endif ()

# Compiler flags
target_compile_options(${PROJECT_NAME}
    PRIVATE
        ## GCC/Clang Flags
        $<$<BOOL:${CXX_FLAGS_STYLE_GNU}>:"-someflag">
        ## MSVC flags
        $<$<BOOL:${CXX_FLAGS_STYLE_MSVC}>:"/someflag">
        ## CLANG-CL flags
        $<$<BOOL:${CXX_FLAGS_STYLE_CLANGCL}>:"-someflag">
)

实用技巧

启用 strip

add_link_options($<$<CONFIG:MinSizeRel>:-s>)
Last moify: 2022-12-04 15:11:33
Build time:2025-07-18 09:41:42
Powered By asphinx