当前位置: 首页 > news >正文

CMake基础:条件判断详解

目录

1.简介

 2.核心判断类型及示例

2.1.变量相关判断

2.2.数值判断

2.3.文件 / 路径判断

2.4. 目标 / 组件判断

2.5. 系统与编译器判断

2.6.逻辑组合(与 / 或 / 非)

2.7.括号分组(优先级控制)

2.8.判断某个元素是否在列表中

3.常见实用场景

4.注意事项

相关链接


1.简介

        CMake 的条件判断是通过 if()/elseif()/else()/endif() 结构实现流程控制的核心,常用于根据环境、配置、依赖等动态调整构建逻辑。

        基本语法:

if(<条件>)# 条件为真时执行
elseif(<另一条件>)  # 可选,可多个# 另一条件为真时执行
else()  # 可选# 所有条件为假时执行
endif()  # 必须闭合(推荐加注释:endif(<条件>) 增强可读性)

如果是基本表达式,条件(expression)有以下三种情况:常量、变量、字符串

  • 如果是1ONYESTRUEY非零值非空字符串时,条件判断返回True
  • 如果是0OFFNOFALSENIGNORENOTFOUND空字符串时,条件判断返回False

 2.核心判断类型及示例

2.1.变量相关判断

1)if(<var>):变量存在且值为 “真”(1/ON/YES/TRUE/Y,不区分大小写)。

set(ENABLE_FEATURE ON)
if(ENABLE_FEATURE)  # 成立message("Feature enabled")
endif()

2)if(NOT <var>):变量不存在或值为 “假”(0/OFF/NO/FALSE/N/ 空值)。

3)if(DEFINED <var>):仅判断变量是否被定义(无论值是否为空)。

set(EMPTY_VAR "")
if(DEFINED EMPTY_VAR)  # 成立(变量已定义)message("变量已定义")
endif()

4)字符串比较STREQUAL(全等,区分大小写)、STRLESS(小于)、STRGREATER(大于)。

 if(string1 STREQUAL string2):字符串相等(区分大小写)。

    if(string1 MATCHES regex):正则匹配。

# 1
if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")  # 字符串完全匹配, 编译Debug版本...
endif()# 2
set(OS_TYPE "Linux")
if(OS_TYPE STREQUAL "macOS")  # 注意大小写message("macOS detected") # 不会执行(L != l)
endif()

2.2.数值判断

支持整数比较,使用 EQUAL(等于)、LESS(小于)、GREATER(大于)、LESS_EQUAL(小于等于)、GREATER_EQUAL(大于等于):

set(NUM 5)
if(NUM GREATER 3)  # 成立(5 > 3)message(STATUS "NUM 大于 3")
endif()

2.3.文件 / 路径判断

  • if(EXISTS <路径>):路径存在(文件或目录均可)。
if(EXISTS "src/main.cpp")  # 若文件存在则成立message(STATUS "找到源文件")
endif()
  • if(IS_DIRECTORY <路径>):路径为目录则成立。
if(IS_DIRECTORY "include")  # 若 include 是目录则成立message(STATUS "找到 include 目录")
endif()
  • if(IS_FILE <路径>):路径为文件则成立(CMake 3.14+ 支持)。

  • if(IS_SYMLINK file-name) : 判断是不是软链接, 此处的file-name必须是绝对路径

  • if(IS_ABSOLUTE path) : 判断是不是绝对路径

2.4. 目标 / 组件判断

  • if(TARGET <目标名>):检查是否存在指定名称的构建目标(如通过 add_executable/add_library 定义的目标)。
add_executable(my_app main.cpp)
if(TARGET my_app)  # 成立(目标存在)message(STATUS "目标 my_app 已定义")
endif()
  • if(<包名>_FOUND):检查通过 find_package() 查找的包是否成功(通常包会定义 <包名>_FOUND 变量)。
find_package(OpenSSL)
if(OpenSSL_FOUND)  # 找到 OpenSSL 则成立message(STATUS "OpenSSL 已找到")
endif()

2.5. 系统与编译器判断

条件含义
if(WIN32)Windows 系统(含 32/64 位)
if(UNIX)类 Unix 系统(Linux/macOS 等)
if(APPLE)macOS/iOS 系统
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")精确匹配 Linux 系统
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")编译器为 GCC
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")编译器为 Clang(含 AppleClang)
if(WIN32)message(STATUS "当前系统:Windows")
elseif(APPLE)message(STATUS "当前系统:macOS")
elseif(UNIX)message(STATUS "当前系统:Linux 或其他类 Unix 系统")
endif()

2.6.逻辑组合(与 / 或 / 非)

  • if(<条件1> AND <条件2>):两个条件都为真则成立。
  • if(<条件1> OR <条件2>):至少一个条件为真则成立。
  • if(NOT <条件>):条件为假则成立(前面已提)。
set(A 1)
set(B 0)
if(A AND NOT B)  # 成立(A 为真,B 为假)message(STATUS "条件成立")
endif()

2.7.括号分组(优先级控制)

用 () 调整逻辑优先级:

