SkillAgentSearch skills...

Abicheck

API/ABI checker: castxml-based header dumper + Python checker + LLVM/GCC support

Install / Use

/learn @napetrov/Abicheck
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

abicheck

CI codecov PyPI version conda-forge Python versions License: Apache 2.0

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

View on GitHub
GitHub Stars5
CategoryCustomer
Updated18h ago
Forks0

Languages

Python

Security Score

90/100

Audited on Apr 3, 2026

No findings