cmake(13):构建时设置预处理宏定义以及add_compile_definitions命令详解

2023-10-30

目录

1. 说明

1.1 无参宏

1.2 有参宏

2. 使用示例

3. 命令解析

add_compile_definitions 命令

add_definitions 命令

参考链接


1. 说明

宏定义在程序设计中几乎是不可避免会用到的,在控制程序运行上有非常重要的作用。除了在源代码中使用 #define 预处理命令定义的宏,我经常会在编译时根据具体需要选择定义某些宏或者绕过某些宏,以期同一套代码能符合多种场景需求。

对于使用 cmake 构建的软件,我们不再需要写 Makefile 也不用直接执行 gcc 等编译命令,为了满足上述需求,cmake 也提供了多种方法让用户能够在编译时自定义宏定义。

1.1 无参宏

假设我们的目标是要在程序中定义一个没有具体值的宏(通常用于一些编译开关之类的),比如:

#define NONE_VALUE_MACRO

cmake 命令行

可以在使用 cmake 命令构建时,添加 /D[MACRONAME] 参数可以在编译时手动选择定义宏参数。

cmake /DNONE_VALUE_MACRO ..

这样的优点是灵活,可以完全不修改代码的情况下选择要定义的宏。缺点嘛,就是麻烦,尤其是有多个宏定义的时候。反正我是不喜欢输入太长的命令的。

需要注意的是,命令行不能直接对源代码生效,而是影响 CMakeLists.txt 文件的执行,所以要上述命令生效,还需要在 CMakeLists.txt 中添加相应语句。

add_definitions 命令

这个命令是 cmake 较早版本就实现的,特点是使用时要在宏名称前添加 "-D" 前缀。

add_definitions(-DNONE_VALUE_MACRO)

add_compile_definitions 命令

这个命令是 cmake v3.12 后添加的,相比于 add_difinitions,功能更加单一且参数使用灵活。

add_compile_definitions(NONE_VALUE_MACRO)

1.2 有参宏

假设要定义一个有具体值的宏:

#define VALUE_MACRO 0x10000000

cmake 命令行

在定义有参宏时,要使用 "-D" 而非 "/D",前者遵循 [VAR:type=value] 的格式,即在定义宏要指定具体值。

cmake -DVALUE_MACRO=0x10000000 ..

add_definitions 命令

add_definitions(-DNONE_VALUE_MACRO=0x10000000)

add_compile_definitions 命令

add_compile_definitions(VALUE_MACRO=0x10000000)

注:

  • -D 或 /D 后与宏名称直接可以有空格也可以没有
  • cmake 官方建议不再使用 add_definitions 而用 add_compile_definitions

2. 使用示例

compile.c

#include <stdio.h>

int main()
{
    printf("This process is used to testing compiler definition in cmake.\n");

#ifdef COMPILE_M1
    printf("Defined macro: COMPILE_M1\n");
#endif

#if COMPILE_M2 == 0x100
    printf("Macro COMPILE_M2: 0x%x\n", COMPILE_M2);
#endif

#if COMPILE_M3 == 0x200
    printf("Macro COMPILE_M3: 0x%x\n", COMPILE_M3);
#endif

#ifdef COMPILE_M4
    printf("Macro COMPILE_M4 is defined by cmake command\n");
#endif

    return 0;
}

CMakeLists.txt

cmake_minimum_required (VERSION 3.13.0)

project (cmake_test VERSION 0.0.4)

add_definitions (-DCOMPILE_M1)
add_definitions (-DCOMPILE_M2=0x100)

add_compile_definitions (COMPILE_M3=0x200)

if(COMPILE_M4)
    add_compile_definitions (COMPILE_M4)
endif()

add_executable(compile compile.c)

编译运行

mkdir build && cd build
cmake .. #或 cmake /DCOMPILE_M4 ..
make

3. 命令解析

add_compile_definitions 命令

这个命令是 cmake v3.12 版本添加的特性,用于将预处理器定义添加到源文件的编译中。

预处理器定义被添加到当前 CMakeLists 文件的 COMPILE_DEFINITIONS 目录属性中。它们也被添加到当前 CMakeLists 文件中每个目标的 COMPILE_DEFINITIONS 目标属性中。

使用语法 VAR 或 VAR=value 指定定义。不支持函数样式定义。 CMake 将自动为本机构建系统正确转义值(请注意,CMake 语言语法可能需要转义来指定某些值)。

