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 — The set of targets this matrix was supposed to produce. Either shape is accepted and recognized by its own content: an expected-target manifest (JSON: {"targets": [{"id", "required"}]}), or an abicheck project plan run-plan.json (declaring schema: abicheck.run-plan/vN), projected to the manifest shape internally so each check's own check_id becomes the expected target id — which is what check-target writes as every report's target_id. The single source of truth for the expected set: generate it in the plan job and feed the same file to both the matrix and this gate so they never drift.
--discovered-only no False Explicitly aggregate whatever reports are present, with NO coverage gate. Required to run without --manifest — because with no declared target set the gate cannot tell a missing required target from an intentionally absent one. Deliberately a flag of its own rather than something inferred from an absent or empty manifest: it states that the operator has no expected inventory, which no document's contents can say for them.
--analysis-context no — A JSON document recording WHICH revision this run analysed, emitted verbatim into the aggregate document's analysis\_context block. On a pull-request build the commit actually checked out is an ephemeral merge commit that no GitHub API endpoint names, so a trusted publisher has no way to learn it except from the producer -- this is how the producer says it, inside the artifact it already publishes, rather than in a sidecar file a publisher would have to parse in privileged shell. Every field is a CLAIM and is shape-validated here, never trusted: a publisher verifies it against the API before displaying it.
--output, -o no — Export this run's report as FORMAT to DESTINATION. FORMAT is one of text/json; DESTINATION is a file path, or '-' for stdout. Repeatable: every export renders the same completed analysis, so the result never depends on which (or how many) you ask for. Default: text=-.
--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 no

Options

