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>: 初始值,通常是ON或OFF。表示默认是否启用该选项。
示例
# 定义一个选项,是否编译所有源文件,默认禁用
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_FILES为ON:则会使用file(GLOB)查找所有.cpp文件,并将它们添加到MyApp可执行文件中。 - 如果
BUILD_ALL_FILES为OFF:则仅会编译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: 指定包含目录仅对当前目标可见。这意味着这些目录不会传递给依赖于该目标的其他目标。
作用
-
指定头文件路径: 通过使用
target_include_directories,你可以明确指定编译器在编译时查找头文件的路径。这对于组织大型项目中的头文件非常有用。 -
控制可见性: 通过使用
INTERFACE、PUBLIC和PRIVATE关键字,你可以控制哪些目标可以访问这些包含目录。这有助于管理依赖关系和减少不必要的依赖。 -
提高可维护性: 使用
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 用例或者进一步的疑问,可以进一步探讨!