初出茅庐的小李博客之根据编译时间生成软件版本号
为什么要软件版本号呢?
生成软件版本号是在软件开发和维护过程中非常重要的一项任务,它有很多意义和好处,同时也有多种常见的方法。
-
标识和追踪:软件版本号是唯一的标识符,用于区分不同版本的软件。这有助于开发人员和用户识别和追踪软件的不同发布版本。当出现问题时,可以更容易地确定特定版本中的错误或改进。
-
沟通和文档:版本号提供了一种简单而清晰的方式来与团队成员、用户和其他利益相关者进行沟通。通过版本号,人们可以明确了解到底是哪个版本的软件正在讨论,从而更容易地协作和解决问题。
-
发布计划:版本号可以用于制定和执行软件的发布计划。通过设定版本号,团队可以计划哪些功能和改进将包含在特定版本中,以及何时发布这些版本。
-
用户期望管理:版本号可以用于管理用户的期望。用户可以根据版本号了解到软件的新功能、改进和修复的问题。这有助于用户知道他们是否需要升级或采取其他行动。
-
软件稳定性:通过良好设计的版本号系统,可以区分主要版本、次要版本和修订版本。这有助于用户快速识别是否有可能引入不稳定性的大幅更改。
常见生成软件版本号的方法有哪些?
-
语义版本号(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…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
BLEU评分:机器翻译质量评估的黄金标准
BLEU评分:机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域,衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标,自2002年由IBM的Kishore Papineni等人提出以来,…...
华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...