Option Required Default Description
--help no False Show common options and exit. Use --help-all to see the remaining advanced options.
--help-all no False Show every option, including advanced/less-common ones.
--no-baseline no False Declare that no prior surface exists for this candidate -- an audit, not a comparison. Takes exactly one operand (the candidate build) instead of OLD NEW; a directory/package of libraries is audited per member (--select/--select-required apply) into one report. The OLD side is recorded with the 'declared_absent' acquisition state. Replaces scan's audit-only mode (no --against): reports candidate-side facts only -- never an addition, a removal, or a compatibility verdict. --severity-preset is the sole switch that arms this audit's own gate: any preset other than 'info-only' contributes exit 3 the first time a finding is BREAKING/API_BREAK-classified; omit it, or pass 'info-only', to opt out.
--select no — Declare an optional expected release member. Repeatable -- see --select-required (directory/package inputs only).
--select-required no — Declare a required expected release member by its canonical release-matching key (e.g. 'libfoo.so', never a raw filename stem; directory/package inputs only). Repeatable. With any --select/--select-required given, only declared members are compared. A missing declared-required member contributes to the .abicheck.yml scope.on_incomplete completeness gate; a plain --select member does not.
--bundle-facts-out no — Persist this run's OLD-side bundle facts (per-library snapshots plus the instantiation manifest, if any) to PATH for a later stored-baseline bundle comparison. Additive output alongside the ordinary live-vs-live comparison. (directory/package inputs only) Phase 7d (one-comparison-product.md §4.1) originally classed this REMOVE ("evidence capture belongs to dump (D2)"). Ruled explicitly, not left pending: dump has no directory/package fan-out at all today -- its operand is a single binary/header input, with no equivalent that walks a release tree and writes a multi-library BundleFacts document -- so this is not a duplicate spelling of a dump capability to collapse, it is the only way to produce a stored-baseline bundle-facts document for a later compare OLD\_FACTS NEW\_INPUT bundle comparison. Under D5's own test it is a per-run operand exactly like -o/--output: PATH names where this invocation's evidence capture lands, which is not a stable project property (it varies by run/CI job, e.g. by date or build id) and has no config vocabulary to merge into (guard 1) without inventing one purely to move a path string (guard 2's "no escape hatch" cuts the other way here -- a fixed config path would make the flag's own PATH argument the escape hatch). Stays a compare CLI flag; revisit only if dump grows a real release fan-out, at which point this becomes a duplicate spelling of that capability rather than the only one.
--instantiation-manifest no — ABI instantiation manifest (YAML/JSON) listing symbols the release publicly promises. Renamed from --manifest (CLI cleanup phase two, PR J): the bare spelling collided with aggregate's own --manifest and the product's several other manifest-shaped concepts (dump manifest, run plan, bundle facts, project config). (directory/package inputs only) Phase 7d (one-comparison-product.md §4.1) classes this CONFIG ("a declared contract is a project property") with no stated prerequisite, but its natural home -- a project-config document -- already has an owner: the compatibility evaluation config resolves a whole contract.* namespace through its own D7 precedence tiers (compatibility_evaluation_frontend.py), separate from this plain BuildConfig/.abicheck.yml schema. Adding a second, uncoordinated top-level contract: block here -- with no D7 resolver, no receipt, no pack-conflict detection -- would be exactly the ad hoc config plumbing this workstream's own task instructions warn against inventing casually, not a mechanical rename. Kept as a CLI flag pending a real design for where a declared instantiation manifest belongs.
--bundle-facts-library-manifest no — When OLD_INPUT is a stored BundleFacts document (from a prior --bundle-facts-out): a YAML/JSON manifest giving one or more libraries their own header root, include path, or compile context, instead of the uniform --header/--include/compile-context flags -- for a bundle whose libraries don't share one toolchain (e.g. a plain-C++ library alongside a -fsycl/icpx one). Shaped {library_name: {headers: [...], includes: [...], gcc_path: ..., gcc_options: [...], sysroot: ..., ...}}; a library not named in the manifest keeps the uniform fallback.
--exclude-header no — Exclude headers matching PATTERN (fnmatch-style) from the parsed surface. Matched against the header's bare name (--exclude-header fftw3.h), its full path, or a glob (--exclude-header '*/detail/'). Repeatable; applies to both sides. Use it when a header directory contains headers that cannot be parsed together -- two vendored copies of a third-party API declaring conflicting typedefs, for example -- which otherwise makes the whole directory unusable as a -H operand. A matching header reached through another header's #include is scoped out like a toolchain header: what only it declares is not observed (reported as reduced evidence, not a removal), while types the library's own API uses are still checked. Requires dependency scoping (off under --include-system-declarations).
--header, -H no — Public header file or directory -- or a development package carrying them (RPM/Deb/tar; directory/package inputs only), which is recognised from the operand's content rather than its name. 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. Recommended for full ABI analysis; without headers, abicheck uses whatever artifact evidence is available instead (ELF may add DWARF/BTF/CTF, PE may add PDB, Mach-O stays limited to binary metadata: exports plus load-command facts like install name, dependencies, and rpaths) but has no header AST or public-surface scoping. 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. 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.
--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'.
--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. 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.
--output, -o no — Export this run's report as FORMAT to DESTINATION. FORMAT is one of json/markdown/sarif/html/junit/review/terminal/oneline; DESTINATION is a file path, or '-' for stdout. Repeatable: every export renders the same completed analysis, so the result never depends on which (or how many) you ask for. Default: terminal=-. A DESTINATION ending in '/' (or naming an existing directory) is a per-component export: every component's own complete report is written there (json only). 'review' emits a compact GitHub-facing digest (verdict + counts + release recommendation + manual-review banner) suitable for a job summary or PR comment; 'oneline' emits a single human-readable summary line -- the 'just tell me' flow. A directory/package (release) comparison renders json/markdown/junit/oneline/html only. Every export is rendered from the one completed comparison -- asking for more artifacts never re-runs the analysis and never changes the verdict or the exit code.
--view no — Repeatable rendering selector: never changes the verdict, findings, or exit code. TOKEN: 'full' (default)/'impact'/'root-cause' (report mode); 'show=' (display filter over severity [breaking/api-break/risk/compatible], element [functions/variables/types/enums/elf/build/source/analysis] and action [added/removed/changed/unchanged] -- AND across dimensions, OR within one, repeatable to OR whole groups together). Example: --view root-cause --view show=breaking,functions. Disclosure is not a token: the pattern-modulation ledger, the scope/reconciliation ledger and the --suppress audit are always reported, and C++ symbols are always demangled in human output with the exact mangled name kept beside them.
--policy no strict_abi How verdicts are classified: a built-in profile (strict_abi, sdk_vendor, plugin_abi), or a YAML policy document -- a path, or a packaged built-in name like 'security' -- carrying per-kind ('overrides:') or selector-scoped ('reclassify:') re-classification.
--suppress no — Suppression file (YAML) to filter known/intentional changes.
--used-by no — Application binary whose actual imports/required symbol versions scope the comparison (repeatable; folds appcompat). The full library comparison always determines this run's own verdict/exit code, exactly as it would without --used-by; the supplied application's own confirmed/potential/unresolved impact is reported alongside it (informational), never in place of it. 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-symbol no — An exported linker symbol a plugin host resolves via dlopen/dlsym and requires (repeatable; folds plugin-check). '@FILE' reads required symbols from FILE, one per line (blank lines and '#' comments ignored) -- combinable with plain symbol values, but at most one '@FILE' per invocation. The full library comparison always determines this run's own verdict/exit code; this contract's own confirmed/potential/unresolved impact is reported alongside it (informational), never in place of it. Mutually exclusive with --used-by.
--used-by-manifest no — A JSON document naming one or more consumer binaries (repeatable), each with optional 'digest'/'platform'/'profile'/'provider_baseline' provenance and a 'requirement': 'required' (default, an unreadable consumer aborts the run, same as --used-by) or 'advisory' (an unreadable consumer is skipped and reported, never aborts the run). Merged into the same scoping pipeline as --used-by; every listed consumer counts toward the reported 'N of M consumers affected' summary. Mutually exclusive with --required-symbol.
--severity-preset no — Severity preset: 'default', 'strict', or 'info-only'. Controls exit codes and report labels. A project config's severity: block overrides individual categories of the preset. Choices: default, strict, info-only.
--config no — Path to the project .abicheck.yml. Default: the nearest .abicheck.yml found from the current directory upward. Supplies stable project settings (severity map, scope/FP tuning, suppression policy); CLI flags override it.
--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-system-declarations no False Include declarations that came from toolchain/system headers (std::/SYCL/etc. pulled in transitively by #include). Unrelated to --follow-deps, which walks the DT_NEEDED library graph. By default these declarations 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).
--define, -D no — Define a preprocessor macro for the header parse (repeatable). A one-off override for headers whose public surface is gated behind a feature macro, e.g. -DPVXS_ENABLE_EXPERT_API or -DPCRE2_CODE_UNIT_WIDTH=8. Applies to both sides of a compare. For a stable project/CI contract prefer .abicheck.yml's compile.defines:, which this overrides per macro name. Takes a macro definition only -- general compiler flags stay in compile.options.
--search-path no — Additional directory to search for shared libraries (with --follow-deps).
--ld-library-path no `` Simulated LD_LIBRARY_PATH (with --follow-deps).
--debug-info no — Separate debug info for a side, in any of its three transports: a directory to search (build-id tree, path mirror, dSYM bundles), a detached DWARF debug file (a .debug sidecar), or a debug package (RPM/Deb/tar; directory/package inputs only). Which one an operand is comes from its content, not its name. Applies to both sides; scope to one with an 'old='/'new=' prefix, repeating the flag per side (e.g. --debug-info old=dbg1 --debug-info new=b-dbg.rpm). Repeatable.
--build-info no — Out-of-band build evidence: a build dir, a compile_commands.json or a pack (compile context, overriding embedded), or a probe-matrix snapshot (build-configuration observations). Which one an operand is comes from the document, not its name, and both kinds may be given for one side -- a matrix on both sides folds CXX_STANDARD_FLOOR_RAISED/API_DEPENDS_ON_CONSUMER_ENV/BEHAVIOURAL_DEFAULT_CHANGED into this comparison's verdict and report (G2: probe -> compare). 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).
--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).
--depth no — Evidence-depth dial: binary=symbols + binary metadata + DWARF types when present, headers=+header AST (default), build=+build context, source=+source replay & call graph. Deeper-than-headers needs --sources or --build-info.
--since no — Focus this run's source-evidence scope on the files changed vs a git ref (e.g. origin/main), resolved with git diff --name-only <ref>...HEAD. Same scoping-only effect as --changed-path, which wins when both are given; a ref that cannot be resolved warns and leaves the scope broad.
--changed-path no — Changed path to focus this run's source-evidence scope on (repeatable; alternative to --since). Narrows the L4/L5 points of interest a --depth source run examines; produces no finding of its own and never changes a verdict.
--abi3 no — Audit the candidate (NEW) 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 it through --policy/.abicheck.yml policy.overrides). Requires the candidate to be a CPython extension module -- anything else is an evidence-contract error (exit 7). Overrides .abicheck.yml's python.abi3_floor for this run.
--budget no — A wall-clock guard on this run's deadline-aware stages, so a CI job fails clearly (exit 5) instead of running unbounded. A duration like 15m/900s/1h; unset means no budget.
--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 A diagnostic 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 no — Which evidence domain each finding is judged against, and the flag that turns the contract evaluator on -- omit it and nothing about the run changes. '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 (replaces the removed --no-scope-public-headers). 'auto': evaluate, but let .abicheck.yml's scope.public choose the domain (public when unset). Each finding is stamped with a contract_relevance (IN_CONTRACT/PROVEN_OUT_OF_CONTRACT/UNKNOWN_UNPROVEN/UNKNOWN_UNRESOLVED/NOT_APPLICABLE), a contract_reason_code and -- when resolved -- a contract_assurance, rendered per finding in -o json=.../markdown, in sarif/junit properties, and as an html badge; -o review=...'s compact digest renders it only in the --used-by/--required-symbol scoped-gate appendix. -o json=... additionally carries contract_evidence_refs per finding (which evidence records the decision rests on) and a top-level contract_context block (observed provider evidence, resolved evaluation context, decision receipt), so a decision can be replayed or re-evaluated later without re-reading the binaries. The decisions are authoritative: relevance is classified before compatibility policy, and policy scores only IN_CONTRACT/NOT_APPLICABLE findings -- so this changes verdicts and exit codes. Nothing is hidden: an excluded finding stays in the report with the relevance and reason that explain why it 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. The coverage floor itself applies to a directory/package (release) comparison too -- each library's own floor is max()-folded into the release's exit code the same way, and a pack-supplied contract.unresolved applies there too (see --pack's own help). Choices: public, exports, all, auto.
--pack no — Select a 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's overrides do; 'kind: contract' assigns surface.internal_namespaces and contract.unresolved (the latter needs --contract, which is what computes the coverage it configures); 'kind: gate' assigns gate.severity. (gate.exit_code_scheme was removed along with --exit-code-scheme, CLI cleanup phase two PR G2 -- the one automatic gate algorithm is fully determined by whether a severity setting is in effect, so a pack asserting it is rejected at load time). Composition is D8's: an explicitly stated value (--policy, --severity-preset, 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. On a directory/package (release) comparison, a 'kind: policy'/'kind: contract'/'kind: gate' pack's policy.overrides/surface.internal_namespaces/contract.unresolved/gate.severity. all apply to every library uniformly (folded into the release's own resolved GateOptions); contract.unresolved still needs --contract on that release comparison, same as everywhere else.
--use-cases no — An impact-use-cases.yaml manifest whose declared use cases this comparison's own findings are attributed to: for each use case, which changes its resolved entrypoints can be shown to reach. Needs a source graph on at least one side (dump --sources/--build-info, or the always-on header-only graph). Read-only -- an unattributed finding is an absence of proof, not proof the finding is harmless, so this never moves a verdict or an exit code. Validate a manifest on its own with abicheck project validate.
--performance-profile no — The memory/speed trade-off to run under; overrides .abicheck.yml's performance.profile. 'balanced' (default) is fastest; 'low-memory' resolves one side at a time, each in its own process on Linux, for the lowest peak memory. Never changes findings or the exit code. Choices: balanced, low-memory.
--verbose, -v no False Enable verbose/debug output.
--variant no — Which build variant to compare when an operand is a stored ProjectSnapshot package directory declaring more than one. Scope to one side with an 'old='/'new=' prefix, repeating the flag per side (e.g. --variant old=v1 --variant new=v2); a bare value applies to both. Defaults to the package's only variant when it declares exactly one; a usage error otherwise. No-op for a live directory/archive/single-file operand.

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).
--output, -o no — Export this run's report as FORMAT to DESTINATION. FORMAT is one of json/markdown/html; DESTINATION is a file path, or '-' for stdout. Repeatable: every export renders the same completed analysis, so the result never depends on which (or how many) you ask for. Default: markdown=-.
--dry-run no False Show old/new roots, resolved binary paths, and search order without running per-library ABI diffs. Writes nothing; incompatible with any -o export to a file.
--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).
--output, -o no — Export this run's report as FORMAT to DESTINATION. FORMAT is one of json/markdown/html; DESTINATION is a file path, or '-' for stdout. Repeatable: every export renders the same completed analysis, so the result never depends on which (or how many) you ask for. Default: markdown=-.
--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
--help no False Show common options and exit. Use --help-all to see the remaining advanced options.
--help-all no False Show every option, including advanced/less-common ones.
--header, -H no — Public header file or directory (repeat for multiple).
--include, -I no — Extra include directory for castxml.
--exclude-header no — Exclude headers matching PATTERN (fnmatch-style) from the parsed surface. Matched against the header's bare name (--exclude-header fftw3.h), its full path, or a glob (--exclude-header '*/detail/'). Repeatable; applies to both sides. Use it when a header directory contains headers that cannot be parsed together -- two vendored copies of a third-party API declaring conflicting typedefs, for example -- which otherwise makes the whole directory unusable as a -H operand. A matching header reached through another header's #include is scoped out like a toolchain header: what only it declares is not observed (reported as reduced evidence, not a removal), while types the library's own API uses are still checked. Requires dependency scoping (off under --include-system-declarations).
--include-system-declarations no False Include declarations that came from toolchain/system headers (std::/SYCL/etc. pulled in transitively by #include). Unrelated to --follow-deps, which walks the DT_NEEDED library graph. By default these declarations 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).
--define, -D no — Define a preprocessor macro for the header parse (repeatable). A one-off override for headers whose public surface is gated behind a feature macro, e.g. -DPVXS_ENABLE_EXPERT_API or -DPCRE2_CODE_UNIT_WIDTH=8. Applies to both sides of a compare. For a stable project/CI contract prefer .abicheck.yml's compile.defines:, which this overrides per macro name. Takes a macro definition only -- general compiler flags stay in compile.options.
--version no unknown Library version string to embed in snapshot.
--output, -o no — Output JSON file. Defaults to stdout.
--compression no auto Snapshot storage envelope: 'auto' infers gzip/zstd/plain from -o/--output's suffix (.json.gz/.json.zst/plain .json); an explicit value is used as-is and errors if it contradicts the output suffix. Compression is a storage detail only -- it never changes the decoded snapshot content. Choices: auto, none, gzip, zstd.
--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).
--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-info no — Separate debug info: a directory to search (build-id tree, path mirror, dSYM bundles) or a detached DWARF debug file (a .debug sidecar) -- told apart by content, not name. Repeatable. A debug package is a release transport (compare --debug-info), rejected here rather than ignored.
--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 (declare the public surface in the manifest's own roots field and base profile instead). ELF only so far.
--verbose, -v no False Enable verbose/debug output.
--provenance no — Repeatable provenance stamp for the snapshot. KEY=VALUE, one of: 'git-tag=' (e.g. git-tag=v2.0.0), 'build-id=' (CI run ID, build number, ...), or 'git=auto'/'git=off' ('off' skips commit-SHA auto-detection). Replaces --git-tag/--build-id/--no-git. A repeated key is last-one-wins. Example: --provenance git-tag=v2.0.0 --provenance build-id=ci-1234.
--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. When it resolves to a compile database and -H/--header is given, that database also parameterizes the header parse with the build's exact flags (scope it with build.compile_db_filter in .abicheck.yml).
--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.)
--config no — Path to the project .abicheck.yml: 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 -- an auto-discovered one never executes it, and no CLI flag can authorize it.
--depth no — Evidence-depth dial (same vocabulary as compare --depth): binary=symbols + binary metadata + DWARF types when present, headers=+header AST (default), build=+build context, source=+source replay & call graph.

