首頁 > 軟體

linphone-sdk-android版本號生成解析

2022-09-18 22:04:41

前言

好久沒寫 linphone-sdk-android 相關的文章了,本文記錄下筆者分析 linphone-sdk 版本號生成的過程。

分析

注:以下原始碼基於 linphone-sdk-android 4.5.26。

修改完 linphone-sdk 的原始碼後總是要編譯的,編譯完成後我們就可以得到一個帶有版本號的 aar 包,那麼這個版本號是從哪裡來的呢?

編譯產物

首先看下編譯完成後 build 目錄下的產物,會發現有兩個 gradle 指令碼檔案:build.gradleupload.gradle,開啟 upload.gradle 指令碼檔案,在裡面發現如下程式碼:println("AAR artefact group is: " + artefactGroupId + ", SDK version 4.5.27"),其中 4.5.27 就是 linphone-sdk 的版本號。

根據前面文章的分析,編譯產物一般是自動生成的,所以筆者在 linphone-sdk 目錄下搜尋 upload.gradlefind . -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_commitversion_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 時或許可以借鑑下。

以上就是linphone-sdk-android版本號生成解析的詳細內容,更多關於linphone sdk android 版本號的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com