Build executable file with Android NDK after Lollipop (Android API 21)

I’ll introduce more functionality of Android NDK continuing from Android NDK set up introduction. Android NDK is not only a tool to build up .so library to call through JNI, but it is also possible to build executable file itself. It is achieved by just changing Android.mk configuration. 

Below is example implementation to build hello-exe file.

1. Write Native (C/C++ language) source code

Make “hello-exe” folder anywhere and inside this folder make “jni” folder. Place “hello-exe.c” in “jni” folder and write following. So we have a folder construction like hello-exe/jni/hello-exe.c.

#include <stdio.h>

int main(int argc, char ** argv){
	printf("Hello world from NDK executable!\n");
	return 0;
}

For this tutorial, it is enough for native source code implementation 🙂

2-1. Build configuration by Android.mk (Before Android L)

Write Android.mk as following in side “jni” folder. The last line, “include $(BUILD_EXECUTABLE)“, is the key for building executable file.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE     := hello-exe
LOCAL_SRC_FILES  := hello-exe.c

include $(BUILD_EXECUTABLE)

However, when I try this code with Android Lollipop device, it was failed with the error 

error: only position independent executables (PIE) are supported

It seems that new security feature added from Android L cause this problem.

2-2. Build configuration by Android.mk (Before Android L)
       – Enable Position Independent Executables –

Instead of 2-1, write jni/Android.mk as following.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# Enable PIE manually. Will get reset on $(CLEAR_VARS). This
# is what enabling PIE translates to behind the scenes.
LOCAL_CFLAGS += -fPIE
LOCAL_LDFLAGS += -fPIE -pie

LOCAL_MODULE     := hello-exe-with-pie
LOCAL_SRC_FILES  := hello-exe.c

include $(BUILD_EXECUTABLE)

3. Build

Open command prompt at “hello-exe” folder and execute ndk-build command. You can get the result like below.

D:\workspace\eclipse\ndk\hello-exe>ndk-build
[armeabi] Compile thumb  : hello-exe-with-pie <= hello-exe.c
[armeabi] Executable     : hello-exe-with-pie
[armeabi] Install        : hello-exe-with-pie => libs/armeabi/hello-exe-with-pie

Now “libs” and “obj” folders are automatically created in the same folder hierarchy with “jni” folder. Executable file is found at “hello-exe/libs/armeabi/hello-exe-with-pie”

4. Run

To execute you need to push executable file to Android device,

D:\workspace\eclipse\ndk\hello-exe>adb push libs\armeabi\hello-exe-with-pie /data/local/tmp/
1839 KB/s (9420 bytes in 0.005s)

Followed by execute at Android device. Be careful about execute permission.

D:\workspace\eclipse\ndk\hello-exe>adb shell
$ cd /data/local/tmp
$ chmod 777 ./hello-exe-with-pie
$ ./hello-exe-with-pie
Hello world from NDK executable!

One very useful usage is to execute device handling interactively. For example, high-performance consecutive sendevent command is introduced in here.

Reference

Leave a Comment

Your email address will not be published. Required fields are marked *