if((A OR B) AND C)  # 先判断 A 或 B,再与 C 组合...
endif()

2.8.判断某个元素是否在列表中

 CMake版本要求 > 3.3

if(<variable|string> IN_LIST <variable>)

3.常见实用场景

1.根据构建类型(Debug/Release)配置:

if(CMAKE_BUILD_TYPE STREQUAL "Debug")add_definitions(-DDEBUG_MODE)  # Debug 模式定义宏set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0")  # 关闭优化
else()set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")  # Release 模式开优化
endif()

2.条件添加源文件 / 宏:

add_executable(myapp main.cpp)
if(ENABLE_FEATURE_X)  # 若启用 Feature X,添加对应源文件target_sources(myapp PRIVATE feature_x.cpp)target_compile_definitions(myapp PRIVATE ENABLE_X)
endif()

3.检查 CMake 版本是否满足要求:

cmake_minimum_required(VERSION 3.10)  # 最低版本要求
if(CMAKE_VERSION VERSION_LESS "3.18")  # 低于 3.18 时提示message(WARNING "CMake 版本过低,部分功能可能受限")
endif()

4.根据用户选项(option())开启/关闭功能

option(ENABLE_FOO "Enable feature FOO" ON)
option(ENABLE_BAR "Enable feature BAR (requires FOO)" OFF)if(ENABLE_BAR AND NOT ENABLE_FOO)message(FATAL_ERROR "ENABLE_BAR requires ENABLE_FOO to be ON")
endif()if(ENABLE_FOO)target_compile_definitions(my_app PRIVATE HAVE_FOO)if(ENABLE_BAR)target_compile_definitions(my_app PRIVATE HAVE_BAR)endif()
endif()

更多内容可参考:CMake指令:option_cmake option-CSDN博客

5.依赖项检查(如 find_package() 结果)

find_package(Protobuf 3.14 QUIET)  # 优先找 3.14+
if(NOT Protobuf_FOUND)find_package(Protobuf 3.0 REQUIRED)  # 找不到则降级到 3.0+
endif()target_link_libraries(my_app PRIVATE ${Protobuf_LIBRARIES})

更多内容可参考:CMake指令:find_package_cmake find package-CSDN博客

4.注意事项

1.变量引用无需 ${}if(MY_VAR) 直接用变量名,而非 if(${MY_VAR})(后者会解析为变量值,易出错)。

2.空变量视为假:未定义的变量或值为空时,if(<var>) 结果为假。

3.字符串比较大小写敏感STREQUAL 严格区分大小写,如需忽略可先统一大小写(如 string(TOLOWER ${A} A_LOW))。

4.路径用绝对路径更可靠:结合 CMAKE_SOURCE_DIR(源码根目录)等内置变量:

if(EXISTS "${CMAKE_SOURCE_DIR}/third_party")  # 绝对路径检查...
endif()

相关链接

  • CMake 官网 CMake - Upgrade Your Software Build System
  • CMake 官方文档:CMake Tutorial — CMake 4.1.0-rc1 Documentation
  • CMake 源码:https://github.com/Kitware/CMake
  • CMake 源码:Sign in · GitLab
http://www.lryc.cn/news/580299.html

相关文章:

  • 探索 Ubuntu 上 MongoDB 的安装过程
  • [Cyclone] 哈希算法 | SIMD优化哈希计算 | 大数运算 (Int类)
  • 【大模型】到底什么是Function Calling和MCP,以及和ReAct推理的关系是什么?
  • 若 VSCode 添加到文件夹内右键菜单中显示
  • 03_性能优化:让软件呼吸更顺畅
  • ABB焊接机器人智能节气仪
  • App爬虫工具篇-appium配置
  • AWS WebRTC:通过shell分析viewer端日志文件
  • 查看linux中steam游戏的兼容性
  • 权电阻网络DAC实现电压输出型数模转换Multisim电路仿真——硬件工程师笔记
  • C++构造和折构函数详解,超详细!
  • Linux基本命令篇 —— uname命令
  • 第二章-AIGC入门-开启AIGC音频探索之旅:从入门到实践(6/36)
  • 利用 AI 打造的开发者工具集合
  • 一个简单的分布式追踪系统
  • 指针篇(7)- 指针运算笔试题(阿里巴巴)
  • 物联网软件层面的核心技术体系
  • 论文解读:《DeepGray:基于灰度图像和深度学习的恶意软件分类方法》
  • 优象光流模块,基于python的数据读取demo
  • 新能源汽车功率级测试自动化方案:从理论到实践的革命性突破
  • 区块链技术在物联网(IoT)中的核心应用场景
  • SQL Server 进阶语法实战:从动态透视到存储过程的深度应用(第四课)
  • 高档宠物食品对宠物的健康益处有哪些?
  • 【C语言刷题】第十天:加量加餐继续,代码题训练,融会贯通IO模式
  • Webpack构建工具
  • Qt创建线程的方法
  • 学习开发之hashmap
  • RabbitMQ 高级特性之死信队列
  • 【python深度学习】Day 59 经典时序预测模型3——SARIMA
  • Day05: Python 中的并发和并行(1)