Abicheck
API/ABI checker: castxml-based header dumper + Python checker + LLVM/GCC support
Install / Use
/learn @napetrov/AbicheckREADME
abicheck
abicheck is a command-line tool that detects breaking changes in C/C++ shared libraries before they reach production. It compares two versions of a shared library — along with their public headers — and reports whether existing binaries will continue to work or break at runtime.
Typical problems it catches: removed or renamed symbols, changed function signatures, struct layout drift, vtable reordering, enum value reassignment, and 114 other ABI/API incompatibilities that cause crashes, silent data corruption, or linker failures after a library upgrade.
Platforms: Linux (ELF), Windows (PE/COFF), macOS (Mach-O). Binary metadata and header AST analysis on all platforms; debug info cross-check uses DWARF (Linux, macOS) and PDB (Windows).
Installation
Install from PyPI:
pip install abicheck
Or with conda:
conda install -c conda-forge abicheck
Prerequisites
| Requirement | Notes |
|-------------|-------|
| Python >= 3.10 | All platforms |
| castxml | Clang-based C/C++ AST parser for header analysis (all platforms) |
| g++ or clang++ | Must be accessible to castxml |
castxml and a C++ compiler are required for header AST analysis. Without them, abicheck still works in binary-only mode (exports, imports, dependencies).
Ubuntu / Debian:
sudo apt install castxml g++
macOS:
brew install castxml
conda (all platforms):
conda install -c conda-forge castxml
Naming note
This project (napetrov/abicheck on PyPI) is distinct from distro-packaged tools
with similar names (abi-compliance-checker wrappers in Debian devscripts, or
abicheck in Fedora's libabigail-tools). Run abicheck --version to confirm
which tool is active — it should show abicheck X.Y.Z (napetrov/abicheck).
If the abicheck command conflicts with a distro tool, use:
python -m abicheck --version
python -m abicheck dump libfoo.so -H include/foo.h
Install from source
git clone https://github.com/napetrov/abicheck.git
cd abicheck
Runtime only:
pip install -e .
With test and lint dependencies:
pip install -e ".[dev]"
Quick start
Compare two library versions
abicheck compare libfoo.so.1 libfoo.so.2 \
--old-header include/v1/foo.h --new-header include/v2/foo.h
Use -H when both versions share the same header:
abicheck compare libfoo.so.1 libfoo.so.2 -H include/foo.h
Save a baseline snapshot, then compare against new builds
abicheck dump libfoo.so -H include/foo.h --version 1.0 -o baseline.json
abicheck compare baseline.json ./build/libfoo.so --new-header include/foo.h
Output formats
Available formats: markdown (default), json, sarif, html.
abicheck compare old.so new.so -H foo.h --format json -o report.json
abicheck compare old.so new.so -H foo.h --format sarif -o report.sarif
abicheck compare old.so new.so -H foo.h --format html -o report.html
Check application compatibility
Check whether your application (not just the library) is affected by a library update. Unlike compare (which shows all library changes), appcompat filters the diff to show only changes that affect the symbols your application actually uses.
Full check — does my app break with the new libfoo?
abicheck appcompat ./myapp libfoo.so.1 libfoo.so.2 -H include/foo.h
Quick check — does this library have all symbols my app needs?
abicheck appcompat ./myapp --check-against libfoo.so.2
See Application Compatibility for full details.
Full-stack dependency validation (Linux ELF)
Check whether a binary will load and run correctly in a given environment by resolving its full dependency tree, simulating symbol binding, and detecting ABI-breaking changes across all loaded DSOs.
Show dependency tree and symbol binding status:
abicheck deps /usr/bin/python3
Compare a binary's full stack across two sysroots:
abicheck stack-check usr/bin/myapp \
--baseline /rootfs/v1 --candidate /rootfs/v2
Include dependency info in a regular compare:
abicheck compare old.so new.so -H foo.h --follow-deps
For the full CLI reference see the documentation.
Exit codes
Use these exit codes to gate CI pipelines. Non-zero exits can fail your build when breaking changes are detected.
compare / compare-release
| Exit code | Verdict | Meaning |
|-----------|---------|---------|
| 0 | NO_CHANGE / COMPATIBLE / COMPATIBLE_WITH_RISK | Safe — no binary ABI break |
| 1 | SEVERITY_ERROR | Severity-driven error (with --severity-* flags) |
| 2 | API_BREAK | Source-level break (recompile needed, binary may still work) |
| 4 | BREAKING | Binary ABI break (old binaries will crash or misbehave) |
| 8 | REMOVED_LIBRARY | Library removed in new version (compare-release only) |
stack-check
| Exit code | Verdict | Meaning |
|-----------|---------|---------|
| 0 | PASS | Binary loads and no harmful ABI changes |
| 1 | WARN | Binary loads but ABI risk in dependencies |
| 4 | FAIL | Load failure or ABI break in dependency stack |
appcompat
| Exit code | Verdict | Meaning |
|-----------|---------|---------|
| 0 | COMPATIBLE | App is not affected by the library change |
| 2 | API_BREAK | App uses changed API (recompile needed) |
| 4 | BREAKING | App will crash or misbehave with new library |
See the full exit code reference for CI gate patterns.
GitHub Action
Basic usage:
- uses: napetrov/abicheck@v1
with:
old-library: abi-baseline.json
new-library: build/libfoo.so
new-header: include/foo.h
With SARIF upload to GitHub Code Scanning:
- uses: napetrov/abicheck@v1
with:
old-library: abi-baseline.json
new-library: build/libfoo.so
new-header: include/foo.h
format: sarif
upload-sarif: true
Fail on both ABI and API breaks:
- uses: napetrov/abicheck@v1
with:
old-library: abi-baseline.json
new-library: build/libfoo.so
new-header: include/foo.h
fail-on-breaking: true
fail-on-api-break: true
Use the action's outputs to control downstream steps:
- uses: napetrov/abicheck@v1
id: abi
with:
old-library: abi-baseline.json
new-library: build/libfoo.so
new-header: include/foo.h
- run: echo "ABI verdict was ${{ steps.abi.outputs.verdict }}"
The action installs Python, castxml, and abicheck automatically. Available outputs: verdict, exit-code, report-path. See the full GitHub Action documentation for cross-compilation and matrix builds.
Policy profiles
Policies control how detected changes are classified. A change that is BREAKING under strict_abi might be downgraded to COMPATIBLE under sdk_vendor.
| Profile | Use case |
|---------|----------|
| strict_abi (default) | System libraries, public SDKs |
| sdk_vendor | Vendor SDKs, optional extensions |
| plugin_abi | Plugins rebuilt with host |
abicheck compare old.so new.so -H foo.h --policy sdk_vendor
Use a custom YAML policy file for per-kind verdict overrides:
abicheck compare old.so new.so -H foo.h --policy-file my-policy.yaml
See Policy Profiles for full details including YAML format.
Suppression files
Suppress known or intentional changes so they don't fail CI:
abicheck compare old.so new.so -H foo.h --suppress suppressions.yaml
Example suppressions.yaml:
version: 1
suppressions:
# Exact symbol match
- symbol: "_ZN3foo6Client10disconnectEv"
change_kind: "func_removed"
reason: "Client::disconnect() deprecated in v1.8, removed in v2.0"
expires: "2026-09-01"
# Pattern match — suppress all changes in internal namespaces
- symbol_pattern: ".*N6detail.*"
reason: "detail:: namespace is not part of public ABI"
# All change kinds for a symbol
- symbol: "_ZN3foo12LegacyHandleEv"
reason: "LegacyHandle replaced by Handle alias — shim keeps compat"
expires: "2026-12-31"
Suppression lifecycle
Auto-generate candidate rules from a JSON diff, then enforce justification and expiry in CI:
# Generate candidates from a diff
abicheck compare old.so new.so -H foo.h --format json -o diff.json
abicheck suggest-suppressions diff.json -o candidates.yml
# Enforce in CI: require reasons and fail on expired rules
abicheck compare old.so new.so -H foo.h \
--suppress suppressions.yaml \
--strict-suppressions \
--require-justification
| Flag | Effect |
|------|--------|
| --strict-suppressions | Fail if any suppression rule is past its expires date |
| --require-justification | Fail if any rule has an empty or missing reason field |
See Suppressions for the full reference.
ABICC-format suppression files are
