How to compile C into an executable binary file and run it in Android from Android Shell?
First, let me say that my answer is dependent on your using NDK r7b (it'll work for r7c as well) on Linux (change paths appropriately for other systems).
Edit: Last tested with NDK r8e
on Linux and Nexus 4
with adb
from SDK Platform-Tools Rev 18
on Windows 7 (latest as of 2013-07-25) without root access.
Yet Another Edit: Please read this question for altering my instruction for native binaries that need to run on Android 5.0(Lollypop) and later.
- Go to
$NDK_ROOT
(The topmost folder of NDK zip when unzipped). - Copy
$NDK_ROOT/samples/hello-jni
directory as$NDK_ROOT/sources/hello-world
. - Go to
$NDK_ROOT/sources/hello-world
. - Edit
AndroidManifest.xml
to give the application an appropriate name (This is optional). - Go to
$NDK_ROOT/sources/hello-world/jni
. This is where the source code is. - Edit
hello-jni.c
, remove all the code, and put in yourhello world
code. Mine is:#include int main( int argc, char* argv[]){ printf("Hello, World!"); return 0;}
- Edit
Android.mk
and change the lineinclude $(BUILD_SHARED_LIBRARY)
toinclude $(BUILD_EXECUTABLE)
. You can also change theLOCAL_MODULE
line to the name you want for your executable(default ishello-jni
) - Go back to
$NDK_ROOT/sources/hello-world
- Run
../../ndk-build
to create the executable. - Copy it from
$NDK_ROOT/sources/hello-jni/libs/armeabi/hello-jni
to/data/local/tmp
on the Android device and change it's permissions to 755 (rwxr-xr-x). If you changed theLOCAL_MODULE
line in$NDK_ROOT/sources/hello-world/jni/Android.mk
, the executable name will be the new value ofLOCAL_MODULE
instead ofhello-jni
. (All this is done viaadb
from the Android SDK.) - Execute the binary with full path as
/data/local/tmp/hello-jni
, or whatever you named it to.
And you're done( and free to start on the documentation in $NDK_ROOT/docs to get a better idea of what to do).
The best/easiest place to put a executable is /data/local. You'll also need to chmod the binary as executable. Often you'll also need to do this in two steps to get the binary from /sdcard/
to /data/local
:
$ adb push mybin /sdcard/$ adb shell$ cp /sdcard/mybin /data/local/mybin$ cd /data/local$ chmod 751 mybin
Caveats:
Not all systems have
cp
. You can use cat if this is the case:$ cat /sdcard/mybin > /data/local/mybin
Some systems don't allow write in
/data/local
for the "shell" user. Try/data/local/tmp
the "/sdcard" location is not executable, meaning that any file there is not executable at all.
the only way to "adb push" executable would be to put them in "/data/local", which should be writable for adb, and allow execution for anyone.