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