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

【CMake】CMake 与 C++ 协同:条件配置机制及控制台控制实例解析

CMake 与 C++ 协同:条件配置机制及控制台控制实例解析

1. CMake中定义变量并传递编译宏
# 设置是否显示控制台(CMake变量定义)
set(ENABLE_CONSOLE OFF)             # 布尔变量(用于条件判断)# 将CMake变量传递给目标程序(需在add_executable之后调用)
if(ENABLE_CONSOLE)# 当ENABLE_CONSOLE为ON时,向softRenderer目标定义宏ENABLE_CONSOLEtarget_compile_definitions(softRenderer PRIVATE ENABLE_CONSOLE)
endif()
  • 核心逻辑:通过set定义CMake变量作为“开关”,再用target_compile_definitions条件性地向C++目标传递宏,实现“构建配置”到“代码逻辑”的映射。
  • 注意点:target_compile_definitions必须在add_executable(softRenderer ...)之后,因为它依赖于目标已被创建(“先定义目标,再配置属性”)。
2. C++中使用宏实现条件编译
// 根据CMake定义的宏选择链接器子系统
#ifdef ENABLE_CONSOLE// 启用控制台(调试时用)#pragma comment(linker, "/subsystem:console /entry:wWinMainCRTStartup")
#else// 禁用控制台(发布时用)#pragma comment(linker, "/subsystem:windows /entry:wWinMainCRTStartup")
#endif
  • 核心逻辑:C++通过#ifdef判断宏是否存在,进而执行不同分支(控制Windows链接器的子系统和入口点)。
  • 作用:区分“调试模式”(显示控制台用于日志输出)和“发布模式”(隐藏控制台,更简洁)。

举一反三:扩展知识点

1. CMake传递配置的其他方式

除了target_compile_definitions,还有更多灵活的配置传递方式:

  • configure_file:通过模板生成头文件,适合传递路径、版本号等(比宏更适合字符串):

    # CMakeLists.txt
    set(APP_VERSION "2.1.0")
    configure_file(config.h.in config.h)  # 用模板生成config.h// config.h.in(模板)
    #define APP_VERSION "@APP_VERSION@"// C++中使用
    #include "config.h"
    std::cout << "版本:" << APP_VERSION << std::endl;
    
  • target_compile_options:传递编译选项(如-O3优化、-Werror警告)。

2. 跨平台的条件编译

Windows用链接器选项控制控制台,其他平台机制不同,可通过宏区分:

#ifdef _WIN32// Windows控制台控制(如示例代码)
#elif defined(__linux__)// Linux默认绑定控制台,隐藏需用后台运行(nohup ./程序 &)
#elif defined(__APPLE__)// macOS类似Linux,可通过Info.plist配置
#endif
3. 编译宏的更多应用场景
  • 功能开关#ifdef ENABLE_VULKAN控制是否启用Vulkan渲染;
  • 调试模式#ifdef DEBUG启用assert断言或详细日志;
  • 代码裁剪:通过宏屏蔽未使用模块,减小二进制体积。

通过这种“CMake配置+代码条件编译”的模式,可灵活适配不同环境(调试/发布、Windows/Linux),是大型项目常用的工程技巧。

http://www.dtcms.com/a/298061.html

相关文章:

  • [C++]string::substr
  • MindJourney:构建空间智能的新范式——VLM与视频扩散式世界模型的融合
  • 【LeetCode Solutions】LeetCode 热题 100 题解(16 ~ 20)
  • 【牛客网C语言刷题合集】(三)
  • 2025年-ClickHouse 高性能实时分析数据库(大纲版)
  • 【开发杂谈】用AI玩AI聊天游戏:使用 Electron 和 Python 开发大模型语音聊天软件
  • 如何搭建Linux环境下的flink本地集群
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-26,(知识点:硬件电路的调试方法:信号追踪,替换,分段调试)
  • 飞算 JavaAI “撤回接口信息” 功能:误删接口不用慌,一键恢复更省心
  • Linux 设备驱动模型
  • WINDOWS10系统重装软件篇
  • QML图形效果之阴影效果(DropShadow与InnerShadow)
  • Cacti命令执行漏洞分析(CVE-2022-46169)
  • compileSdkVersion和targetSdkVersion可以不一样的版本吗
  • 图论:并查集
  • 深入解析JVM垃圾回收调优:性能优化实践指南
  • Python 数据可视化之 Matplotlib 库
  • Java常用命令、JVM常用命令
  • RAG面试内容整理-3. 向量检索原理与常用库(ANN、FAISS、Milvus 等)
  • blender基本操作
  • flutter TextField 失去焦点事件
  • Qt:qRegisterMetaType函数使用介绍
  • 安全风险监测平台:被动应对向主动预防的转变
  • Ethereum:告别 personal API,拥抱 Geth 的独立签名器 Clef
  • [HarmonyOS] Harmony LiteOS-A 驱动框架深度解析:HDF 让万物互联更简单
  • EC 技术赋能:福佑防爆风扇如何平衡安全与节能?
  • JVM相关面试八股
  • Mysql实现高可用(主从、集群)
  • Unity GC 系列教程第五篇:高级 GC 内核
  • Python(32)Python内置函数全解析:30个核心函数的语法、案例与最佳实践