Creating and Comparing a Baseline¶
The practical mechanics of producing an ABI baseline and comparing against one. For what a baseline is and why most projects need two of them, see Baseline Management; for where to keep the file once you've created it, see Storing Baselines.
Creating a Baseline¶
# Basic: write to stdout
abicheck dump libfoo.so -H include/foo.h --version 2.0.0
# Write to a specific file
abicheck dump libfoo.so -H include/foo.h --version 2.0.0 -o baseline.json
# Conventionally named (see naming convention below)
abicheck dump libfoo.so -H include/foo.h --version 2.0.0 -o libfoo-2.0.0.abicheck.json
Provenance Metadata¶
Snapshots include provenance metadata that tracks where and when they were created:
abicheck dump libfoo.so -H include/foo.h \
--version 2.0.0 \
--provenance git-tag=v2.0.0 \
--provenance build-id="$CI_RUN_ID" \
-o libfoo-2.0.0.abicheck.json
This embeds in the snapshot JSON:
| Field | Source | Example |
|---|---|---|
git_commit |
Auto-detected from git rev-parse HEAD |
abc1234def5678 |
git_tag |
--provenance git-tag=... |
v2.0.0 |
created_at |
Auto-set (ISO 8601 UTC) | 2026-03-24T12:00:00+00:00 |
build_id |
--provenance build-id=... |
gh-actions-1234 |
Use --provenance git=off to skip automatic git commit detection (e.g., in non-git environments).
The .abicheck.json Naming Convention¶
Name baselines <library>-<version>.abicheck.json (via -o):
| Library | Version | Output File |
|---|---|---|
libfoo.so.1 |
2.0.0 |
libfoo-2.0.0.abicheck.json |
bar.dll |
3.1 |
bar-3.1.abicheck.json |
libqux.dylib |
1.0 |
libqux-1.0.abicheck.json |
This convention makes CI scripts predictable: upload with *.abicheck.json, download
with --pattern '*.abicheck.json'. The GitHub Action's abi-baseline input looks for
*.abicheck.json assets on releases.
See Storing Baselines for where to put the file once
you've created it, including the baseline Action for multi-library releases.
Comparing Against a Baseline¶
Once you have a baseline, comparison is the same regardless of storage:
# JSON snapshot vs new binary
abicheck compare baseline.json build/libfoo.so --header new=include/foo.h
# Two snapshots (no headers or tools needed)
abicheck compare old-baseline.json new-baseline.json
Snapshots are self-contained — they include all type, function, variable, and enum information. Comparing two snapshots requires no headers, compilers, or debug info.
You can also pass packages (RPM, Deb, tar, conda, or wheel) straight to
compare — it compares all shared libraries inside them without manual
extraction:
See Multi-Binary Releases for the bundle/package flags and the GitHub Action guide for CI examples with packages.
A one-off comparison with side-scoped headers¶
abicheck compare OLD NEW doesn't require a stored baseline at all — OLD
can be a previous native library or a saved ABI dump directly (a single
file, not a directory or package -- for those, compare takes the two
package roots the same way). compare always runs its always-on
pattern/cross-source audit checks alongside the comparison itself, in one
pass:
-H/--header and -I/--include are side-aware: a bare value applies to
both sides, and an old=/new= prefix scopes to one side. When OLD is a
native library (not a snapshot) and its public headers differ from the
new version, parse the old side with its own headers using the old=
prefix:
- Without an
old=-scoped header, a nativeOLDlibrary is parsed with the same headers asNEW(correct only when the headers didn't change). - A JSON-snapshot
OLDoperand already has its headers baked in, so side-scoped headers are unnecessary there. Prefer a pre-dumped snapshot baseline when you can — it's unambiguous and needs no toolchain at compare time.
(scan ARTIFACT --against OLD was this workflow's spelling before scan
was deleted outright in 0.6 — no alias, no deprecation window;
compare OLD NEW is the direct replacement, with OLD/ARTIFACT swapping
argument order to match compare's own OLD NEW convention.)
See Evidence Depth for the full --depth reference.