ABICOMPAT(1)
๐ธ NAME ๐ธ
Okay so this is abicompat from the Libabigail fam โ section 1 of the manual, ABICOMPAT(1) energy โ and bestie, it checks ABI compatibility. Specifically: abicompat checks that an application that links against a given shared library is still ABI compatible with a subsequent version of that library. If the new version of the library introduces an ABI incompatibility, then abicompat hints the user at what exactly that incompatibility is. No cap.
๐ INVOCATION ๐
Here's the shape of it, literally:
abicompat [options] [<application> <shared-library-first-version> <shared-library-second-version>]
๐ ENVIRONMENT ๐
- Parallel processing โ The environment variable
ABIGAIL_THREAD_POOL_SIZEcan be set to either an integer, or a percentage value, e.g.10%. The integer value defines the number of threads used by Libabigail to perform parallel processing when applicable. The percentage defines the percentage of the total available cores to use by Libabigail to perform the parallel processing when applicable.
By default, Libabigail uses all the available cores to perform its parallel processing.
โจ OPTIONS โจ
Every flag, accounted for. Let's get into it, bestie:
--app-debug-info-dir,--appd <path-to-app-debug-info-directory>โ set the path to the directory under which the debug information of the application is supposed to be laid out. This is useful for application binaries for which the debug info is in a separate set of files.--btfโ when comparing binaries, extract ABI information from BTF debug information, if present.--ctfโ when comparing binaries, extract ABI information from CTF debug information, if present.--fail-no-debug-infoโ if no debug info was found, then this option makes the program fail. Otherwise, without this option, the program will attempt to compare properties of the binaries that are not related to debug info, like pure ELF properties.--helpโ display a short help about the command and exit.--ignore-sonameโ ignore differences in the SONAME when doing a comparison.--lib-debug-info-dir1,--libd1 <path-to-lib1-debug-info>โ set the path to the directory under which the debug information of the first version of the shared library is supposed to be laid out. This is useful for shared library binaries for which the debug info is in a separate set of files.--lib-debug-info-dir2,--libd2 <path-to-lib1-debug-info>โ set the path to the directory under which the debug information of the second version of the shared library is supposed to be laid out. This is useful for shared library binaries for which the debug info is in a separate set of files.--list-undefined-symbols,-uโ display the list of undefined symbols of the application and exit.--no-show-locsโ do not show information about where in the second shared library the respective type was changed.--show-base-names,-bโ in the resulting report emitted by the tool, this option makes the application and libraries be referred to by their base names only; not by a full absolute name. This can be useful for use in scripts that wants to compare names of the application and libraries independently of what their directory names are.--suppressions,--suppr <path-to-suppressions>โ use a suppression specification file located at path-to-suppressions. Note that this option can appear multiple times on the command line; all the suppression specification files are then taken into account.โversion,-vโ display the version of the program and exit.--thread-pool-size <N|N%>,-j <N|N%>โ set the size of the thread pool used by Libabigail for parallel processing. The size is either the number of threads or a percentage of the total number of available cores on the machine. By default, all the available cores of the machine are used for parallel processing.
Note that the environment variable ABIGAIL_THREAD_POOL_SIZE can also be set to similar values. This command line option, if present, supersedes the value of the environment variable.
--weak-modeโ this triggers the weak mode ofabicompat. In this mode, only one version of the library is required. That is,abicompatis invoked like this:
abicompat --weak-mode <the-application> <the-library>
Note that the --weak-mode option can even be omitted if only one version of the library is given, along with the application; in that case, abicompat automatically switches to operate in weak mode:
abicompat <the-application> <the-library>
In this weak mode, the types of functions and variables exported by the library and consumed by the application (as in, the symbols of these functions and variables are undefined in the application and are defined and exported by the library) are compared to the version of these types as expected by the application. And if these two versions of types are different, abicompat tells the user what the differences are.
In other words, in this mode, abicompat checks that the types of the functions and variables exported by the library mean the same thing as what the application expects, as far as the ABI is concerned.
Note that in this mode, abicompat doesnโt detect exported functions or variables (symbols) that are expected by the application but that are removed from the library. That is why it is called weak mode. ๐
๐งฎ RETURN VALUES ๐งฎ
The exit code of the abicompat command is either 0 if the ABI of the binaries being compared are equal, or non-zero if they differ or if the tool encountered an error.
In the later case, the exit code is a 8-bits-wide bit field in which each bit has a specific meaning.
- The first bit, of value
1, namedABIDIFF_ERRORmeans there was an error. - The second bit, of value
2, namedABIDIFF_USAGE_ERRORmeans there was an error in the way the user invoked the tool. It might be set, for instance, if the user invoked the tool with an unknown command line switch, with a wrong number or argument, etc. If this bit is set, then theABIDIFF_ERRORbit must be set as well. - The third bit, of value
4, namedABIDIFF_ABI_CHANGEmeans the ABI of the binaries being compared are different. - The fourth bit, of value
8, namedABIDIFF_ABI_INCOMPATIBLE_CHANGEmeans the ABI of the binaries compared are different in an incompatible way. If this bit is set, then theABIDIFF_ABI_CHANGEbit must be set as well. If theABIDIFF_ABI_CHANGEis set and theABIDIFF_INCOMPATIBLE_CHANGEis NOT set, then it means that the ABIs being compared might or might not be compatible. In that case, a human being needs to review the ABI changes to decide if they are compatible or not. - The remaining bits are not used for the moment.
๐ USAGE EXAMPLES ๐
Okay bestie, this is the part where we actually run the thing. Buckle up ๐
- Detecting a possible ABI incompatibility in a new shared library version โ here's the full setup, no cap:
$ cat -n test0.h
1 struct foo
2 {
3 int m0;
4
5 foo()
6 : m0()
7 {}
8 };
9
10 foo*
11 first_func();
12
13 void
14 second_func(foo&);
15
16 void
17 third_func();
$
$ cat -n test-app.cc
1 // Compile with:
2 // g++ -g -Wall -o test-app -L. -ltest-0 test-app.cc
3
4 #include "test0.h"
5
6 int
7 main()
8 {
9 foo* f = first_func();
10 second_func(*f);
11 return 0;
12 }
$
$ cat -n test0.cc
1 // Compile this with:
2 // g++ -g -Wall -shared -o libtest-0.so test0.cc
3
4 #include "test0.h"
5
6 foo*
7 first_func()
8 {
9 foo* f = new foo();
10 return f;
11 }
12
13 void
14 second_func(foo&)
15 {
16 }
17
18 void
19 third_func()
20 {
21 }
$
$ cat -n test1.h
1 struct foo
2 {
3 int m0;
4 char m1; /* <-- a new member got added here! */
5
6 foo()
7 : m0(),
8 m1()
9 {}
10 };
11
12 foo*
13 first_func();
14
15 void
16 second_func(foo&);
17
18 void
19 third_func();
$
$ cat -n test1.cc
1 // Compile this with:
2 // g++ -g -Wall -shared -o libtest-1.so test1.cc
3
4 #include "test1.h"
5
6 foo*
7 first_func()
8 {
9 foo* f = new foo();
10 return f;
11 }
12
13 void
14 second_func(foo&)
15 {
16 }
17
18 /* Let's comment out the definition of third_func()
19 void
20 third_func()
21 {
22 }
23 */
$
- Compile the first and second versions of the libraries โ
libtest-0.soandlibtest-1.so, periodt:
$ g++ -g -Wall -shared -o libtest-0.so test0.cc
$ g++ -g -Wall -shared -o libtest-1.so test1.cc
- Compile the application and link it against the first version of the library, creating the
test-appbinary โ this is giving main character energy:
$ g++ -g -Wall -o test-app -L. -ltest-0.so test-app.cc
- Now use
abicompatto see iflibtest-1.sois ABI compatible withapp, with respect to the ABI oflibtest-0.soโ vibe check time ๐ฅ:
$ abicompat test-app libtest-0.so libtest-1.so
ELF file 'test-app' might not be ABI compatible with 'libtest-1.so' due to differences with 'libtest-0.so' below:
Functions changes summary: 0 Removed, 2 Changed, 0 Added functions
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
2 functions with some indirect sub-type change:
[C]'function foo* first_func()' has some indirect sub-type changes:
return type changed:
in pointed to type 'struct foo':
size changed from 32 to 64 bits
1 data member insertion:
'char foo::m1', at offset 32 (in bits)
[C]'function void second_func(foo&)' has some indirect sub-type changes:
parameter 0 of type 'foo&' has sub-type changes:
referenced type 'struct foo' changed, as reported earlier
$
- Now use the weak mode of
abicompat, that is, providing just the application and the new version of the library โ lowkey iconic:
$ abicompat --weak-mode test-app libtest-1.so
functions defined in library
'libtest-1.so'
have sub-types that are different from what application
'test-app'
expects:
function foo* first_func():
return type changed:
in pointed to type 'struct foo':
size changed from 32 to 64 bits
1 data member insertion:
'char foo::m1', at offset 32 (in bits)
$
๐ AUTHOR ๐
Dodji Seketeli
๐ COPYRIGHT ๐
2014-2026, Red Hat, Inc.
Catch you in the terminal, bestie โ this page's footer stamp is Oct 08, 2026, and it's ABICOMPAT(1) ๐ โจ๐ซถ
๐ฆ where this page comes from
- centos-stream 9: libabigail 3.0-1.el9 ยท Apache-2.0 WITH LLVM-exception
- centos-stream 9: libabigail 3.0-1.el9 ยท Apache-2.0 WITH LLVM-exception
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms