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.
Files changed (115) hide show
  1. abicheck-0.1.0/LICENSE +89 -0
  2. abicheck-0.1.0/NOTICE.md +42 -0
  3. abicheck-0.1.0/PKG-INFO +490 -0
  4. abicheck-0.1.0/README.md +450 -0
  5. abicheck-0.1.0/abicheck/__init__.py +9 -0
  6. abicheck-0.1.0/abicheck/abicc_dump_import.py +20 -0
  7. abicheck-0.1.0/abicheck/checker.py +2634 -0
  8. abicheck-0.1.0/abicheck/checker_policy.py +744 -0
  9. abicheck-0.1.0/abicheck/cli.py +508 -0
  10. abicheck-0.1.0/abicheck/compat/__init__.py +11 -0
  11. abicheck-0.1.0/abicheck/compat/abicc_dump_import.py +256 -0
  12. abicheck-0.1.0/abicheck/compat/cli.py +1293 -0
  13. abicheck-0.1.0/abicheck/compat/descriptor.py +121 -0
  14. abicheck-0.1.0/abicheck/compat/xml_report.py +384 -0
  15. abicheck-0.1.0/abicheck/detectors.py +32 -0
  16. abicheck-0.1.0/abicheck/dumper.py +897 -0
  17. abicheck-0.1.0/abicheck/dwarf_advanced.py +911 -0
  18. abicheck-0.1.0/abicheck/dwarf_metadata.py +658 -0
  19. abicheck-0.1.0/abicheck/dwarf_unified.py +118 -0
  20. abicheck-0.1.0/abicheck/dwarf_utils.py +71 -0
  21. abicheck-0.1.0/abicheck/elf_metadata.py +342 -0
  22. abicheck-0.1.0/abicheck/errors.py +29 -0
  23. abicheck-0.1.0/abicheck/html_report.py +951 -0
  24. abicheck-0.1.0/abicheck/model.py +213 -0
  25. abicheck-0.1.0/abicheck/policy_file.py +194 -0
  26. abicheck-0.1.0/abicheck/report_classifications.py +163 -0
  27. abicheck-0.1.0/abicheck/report_summary.py +66 -0
  28. abicheck-0.1.0/abicheck/reporter.py +263 -0
  29. abicheck-0.1.0/abicheck/sarif.py +204 -0
  30. abicheck-0.1.0/abicheck/serialization.py +287 -0
  31. abicheck-0.1.0/abicheck/suppression.py +195 -0
  32. abicheck-0.1.0/abicheck.egg-info/PKG-INFO +490 -0
  33. abicheck-0.1.0/abicheck.egg-info/SOURCES.txt +113 -0
  34. abicheck-0.1.0/abicheck.egg-info/dependency_links.txt +1 -0
  35. abicheck-0.1.0/abicheck.egg-info/entry_points.txt +2 -0
  36. abicheck-0.1.0/abicheck.egg-info/requires.txt +12 -0
  37. abicheck-0.1.0/abicheck.egg-info/top_level.txt +1 -0
  38. abicheck-0.1.0/pyproject.toml +101 -0
  39. abicheck-0.1.0/setup.cfg +4 -0
  40. abicheck-0.1.0/tests/test_abi_examples.py +146 -0
  41. abicheck-0.1.0/tests/test_abicc_compat_flags.py +233 -0
  42. abicheck-0.1.0/tests/test_abicc_dump_import.py +153 -0
  43. abicheck-0.1.0/tests/test_abicc_dump_integration.py +77 -0
  44. abicheck-0.1.0/tests/test_abicc_full_parity.py +627 -0
  45. abicheck-0.1.0/tests/test_abicc_parity.py +658 -0
  46. abicheck-0.1.0/tests/test_abicc_parity_extended.py +1230 -0
  47. abicheck-0.1.0/tests/test_abidiff_parity.py +333 -0
  48. abicheck-0.1.0/tests/test_anon_union_fp.py +420 -0
  49. abicheck-0.1.0/tests/test_architecture_conformance.py +45 -0
  50. abicheck-0.1.0/tests/test_benchmark_smoke.py +147 -0
  51. abicheck-0.1.0/tests/test_builtins_filtered.py +316 -0
  52. abicheck-0.1.0/tests/test_changekind_completeness.py +484 -0
  53. abicheck-0.1.0/tests/test_changekind_coverage.py +481 -0
  54. abicheck-0.1.0/tests/test_checker.py +297 -0
  55. abicheck-0.1.0/tests/test_cli_coverage.py +307 -0
  56. abicheck-0.1.0/tests/test_cli_new_features.py +457 -0
  57. abicheck-0.1.0/tests/test_cli_phase1.py +193 -0
  58. abicheck-0.1.0/tests/test_cli_unit.py +374 -0
  59. abicheck-0.1.0/tests/test_compare_input_modes.py +466 -0
  60. abicheck-0.1.0/tests/test_compat.py +229 -0
  61. abicheck-0.1.0/tests/test_compat_extended.py +889 -0
  62. abicheck-0.1.0/tests/test_detector_contracts.py +27 -0
  63. abicheck-0.1.0/tests/test_dumper_coverage.py +431 -0
  64. abicheck-0.1.0/tests/test_dumper_members.py +139 -0
  65. abicheck-0.1.0/tests/test_dumper_phase1.py +86 -0
  66. abicheck-0.1.0/tests/test_dumper_unit.py +645 -0
  67. abicheck-0.1.0/tests/test_dumper_unit_phase0.py +154 -0
  68. abicheck-0.1.0/tests/test_duplicate_mangled.py +175 -0
  69. abicheck-0.1.0/tests/test_dwarf_metadata_coverage.py +663 -0
  70. abicheck-0.1.0/tests/test_dwarf_nontrivial.py +407 -0
  71. abicheck-0.1.0/tests/test_dwarf_unified.py +224 -0
  72. abicheck-0.1.0/tests/test_elf_metadata_unit.py +470 -0
  73. abicheck-0.1.0/tests/test_elf_parse_integration.py +135 -0
  74. abicheck-0.1.0/tests/test_elf_symbol_filters.py +170 -0
  75. abicheck-0.1.0/tests/test_error_handling.py +273 -0
  76. abicheck-0.1.0/tests/test_example_autodiscovery.py +236 -0
  77. abicheck-0.1.0/tests/test_exit_codes.py +238 -0
  78. abicheck-0.1.0/tests/test_followup_100_101.py +475 -0
  79. abicheck-0.1.0/tests/test_format_compliance.py +283 -0
  80. abicheck-0.1.0/tests/test_frame_register.py +109 -0
  81. abicheck-0.1.0/tests/test_func_deleted.py +180 -0
  82. abicheck-0.1.0/tests/test_golden_output.py +198 -0
  83. abicheck-0.1.0/tests/test_init_coverage.py +22 -0
  84. abicheck-0.1.0/tests/test_integration_phase2_negative.py +96 -0
  85. abicheck-0.1.0/tests/test_negative.py +201 -0
  86. abicheck-0.1.0/tests/test_nested_struct_tag.py +129 -0
  87. abicheck-0.1.0/tests/test_orphan_struct.py +175 -0
  88. abicheck-0.1.0/tests/test_phase0_golden_dumper.py +80 -0
  89. abicheck-0.1.0/tests/test_phase3_dwarf_helpers.py +126 -0
  90. abicheck-0.1.0/tests/test_policy_file.py +196 -0
  91. abicheck-0.1.0/tests/test_policy_registry_and_summary.py +101 -0
  92. abicheck-0.1.0/tests/test_pr89_hard_gaps_schema.py +633 -0
  93. abicheck-0.1.0/tests/test_report_metadata.py +509 -0
  94. abicheck-0.1.0/tests/test_reporter.py +90 -0
  95. abicheck-0.1.0/tests/test_sarif.py +273 -0
  96. abicheck-0.1.0/tests/test_serialization.py +246 -0
  97. abicheck-0.1.0/tests/test_serialization_roundtrip.py +106 -0
  98. abicheck-0.1.0/tests/test_snapshot_roundtrip.py +391 -0
  99. abicheck-0.1.0/tests/test_sprint1.py +209 -0
  100. abicheck-0.1.0/tests/test_sprint10_abicc_parity.py +274 -0
  101. abicheck-0.1.0/tests/test_sprint2_elf.py +587 -0
  102. abicheck-0.1.0/tests/test_sprint2_gap_detectors.py +295 -0
  103. abicheck-0.1.0/tests/test_sprint3_dwarf.py +372 -0
  104. abicheck-0.1.0/tests/test_sprint4_dwarf_advanced.py +357 -0
  105. abicheck-0.1.0/tests/test_sprint7_full_parity.py +1037 -0
  106. abicheck-0.1.0/tests/test_sprint9_html.py +373 -0
  107. abicheck-0.1.0/tests/test_suppression.py +242 -0
  108. abicheck-0.1.0/tests/test_suppression_matrix.py +456 -0
  109. abicheck-0.1.0/tests/test_symbol_origin.py +580 -0
  110. abicheck-0.1.0/tests/test_unknown_type_warning.py +102 -0
  111. abicheck-0.1.0/tests/test_validate_examples_unit.py +184 -0
  112. abicheck-0.1.0/tests/test_visibility.py +148 -0
  113. abicheck-0.1.0/tests/test_vtable_severity.py +88 -0
  114. abicheck-0.1.0/tests/test_xml_parity.py +287 -0
  115. 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
@@ -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.
@@ -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
+ [![CI](https://github.com/napetrov/abicheck/actions/workflows/ci.yml/badge.svg)](https://github.com/napetrov/abicheck/actions/workflows/ci.yml)
44
+ [![codecov](https://codecov.io/gh/napetrov/abicheck/branch/main/graph/badge.svg)](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).