project

Advanced multi-target project integration.

project capture-variants

Capture every declared bundle variant into one ProjectSnapshot package.

Options

Option Required Default Description
--variant yes — Capture declared bundle variant NAME from PATH: a binary, a directory of binaries/snapshots, or a single snapshot (the same operand shape compare's release fan-out takes). Repeatable, one per variant. NAME must be declared under .abicheck.yml bundle_variants:.
--package yes — Directory to write the one multi-variant ProjectSnapshot package to. Must not exist or be empty; written atomically, so a failed capture leaves nothing behind.
--config no — The .abicheck.yml whose bundle_variants: block declares the variants. Default: the nearest project config at or above the current directory.
--variant-header no — A public header (or header directory) for variant NAME's dumps. Repeatable.
--variant-include no — An include directory for variant NAME's header parse. Repeatable.
--dry-run no False Resolve and check the plan (every required variant reachable, every input discoverable) and report it, without capturing or writing.
--output, -o no — Export this run's report as FORMAT to DESTINATION. FORMAT is one of text/json; DESTINATION is a file path, or '-' for stdout. Repeatable: every export renders the same completed analysis, so the result never depends on which (or how many) you ask for. Default: text=-.

project history

Derive per-API lifecycle events from an ordered chain of SNAPSHOTS (offline longitudinal compatibility history).

Arguments

Name Required Description
snapshots yes

Options

Option Required Default Description
--version no — Explicit release label for one SNAPSHOT, in the same order as the SNAPSHOTS arguments (repeatable — pass one per snapshot, or omit entirely). Without this, each snapshot's own recorded AbiSnapshot.version is used as its release label.
--policy no strict_abi How verdicts are classified: a built-in profile (strict_abi, sdk_vendor, plugin_abi), or a YAML policy document -- a path, or a packaged built-in name like 'security' -- carrying per-kind ('overrides:') or selector-scoped ('reclassify:') re-classification.
--output, -o no — Export this run's report as FORMAT to DESTINATION. FORMAT is one of json/text/html; DESTINATION is a file path, or '-' for stdout. Repeatable: every export renders the same completed analysis, so the result never depends on which (or how many) you ask for. Default: json=-.
--verbose, -v no False Enable verbose/debug output.

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.
--output, -o no — Export this run's report as FORMAT to DESTINATION. FORMAT is one of json/text; DESTINATION is a file path, or '-' for stdout. Repeatable: every export renders the same completed analysis, so the result never depends on which (or how many) you ask for. Default: json=-.
--verbose, -v no False Enable verbose/debug output.

project validate

Validate INPUT, a project-integration document.

Arguments

Name Required Description
input_path no

Options

Option Required Default Description
--output, -o no — Export this run's report as FORMAT to DESTINATION. FORMAT is one of text/json; DESTINATION is a file path, or '-' for stdout. Repeatable: every export renders the same completed analysis, so the result never depends on which (or how many) you ask for. Default: text=-.
--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. Applies to a project config; supplying it with any other INPUT is a usage error.
--verbose, -v no False Enable verbose/debug output.