其命令格式如下:

add_compile_definitions(<definition> ...)

add_compile_definitions 的参数可以使用语法为 $<...> 的“生成器表达式”。如:

set(VAR_TESTCASE_CONFIG_FILE \"testcases.json\") add_compile_definitions(TESTCASE_CONFIG_FILE="${VAR_TESTCASE_CONFIG_FILE}")

add_definitions 命令

将 -D 定义标志添加到源文件的编译中。将定义添加到当前目录中的目标的编译器命令行,无论是在调用此命令之前还是之后添加,以及之后添加的子目录中的目标。此命令可用于添加任何标志,但它旨在添加预处理器定义。

add_definitions(-DFOO -DBAR ...)

以 -D 或 /D 开头的看起来像预处理器定义的标志会自动添加到当前目录的 COMPILE_DEFINITIONS 目录属性中。具有非平凡值的定义可能会留在标志集中,而不是出于向后兼容性的原因进行转换。

cmake 官方建议现在使用其他的命令来代替这个命令:

  • add_compile_definitions() : 添加预处理器定义
  • include_directories() : 添加 include 目录
  • add_compile_options() : 添加编译选项

参考链接

CMake定义宏的方式_风闲1217的博客-CSDN博客_cmake 宏定义

add_definitions — CMake 3.24.0-rc2 Documentation

add_compile_definitions — CMake 3.24.0-rc2 Documentation

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

cmake(13):构建时设置预处理宏定义以及add_compile_definitions命令详解 的相关文章

  • 使用 CLion 进行 OpenCV Windows 设置

    我想在 Windows 上为 CLion IDE 设置 OpenCV 我尝试使用 OpenCV 3 1 和 2 4 得到相同的结果 我有 Windows 10 64 位 CLion 使用 cygwin 环境 到目前为止我做了什么 1 从Op
  • Poco c++Net:Http 从响应中获取标头

    我使用 POCO C Net 库进行 http 我想尝试制定持久缓存策略 首先 我认为我需要从缓存标头中获取过期时间 并与缓存值进行交叉检查 如果我错了 请告诉我 那么我如何从中提取缓存头httpResponse 我已经看到你可以用 Jav
  • 检测wlan是否关闭

    任何人都可以给我一个提示 如何在 Windows Phone 上以编程方式检测 C 8 1 应用程序 不是 8 0 是否启用 禁用 WLAN 我不想更改这些设置 只是需要知道 该解决方案是一个 Windows 8 1 通用应用程序 Wind
  • linq 中使用字符串数组 c# 的 'orderby'

    假设我有一个这样的方法定义 public CustomerOrderData GetCustomerOrderData string CustomerIDs var query from a in db Customer join b in
  • CSharpRepl emacs 集成?

    我碰巧知道莫诺CSharpRepl http www mono project com CsharpRepl 是否有 emacs csharp 模式使用它在一个窗口中运行 REPL 并像 python 模式一样在另一个窗口中编译 运行 C
  • 从代码中,如何创建对存储在附加属性中的对象的属性的绑定?

    我们有一个继承的附加属性来存储一个对象 在可视化树的更下方 我们希望从代码绑定到该对象的属性 通常我们像这样构建绑定的路径部分 var someBinding new Binding Path new PropertyPath Attach
  • Gwan C#,如何获取HTTP标头?

    我需要它来重写 url 以了解我正在处理哪个友好的 url 用于用户代理和其他东西 EDIT public class Gwan MethodImplAttribute MethodImplOptions InternalCall exte
  • 如何制作可启动程序?

    所以 这个问题可能看起来很奇怪 但假设我编译了 int main void int x 3 int y 4 int z x y 是否可以让CPU这样运行 如何 例如 这允许我写入监视器吗 如果我没记错的话 内存中有些地方可以写入要显示的内容
  • MFC:如何设置CEdit框的焦点?

    我正在开发我的第一个简单的 MFC 项目 但我正在努力解决一个问题 想要设置所有的焦点CEdit其中一个对话框中的框 我的想法是 当打开对话框时 焦点位于第一个编辑框上 然后使用 选项卡 在它们之间交换 我看到了方法SetFocus 但我无
  • 根据对象变量搜索对象列表

    我有一个对象列表 这些对象具有三个变量 ID 名称和值 这个列表中可能有很多对象 我需要根据ID或Name找到一个对象 并更改值 例子 class objec public string Name public int UID public
  • 如何在三个 IEnumerable 上使用 Zip [重复]

    这个问题在这里已经有答案了 可能的重复 使用 Linq 从 3 个集合创建项目 https stackoverflow com questions 5284315 create items from 3 collections using
  • 在 asp.net MVC 中使用活动目录进行身份验证

    我想使用活动目录对我的 asp net mvc 项目中的用户进行身份验证 在网上冲浪了几个小时后 我没有找到任何对我有用的东西 我已经看到了所有结果 但什么也没有 我尝试按照许多帖子的建议编辑我的 web config 如果有人可以帮助我提
  • 搜索实体的所有字段

    我正在尝试在客户数据库上实现 多功能框 类型的搜索 其中单个查询应尝试匹配客户的任何属性 这是一些示例数据来说明我想要实现的目标 FirstName LastName PhoneNumber ZipCode Mary Jane 12345
  • 从浏览器访问本地文件?

    您好 我想从浏览器访问系统的本地文件 由于涉及大量安全检查 是否可以通过某种方式实现这一目标 或使用 ActiveX 或 Java Applet 的任何其他工作环境 请帮帮我 要通过浏览器访问本地文件 您可以使用签名的 Java Apple
  • 使用 jQuery 从 ASP.Net JSON 服务获取数据

    我正在尝试调用 Google 地图地理编码 API 从纬度 经度对中获取格式化的地址 然后将其记录到控制台 我正在尝试获取为给定位置返回的第一个 formatted address 项目 我很简单无法从 JSON 中提取该项目 我不知道为什
  • 如何调试 .NET 运行时中的内部错误?

    我正在尝试调试一些处理大文件的工作 代码本身works 但 NET 运行时本身会报告零星错误 对于上下文 这里的处理是一个 1 5GB 文件 仅加载到内存中一次 在循环中处理和释放 故意尝试重现此否则不可预测的错误 我的测试片段基本上是 t
  • 如何在 winforms 应用程序的主屏幕显示之前显示欢迎屏幕?

    我想在应用程序启动时加载欢迎屏幕 然后用户单击欢迎屏幕上的按钮 然后关闭欢迎屏幕 最后显示主屏幕 static void Main startup method being called Application EnableVisualSt
  • 使用 using 声明时,非限定名称查找如何工作?

    根据 C 标准 这是格式错误还是格式良好 namespace M struct i namespace N static int i 1 using M i using N i int main sizeof i Clang 拒绝它 GCC
  • 如何使用placement new重新初始化该字段?

    我的课程包含字段 private OrderUpdate curOrderUpdate 我一遍又一遍地使用它 经常需要重新初始化 for int i 0 i lt entries size i auto entry entries i ne
  • 结构化绑定的用例有哪些?

    C 17 标准引入了新的结构化绑定 http en cppreference com w cpp language structured binding功能 最初是proposed http www open std org jtc1 sc

随机推荐

  • c语言 计算职工工资

    给定N个职员的信息 包括姓名 基本工资 浮动工资和支出 要求编写程序顺序输出每位职员的姓名和实发工资 实发工资 基本工资 浮动工资 支出 输入格式 输入在一行中给出正整数N 随后N行 每行给出一位职员的信息 格式为 姓名 基本工资 浮动工资
  • java的createImage_Java——BufferedImage操作实例

    通过鼠标位置改变图像ColorModel对象索引 从而实现图像像素自动变化 BufferedImage 由图像数据的 ColorModel 和 Raster 组成 Raster 的 SampleModel 中 band 的数量和类型必须与
  • 您的应用存在隐藏最近任务列表名称的行为,不符合华为应用市场审核标准

    flutter应用 华为上架 遇到的问题 解答 加入列表名称
  • Win10安全中心一片空白,只显示安全性概览

    1 按下WIN R 运行regedit回车 2 找到路径 HKEY LOCAL MACHINE SYSTEM CurrentControlSet Services SecurityHealthService 然后双击右边的 start 把值
  • Mysql安装步骤

    安装步骤 链接 链接 https pan baidu com s 1e74jvXPh9oqpk wRQBiyiQ 提取码 mntm 1 下载后得到zip压缩包 2 解压到自己想要安装到的目录 本人解压到的是D Environment mys
  • Python opencv连通域

    1 求解连通域 Opencv 连通域函数connectedComponentsWithStats num labels labels stats centroids cv2 connectedComponentsWithStats imag
  • Docker部署AI算法教程

    docker上部署算法除了一些推理框架外 有时候会自己用torch推理加上一些web应用 下面写下自己用的一套方法 Docker cuda10 1 miniconda3 torch1 7 1 docker要求19 03以上才支持cuda 1
  • Harbor----使用 Harbor 安装包安装部署 Harbor

    文章目录 一 Harbor安装准备条件 1 1 硬件要求 1 2 软件要求 1 3 网络端口要求 二 下载 Harbor 的安装包文件 2 1 Harbor 安装包分类 2 2 下载并解压安装包 三 配置安装 Harbor 3 1 安装基于
  • org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class

    Application run failed org springframework beans factory BeanDefinitionStoreException Failed to parse configuration clas
  • 宝德服务器安装过程

    每次装的话 都会绕晕 然后记录下 德宝服务器 首先开机的话 开到提示按Ctrl H进入WebBIOS 迅速的按下Ctrl H 进入配置页面 如图 点击 Configuration Wizard 点击 Next 点击 Next 选中一个磁盘
  • 动态内存管理

    目录 一 为什么存在动态内存分配 二 动态内存函数的介绍 1 malloc 2 free 释放回收内存 3 calloc 4 realloc 三 常见的动态内存错误 1 对NULL指针的解引用操作 2 对动态开辟空间的越界访问 3 对非动态
  • 介绍几款常用的在线API管理工具

    在项目开发过程中 总会涉及到接口文档的设计编写 之前使用的都是ms office工具 不够漂亮也不直观 变更频繁的话维护成本也更高 及时性也是大问题 基于这个背景 下面介绍几个常用的API管理工具 方便你与调用方更高效的沟通测试 Swagg
  • Mac os 安装homebrew

    Mac os 不会自带homebrew工具 而很多需要的工具需要用brew命令下载和安装 但是因为homebrew是国外网站 如果没有VPN 就无法下载 下面记录一下如何解决这个问题 1 国内安装的命令如下 bin zsh c curl f
  • centos或Ubuntu机器出现 pycharm.desktop文件出现 未信任的应用程序启动器的情况,怎么解决?

    桌面图标启动编辑 vi pycharm desktop usr bin env xdg open Desktop Entry Version 1 0 Type Application Name Pycharm 根据自己的安装位置灵活修改 I
  • centOs7 安装docker 镜像

    Step1 检查是否安装过 docker yum list installed grep docker 如果出现如下图所示的情况 说明安装过 如果重新安装需要先卸载 使用命令 yum y remove docker ce x86 64 卸载
  • TensorRT -- github

    此存储库包含 NVIDIA TensorRT 的开源软件 OSS 组件 它包括 TensorRT 插件和解析器 Caffe 和 ONNX 的源代码 以及演示 TensorRT 平台用法和功能的示例应用程序 这些开源软件组件是 TensorR
  • Python 预测股票价格,竟然这么简单

    作为一种技术手段 预测在金融 证券领域的应用非常广泛 尤其是对股票价格的预测 我们介绍一下获得股票数据的方法 并基于此对数据进行预处理 接着使用数据分析方法 建立基础特征 进一步构建预测模型 且基于新数据验证模型效果 拟使用 VAR 及LS
  • Oracle数据库精讲与疑难解析(第2版)

    Oracle数据库精讲与疑难解析 第2版 赵振平编著 ISBN978 7 121 20021 2 2013年4月出版 定价 148 00元 1100页 16开 编辑推荐 耗时3年 作者曾为本书辞职在家专心写作 754个实务 件件源自实际工作
  • 可视化Docker管理工具-DockerUI

    DockerUI 产品介绍 DockerUI是一个易用且轻量化的 Docker 管理工具 透过 Web 界面的操作 更方便对于 Docker 指令不熟悉的用户更快进入 Docker 的世界 DockerUI拥有易操作化化界面 不须记忆Doc
  • cmake(13):构建时设置预处理宏定义以及add_compile_definitions命令详解

    目录 1 说明 1 1 无参宏 1 2 有参宏 2 使用示例 3 命令解析 add compile definitions 命令 add definitions 命令 参考链接 1 说明 宏定义在程序设计中几乎是不可避免会用到的 在控制程序