阅读本文大概需要3.3分钟

我们平时在软件开发过程中需要定义一些宏,以便在代码中调用,这样每次不需要修改代码,只需要修改外部编译命令就可以得到想要的参数,非常方便

比如我们想在软件介绍中显示软件版本,让别人知道当前使用的软件是那个版本,一般会怎么做呢?

  • 直接在代码中写死,版本号是多少
  • 从外部配置读取显示
  • 编译的时候通过编译条件读取,然后代码中读取对应变量值

今天看看平时使用最多的 Qt Creator 是怎么处理的

随便打开 Qt Creator的关于软件可以看到

通过阅读源码就可以很清楚的知道,Qt Creator是通过在 Pro 配置文件中定义宏,然后在源代码中直接读取显示的

下面来简单说说如何实现,主要包含下面几个过程

  1. 在 pro文件中定义字符串宏
  2. 宏定义字符串
  3. 在源码中直接调用

感兴趣的朋友可以下载 Qt Creator 源码详细查看,墙裂学习 C++ 的朋友去读读源码,真的可以让你学到很多意想不到的知识

pro 定义字符串宏

我们打开源码 qtcreator.pri文件,就可以看到关于版本号的定义

QTCREATOR_VERSION = 4.4.1

上面 QTCREATOR_VERSION 变量定义了一个版本号,在其他配置文件中也可以直接读取该变量

但是,仅仅定义一个变量是不够的,在源码中是无法读取到的,直接编译会报错

宏定义字符串

宏定义就是这样一个简单语句

DEFINES += QTCREATOR_VERSION=\"\\\"$$QTCREATOR_VERSION\\\"\"

在搞清楚上述语法之前,必须要知道反斜杠转义的知识 反斜杠转义

