Table of Contents:

This guide aims to explain how to use the apertis-abi-compare tool in order to detect API/ABI breakage between two versions of a library package.

Other Apertis documents are available:

How to use apertis-abi-compare tool

First, install the apertis-dev-tools package (>= 0.2021.11) providing the apertis-abi-compare tool.

1
sudo apt install apertis-dev-tools

Then, build you library package using gbp buildpackage (or dpkg-buildpackage) for example.

1
2
3
4
5
6
7
8
user@apertis:~$ cd dev/
user@apertis:~/dev$ git clone https://gitlab.apertis.org/pkg/zlib.git
user@apertis:~/dev$ cd zlib/
user@apertis:~/dev/zlib$ dch -i
...
# work on packaging update
...
user@apertis:~/dev/zlib$ dpkg-buildpackage

This has generated several files in the higher level folder:

user@apertis:~/dev/zlib$ cd ..
user@apertis:~/dev$ ls -l
total 1144
-rw-r--r--  1 user user  96856 Apr 15 09:33 lib32z1-dbgsym_1.2.11.dfsg-2+deb11u1+apertis0_amd64.deb
-rw-r--r--  1 user user  96620 Apr 15 09:33 lib32z1-dev_1.2.11.dfsg-2+deb11u1+apertis0_amd64.deb
-rw-r--r--  1 user user  94264 Apr 15 09:33 lib32z1_1.2.11.dfsg-2+deb11u1+apertis0_amd64.deb
drwxr-xr-x 15 user user   4096 Apr 15 09:33 zlib
-rw-r--r--  1 user user 102404 Apr 15 09:33 zlib1g-dbgsym_1.2.11.dfsg-2+deb11u1+apertis0_amd64.deb
-rw-r--r--  1 user user 191712 Apr 15 09:33 zlib1g-dev_1.2.11.dfsg-2+deb11u1+apertis0_amd64.deb
-rw-r--r--  1 user user  50368 Apr 15 09:33 zlib1g-udeb_1.2.11.dfsg-2+deb11u1+apertis0_amd64.udeb
-rw-r--r--  1 user user  92172 Apr 15 09:33 zlib1g_1.2.11.dfsg-2+deb11u1+apertis0_amd64.deb
-rw-r--r--  1 user user  23968 Apr 15 09:33 zlib_1.2.11.dfsg-2+deb11u1+apertis0.debian.tar.xz
-rw-r--r--  1 user user   1903 Apr 15 09:33 zlib_1.2.11.dfsg-2+deb11u1+apertis0.dsc
-rw-r--r--  1 user user  12293 Apr 15 09:33 zlib_1.2.11.dfsg-2+deb11u1+apertis0_amd64.buildinfo
-rw-r--r--  1 user user   4127 Apr 15 09:33 zlib_1.2.11.dfsg-2+deb11u1+apertis0_amd64.changes
-rw-r--r--  1 user user 370248 Apr 14 19:18 zlib_1.2.11.dfsg.orig.tar.gz

Only .deb and .dsc files are used to check API/ABI breakage, so let’s move them to a new folder for clarity:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
user@apertis:~/dev$ mkdir zlib_test_api
user@apertis:~/dev$ mv *.deb *.dsc zlib_test_api
user@apertis:~/dev$ ls -l zlib_test_api/
total 676
-rw-r--r-- 1 user user  96856 Apr 15 09:33 lib32z1-dbgsym_1.2.11.dfsg-2+deb11u1+apertis0_amd64.deb
-rw-r--r-- 1 user user  96620 Apr 15 09:33 lib32z1-dev_1.2.11.dfsg-2+deb11u1+apertis0_amd64.deb
-rw-r--r-- 1 user user  94264 Apr 15 09:33 lib32z1_1.2.11.dfsg-2+deb11u1+apertis0_amd64.deb
-rw-r--r-- 1 user user 102404 Apr 15 09:33 zlib1g-dbgsym_1.2.11.dfsg-2+deb11u1+apertis0_amd64.deb
-rw-r--r-- 1 user user 191712 Apr 15 09:33 zlib1g-dev_1.2.11.dfsg-2+deb11u1+apertis0_amd64.deb
-rw-r--r-- 1 user user  92172 Apr 15 09:33 zlib1g_1.2.11.dfsg-2+deb11u1+apertis0_amd64.deb
-rw-r--r-- 1 user user   1903 Apr 15 09:33 zlib_1.2.11.dfsg-2+deb11u1+apertis0.dsc

