Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tell Android NDK to use a different toolchain

Tags:

I've downloaded a custom toolchain (linaro) to build ARM based Android apps. How do I tell the NDK to use it? Can I define or set something in Android.mk and Application.mk that would allow me to do that? Is there another way?

like image 654
Phonon Avatar asked Jul 07 '11 17:07

Phonon


People also ask

What is NDK Sysroot?

$NDK/sysroot is the unified headers and is what you should be using when compiling. When linking, you should still be using $NDK/platforms/android-$API/arch-$ARCH . We do have a doc explaining how to use unified headers in a custom build system: android.googlesource.com/platform/ndk/+/master/docs/….

What compiler does Android NDK use?

Code written in C/C++ can be compiled to ARM, or x86 native code (or their 64-bit variants) using the Android Native Development Kit (NDK). The NDK uses the Clang compiler to compile C/C++. GCC was included until NDK r17, but removed in r18 in 2018.

How do I set local property NDK?

Select the menu File > Project Structure > SDK Location , Android NDK Location if it is not set yet, then click ... , and browse to your NDK location and click "OK" (you may also choose "download").


2 Answers

The NDK makefile system is quite extensible and you can indeed define a different toolchain. You'll need some understanding of how Make works.

Toolchains are discovered and initialized in build/core/init.mk line 261 (in NDKr6, the line # may change in future versions). The initialization code looks for files named config.mk under $(NDK_ROOT)/toolchains/*. So you'll need to add your toolchain in a subdirectory under the NDK toolchains directory, and add a config.mk and setup.mk to that subdirectory. Look at toolchains/x86-4.4.3 and toolchains/arm-linux-androideabi-4.4.3 for examples. You should be able to cut and paste the ARM toolchain config.mk and setup.mk if your toolchain has a standard layout.

Once you've defined a toolchain in the toolchain directory, you can switch to it by setting the NDK_TOOLCHAIN variable inside your Application.mk file.

like image 130
Ian Ni-Lewis Avatar answered Dec 18 '22 00:12

Ian Ni-Lewis


As the other answer mentions, toolchains are discovered by ndk-build makefile system in $(NDK_ROOT)/toolchains/ and you can mirror ideas you see there. But there are a few extra concepts for supporting non-Android target platforms that are interesting although they may be soon outdated as ndk-build starts to explicitly support other platforms, such as mingw targeting win32 (or other gcc compilers targeting plain 'ol linux).

In config.mk:

TOOLCHAIN_ABIS := (list of ABIs that the toolchain supports) 

This is an important definition, because you can use this name in your Application.mk to build using the toolchain for a particular ABI. One of the benefits of corrupting the usage of this definition, is that ndk-build can simultaneously build for multiple ABIs. It always assumes that the platform is Android, but if you want to target win32 using a mingw based toolchain, you can define an "ABI" as x86-win32, and then use this ABI in your Application.mk to select it as an additional target via APP_ABI:= x86-win32 Then in your Android.mk files you can use the TARGET_ARCH_ABI definition to select win32 specific sources and include paths, for example:

ifeq ($(TARGET_ARCH_ABI),x86-win32)   LOCAL_SRC_FILES += my_win32_file.c   LOCAL_CFLAGS += -DSOME_WIN32_SPECIFIC endif 

The final piece is that in setup.mk for your toolchain, it may be insufficient to look at other toolchains as examples, because what setup.mk for a particular toolchain really does is override build settings in default-build-commands.mk, so what you want to do is inspect that file, and redefine things in it that you don't like.

Following the previous example, mingw does not support the noexec flag in the binaries, and you can get rid of this feature by adding the following lines in your setup.mk:

# These flags are used to enforce the NX (no execute) security feature in the # generated machine code. This adds a special section to the generated shared # libraries that instruct the Linux kernel to disable code execution from # the stack and the heap. TARGET_NO_EXECUTE_CFLAGS  := # our platform doesn't support this flag! TARGET_NO_EXECUTE_LDFLAGS := # our platform doesn't support this flag!  # These flags disable the above security feature TARGET_DISABLE_NO_EXECUTE_CFLAGS  :=  # our platform doesn't support this flag! TARGET_DISABLE_NO_EXECUTE_LDFLAGS :=  # our platform doesn't support this flag! 

This is just one example of the many features in default-build-commands.mk that may need to be overridden, and of course it's important to provide TOOLCHAIN_NAME so that the toolchain can be selected via NDK_TOOLCHAIN variable inside your Application.mk file in addition to the ABI methodology I mention above.

like image 41
Peter M Avatar answered Dec 18 '22 01:12

Peter M