1# When to use which `#define` 2 3Using `#ifdef` or equivalents is common when writing portable code. Which to use 4when can be quite tricky. This document describes the most common choices 5related to Android. 6 7## `__BIONIC__` 8 9If your code is specific to Android's C library, bionic, use `__BIONIC__`. This 10is typically a good choice when you use libc API that's only in bionic, such as 11the system property functions. Common alternatives on this dimension are 12`__GLIBC__`, `__APPLE__`, or `_WIN32`. Note that although bionic is most often 13seen on Android devices, it is possible to use bionic on the host too. 14 15## `__ANDROID__` 16 17If your code is specific to Android devices, use `__ANDROID__`. This isn't 18useful as you might think, and one of the other choices on this page is usually 19more appropriate. This is typically a good choice if you have code that's part 20of the OS and needs to behave differently on the host than on the device. 21Genuine cases are quite rare, and `__BIONIC__` is often more specific (but 22remember that it is possible -- if unusual -- to use bionic on the host). 23 24## `ANDROID` (rarely useful) 25 26Not to be confused with `__ANDROID__`, the similar-looking but very different 27`ANDROID` is _not_ set by the toolchain or NDK build system. This is set by 28the AOSP build system for both device and host code. For that reason, it's 29not typically very useful except as a signal when patching third-party code --- 30but even then, you'd typically _not_ want this because it's true for both 31device and host. 32 33## `__ANDROID_API__` 34 35If your code can be built targeting a variety of different OS versions, use 36`__ANDROID_API__` to test which version you're building against. This is 37typically useful if you can use new NDK APIs when available, but don't require 38them if not. 39 40One thing to note (if your code may also be built as part of the OS itself) is 41that for most of the year, the OS builds with this set to 10,000 rather than the 42obvious "next" API level such as 19. Once the API level has been decided, the 43value of `__ANDROID_API__` drops to that number. 44 45## `__linux__` 46 47If your code requires a Linux kernel, use `__linux__`. This is typically a good 48choice when you use Linux-specific API, such as a Linux-specific system call or 49a file in `/proc`, but aren't restricted to just Android and would work equally 50well on a desktop Linux distro, say. Common alternatives on this dimension 51are `__APPLE__` or `_WIN32`. 52 53## `__ANDROID_NDK__` 54 55If your code can be built either as part of an app _or_ as part of the OS 56itself, use `__ANDROID_NDK__` to differentiate between those two circumstances. 57This is typically a good choice when your code uses non-NDK API if it's built as 58part of the OS, but sticks to just the NDK APIs otherwise. 59 60## `__NDK_MAJOR__`, `__NDK_MINOR__`, `__NDK_BETA__`, `__NDK_BUILD__`, `__NDK_CANARY__` 61 62If your code can be built with a variety of different NDK versions, and needs to 63work around issues with some of them, use these macros to detect the versinon of 64the NDK you're being built with. Usually only `__NDK_MAJOR__` will be necessary. 65 66## `__arm__`/`__aarch64__`, `__i386__`/`__x86_64__`, `__riscv` 67 68If your code is specific to a particular processor architecture, use 69these macros to conditionally compile. Note that the ABI usually called 70`arm64` uses the macro `__aarch64__` and the ABI usually called `x86` uses 71`__i386__`. Android only supports riscv64, so `__riscv` is a sufficient 72check for Android-only code. If you need to write code portable to other 73operating systems that do support riscv32, you'll also need to check 74whether `__riscv_xlen` is 32 or 64. 75 76## `__ILP32__` and `__LP64__` 77 78If your code depends on "bitness" -- whether `long` and pointers are 32- 79or 64-bit -- use these macros to conditionally compile. Note the extra 80"I" in the 32-bit macro (since `int`, `long`, and pointers are all 32-bit 81on such systems, with `long long` being needed for a 64-bit type). 82