VS 基于git工程编译版本自动添加版本号

目录

概要

实现方案


概要

最近在用visual Studio 开发MFC项目时,需要在release版本编译后的exe文件自动追加版本信息。

由于我们用的git工程管理,即需要基于最新的git 提交来打版本。

比如: MFCApplication_V1.0.2_9.exe

由于git 提交信息是hash 记录,不便于看出不同版本时间先后顺序。这里不使用commit 记录。

换个思路,可用最新的commit  count 计数来区分版本。但这个是个纯数字。

如果用tag,可以写成任意样式,是个不错的思路。所以决定采用tag自加方式。

但是如果每笔commit 都打tag,感觉有点滥用tag了。故采用在正式出release版本编译时才让tag自加。

实现方案

获取下一个要打的tag 信息。

下面是一个根据当前tag 生成下一tag的脚本:get_next_tag.bat

REM 配置后可支持中文
chcp 65001
@echo off
::开启后以便让变量即时生效
setlocal enabledelayedexpansionset OUTPUT_FILE=build_tag_info.txt:: --------------------------------
:: 获取当前提交的 tag(如果有)
:: 场景:
:: 1.从未打过tag; 
:: 2. 当前提交不带tag;
:: 3. 当前提交就带tag 含反复编译情况。
:: :: --------------------------------
for /f "delims=" %%i in ('git tag --points-at HEAD') do (set COMMIT_TAG=%%i
)if "!COMMIT_TAG!"=="" (echo "head has no tag"
) else (echo "Current has tag, not need to increase"set NEXT_TAG=%COMMIT_TAG%REM @pausegoto save_info
):: 获取最后一个 tag, 命令用'""' 包含,防止不能识别=
for /f "delims=" %%i in ('"git describe --tags --abbrev=0"') do set LAST_TAG=%%i:: 去掉前缀V(如果有)
echo LAST_TAG=!LAST_TAG!
if "!LAST_TAG!"==""  (set MAJOR=1set MINOR=0set PATCH=0
) else (set TAG_CLEAN=%LAST_TAG:V=%echo "cur tag: !TAG_CLEAN! .need new tag:  ":: 拆分为主版本.次版本.补丁for /f "tokens=1,2,3 delims=." %%a in ("!TAG_CLEAN!") do (set MAJOR=%%aset MINOR=%%bset PATCH=%%c)echo "before PATCH=!PATCH!":: 如果 PATCH 为空,则设为 0if "!MAJOR!"=="" set MAJOR=1if "!MINOR!"=="" set MINOR=0if "!PATCH!"=="" set PATCH=0echo "PATCH=!PATCH!":: 补丁号 +1set /a PATCH+=1
)echo MAJOR=!MAJOR!
echo MINOR=!MINOR!
echo PATCH=!PATCH!:: 组合新的 tag
set NEW_TAG=V!MAJOR!.!MINOR!.!PATCH!:: 打印输出
echo LAST_TAG=%LAST_TAG%
set NEXT_TAG=!NEW_TAG!:: 提交tag 
git tag !NEXT_TAG!
git push origin --tags:: 输出调试信息
:save_info
echo NEXT_TAG=!NEXT_TAG!
REM echo BUILD_TIME=%BUILD_TIME%:: 保存到文件, ">"左边不要加空格,避免生成文件含空格
echo !NEXT_TAG!> "%OUTPUT_FILE%":: get git count
for /f "delims=" %%i in ('git rev-list --count HEAD') do set GIT_COUNT=%%i
echo GIT_COUNT: !GIT_COUNT!
echo !GIT_COUNT!>> "%OUTPUT_FILE%"endlocal

copy_files.bat

编译后,自动追加tag信息,并把要拷贝的文件拷贝到output目录下。

