Skip to content

CLI Reference

Every abicheck command, subcommand, argument, and option, generated directly from the live Click command tree (the same help= text --help shows). See CLI Usage and Dump & Compare Flags for the narrative walkthroughs of the primary workflows; this page is the exhaustive field list only.

Root options

Options available directly on abicheck, before any subcommand (shown by python -m abicheck --help).

Option Required Default Description
--version no False Show the version and exit.

aggregate

Aggregate per-target ABI reports in REPORTS_DIR into one CI gate verdict.

Arguments

Name Required Description
reports_dir yes

Options

Option Required Default Description
--manifest no Expected-target manifest (JSON: {"targets": [{"id", "required"}]}). The single source of truth for which targets the matrix must produce — generate it in the plan job and feed the same file to both the matrix and this gate so they never drift.
--run-plan no A project run-plan.json (from abicheck project plan), projected to the expected-target manifest shape internally -- an alternative to --manifest that skips the separate projection step. Each check's own check_id becomes the expected target id, matching what check-target writes as every report's target_id.
--expect no Required target id(s), as an alternative to --manifest (repeatable / comma-separated). A required target with no report is unavailable and fails the coverage gate — never treated as compatible.
--optional no Optional target id(s) (used with --expect): analyzed when present, but a missing one never fails the coverage gate.
--discovered-only no False Explicitly aggregate whatever reports are present, with NO coverage gate. Required to run without a manifest/--expect — because with no declared target set the gate cannot tell a missing required target from an intentionally absent one.
--report-prefix no abi-report- Filename prefix stripped when deriving a target id from a report file that does not self-identify a 'target_id' (e.g. 'abi-report-linux.json' -> 'linux').
--on-missing-required no fail How an unavailable required target affects the exit code: 'fail' makes incomplete required coverage a gate failure (exit 1); 'warn' reports the gap but lets the per-target gate decisions alone decide. Choices: fail, warn.
--on-unexpected-target no include How a report for a target not in the expected set is handled: 'include' counts its real findings in the gate (but not in coverage); 'warn' surfaces it without gating; 'fail' fails the gate on any such target; 'ignore' drops it. Choices: include, warn, fail, ignore.
--format no text Output format for the aggregated result. Choices: text, json.
--output, -o no Write output to this path (default: stdout).
--verbose, -v no False Enable verbose/debug output.

compare

Compare two ABI surfaces and report changes.

Arguments

Name Required Description
old_input yes
new_input yes

Options

