目錄
概要
實現方案
概要
最近在用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)
大家可根據自己實際情況自行修改。