Now, we can call apertis-abi-compare to compare API/ABI between our freshly created package with the one available in the apt repository. We just need to give as an argument to apertis-abi-compare the folder containing our .deb and .dsc files:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
user@apertis:~/dev$ apertis-abi-compare zlib_test_api
Checking for ABI/API breakage!
INFO: abi-compliance-checker requires having Build-Deps installed
INFO: Trying to install them now:
['debhelper', 'gcc-multilib<!nobiarch>', 'dpkg-dev']
...
...
Comparing ABIs ...
Comparing APIs ...
Creating compatibility report ...
Binary compatibility: 100%
Source compatibility: 100%
Total binary compatibility problems: 0, warnings: 0
Total source compatibility problems: 0, warnings: 0
Report: compat_reports/z/1:1.2.11.dfsg-2+deb11u1+apertis0bv2023dev2b2_to_1:1.2.11.dfsg-2+deb11u1+apertis0/compat_report.html

apertis-abi-compare reads the .dsc file to determine and download the previous version of the library available in the apt repository. Then, it extracts the .deb files of both versions in order to compare headers and libraries. apertis-abi-compare uses abi-compliance-checker internally to compare versions. Thus, a library XML descriptor file can be provided with the library package. If the descriptor file is not provided, apertis-abi-compare tries to generate a basic one.

A summary of the analysis is displayed with the number of problems detected and a comprehensive HTML report has been generated at compat_reports/z/1:1.2.11.dfsg-2+deb11u1+apertis0bv2023dev2b2_to_1:1.2.11.dfsg-2+deb11u1+apertis0/compat_report.html.

This report contains a list of problems detected regarding the Binary Compatibility and the Source Compatibility, both in separate tabs.

The first paragraph Test Info contains information about the analyzed library including the library name, compared package versions and architecture.

A second paragraph Test Results reports how many header files, libraries and symbols/types have been analyzed with a percentage of compatibility between both versions. In our example, the compatibility is 100% because we compared the same version of the zlib.

Next, Problem Summary summarizes all issues detected. These issues are sorted by categories: Added Symbols, Removed Symbols, Problems with Data Types, Problems with Symbols and Problems with Constants. Then, by their severity: High, Medium or Low.

Finally, the last parts contain respectively the list of Header files and Libraries analyzed.

Now, let’s simulate an API breakage by downloading a very old zlib package (1:1.2.3-11) from snapshot.debian.org and compare it to the new version (1:1.2.11.dfsg-2). Because the old version has less functionalities compared to the new one, abi-compliance-checker will complain about API/ABI breakages.

The package automatically downloaded by apertis-abi-compare from the apt repository will always be considered as older than the local one.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
user@apertis:~/dev$ mkdir zlib_test_api_broken
user@apertis:~/dev$ wget https://snapshot.debian.org/archive/debian/20060308T000000Z/pool/main/z/zlib/zlib_1.2.3-11.dsc
user@apertis:~/dev$ wget https://snapshot.debian.org/archive/debian/20060318T000000Z/pool/main/z/zlib/zlib1g_1.2.3-11_amd64.deb
user@apertis:~/dev$ wget https://snapshot.debian.org/archive/debian/20060318T000000Z/pool/main/z/zlib/zlib1g-dev_1.2.3-11_amd64.deb
user@apertis:~/dev$ mv *.deb *.dsc zlib_test_api_broken
user@apertis:~/dev$ ls -l zlib_test_api_broken/
total 500
-rw-r--r-- 1 user user 430142 Oct  8  2009 zlib1g-dev_1.2.3-11_amd64.deb
-rw-r--r-- 1 user user  73222 Oct  8  2009 zlib1g_1.2.3-11_amd64.deb
-rw-r--r-- 1 user user    735 Oct  8  2009 zlib_1.2.3-11.dsc
user@apertis:~/dev$ apertis-abi-compare zlib_test_api_broken/
Checking for ABI/API breakage!
INFO: abi-compliance-checker requires having Build-Deps installed
INFO: Trying to install them now:
['debhelper', 'dbs', 'libc6-dev-powerpc', 'libc6-dev-i386', 'lib64c-dev']
...
...
Comparing ABIs ...
Comparing APIs ...
Creating compatibility report ...
Binary compatibility: 67.6%
Source compatibility: 68.2%
Total binary compatibility problems: 28, warnings: 2
Total source compatibility problems: 27, warnings: 12
Report: compat_reports/z/1:1.2.11.dfsg-2+deb11u1+apertis0bv2023dev2b2_to_1:1.2.3-11/compat_report.html

