網站首頁 編程語言 正文
前言
好久沒寫 linphone-sdk-android
相關的文章了,本文記錄下筆者分析 linphone-sdk
版本號生成的過程。
分析
注:以下源碼基于 linphone-sdk-android 4.5.26。
修改完 linphone-sdk
的源碼后總是要編譯的,編譯完成后我們就可以得到一個帶有版本號的 aar
包,那么這個版本號是從哪里來的呢?
編譯產物
首先看下編譯完成后 build
目錄下的產物,會發現有兩個 gradle
腳本文件:build.gradle
和 upload.gradle
,打開 upload.gradle
腳本文件,在里面發現如下代碼:println("AAR artefact group is: " + artefactGroupId + ", SDK version 4.5.27")
,其中 4.5.27
就是 linphone-sdk
的版本號。
根據前面文章的分析,編譯產物一般是自動生成的,所以筆者在 linphone-sdk
目錄下搜索 upload.gradle
:find . -name '*upload.gradle*'
:
./cmake/Android/gradle/upload.gradle.cmake ./build/upload.gradle
果然找到了,其中第2行是筆者剛才打開的文件,找到并打開第1行的文件 upload.gradle.cmake
,與第2行的文件對比,發現前者就是后者的模板文件,在 upload.gradle.cmake
文件中發現:println("AAR artefact group is: " + artefactGroupId + ", SDK version @LINPHONESDK_VERSION@")
,其中 @LINPHONESDK_VERSION@
就是 linphone-sdk
的版本號了。因為此文件后綴是 .cmake
,那么聯想 @LINPHONESDK_VERSION@
應該是個 cmake 參數。
接下來在 linphone-sdk
目錄下搜索包含 LINPHONESDK_VERSION
字樣的文件:find . -type f | xargs grep 'LINPHONESDK_VERSION'
,本次查找結果較多,就不貼出來了,經過筆者的對比分析,鎖定了最后一行結果:./CMakeLists.txt:bc_compute_full_version(LINPHONESDK_VERSION)
。
CMake
打開 ./CMakeLists.txt
,在前幾行就可以找到如下代碼:
include(bctoolbox/cmake/BcToolboxCMakeUtils.cmake) bc_compute_full_version(LINPHONESDK_VERSION)
其中第2行代碼 bc_compute_full_version
就是計算 linphone-sdk
版本號的函數,其定義在第1行代碼中的 BcToolboxCMakeUtils.cmake
中,打開 BcToolboxCMakeUtils.cmake
文件并找到 bc_compute_full_version
函數:
function(bc_compute_full_version OUTPUT_VERSION) # 查找 Git 程序 find_program(GIT_EXECUTABLE git NAMES Git CMAKE_FIND_ROOT_PATH_BOTH) # 如果找到 Git 程序 if(GIT_EXECUTABLE) # 執行 git describe 命令 execute_process( COMMAND "${GIT_EXECUTABLE}" "describe" OUTPUT_VARIABLE GIT_DESCRIBE_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" ) # parse git describe version # 解析 git describe 的返回值作為版本號, 通過正則表達式的分組匹配進行解析:4.5.26-alpha-9-gb342a93 # 如果沒有解析到, 輸出錯誤信息 if (NOT (GIT_DESCRIBE_VERSION MATCHES "^([0-9]+)[.]([0-9]+)[.]([0-9]+)(-alpha|-beta)?(-[0-9]+)?(-g[0-9a-f]+)?$")) message(FATAL_ERROR "invalid git describe version: '${GIT_DESCRIBE_VERSION}'") endif() # 設置分組1為主要版本: ([0-9]+) -> 4 set(version_major ${CMAKE_MATCH_1}) # 設置分組2為次要版本: ([0-9]+) -> 5 set(version_minor ${CMAKE_MATCH_2}) # 設置分組3為補丁版本: ([0-9]+) -> 26 set(version_patch ${CMAKE_MATCH_3}) # 如果解析到分組4: (-alpha|-beta)? -> -alpha, 則去掉前面的‘-', 得到后面的‘alpha|beta', 賦值給 version_prerelease if (CMAKE_MATCH_4) string(SUBSTRING "${CMAKE_MATCH_4}" 1 -1 version_prerelease) endif() # 如果解析到分組5:(-[0-9]+)? -> -9, 則去掉前面的‘-', 得到后面的‘9', 賦值給 version_commit if (CMAKE_MATCH_5) string(SUBSTRING "${CMAKE_MATCH_5}" 1 -1 version_commit) endif() # 如果解析到分組6: (-g[0-9a-f]+)? -> -gb342a93, 則去掉前面的‘-g', 得到后面的‘b342a93', 賦值給 version_hash if (CMAKE_MATCH_6) string(SUBSTRING "${CMAKE_MATCH_6}" 2 -1 version_hash) endif() # interpret untagged hotfixes as pre-releases of the next "patch" release # 如果沒有 version_prerelease, 但是有 version_commit, 認為是此補丁程序是下一個補丁版本的預發版本, 即將補丁版本號+1 # 并設置 version_prerelease 為 "pre" if (NOT version_prerelease AND version_commit) math(EXPR version_patch "${version_patch} + 1") set(version_prerelease "pre") endif() # format full version # 拼接主、次、補丁版本號 set(full_version "${version_major}.${version_minor}.${version_patch}") # 如果有 version_prerelease if (version_prerelease) # 版本號追加 "-pre" string(APPEND full_version "-${version_prerelease}") # 如果有 version_commit if (version_commit) # 版本號追加 ".9+b342a93" string(APPEND full_version ".${version_commit}+${version_hash}") endif() endif() # 省略其他檢查邏輯 # 設置版本號為CMake緩存參數, 完整版本號: 4.5.27-pre.9+b342a93 set(${OUTPUT_VERSION} "${full_version}" CACHE STRING "" FORCE) endif() endfunction()
下面就是分析 bc_compute_full_version
函數了。
首先查找 Git
程序,如果找到 Git
程序,函數才會繼續,否則無法計算版本號。
找到 Git
程序后會執行 git describe
命令,此命令會基于當前可用的 ref 給一個人類可讀的名稱。
- 如果當前最新的 commit 上有 TAG,且 TAG 必須有描述信息或者帶有
-- tags
參數,此命令則返回此 TAG 名稱:4.5.26, - 否則返回離當前最近的 TAG 名稱 + 此 TAG 之后的提交次數 + 當前的 commit hash 值前 7 位:4.5.26-9-gb342a93,其中 'g' 表示是
Git
,
具體可查看 git-describe。
假設 git describe
命令返回的是:4.5.26-alpha-9-gb342a93
,接下來通過正則表達式的分組匹配解析返回的結果。
正則表達式:
^([0-9]+)[.]([0-9]+)[.]([0-9]+)(-alpha|-beta)?(-[0-9]+)?(-g[0-9a-f]+)?$,
其分為以下 6 組:
-
([0-9]+)
為第一組CMAKE_MATCH_1
,對應 4, -
([0-9]+)
為第二組CMAKE_MATCH_2
,對應 5, -
([0-9]+)
為第三組CMAKE_MATCH_3
,對應 26, -
(-alpha|-beta)?
為第四組CMAKE_MATCH_4
,可為空,對應 -alpha, -
(-[0-9]+)?
為第五組CMAKE_MATCH_5
,可為空,對應 -9, -
(-g[0-9a-f]+)?
為第六組CMAKE_MATCH_6
,可為空,對應 gb342a93,
分組一、分組二和分組三分別作為主要版本、次要版本和補丁版本:4.5.26。
如果解析到分組四: -alpha
,則去掉前面的 -
,得到后面的 alpha
,并賦值給 version_prerelease
變量;如果解析到分組五: -9
,則去掉前面的 -
,得到后面的 9
,并賦值給 version_commit
變量;如果解析到分組六: -gb342a93
,則去掉前面的 -g
,得到后面的 b342a93
,并賦值給 version_hash
變量。
如果沒有 version_prerelease
變量,但是有 version_commit
變量,則認為此補丁程序是下一個補丁版本的預發布版本,即將補丁版本號增加一個版本并賦值version_prerelease
變量為 pre
。
拼接主要版本、次要版本和補丁版本為:4.5.27
,并賦值給 full_version
變量。
如果有 version_prerelease
變量,則 full_version
變量追加 -pre
,此時版本號為:4.5.27-pre
;如果有 version_commit
變量,則版本號再追加 version_commit
和 version_hash
變量的值 .9+b342a93
,得到版本號:4.5.27-pre.9+b342a93
。
最終得到 linphone-sdk
的版本號:4.5.27-pre.9+b342a93
。
總結
本文記錄了筆者查找 linphone-sdk
生成版本號的過程,同時分析了版本號的生成邏輯,linphone-sdk
通過獲取 Git
提交記錄和 TAG 來生成版本號:
- 執行
git describe
命令獲取可讀Git
提交信息, - 通過正則表達式的分組配置模式解析得到的
Git
提交信息, - 最后根據分組信息修正并拼接得到完整的版本號。
利用 Git
提交信息來生成版本號這種方式,我們在寫 SDK 時或許可以借鑒下。
原文鏈接:https://juejin.cn/post/7143905843124109349
相關推薦
- 2022-06-08 HDFS免重啟掛載新磁盤_服務器其它
- 2022-08-14 使用Python去除字符串中某個字符的多種實現方式比較_python
- 2022-09-13 go開源項目用戶名密碼驗證的邏輯鬼才寫法_Golang
- 2022-09-09 PyCharm?設置數據庫,查詢數據庫語句方式_python
- 2022-11-18 React中props使用教程_React
- 2023-06-20 k8s應用監控探針詳解_云其它
- 2022-09-14 Python使用pip安裝Matplotlib的方法詳解_python
- 2022-07-18 RestTemplate轉發MultipartFile
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支