REM 配置后可支持中文
chcp 65001
@echo off
setlocal enabledelayedexpansionset "TargetPath=%~1"
set "ProjectDir=%~2"
set "TargetName=%~3"
set "TargetExt=%~4"
echo "TargetPath=%TargetPath%"
echo "ProjectDir=%ProjectDir%"
echo "TargetName=%TargetName%"
echo "TargetExt=%TargetExt%"
set GIT_RECORD_FILE=%ProjectDir%build_tag_info.txtset /p BUILD_TAG=<"%GIT_RECORD_FILE%"
echo BUILD_TAG=%BUILD_TAG%::读取第二行count计数
for /f "usebackq delims=" %%A in ("%GIT_RECORD_FILE%") do (set /a LINE_NUM+=1if !LINE_NUM! EQU 2 (set "SECOND_LINE=%%A"goto :findCount)
):findCount
SET GIT_COUNT=!SECOND_LINE!
echo "SECOND_LINE: !SECOND_LINE!"
echo "GIT_COUNT=!SECOND_LINE!"set "NEW_NAME=%TargetName%_!BUILD_TAG!_!SECOND_LINE!%TargetExt%"::copy 前先删除之前的目标文件,此时不能删除!TargetPath!代表的文件
set TARGET_ABS_PATH=!TargetPath!\..\!NEW_NAME!
echo ".............................Renaming to !TARGET_ABS_PATH!"
for %%f in (!TargetPath!\..\!TargetName!*.exe) do (REM 检查文件名是否不等于 !TargetName!.exeif /i not "%%f"=="!TargetPath!\..\!TargetName!.exe" (echo will delete %%fdel "%%f")
)REM 保存当前路径到环境变量
set PREV_PATH=%CD%
cd ..
if exist  .\output\!TargetName!*.exe      (del /S /Q output\!TargetName!*.exe)        else (md output\ )echo "...................start copy"
echo TargetPath=!TargetPath!
echo "NEW_NAME=!NEW_NAME!"
::需要重命名,不要使用xcopy
copy !TargetPath!                output\!NEW_NAME!  /Y::copy other files to Debug\Release 便于调试
xcopy Config.ini                 !TargetPath!\..  /D /Y::copy other files to output
xcopy Config.ini                 output\  /D /Y
xcopy README.md                output\  /D /Ycd /D %PREV_PATH%del  !GIT_RECORD_FILE!endlocal

最后在项目属性中——生成事件——生成后事件,为Release版本配置:

call "$(ProjectDir)get_next_tag.bat"
call "$(ProjectDir)copy_files.bat"  "$(TargetPath)" $(ProjectDir) "$(TargetName)" $(TargetExt)

大家可根据自己实际情况自行修改。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/901491.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nginx入门,部署静态资源,反向代理,负载均衡使用

Nginx在linux上部署静态资源 概念介绍 Nginx可以作为静态web服务器来部署静态资源。这里所说的静态资源是指在服务端真实存在&#xff0c;并且能够直接展示的一些文件&#xff0c;比如常见的html页面、css文件、js文件、图片、视频等资源。 相对于Tomcat&#xff0c;Nginx处理…

【字节跳动AI论文】Seaweed-7B:视频生成基础模型的高成本效益培训

摘要&#xff1a;本技术报告介绍了一种经济有效的视频生成基础模型训练策略。 我们提出了一种中等规模的研究模型&#xff0c;大约有70亿个参数&#xff08;7B&#xff09;&#xff0c;称为Seaweed-7B&#xff0c;使用665,000个H100 GPU小时从头开始训练。 尽管使用适度的计算资…

Java单例模式:实现全局唯一对象的艺术

精心整理了最新的面试资料和简历模板&#xff0c;有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 一、什么是单例模式&#xff1f; 单例模式&#xff08;Singleton Pattern&#xff09;是一种创建型设计模式&#xff0c;确保一个类只有一个实例&#xff0c…

Oracle 复制表结构(含索引、主键)操作指南

Oracle 复制表结构&#xff08;含索引、主键&#xff09;操作指南 1. 复制基础表结构 -- 创建空表结构&#xff08;不复制数据&#xff09; CREATE TABLE new_table AS SELECT * FROM old_table WHERE 10;2. 复制主键约束 -- 查询原表主键信息 SELECT constraint_name, co…

React 更新state中的对象

更新 state 中的对象 state 中可以保存任意类型的 JavaScript 值&#xff0c;包括对象。但是&#xff0c;你不应该直接修改存放在 React state 中的对象。相反&#xff0c;当你想要更新一个对象时&#xff0c;你需要创建一个新的对象&#xff08;或者将其拷贝一份&#xff09;…

基于 GoFrame 框架的电子邮件发送实践:优势、特色与经验分享

1. 引言 如果你是一位有1-2年Go开发经验的后端开发者&#xff0c;可能已经熟悉了Go语言在性能和并发上的天然优势&#xff0c;也曾在项目中遇到过邮件发送的需求——无论是用户注册时的激活邮件、系统异常时的通知&#xff0c;还是营销活动中的批量促销邮件&#xff0c;邮件功…

AndroidStudio编译报错 Duplicate class kotlin

具体的编译报错信息如下&#xff1a; Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and kotlin-stdlib-jdk8-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21) D…

后端面试问题收集以及答案精简版

思路 不要问什么答什么 要学会扩充 比如问你go map的原理 map 是什么 数据结构&#xff0c;字典&#xff0c;k/v 结构map的应用场景有哪些 快速查找、计数器、配置管理、去重、缓存实现map有哪些限制 无序性、非线程安全的读写map的key的访问 v: mp[key] v,ok : mp[key] for…

MicroPython 开发ESP32应用教程 之 I2S、INMP441音频录制、MAX98357A音频播放、SD卡读写

