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 构建脚本。