abicheck 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- abicheck-0.1.0/LICENSE +89 -0
- abicheck-0.1.0/NOTICE.md +42 -0
- abicheck-0.1.0/PKG-INFO +490 -0
- abicheck-0.1.0/README.md +450 -0
- abicheck-0.1.0/abicheck/__init__.py +9 -0
- abicheck-0.1.0/abicheck/abicc_dump_import.py +20 -0
- abicheck-0.1.0/abicheck/checker.py +2634 -0
- abicheck-0.1.0/abicheck/checker_policy.py +744 -0
- abicheck-0.1.0/abicheck/cli.py +508 -0
- abicheck-0.1.0/abicheck/compat/__init__.py +11 -0
- abicheck-0.1.0/abicheck/compat/abicc_dump_import.py +256 -0
- abicheck-0.1.0/abicheck/compat/cli.py +1293 -0
- abicheck-0.1.0/abicheck/compat/descriptor.py +121 -0
- abicheck-0.1.0/abicheck/compat/xml_report.py +384 -0
- abicheck-0.1.0/abicheck/detectors.py +32 -0
- abicheck-0.1.0/abicheck/dumper.py +897 -0
- abicheck-0.1.0/abicheck/dwarf_advanced.py +911 -0
- abicheck-0.1.0/abicheck/dwarf_metadata.py +658 -0
- abicheck-0.1.0/abicheck/dwarf_unified.py +118 -0
- abicheck-0.1.0/abicheck/dwarf_utils.py +71 -0
- abicheck-0.1.0/abicheck/elf_metadata.py +342 -0
- abicheck-0.1.0/abicheck/errors.py +29 -0
- abicheck-0.1.0/abicheck/html_report.py +951 -0
- abicheck-0.1.0/abicheck/model.py +213 -0
- abicheck-0.1.0/abicheck/policy_file.py +194 -0
- abicheck-0.1.0/abicheck/report_classifications.py +163 -0
- abicheck-0.1.0/abicheck/report_summary.py +66 -0
- abicheck-0.1.0/abicheck/reporter.py +263 -0
- abicheck-0.1.0/abicheck/sarif.py +204 -0
- abicheck-0.1.0/abicheck/serialization.py +287 -0
- abicheck-0.1.0/abicheck/suppression.py +195 -0
- abicheck-0.1.0/abicheck.egg-info/PKG-INFO +490 -0
- abicheck-0.1.0/abicheck.egg-info/SOURCES.txt +113 -0
- abicheck-0.1.0/abicheck.egg-info/dependency_links.txt +1 -0
- abicheck-0.1.0/abicheck.egg-info/entry_points.txt +2 -0
- abicheck-0.1.0/abicheck.egg-info/requires.txt +12 -0
- abicheck-0.1.0/abicheck.egg-info/top_level.txt +1 -0
- abicheck-0.1.0/pyproject.toml +101 -0
- abicheck-0.1.0/setup.cfg +4 -0
- abicheck-0.1.0/tests/test_abi_examples.py +146 -0
- abicheck-0.1.0/tests/test_abicc_compat_flags.py +233 -0
- abicheck-0.1.0/tests/test_abicc_dump_import.py +153 -0
- abicheck-0.1.0/tests/test_abicc_dump_integration.py +77 -0
- abicheck-0.1.0/tests/test_abicc_full_parity.py +627 -0
- abicheck-0.1.0/tests/test_abicc_parity.py +658 -0
- abicheck-0.1.0/tests/test_abicc_parity_extended.py +1230 -0
- abicheck-0.1.0/tests/test_abidiff_parity.py +333 -0
- abicheck-0.1.0/tests/test_anon_union_fp.py +420 -0
- abicheck-0.1.0/tests/test_architecture_conformance.py +45 -0
- abicheck-0.1.0/tests/test_benchmark_smoke.py +147 -0
- abicheck-0.1.0/tests/test_builtins_filtered.py +316 -0
- abicheck-0.1.0/tests/test_changekind_completeness.py +484 -0
- abicheck-0.1.0/tests/test_changekind_coverage.py +481 -0
- abicheck-0.1.0/tests/test_checker.py +297 -0
- abicheck-0.1.0/tests/test_cli_coverage.py +307 -0
- abicheck-0.1.0/tests/test_cli_new_features.py +457 -0
- abicheck-0.1.0/tests/test_cli_phase1.py +193 -0
- abicheck-0.1.0/tests/test_cli_unit.py +374 -0
- abicheck-0.1.0/tests/test_compare_input_modes.py +466 -0
- abicheck-0.1.0/tests/test_compat.py +229 -0
- abicheck-0.1.0/tests/test_compat_extended.py +889 -0
- abicheck-0.1.0/tests/test_detector_contracts.py +27 -0
- abicheck-0.1.0/tests/test_dumper_coverage.py +431 -0
- abicheck-0.1.0/tests/test_dumper_members.py +139 -0
- abicheck-0.1.0/tests/test_dumper_phase1.py +86 -0
- abicheck-0.1.0/tests/test_dumper_unit.py +645 -0
- abicheck-0.1.0/tests/test_dumper_unit_phase0.py +154 -0
- abicheck-0.1.0/tests/test_duplicate_mangled.py +175 -0
- abicheck-0.1.0/tests/test_dwarf_metadata_coverage.py +663 -0
- abicheck-0.1.0/tests/test_dwarf_nontrivial.py +407 -0
- abicheck-0.1.0/tests/test_dwarf_unified.py +224 -0
- abicheck-0.1.0/tests/test_elf_metadata_unit.py +470 -0
- abicheck-0.1.0/tests/test_elf_parse_integration.py +135 -0
- abicheck-0.1.0/tests/test_elf_symbol_filters.py +170 -0
- abicheck-0.1.0/tests/test_error_handling.py +273 -0
- abicheck-0.1.0/tests/test_example_autodiscovery.py +236 -0
- abicheck-0.1.0/tests/test_exit_codes.py +238 -0
- abicheck-0.1.0/tests/test_followup_100_101.py +475 -0
- abicheck-0.1.0/tests/test_format_compliance.py +283 -0
- abicheck-0.1.0/tests/test_frame_register.py +109 -0
- abicheck-0.1.0/tests/test_func_deleted.py +180 -0
- abicheck-0.1.0/tests/test_golden_output.py +198 -0
- abicheck-0.1.0/tests/test_init_coverage.py +22 -0
- abicheck-0.1.0/tests/test_integration_phase2_negative.py +96 -0
- abicheck-0.1.0/tests/test_negative.py +201 -0
- abicheck-0.1.0/tests/test_nested_struct_tag.py +129 -0
- abicheck-0.1.0/tests/test_orphan_struct.py +175 -0
- abicheck-0.1.0/tests/test_phase0_golden_dumper.py +80 -0
- abicheck-0.1.0/tests/test_phase3_dwarf_helpers.py +126 -0
- abicheck-0.1.0/tests/test_policy_file.py +196 -0
- abicheck-0.1.0/tests/test_policy_registry_and_summary.py +101 -0
- abicheck-0.1.0/tests/test_pr89_hard_gaps_schema.py +633 -0
- abicheck-0.1.0/tests/test_report_metadata.py +509 -0
- abicheck-0.1.0/tests/test_reporter.py +90 -0
- abicheck-0.1.0/tests/test_sarif.py +273 -0
- abicheck-0.1.0/tests/test_serialization.py +246 -0
- abicheck-0.1.0/tests/test_serialization_roundtrip.py +106 -0
- abicheck-0.1.0/tests/test_snapshot_roundtrip.py +391 -0
- abicheck-0.1.0/tests/test_sprint1.py +209 -0
- abicheck-0.1.0/tests/test_sprint10_abicc_parity.py +274 -0
- abicheck-0.1.0/tests/test_sprint2_elf.py +587 -0
- abicheck-0.1.0/tests/test_sprint2_gap_detectors.py +295 -0
- abicheck-0.1.0/tests/test_sprint3_dwarf.py +372 -0
- abicheck-0.1.0/tests/test_sprint4_dwarf_advanced.py +357 -0
- abicheck-0.1.0/tests/test_sprint7_full_parity.py +1037 -0
- abicheck-0.1.0/tests/test_sprint9_html.py +373 -0
- abicheck-0.1.0/tests/test_suppression.py +242 -0
- abicheck-0.1.0/tests/test_suppression_matrix.py +456 -0
- abicheck-0.1.0/tests/test_symbol_origin.py +580 -0
- abicheck-0.1.0/tests/test_unknown_type_warning.py +102 -0
- abicheck-0.1.0/tests/test_validate_examples_unit.py +184 -0
- abicheck-0.1.0/tests/test_visibility.py +148 -0
- abicheck-0.1.0/tests/test_vtable_severity.py +88 -0
- abicheck-0.1.0/tests/test_xml_parity.py +287 -0
- abicheck-0.1.0/tests/test_xml_report.py +492 -0
abicheck-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owners or entities authorized by
|
|
13
|
+
the copyright owners granting this License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity.
|
|
18
|
+
|
|
19
|
+
"You" (or "Your") shall mean an individual or Legal Entity exercising
|
|
20
|
+
permissions granted by this License.
|
|
21
|
+
|
|
22
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
23
|
+
including but not limited to software source code, documentation
|
|
24
|
+
source, and configuration files.
|
|
25
|
+
|
|
26
|
+
"Object" form shall mean any form resulting from mechanical
|
|
27
|
+
transformation or translation of a Source form.
|
|
28
|
+
|
|
29
|
+
"Work" shall mean the work of authorship made available under the
|
|
30
|
+
License.
|
|
31
|
+
|
|
32
|
+
"Derivative Works" shall mean any work that is based on the Work.
|
|
33
|
+
|
|
34
|
+
"Contribution" shall mean any work submitted to the Licensor for
|
|
35
|
+
inclusion in the Work.
|
|
36
|
+
|
|
37
|
+
"Contributor" shall mean Licensor and any Legal Entity on behalf of
|
|
38
|
+
whom a Contribution has been received by the Licensor.
|
|
39
|
+
|
|
40
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
41
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
42
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
43
|
+
copyright license to reproduce, prepare Derivative Works of, publicly
|
|
44
|
+
display, publicly perform, sublicense, and distribute the Work and
|
|
45
|
+
such Derivative Works in Source or Object form.
|
|
46
|
+
|
|
47
|
+
3. Grant of Patent License. Subject to the terms and conditions of this
|
|
48
|
+
License, each Contributor hereby grants to You a perpetual, worldwide,
|
|
49
|
+
non-exclusive, no-charge, royalty-free, irrevocable patent license to
|
|
50
|
+
make, use, sell, offer for sale, import, and otherwise transfer the
|
|
51
|
+
Work.
|
|
52
|
+
|
|
53
|
+
4. Redistribution. You may reproduce and distribute copies of the Work
|
|
54
|
+
or Derivative Works thereof in any medium, with or without
|
|
55
|
+
modifications, provided that You meet the following conditions:
|
|
56
|
+
|
|
57
|
+
(a) You must give any other recipients a copy of this License; and
|
|
58
|
+
(b) You must cause any modified files to carry prominent notices
|
|
59
|
+
stating that You changed the files; and
|
|
60
|
+
(c) You must retain all copyright, patent, trademark, and attribution
|
|
61
|
+
notices from the Source form of the Work; and
|
|
62
|
+
(d) If the Work includes a "NOTICE" text file, you must include a
|
|
63
|
+
readable copy of the attribution notices contained within.
|
|
64
|
+
|
|
65
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
66
|
+
any Contribution submitted for inclusion in the Work shall be under
|
|
67
|
+
the terms of this License.
|
|
68
|
+
|
|
69
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
70
|
+
names, trademarks, service marks, or product names of the Licensor.
|
|
71
|
+
|
|
72
|
+
7. Disclaimer of Warranty. THE WORK IS PROVIDED "AS IS", WITHOUT
|
|
73
|
+
WARRANTY OF ANY KIND, EXPRESS OR IMPLIED.
|
|
74
|
+
|
|
75
|
+
8. Limitation of Liability. IN NO EVENT SHALL ANY CONTRIBUTOR BE LIABLE
|
|
76
|
+
FOR ANY DAMAGES ARISING FROM THE USE OF THIS WORK.
|
|
77
|
+
|
|
78
|
+
9. Accepting Warranty or Additional Liability. While redistributing the
|
|
79
|
+
Work, You may offer warranty or liability obligations, for a fee.
|
|
80
|
+
|
|
81
|
+
END OF TERMS AND CONDITIONS
|
|
82
|
+
|
|
83
|
+
Copyright 2026 Nikolay Petrov
|
|
84
|
+
|
|
85
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
86
|
+
you may not use this file except in compliance with the License.
|
|
87
|
+
You may obtain a copy of the License at
|
|
88
|
+
|
|
89
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
abicheck-0.1.0/NOTICE.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# NOTICE — Third-Party Software
|
|
2
|
+
|
|
3
|
+
This project (`abicheck`) is licensed under the **Apache License 2.0**.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## What this project is NOT derived from
|
|
8
|
+
|
|
9
|
+
| Tool | License | Status |
|
|
10
|
+
|------|---------|--------|
|
|
11
|
+
| `abi-compliance-checker` (lvc/abi-compliance-checker) | LGPL-2.1 | ❌ No code or tests copied |
|
|
12
|
+
| `libabigail` (abidiff/abidw) | LGPL-2.1+ | ❌ No code copied |
|
|
13
|
+
| `abi-dumper` (lvc/abi-dumper) | LGPL-2.1 | ❌ No code copied |
|
|
14
|
+
|
|
15
|
+
All code in this repository was written independently.
|
|
16
|
+
Test fixtures in `tests/fixtures/` are original C/C++ snippets authored for this project.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Runtime / tool dependencies (not linked, invoked as subprocesses)
|
|
21
|
+
|
|
22
|
+
| Tool | License | Usage |
|
|
23
|
+
|------|---------|-------|
|
|
24
|
+
| [castxml](https://github.com/CastXML/CastXML) | Apache-2.0 | C++ header → XML dump (subprocess) |
|
|
25
|
+
| GCC / Clang | GPL-3.0 / Apache-2.0 | C++ compiler backend for castxml (system tool) |
|
|
26
|
+
|
|
27
|
+
These tools are invoked as external processes and are **not** distributed with this project.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Python dependencies
|
|
32
|
+
|
|
33
|
+
| Package | License | Usage |
|
|
34
|
+
|---------|---------|-------|
|
|
35
|
+
| `click` | BSD-3-Clause | CLI framework |
|
|
36
|
+
| `pyyaml` | MIT | YAML parsing (policy files, suppressions) |
|
|
37
|
+
| `defusedxml` | PSF-2.0 | Safe XML parsing (ABICC descriptor mode) |
|
|
38
|
+
| `pyelftools` | Public Domain | ELF/DWARF binary metadata extraction |
|
|
39
|
+
| `google-re2` | BSD-3-Clause | RE2 suppression engine (O(N) guaranteed) |
|
|
40
|
+
| `packaging` | Apache-2.0 / BSD-2-Clause | Version comparison for suppressions |
|
|
41
|
+
|
|
42
|
+
See `pyproject.toml` for the full dependency list.
|
abicheck-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: abicheck
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: ABI compatibility checker for C/C++ shared libraries
|
|
5
|
+
Author-email: Nikolay Petrov <sfasp.post@gmail.com>
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Repository, https://github.com/napetrov/abicheck
|
|
8
|
+
Project-URL: Documentation, https://napetrov.github.io/abicheck/
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/napetrov/abicheck/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/napetrov/abicheck/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: abi,api,compatibility,checker,shared-library,elf,dwarf,castxml
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
16
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
24
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
License-File: NOTICE.md
|
|
29
|
+
Requires-Dist: click>=8.0
|
|
30
|
+
Requires-Dist: pyyaml>=6.0
|
|
31
|
+
Requires-Dist: defusedxml>=0.7.1
|
|
32
|
+
Requires-Dist: pyelftools>=0.29
|
|
33
|
+
Requires-Dist: packaging>=21.0
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
36
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
37
|
+
Requires-Dist: ruff>=0.3; extra == "dev"
|
|
38
|
+
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
39
|
+
Requires-Dist: types-PyYAML; extra == "dev"
|
|
40
|
+
|
|
41
|
+
# abicheck
|
|
42
|
+
|
|
43
|
+
[](https://github.com/napetrov/abicheck/actions/workflows/ci.yml)
|
|
44
|
+
[](https://codecov.io/gh/napetrov/abicheck)
|
|
45
|
+
|
|
46
|
+
**abicheck** is a command-line tool that detects breaking changes in C/C++ shared libraries before they reach production. It compares two versions of a `.so` library — along with their public headers — and reports whether existing binaries will continue to work or break at runtime.
|
|
47
|
+
|
|
48
|
+
Typical problems it catches: removed or renamed symbols, changed function signatures, struct layout drift, vtable reordering, enum value reassignment, and dozens of other ABI/API incompatibilities that cause crashes, silent data corruption, or linker failures after a library upgrade.
|
|
49
|
+
|
|
50
|
+
> **Platform:** Linux (ELF binaries + DWARF debug info + C/C++ headers). Windows PE and macOS Mach-O are not yet supported.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Installation
|
|
55
|
+
|
|
56
|
+
> **Note:** abicheck is not yet published to PyPI or conda-forge. Install from source for now.
|
|
57
|
+
|
|
58
|
+
### Prerequisites
|
|
59
|
+
|
|
60
|
+
| Requirement | Notes |
|
|
61
|
+
|-------------|-------|
|
|
62
|
+
| **Linux** | ELF/DWARF + header-based analysis |
|
|
63
|
+
| **Python >= 3.10** | |
|
|
64
|
+
| **`castxml`** | Clang-based C/C++ AST parser for header analysis |
|
|
65
|
+
| **`g++` or `clang++`** | Must be accessible to castxml |
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Ubuntu / Debian
|
|
69
|
+
sudo apt install castxml g++
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# conda
|
|
74
|
+
conda install -c conda-forge castxml
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Install from source
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
git clone https://github.com/napetrov/abicheck.git
|
|
81
|
+
cd abicheck
|
|
82
|
+
pip install -e .
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
For development (includes test & lint dependencies):
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
pip install -e ".[dev]"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Quick start
|
|
94
|
+
|
|
95
|
+
### Compare two library versions
|
|
96
|
+
|
|
97
|
+
The simplest way to check ABI compatibility — pass two `.so` files and their public headers:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
abicheck compare libfoo.so.1 libfoo.so.2 \
|
|
101
|
+
--old-header include/v1/foo.h --new-header include/v2/foo.h
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
If the header file is the same for both versions, use the shorthand:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
abicheck compare libfoo.so.1 libfoo.so.2 -H include/foo.h
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Use saved snapshots (for CI baselines)
|
|
111
|
+
|
|
112
|
+
Save an ABI snapshot once per release, then compare against new builds:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# Save baseline
|
|
116
|
+
abicheck dump libfoo.so -H include/foo.h --version 1.0 -o baseline.json
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Compare new build against saved baseline
|
|
121
|
+
abicheck compare baseline.json ./build/libfoo.so --new-header include/foo.h
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Key flags
|
|
125
|
+
|
|
126
|
+
| Flag | Description |
|
|
127
|
+
|------|-------------|
|
|
128
|
+
| `--old-header` / `--new-header` | Public headers for each version |
|
|
129
|
+
| `-H` | Same header for both versions (shorthand) |
|
|
130
|
+
| `--format` | Output format: `markdown` (default), `json`, `sarif`, `html` |
|
|
131
|
+
| `-o` | Write report to file |
|
|
132
|
+
| `--policy` | Verdict policy: `strict_abi` (default), `sdk_vendor`, `plugin_abi` |
|
|
133
|
+
| `--policy-file` | Custom YAML policy overrides |
|
|
134
|
+
| `--lang` | Language mode: `c++` (default) or `c` |
|
|
135
|
+
| `-v` / `--verbose` | Debug output |
|
|
136
|
+
|
|
137
|
+
For full CLI reference and advanced options (cross-compilation, suppression files, symbol filtering), see the [documentation](https://napetrov.github.io/abicheck/getting_started/).
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Output formats and reports
|
|
142
|
+
|
|
143
|
+
abicheck supports four output formats:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# Markdown (default) — human-readable, printed to stdout
|
|
147
|
+
abicheck compare old.so new.so -H foo.h
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# JSON — machine-readable, includes precise verdict field for CI parsing
|
|
152
|
+
abicheck compare old.so new.so -H foo.h --format json -o result.json
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# SARIF — for GitHub Code Scanning integration
|
|
157
|
+
abicheck compare old.so new.so -H foo.h --format sarif -o abi.sarif
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
# HTML — standalone report for review
|
|
162
|
+
abicheck compare old.so new.so -H foo.h --format html -o report.html
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Example report (markdown output)
|
|
166
|
+
|
|
167
|
+
```text
|
|
168
|
+
# ABI Report: libfoo.so
|
|
169
|
+
|
|
170
|
+
| | |
|
|
171
|
+
|---|---|
|
|
172
|
+
| **Old version** | `1.0` |
|
|
173
|
+
| **New version** | `2.0` |
|
|
174
|
+
| **Verdict** | ❌ `BREAKING` |
|
|
175
|
+
| Breaking changes | 2 |
|
|
176
|
+
| Source-level breaks | 0 |
|
|
177
|
+
| Deployment risk changes | 0 |
|
|
178
|
+
| Compatible additions | 1 |
|
|
179
|
+
|
|
180
|
+
## ❌ Breaking Changes
|
|
181
|
+
|
|
182
|
+
- **func_removed**: Public function removed: helper (`helper`)
|
|
183
|
+
> Old binaries call a symbol that no longer exists; dynamic linker will refuse to load or crash at call site.
|
|
184
|
+
|
|
185
|
+
- **type_size_changed**: Size changed: Point (64 → 96 bits) (`64` → `96`)
|
|
186
|
+
> Old code allocates or copies the type with the old size; heap/stack corruption, out-of-bounds access.
|
|
187
|
+
|
|
188
|
+
## ✅ Compatible Additions
|
|
189
|
+
|
|
190
|
+
- Field added: Point::z
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
## Legend
|
|
194
|
+
|
|
195
|
+
| Verdict | Meaning |
|
|
196
|
+
|---------|---------|
|
|
197
|
+
| ✅ NO_CHANGE | Identical ABI |
|
|
198
|
+
| ✅ COMPATIBLE | Only additions (backward compatible) |
|
|
199
|
+
| ⚠️ COMPATIBLE_WITH_RISK | Binary-compatible; verify target environment |
|
|
200
|
+
| ⚠️ API_BREAK | Source-level API change — recompilation required |
|
|
201
|
+
| ❌ BREAKING | Binary ABI break — recompilation required |
|
|
202
|
+
|
|
203
|
+
_Generated by [abicheck](https://github.com/napetrov/abicheck)_
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Policy profiles
|
|
209
|
+
|
|
210
|
+
Policies control how detected changes are classified. A change that is `BREAKING` under `strict_abi` might be downgraded to `COMPATIBLE` under `sdk_vendor`.
|
|
211
|
+
|
|
212
|
+
**Built-in profiles:**
|
|
213
|
+
|
|
214
|
+
| Profile | Use case | Behavior |
|
|
215
|
+
|---------|----------|----------|
|
|
216
|
+
| `strict_abi` (default) | System libraries, public SDKs | Every ABI change at maximum severity |
|
|
217
|
+
| `sdk_vendor` | Vendor SDKs, optional extensions | Source-only changes (renames, access) downgraded to COMPATIBLE |
|
|
218
|
+
| `plugin_abi` | Plugins rebuilt with host | Calling-convention changes downgraded to COMPATIBLE |
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
abicheck compare old.so new.so -H foo.h --policy sdk_vendor
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Custom policy file
|
|
225
|
+
|
|
226
|
+
Create a YAML file to override classification of specific change kinds:
|
|
227
|
+
|
|
228
|
+
```yaml
|
|
229
|
+
base_policy: strict_abi
|
|
230
|
+
overrides:
|
|
231
|
+
enum_member_renamed: ignore # break | warn | ignore
|
|
232
|
+
field_renamed: ignore
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
abicheck compare old.so new.so -H foo.h --policy-file project_policy.yaml
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Semantics: `break` = BREAKING (exit 4), `warn` = API_BREAK (exit 2), `ignore` = COMPATIBLE (exit 0). Kinds not listed in `overrides` use the `base_policy`.
|
|
240
|
+
|
|
241
|
+
See [Policy Profiles](https://napetrov.github.io/abicheck/policies/) for full details.
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Exit codes
|
|
246
|
+
|
|
247
|
+
| Exit code | Verdict | Meaning |
|
|
248
|
+
|-----------|---------|---------|
|
|
249
|
+
| `0` | `NO_CHANGE`, `COMPATIBLE`, `COMPATIBLE_WITH_RISK` | Safe — no binary ABI break (risk report may have warnings) |
|
|
250
|
+
| `1` | — | Tool/runtime error |
|
|
251
|
+
| `2` | `API_BREAK` | Source-level break (recompile needed, binary may work) |
|
|
252
|
+
| `4` | `BREAKING` | Binary ABI break (old binaries will crash or misbehave) |
|
|
253
|
+
|
|
254
|
+
Use exit codes directly in CI gates. For precise verdicts, parse `--format json` output.
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## GitHub Actions integration
|
|
259
|
+
|
|
260
|
+
A typical CI flow: dump the ABI snapshot once at release time, then compare every new build against that saved baseline.
|
|
261
|
+
|
|
262
|
+
```yaml
|
|
263
|
+
name: ABI check
|
|
264
|
+
on: [push, pull_request]
|
|
265
|
+
|
|
266
|
+
jobs:
|
|
267
|
+
abi-check:
|
|
268
|
+
runs-on: ubuntu-latest
|
|
269
|
+
steps:
|
|
270
|
+
- uses: actions/checkout@v4
|
|
271
|
+
|
|
272
|
+
- name: Install abicheck
|
|
273
|
+
run: pip install git+https://github.com/napetrov/abicheck.git
|
|
274
|
+
|
|
275
|
+
# ── Release step (run once when cutting a release) ─────────────
|
|
276
|
+
# Dump the ABI baseline and upload it as a release artifact:
|
|
277
|
+
#
|
|
278
|
+
# abicheck dump ./build/libfoo.so -H include/foo.h \
|
|
279
|
+
# --version ${{ github.ref_name }} -o abi-baseline.json
|
|
280
|
+
#
|
|
281
|
+
# Then download it in CI (e.g. from a release asset or artifact).
|
|
282
|
+
|
|
283
|
+
- name: Download ABI baseline
|
|
284
|
+
uses: actions/download-artifact@v4
|
|
285
|
+
with:
|
|
286
|
+
name: abi-baseline
|
|
287
|
+
# abi-baseline.json saved from the last release
|
|
288
|
+
|
|
289
|
+
- name: Build current library
|
|
290
|
+
run: make -C src/ # produces ./build/libfoo.so
|
|
291
|
+
|
|
292
|
+
# ── CI step: compare new build against saved baseline ──────────
|
|
293
|
+
- name: Compare ABI
|
|
294
|
+
run: |
|
|
295
|
+
abicheck compare abi-baseline.json ./build/libfoo.so \
|
|
296
|
+
--new-header include/foo.h \
|
|
297
|
+
--format sarif -o abi.sarif
|
|
298
|
+
|
|
299
|
+
- uses: github/codeql-action/upload-sarif@v3
|
|
300
|
+
if: always()
|
|
301
|
+
with:
|
|
302
|
+
sarif_file: abi.sarif
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Exit codes for CI gates: `0` = compatible, `1` = tool error, `2` = API break, `4` = breaking ABI change.
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## ABICC drop-in replacement
|
|
310
|
+
|
|
311
|
+
For teams migrating from [ABI Compliance Checker (ABICC)](https://lvc.github.io/abi-compliance-checker/) — swap one command, keep your existing XML descriptors:
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
# Before (ABICC):
|
|
315
|
+
abi-compliance-checker -lib libfoo -old old.xml -new new.xml -report-path r.html
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
# After (abicheck — same flags):
|
|
320
|
+
abicheck compat check -lib libfoo -old old.xml -new new.xml -report-path r.html
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
When ready, migrate to the simpler native workflow:
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
abicheck compare libfoo.so.1 libfoo.so.2 -H include/foo.h
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
See [ABICC Migration Guide](https://napetrov.github.io/abicheck/migration/from_abicc/) for full flag reference, exit code differences, and migration checklist.
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## Examples and ABI breakage catalog
|
|
334
|
+
|
|
335
|
+
The `examples/` directory contains **48 real-world ABI break scenarios** — each with paired `v1`/`v2` source code, a consumer app that demonstrates the actual failure, and a Makefile to reproduce it.
|
|
336
|
+
|
|
337
|
+
### Try an example
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
cd examples/case01_symbol_removal
|
|
341
|
+
make
|
|
342
|
+
abicheck compare libv1.so libv2.so --old-header v1.h --new-header v2.h
|
|
343
|
+
# Verdict: BREAKING — symbol 'helper' was removed
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### What the examples cover
|
|
347
|
+
|
|
348
|
+
**Breaking changes** — changes that crash or corrupt existing binaries:
|
|
349
|
+
|
|
350
|
+
| Category | Cases | Examples |
|
|
351
|
+
|----------|-------|---------|
|
|
352
|
+
| Symbol removal / rename | 01, 12 | Function removed from export table |
|
|
353
|
+
| Type/signature changes | 02, 10, 33 | Parameter type, return type, pointer level changed |
|
|
354
|
+
| Struct/class layout | 07, 14, 40, 43, 44 | Field added/reordered, class size changed |
|
|
355
|
+
| Enum changes | 08, 19, 20 | Value reassigned, member removed |
|
|
356
|
+
| C++ vtable / virtual | 09, 23, 38 | Vtable reorder, pure virtual added |
|
|
357
|
+
| Qualifiers / binding | 21, 22, 30, 39 | Method became static, const changed |
|
|
358
|
+
| Templates / typedefs | 17, 28, 45, 46, 48 | Template layout, typedef opaque |
|
|
359
|
+
| Complex types | 24, 26, 35, 36, 37 | Union field removed, field renamed, base class changed |
|
|
360
|
+
|
|
361
|
+
**Compatible changes** — safe, no binary break:
|
|
362
|
+
|
|
363
|
+
| Cases | Examples |
|
|
364
|
+
|-------|---------|
|
|
365
|
+
| 03, 25, 26b | New symbol added, enum member appended, union in reserved space |
|
|
366
|
+
| 04, 32 | No change, parameter defaults changed |
|
|
367
|
+
| 05, 06 | SONAME policy, visibility leak (bad practice but binary-safe) |
|
|
368
|
+
| 13, 27, 29, 47 | Symbol versioning, weak binding, IFUNC, inline-to-outlined |
|
|
369
|
+
| 16 | Inline to non-inline (ODR concern, not binary break) |
|
|
370
|
+
|
|
371
|
+
**API-only breaks** — source-level break, binary still works:
|
|
372
|
+
|
|
373
|
+
| Cases | Examples |
|
|
374
|
+
|-------|---------|
|
|
375
|
+
| 31, 34 | Enum renamed, access level changed |
|
|
376
|
+
|
|
377
|
+
### Benchmarks
|
|
378
|
+
|
|
379
|
+
abicheck detects 100+ change types across ELF, AST, and DWARF layers. The `examples/` directory contains 48 representative test cases with expected verdicts in `examples/ground_truth.json`. Cross-tool comparison on 42 of these cases:
|
|
380
|
+
|
|
381
|
+
| Tool | Correct / Scored | Accuracy |
|
|
382
|
+
|------|-----------------|----------|
|
|
383
|
+
| **abicheck (compare)** | **42/42** | **100%** |
|
|
384
|
+
| abicheck (compat) | 40/42 | 95% |
|
|
385
|
+
| ABICC (xml) | 25/41 | 61% |
|
|
386
|
+
| ABICC (abi-dumper) | 20/30 | 66% |
|
|
387
|
+
| abidiff | 11/42 | 26% |
|
|
388
|
+
|
|
389
|
+
abicheck passes all 48 cases. Run `python3 scripts/benchmark_comparison.py` to reproduce.
|
|
390
|
+
|
|
391
|
+
See [Benchmark & Tool Comparison](https://napetrov.github.io/abicheck/tool_comparison/) for per-case results, methodology, and timing data.
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
## ABI compatibility guide
|
|
396
|
+
|
|
397
|
+
Understanding what breaks ABI and what doesn't is essential for library maintainers. Here is a quick reference:
|
|
398
|
+
|
|
399
|
+
### Changes that break binary compatibility
|
|
400
|
+
|
|
401
|
+
- **Removing or renaming** an exported function or variable
|
|
402
|
+
- **Changing function signature** — parameter types, return type, calling convention
|
|
403
|
+
- **Modifying struct/class layout** — adding/removing/reordering fields, changing field types
|
|
404
|
+
- **Changing enum values** — reassigning numeric values, removing members
|
|
405
|
+
- **C++ vtable changes** — reordering virtual methods, adding pure virtuals
|
|
406
|
+
- **Changing method qualifiers** — `const`, `static`, `noexcept` (when it affects mangling)
|
|
407
|
+
- **Changing global variable type** — size/alignment mismatch
|
|
408
|
+
|
|
409
|
+
### Changes that are safe (binary compatible)
|
|
410
|
+
|
|
411
|
+
- **Adding** new exported functions or variables
|
|
412
|
+
- **Adding** new enum members at the end (without shifting existing values)
|
|
413
|
+
- **Weakening** symbol binding (GLOBAL to WEAK)
|
|
414
|
+
- **Adding** IFUNC resolvers
|
|
415
|
+
- **Adding** symbol version tags
|
|
416
|
+
|
|
417
|
+
### Best practices for library maintainers
|
|
418
|
+
|
|
419
|
+
1. **Treat public headers as ABI contracts** — any change is potentially breaking
|
|
420
|
+
2. **Use SONAME versioning** — bump major version on incompatible changes
|
|
421
|
+
3. **Hide implementation details** — use Pimpl pattern, opaque handles, `-fvisibility=hidden`
|
|
422
|
+
4. **Add, don't modify** — introduce `foo_v2()` instead of changing `foo()`
|
|
423
|
+
5. **Freeze enum values** — never renumber released constants
|
|
424
|
+
6. **Don't expose third-party types** in public API — wrap them behind stable project-owned types
|
|
425
|
+
|
|
426
|
+
See [Examples Breakage Guide](https://napetrov.github.io/abicheck/examples_breakage_guide/) for detailed code examples and failure demonstrations for each case.
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
## Architecture
|
|
431
|
+
|
|
432
|
+
abicheck uses a 3-layer comparison pipeline:
|
|
433
|
+
|
|
434
|
+
1. **ELF metadata** (via pyelftools) — exported symbols, SONAME, visibility, binding, symbol versions
|
|
435
|
+
2. **Header AST** (via castxml/Clang) — function signatures, classes, fields, typedefs, enums, vtable layout
|
|
436
|
+
3. **DWARF cross-check** (optional) — validates actual compiled struct sizes, member offsets, vtable slots
|
|
437
|
+
|
|
438
|
+
Each layer provides independent signals. Combining all three gives abicheck higher accuracy than tools that rely on only one or two sources (e.g., abidiff uses only DWARF; ABICC uses only GCC AST).
|
|
439
|
+
|
|
440
|
+
### Key modules
|
|
441
|
+
|
|
442
|
+
| Module | Responsibility |
|
|
443
|
+
|--------|---------------|
|
|
444
|
+
| `cli.py` | CLI entrypoint (`dump`, `compare`, `compat check/dump`) |
|
|
445
|
+
| `dumper.py` | Snapshot generation from `.so` + headers |
|
|
446
|
+
| `checker.py` | Diff orchestration and change collection |
|
|
447
|
+
| `checker_policy.py` | Change classification, built-in policies, verdict logic |
|
|
448
|
+
| `detectors.py` | ABI change detection rules |
|
|
449
|
+
| `reporter.py` | Output formatting (markdown, JSON, SARIF, HTML) |
|
|
450
|
+
| `suppression.py` | Suppression rules and symbol filtering |
|
|
451
|
+
| `policy_file.py` | Custom YAML policy file parsing |
|
|
452
|
+
|
|
453
|
+
See [Architecture reference](https://napetrov.github.io/abicheck/reference/architecture/) for the full design documentation.
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
## Documentation
|
|
458
|
+
|
|
459
|
+
Full documentation is available at **[napetrov.github.io/abicheck](https://napetrov.github.io/abicheck/)**.
|
|
460
|
+
|
|
461
|
+
**Getting started:**
|
|
462
|
+
- [Installation & first check](https://napetrov.github.io/abicheck/getting_started/)
|
|
463
|
+
- [Exit codes reference](https://napetrov.github.io/abicheck/exit_codes/)
|
|
464
|
+
|
|
465
|
+
**Concepts:**
|
|
466
|
+
- [Verdicts explained](https://napetrov.github.io/abicheck/concepts/verdicts/) — NO_CHANGE / COMPATIBLE / COMPATIBLE_WITH_RISK / API_BREAK / BREAKING
|
|
467
|
+
- [Limitations](https://napetrov.github.io/abicheck/concepts/limitations/)
|
|
468
|
+
- [Troubleshooting](https://napetrov.github.io/abicheck/concepts/troubleshooting/)
|
|
469
|
+
|
|
470
|
+
**User guide:**
|
|
471
|
+
- [Policy profiles](https://napetrov.github.io/abicheck/policies/)
|
|
472
|
+
- [SARIF output](https://napetrov.github.io/abicheck/sarif_output/)
|
|
473
|
+
- [Examples & breakage guide](https://napetrov.github.io/abicheck/examples_breakage_guide/)
|
|
474
|
+
- [ABICC migration](https://napetrov.github.io/abicheck/migration/from_abicc/)
|
|
475
|
+
|
|
476
|
+
**Reference:**
|
|
477
|
+
- [Architecture](https://napetrov.github.io/abicheck/reference/architecture/)
|
|
478
|
+
- [Change kind reference](https://napetrov.github.io/abicheck/reference/change_kinds/)
|
|
479
|
+
- [Benchmark & tool comparison](https://napetrov.github.io/abicheck/tool_comparison/)
|
|
480
|
+
- [ABICC compatibility reference](https://napetrov.github.io/abicheck/abicc_compat/)
|
|
481
|
+
|
|
482
|
+
---
|
|
483
|
+
|
|
484
|
+
## Contributing
|
|
485
|
+
|
|
486
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for setup instructions, testing, code style, and PR workflow.
|
|
487
|
+
|
|
488
|
+
## License
|
|
489
|
+
|
|
490
|
+
Apache-2.0. See [LICENSE](LICENSE) and [NOTICE.md](NOTICE.md).
|