CMake语法总结

373 阅读4分钟

CMake 是一个跨平台的构建工具,广泛用于管理 C++ 项目。它利用 CMakeLists.txt 文件来控制构建过程。以下是 CMake 语法的总结,包括常见命令、变量、条件语句、函数和常用功能的介绍。


1. 基本语法

1.1. 设置项目和版本

  • project() :定义项目名称和版本。

    project(MyProject VERSION 1.0)
    
  • cmake_minimum_required() :设置所需的最低 CMake 版本。

    cmake_minimum_required(VERSION 3.10)
    

1.2. 变量定义与使用

  • set() :定义变量并赋值。

    set(MY_VAR "Hello, CMake")
    
  • message() :打印变量的值。

    message(STATUS "Variable MY_VAR is: ${MY_VAR}")
    
  • CACHE:将变量值缓存到 CMake 配置中。

    set(MY_VAR "Hello" CACHE STRING "A greeting message")
    

1.3. 添加源文件

  • add_executable() :定义可执行文件,并添加源文件。

    add_executable(MyApp main.cpp)
    
  • add_library() :定义库(静态库或动态库)。

    add_library(MyLib STATIC mylib.cpp)
    

1.4. 查找库和包

  • find_package() :查找并配置库或工具。

    find_package(OpenGL REQUIRED)
    
  • find_library() :查找特定的库文件。

    find_library(MYLIB NAMES mylib PATHS /usr/local/lib)
    
  • find_file() :查找特定的文件。

    find_file(MY_HEADER NAMES myheader.h PATHS /usr/local/include)
    

1.5. 添加包含目录

  • include_directories() :为目标添加头文件目录。

    include_directories(${PROJECT_SOURCE_DIR}/include)
    
  • target_include_directories() :为特定目标添加头文件目录。

    target_include_directories(MyApp PUBLIC ${PROJECT_SOURCE_DIR}/include)
    

2. 目标依赖与链接

2.1. 链接库

  • target_link_libraries() :为目标链接库。

    target_link_libraries(MyApp PUBLIC MyLib)
    

2.2. 设置编译选项

  • target_compile_options() :为目标设置编译选项。

    target_compile_options(MyApp PRIVATE -Wall -Wextra)
    
  • set_target_properties() :设置目标的属性(如设置共享库的版本)。

    set_target_properties(MyApp PROPERTIES VERSION 1.0 SOVERSION 1)
    

2.3. 其他构建配置

  • add_compile_definitions() :为目标定义预处理宏。

    add_compile_definitions(MY_MACRO=1)
    

3. 条件判断与循环

3.1. 条件语句

  • if() :用于条件判断。

    if(MY_VAR STREQUAL "Hello")
        message(STATUS "The message is Hello")
    else()
        message(STATUS "The message is not Hello")
    endif()
    

3.2. 循环语句

  • foreach() :用于循环遍历。

    foreach(file ${MY_FILES})
        message(STATUS "Processing file: ${file}")
    endforeach()
    

3.3. 字符串操作

  • string() :进行字符串操作。

    string(REPLACE "old" "new" MY_VAR "${MY_VAR}")
    

4. 安装与配置

4.1. 安装目标

  • install() :安装文件或目标。

    install(TARGETS MyApp DESTINATION /usr/local/bin)
    install(FILES myheader.h DESTINATION /usr/local/include)
    

4.2. 配置文件

  • configure_file() :将文件复制到构建目录,并在其中替换变量。

    configure_file(config.h.in config.h)
    

5. 外部项目与插件

5.1. 外部项目

  • ExternalProject_Add() :添加外部项目(如下载和构建外部依赖)。

    include(ExternalProject)
    ExternalProject_Add(
        MyExternalProject
        GIT_REPOSITORY https://github.com/example/repo.git
        CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
    )
    

5.2. 添加子目录

  • add_subdirectory() :包含子目录中的 CMake 配置。

    add_subdirectory(src)
    

6. 常用模块

6.1. CPack

  • include(CPack) :启用 CPack 模块以创建包(如 .deb.rpm.zip 等)。

    include(CPack)
    

6.2. CTest

  • include(CTest) :启用 CTest 模块以支持测试。

    include(CTest)
    add_test(NAME MyTest COMMAND MyApp)
    

7. 调试与输出

7.1. 打印信息

  • message() :打印调试信息。

    message(STATUS "This is a status message")
    message(WARNING "This is a warning")
    message(FATAL_ERROR "This is a fatal error")
    

7.2. 生成构建系统的日志

  • CMake 输出日志:可以通过设置 CMake 的输出等级来调试构建过程。

    cmake -DCMAKE_VERBOSE_MAKEFILE=ON ..
    

8. 高级功能

8.1. 包装工具(CPack 和 CTest)

  • CPack:用于创建项目包。

    include(CPack)
    

8.2. 配置和跨平台构建

  • CMake 支持跨平台构建,可以在不同平台上生成 Makefile、Visual Studio 工程、Xcode 项目等构建系统。

option() 是 CMake 中用于定义布尔选项的命令,通常用于控制项目中某些功能的启用或禁用。通过 option(),你可以在 CMakeLists.txt 文件中定义一个选项,允许用户通过 CMake GUI 或命令行来配置项目的构建行为。

