blob: b75ef52bdb5d6cf211188bac3f45e8f5e3e8342b [file] [log] [blame] [view]
Dan Albertdb231382018-09-07 16:33:36 -07001# Build System Maintainers Guide
2
3The latest version of this document is available at
Dan Albertc4bdd152025-03-28 15:11:24 -07004https://android.googlesource.com/platform/ndk/+/mirror-goog-main-ndk/docs/BuildSystemMaintainers.md.
Dan Albert92a3be32019-02-08 15:48:51 -08005Ensure that you are using the version that corresponds to your NDK. Replace
Dan Albert60a80742025-03-11 12:46:32 -07006`master` in the URL with the appropriate NDK release branch. For example, the
7NDK r28 version of this document is located at
8https://android.googlesource.com/platform/ndk/+/ndk-r28-release/docs/BuildSystemMaintainers.md.
9For r23 and older, the branch name follows a different pattern. The r23 version
10of this document is located at
11https://android.googlesource.com/platform/ndk/+/ndk-release-r23/docs/BuildSystemMaintainers.md.
Dan Albertdb231382018-09-07 16:33:36 -070012
13The purpose of this guide is to instruct third-party build system maintainers in
14adding NDK support to their build systems. This guide will not be useful to most
15NDK users. NDK users should start with [Building Your Project].
16
17Note: This guide is written assuming Linux is the host OS. Mac should be no
18different, and the only difference on Windows is that file extensions for
19executables and scripts will differ.
20
21[Building Your Project]: https://developer.android.com/ndk/guides/build
22
23[TOC]
24
25## Introduction
26
Dan Albert48b8e522020-03-18 12:33:56 -070027The NDK uses the [LLVM] family of tools for building C/C++ code. These include
28[Clang] for compilation, [LLD] for linking, and other [LLVM tools] for other
Dan Albertae0943e2023-04-17 13:26:01 -070029tasks.
Dan Albertdb231382018-09-07 16:33:36 -070030
Dan Albertdb231382018-09-07 16:33:36 -070031[Clang]: https://clang.llvm.org/
32[LLD]: https://lld.llvm.org/
Dan Albertad4282f2020-06-19 13:24:48 -070033[LLVM tools]: https://llvm.org/docs/CommandGuide/
34[LLVM]: https://llvm.org/
Dan Albertdb231382018-09-07 16:33:36 -070035
36### Architectures
37[Architectures]: #architectures
38
39Note: In general an architecture may have multiple ABIs. An ABI (application
40binary interface) is different from an architecture in that it also specifies a
41calling convention, size and alignment of types, and other implementation
42details. For Android, each architecture supports only one ABI.
43
44Android supports multiple architectures: ARM32, ARM64, x86, and x86_64. NDK
45applications must build libraries for every architecture they support. 64-bit
46devices usually also support the 32-bit variant of their architecture, but this
47may not always be the case. While in general this means that an app with only
4832-bit libraries can run on 64-bit capable devices, the 64-bit ABI will have
49improved performance.
50
51This document will make use of `<arch>`, `<ABI>`, and `<triple>` in describing
52paths and arguments. The values of these variables for each architecture are as
53follows except where otherwise noted:
54
55| Name | arch | ABI | triple |
56| ------------ | ------- | ----------- | --------------------- |
57| 32-bit ARMv7 | arm | armeabi-v7a | arm-linux-androideabi |
58| 64-bit ARMv8 | aarch64 | aarch64-v8a | aarch64-linux-android |
59| 32-bit Intel | x86 | x86 | i686-linux-android |
60| 64-bit Intel | x86_64 | x86_64 | x86_64-linux-android |
61
Dan Albertc81c62a2018-10-10 13:49:14 -070062Note: Strictly speaking ARMv7 with [NEON] is a different ABI from ARMv7 without
Dan Albertdb231382018-09-07 16:33:36 -070063NEON, but it is not a *system* ABI. Both NEON and non-NEON ARMv7 code uses the
64ARMv7 system and toolchains.
65
66To programatically determine the list of supported ABIs, their bitness, as well
67as their deprecation status and whether or not it is recommended to build them
68by default, use `<NDK>/meta/abis.json`.
69
70### Thumb
71
7232-bit ARM can be built using either the [Thumb] or ARM instruction sets. Thumb
73code is smaller but may perform worse than ARM. However, smaller code makes more
74effective use of a processor's instruction cache, so benchmarking is necessary
75to determine which is more effective for a given application. ndk-build and the
76NDK's CMake toolchain file generate Thumb code by default.
77
78The ARM or Thumb instruction sets are selected by passing `-marm` or `-mthumb`
79to Clang respectively. By default, Clang will generate ARM code as opposed to
80Thumb for the `armv7a-linux-androideabi` target.
81
82Note: For ARMv7, Thumb-2 is used. Android no longer supports ARMv5, but if your
83build system mistakenly targets ARMv5 the less efficient Thumb-1 will be used.
84
85[Thumb]: https://en.wikipedia.org/wiki/ARM_architecture#Thumb-2
86
87### NEON
88
89Most ARM Android devices support [NEON]. This is supported by all 64-bit ARM
90devices and nearly all 32-bit ARM devices running at least Android Marshmallow
91(API 23). The [Android CDD] has required NEON support since that version, but it
92is possible that extant devices that were upgraded to Marshmallow do not include
93NEON support.
94
Dan Alberta78a3dc2019-09-04 13:15:15 -070095NEON can significantly improve application performance.
Dan Albertdb231382018-09-07 16:33:36 -070096
Dan Alberta78a3dc2019-09-04 13:15:15 -070097Clang automatically enables NEON for all API levels. ARM devices without NEON
98are uncommon. To support non-NEON devices, pass `-mfpu=vfpv3-d16` when
Dan Albert73c19ee2020-07-24 16:25:18 -070099compiling. Alternatively, use the Play Console to [exclude CPUs] without NEON
Dan Alberta78a3dc2019-09-04 13:15:15 -0700100to disallow your app from being installed on those devices.
Dan Albertdb231382018-09-07 16:33:36 -0700101
102[Android CDD]: https://source.android.com/compatibility/cdd
103[NEON]: https://developer.arm.com/technologies/neon
Dan Albert73c19ee2020-07-24 16:25:18 -0700104[exclude CPUs]: https://support.google.com/googleplay/android-developer/answer/7353455?hl=en
Dan Albertdb231382018-09-07 16:33:36 -0700105
106### OS Versions
107[OS Versions]: #os-versions
108
109As users are distributed over a wide variety of Android OS versions (see the
110[Distribution dashboard]), applications have a minimum and maximum supported
111version, as well as a targeted version. These are `minSdkVersion`,
112`maxSdkVersion`, and `targetSdkVersion` respectively. See the [uses-sdk]
113documentation for more information.
114
115For NDK code, the only relevant value is the minimum supported version. Any time
116this doc refers to an API level, OS version, or target version, it is referring
117to the application's `minSdkVersion`.
118
119The API level targeted by an NDK application determines which APIs will be
Dan Albertac91a272022-10-06 15:13:04 -0700120exposed for use by the application. By default, APIs that are not present in the
121targeted API level cannot be linked directly, but may be accessed via `dlsym`.
122An NDK application running on a device with an API level lower than the target
123will often not load at all. If it does load, it may not behave as expected. This
124is not a supported configuration. This behavior can be altered by following the
125section about [weak symbols]. Be sure your users understand the implications of
126doing so.
Dan Albertdb231382018-09-07 16:33:36 -0700127
128The major/minor version number given to an Android OS has no meaning when it
129comes to determining its API level. See the table in the [Build numbers]
130document to map Android code names and version numbers to API levels.
131
132Note: Not every API level includes new NDK APIs. If there were no new NDK APIs
133for the given API level, there is no library directory for that API level. In
134that case, the build system should select the closest available API that is
135below the target API level. For example, applications with a `minSdkVersion` of
13620 should use API 19 for their NDK target.
137
138To programatically determine the list of supported API levels as well as aliases
Dan Albertf0f3bdf2024-01-22 15:48:36 -0800139that are accepted by ndk-build and CMake, see `<NDK>/meta/platforms.json`. For
140ABI specific minimum supported API levels, see `<NDK>/meta/abis.json`.
Dan Albertdb231382018-09-07 16:33:36 -0700141
142Note: In some contexts the API level may be referred to as a platform. In this
143document an API level is always an integer, and a platform takes the form of
144`android-<API level>`. The latter format is not specifically used anywhere in
145the NDK toolchain, but is used to specify target API levels for ndk-build and
146CMake.
147
148Note: As a new version of the Android OS approaches release, previews and betas
149of that OS will be released and an NDK will be released that can make use of the
150new APIs. Targeting a preview API level is no different than targeting a
151released API level, with the exception that applications built targeting preview
152releases should not be shipped to production. Consult
153`<NDK>/meta/platforms.json` to determine the API level for a preview release.
154
155[Build numbers]: https://source.android.com/setup/start/build-numbers
156[Distribution dashboard]: https://developer.android.com/about/dashboards/
157[uses-sdk]: https://developer.android.com/guide/topics/manifest/uses-sdk-element
Dan Albertac91a272022-10-06 15:13:04 -0700158[weak symbols]: #weak-symbols-for-api-definitions
Dan Albertdb231382018-09-07 16:33:36 -0700159
Dan Albert7b4281b2024-03-25 14:40:17 -0700160### Page sizes
161
162Android V will allow OEMs to ship arm64-v8a and x86_64 devices with 16KiB page
163sizes. Devices that use this configuration will not be able to run existing apps
164that use native code. To be compatible with these devices, applications will
165need to rebuild all their native code to be 16KiB aligned, and rewrite any code
166which assumes a specific page size. See [Support 16 KB page sizes] for details.
167
168Note: 16KiB compatible binaries are also compatible with 4KiB page devices. You
169do not need to build both 16KiB and 4KiB variants of your libraries.
170
171To minimize disruption, the default configuration for NDK r27 remains 4KiB page
172sizes. A future NDK (likely r28) will change the defaults. To support building
17316KiB compatible apps in your build system, do the following:
174
1751. When linking arm64-v8a or x86_64 code, set the linker's max-page-size to
176 16384: `-Wl,-z,max-page-size=16384`. This will increase the size of the
177 binaries.
1782. Define `__BIONIC_NO_PAGE_SIZE_MACRO` to configure libc to hide the
179 declaration of `PAGE_SIZE` from the build: `-D__BIONIC_NO_PAGE_SIZE_MACRO`.
180 There is no valid build-time constant for the page size in a world where
181 devices have varying page sizes. Runtime checks with `getpagesize()` are
182 required.
183
184Note that, for the time being, this only needs to be done for arm64-v8a. The
185x86_64 emulator (see [Support 16 KB page sizes] for details) will support larger
186page sizes for testing purposes, but there are no plans to change the page size
187for the 32-bit ABIs, and riscv64 does not support 16KiB page sizes at all.
188
189[Support 16 KB page sizes]: https://developer.android.com/guide/practices/page-sizes
190
Dan Albertdb231382018-09-07 16:33:36 -0700191## Clang
192
Dan Albertdae41c72018-10-25 13:36:51 -0700193Clang is installed to `<NDK>/toolchains/llvm/prebuilt/<host-tag>/bin/clang`.
194The C++ compiler is installed as `clang++` in the same directory. `clang++` will
195make C++ headers available when compiling and will automatically link the C++
196runtime libraries when linking.
Dan Albertdb231382018-09-07 16:33:36 -0700197
198`clang` should be used when compiling C source files, and `clang++` should be
199used when compiling C++ source files. When linking, `clang` should be used if
200the binary being linked contains no C++ code (i.e. none of the object files
201being linked were generated from C++ files) and `clang++` should be used
202otherwise. Using `clang++` ensures that the C++ standard library is linked.
203
Dan Alberteb4cc502023-04-17 13:28:53 -0700204When linking a shared library, the `-Wl,-soname,$NAME_OF_LIBRARY` argument is
205required. This is necessary to avoid the problems described in [this stack
206overflow post](https://stackoverflow.com/a/48291044/632035). For example, when
207building `libapp.so`, `-Wl,-soname,libapp.so` must be used.
208
Dan Albertdb231382018-09-07 16:33:36 -0700209### Target Selection
210
James Farrell37befa42022-06-22 20:17:58 +0000211[Cross-compilation] targets can be selected in one of two ways: by using
212the `--target` flag, or by using target-specific wrapper scripts.
Dan Albertdb231382018-09-07 16:33:36 -0700213
James Farrell37befa42022-06-22 20:17:58 +0000214If possible, we recommend using the `--target` flag, which is described more
215fully in the [Clang User Manual]. The value passed is a Clang target
Dan Albertdb231382018-09-07 16:33:36 -0700216triple suffixed with an Android API level. For example, to target API 26 for
21732-bit ARM, use `--target armv7a-linux-androideabi26`.
218
219Note: "armv7a" should be used rather than simply "arm" when specifying targets
220for Clang to generate ARMv7 code rather than the slower ARMv5 code. Specifying
221ARMv5 and thumb code generation will result in Thumb-1 being generated rather
222than Thumb-2, which is less efficient.
223
James Farrell37befa42022-06-22 20:17:58 +0000224If not possible to use the `--target` flag, we supply wrapper scripts alongside
225the `clang` and `clang++` binaries, named `<triple><API-level>-clang` and
226`<triple><API-level>-clang++`. For example, to target API 26 32-bit ARM,
Dan Albertdb231382018-09-07 16:33:36 -0700227invoke `armv7a-linux-androideabi26-clang` or
James Farrell37befa42022-06-22 20:17:58 +0000228`armv7a-linux-androideabi26-clang++` instead of `clang` or `clang++`. These
229wrappers come in two forms: Bash scripts (for Mac, Linux, Cygwin, and WSL) and
230Windows batch files (with `.cmd` extensions).
Dan Albertdb231382018-09-07 16:33:36 -0700231
James Farrell37befa42022-06-22 20:17:58 +0000232Note: For projects with many source files, the wrapper scripts may cause
233noticeable overhead, which is why we recommend using `--target`. The overhead
234is most significant on Windows, as `CreateProcess` is slower than `fork`.
Dan Albertdb231382018-09-07 16:33:36 -0700235
236For more information on Android targets, see the [Architectures] and [OS
237Versions] sections.
238
239[Clang User Manual]: https://clang.llvm.org/docs/UsersManual.html
240[Cross-compilation]: https://en.wikipedia.org/wiki/Cross_compiler
241
242## Linkers
243
Dan Albertae0943e2023-04-17 13:26:01 -0700244The NDK uses LLD for linking. The linker is installed to
245`<NDK>/toolchains/llvm/prebuilt/<host-tag>/bin/<triple>-ld`.
Dan Albertdb231382018-09-07 16:33:36 -0700246
247Note: It is usually not necessary to invoke the linkers directly since Clang
248will do so automatically. Clang will also automatically link CRT objects and
249default libraries and set up other target-specific options, so it is generally
250better to use Clang for linking.
251
Dan Albertdb231382018-09-07 16:33:36 -0700252[Issue 70838247]: https://issuetracker.google.com/70838247
Dan Alberte043c262018-11-13 15:10:18 -0800253
254## Binutils
255
Dan Albert1cc962e2020-06-24 13:32:45 -0700256LLVM's binutils tools are installed to the NDK at
257`<NDK>/toolchains/llvm/prebuilt/<host-tag>/bin/llvm-<tool>`. These include but
258are not limited to:
259
260* llvm-ar
Dan Albert1cc962e2020-06-24 13:32:45 -0700261* llvm-objcopy
262* llvm-objdump
263* llvm-readelf
264* llvm-strip
265
Dan Albert0ba64932023-08-01 14:30:41 -0700266All LLVM tools are capable of handling every target architecture. Unlike Clang,
267no `-target` argument is required for these tools, so they should behave
268correctly when used as drop-in replacements for their GNU equivalents. Some
269tools may optionally accept a `-target` argument, but if omitted they will
270select the correct target based on the input files.
271
Dan Albertf52235b2020-06-24 15:48:52 -0700272Note that `llvm-as` is **not** an equivalent of GNU `as`, but rather a tool for
273assembling LLVM IR. If you are currently using `as` directly, you will need to
Elliott Hughes3e47e462021-08-24 10:30:26 -0700274migrate to using `clang` as a driver for building assembly. See [Clang
275Migration Notes] for advice on fixing assembly to be LLVM compatible.
Dan Albertf52235b2020-06-24 15:48:52 -0700276
Elliott Hughes3e47e462021-08-24 10:30:26 -0700277Note that by default `/usr/bin/as` is used by Clang if the
278`-fno-integrated-as` argument is used, which is almost certainly not
279what you want!
280
281[Clang Migration Notes]: ClangMigration.md
Dan Albertad4282f2020-06-19 13:24:48 -0700282
Dan Albertdb231382018-09-07 16:33:36 -0700283## Sysroot
284
Dan Albertdae41c72018-10-25 13:36:51 -0700285The Android sysroot is installed to
286`<NDK>/toolchains/llvm/prebuilt/<host-tag>/sysroot` and contains the headers,
287libraries, and CRT object files for each Android target.
Dan Albertdb231382018-09-07 16:33:36 -0700288
289Headers can be found in the `usr/include` directory of the sysroot. Target
290specific include files are installed to `usr/include/<triple>`. When using
291Clang, it is not necessary to include these directories explicitly; Clang will
292automatically select the sysroot. If using a compiler other than Clang, ensure
293that the target-specific include directory takes precedence over the
294target-generic directory.
295
296Libraries are found in the `usr/lib/<triple>` directory of the sysroot.
297Version-specific libraries are installed to `usr/lib/<triple>/<API-level>`. As
298with the header files, when using Clang it is not necessary to include these
299directories explicitly; the sysroot will be automatically selected. If using a
300compiler other than Clang, ensure that the version-specific library directory
301takes precedence over the version-generic directory.
302
303## Libraries
304
305The NDK contains three types of libraries. Static libraries have a .a file
306extension and are linked directly into app binaries. Shared libraries have a .so
307file extension and must be included in the app's APK if used. System stub
308libraries are a special type of shared library that should not be included in
309the APK. The system stub libraries define the interface of a library that is
310provided by the Android OS but contain no implementation. They can be identified
Dan Alberta737dee2019-04-18 15:26:58 -0700311by their .so file extension and their presence in `<NDK>/meta/system_libs.json`.
312The entries in this file are a key/value pair that maps library names to the
313first API level the library is introduced.
Dan Albertdb231382018-09-07 16:33:36 -0700314
Dan Albertac91a272022-10-06 15:13:04 -0700315## Weak symbols for API definitions
316
317See [Issue 837].
318
319The Android APIs are exposed as strong symbols by default. This means that apps
320must not directly refer to any APIs that were not available in their
321`minSdkVersion`, even if they will not be called at runtime. The loader will
322reject any library with strong references to symbols that are not present at
323load time.
324
325It is possible to expose Android APIs as weak symbols to alter this behavior to
326more closely match the Java behavior, which many app developers are more
327familiar with. The loader will allow libraries with unresolved references to
328weak symbols to load, allowing those APIs to be safely called as long as they
329are only called when the API is available on the device. Absent APIs will have a
330`nullptr` address, so calling an unavailable API will segfault.
331
332Note: APIs that are guaranteed to be available in the `minSdkVersion` (the API
333level passed to Clang with `-target`) will always be strong references, even
334with this option enabled.
335
336This is not enabled by default because, unless used cautiously, this method is
337prone to deferring build failures to run-time (and only on older devices, since
338newer devices will have the API). The loader not prevent the library from
339loading, but the function's address will be `nullptr` if the API is not
340available (if the API is newer than the OS). The API availability should be
341checked with `__builtin_available` before making the call:
342
343```c++
344if (__builtin_available(android 33, *)) {
345 // Call some API that's only available in API 33+.
346} else {
347 // Use some fallback behavior, perhaps doing nothing.
348}
349```
350
351Clang offers some protections for this approach via `-Wunguarded-availability`,
352which will emit a warning unless the call to the API is guarded with
353`__builtin_available`.
354
355To enable this functionality, pass `-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__`
356to Clang when compiling. We **strongly** recommend forcing
357`-Werror=unguarded-availability` when using this option.
358
359We recommend making the choice of weak or strong APIs an option in your build
360system. Most developers will likely prefer weak APIs as they are simpler than
361using `dlopen`/`dlsym`, and as long as `-Werror=unguarded-availability` is used,
362it should be safe. At the time of writing, the NDK's own build systems
363(ndk-build and CMake) use strong API references by default, but that may change
364in the future.
365
366Known issues and limitations:
367
368* Only symbols are affected, not libraries. The only way to conditionally depend
369 on a library that is not available in the app's `minSdkVersion` is with
370 `dlopen`. We do not know how to solve this in a backwards compatible manner.
371* APIs in bionic (libc, libm, libdl) are not currently supported. See the bug
372 for more information. If the source compatibility issues can be resolved, that
373 will change in a future NDK release.
374* Headers authored by third-parties (e.g. `vulkan.h`, which comes directly from
375 Khronos) are not supported. The implementation of this feature requires
376 annotation of all function declarations, and the upstream headers likely do
377 not contain those annotations. Solutions to this problem are being
378 investigated.
379
380[Issue 837]: https://github.com/android/ndk/issues/837
381
Dan Albertdb231382018-09-07 16:33:36 -0700382## STL
383
384### libc++
385
386The STL provided by the NDK is [libc++]. Its headers are installed to
Dan Albert7e814262018-12-18 15:49:54 -0800387`<NDK>/sysroot/usr/include/c++/v1`. This STL is used by default. This STL comes
388in both a static and shared variant. The shared variant is used by default. To
389use the static variant, pass `-static-libstdc++` when linking. If using the
390shared variant, libc++_shared.so must be included in the APK. This library is
391installed to `<NDK>/sysroot/usr/lib/<triple>`.
Dan Albertdb231382018-09-07 16:33:36 -0700392
393Warning: There are a number of things to consider when selecting between the
394shared and static STLs. See the [Important Considerations] section of the C++
395Support document for more details.
396
397There are version-specific libc++.so and libc++.a libraries installed to
398`<NDK>/sysroot/usr/lib/<triple>/<version>`. These are not true libraries but
399[implicit linker scripts]. They inform the linker how to properly link the STL
Dan Albert4eea3b02022-10-13 16:49:47 -0700400for the given version. These scripts handle the inclusion of any libc++
Dan Albertdb231382018-09-07 16:33:36 -0700401dependencies if necessary. Linker scripts should not be included in the APK.
402
403Build systems should prefer to let Clang link the STL. If not using Clang, the
404version scripts should be used. Linking libc++ and its dependencies manually
405should only be used as a last resort.
406
407Note: Linking libc++ and its dependencies explicitly may be necessary to defend
Dan Albertd471b922021-03-17 16:52:35 -0700408against exception unwinding bugs caused by improperly built dependencies (see
409[Issue 379]). If not dependent on stack unwinding (the usual reason being that
410the application does not make use of C++ exceptions) or if no dependencies were
411improperly built, this is not necessary. If needed, link the libraries as listed
412in the linker script and be sure to follow the instructions in [Unwinding].
Dan Albertdb231382018-09-07 16:33:36 -0700413
414[Important Considerations]: https://developer.android.com/ndk/guides/cpp-support#important_considerations
415[Issue 379]: https://github.com/android-ndk/ndk/issues/379
416[implicit linker scripts]: https://sourceware.org/binutils/docs/ld/Scripts.html
417[libc++]: https://libcxx.llvm.org/
418
419### System STL
420
421The legacy "system STL" is also included, but it will be removed in a future NDK
422release. It is not in fact an STL; it contains only the barest C++ library
423support: the C++ versions of the C library headers and basic C++ runtime support
424like `new` and `delete`. Its headers are installed to
Dan Albertdae41c72018-10-25 13:36:51 -0700425`<NDK>/toolchains/llvm/prebuilt/<host-tag>/include/c++/4.9.x` and its library is
426the libstdc++.so system stub library. To use this STL, use the
427`-stdlib=libstdc++` flag.
Dan Albertdb231382018-09-07 16:33:36 -0700428
429TODO: Shouldn't it be installed to sysroot like libc++?
430
431Note: The system STL will likely be removed in a future NDK release.
432
433### No STL
434
435To avoid using the STL at all, pass `-nostdinc++` when compiling and
436`-nostdlib++` when linking. This is not necessary when using `clang`, only when
437using `clang++`.
438
439## Sanitizers
440
441The NDK supports [Address Sanitizer] (ASan). This tool is similar to Valgrind in
442that it diagnoses memory bugs in a running application, but ASan is much faster
443than Valgrind (roughly 50% performance compared to an unsanitized application).
444
445To use ASan, pass `-fsanitize=address` when both compiling and linking. The
Dan Albert2991a552023-07-21 10:32:20 -0700446sanitizer runtime libraries are installed to `<clang resource dir>/lib/linux`.
447The Clang resource directory is given by `clang -print-resource-dir`. The
448library is named `libclang_rt.asan-<arch>-android.so`. This library must be
Dan Albertaa7f8432019-07-01 13:51:02 -0700449included in the APK. A [wrap.sh] file must also be included in the APK. A
450premade wrap.sh file for ASan is installed to `<NDK>/wrap.sh`.
Dan Albertdb231382018-09-07 16:33:36 -0700451
452Note: wrap.sh is only available for [debuggable] APKs running on Android Oreo
453(API 26) or higher. ASan can still be used devices prior to Oreo but at least
454Lollipop (API 21) if the device has been rooted. Direct users to the
455[AddressSanitizerOnAndroid] document for instructions on using this method.
456
457[Address Sanitizer]: https://clang.llvm.org/docs/AddressSanitizer.html
458[AddressSanitizerOnAndroid]: https://github.com/google/sanitizers/wiki/AddressSanitizerOnAndroid#run-time-flags
459[debuggable]: https://developer.android.com/guide/topics/manifest/application-element#debug
460[wrap.sh]: https://developer.android.com/ndk/guides/wrap-script
461
Dan Alberte3f70782019-02-12 13:37:49 -0800462## Additional Required Arguments
Dan Albertdb231382018-09-07 16:33:36 -0700463
464Note: It is a bug that any of these need to be specified by the build system.
465All flags discussed in this section should be automatically selected by Clang,
466but they are not yet. Check back in a future NDK release to see if any can be
467removed from your build system.
468
Dan Albertdb231382018-09-07 16:33:36 -0700469For x86 targets prior to Android Nougat (API 24), `-mstackrealign` is needed to
470properly align stacks for global constructors. See [Issue 635].
471
Dan Albertc81c62a2018-10-10 13:49:14 -0700472Android requires [Position-independent executables] beginning with API 21. Clang
473builds PIE executables by default. If invoking the linker directly or not using
474Clang, use `-pie` when linking.
475
Ryan Prichard1bbeeea2019-07-03 14:48:37 -0700476Android Studio's LLDB debugger uses a binary's build ID to locate debug
477information. To ensure that LLDB works with a binary, pass an option like
478`-Wl,--build-id=sha1` to Clang when linking. Other `--build-id=` modes are OK,
479but avoid a plain `--build-id` argument when using LLD, because Android Studio's
480version of LLDB doesn't recognize LLD's default 8-byte build ID. See [Issue
481885].
482
Dan Albertcfdc5e22020-06-25 15:53:55 -0700483The unwinder used for crash handling on Android devices prior to API 29 cannot
484correctly unwind binaries built with `-Wl,--rosegment`. This flag is enabled by
485default when using LLD, so if using LLD and targeting devices older than API 29
486you must pass `-Wl,--no-rosegment` when linking for correct stack traces in
487logcat. See [Issue 1196].
488
Dan Albertdb231382018-09-07 16:33:36 -0700489[Issue 635]: https://github.com/android-ndk/ndk/issues/635
Ryan Prichard1bbeeea2019-07-03 14:48:37 -0700490[Issue 885]: https://github.com/android-ndk/ndk/issues/885
Dan Alberte3f70782019-02-12 13:37:49 -0800491[Issue 906]: https://github.com/android-ndk/ndk/issues/906
Dan Albertcfdc5e22020-06-25 15:53:55 -0700492[Issue 1196]: https://github.com/android/ndk/issues/1196
Dan Albertc81c62a2018-10-10 13:49:14 -0700493[Position-independent executables]: https://en.wikipedia.org/wiki/Position-independent_code#Position-independent_executables
Dan Albertdb231382018-09-07 16:33:36 -0700494
495## Useful Arguments
496
497### Dependency Management
498
499It is recommended that `-Wl,--exclude-libs,<library file name>` be used for each
500static library linked. This causes the linker to give symbols imported from a
501static library hidden [visibility]. This prevents a binary from unintentionally
502re-exporting an API other than its own. If the intent is to re-export all the
503symbols in a static library, `-Wl,--whole-archive <library>
504-Wl,--no-whole-archive` should be used to ensure that the whole archive is
505preserved. By default, only symbols in used sections will be included in the
506linked binary.
507
Dan Albertdb231382018-09-07 16:33:36 -0700508[visibility]: https://gcc.gnu.org/wiki/Visibility
509
510### Controlling Binary Size
511
512To minimize the size of an APK, it may be desirable to use the `-Oz`
513optimization mode. This will generate somewhat slower code than `-O2` or `-O3`,
514but it will be smaller.
515
516Note: `-Os` behavior is not the same with Clang as it is with GCC. Clang's `-Oz`
517behaves similarly to GCC's `-Os`. `-Os` with Clang is a middle ground between
518size and speed optimizations.
519
520To aid the linker in removing as much unused code as possible, the compiler
521flags `-ffunction-sections` and `-fdata-sections` may be used. These flags
522should only be used in conjunction with the `-Wl,--gc-sections` linker flag.
523Failing to use `-Wl,--gc-sections` will cause the former flags to *increase*
524output size. The linker is only able to discard unused sections, so it can only
525discard at per-function or per-variable granularity if each is in its own
526section.
527
528While `-Wl,--gc-sections` should always be used, whether or not to enable
529`-ffunction-sections` and `-fdata-sections` depends on how the object file being
530compiled is expected to be used. If it will be used in a shared library then all
531of its [public symbols] will be preserved and the additional overhead of placing
532each item in its own section may make the shared library *larger* rather than
533smaller. If it will be used only in a static library or an executable then it
534will depend on how much of the resulting object file is expected to be unused.
535
536[public symbols]: #dependency-management
537
Dan Albertf8ddc6b2021-09-22 16:02:43 -0700538#### RELR and relocation packing
539
540Note that each of the flags below will prevent the library or executable from
541loading on older devices. If your `minSdkVersion` is at least the supported API
542level, these flags are typically beneficial. A future release of the NDK will
543likely enable this by default based on the `minSdkVersion` passed to Clang. See
544[Issue 909] for more information.
545
546Beginning with API level 23 it is possible to compress the relation data in
547libraries and executables. Libraries with large numbers of relocations will
548benefit from this. Enable with `-Wl,--pack-dyn-relocs=android` at link time.
549
550API level 28 adds support for relative relocations (RELR) which can further
551reduce the size of relocations. Enable with `-Wl,--pack-dyn-relocs=android+relr`
552at link time. API levels 28 and 29 predate the standardization of this feature
553in ELF, so for those API levels also pass `-Wl,--use-android-relr-tags` at link
554time.
555
556[Issue 909]: https://github.com/android/ndk/issues/909
557
Dan Albertdb231382018-09-07 16:33:36 -0700558### Helpful Warnings
559
560It is recommended that build systems promote the following warnings to errors.
561These warnings indicate either a bug or undefined behavior, the latter of which
562Clang will usually turn into a bug.
563
564 * `-Werror=return-type`: A non-void function is missing a return statement.
565 Clang may "optimize" this function to fall through into the next one.
566 * `-Werror=int-to-pointer-cast` and `-Werror=pointer-to-int-cast`: These
567 indicate bugs that will affect the 64-bit version of the application.
568 * `-Werror=implicit-function-declaration`: Undeclared functions may be inferred
569 to have a return type of `int` in C. For functions that return a pointer, the
570 return type will be silently truncated to a 32-bit `int`, resulting in bugs
571 that will affect the 64-bit version of the application.
572
573For more information on Clang's supported arguments, see the [Clang User
574Manual].
575
Dan Albertff3acaf2019-09-04 13:20:59 -0700576### Hardening
577
Dan Albert9c6bc632019-09-18 14:51:01 -0700578#### Stack protectors
579
Dan Albertff3acaf2019-09-04 13:20:59 -0700580It is recommented to build all code with `-fstack-protector-strong`. This causes
581the compiler to emit stack guards to protect against security vulnerabilities
582caused by buffer overruns.
583
584Note: ndk-build and the NDK's CMake toolchain file enable this option by
585default.
586
Dan Albert9c6bc632019-09-18 14:51:01 -0700587#### Fortify
588
589FORTIFY is a set of extensions to the C standard library that tries to catch the
590incorrect use of standard functions, such as `memset`, `sprintf`, and `open`.
591Where possible, runtime bugs will be diagnosed as errors at compile-time. If not
592provable at compile-time, a run-time check is used. Note that the specific set
593of APIs checked depends on the `minSdkVersion` used, since run-time support is
594required. See [FORTIFY in Android] for more details.
595
596To enable this feature in your build define `_FORTIFY_SOURCE=2` when compiling.
597
598Note: ndk-build and the NDK's CMake toolchain file enable this option by
599default.
600
601[FORTIFY in Android]: https://android-developers.googleblog.com/2017/04/fortify-in-android.html
602
Dan Alberta79281a2022-10-13 16:31:52 -0700603### Version script validation
604
605LLD will not raise any errors for symbols named in version scripts that are
606absent from the library. This is either a mistake in the version script, or a
607missing definition in the library. To have LLD diagnose these errors, pass
608`-Wl,--no-undefined-version` when linking.
609
Dan Albertdb231382018-09-07 16:33:36 -0700610## Common Issues
611
612### Unwinding
613[Unwinding]: #unwinding
614
Dan Albertd471b922021-03-17 16:52:35 -0700615The NDK uses LLVM's libunwind. libunwind is needed to provide C++ exception
616handling support and C's `__attribute__((cleanup))`. The unwinder is linked
617automatically by Clang, and is built with hidden visibility to avoid shared
618libraries re-exporting the unwind interface.
Dan Albertdb231382018-09-07 16:33:36 -0700619
Dan Albertd471b922021-03-17 16:52:35 -0700620Until NDK r23, libgcc was the unwinder for all architectures other than 32-bit
621ARM, and even 32-bit ARM used libgcc to provide compiler runtime support.
622Libraries built with NDKs older than r23 by build systems that did not follow
623the advice in this document may re-export that incompatible unwinder. In this
624case those libraries can prevent the correct unwinder from being used by your
625build, resulting in crashes or incorrect behavior at runtime.
Dan Albertdb231382018-09-07 16:33:36 -0700626
Dan Albertd471b922021-03-17 16:52:35 -0700627The best way to avoid this problem is to ensure all libraries in the application
Dan Albert3cb26742023-05-02 18:04:22 -0700628were built with NDK r23 or newer, but even libraries built by older NDKs are
629unlikely to have this problem.
Dan Albertdb231382018-09-07 16:33:36 -0700630
Dan Albert3cb26742023-05-02 18:04:22 -0700631For build systems that want to protect their users against improperly built
632libraries, read on. **Neither ndk-build nor CMake make this effort.**
633
634To protect against improperly built libraries, build systems can ensure that
635shared libraries are always linked **after** static libraries, and explicitly
636link the unwinder between each group. The linker will prefer definitions that
637appear sooner in the link order, so libunwind appearing **before** the shared
638libraries will prevent the linker from considering the incompatible unwinder
639provided by the broken library. libunwind must be linked after other static
640libraries to provide the unwind interface to those static libraries.
Dan Albertd471b922021-03-17 16:52:35 -0700641
642The following link order will protect against incorrectly built dependencies:
Dan Albertdb231382018-09-07 16:33:36 -0700643
644 1. crtbegin
645 2. object files
646 3. static libraries
Dan Albertd471b922021-03-17 16:52:35 -0700647 4. libunwind
Dan Albertdb231382018-09-07 16:33:36 -0700648 5. shared libraries
649 6. crtend
650
651Unless using `-nostdlib` when linking, crtend and crtbegin will be linked
Dan Albertd471b922021-03-17 16:52:35 -0700652automatically by Clang. libunwind can be manually linked with `-lunwind`.
Dan Albertdb231382018-09-07 16:33:36 -0700653
654## Windows Specific Issues
655
656### Command Line Length Limits
657
658Command line length limits on Windows are short enough that they can pose
659problems when building large projects. Commands executed via cmd.exe are limited
660to [8,191 characters] and commands executed with `CreateProcess` are limited to
661[32,768 characters].
662
663To work around these issues, Clang, the linkers, and the archiver all accept a
664response file that specifies the input files in place of specifying each input
665explicitly on the command line. Response files are identified on the command
666line with a "@" prefix and are formatted as space separated arguments. For
667example:
668
669 $ ar crsD liba.a @inputs.rsp
670
671If the contents of `inputs.rsp` are `a.o b.o c.o` then `ar` will insert `a.o`,
672`b.o`, and `c.o` into `liba.a`.
673
674[8,191 characters]: https://support.microsoft.com/en-us/help/830473/command-prompt-cmd-exe-command-line-string-limitation
675[32,768 characters]: https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessa
676
677### Path Length Limits
678
679Windows paths are limited to 260 characters, including the drive letter, colon,
680backslash, and terminating null. See Microsoft's documentation on [path length
681limits] for possible solutions.
682
683[path length limits]: https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file#maximum-path-length-limitation
684
685### Performance Differences
686
687Our experience shows that builds on Windows are generally slower than they are
688on Linux. The cost of `CreateProcess` in comparison to `fork` accounts for much
689of the difference, so it is best to minimize process creation in your build
690system.
691
692File system performance can also make a large difference. This also appears to
693be the reason that Mac, while it has better build performance than Windows,
694still underperforms Linux.
695
696Windows and Mac users will see optimum build performance in a Linux VM.