初出茅庐的小李博客之根据编译时间生成软件版本号
为什么要软件版本号呢?
生成软件版本号是在软件开发和维护过程中非常重要的一项任务,它有很多意义和好处,同时也有多种常见的方法。
-
标识和追踪:软件版本号是唯一的标识符,用于区分不同版本的软件。这有助于开发人员和用户识别和追踪软件的不同发布版本。当出现问题时,可以更容易地确定特定版本中的错误或改进。
-
沟通和文档:版本号提供了一种简单而清晰的方式来与团队成员、用户和其他利益相关者进行沟通。通过版本号,人们可以明确了解到底是哪个版本的软件正在讨论,从而更容易地协作和解决问题。
-
发布计划:版本号可以用于制定和执行软件的发布计划。通过设定版本号,团队可以计划哪些功能和改进将包含在特定版本中,以及何时发布这些版本。
-
用户期望管理:版本号可以用于管理用户的期望。用户可以根据版本号了解到软件的新功能、改进和修复的问题。这有助于用户知道他们是否需要升级或采取其他行动。
-
软件稳定性:通过良好设计的版本号系统,可以区分主要版本、次要版本和修订版本。这有助于用户快速识别是否有可能引入不稳定性的大幅更改。
常见生成软件版本号的方法有哪些?
-
语义版本号(Semantic Versioning,SemVer):SemVer 是一种流行的版本号方案,通常由三部分组成:主版本号、次版本号和修订号,例如 1.2.3。主版本号增加表示不兼容的变化,次版本号增加表示向后兼容的功能添加,修订号增加表示向后兼容的错误修复。
-
日期版本号:使用日期作为版本号的一部分,例如 2023.09.11,可以让人们很容易地知道软件的发布日期。这对于在特定日期之前或之后的版本上工作或测试很有用。
-
自定义版本号:一些团队和组织使用自定义版本号方案,根据他们的需求制定。这可能包括项目标识符、构建号码、分支信息等。
-
预发布版本和元数据:有时,版本号可能包括预发布版本和元数据信息,以进一步详细说明软件的状态和特性。例如,1.2.3-beta1 表示一个预发布版本,而 1.2.3+build456 表示带有构建号的版本。
-
语言特定的版本号:某些编程语言和工具具有自己的版本号规范,开发人员应遵循这些规范,以确保与相关工具的兼容性。
在单片机中如何生成日期版本号?
先介绍一下c语言常见的两个宏定义
在C语言中,有一些特殊的宏定义,用于获取当前编译日期和时间等信息。以下是两个常见的宏定义示例:
-
__DATE__ 宏:
printf("编译日期:%s\n", __DATE__);这个宏会在编译时被替换为一个字符串,表示编译源代码的日期。通常,它的格式类似于"Sep 11 2023",表示月份、日期和年份。
-
__TIME__ 宏:
printf("编译时间:%s\n", __TIME__);这个宏会在编译时被替换为一个字符串,表示编译源代码的时间。通常,它的格式类似于"12:34:56",表示小时、分钟和秒。
这些宏可以用于在代码中记录编译日期和时间,这在调试和版本管理中非常有用。
具体实现
#include "version.h"
#include <string.h>
#include <stdlib.h>void Get_Compile_Date_Base(uint8_t *Year, uint8_t *Month, uint8_t *Day)
{//Sep 11 2023const char *pMonth[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};const char Date[12] = __DATE__;//取编译日期uint8_t i;for(i = 0; i < 12; i++)if(memcmp(Date, pMonth[i], 3) == 0)*Month = i + 1, i = 12;*Year = (uint8_t)atoi(Date + 9); //Date[9]为2位年份,Date[7]为完整年份*Day = (uint8_t)atoi(Date + 4);
}void Get_Compile_Time_Base(uint8_t *HH, uint8_t *MM, uint8_t *SS)
{//15:40:23const char Time[10] = __TIME__;//取编译时间*HH = (uint8_t)atoi(Time + 0);*MM = (uint8_t)atoi(Time + 3);*SS = (uint8_t)atoi(Time + 6);
}char g_date_buf[10];
char g_time_buf[10];
char g_version_buf[20];
char* Get_Compile_Date(void)
{uint8_t Year, Month, Day;Get_Compile_Date_Base(&Year, &Month, &Day);//取编译日期sprintf(g_date_buf, "20%02d-%02d-%02d", Year, Month, Day);//任意格式化return g_date_buf;
}char* Get_Compile_Time(void)
{uint8_t HH, MM, SS;Get_Compile_Time_Base(&HH, &MM, &SS);//取编译时间sprintf(g_time_buf, "%02d:%02d:%02d", HH, MM, SS);//任意格式化return g_time_buf;
}char* Get_Compile_Ver(void)
{uint8_t Year, Month, Day;uint8_t HH, MM, SS;Get_Compile_Date_Base(&Year, &Month, &Day);//取编译日期Get_Compile_Time_Base(&HH, &MM, &SS);//取编译时间sprintf(g_version_buf, "20%02d-%02d-%02d-%02d-%02d-%02d",Year, Month, Day, HH, MM, SS);//任意格式化return g_version_buf;
}
#ifndef _VERSION_H_
#define _VERSION_H_#include "stm32f4xx.h"char* Get_Compile_Date(void);
char* Get_Compile_Time(void);
char* Get_Compile_Ver(void);#endif
实现效果
printf("RI QI:%s\r\n",__DATE__);printf("SHI JIAN:%s\r\n",__TIME__);printf("#############################Test#########################\r\n");printf("RI QI:%s\r\n",Get_Compile_Date());printf("SHI JIAN:%s\r\n",Get_Compile_Time());printf("Soft Version:%s\r\n",Get_Compile_Ver());

