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