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