67 lines
3 KiB
Markdown
67 lines
3 KiB
Markdown
|
# When to use which `#define`
|
||
|
|
||
|
Using `#ifdef` or equivalents is common when writing portable code. Which to use
|
||
|
when can be quite tricky. This document describes the most common choices
|
||
|
related to Android.
|
||
|
|
||
|
## `__BIONIC__`
|
||
|
|
||
|
If your code is specific to Android's C library, bionic, use `__BIONIC__`. This
|
||
|
is typically a good choice when you use libc API that's only in bionic, such as
|
||
|
the system property functions. Common alternatives on this dimension are
|
||
|
`__GLIBC__`, `__APPLE__`, or `_WIN32`. Note that although bionic is most often
|
||
|
seen on Android devices, it is possible to use bionic on the host too.
|
||
|
|
||
|
## `__ANDROID__`
|
||
|
|
||
|
If your code is specific to Android devices, use `__ANDROID__`. This isn't
|
||
|
useful as you might think, and one of the other choices on this page is usually
|
||
|
more appropriate. This is typically a good choice if you have code that's part
|
||
|
of the OS and needs to behave differently on the host than on the device.
|
||
|
Genuine cases are quite rare, and `__BIONIC__` is often more specific (but
|
||
|
remember that it is possible -- if unusual -- to use bionic on the host).
|
||
|
|
||
|
## `__ANDROID_API__`
|
||
|
|
||
|
If your code can be built targeting a variety of different OS versions, use
|
||
|
`__ANDROID_API__` to test which version you're building against. This is
|
||
|
typically useful if you can use new NDK APIs when available, but don't require
|
||
|
them if not.
|
||
|
|
||
|
One thing to note (if your code may also be built as part of the OS itself) is
|
||
|
that for most of the year, the OS builds with this set to 10,000 rather than the
|
||
|
obvious "next" API level such as 19. Once the API level has been decided, the
|
||
|
value of `__ANDROID_API__` drops to that number.
|
||
|
|
||
|
## `__linux__`
|
||
|
|
||
|
If your code requires a Linux kernel, use `__linux__`. This is typically a good
|
||
|
choice when you use Linux-specific API, such as a Linux-specific system call or
|
||
|
a file in `/proc`, but aren't restricted to just Android and would work equally
|
||
|
well on a desktop Linux distro, say. Common alternatives on this dimension
|
||
|
are `__APPLE__` or `_WIN32`.
|
||
|
|
||
|
## `__ANDROID_NDK__`
|
||
|
|
||
|
If your code can be built either as part of an app _or_ as part of the OS
|
||
|
itself, use `__ANDROID_NDK__` to differentiate between those two circumstances.
|
||
|
This is typically a good choice when your code uses non-NDK API if it's built as
|
||
|
part of the OS, but sticks to just the NDK APIs otherwise.
|
||
|
|
||
|
## `__NDK_MAJOR__`, `__NDK_MINOR__`, `__NDK_BETA__`, `__NDK_BUILD__`, `__NDK_CANARY__`
|
||
|
|
||
|
If your code can be built with a variety of different NDK versions, and needs to
|
||
|
work around issues with some of them, use these macros to detect the versinon of
|
||
|
the NDK you're being built with. Usually only `__NDK_MAJOR__` will be necessary.
|
||
|
|
||
|
## `__arm__`, `__aarch64__`, `__i386__`, `__x86_64__`
|
||
|
|
||
|
If your code is specific to a particular processor architecture, use these
|
||
|
macros to conditionally compile. Note that the ABI usually called `arm64` uses
|
||
|
the macro `__aarch64__` and the ABI usually called `x86` uses `__i386__`.
|
||
|
|
||
|
## `__LP32__` and `__LP64__`
|
||
|
|
||
|
If your code depends on "bitness" -- whether `long` and pointers are 32- or
|
||
|
64-bit -- use these macros to conditionally compile.
|