QT方案一:使用预定义宏与QMake配置(推荐)
这是最直接和常见的方案,通过C++宏获取编译时间,并利用QMake确保其每次更新。
1. 项目文件配置 (.pro)
核心在于配置预编译目标,强制每次构建时都重新编译版本信息源文件。
# 定义主版本号、次版本号、修订号(可根据需要从外部传入或手动修改)
VER_MAJ = 1
VER_MIN = 0
VER_PAT = 1
VERSION_TAG = RC # 版本附加标识,如 RC(Release Candidate), DEV, BETA等
# 定义预编译目标,确保 version.cpp 每次都被编译
precompile.target = $$PWD/version.cpp
precompile.commands = touch $$precompile.target # 在类Unix系统上更新文件时间戳。Windows下可用 `echo. > $$precompile.target` 或其他方法
precompile.depends = FORCE
QMAKE_EXTRA_TARGETS += precompile
PRE_TARGETDEPS += $$precompile.target
关键点
:
FORCE依赖和touch命令确保了version.cpp的修改时间在每次构建前都会被更新,从而触发qmake重新编译它,更新其中的__DATE__和__TIME__宏值
2. 版本信息头文件 (versioninfo.h)
#ifndef VERSIONINFO_H
#define VERSIONINFO_H
#include <QString>
class VersionInfo
{
public:
// 获取完整版本字符串,格式:V1.0.1_20251127152030_RC
static QString getFullVersionString();
// 获取各部分版本信息
static int getMajorVersion() { return MAJOR_VER; }
static int getMinorVersion() { return MINOR_VER; }
static int getPatchVersion() { return PATCH_VER; }
static QString getVersionTag() { return VERSION_TAG; }
static QString getBuildTimestamp(); // 获取格式化后的编译时间戳
private:
static const int MAJOR_VER = 1;
static const int MINOR_VER = 0;
static const int PATCH_VER = 1;
static const QString VERSION_TAG; // 例如 "RC"
// 私有构造函数,这是一个静态工具类
VersionInfo() {}
};
#endif // VERSIONINFO_H
3. 版本信息实现文件 (versioninfo.cpp)
这是核心逻辑所在,负责解析 __DATE__和 __TIME__宏并格式化成所需字符串。
#include "versioninfo.h"
#include <QLocale>
#include <QMap>
// 在.cpp文件中定义静态常量
const QString VersionInfo::VERSION_TAG = "RC";
QString VersionInfo::getBuildTimestamp()
{
// 获取原始编译日期和时间字符串
QString dateStr = __DATE__; // 格式如 "Nov 27 2025"
QString timeStr = __TIME__; // 格式如 "15:20:30"
// 处理日期字符串中可能存在的多余空格(当日期为个位数时,如"Nov 7 2025")
dateStr = dateStr.simplified();
// 将英文月份缩写转换为数字字符串
QMap<QString, QString> monthMap;
monthMap["Jan"] = "01"; monthMap["Feb"] = "02"; monthMap["Mar"] = "03";
monthMap["Apr"] = "04"; monthMap["May"] = "05"; monthMap["Jun"] = "06";
monthMap["Jul"] = "07"; monthMap["Aug"] = "08"; monthMap["Sep"] = "09";
monthMap["Oct"] = "10"; monthMap["Nov"] = "11"; monthMap["Dec"] = "12";
// 解析日期字符串
QStringList dateParts = dateStr.split(' ');
if (dateParts.size() != 3) {
return "00000000000000"; // 解析失败返回默认值
}
QString monthAbbr = dateParts[0];
QString day = dateParts[1];
QString year = dateParts[2];
// 确保日期的数字部分为两位数
if (day.length() == 1) {
day = "0" + day;
}
QString monthNum = monthMap.value(monthAbbr, "00");
// 处理时间字符串,移除冒号
QString compactTime = timeStr.remove(':');
// 组合成 YYYYMMDDHHMMSS 格式
QString timestamp = year + monthNum + day + compactTime;
return timestamp;
}
QString VersionInfo::getFullVersionString()
{
QString timestamp = getBuildTimestamp();
return QString("V%d.%d.%d_%2_%3")
.arg(MAJOR_VER)
.arg(MINOR_VER)
.arg(PATCH_VER)
.arg(timestamp)
.arg(VERSION_TAG);
}
4. 在程序中使用版本号
#include <QApplication>
#include <QDebug>
#include "versioninfo.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// 设置应用程序版本(基础部分,可选)
QApplication::setApplicationVersion(QString("%1.%2.%3")
.arg(VersionInfo::getMajorVersion())
.arg(VersionInfo::getMinorVersion())
.arg(VersionInfo::getPatchVersion()));
// 输出完整版本信息
qDebug() << "应用程序版本:" << VersionInfo::getFullVersionString();
qDebug() << "编译时间:" << VersionInfo::getBuildTimestamp();
qDebug() << "版本标签:" << VersionInfo::getVersionTag();
// ... 应用程序的其他逻辑
return app.exec();
}
-
C/C++方案:获取编译时间戳进行拼接处理
// 月份缩写转数字(如 "Aug" → 8)
int ByteUtils::parseMonth(const char* month) {
const char* months[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
for (int i = 0; i < 12; i++) {
if (std::strncmp(month, months[i], 3) == 0) return i + 1;
}
return 0;
}
// 生成紧凑时间戳字符串(格式:YYYYMMDD_HHMMSS)
std::string ByteUtils::getBuildTimestamp() {
// 提取日期和时间分量
char month_str[4] = {__DATE__[0], __DATE__[1], __DATE__[2], '\0'};
int day = (__DATE__[4] == ' ' ? 0 : __DATE__[4] - '0') * 10 + (__DATE__[5] - '0');
int year = std::atoi(&__DATE__[7]);
int month = parseMonth(month_str);
// 处理时间(移除冒号)
char time_no_colon[9];
std::strncpy(time_no_colon, __TIME__, 8);
//for (int i = 0; i < 8; i++) {
// if (time_no_colon[i] == ':') time_no_colon[i] = ' ';
//}
// 组合为 YYYYMMDD_HHMMSS
char timestamp[20] = {0};
snprintf(timestamp, sizeof(timestamp), "%04d%02d%02d_%s",
year, month, day, time_no_colon);
return timestamp;
}
// 生成完整版本号
std::string getVersion() {
return "V1.0.1_" + ByteUtils::getBuildTimestamp() + "_RC";
}
//输出版本号
std::string versionStr = getVersion();
ALOGD("mcuserver_Idps start[version:%s]\n", versionStr.c_str());
2067

被折叠的 条评论
为什么被折叠?



