Getting Started¶
abicheck compares two versions of a C/C++ shared library and tells you whether existing binaries will break. It supports ELF (Linux), PE/COFF (Windows), and Mach-O (macOS) binaries.
On all platforms it provides binary metadata analysis (exports, imports, dependencies) and header AST analysis (via castxml). Debug info cross-check uses DWARF (Linux, macOS) and PDB (Windows).
Platforms: Linux, Windows, macOS.
1) Install abicheck¶
Requirements¶
- Python 3.10+
castxml+ C/C++ compiler — for header AST analysis (optional but recommended, all platforms)
All Python dependencies (pyelftools, pefile, macholib) come with abicheck install.
Without castxml, abicheck still works in binary-only mode.
Option A: system packages¶
Option B: conda-forge (recommended for reproducible envs)¶
# create env and install abicheck (recipe includes required analysis deps)
# Python >= 3.10 is required; any supported version works
conda create -n abicheck -c conda-forge python=3.12 abicheck
conda activate abicheck
No extra manual dependency installation is required when using the conda-forge package.
Install from source¶
2) First check (using repo examples)¶
The repo includes 63 ABI scenario examples with paired v1/v2 sources and headers:
# Build v1 and v2 shared libraries
gcc -shared -fPIC -g v1.c -o libv1.so
gcc -shared -fPIC -g v2.c -o libv2.so
# Compare
abicheck compare libv1.so libv2.so --old-header v1.h --new-header v2.h
# Verdict: BREAKING (symbol 'helper' was removed)
For your own library:
abicheck compare libfoo.so.1 libfoo.so.2 \
--old-header include/v1/foo.h --new-header include/v2/foo.h
If the header is the same for both versions:
You can also pass a header directory (recursive scan for *.h, *.hpp, ...):
If no headers are provided for ELF inputs, abicheck falls back to symbols-only mode and prints a warning (weaker analysis: may miss type/signature ABI breaks).
3) Output formats¶
abicheck supports four output formats: markdown (default), json, sarif, html.
Markdown (default, printed to stdout):
JSON — machine-readable, includes precise verdict field:
SARIF — for GitHub Code Scanning:
HTML — standalone human-readable report:
4) Snapshot workflow (for CI baselines)¶
Save a snapshot once per release, then compare against new builds without re-dumping:
# Save baseline (header is baked into the snapshot)
abicheck dump libfoo.so -H include/foo.h --version 1.0 -o baseline.json
# Compare saved baseline against current build
abicheck compare baseline.json ./build/libfoo.so \
--new-header include/foo.h --new-version 2.0-dev
# Or compare two snapshots (no headers needed — already baked in)
abicheck compare old.json new.json
compare auto-detects each input: .so files are dumped on-the-fly, .json snapshots are loaded directly. You can mix them freely.
Language mode¶
Use --lang c for pure C libraries (default is c++):
Cross-compilation¶
When analysing libraries built for a different architecture:
abicheck dump libfoo.so -H include/foo.h \
--gcc-prefix aarch64-linux-gnu- \
--sysroot /opt/sysroots/aarch64 \
-o snap.json
Available flags: --gcc-path, --gcc-prefix, --gcc-options, --sysroot, --nostdinc.
Verbose output¶
5) Application compatibility check¶
Check whether your application is affected by a library update — filtering out irrelevant changes:
This parses your application binary to find which library symbols it actually uses, then shows only the changes that matter. If the library removed a function your app never calls, it won't appear in the report.
Quick symbol availability check (no old library needed):
See Application Compatibility for the full reference.
6) Exit codes and CI¶
| Exit code | Verdict | Meaning |
|---|---|---|
0 |
NO_CHANGE / COMPATIBLE / COMPATIBLE_WITH_RISK |
Safe — no binary ABI break |
1 |
— | Tool/runtime error |
2 |
API_BREAK |
Source-level API break (binary still works) |
4 |
BREAKING |
Binary ABI break |
Full reference (including compat mode): Exit Codes
GitHub Actions example¶
Save a baseline once at release time, then compare every new build:
# Release step — save baseline as an artifact
abicheck dump ./build/libfoo.so -H include/foo.h \
--version 1.0 -o abi-baseline.json
# Upload abi-baseline.json as a release artifact
# CI step — compare new build against saved baseline
steps:
- name: Download ABI baseline
uses: actions/download-artifact@v4
with:
name: abi-baseline
- name: Compare ABI
run: |
abicheck compare abi-baseline.json ./build/libfoo.so \
--new-header include/foo.h \
--format sarif -o abi.sarif
- uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: abi.sarif
Next steps¶
- Verdicts — what each verdict means
- Policy Profiles — control how changes are classified
- Examples & Breakage Guide — real-world ABI/API break scenarios
- ABICC Compatibility — migrating from abi-compliance-checker
- Limitations