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