Now, we see the binary and source compatibilities fell to 68%. Several problems and warnings are reported as well.

Opening the report will give use more information about the detected issues:

The Problem Summary informs us that 27 symbols have been removed with a high severity. Two problems have been detected regarding data types or constants, classified in low severity and one medium severity issue with symbols has been detected.

Then, we have the list of Removed Symbols

Followed by the list of detected Problems:

By clicking on the + button, the report displays the detected change and its implications.

The source compatibility tab reports similar information than the binary compatibility tab.

How to enable the apertis-abi-compare job in the build pipeline

The apertis-abi-compare tool is only useful for comparing ABI of different versions of a library. Thus, it is useless to run the tool on packages not providing a library, and consequently the associated pipeline job is not enabled by default. To enable the apertis-abi-compare job in the build pipeline, you just need to create an empty debian/apertis/abi-compare in your package.

1
2
3
4
5
6
cd pkg/my_lib
git checkout apertis/v2023
touch debian/apertis/abi-compare
git add debian/apertis/abi-compare
git commit -m"Add debian/apertis/abi-compare to enable the apertis-abi-compare job"
git push origin

Pushing the commit adding the debian/apertis/abi-compare file will trigger the pipeline with a new job called abi-checker.

Let’s use the tests/zlib repository as an example. The last two commits added a debian/apertis/abi-compare file and created a new debian/changelog entry. Then, go to the CI/CD > Pipelines page. As shown in the screenshot below, a new abi-checker job is available.

By clicking on it, the log is displayed. In case no ABI breaks are detected, the job will succeed and the report generated by abi-compliance-checker can be downloaded by clicking on Download.

The generated report is also directly displayable by using the Browse button.

Now, let’s take a look at the tests/zlib_broken repository. Like in the previous example for apertis-abi-compare, this repository contains an old version of zlib in order to simulate an ABI breakage. The pipeline will try to upload the old version 1.2.3 over the current version 1.2.11, thus some functionalities will be removed and apertis-abi-compare will detect a breakage. By looking at its CI/CD > Pipelines page, we see the abi-checker job fails.

The job log contains some information regarding the ABI breaks detected, but a comprehensive report can be downloaded.

This report contains all information useful to understand the ABI breaks detected as explained in the previous part above.

Limitations

  • The apertis-abi-compare tool only supports source packages providing a single library. For source packages building multiple libraries, only one library will be analyzed.

  • The abi-compliance-checker tool which is used by apertis-abi-compare is only able to compare libraries for the current architecture. Indeed, it compiles headers in order to create an ABI dump. Since GitLab runners run on Intel machines, this means only x86_64 can be checked and we can’t check the ABI of ARM packages.

FAQ

abi-compliance-checker fails to build headers

abi-compliance-checker can fails to build headers of your library. In this case, you need to provide and customize a library XML descriptor. Please refer to the documentation of abi-compliance-checker to know how to write it: library descriptor documentation.

To be detected by apertis-abi-compare, the descriptor file must be named abi-descriptor.xml and must be installed by your lib***-dev package in /usr/share/doc/lib***-dev/. The location of the installation does not matter because apertis-abi-compare will scan all files installed by the lib***-dev package to find a file called abi-descriptor.xml.

References