9 用法详解

9.1 option用法

基本语法

option(<option_variable> <description> <initial_value>)
  • <option_variable>: 选项变量名(通常是大写字母加下划线的形式)。
  • <description>: 选项的描述,用于帮助用户了解该选项的功能。
  • <initial_value>: 初始值,通常是 ONOFF。表示默认是否启用该选项。

示例

# 定义一个选项,是否编译所有源文件,默认禁用
option(BUILD_ALL_FILES "Build all source files" OFF)
  • BUILD_ALL_FILES:选项变量,用户可以通过 CMake GUI 或命令行来启用或禁用这个选项。
  • "Build all source files" :选项的描述,解释该选项的作用。
  • OFF:初始值,表示默认情况下此选项为禁用。

使用选项变量

你可以使用 option() 定义的变量来控制项目中的其他部分,例如决定是否添加某些文件、库或者是否启用某些功能。

示例:根据选项启用某个功能

option(BUILD_ALL_FILES "Build all source files" OFF)

# 如果 BUILD_ALL_FILES 为 ON,则编译所有源文件
if(BUILD_ALL_FILES)
    message(STATUS "Building all source files.")
    # 添加所有源文件
    file(GLOB ALL_SOURCES "*.cpp")
    add_executable(MyApp ${ALL_SOURCES})
else()
    message(STATUS "Building default source files.")
    # 仅添加默认源文件
    add_executable(MyApp main.cpp)
endif()
  • 如果 BUILD_ALL_FILESON:则会使用 file(GLOB) 查找所有 .cpp 文件,并将它们添加到 MyApp 可执行文件中。
  • 如果 BUILD_ALL_FILESOFF:则仅会编译 main.cpp 文件。

命令行中设置选项

可以在命令行中通过 -D 选项来启用或禁用选项。例如,构建时启用 BUILD_ALL_FILES 选项:

cmake -DBUILD_ALL_FILES=ON ..

如果你没有在命令行中设置选项,CMake 会使用在 CMakeLists.txt 中定义的默认值(如 OFF)。


CMake GUI 设置选项

如果使用 CMake GUI,选项将显示在界面中,允许用户勾选或取消勾选来启用或禁用选项。


总结

option() 命令在 CMake 中用于创建简单的布尔选项,用户可以通过 CMake GUI 或命令行来启用或禁用某些构建功能。它通常与条件语句(if())结合使用,动态调整构建行为。

9.2 target_include_directories 用法

在CMake中,target_include_directories 是一个用于指定目标(如库或可执行文件)所需的头文件搜索路径的命令。它告诉编译器在编译源文件时应该在哪里查找头文件。

语法

target_include_directories(target_name [INTERFACE|PUBLIC|PRIVATE] include_directory1 [include_directory2 ...])

参数说明

  • target_name: 这是你要为其设置包含目录的目标的名称(例如,库或可执行文件)。
  • INTERFACE: 指定包含目录仅对使用该目标的其他目标可见。这意味着这些目录不会影响当前目标的编译。
  • PUBLIC: 指定包含目录对当前目标和使用该目标的其他目标都可见。这意味着这些目录会影响当前目标的编译,并且也会传递给依赖于该目标的其他目标。
  • PRIVATE: 指定包含目录仅对当前目标可见。这意味着这些目录不会传递给依赖于该目标的其他目标。

作用

  1. 指定头文件路径: 通过使用 target_include_directories,你可以明确指定编译器在编译时查找头文件的路径。这对于组织大型项目中的头文件非常有用。

  2. 控制可见性: 通过使用 INTERFACEPUBLICPRIVATE 关键字,你可以控制哪些目标可以访问这些包含目录。这有助于管理依赖关系和减少不必要的依赖。

  3. 提高可维护性: 使用 target_include_directories 可以使CMakeLists.txt文件更清晰,便于理解和维护。它明确了每个目标所需的依赖关系。

示例

以下是一个简单的示例,展示了如何使用 target_include_directories

# 创建一个库
add_library(my_library src/my_library.cpp)

# 指定头文件目录
target_include_directories(my_library
    PUBLIC
        ${CMAKE_CURRENT_SOURCE_DIR}/include
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/src
)

在这个示例中:

  • my_library 目标将会在编译时查找 include 目录中的头文件(对其他依赖于 my_library 的目标可见)。
  • src 目录中的头文件仅对 my_library 自身可见,不会传递给依赖于 my_library 的其他目标。

总结

target_include_directories 是CMake中一个重要的命令,用于指定目标的头文件搜索路径。通过控制包含目录的可见性,它有助于管理项目的依赖关系,提高代码的可维护性和可读性。

实践


总结

CMake 使得管理跨平台构建变得更加简便,它通过 CMakeLists.txt 文件描述构建流程,支持丰富的功能,如添加目标、处理文件、设置依赖、条件判断、生成安装包等。CMake 通过其强大的配置语言,简化了多平台、多配置的构建工作,是现代 C++ 项目构建的标准工具之一。

如果你有特定的 CMake 用例或者进一步的疑问,可以进一步探讨!