编译时间是:
2023年9月11日21点03分57秒(就是刚才)
其他方式(直接宏定义实现)
参考博客:http://t.csdn.cn/BNv0F
相关文章:
初出茅庐的小李博客之根据编译时间生成软件版本号
为什么要软件版本号呢? 生成软件版本号是在软件开发和维护过程中非常重要的一项任务,它有很多意义和好处,同时也有多种常见的方法。 标识和追踪:软件版本号是唯一的标识符,用于区分不同版本的软件。这有助于开发人员和…...
“投资教父”熊晓鸽老了,IDG光环不再
作者 | 鸠白 艺馨 排版 | Cathy 监制 | Yoda 出品 | 不二研究 2017年,世界互联网大会上,“投资教父”熊晓鸽问映客的创始人:“今年你们利润能有多少?” 对方笑答:“5个亿吧!” “才五个亿?…...
XEX智能交易所:加密货币衍生品杠杆、期货和期权简介
加密货币衍生品杠杆、期货和期权简介 加密货币衍生品是指通过基于区块链技术的交易平台进行交易的各种金融工具。与传统金融衍生品类似,加密货币衍生品的交易方式是基于预测未来市场价格变动的套利策略。接下来将具体介绍不同类型的加密货币衍生品以及风险。 加密…...
记录第一次带后端团队
在过去的一个半月里我第一次作为后端开发组长角色参与公司项目从0到1的开发,记录这一次开发的经历。 1、背景介绍 首先说明一下背景。我所在的公司是做智慧社区相关业务,开发的项目是系统升级工具,方便公司实施同事安装和升级系统。 参与后…...
Python文件操作(02):读文件
一、读文本文件 打开文件读文件内容关闭文件 1、在读取文件内容后进行解码操作 """ 1. 打开文件- 路径:相对路径:当前项目(读文件.py)所在的目录下查找需要读取的文件绝对路径:文件--右键--Copy Pat…...
Flink(java版)
watermark 时间语义和 watermark 注意:数据进入flink的时间:如果用这个作为时间语义就不存在问题,但是开发中往往会用处理时间 作为时间语义这里就需要考虑延时的问题。 如上图,数据从kafka中获取出来,从多个分区中获取…...
什么是动态组件以及使用场景
文章目录 一、vue中的动态组件是什么?有什么用?二、使用demo1.tab页签中的使用2.模拟新闻页demo 三、用keep-alive包裹,保持状态总结 一、vue中的动态组件是什么?有什么用? 动态组件指可以动态切换组件的显示和隐藏。…...
CRM销售管理系统如何提高销售效率
CRM销售管理系统是帮助企业对销售活动进行管理、执行和优化的软件系统。它可以帮助企业提高销售效率,提高客户转化率,实现企业的业绩增长。那么,CRM销售管理系统好用吗? CRM销售管理系统的功能 线索管理: CRM系统可…...
纯小白安卓刷机1
文章目录 常见的英文意思刷机是什么?为什么要刷机?什么是BL锁(BootLoader锁)?我的机能够刷机吗?什么是Boot镜像/分区?什么是Recovery镜像/分区(缩写为rec)?什…...
C高级day4循环语句
1,思维导图 运行结果为: 运行结果为:...
Linux 操作系统云服务器安装部署 Tomcat 服务器详细教程
Tomcat 基本概述 Tomcat 服务器是Apache软件基金会(Apache Software Foundation)的 Jakarta 项目中的一个核心项目,由 Apache、Sun 和其他一些公司及个人共同开发而成。它是一个免费的开放源代码的 Web 应用服务器,属于轻量级应用…...
【易盾点选】
拿官网的点选做个例子吧,比较省事,水一篇~ 官网的接口目前都改成V3了,多了个dt参数,以及加密的一个函数也变动了下 点选坐标在这,加密函数未变,用逗号拼接 整个加密里的函数变了,直接重新…...
vue中打印指定dom元素
和window.print()效果一样,调出打印窗口,只是当前使用的插件是vue-print-nb 官网地址:vue-print-nb vue2中使用 安装插件 npm install vue-print-nb --save导入插件 import Print from vue-print-nb // 全局使用 Vue.use(Print);//or// 单…...
OpenCV(三十六):霍夫直线检测
1.检测直线的霍夫变换原理 2.检测直线函数HoughLines() 检测直线流程: Step1:将参数空间的坐标轴离散化。 Step2:将图像中每个非0像素通过映射关系求取在参数空间通过的方格 Step3:统计参数空间内每个方格出现的次数,选取次数大于某一值的方格作为表示直线的方格…...
文心一言 VS 讯飞星火 VS chatgpt (91)-- 算法导论8.3 4题
四、用go语言,说明如何在 O(n) 时间内,对 0 到 n 3 − 1 n^3-1 n3−1 区间内的n个整数进行排序。 文心一言: 在 O(n) 时间内对 0 到 n^3-1 区间内的 n 个整数进行排序,可以使用基数排序(Radix Sort)算法…...
keep-alive缓存三级及三级以上路由
需求需要缓存这个出入记录,当tab切换时不重新加载,当刷新页面时,或把这个关闭在重新打开时重新加载如图: (我这里用的是芋道源码的前端框架) keep-alive 1、include 包含页面组件name的这些组件页面,会被…...
vite vue项目 运行时 \esbuild\esbuild.exe 缺失 错误码 errno: -4058, code: ‘ENOENT‘,
vite vue项目运行 npm run dev 报错某个模块启动文件丢失信息 D:\PengYe_code\2\vite-vue3-admin>npm run dev> vite-vue3-admin1.0.2 dev > vitenode:events:504throw er; // Unhandled error event^Error: spawn D:\PengYe_code\2\vite-vue3-admin\node_modules\vi…...
favicon.ico网站图标不显示问题 Failed to load resource: net::ERR_FILE_NOT_FOU
上述问题主要由于网站的小图标无法显示导致的:可以检查如下部分: 1、是否存在一个favicon.ico文件在根目录下 2、如果存在,看是否写的相对路径:改为绝对路径 <link rel"shortcut icon" href"../favicon.ico&quo…...
微服务·架构组件之服务注册与发现-Nacos
微服务组件架构之服务注册与发现之Nacos Nacos服务注册与发现流程 服务注册:Nacos 客户端会通过发送REST请求的方式向Nacos Server注册自己的服务,提供自身的元数据,比如ip地址、端口等信息。 Nacos Server接收到注册请求后,就会…...
Linux驱动【day2】
mychrdev.c: #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include<linux/uaccess.h> #include<linux/io.h> #include"head.h" unsigned int major; // 保存主设备号 char kbuf[128]{0}; unsigned int…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
