I spent some time trying to figure out how to build a native code “Hello, world!” program for Android and noticed that prior to the r4b release of the Android NDK, there is a lot of bad info out there on how to do this. Usually, it involves using some kind of unofficial cross-compiler, plus the entire source tree of the Android OS, and/or whatever other kludgy hacks like linking the executable statically to some kind of ARM libc. This seems bad. With the newest version of the NDK generating a proper gdbserver executable and gdb setup stubs, why anyone would want to do this by hand is beyond me.
There was a script that made sense at one point: agcc.pl (here), which essentially takes all of the Makefile fragments and command-line switches and wraps them for you, letting you treat the NDK’s cross-compilers almost like a normal gcc, but this is probably still more work than it’s worth.
The Easy Way
The easiest way to get the NDK to build a native executable for you is just to use
1 include $(BUILD_EXECUTABLE)
at the end of your Android.mk, and then build like normal.
Anything else will just cause premature baldness.
Read on to see a fully-worked example…
hello-exe.c
1
2
3
4
5
6
|
#include
int main(int argc, char ** argv)
{
printf("Hello, world!n");
return 0;
}
|
Android.mk
1
2
3
4
5
6
7
8
|
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-exe
LOCAL_SRC_FILES := hello-exe.c
include $(BUILD_EXECUTABLE)
|
Example build + install output (it really is that easy)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
vilimpoc@funky ~
$ cd ~/android-ndk-r4b/samples/hello-exe
vilimpoc@funky ~/android-ndk-r4b/samples/hello-exe
$ ls
jni
vilimpoc@funky ~/android-ndk-r4b/samples/hello-exe
$ ~/android-ndk-r4b/ndk-build -B
Compile thumb : hello-exe <= /home/vilimpoc/android-ndk-r4b/samples/hello-exe/jni/hello-exe.c
Executable : hello-exe
Install : hello-exe => /home/vilimpoc/android-ndk-r4b/samples/hello-exe/libs/armeabi
vilimpoc@funky ~/android-ndk-r4b/samples/hello-exe
$ ls
jni libs obj
vilimpoc@funky ~/android-ndk-r4b/samples/hello-exe
$ cd libs/armeabi
vilimpoc@funky ~/android-ndk-r4b/samples/hello-exe/libs/armeabi
$ ls
hello-exe
vilimpoc@funky ~/android-ndk-r4b/samples/hello-exe/libs/armeabi
$ adb devices
List of devices attached
emulator-5554 device
vilimpoc@funky ~/android-ndk-r4b/samples/hello-exe/libs/armeabi
$ adb -e shell
# mkdir /data/data/hello-exe
# ls /data/data/hello-exe
# exit
vilimpoc@funky ~/android-ndk-r4b/samples/hello-exe/libs/armeabi
$ adb -e push hello-exe /data/data/hello-exe/hello-exe
427 KB/s (0 bytes in 13670.000s)
vilimpoc@funky ~/android-ndk-r4b/samples/hello-exe/libs/armeabi
$ adb -e shell
# cd /data/data/hello-exe
# ls -l
-rw-rw-rw- root root 13670 2010-09-23 12:37 hello-exe
# chmod 777 ./hello-exe
# ls -l
-rwxrwxrwx root root 13670 2010-09-23 12:37 hello-exe
# ./hello-exe
Hello, world!
#
# exit
vilimpoc@funky ~/android-ndk-r4b/samples/hello-exe/libs/armeabi
$
|
Helpful blog, bookmarked the website with hopes to read more!
I see that NDK5 now has the ability to create a standalone tool chain which can be easily used with a makefile. I’m a bit confused though why they did this vs your solution in this article for NDK4?
Tom
Beats me. I also don’t know why they haven’t included a sample project showing how to debug things, considering the amount of dev time that gets wasted on figuring this out.
Bookmarked !
Very helpful. Keep up the good work.
oh, very helpful, thank you…
if you use NDKr5, you should edit build/core/build-binary.mk:322, not build/core/install-binary.mk:29
dude, this is great!!!
wonderfull ! thanks. tested ok w/ ndk r6b on ubuntu/x86 (just a minor issue for me with the prototype of main()).
Thanks a lot!
This puzzled me much time!
Thank you. Worked with NDKr7 on Mac OSX Snow Leopard. I had wasted a lot of time screwing with Makefile. This ‘just works’ the first time.
Very helpful. Good Job….
Great stuff !! Thanks for this post. I didn’t know compiling a native binary was that easy on Android.
Very useful .. Thanks a lot
Two years late…
Your include for stdio.h got truncated to only “#include”… Probably because the blog doesn’t like the brackets.
Cheers,
Anne
you are the man! I spent so much time trying to link the right libraries and compile. You saved me
Dear Max,
I have one question,
I followed your instruction and created the executable as ‘hello-exe’.
I can see the output over adb-shell as shown by you, but could not able to see the same output over adb device(emulator) which is running.
1. Do we have to do so some configuration in emulator to see the output of executable? If yes please explain..
Thanks,
Akhilesh
I think the difference is the executable output is on stdout which is tied to the adb-shell console. So you’re not going to see this in the graphical emulator window. adb-shell is connected to the emulator.