Option Required Default Description
--help no False Show common options and exit. Use --help-all to see every option.
--help-all no False Show every option, including advanced/less-common ones.
--jobs, -j no 0 Parallel library comparisons for directory/package inputs (0 = auto-detect CPU count, the default).
--dso-only no False Only compare shared objects, skip executables (directory/package inputs only).
--output-dir no Directory to write per-library reports (directory/package inputs only).
--fail-on-removed-library, --no-fail-on-removed-library no False Exit 8 when a library present in old_dir is absent in new_dir. (directory/package inputs only)
--debug-info no Debug info package (RPM/Deb/tar), scoped per side with an 'old='/'new=' prefix (e.g. --debug-info old=a-dbg.rpm --debug-info new=b-dbg.rpm). Directory/package inputs only (ADR-040).
--devel-pkg no Development package with headers, scoped per side with an 'old='/'new=' prefix (e.g. --devel-pkg old=a-dev.rpm --devel-pkg new=b-dev.rpm). Directory/package inputs only (ADR-040).
--include-private-dso no False Include private (non-public) shared objects from non-standard paths. (directory/package inputs only)
--keep-extracted no False Keep extracted temporary files for debugging. (directory/package inputs only)
--manifest no ABI instantiation manifest (YAML/JSON) listing symbols the release publicly promises (ADR-023). (directory/package inputs only)
--bundle-system-providers no `` Comma-separated extra sonames to treat as system-provided (extends the built-in libc/libstdc++/libgcc/libtbb allow-list). (directory/package inputs only)
--bundle-cohort no Declare a co-versioned library cohort by name prefix (e.g. 'libfoo_'). Repeatable. Enables the BUNDLE_SONAME_SKEW check. (directory/package inputs only)
--no-bundle-analysis no False Skip bundle-level cross-library analysis (debug/parity escape hatch). Bundle findings catch intra-bundle symbol removals, signature drift across DSO boundaries, type drift across siblings, provider migration, and manifest mismatches. (directory/package inputs only)
--header, -H no Public header file or directory. Applies to both sides; scope to one side with an 'old='/'new=' prefix, repeating the flag per side (e.g. --header old=v1/foo.h --header new=v2/foo.h). Repeatable (ADR-040). Recommended for full ABI analysis; without headers, native binaries fall back to symbols-only mode. Scopes the ABI surface to declarations in these headers for ELF; on PE/Mach-O scoping is best-effort and falls back to the export table when castxml is unavailable or names don't match (e.g. MSVC C++ mangling). Validated for native binaries; ignored for snapshots.
--include, -I no Extra include directory for castxml. Applies to both sides; scope to one side with an 'old='/'new=' prefix, repeating the flag per side (e.g. --include old=inc1 --include new=inc2). Repeatable (ADR-040). A labeled 'old:LABEL=PATH'/'new:LABEL=PATH' form (e.g. --include old:support=old/src --include new:support=new/src) names a side-specific support root under one shared logical identity, so a genuine two-checkout compare doesn't spuriously PROFILE_MISMATCH on it (ADR-050 D1).
--version no Version label used when an input is a bare .so file. Scope to one side with an 'old='/'new=' prefix, repeating the flag per side (e.g. --version old=1.0 --version new=2.0); a bare value applies to both. Defaults: old side 'old', new side 'new' (ADR-040).
--dump-manifest no A strict YAML document describing multiple translation units to compile and merge into one side's snapshot, instead of a single -H/--header list (ADR-050 D3). Side-scoped: repeat the flag with an 'old='/'new=' prefix per side (e.g. --dump-manifest old=v1/abi.yml --dump-manifest new=v2/abi.yml); a bare value applies to both. Mutually exclusive with -H/--header for that side (declare the public surface in the manifest's own base profile instead). ELF only so far.
--ast-frontend no auto C/C++ AST frontend (ADR-037 D8): castxml (default schema reference) or clang (-ast-dump=json; for hosts where castxml is absent or its bundled frontend chokes). hybrid (G28 Phase 3) runs BOTH and merges them (dumper_hybrid.merge_snapshots) — needs both tools installed and costs roughly 2x a single-backend dump; never selected by auto. auto resolves to castxml (or the ABICHECK_AST_FRONTEND pin) and never changes producer unless --allow-ast-frontend-fallback (or ABICHECK_ALLOW_AST_FALLBACK=1) is explicitly set. Env: ABICHECK_AST_FRONTEND. Choices: auto, castxml, clang, hybrid.
--allow-ast-frontend-fallback no False Allow auto-selected CastXML to fall back to Clang for a recognized toolchain mismatch or direct-include guard. Disabled by default because the frontends can produce materially different findings.
--allow-unsupported-castxml no False Proceed with a CastXML build outside the supported version range (castxml_policy.MIN_CASTXML/MAX_CASTXML/MIN_CASTXML_CLANG_MAJOR) instead of aborting the scan before headers are parsed. Exploratory-mode-only: the resulting snapshot's ast_toolchain_supported is recorded as false with ast_toolchain_unsupported_reasons, so it is never mistaken for a normal supported scan and cannot become a new strict baseline without a further explicit acknowledgment.
--gcc-path no Path to a GCC/G++ (or clang) cross-compiler binary.
--gcc-prefix no Cross-toolchain prefix (e.g. aarch64-linux-gnu-).
--gcc-options no Extra compiler flags passed through to the header frontend (split on whitespace). For a flag whose value contains spaces use --gcc-option.
--gcc-option no A single extra compiler flag passed to the header frontend verbatim (repeatable; not whitespace-split). Use two for a flag + spaced value, e.g. --gcc-option=-include --gcc-option='some header.h'.
--sysroot no Alternative system root directory for header resolution.
--nostdinc, --no-nostdinc no False Do not search the standard system include paths (suppresses the castxml/clang system-include auto-detection too). Paired form so an explicit --no-nostdinc on scan can override a config compile.nostdinc: true for a one-off run (CLI > config).
--frontend-context no host Which AST context the L2 header frontend should target (ADR-050 D3/D5). 'device' selects the SYCL/DPC++ offload-device AST from a DPC++-capable compiler (icx/icpx/dpcpp) invoked with -fsycl; it fails loudly if the configured frontend cannot produce a device context. Matches a manifest's own frontend_context field for the legacy, non-manifest path. Choices: host, device.
--lang no c++ Language mode for the header backend. Choices: c++, c.
--old-ast-frontend no C/C++ AST frontend for the old side only (overrides --ast-frontend for old). Use when the old release parses on castxml but the new one needs clang (or vice versa). Choices: auto, castxml, clang, hybrid.
--new-ast-frontend no C/C++ AST frontend for the new side only (overrides --ast-frontend for new). Choices: auto, castxml, clang, hybrid.
--format no markdown Output format. 'review' emits a compact GitHub-facing digest (verdict + counts + release recommendation + manual-review banner) suitable for a job summary or PR comment. Choices: json, markdown, sarif, html, junit, review.
--output, -o no Write output to this path (default: stdout).
--secondary-format no Emit a second output format from this same comparison run, without re-running the comparison a second time (e.g. a human --format markdown report alongside a --secondary-format json artifact for tooling). Requires --secondary-output (writing two formats to the same stream would be ambiguous). Always renders the full, unfiltered report (ignores --show-only/--stat). Not supported for directory/package (release) comparisons. Choices: json, markdown, sarif, html, junit, review.
--secondary-output no File path to write --secondary-format's output to. Must differ from --output/-o, or the secondary render would silently overwrite the primary report.
--demangle, --no-demangle no Demangle C++ symbol names in markdown/review output (default ON; use --no-demangle to turn off). json/sarif always keep raw mangled names, and HTML is rendered structurally and is never demangled regardless of this flag.
--policy no strict_abi Built-in policy profile for verdict classification. Ignored when --policy-file is given. Choices: strict_abi, sdk_vendor, plugin_abi.
--policy-file no YAML policy file with per-kind verdict overrides, or a built-in name (e.g. 'security'). Overrides --policy.
--suppress no Suppression file (YAML) to filter known/intentional changes.
--pdb-path no Explicit PDB file path for Windows PE debug info. Applies to both sides; scope to one with an 'old='/'new=' prefix, repeating the flag per side (e.g. --pdb-path old=a.pdb --pdb-path new=b.pdb). Overrides automatic PDB discovery (ADR-040).
--used-by no Application binary whose actual imports/required symbol versions scope the comparison (repeatable; folds appcompat). The full library comparison still runs once; the worst app-scoped result becomes the primary verdict/exit code, with the full verdict and unrelated changes kept as informational context. OLD/NEW may be real library binaries or JSON snapshots carrying binary evidence (a dump of a real library, not headers-only). Mutually exclusive with --required-symbol/--required-symbols.
--verify-runtime no False With --used-by: actually run each consumer binary once against the OLD library and once against the NEW one (LD_BIND_NOW=1), recording a consumer_runtime_load_failed RISK finding when the dynamic linker itself reports an undefined symbol against the new library after loading cleanly against the old one (ADR-044 P2 item 2). A dynamic corroborating signal alongside the static scanner, never a replacement for it. Requires OLD/NEW to be real library binaries (not JSON snapshots) and is Linux-only; a no-op elsewhere. Ignored without --used-by.
--required-symbol no An exported linker symbol a plugin host resolves via dlopen/dlsym and requires (repeatable; folds plugin-check). Scopes the comparison to this explicit entrypoint contract instead of the full diff. Mutually exclusive with --used-by.
--required-symbols no File of required symbols, one per line (blank lines and '#' comments ignored). Combined with any --required-symbol values.
--severity-preset no Severity preset: 'default', 'strict', or 'info-only'. Controls exit codes and report labels. Per-category --severity-* options override the chosen preset. Choices: default, strict, info-only.
--config no Path to the project .abicheck.yml (ADR-037 D4). Default: the nearest .abicheck.yml found from the current directory upward. Supplies stable project settings (severity map, scope/FP tuning, suppression policy, exit-code scheme); CLI flags override it.
--exit-code-scheme no Exit-code scheme (ADR-037 D12): 'legacy' (0/2/4 verdict), 'severity' (per-category error levels), or 'auto' (severity when a severity setting is in effect, else legacy). Declared explicitly here so passing --severity-* no longer silently changes the scheme. Default: config's exit_code_scheme, else auto. Choices: auto, legacy, severity.
--follow-deps no False Resolve transitive dependencies for both old and new, compute symbol bindings, and include a dependency-change section in the report. ELF only.
--include-dependencies no False Include toolchain/system-header declarations (std::/SYCL/etc. pulled in transitively by #include). By default these are excluded -- pass this flag to get the old, unfiltered full surface instead. A no-op on a binary-only/DWARF-only dump. Mixing a filtered and an unfiltered snapshot across a comparison raises ScopeMismatchError (dumper_scoping.py).
--search-path no Additional directory to search for shared libraries (with --follow-deps).
--ld-library-path no `` Simulated LD_LIBRARY_PATH (with --follow-deps).
--scope-public-headers, --no-scope-public-headers no True Restrict findings to the public-header ABI surface (ADR-024): changes to symbols/types not reachable from public-header-declared exported API are recorded as filtered, not reported. Internal-type leaks are never hidden. On by default; use --no-scope-public-headers to report every finding regardless of surface.
--show-filtered no False List findings excluded by --scope-public-headers (audit trail).
--post-manifest no Scope the comparison to a POST Python export manifest's committed ABI surface. Only changes to the manifest's pp_/ufunc-loop symbols count; private __pp_ kernel churn and other non-committed exports are demoted to the filtered ledger (see --show-filtered).
--probe-matrix no Build-configuration matrix snapshot, scoped per side with an 'old='/'new=' prefix (e.g. --probe-matrix old=m1 --probe-matrix new=m2). With both sides given, build-config findings (CXX_STANDARD_FLOOR_RAISED, API_DEPENDS_ON_CONSUMER_ENV, BEHAVIOURAL_DEFAULT_CHANGED) are folded into this comparison's verdict and report (G2: probe -> compare; ADR-040).
--show-only no Comma-separated filter tokens to limit displayed changes. Severity: breaking, api-break, risk, compatible. Element: functions, variables, types, enums, elf. Action: added, removed, changed. AND across dimensions, OR within. Does not affect exit codes.
--stat no False One-line summary output for CI gates. With --format json, emits only the summary object.
--report-mode no full Report mode: 'full' lists all changes individually (default), 'leaf' groups by root type changes with impact lists, 'impact' behaves as 'full' with the impact summary table enabled (equivalent to --report-mode full --show-impact), 'root-cause' groups findings sharing a root cause (Change.caused_by_type) under one entry for --format json/markdown (the default rendered text output); --format sarif keeps its normal one-result-per-finding shape but adds properties.rootCauseId/rootCause to each result; --format junit still renders as 'full'. Choices: full, leaf, impact, root-cause.
--show-impact no False Append an impact summary table showing root changes and affected interfaces.
--recommend no False Append a release recommendation (semver bump + SONAME action) to the report. Always present in --format json under 'release_recommendation'.
--annotate no False Emit GitHub Actions workflow command annotations to stderr. Annotations appear as inline comments on PR diffs. Only effective when GITHUB_ACTIONS=true.
--annotate-additions no False Include additions/compatible changes as ::notice annotations (requires --annotate).
--debug-root no Directory containing separate debug files (build-id trees, path-mirror, dSYM bundles). Applies to both sides; scope to one with an 'old='/'new=' prefix, repeating the flag per side (e.g. --debug-root old=dbg1 --debug-root new=dbg2). Repeatable (ADR-040).
--build-info no Out-of-band build context: a build dir, a compile_commands.json, or a pack, overriding embedded. Applies to both sides; scope to one with an 'old='/'new=' prefix, repeating the flag per side (e.g. --build-info old=b1 --build-info new=b2) (ADR-040).
--sources no Source checkout for --depth build/source (collected inline, embedding build/source/graph facts) or a pre-built collect pack, overriding embedded. Applies to both sides; scope to one with an 'old='/'new=' prefix, repeating the flag per side (e.g. --sources old=src_v1 --sources new=src_v2) (ADR-040).
--depth no Evidence-depth dial: binary=symbols only, headers=+header AST (default), build=+build context, source=+source replay & call graph. Deeper-than-headers needs --sources or --build-info.
--pattern-verdicts, --no-pattern-verdicts no False Modulate verdicts with idiom/anti-pattern evidence (ADR-027): demote opaque-pointer/PIMPL-hidden layout changes (header-aware only) and raise breaks when an opacity/handle guarantee is lost. Disclosed in the pattern_modulations ledger; reversible.
--explain-patterns no False Print idiom evidence behind each modulation (implies --pattern-verdicts).
--surface-metrics no False Emit aggregate public-surface metric drift (ADR-027): public_surface_grew/shrank, undocumented_export_ratio_increased. Informational (COMPATIBLE).
--env-matrix no Environment-matrix YAML declaring deployment constraints (ADR-020b). With runtime_floors (e.g. 'runtime_floors: {GLIBC: "2.28"}'), a new symbol-version requirement is judged against the declared floor: at/below it -> compatible, above it -> breaking, instead of the default deployment-risk verdict.
--profile no Run-profile preset bundling workflow defaults (ADR-040): 'ci-gate' (headers depth, review digest, severity exit codes), 'release-cut' (source depth, recommendation, Markdown -- the 'should I bump semver?' flow; distinct from directory/package 'release' comparisons, which this profile does not apply to), 'quick' (symbols-only, one-line summary). Explicit flags override the profile; single-pair compares only (configure release defaults in .abicheck.yml). Choices: ci-gate, release-cut, quick.
--reconcile-build-context no False Clear context-free header-parse false positives using the build's active preprocessor defines (ADR-039): a conditional field's phantom add/remove/size change the build proves never happened is moved to an audit bucket instead of the verdict. No-op unless snapshots carry build_context_defines + per-field guards.
--dry-run no False Resolve and validate the invocation -- classify inputs, resolve depth/scope, show tool/config resolution -- and print a report without running the diff. Writes nothing; incompatible with -o/--output.
--diagnostic-comparison no False ADR-050 D2's sanctioned escape hatch: when OLD and NEW were extracted under a genuinely incomparable profile/scope (ExtractionContract mismatch), downgrade the default hard failure (exit 16, no verdict) into a tentative diff instead, stamped assurance: "none" everywhere in the report so a reader knows not to trust it the way an ordinary comparable diff is trusted. Not needed, and does nothing, on a comparable pair.
--contract-evaluation no False ADR-049's contract evaluator (pick its evidence domain with --contract). Stamps each finding in the report with a contract_relevance (IN_CONTRACT/PROVEN_OUT_OF_CONTRACT/UNKNOWN_UNPROVEN/UNKNOWN_UNRESOLVED/NOT_APPLICABLE), contract_reason_code, and -- when resolved -- contract_assurance field, reflecting whether the finding falls inside the library's declared public contract. Rendered per finding in --format json/markdown; --format review's compact digest does not (its top-impacted-symbols list predates this field), except for the --used-by/--required-symbol scoped-gate appendix, which renders it under json/markdown/review alike. Also rendered per finding in sarif/junit (properties/) and as a contract badge in html. --format json additionally carries contract_evidence_refs per finding (which evidence records its decision rests on) and a top-level contract_context block (the observed provider evidence, the resolved evaluation context, and the decision receipt), so a decision can be replayed or re-evaluated later without re-reading the binaries. The decisions are authoritative (ADR-049 Phase 7): relevance is classified before compatibility policy, and policy scores only IN_CONTRACT/NOT_APPLICABLE findings. A finding proven outside the contract, or unresolved for want of evidence, is NOT_EVALUATED -- null compatibility_decision, no gate contribution -- so this flag changes verdicts and exit codes. Nothing is hidden: such findings stay in the report with the relevance and reason that explain why they did not gate. Uncertainty is not treated as compatible either -- if the selected domain's required evidence is incomplete, the orthogonal contract-coverage ledger contributes exit 1, folded with max so it never lowers an ABI break's 2/4. Set contract.unresolved=warn (e.g. via a kind: contract --pack) to accept incomplete coverage: that zeroes the contribution while still reporting every failure. Also applies to a directory/package (release) comparison: each library's own contract-coverage floor is max()-folded into the release's exit code the same way. Default off; a run without this flag is unaffected in every respect.
--contract no Which evidence domain --contract-evaluation judges each finding against (ADR-049 Phase 6). 'public': the header-derived declared surface. 'exports': the binary's own export table (ELF .dynsym / PE export directory / Mach-O export trie) plus the raw type closure reachable from it -- a private-header type reached from a real export is inside this contract, an unexported public-header declaration is not. 'all': every entity, no root or closure evidence required. Omitted, the domain follows --scope-public-headers/--no-scope-public-headers as before; an explicit value outranks those. Requires --contract-evaluation. The domain is authoritative (ADR-049 Phase 7): it decides which findings compatibility policy scores, so it can change the verdict and the exit code -- a finding one domain proves outside the contract is one another domain gates on. It also selects which evidence the orthogonal contract-coverage axis is answered against -- see --contract-evaluation. Choices: public, exports, all.
--audit-suppressions no False Audit the --suppress rule file against this run's findings: which rules matched nothing (stale), matched a BREAKING change (high risk), are expired, or expire soon. Requires --suppress. Adds a suppression_audit key in --format json, a '## Suppression Audit' section in markdown/review. Advisory only.
--pack no Select an ADR-049 D8 pack manifest (repeatable). A pack is a small versioned YAML document (id/version/kind/assignments) carrying one reusable piece of configuration. 'kind: policy' assigns ChangeKind slugs to break/warn/risk/ignore, exactly as --policy-file's overrides do; 'kind: contract' assigns surface.internal_namespaces and contract.unresolved (the latter needs --contract-evaluation, which is what computes the coverage it configures); 'kind: gate' assigns gate.exit_code_scheme and gate.severity.. Composition is D8's: an explicitly stated value (--policy-file, --exit-code-scheme, --severity-*, a --profile, or .abicheck.yml) always outranks a pack, and two selected packs assigning different values to the same field are a usage error unless something else already states it. A manifest assigning a field this build resolves but does not yet apply is rejected rather than silently recorded, as is --pack on a directory/package (release) comparison, whose per-library fan-out dispatches before the effective configuration is resolved. On scan this requires --against (a pack's only application there is the baseline comparison) and a 'kind: gate' pack is rejected, since a scan's exit code follows its verdict directly and has no gate to move.
--verbose, -v no False Enable verbose/debug output.

compat

ABICC-compatible commands (drop-in replacement for abi-compliance-checker).

compat check

Drop-in replacement for abi-compliance-checker.

Options

Option Required Default Description
-l, -lib, -library yes Library name (e.g. libdnnl).
-d1, -old yes Path to old version ABICC XML descriptor or ABI dump.
-d2, -n, -new yes Path to new version ABICC XML descriptor or ABI dump.
-d, -f, -filter no Path to XML descriptor with skip_* filtering rules.
-p, -params no Path to parameters file (accepted for compat, informational).
-app, -application no Application binary for portability checking (accepted for compat).
-report-path no Output report path.
-bin-report-path no Separate binary-mode report output path.
-src-report-path no Separate source-mode report output path.
-report-format no html Report format (default: html). 'htm' is an alias for 'html'. Choices: html, htm, xml, json, md.
--suppress no Suppression YAML file.
-s, -strict no False Strict mode: any incompatible change is an error (exit 1).
--strict-mode no full Strict promotion mode: 'full' (COMPATIBLE+API_BREAK->BREAKING, ABICC parity) or 'api' (only API_BREAK->BREAKING, COMPATIBLE stays COMPATIBLE). Only applies when -strict is also set. Choices: full, api.
-show-retval no False Show return-value changes in report.
-headers-only no False Header-only analysis mode (ELF/DWARF checks still run).
-api, -source, -src no False Check source (API) compatibility only.
-abi, -bin, -binary no False Check binary (ABI) compatibility only (default).
-warn-newsym no False Treat new symbols as compatibility breaks.
-compat-html, -old-style no False Generate ABICC-compatible HTML with matching element IDs and structure.
-use-dumps no False Interpret -old/-new as pre-built dumps (auto-detected).
-v1, -version1, -vnum1 no Override version label for old library.
-v2, -version2, -vnum2 no Override version label for new library.
-title no Custom report title.
-component no Component name shown in report.
-limit-affected no 0 Max affected symbols shown per change kind.
-list-affected no False Generate a separate file listing affected symbols.
-stdout no False Print report to stdout.
-skip-headers no File listing headers to exclude from analysis, one per line.
-headers-list no File listing specific headers to include.
-header no Single header file to analyze.
-skip-symbols no File with symbols to skip (blacklist).
-skip-types no File with types to skip (blacklist).
-symbols-list no File with symbols to check (whitelist).
-types-list no File with types to check (whitelist).
-skip-internal-symbols no Regex pattern for internal symbols to skip.
-skip-internal-types no Regex pattern for internal types to skip.
-keep-cxx no False Include _ZS, _ZNS, _ZNKS* (C++ std) mangled symbols.
-keep-reserved no False Report changes in reserved fields.
-cross-gcc, -gcc-path no Path to GCC/G++ cross-compiler binary.
-cross-prefix, -gcc-prefix no Cross-toolchain prefix (e.g. aarch64-linux-gnu-).
-gcc-options no Extra compiler flags passed through to castxml.
-sysroot no Alternative system root directory.
-nostdinc no False Do not search standard system include paths.
-lang no Force language: C or C++.
-arch no Target architecture (informational).
-relpath no Replace {RELPATH} macros in both descriptor paths.
-relpath1 no Replace {RELPATH} macros in old descriptor paths.
-relpath2 no Replace {RELPATH} macros in new descriptor paths.
-q, -quiet no False Suppress console output.
-log-path no Redirect log output to file.
-log1-path no Separate log path for old library analysis.
-log2-path no Separate log path for new library analysis.
-logging-mode no Logging mode: 'w' (overwrite), 'a' (append), 'n' (none).

compat dump

Create an ABI dump from an ABICC XML descriptor (ABICC -dump equivalent).

Options

Option Required Default Description
-l, -lib, -library yes Library name.
-dump yes Path to ABICC XML descriptor to dump.
-dump-path no Output dump file path. Default: abi_dumps///dump.json.
-dump-format no json Dump format. Only 'json' is supported (ABICC perl/xml not supported).
-vnum no Override version label.
-cross-gcc, -gcc-path no Path to GCC/G++ cross-compiler binary.
-cross-prefix, -gcc-prefix no Cross-toolchain prefix (e.g. aarch64-linux-gnu-).
-gcc-options no Extra compiler flags passed through to castxml.
-sysroot no Alternative system root directory.
-nostdinc no False Do not search standard system include paths.
-lang no Force language: C or C++.
-arch no Target architecture (informational).
-relpath no Replace {RELPATH} macros in descriptor paths.
-q, -quiet no False Suppress console output.

deps

Inspect a binary's shared-library dependency stack.

deps compare

Compare a binary's full dependency stack across two environments.

Arguments

Name Required Description
binary yes

Options

Option Required Default Description
--old-root no / Sysroot for the old (baseline) environment.
--new-root no / Sysroot for the new (candidate) environment.
--search-path no Additional directory to search for shared libraries.
--ld-library-path no `` Simulated LD_LIBRARY_PATH (colon-separated).
--format no markdown Output format. Choices: json, markdown, html.
--output, -o no Write output to this path (default: stdout).
--dry-run no False Show old/new roots, resolved binary paths, and search order without running per-library ABI diffs. Writes nothing; incompatible with -o/--output.
--verbose, -v no False Enable verbose/debug output.

deps tree

Show the resolved dependency tree and symbol binding status.

Arguments

Name Required Description
binary yes

Options

Option Required Default Description
--search-path no Additional directory to search for shared libraries.
--sysroot no Sysroot prefix for cross/container analysis.
--ld-library-path no `` Simulated LD_LIBRARY_PATH (colon-separated).
--format no markdown Output format. Choices: json, markdown, html.
--output, -o no Write output to this path (default: stdout).
--dry-run no False Show the resolved binary, sysroot, search order, and loader inputs without walking/checking the full stack. Writes nothing; incompatible with -o/--output.
--verbose, -v no False Enable verbose/debug output.

dump

Dump ABI snapshot of a shared library to JSON.

Arguments

Name Required Description
so_path no

Options

Option Required Default Description
--header, -H no Public header file or directory (repeat for multiple).
--include, -I no Extra include directory for castxml.
--public-header no Header treated as public for provenance classification (repeat for multiple). Declarations are tagged public/private/system in the snapshot. Opt-in: omitting this leaves every origin UNKNOWN.
--public-header-dir no Directory whose headers are treated as public for provenance classification (repeat for multiple).
--include-dependencies no False Include toolchain/system-header declarations (std::/SYCL/etc. pulled in transitively by #include). By default these are excluded -- pass this flag to get the old, unfiltered full surface instead. A no-op on a binary-only/DWARF-only dump. Mixing a filtered and an unfiltered snapshot across a comparison raises ScopeMismatchError (dumper_scoping.py).
--version no unknown Library version string to embed in snapshot.
--lang no c++ Language mode for the header backend. Choices: c++, c.
--output, -o no Output JSON file. Defaults to stdout.
--pdb-path no Explicit path to PDB file for Windows PE debug info. Overrides automatic PDB discovery from the PE debug directory.
--follow-deps no False Resolve transitive DT_NEEDED dependencies and include the full dependency graph and symbol binding status in the snapshot. ELF only.
--search-path no Additional directory to search for shared libraries (with --follow-deps).
--ld-library-path no `` Simulated LD_LIBRARY_PATH (with --follow-deps).
--dwarf-only no False Force DWARF-only mode: use DWARF debug info as the primary data source even when headers are available. Enables type-aware artifact checks without requiring castxml.
--dry-run no False Resolve and validate the invocation -- classify inputs, discover config, show which evidence depths (binary/headers/build/source) are available -- and print a report without producing a snapshot. Writes nothing; incompatible with -o/--output.
--debug-format no Force the ELF debug format (auto=pick best available). Supersedes the individual --btf/--ctf/--dwarf flags. Choices: auto, dwarf, btf, ctf.
--build-dir, -p no Build directory containing compile_commands.json, or path to the file itself. Enables deterministic header parsing with exact build flags. Requires -H/--header.
--compile-db-filter no Glob pattern to filter compile_commands.json entries by source file (e.g. 'src/libfoo/**'). Useful for large databases.
--debug-root no Directory containing separate debug files (build-id trees, path-mirror debug files, or dSYM bundles). This option can be repeated.
--debuginfod no False Enable debuginfod network resolution for debug info (opt-in). Uses DEBUGINFOD_URLS environment variable or --debuginfod-url.
--debuginfod-url no debuginfod server URL (overrides DEBUGINFOD_URLS env var).
--dump-manifest no A strict YAML document describing multiple translation units to compile and merge into one snapshot, instead of a single -H/--header list. Mutually exclusive with -H/--header and --public-header/--public-header-dir (declare those in the manifest's own base profile instead). ELF only so far.
--verbose, -v no False Enable verbose/debug output.
--git-tag no Git tag to embed in the snapshot (e.g. v2.0.0).
--build-id no Opaque build identifier (CI run ID, build number, etc.).
--no-git no False Do not auto-detect git commit SHA.
--build-info no Optional build context: a build dir, a compile_commands.json, or a pre-captured pack. Auto-discovered inside the --sources tree when omitted.
--sources no Source checkout to run source-ABI replay and build the call graph over, embedding both inline. (An existing pack directory — e.g. from the abicheck-cc wrapper or Clang plugin — is auto-detected by its manifest.json and loaded as that pack instead.)
--build-query no Override the inferred build-system query command that emits a compile DB without a full build (e.g. 'cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON'). CLI equivalent of .abicheck.yml build.query — runs automatically as trusted operator input. Usually unnecessary: with just --sources, abicheck infers and runs the query itself.
--build-compile-db no Where a build/query lands its compile_commands.json, relative to --sources (e.g. 'build/compile_commands.json'). CLI equivalent of .abicheck.yml build.compile_db; overrides it when both are given.
--config no Path to the project .abicheck.yml (ADR-037 D4): build system, query command, compile-DB location, plus the stable severity/scope/suppression/source settings. Defaults to .abicheck.yml at the --sources tree root for non-executing settings; build.query runs only from an explicit --config.
--depth no Evidence-depth dial (same vocabulary as compare/scan --depth): binary=symbols only, headers=+header AST (default), build=+build context, source=+source replay & call graph.
--ast-frontend no auto C/C++ AST frontend (ADR-037 D8): castxml (default schema reference) or clang (-ast-dump=json; for hosts where castxml is absent or its bundled frontend chokes). hybrid (G28 Phase 3) runs BOTH and merges them (dumper_hybrid.merge_snapshots) — needs both tools installed and costs roughly 2x a single-backend dump; never selected by auto. auto resolves to castxml (or the ABICHECK_AST_FRONTEND pin) and never changes producer unless --allow-ast-frontend-fallback (or ABICHECK_ALLOW_AST_FALLBACK=1) is explicitly set. Env: ABICHECK_AST_FRONTEND. Choices: auto, castxml, clang, hybrid.
--allow-ast-frontend-fallback no False Allow auto-selected CastXML to fall back to Clang for a recognized toolchain mismatch or direct-include guard. Disabled by default because the frontends can produce materially different findings.
--allow-unsupported-castxml no False Proceed with a CastXML build outside the supported version range (castxml_policy.MIN_CASTXML/MAX_CASTXML/MIN_CASTXML_CLANG_MAJOR) instead of aborting the scan before headers are parsed. Exploratory-mode-only: the resulting snapshot's ast_toolchain_supported is recorded as false with ast_toolchain_unsupported_reasons, so it is never mistaken for a normal supported scan and cannot become a new strict baseline without a further explicit acknowledgment.
--gcc-path no Path to a GCC/G++ (or clang) cross-compiler binary.
--gcc-prefix no Cross-toolchain prefix (e.g. aarch64-linux-gnu-).
--gcc-options no Extra compiler flags passed through to the header frontend (split on whitespace). For a flag whose value contains spaces use --gcc-option.
--gcc-option no A single extra compiler flag passed to the header frontend verbatim (repeatable; not whitespace-split). Use two for a flag + spaced value, e.g. --gcc-option=-include --gcc-option='some header.h'.
--sysroot no Alternative system root directory for header resolution.
--nostdinc, --no-nostdinc no False Do not search the standard system include paths (suppresses the castxml/clang system-include auto-detection too). Paired form so an explicit --no-nostdinc on scan can override a config compile.nostdinc: true for a one-off run (CLI > config).
--frontend-context no host Which AST context the L2 header frontend should target (ADR-050 D3/D5). 'device' selects the SYCL/DPC++ offload-device AST from a DPC++-capable compiler (icx/icpx/dpcpp) invoked with -fsycl; it fails loudly if the configured frontend cannot produce a device context. Matches a manifest's own frontend_context field for the legacy, non-manifest path. Choices: host, device.

project

Advanced multi-target project integration (ADR-047).

project plan

Generate run-plan.json from CONFIG's targets:/bundles:/profiles: block.

Arguments

Name Required Description
config no

Options

Option Required Default Description
--build-output no One contract profile's abicheck-build/ directory (containing build-output.json), as profile_id=path/to/dir. Repeatable — pass one per profile referenced by CONFIG's checks:.
--project no `` Project identifier recorded in run-plan.json, e.g. owner/repo.
--head-sha no `` Candidate commit SHA recorded in run-plan.json.
--toolchain-bindings no Path to a trusted toolchain-bindings file (schema abicheck.toolchain-bindings/v1). Every declared profiles..compile.binding (and consumer_compile.binding) is checked against it (an unresolvable binding, or a resolved binding whose probed identity disagrees with a declared compiler_family/compiler_version/target, is a generation error, same severity as an unresolvable build-output target) -- identity probing only covers the profiles the generated plan actually resolves a check for, not every profile declared in CONFIG (unlike project validate, which checks every declared profile); each resolved cell's compile_gcc_path is populated from it. Omitting this flag skips the check entirely and leaves compile_gcc_path empty on every cell — backward compatible, matching project validate --toolchain-bindings.
--allow-empty no False Accept a run-plan that resolves to zero checks (exit 0 instead of 1). Off by default: an empty run-plan silently skips every downstream matrix/aggregate step, so a consumer that doesn't add its own guard would report success having checked nothing. Pass this only for a deliberately empty bootstrap run (e.g. before any targets: are declared yet).
--format no json Output format for the generated run-plan. Choices: json, text.
--output, -o no Write output to this path (default: stdout).
--verbose, -v no False Enable verbose/debug output.

project validate

Validate CONFIG's targets:/bundles:/profiles:/baseline: block (ADR-047 §3).

Arguments

Name Required Description
config no

Options

Option Required Default Description
--format no text Output format for the validation report. Choices: text, json.
--output, -o no Write output to this path (default: stdout).
--toolchain-bindings no Path to a trusted toolchain-bindings file (schema abicheck.toolchain-bindings/v1) to additionally check every declared profiles..compile.binding (and consumer_compile.binding) resolves, and — when compiler_family/compiler_version/target is also declared — that the resolved executable's probed identity actually matches. Loaded only from this explicit path — never auto-discovered, per the untrusted-config trust boundary ProfileCompileSpec.binding documents.
--verbose, -v no False Enable verbose/debug output.

project validate-build

Validate DIRECTORY's build-output.json (ADR-047 §11.1).

Arguments

Name Required Description
directory yes

Options

Option Required Default Description
--format no text Output format for the validation report. Choices: text, json.
--output, -o no Write output to this path (default: stdout).
--verbose, -v no False Enable verbose/debug output.

scan

Deterministic source-intelligence scan (classify → always-on tier → level).

Arguments

Name Required Description
artifact no

Options

Option Required Default Description
--bundle-system-providers no `` Comma-separated extra sonames to treat as system-provided (extends the built-in libc/libstdc++/libgcc/libtbb allow-list). Only meaningful with --artifact-set.
--artifact-set no Audit a set of libraries with no old side, as one artifact (ADR-056): a directory (every discoverable shared library in it) or an explicit comma-separated path list. Mutually exclusive with the positional ARTIFACT and with --against (audit-only — no old-side comparison for a set).
--header, -H no Public header file or directory (repeatable). Applies to the current ARTIFACT by default; scope to the --against side with an 'old=' prefix (e.g. --header old=old/include, --header new=new/include).
--include, -I no Additional include directory for header parsing (repeatable). Same old=/new= side-aware scoping as --header.
--public-header-dir no Directory whose headers are public for provenance classification (repeatable). Establishes the public/internal boundary so the leakage / RTTI / exported-vs-public cross-checks run instead of skipping. A directory passed via -H also counts; a lone -H umbrella file cannot establish a boundary, so origins stay UNKNOWN unless a directory is given.
--sources no Source tree (compile DB auto-discovered within it).
--build-info no Out-of-tree build dir / compile_commands.json / pack supplying build context.
--compile-db no Explicit compile_commands.json (use when not under --sources).
--config no Trusted project .abicheck.yml (enables build.query with --allow-build-query). Also supplies scope/suppression settings (scope.public, scope.public_symbols, suppression.strict) the same way compare --config does (CLI flags override); auto-discovered upward from the current directory when omitted.
--against no Previous native library or saved ABI dump to compare ARTIFACT against (a single file -- not a directory or package; for those use abicheck compare OLD\_PACKAGE NEW\_PACKAGE). Without --against, scan runs a one-build audit/hygiene/source consistency scan only; with it, scan also compares ARTIFACT against this (the two modes are not separate flags -- --against alone selects between them).
--depth no Evidence depth to collect -- the single dial, named by what you get: binary (symbols only), headers (+header AST), build (+build context), source (+source replay & call graph). Omit for 'auto' (risk-driven when a --since/--changed-path seed is present, else a sensible default). --depth source uses changed-path scope when --since/--changed-path is given, else the current library target -- never a zero-TU no-op.
--since no Focus the scan on files changed vs a git ref (e.g. origin/main).
--changed-path no Changed path to focus the scan on (repeatable; alternative to --since).
--budget no Time guard (e.g. 15m); FAILS on overflow, never shrinks scope.
--abi3 no Audit a CPython extension against a Py_LIMITED_API floor, e.g. 3.9. Classifies the module's imported CPython C-API against the stable ABI and flags private/unstable imports and stable symbols newer than the floor as python\_stable\_abi\_violation (advisory; gate with --crosscheck python\_stable\_abi\_violation=error). Requires a CPython extension module as the --binary.
--dry-run no False Resolve and validate the invocation -- classify inputs, resolve changed paths, show the audit checks and (if --against) the comparison that would run, and print projected per-layer cost -- without scanning. Writes nothing; incompatible with -o/--output.
--crosscheck no Per-check level KEY=LEVEL (off|info|warning|error); repeatable.
--risk-rules no Override the risk_rules profile (YAML).
--policy no strict_abi Built-in policy profile for verdict classification. Ignored when --policy-file is given. Choices: strict_abi, sdk_vendor, plugin_abi.
--policy-file no YAML policy file with per-kind verdict overrides, or a built-in name (e.g. 'security'). Overrides --policy.
--suppress no Suppression file (YAML) to filter known/intentional changes.
--scope-public-headers, --no-scope-public-headers no True Restrict findings to the public-header ABI surface (ADR-024): changes to symbols/types not reachable from public-header-declared exported API are recorded as filtered, not reported. Internal-type leaks are never hidden. On by default; use --no-scope-public-headers to report every finding regardless of surface.
--strict-suppressions no False With --against: fail with exit code 1 if any --suppress rule has expired (mirrors compare --strict-suppressions, ADR-049 Phase 5 §6.4).
--public-symbol no With --against: force a symbol (mangled or demangled name) into the public surface even when header provenance can't see it (mirrors compare --public-symbol). Repeatable. Only meaningful with --scope-public-headers.
--public-symbols-list no With --against: file of symbols to force public (one per line; '#' comments and blank lines ignored), merged with --public-symbol (mirrors compare --public-symbols-list).
--pattern-verdicts, --no-pattern-verdicts no False With --against: modulate verdicts with idiom/anti-pattern evidence (ADR-027, mirrors compare --pattern-verdicts): demote opaque-pointer/PIMPL-hidden layout changes and raise breaks when an opacity/handle guarantee is lost.
--env-matrix no Environment-matrix YAML declaring deployment constraints (ADR-020b). With runtime_floors (e.g. 'runtime_floors: {GLIBC: "2.28"}'), a new symbol-version requirement is judged against the declared floor: at/below it -> compatible, above it -> breaking, instead of the default deployment-risk verdict.
--contract-evaluation no False With --against: stamp each comparison finding with its ADR-049 contract decision (contract_relevance / contract_reason_code / contract_assurance / contract_evidence_refs), exactly as compare --contract-evaluation does. The decisions are authoritative (ADR-049 Phase 7): relevance is classified before compatibility policy, which then scores only IN_CONTRACT/NOT_APPLICABLE findings -- so this changes the verdict and the exit code, while the excluded findings stay in the report with the reason they did not gate. Separately, if the selected domain's evidence is incomplete the orthogonal contract-coverage ledger contributes exit 1 (folded with max, so it never lowers a 2/4). Set contract.unresolved=warn via a kind: contract --pack to accept incomplete coverage; the failures stay reported either way.
--contract no With --against: which evidence domain --contract-evaluation judges against ('public' header-derived surface, 'exports' the binary's own export table plus its type closure, 'all' every entity). Omitted, the domain follows --scope-public-headers/--no-scope-public-headers. Requires --contract-evaluation. The domain decides which findings compatibility policy scores, so it can change the verdict and the exit code, and it is also what the orthogonal contract-coverage axis is answered against (mirrors compare --contract). Choices: public, exports, all.
--pack no Select an ADR-049 D8 pack manifest (repeatable). A pack is a small versioned YAML document (id/version/kind/assignments) carrying one reusable piece of configuration. 'kind: policy' assigns ChangeKind slugs to break/warn/risk/ignore, exactly as --policy-file's overrides do; 'kind: contract' assigns surface.internal_namespaces and contract.unresolved (the latter needs --contract-evaluation, which is what computes the coverage it configures); 'kind: gate' assigns gate.exit_code_scheme and gate.severity.. Composition is D8's: an explicitly stated value (--policy-file, --exit-code-scheme, --severity-*, a --profile, or .abicheck.yml) always outranks a pack, and two selected packs assigning different values to the same field are a usage error unless something else already states it. A manifest assigning a field this build resolves but does not yet apply is rejected rather than silently recorded, as is --pack on a directory/package (release) comparison, whose per-library fan-out dispatches before the effective configuration is resolved. On scan this requires --against (a pack's only application there is the baseline comparison) and a 'kind: gate' pack is rejected, since a scan's exit code follows its verdict directly and has no gate to move.
--lang no c++ Language mode for the header backend. Choices: c++, c.
--format no text Output format. Choices: text, json.
--output, -o no Write output to this path (default: stdout).
--verbose, -v no False Enable verbose/debug output.
--ast-frontend no auto C/C++ AST frontend (ADR-037 D8): castxml (default schema reference) or clang (-ast-dump=json; for hosts where castxml is absent or its bundled frontend chokes). hybrid (G28 Phase 3) runs BOTH and merges them (dumper_hybrid.merge_snapshots) — needs both tools installed and costs roughly 2x a single-backend dump; never selected by auto. auto resolves to castxml (or the ABICHECK_AST_FRONTEND pin) and never changes producer unless --allow-ast-frontend-fallback (or ABICHECK_ALLOW_AST_FALLBACK=1) is explicitly set. Env: ABICHECK_AST_FRONTEND. Choices: auto, castxml, clang, hybrid.
--allow-ast-frontend-fallback no False Allow auto-selected CastXML to fall back to Clang for a recognized toolchain mismatch or direct-include guard. Disabled by default because the frontends can produce materially different findings.
--allow-unsupported-castxml no False Proceed with a CastXML build outside the supported version range (castxml_policy.MIN_CASTXML/MAX_CASTXML/MIN_CASTXML_CLANG_MAJOR) instead of aborting the scan before headers are parsed. Exploratory-mode-only: the resulting snapshot's ast_toolchain_supported is recorded as false with ast_toolchain_unsupported_reasons, so it is never mistaken for a normal supported scan and cannot become a new strict baseline without a further explicit acknowledgment.
--gcc-path no Path to a GCC/G++ (or clang) cross-compiler binary.
--gcc-prefix no Cross-toolchain prefix (e.g. aarch64-linux-gnu-).
--gcc-options no Extra compiler flags passed through to the header frontend (split on whitespace). For a flag whose value contains spaces use --gcc-option.
--gcc-option no A single extra compiler flag passed to the header frontend verbatim (repeatable; not whitespace-split). Use two for a flag + spaced value, e.g. --gcc-option=-include --gcc-option='some header.h'.
--sysroot no Alternative system root directory for header resolution.
--nostdinc, --no-nostdinc no False Do not search the standard system include paths (suppresses the castxml/clang system-include auto-detection too). Paired form so an explicit --no-nostdinc on scan can override a config compile.nostdinc: true for a one-off run (CLI > config).
--frontend-context no host Which AST context the L2 header frontend should target (ADR-050 D3/D5). 'device' selects the SYCL/DPC++ offload-device AST from a DPC++-capable compiler (icx/icpx/dpcpp) invoked with -fsycl; it fails loudly if the configured frontend cannot produce a device context. Matches a manifest's own frontend_context field for the legacy, non-manifest path. Choices: host, device.