iT邦幫忙

2023 iThome 鐵人賽

DAY 17
0
Software Development

建構屬於自己的C/C++專案 : 我的30天CMake學習之旅系列 第 17

[Day 17] 發布軟體流程:ABI Cheacker->Release

  • 分享至 

  • xImage
  •  

在了解過Day14 從原始碼安裝庫Day16 使用包管理器安裝庫這兩種不同的安裝方法後,今天就來介紹軟體發布的流程。

首先,當我們進行軟體版本的更新時,如果這次的變更不涉及主版本號的提升,那麼我們就需要使用Debug模式來編譯原始碼後,讓ABI cheacker 檢查庫的程式介面(API)與二進制接口(ABI),確保它是否與之前的版本保持一致的相容性,否則有可能使用者無法正確使用新版本的庫。

檢查完後,接下來在進行軟體發布時,通常會使用 Release 模式來編譯原始碼,這個模式會優化程式碼,以提高執行效能。

ABI Compliance Cheacker 簡介

ABI Compliance Cheacker的主要功能是分析 API/ABI(程式介面/二進制接口)中的變更。

這個工具的操作方式是建立並比較庫的頭文件和共享物件的 ABI 。如果共享物件包含偵錯訊息(就是以Debug模式編譯專案),也可以使用 ABI Dumper 工具( https://github.com/lvc/abi-dumper )追蹤 C/C++ 庫或核心模組的 ABI 變更 。

這個工具的主要使用場景是針對軟體庫開發人員以及 Linux 系統維護人員。它特別適用於那些希望確保向後相容性的場景,這意味著舊版應用程式可以繼續運行,或者可以使用新版的庫重新編譯,而不會出現問題。這對於軟體庫的穩定性和可靠性非常重要,特別是在不斷演進的軟體環境中。

ABI Compliance Cheacker 與 ABI Dumper 安裝

  1. 安裝依賴: elfutils

$ sudo apt-get install -y elfutils

P.S. 基本上只要安裝這個額外的依賴就能動了,如果編譯過程中有錯誤,請參考GitHub頁面中的需求

  1. 安裝 abi-compliance-checker

$ git clone https://github.com/lvc/abi-compliance-checker.git
$ cd abi-compliance-checker
$ sudo make install prefix=/usr

  1. 安裝 abi-dumper

$ git clone https://github.com/lvc/abi-dumper.git
$ cd abi-dumper
$ sudo make install prefix=/usr

語法

$ {DCMAKE_BUILD_TYPE}

定義:專案的建構方式

  • 可以透過CMakeLists.txt更改
SET(CMAKE_BUILD_TYPE "Debug") # 將專案的建構方式設定為 Debug 模式
SET(CMAKE_BUILD_TYPE "Release") # 將專案的建構方式設定為 Release 模式
  • 也可以通過命令行提供此參數

$ cmake -DCMAKE_BUILD_TYPE=Debug // 將專案的建構方式設定為 Debug 模式
$ cmake -DCMAKE_BUILD_TYPE=Release // 將專案的建構方式設定為 Release 模式

ABI Compliance Cheacker

  • 生成 .dump 文件

$ abi-dumper <OLD.so> -o <ABI-0.dump> -lver 0
$ abi-dumper <NEW.so> -o <ABI-1.dump> -lver 1

  • 比較並生成報表

$ abi-compliance-checker -l NAME -old <ABI-0.dump> -new <ABI-1.dump>

範例 1.0.0 -> 1.0.1

範例會用採用Day13一樣的方式依序更新並使用ABI Compliance Cheacker
$ git clone https://github.com/m11112089/2023_iT_CMake.git
$ cd ~/2023_iT_CMake/Day17/MathFunctions

1. 使用 Debug 模式編譯1.0.0版本

$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
$ make

2. 更新 MathFunctions/src/mysqrt.cpp 原始碼

//mysqrt 1.0.0
#include "mysqrt.h"
#include <iostream>
double sqrt(double x)
{
  if (x <= 0) return 0;
  double result = x;

  for (int i = 0; i < 5; ++i) {
    if (result <= 0) {
      result = 0.1;
    }
    double delta = x - (result * result);
    result = result + 0.5 * delta / result;
    std::cout << i << "Computing sqrt of " << x << " to be " << result << std::endl;
  }
  return result;
}

3. 更新 MathFunctions/CMakeLists.txt 動態庫版本號為 1.0.1

project(MathFunctions VERSION 1.0.1 LANGUAGES CXX)
# 設定專案名稱為MathFunctions,版本為1.0.1,且此項目使用C++

4. 使用 Debug 模式編譯1.0.1版本

$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
$ make

5. 進入lib資料夾比較新舊版本差異

  • 生成 .dump 文件

$ abi-dumper libmysqrt.so.1.0.0 -o 1.0.0.dump -lver 1.0.0
$ abi-dumper libmysqrt.so.1.0.1 -o 1.0.1.dump -lver 1.0.1

kai@esoc:~/2023_iT_CMake/Day17/lib$ tree
.
├── 1.0.0.dump            <------- 生成的.dump文件⭐
├── 1.0.1.dump            <------- 生成的.dump文件⭐
├── libmysqrt.so -> libmysqrt.so.1
├── libmysqrt.so.1 -> libmysqrt.so.1.0.1
├── libmysqrt.so.1.0.0
└── libmysqrt.so.1.0.1
  • 生成比較報表

$ abi-compliance-checker -l NAME -old 1.0.0.dump -new 1.0.1.dump

生成的報表文件 compat_report.html 可以用google打開,在二進制相容性與原始碼相容性的 test Results 那一欄可以發現是100%
https://ithelp.ithome.com.tw/upload/images/20231001/20162026mvXJBrcF9i.jpg

kai@esoc:~/2023_iT_CMake/Day17/lib$ tree
.
├── 1.0.0.dump
├── 1.0.1.dump
├── compat_reports
│    └── NAME
│        └── 1.0.0_to_1.0.1
│            └── compat_report.html    <----- 生成的報表⭐
├── libmysqrt.so -> libmysqrt.so.1
├── libmysqrt.so.1 -> libmysqrt.so.1.0.1
├── libmysqrt.so.1.0.0
└── libmysqrt.so.1.0.1

6. 確認過沒有相容性問題後使用 Release 模式重新發布1.0.1版本

$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ make

P.S. 如果使用 Release 模式編譯時生成 .dump 文件會發現出現 ERROR ,因為 ABI Compliance Cheacker 需要 Debug 模式產生的 Debug information 來生成比較報表。

kai@esoc:~/2023_iT_CMake/Day17/lib$ abi-dumper libmysqrt.so.1.0.1 -o 1.0.1.dump -lver 1.0.1
Reading v-tables
ERROR: cannot find 'vtable-dumper'
ERROR: can't find debug info in object(s)

範例 1.0.1 -> 2.0.0

1. 先將剛剛使用 Release 模式編譯的1.0.1改回 Debug 模式

$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
$ make

2. 更新 MathFunctions/src/mysqrt.cpp 和 MathFunctions/include/mysqrt.h 原始碼

//mysqrt 2.0.0
#include "mysqrt.h"
#include <iostream>
double sqrt(double x, int iterations)
{
  if (x <= 0) return 0;
  double result = x;

  for (int i = 0; i < iterations; ++i) {
    if (result <= 0) {
      result = 0.1;
    }
    double delta = x - (result * result);
    result = result + 0.5 * delta / result;
    std::cout << i << "Computing sqrt of " << x << " to be " << result << std::endl;
  }
  return result;
}
//mysqrt.h 2.0.0
#ifndef MYSQRT_H
#define MYSQRT_H
double sqrt(double x, int iterations);
#endif // MYSQRT_H

3. 更新 MathFunctions/CMakeLists.txt 動態庫版本號為 2.0.0

project(MathFunctions VERSION 2.0.0 LANGUAGES CXX)
# 設定專案名稱為MathFunctions,版本為2.0.0,且此項目使用C++

4. 使用 Debug 模式編譯2.0.0版本

$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
$ make

5. 進入lib資料夾比較新舊版本差異

  • 生成 .dump 文件

$ abi-dumper libmysqrt.so.2.0.0 -o 2.0.0.dump -lver 2.0.0

  • 生成比較報表

$ abi-compliance-checker -l NAME -old 1.0.1.dump -new 2.0.0.dump

kai@esoc:~/2023_iT_CMake/Day17/lib$ tree
.
├── 1.0.0.dump
├── 1.0.1.dump
├── 2.0.0.dump           <----- 生成的.dump文件⭐
├── compat_reports
│    └── NAME
│        ├── 1.0.0_to_1.0.1
│        │   └── compat_report.html
│        └── 1.0.1_to_2.0.0
│            └── compat_report.html    <----- 生成的報表⭐
├── libmysqrt.so -> libmysqrt.so.2
├── libmysqrt.so.1 -> libmysqrt.so.1.0.1
├── libmysqrt.so.1.0.0
├── libmysqrt.so.1.0.1
├── libmysqrt.so.2 -> libmysqrt.so.2.0.0
└── libmysqrt.so.2.0.0

生成的報表文件 1.0.1_to_2.0.0 / compat_report.html 中顯示1.0.1版本和2.0.0版本相容性為0,因此要在手冊中提醒使用該庫的人員。

6. 使用 Release 模式重新發布2.0.0版本

$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ make

P.S. 如果手冊中沒有列出版本更新了什麼東西,或者是手冊中對本次更新有錯誤描述,可以透過生成出的相容性報告來 Debug , ABI Compliance Cheacker 會幫忙產生新增或移除了那一些接口的報告。

https://ithelp.ithome.com.tw/upload/images/20231002/2016202622RugFUc9d.png


上一篇
[Day 16] 使用包管理器管理庫
下一篇
[Day 18] 版本號與宏
系列文
建構屬於自己的C/C++專案 : 我的30天CMake學習之旅29
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言