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