您的位置:

深入了解 CMake 变量

CMake 是一个功能丰富的自动化构建系统。它允许开发人员生成现代的、高效的构建过程,简化跨平台构建工作,同时为广大用户提供便捷的可执行文件。

其中 ,变量是构建功能中最基本的一部分。

一、CMake 变量简介

CMake 变量是用于存储文本常量、数字以及布尔类型等的名称值对,它们被广泛用于构建脚本中的各种设置、任务和参数。

变量在 CMake 中的使用方式非常类似于其他编程语言中的变量,甚至更加灵活。它们可以被赋值、传递给函数、以及通过堆栈方式来管理上下文,最终用于控制构建和处理代码的流程。

下面我们介绍几个常用的变量:

1. CMAKE_变量 系列

CMAKE_变量 系列是一组预定义的变量,用于控制 CMake 及其生成器的行为。这些变量在 CMake 的内部使用,通常不需要修改。

cmake_minimum_required(VERSION 3.5)

message(STATUS "CMake Version: ${CMAKE_VERSION}")
message(STATUS "CMake Source Dir: ${CMAKE_SOURCE_DIR}")
message(STATUS "CMake Binary Dir: ${CMAKE_BINARY_DIR}")

上述代码演示了如何使用 CMake 预定义变量 CMAKE_VERSION、CMAKE_SOURCE_DIR、CMAKE_BINARY_DIR 来显示 Cmake本身的版本号及源码路径和目标路径。

2. 构建选项

CMake 变量可以用于控制构建选项,比如编译器标志、依赖库路径、安装路径等。

下面我们定义了两个常用的构建选项。

# Enable debug symbols by default
if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE Debug)
endif()

# Set the output directory 
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)

上述代码片段将默认的构建类型设置为 Debug,并且定义了输出目录为 ${PROJECT_BINARY_DIR}/lib 或 ${PROJECT_BINARY_DIR}/bin。

3. 自定义变量

除了 CMake 预定义的变量和构建选项外,开发人员还可以自定义变量并将它们用于其他目的,例如:

1)自定义变量 PATHS,用于存储依赖库的位置:

set(PATHS "/usr/local/include" "/usr/include")
message(STATUS "Search paths: ${PATHS}")

2)自定义变量 SOURCES,用于存储需要编译的源文件列表:

file(GLOB SOURCES "${PROJECT_SOURCE_DIR}/src/*.cpp")
add_executable(myapp ${SOURCES})

二、CMake 变量的作用域

CMake 变量作为关键概念,它们拥有各自的作用域和生命周期。

变量的作用域被定义为变量的可见范围,这取决于变量被定义的位置。在 CMake 中,变量的作用域主要分为以下几种情况:

1. 全局变量

CMake 中的全局变量可以在 CMake 文件中任何地方进行定义,并且在整个 CMake 运行期间都有效。CMake 内置的变量和用户自己定义的变量都是全局的。

下面定义了两个全局变量:

set(GLOBAL_VAR "Global variable")
function(f)
  message(STATUS "Func: ${GLOBAL_VAR}")
endfunction()

f() # "Global variable"

2. 局部变量

局部变量只在它们被定义的函数中有效。

下面定义了两个局部变量 UNITS 和 TOTAL,分别用于计算 list 中所有元素的和。

function(sum list)
  set(UNITS "")
  set(TOTAL 0)
  foreach(num ${list})
    math(EXPR TOTAL "${TOTAL} + ${num}")
  endforeach()
  message(STATUS "Sum: ${TOTAL}")
endfunction()

sum(1 2 3) # "Sum: 6"

3. CACHE 变量

CACHE 变量既可以作为全局变量,也可以作为本地变量。它们可以在运行 CMake 时被设置,然后保存到 CMake 缓存中,以便在之后的构建中重复使用。

下面示例中的 CACHE 变量用法:为可自定义安装路径的命令行界面添加一个选项。

option(INSTALL_MYAPP "Install MyApp" OFF)
if(INSTALL_MYAPP)
  set(INSTALL_DIR /usr/local/myapp CACHE PATH "Installation directory")
endif()

三、CMake 变量的扩展和转义

CMake 提供了多种方式来扩展和转义变量,以满足各种复杂的需求。

1. 变量替换和扩展

CMake 支持将变量的值作为另一个变量的名称来访问、扩展变量以及在字符串中使用变量。

下面分别演示了三种方法:

set(FULL_NAME "Software Engineer")
set(AGE 30)

# Access variable by using another variable name
set(NEW_VAR "FULL_NAME")
message(STATUS "Access variable: ${${NEW_VAR}}")

# Expand variable in a string
set(MESSAGE "I am ${FULL_NAME}, ${AGE} years old")
message(STATUS "Expand variable in string: ${MESSAGE}")

# Append string to variable
set(PATH "/usr/local/include" CACHE PATH "Installation path")
set(PATH "${PATH}:/usr/include")
message(STATUS "Append string to variable: ${PATH}")

2. 变量引用和转义

在一些特殊情况下,我们需要引用某些变量的文本值,例如将变量的值传递给 shell 命令。

下面演示了将变量作为命令行参数使用时的转义。

set(PATH "/usr/local/my\ app" CACHE PATH "Installation path")
execute_process(COMMAND echo ${PATH}) # "/usr/local/my app"

四、CMake 命令和函数参数默认值和类型声明

如果没有为命令或函数传递足够的参数,CMake 会发出警告并退出。

因此,CMake 允许在命令和函数中定义默认参数,以及指定参数类型,这样可以在必要的时候在代码中使用。

下面演示了如何为命令和函数定义默认值并声明类型:

# Define default values
set(FILE_PATH "file.txt")
set(TEXT "Hello, World!")

# Declare parameter types
function(write_to_file FILE_NAME STRING)
  file(WRITE "${FILE_NAME}" "${STRING}")
endfunction()

write_to_file(${FILE_PATH} ${TEXT}) # Write "Hello, World!" to "file.txt"

结论

CMake 变量是 CMake 构建中最基本的概念之一,开发人员可以将变量用于各种设置、任务和参数中。同时,CMake 还提供了丰富的变量扩展和转义方式,以及将参数默认值和类型声明方式。熟练掌握这些技巧可以帮助开发人员更高效地编写、管理 CMake 构建脚本。