\\(对反斜杠转义)
\[(对中括号转义)
\{(对花括号转义)
\.(对点转义)

说明

  • 第一个反斜杠+引号(首尾成对),表示要对引号转义,告诉 qmake里面是一个字符串;
  • 第二个反斜杠对(2个连续反斜杠),也是转义,表示对反斜杠本身进行转义,最终在 makefile中变成一个反斜杠
  • 第三个反斜杠+引号是对引号进行转义,表示里面最终是一个字符串

因此,上述语句最终会生成一个字符串,后面我们直接可以使用该字符串宏

在源码中直接调用

#include "Widget.h"
#include <QApplication> #include <QDebug> int main(int argc, char *argv[])
{
QApplication a(argc, argv); qDebug() << APP_NAME << QTCREATOR_VERSION; return a.exec();
} debug out QtCreator 4.4.1

很轻松就可以定义字符串宏在代码中使用,这个技巧还是很方便的

总结

在定义字符串宏的时候一定要注意,你要定义的字符串是否包含空格,如果没有空格,还可以简单这样写

DEFINES += APP_NAME=\\\"QtCreator\\\"

这是为什呢?我们通过 makefile 文件可以发现,如果你的字符串包含空格,那么处理后会是这个样子

-DAPP_NAME=\"QtCreator -D\"

qmake在处理时后面多加了一个 -D,进而出现错误

<command-line>:0:10: warning: missing terminating " character

正确的 makefile文件处理过程

DEFINES = -DUNICODE -DQTCREATOR_VERSION="\"4.4.1\"" -DAPP_NAME=\"QtCreator\"
......

后续关于 Qt Creator源码分析会有一个系列进行总结,尽请关注

Qt Creator 代码是开源的,感兴趣的可以直接去下载阅读

qmake奇淫技巧之字符串宏定义的更多相关文章

  1. C语言奇淫技巧,字符串的三种表示方法,不会用不是合格的程序员

    1.在C语言中,是将字符串作为字符数组来处理的,字符串是逐个存放到数组元素中的 例如用一个一维的字符数组存放字符串"I am a boy.",如下代码: char c[12] = ...

  2. Zepto源码分析(二)奇淫技巧总结

    Zepto源码分析(一)核心代码分析 Zepto源码分析(二)奇淫技巧总结 目录 * 前言 * 短路操作符 * 参数重载(参数个数重载) * 参数重载(参数类型重载) * CSS操作 * 获取属性值的 ...

  3. Gradle更小、更快构建APP的奇淫技巧

    本文已获得原作者授权同意,翻译以及转载原文链接:Build your Android app Faster and Smaller than ever作者:Jirawatee译文链接:Gradle更小 ...

  4. JavaScript 系列--JavaScript一些奇淫技巧的实现方法(二)数字格式化 1234567890转1,234,567,890;argruments 对象(类数组)转换成数组

    一.前言 之前写了一篇文章:JavaScript 系列--JavaScript一些奇淫技巧的实现方法(一)简短的sleep函数,获取时间戳 https://www.mwcxs.top/page/746 ...

  5. ASP.NET Core 奇淫技巧之伪属性注入

    一.前言 开局先唠嗑一下,许久未曾更新博客,一直在调整自己的状态,去年是我的本命年,或许是应验了本命年的多灾多难,过得十分不顺,不论是生活上还是工作上.还好当我度过了所谓的本命年后,许多事情都在慢慢变 ...

  6. 优化DP的奇淫技巧

    DP是搞OI不可不学的算法.一些丧心病狂的出题人不满足于裸的DP,一定要加上优化才能A掉. 故下面记录一些优化DP的奇淫技巧. OJ 1326 裸的状态方程很好推. f[i]=max(f[j]+sum ...

  7. 12个实用的 Javascript 奇淫技巧

    这里分享12个实用的 Javascript 奇淫技巧.JavaScript自1995年诞生以来已过去了16个年头,如今全世界无数的网页在依靠她完成各种关键任务,JavaScript曾在Tiobe发布的 ...

  8. NGINX的奇淫技巧 —— 5. NGINX实现金盾防火墙的功能(防CC)

    NGINX的奇淫技巧 —— 5. NGINX实现金盾防火墙的功能(防CC) ARGUS 1月13日 发布 推荐 0 推荐 收藏 2 收藏,1.1k 浏览 文章整理中...... 实现思路 当服务器接收 ...

  9. NGINX的奇淫技巧 —— 3. 不同域名输出不同伺服器标识

    NGINX的奇淫技巧 —— 3. 不同域名输出不同伺服器标识 ARGUS 1月13日 发布 推荐 0 推荐 收藏 6 收藏,707 浏览 大家或许会有这种奇葩的需求...要是同一台主机上, 需要针对不 ...

随机推荐

  1. Unity 黑暗之光 笔记 第一章

    第一章 设计游戏开始进入场景 1.设置相机视野同步 选中要调整的相机 GameObject - Align With View(快捷键 Ctrl + Shift + F)

  2. vue 表单基本 表单修饰符

    表单的基础 利用v-model进行双向数据绑定: 1.在下拉列表中,将v-model写在select中 2.单选框和复选框需要每个按钮都需要写上v-model 3.v-model在输入框中获取得是输入 ...

  3. css 14-CSS3属性详解:Web字体

    14-CSS3属性详解:Web字体 #前言 开发人员可以为自已的网页指定特殊的字体(将指定字体提前下载到站点中),无需考虑用户电脑上是否安装了此特殊字体.从此,把特殊字体处理成图片的方式便成为了过去. ...

  4. Pyhton3 文件拷贝

    目录 Pyhton3 文件拷贝 shutil.copy()简单使用说明 Pyhton3 文件拷贝 ​ 导入模块shutil,使用模块中的shutil.copy()函数进行文件拷贝 shutil.cop ...

  5. Python高级语法-多继承MRO相关-args和kwargs(4.5.2)

    @ 目录 1.说明 2.代码 关于作者 1.说明 args数据类型为元组 kwargs数据类型为字典 一般传入方法中使用遍历去得到值 这个传入参数的顺序没有特殊的要求 当你自定义的参数传完以后,写了名 ...

  6. CSS —— css属性

    1.颜色属性 background-color: #CCCCCC; rgba (红色,绿色,蓝色,透明度) background-color: rgba( 0, 0, 0, 5 ) 2.字体属性 fo ...

  7. Python中的”黑魔法“与”骚操作“

    本文主要介绍Python的高级特性:列表推导式.迭代器和生成器,是面试中经常会被问到的特性.因为生成器实现了迭代器协议,可由列表推导式来生成,所有,这三个概念作为一章来介绍,是最便于大家理解的,现在看 ...

  8. C#中打印拼接的字符串

    实例化打印文档 //声明打印对象 PrintDocument pd = new PrintDocument(); int ilvPreviewIndex = 0; 在打印事件中设置基本属性 priva ...

  9. 【进程/作业】篇章一:Linux进程及其管理(进程的管理基础)

    概述:监控系统各方面的性能,保障各类服务的有序运行,是运维工作的重要组成部分,本篇就介绍一次常用的系统监控命令和相关的参数说明 具体包含以下几部分: 1.进程的管理基础 ,主要是讲一下概念性的东西 2 ...

  10. 让API并行调用变得如丝般顺滑的绝招

    当数据量较大的时候,都会通过分库分表来拆分,分担读写的压力.分库分表后比较麻烦的就是查询的问题,如果不是直接根据分片键去查询的话,需要对多个表进行查询. 在一些复杂的业务场景下,比如订单搜索,除了订单 ...