What's the use of LLVM in Android NDK Toolchains?
LLVM is the compiler (backend). The compiler used is Clang, which resides within the llvm directory. (LLVM is the name of the component of Clang that does the actual code generation, aka backend.)
Previously, the NDK used GCC as compiler. With GCC, each target architecture (arm, aarch64, x86 etc) had a separate copy of GCC built with that individual target configured. Clang/LLVM on the other hand can target any configured architecture with one single compiler executable. So with Clang, you'll save a bit of diskspace, avoiding to have many separate compiler executables. That's why there's only one copy of the llvm directory tree.
In NDK r17, you have both GCC and Clang compilers available; Clang is used by default but GCC is still available for projects that haven't been able to migrate to using Clang yet. In newer NDK versions, the old GCC is removed.
In the newer NDK versions, even if GCC is removed, the architecture specific directories like aarch64-linux-android-4.9
are still kept around, as the GNU binutils (minor tools used by the build process) are still used, and those also come in one copy per architecture (even though they technically might work across architectures).
And as for why building for e.g. arm also mentions x86_64; when you are running Clang or GCC, you are running an executable for your build computer which runs x86_64, hence the prebuilt/linux-x86_64
part of the paths.
LLVM is an umbrela project now, and it contains multiple modular and reusable compiler and toolchain technologies. You can check more details at The LLVM Compiler Infrastructure.
For Android NDK, llvm became the default toolchain since r13b and gcc was removed since r18b.
According to toolchains directory toolchains/llvm/prebuilt/darwin-x86_64
, llvm supports all the ABIs, i.e. x86, x86_64, arm, arm64.
Probably there will be only one llvm
directory under toolchains
directory in future NDK releases when all the gcc related tools, headers and libs are completely ported to llvm.
References that may help: Android NDK path variable for "strip" command in CMake build tool chain
Updates
Just did a quick test on different NDK revisions to check the configurations for --gcc-toolchain
and --sysroot
which are for cross compilation.
On r16b
--target=armv7-none-linux-androideabi
--gcc-toolchain=~/ndks/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
--sysroot=~/ndks/android-ndk-r16b/sysroot
On r17c
--target=armv7-none-linux-androideabi
--gcc-toolchain=~/ndks/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
--sysroot=~/ndks/android-ndk-r17c/sysroot
On r18b
--target=armv7-none-linux-androideabi19
--gcc-toolchain=~/ndks/android-ndk-r18b/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
--sysroot=~/ndks/android-ndk-r18b/sysroot
On r19b
--target=armv7-none-linux-androideabi19
--gcc-toolchain=~/ndks/android-ndk-r19b/toolchains/llvm/prebuilt/darwin-x86_64
--sysroot=~/ndks/android-ndk-r19b/toolchains/llvm/prebuilt/darwin-x86_64/sysroot
As seen above, before NDK r19b, NDK uses clang compiler but the --gcc-toolchain
and --sysroot
are configured as the older paths for build tools, headers and libs.
But, since NDK r19b, the --gcc-toolchain
and --sysroot
are configured as the new tool chains llvm, i.e. toolchains/llvm/prebuilt/darwin-x86_64
, and the tools (e.g. ranlib, ar, strip, etc) header files and libraries of "llvm version" will be used.
Also, note that toolchains/llvm/prebuilt/darwin-x86_64
contains the support for all the Android ABIs, i.e. aarch64-linux-android
for arm64-v8a, arm-linux-androideabi
for armeabi-v7a, i686-linux-android
for x86, x86_64-linux-android
for x86_64.
So, you can try out the NDK r19b if you want to purely use llvm toolchains.