README.md
1Header ABI Checker
2===================
3
4The header ABI checker consists of 3 tools:
5[header-abi-dumper](#Header-ABI-Dumper),
6[header-abi-linker](#Header-ABI-Linker), and
7[header-abi-diff](#Header-ABI-Diff). The first two commands generate ABI dumps
8for shared libraries. The third command compares the ABI dumps with the
9prebuilt reference ABI dumps.
10
11## Header ABI Dumper
12
13`header-abi-dumper` dumps the ABIs (including classes, functions, variables,
14etc) defined in a C/C++ source file.
15
16The `-I` command line option controls the scope of ABIs that must be dumped.
17If `-I <path-to-export-include-dir>` is specified, the generated ABI dump will
18only include the classes, the functions, and the variables that are defined in
19the header files under the exported include directories.
20
21### Usage
22
23```
24header-abi-dumper -o <dump-file> <source_file> \
25 -I <export-include-dir-1> \
26 -I <export-include-dir-2> \
27 ... \
28 -- \
29 <cflags>
30```
31
32For more command line options, run `header-abi-dumper --help`.
33
34
35## Header ABI Linker
36
37`header-abi-linker` links several ABI dumps produced by `header-abi-dumper`.
38This tool combines all the ABI information present in the input ABI dump files
39and prunes the irrelevant ABI dumps.
40
41### Usage
42
43```
44header-abi-linker -o <linked-abi-dump> \
45 <abi-dump1> <abi-dump2> <abi-dump3> ... \
46 -so <path to so file> \
47 -v <path to version script>
48```
49
50For more command line options, run `header-abi-linker --help`.
51
52
53## Header ABI Diff
54
55`header-abi-diff` compares two header ABI dumps produced by
56`header-abi-dumper`. It produces a report outlining all the differences
57between the ABIs exposed by the two dumps.
58
59### Usage
60
61```
62header-abi-diff -old <old-abi-dump> -new <new-abi-dump> -o <report>
63```
64
65For more command line options, run `header-abi-diff --help`.
66
67### Return Value
68
69* `0`: Compatible
70* `1`: Changes to APIs unreferenced by symbols in the `.dynsym` table
71* `4`: Compatible extension
72* `8`: Incompatible
73* `16`: ELF incompatible (Some symbols in the `.dynsym` table, not exported by
74 public headers, were removed.)
75
76### Configuration
77header-abi-diff reads a config file named `config.json`. The config file must
78be placed in the dump directory, such as
79`prebuilts/abi-dumps/platform/33/64/x86_64/source-based/config.json`.
80The file consists of multiple sections. There are two types of sections: global
81config section and library config section. Each library config section contains
82flags for a specific version and a library. header-abi-diff chooses the library
83config section by command line options `-target-version` and `-lib`.
84
85#### Format
86Here is an example of a config.json.
87```json
88{
89 "global": {
90 "flags": {
91 "allow_adding_removing_weak_symbols": true,
92 },
93 },
94 "libfoo": [
95 {
96 "target_version": "current",
97 "flags": {
98 "check_all_apis": true,
99 },
100 },
101 {
102 "target_version": "34",
103 "ignore_linker_set_keys": [
104 "_ZTI14internal_state",
105 ],
106 "flags": {
107 "allow_extensions": true,
108 }
109 }
110 ]
111}
112```
113
114#### Library Config Section
115A library config section includes members: "target_version",
116"ignore_linker_set_keys" and "flags". header-abi-diff selects the config
117section that matches the target version given by CLI.
118Take above config as an example, if `-target-version 34` and `-lib libfoo` are
119specified, the selected config section is:
120```json
121{
122 "target_version": "34",
123 "ignore_linker_set_keys": [
124 "_ZTI14internal_state",
125 ],
126 "flags": {
127 "allow_extensions": true,
128 }
129}
130```
131
132#### Flags
133
134The config file and the header-abi-diff CLI support the same set of `flags`. If
135a flag is present in both CLI and config sections, the library config section
136takes priority, then the global config section and the CLI.
137
138## Opt-in ABI check
139
140Android build system runs the ABI checker automatically when it builds
141particular libraries, such as NDK and VNDK. Developers can enable the ABI
142check for common libraries by the following steps:
143
1441. Set the ABI checker properties in Android.bp. For example,
145
146 ```
147 cc_library {
148 name: "libfoo",
149 ...
150 target: {
151 vendor: {
152 header_abi_checker: {
153 enabled: true,
154 symbol_file: "map.txt",
155 ref_dump_dirs: ["abi-dumps"],
156 },
157 },
158 },
159 }
160 ```
161
162 `cc_library` modules and their `platform`, `product`, and `vendor` variants
163 support `header_abi_checker`. The following are the commonly used
164 properties of `header_abi_checker`:
165
166 - `enabled` explicitly enables or disables the check.
167 - `symbol_file` is the file containing the exported symbols.
168 - `diff_flags` are the command line options for header-abi-diff.
169 - `ref_dump_dirs` are the directories containing the dumps and
170 [config files](#Configuration).
171
1722. Follow the instructions in
173 [Update Opt-in Reference ABI Dumps](#Update-Opt_in-Reference-ABI-Dumps)
174 to generate ABI dumps in the `ref_dump_dirs`.
175
1763. Verify that the ABI check is working.
177
178 ```
179 $ make libfoo.vendor
180 $ find $ANDROID_BUILD_TOP/out/soong/.intermediates \
181 -name libfoo.so.opt0.abidiff
182 ```
183
184## FAQ
185
186### How to Resolve ABI Difference
187
188The build system compares the source code with three sets of reference dumps:
189**current version**, **opt-in**, and **previous version**. The ABI difference
190is propagated as build errors. This section describes the common methods to
191resolve them.
192
193#### Update Reference ABI Dumps for Current Version
194
195When the build system finds difference between the source code and the ABI
196reference dumps for the **current version**, it instructs you to run
197`create_reference_dumps.py` to update the dumps.
198
199The command below updates the reference ABI dumps for all monitored libraries
200on arm, arm64, x86, and x86_64 architectures:
201
202```
203$ python3 utils/create_reference_dumps.py
204```
205
206To update reference ABI dumps for a specific library, `libfoo` for example,
207run the command below:
208
209```
210$ python3 utils/create_reference_dumps.py -l libfoo
211```
212
213For more command line options, run:
214
215```
216$ utils/create_reference_dumps.py --help
217```
218
219#### Update Opt-in Reference ABI Dumps
220
221When the build system finds difference between the source code and the
222**opt-in** ABI reference dumps, it instructs you to run
223`create_reference_dumps.py` with `--ref-dump-dir` to update the dumps.
224
225The command below updates the reference ABI dumps for a specific library:
226
227```
228$ python3 utils/create_reference_dumps.py -l libfoo \
229 --ref-dump-dir /path/to/abi-dumps
230```
231
232You may specify `--product` if you don't want to create the ABI dumps for
233all architectures. For example, with `--product aosp_arm`, the command creates
234dumps for 32-bit arm only.
235
236#### Configure Cross-Version ABI Check
237
238When the build system finds incompatibility between the source code and the ABI
239of the **previous version**, it instructs you to follow this document to
240resolve it.
241
242If the ABI difference is intended, you may configure the ABI tools to ignore
243it. The following example shows how to make an exception for the ABI difference
244in `libfoo` between the current source and the previous version, `33`:
245
2461. Open `libfoo.so.33.abidiff` which is located in
247 `$OUT_DIR/soong/.intermediates` or `$DIST_DIR/abidiffs`. Find out the
248 `linker_set_key` of the type that has ABI difference. Here is a sample
249 abidiff file:
250
251 ```
252 lib_name: "libfoo"
253 arch: "x86_64"
254 record_type_diffs {
255 name: "bar"
256 ...
257 linker_set_key: "_ZTI3bar"
258 }
259 compatibility_status: INCOMPATIBLE
260 ```
261
2622. Find the reference dump directories by
263
264 `find $ANDROID_BUILD_TOP/prebuilts/abi-dumps/*/33 -name libfoo.so.lsdump -exec dirname {} +`
265
266 The command should show 6 directories for different architectures.
267
2683. Create or edit `config.json` in every directory, for instance,
269
270 `prebuilts/abi-dumps/ndk/33/64/x86_64/source-based/config.json`
271
272 ```
273 {
274 "libfoo": [
275 {
276 "target_version": "34",
277 "ignore_linker_set_keys": [
278 "_ZTI3bar",
279 ],
280 },
281 ],
282 }
283 ```
284
285 The config above makes the ABI tools ignore the difference in type
286 `_ZTI3bar` in `libfoo`. If the API level of this branch has been finalized
287 (i.e., PLATFORM_VERSION_CODENAME=REL), `target_version` must be set to the
288 API level. Otherwise, `target_version` must be set to
289 **the previous finalized API level + 1** so that the config will continue
290 being effective after finalization.
291
292For more information about the config files, please refer to
293[Configuration](#Configuration).
294
295### How to Ignore Weak Symbol Difference
296
297If you compile Android with a customized toolchain, it may produce different
298weak symbols. You may make header-abi-diff ignore the weak symbols by adding
299`config.json` to each reference dump directory. For example, the following
300configuration makes header-abi-diff ignore weak symbols for all x86_64 NDK
301libraries at API level 33:
302
303`prebuilts/abi-dumps/ndk/33/64/x86_64/source-based/config.json`
304
305```
306{
307 "global": {
308 "flags": {
309 "allow_adding_removing_weak_symbols": true,
310 },
311 },
312}
313```
314
315To ignore weak symbols for a specific library, you can add extra flags to its
316Android.bp. For example,
317
318```
319cc_library {
320 header_abi_checker: {
321 diff_flags: ["-allow-adding-removing-weak-symbols"],
322 },
323}
324```
325
326### How to Disable the ABI Check
327
328You can disable the ABI check entirely by setting the environment variable
329`SKIP_ABI_CHECKS`. For example,
330
331`$ SKIP_ABI_CHECKS=true make`
332
333You can disable the ABI check for a specific library by using the property
334`enabled` in its Android.bp. For example,
335
336```
337cc_library {
338 header_abi_checker: {
339 enabled: false,
340 },
341}
342```
343