本课程我们讲解Micropython for ESP32 的i2s及其应用&#xff0c;比如INMP441音频录制、MAX98357A音频播放等&#xff0c;还有SD卡的读写。 一、硬件准备 1、支持micropython的ESP32S3开发板 2、INMP441数字全向麦克风模块 3、MAX98357A音频播放模块 4、SD卡模块 5、面包板及…

UE5 物理模拟 与 触发检测

文章目录 碰撞条件开启模拟关闭模拟 多层级的MeshUE的BUG 触发触发条件 碰撞 条件 1必须有网格体组件 2网格体组件必须有网格&#xff0c;没有网格虽然可以开启物理模拟&#xff0c;但是不会有任何效果 注意开启的模拟的网格体组件会计算自己和所有子网格的mesh范围 3只有网格…

微信小程序 - swiper轮播图

官方文档&#xff1a;https://developers.weixin.qq.com/miniprogram/dev/component/swiper.html <swiper indicator-color"ivory" indicator-active-color"#d43c33" indicator-dots autoplay><swiper-item><image src"/images/banner…

深入探究C#官方MCP:开启AI集成新时代

一、引言 在当今数字化时代&#xff0c;.NET 开发领域不断演进&#xff0c;而 C# 官方 MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09;的出现&#xff0c;无疑为开发者们带来了全新的机遇与挑战。随着人工智能技术的迅猛发展&#xff0c;将 AI…

二分查找法

使用二分查找法的前提&#xff1a;&#xff08;1&#xff09;数组为有序数组. &#xff08;2&#xff09;数组中无重复元素. 二分的两种写法&#xff1a; 方法一&#xff1a;[left&#xff0c;right] class Solution { public:int search(vector<int>& nums, int …

HarmonyOS:页面滚动时标题悬浮、背景渐变

一、需求场景 进入到app首页或者分页列表首页时&#xff0c;随着页面滚动&#xff0c;分类tab要求固定悬浮在顶部。进入到app首页、者分页列表首页、商品详情页时&#xff0c;页面滚动时&#xff0c;顶部导航栏&#xff08;菜单、标题&#xff09;背景渐变。 二、相关技术知识点…

鲲鹏+昇腾部署集群管理软件GPUStack,两台服务器搭建双节点集群【实战详细踩坑篇】

前期说明 配置&#xff1a;2台鲲鹏32C2 2Atlas300I duo&#xff0c;之前看网上文档&#xff0c;目前GPUstack只支持910B芯片&#xff0c;想尝试一下能不能310P也部署试试&#xff0c;毕竟华为的集群软件要收费。 系统&#xff1a;openEuler22.03-LTS 驱动&#xff1a;24.1.rc…

React中 点击事件写法 的注意(this、箭头函数)

目录 ‌1、错误写法‌&#xff1a;onClick{this.acceptAlls()} ‌2、正确写法‌&#xff1a;onClick{this.acceptAlls}&#xff08;不带括号&#xff09; 总结 方案1&#xff1a;构造函数绑定 方案2&#xff1a;箭头函数包装方法&#xff08;更简洁&#xff09; 方案3&am…

【路由交换方向IE认证】BGP选路原则之Weight属性

文章目录 一、路由器BGP路由的处理过程控制平面和转发平面选路工具 二、BGP的选路顺序选路的前提选路顺序 三、Wight属性选路原则规则9与规则11的潜移默化使用Weight值进行选路直接更改Weight值进行选路配合使用route-map进行选路 四、BGP邻居建立配置 一、路由器BGP路由的处理…

Missashe考研日记-day20

Missashe考研日记-day20 1 高数 学习时间&#xff1a;2h30min学习内容&#xff1a; 今天当然是刷题啦&#xff0c;做不等式的证明板块的真题&#xff0c;证明题懂的都懂&#xff0c;难起来是真的一点思路都没有&#xff0c;这个板块还没做完&#xff0c;做完再总结题型。 2…

了解JVM

一.JVM概述 1.JVM的作用 把字节码编译为机器码去执行,负责把字节码装载到虚拟机中 现在的 JVM 不仅可以执行 java 字节码文件,还可以执行其他语言编译后的字节码文件,是一个跨语言平台 2.JVM的组成部分 类加载器&#xff08;ClassLoader&#xff09;运行时数据区&#x…

LeetCode LCR157 套餐内商品的排列顺序

生成字符串的全部排列&#xff08;去重&#xff09;&#xff1a;从问题到解决方案的完整解析 问题背景 在编程和算法设计中&#xff0c;生成字符串的所有排列是一个经典问题。它不仅出现在算法竞赛中&#xff0c;也在实际开发中有着广泛的应用&#xff0c;比如生成所有可能的…