README.md
1This directory contains a number of shell scripts, which we will
2call the "dev-scripts", that are only used to develop the NDK
3itself, i.e. they are not needed when using ndk-build to build
4applicative native code.
5
6Their purpose is to handle various sophisticated issues:
7
8 * Rebuilding host cross-toolchains for our supported CPU ABIs.
9
10 * Rebuilding other required host tools (e.g. ndk-stack) from sources.
11
12 * Rebuilding all target-specific prebuilt binaries from sources (this requires
13 working host cross-toolchains).
14
15 * Packaging final NDK release tarballs, including adding documentation which
16 normally lives in $NDK/../development/ndk.
17
18This document is here to explain how to use these dev-scripts and how everything
19is architected / designed, in case you want to maintain it.
20
21Generally, everything dev-script supports the --help option to display a
22description of the program and the list of all supported options. Also, debug
23traces can be activated by using the --verbose option. Use it several times to
24increase the level of verbosity.
25
26Note that all Windows host programs can be built on Linux if you have the
27`mingw-w64` cross-toolchain installed (`apt-get install mingw-w64` on Debian or
28Ubuntu). You will need to add the `--mingw` option when invoking the script.
29
30All dev-scripts rebuilding host programs on Linux and Darwin will only generate
3132-bit programs by default. You can experiment with 64-bit binary generation by
32adding the `--try-64` option. Note that as of now, 64-bit binaries are never
33distributed as part of official NDK releases.
34
35When building 32-bit Linux host programs, the dev-scripts will look for
36`$ANDROID_BUILD_TOP/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8`,
37which is part of the Android platform source tree. It is a special toolchain
38that ensures that the generated programs can run on old systems like Ubuntu 8.04
39that only have GLibc 2.7. Otherwise, the corresponding binaries may not run due
40to ABI changes in more recent versions of GLibc.
41
42I. Organization:
43================
44
45First, a small description of the NDK's overall directory structure:
46
47build/core
48----------
49
50Contains the main NDK build system used when `ndk-build`. Relies heavily on GNU
51Make 3.81+ but isn't used by any of the scripts described here.
52
53build/tools
54-----------
55
56Contains all the dev-scripts that are described in this document. More on this
57later.
58
59sources/host-tools
60------------------
61
62Contains sources of various libraries or programs that will be compiled to
63generate useful host programs for the final NDK installation. For example,
64$NDK/sources/host-tools/ndk-stack/ contains the sources of the `ndk-stack`
65program.
66
67sources/cxx-stl
68---------------
69
70Contains the sources of various C++ runtime and libraries that can be used with
71`ndk-build`. See docs/CPLUSPLUS-SUPPORT.html for more details.
72
73sources/cxx-stl/gabi++
74----------------------
75
76Contains the sources of the GAbi++ C++ runtime library. Only used via stlport or
77libc++.
78
79sources/cxx-stl/stlport
80-----------------------
81
82Contains the sources of a port of STLport that can be used with `ndk-build`. The
83dev-script `build-cxx-stl.sh` can be used to generate prebuilt libraries from
84these sources, that will be copied under this directory.
85
86sources/cxx-stl/llvm-libc++
87---------------------------
88
89Contains the sources of a port of LLVM's libc++ that can be used with ndk-build.
90The dev-script `build-cxx-stl.sh` can be used to generate prebuilt libraries
91from these sources, that will be copied under this directory.
92
93sources/cxx-stl/gnu-libstdc++
94-----------------------------
95
96This directory doesn't contain sources at all, only an Android.mk. The
97dev-script `build-gnu-libstdc++.sh` is used to generate prebuilt libraries from
98the sources that are located in the toolchain source tree instead.
99
100sources/cxx-stl/system
101----------------------
102
103This directory contains a few headers used to use the native system Android C++
104runtime (with _very_ limited capabilities), a.k.a. /system/lib/libstdc++.so. The
105prebuilt version of this library is generated by the `gen-platform.sh`
106dev-script described later, but it never placed in this directory.
107
108sources/android/libthread\_db
109-----------------------------
110
111This directory contains the sources of the libthread\_db implementation that is
112linked into the prebuilt target gdbserver binary.
113
114sources
115-------
116
117The rest of `sources` is used to store the sources of helper libraries used with
118`ndk-build`. For example, the `cpu-features` helper library is under
119`sources/android/cpu-features`.
120
121$DEVNDK a.k.a $NDK/../development/ndk
122-------------------------------------
123
124This directory contains platform-specific files. The reason why it it is
125separate from $NDK is because it is not primarily developed in the open.
126
127More specifically:
128
129 * All $NDK development happens in the public AOSP repository ndk.git.
130
131 * Any $DEVNDK development that happens in the public AOSP development.git
132 repository is auto-merged to the internal tree maintained by Google.
133
134 * $DEVNDK developments that are specific to an yet-unreleased version of the
135 system happen only in the internal tree. They get back-ported to the public
136 tree only when the corresponding system release is open-sourced.
137
138$DEVNDK/platforms/android-$PLATFORM
139-----------------------------------
140
141Contains all files that are specific to a given API level `$PLATFORM`, that were
142not already defined for the previous API level.
143
144For example, android-3 corresponds to Android 1.5, and android-4 corresponds to
145Android 1.6. The platforms/android-4 directory only contains files that are
146either new or modified, compared to android-3.
147
148$DEVNDK/platforms/android-$PLATFORM/include
149-------------------------------------------
150
151Contains all system headers exposed by the NDK for a given platform. All these
152headers are independent from the CPU architecture of target devices.
153
154$DEVNDK/platforms/android-$PLATFORM/arch-$ARCH
155----------------------------------------------
156
157Contains all files that are specific to a given $PLATFORM level and a specific
158CPU architecture. $ARCH is typically 'arm' or 'x86'
159
160$DEVNDK/platforms/android-$PLATFORM/arch-$ARCH/include
161------------------------------------------------------
162
163Contains all the architecture-specific headers for a given API level.
164
165$DEVNDK/platforms/android-$PLATFORM/arch-$ARCH/lib
166--------------------------------------------------
167
168Contains several CPU-specific object files and static libraries that are
169required to build the host cross-toolchains properly.
170
171Before NDK r7, this also contains prebuilt system shared libraries that had been
172hand-picked from various platform builds. These have been replaced by symbol
173list files instead (see below).
174
175$DEVNDK/platforms/android-$PLATFORM/arch-$ARCH/symbols
176------------------------------------------------------
177
178Contains, for each system shared library exposed by the NDK, two files
179describing the dynamic symbols it exports, for example, for the C library:
180
181 libc.so.functions.txt -> list of exported function names
182 libc.so.variables.txt -> list of exported variable names
183
184These files were introduced in NDK r7 and are used to generate stub shared
185libraries that can be used by ndk-build at link time. These shared libraries
186contain the same symbols that make the NDK ABI for the given version, but do not
187function.
188
189These files can be generated from a given platform build using the
190`dev-platform-import.sh` dev-script, described later in this document.
191
192This is handy to compare which symbols were added between platform releases (and
193check that nothing disappeared).
194
195$NDK/platforms
196--------------
197
198Not to be confused with $DEVNDK/platforms/, this directory is not part of the
199NDK git directory (and is specifically listed in $NDK/.gitignore) but of its final
200installation.
201
202Its purpose is to hold the fully expanded platform-specific files. This means
203that, unlike $DEVNDK/platforms/android-$PLATFORM, the
204$NDK/platforms/android-$PLATFORM will contain _all_ the files that are specific
205to API level $PLATFORM.
206
207Moreover, the directory is organized slightly differently, i.e. as toolchain
208sysroot, i.e. for each supported $PLATFORM and $ARCH values, it provides two
209directories:
210
211 $NDK/platforms/android-$PLATFORM/arch-$ARCH/usr/include
212 $NDK/platforms/android-$PLATFORM/arch-$ARCH/usr/lib
213
214Notice the `usr` subdirectory here. It is required by GCC to be able to use the
215directories with --with-sysroot. For example, to generate binaries that target
216API level 5 for the arm architecture, one would use:
217
218 $TOOLCHAIN_PREFIX-gcc --with-sysroot=$NDK/platforms/android-5/arch-arm
219
220Where `$TOOLCHAIN_PREFIX` depends on the exact toolchain being used.
221
222The dev-script `gen-platforms.sh` is used to populate $NDK/platforms. Note that
223by default, the script does more, see its detailed description below.
224
225II. Host toolchains:
226====================
227
228The host toolchains are the compiler, linker, debugger and other crucial
229programs used to generate machine code for the target Android system supported
230by the NDK.
231
232II.1 Getting the toolchain sources:
233-----------------------------------
234
235The AOSP toolchain/ repository contains the source for the toolchains used to
236build the Android platform and in the NDK.
237
238The master-ndk branch of AOSP contains an already checked out and patched
239version of the toolchain repository at toolchain/. The old process of using
240download-toolchain-sources.sh is now obsolete.
241
242The toolchains binaries are typically placed under the directory
243$NDK/toolchains/$NAME/prebuilt, where $NAME is the toolchain name's full name
244(e.g. arm-linux-androideabi-4.8).
245
246I.2. Building the toolchains:
247-----------------------------
248
249First you will need to build a proper "sysroot" directory before being able to
250configure/build them.
251
252A sysroot is a directory containing system headers and libraries that the
253compiler will use to build a few required target-specific binaries (e.g.
254libgcc.a)
255
256To do that, use:
257
258 $NDK/build/tools/gen-platforms.sh --minimal
259
260This will populate $NDK/platforms/ with just the files necessary to rebuild the
261toolchains. Note that without the --minimal option, the script will fail without
262prebuilt toolchain binaries.
263
264Once the sysroots are in place, use `build-gcc.sh` by providing the path to the
265toolchain sources root directory, a destination NDK installation directory to
266build, and the full toolchain name.
267
268For example, to rebuild the arm and x86 prebuilt toolchain binaries in the
269current NDK directory (which can be handy if you want to later use them to
270rebuild other target prebuilts or run tests), do:
271
272 $NDK/build/tools/build-gcc.sh /tmp/ndk-$USER/src $NDK \
273 arm-linux-androideabi-4.8
274 $NDK/build/tools/build-gcc.sh /tmp/ndk-$USER/src $NDK x86-4.8
275
276Here, we assume you're using the master-ndk branch as described in the previous
277section.
278
279This operation can take some time. The script automatically performs a parallel
280build to speed up the build on multi-core machine (use the -j<number> option to
281control this), but the GCC sources are very large, so expect to wait a few
282minutes.
283
284For the record, on a 2.4 GHz Xeon with 16 Hyper-threaded cores and 12GB of
285memory, rebuilding each toolchain takes between 2 and 4 minutes.
286
287You need to be on Linux to build the Windows binaries, using the "mingw-w64"
288cross-toolchain (install it with "apt-get install mingw-w64" on Ubuntu). To do
289so use the "--mingw" option, as in:
290
291 $NDK/build/tools/build-gcc.sh --mingw \
292 /tmp/ndk-$USER/src $NDK arm-linux-androideabi-4.8
293
294 $NDK/build/tools/build-gcc.sh --mingw \
295 /tmp/ndk-$USER/src $NDK x86-4.8
296
297The corresponding binaries are installed under $NDK/toolchains/$NAME/prebuilt.
298Note that these are native Windows programs, not Cygwin ones.
299
300Building the Windows toolchains under MSys and Cygwin is completely unsupported
301and highly un-recommended: even if it works, it will probably take several
302hours, even on a powerful machine :-(
303
304The Darwin binaries must be generated on a Darwin machine. Note that the script
305will try to use the 10.5 XCode SDK if it is installed on your system. This
306ensures that the generated binaries run on Leopard, even if you're building on a
307more recent version of the system.
308
309Once you've completed your builds, you should be able to generate the other
310target-specific prebuilts.
311
312III. Target-specific prebuilt binaries:
313=======================================
314
315A final NDK installation comes with a lot of various target-specific prebuilt
316binaries that must be generated from sources once you have working host
317toolchains.
318
319III.1.: Preparation of platform sysroots:
320-----------------------------------------
321
322Each target prebuilt is handled by a specific dev-script. HOWEVER, all these
323script require that you generate a fully populated $NDK/platforms/ directory
324first. To do that, simply run:
325
326 $NDK/gen-platforms.sh
327
328Note that we used this script with the --minimal option to generate the host
329toolchains. That's because without this flag, the script will also auto-generate
330tiny versions of the system shared libraries that will be used at link-time when
331building our target prebuilts.
332
333III.2.: Generation of gdbserver:
334---------------------------------
335
336A target-specific `gdbserver` binary is required. This is a small program that
337is run on the device through `ndk-gdb` during debugging. For a variety of
338technical reasons, it must be copied into a debuggable project's output
339directory when `ndk-build` is called.
340
341The prebuilt binary is placed under $NDK/gdbserver/$ARCH in the final NDK
342installation. You can generate them with `build-gdbserver.py`.
343
344
345III.3. Generating C++ runtime prebuilt binaries:
346-----------------------------------------------
347
348Sources and support files for several C++ runtimes / standard libraries are
349provided under $NDK/sources/cxx-stl/. Several dev-scripts are provided to
350rebuild their binaries. The scripts place them to their respective location
351(e.g. the libc++ binaries will go to $NDK/sources/cxx-stl/llvm-libc++/libs/)
352unless you use the --out-dir=<path> option.
353
354Note that:
355
356 * Each script will generate the binaries for all the CPU ABIs supported by the
357 NDK, e.g. armeabi, armeabi-v7a, x86 and mips. You can restrict them using the
358 --abis=<list> option though.
359
360 - The GNU libstdc++ dev-script requires the path to the toolchain sources,
361 since this is where the library's sources are located.
362
363An example usage would be:
364
365 $NDK/build/tools/build-cxx-stl.sh --stl=stlport
366 $NDK/build/tools/build-cxx-stl.sh --stl=libc++
367 $NDK/build/tools/build-gnu-libstdc++.sh /tmp/ndk-$USER/src
368
369Note that generating the STLport and GNU libstdc++ binaries can take a few
370minutes. You can follow the build by using the --verbose option to display
371what's going on.
372
373IV. Other host prebuilt binaries:
374=================================
375
376There are a few other host prebuilt binaries that are needed for a full NDK
377installation. Their sources are typically installed under
378$NDK/sources/host-tools/
379
380Note that the corresponding dev-script recognize the --mingw and --try-64
381options described at the end of section I above.
382
383IV.1.: Building `ndk-stack`:
384---------------------------
385
386The `build-ndk-stack.sh` script can be used to rebuild the `ndk-stack` helper
387host program. See docs/NDK-STACK.html for a usage description. To build it,
388just do:
389
390 $NDK/build/tools/build-ndk-stack.sh
391
392IV.2.: Building `ndk-depends`:
393-----------------------------
394
395Similar to `ndk-stack`, see the `build-ndk-depends.sh` script.
396
397V. Packaging all prebuilts:
398===========================
399
400Generating all the prebuilt binaries takes a lot of time and is no fun. To
401avoid doing it again and again, it is useful to place all the generated files
402aside in special tarballs.
403
404Most dev-scripts generating them typically support a --package-dir=<path> option
405to do this, where <path> points to a directory that will store compressed
406tarballs of the generated binaries.
407
408For example, to build and package the libc++ binaries, use:
409
410 $NDK/build/tools/build-cxx-stl.sh --stl=libc++ \
411 --package-dir=/tmp/ndk-$USER/prebuilt/
412
413This will actually create one tarball per supported ABI in
414`$ANDROID_BUILD_TOP/out/ndk`, i.e.:
415
416 * libcxx-libs-armeabi.tar.bz2
417 * libcxx-libs-armeabi-v7a.tar.bz2
418 * libcxx-libs-x86.tar.bz2
419 * ...
420
421Note that these tarballs are built to be uncompressed from the top-level of an
422existing NDK install tree.
423
424Similarly, to rebuild the STLport binaries and package them:
425
426 $NDK/build/tools/build-cxx-stl.sh --stl=stlport \
427 --package-dir=/tmp/ndk-$USER/prebuilt
428
429The `rebuilt-all-prebuilt.sh` script has been entirely replaced by checkbuild.py
430in the root of the NDK. Note that by default, it will automatically place the
431prebuilt tarballs under `$ANDROID_BUILD_TOP/out/ndk`.
432
433By default, this only rebuilds the host prebuilts for the current host system.
434You can use `--system windows` or `--system windows64` to build Windows binaries
435on Linux.
436
437Once you have used the script three times (once per supported host systems), you
438should have plenty of files under /tmp/ndk-$USER/prebuilt-$DATE. For the
439record, with NDK r7, the list was:
440
441VI. Packaging NDK releases:
442===========================
443
444Use the `package-release.sh` dev-script to generate full NDK release packages.
445These contain everything needed by a typical NDK user, including:
446
447 * All prebuilt binaries (host toolchains, host tools, target libs, etc...).
448 * All documentation.
449
450You need to have a directory containing prebuilt tarballs, as described in the
451previous section. You can use it as:
452
453 $NDK/build/tools/package-release.sh \
454 --release=<name> \
455 --systems=<list> \
456 --arch=<list> \
457 --prebuilt-dir=<path>
458
459The --release option is optional and allows you to provide a name for your
460generated NDK archive. More specifically, the archive file name will be
461something like android-ndk-$RELEASE-$SYSTEM.tar.bz2, where $RELEASE is the
462release name, and $SYSTEM the supported host system (e.g. linux-x86).
463
464By default, i.e. without the option, $RELEASE will be set to the current $DATE.
465
466The --systems=<list> is optional, but can be used to limit the number of host
467systems you want to generate for. <list> must be a comma-separated list of
468system names (from `linux-x86`, `windows` and `darwin-x86`). This is useful if
469you're working on a experimental feature and don't have the time to regenerate
470the host toolchains for all systems. It allows you to generate an experimental
471package that you can distribute to third-party for experimentation.
472
473By default, i.e. without the option, the scripts tries to build NDK archives for
474all supported host systems.
475
476The --arch=<list> is also optional, but can be used to limit the number of
477target architectures you want to generate for. <list> must be a comma-separated
478list of CPU architectures (e.g. from `arm` and `x86`). Without the option, this
479will try to build packages that support all architectures.
480
481Finally, --prebuilt-dir=<path> must point to the directory that contains the
482prebuilt tarballs described in section V. Following our previous example, one
483could use --prebuilt-dir=/tmp/ndk-$USER/prebuilt here.
484
485VI. Testing:
486============
487
488The $NDK/tests directory contains a number of NDK unit-tests that can be used to
489verify that the generated NDK packages or the working NDK tree still behave
490correctly.
491
492If you have an NDK package archive, you can run the following to run the test
493suite against it:
494
495 $NDK/tests/run-tests.sh --package=<ndk-archive>
496
497This will uncompress the NDK archive in a temporary directory, then run all the
498tests with it. When all tests have run, the temporary directory is removed
499automatically.
500
501You can also point to an existing NDK installation with --ndk=<path>, as in:
502
503 $NDK/tests/run-tests.sh --ndk=<path>
504
505Where <path> points to another NDK installation. The script will run the test
506suite present under $NDK/tests/, not the one in the remote NDK directory.
507
508If you don't use any option, the test suite will be run with the current NDK
509directory. This can only work if you have generated or unpacked all prebuilt
510archives into it before that.
511
512You can get more traces from the tests by using --verbose. Use it twice to see
513even more traces.
514
515There are several kinds of tests:
516
517 * 'build tests' are used to test the building capabilities of the NDK.
518 I.e. the tests will only use them to check that the NDK build system
519 didn't regress. The corresponding generated binaries are never used
520 otherwise.
521
522 * 'device tests' are used to test both the build and the behaviour of
523 the generated code. If the `adb` program is in your path, and have
524 one device or emulator connected to your host machine, `run-tests.sh`
525 will automatically upload, run and cleanup these tests for you.
526
527 If adb is not in your path, or no device is connected, run-tests.sh
528 will simply print a warning and carry on.
529
530
531Whenever you add a feature to the NDK, or fix a bug, it is recommended to add a
532unit test to check the feature or the fix. Use $NDK/tests/build for build tests,
533and $NDK/tests/device for device tests.
534