Want to compile native Android binary I can run in terminal on the phone
Just use the android-ndk. And build a Android.mk like so.include $(BUILD_EXECUTABLE)
is what tells it build a executable instead of a JNI .lib
Android.mk
ifneq ($(TARGET_SIMULATOR),true)
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS += -Wall
LOCAL_LDLIBS := -L$(LOCAL_PATH)/lib -llog -g
LOCAL_C_INCLUDES := bionic
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_SRC_FILES:= main.cpp
LOCAL_MODULE := mycmd
include $(BUILD_EXECUTABLE)
endif # TARGET_SIMULATOR != true
Can I use printf in an Android native binary
#include <stdio.h>
int main() {
printf("Hello, world\n");
return 0;
}
Then:
~/Library/Android/sdk/ndk/24.0.8215888/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang --target=aarch64-linux-android21 helloworld.c -o helloworld
adb push helloworld /data/local/tmp/helloworld
adb shell /data/local/tmp/helloworld
How to build an executable for Android shell
The answer provides a sequence of steps for building an executable for Android shell
through both Eclipse
(outdated) and Android Studio
(4.1+ by the time of this writing). The last includes ndk-build
and CMake
.
I. PREPARE SOURCE CODE
As an example consider mycommand.c
:
#include <stdio.h>
int main()
{
printf("My Command!\n");
return 0;
}
II. BUILD EXECUTABLE
Eclipse (might be outdated)
In assumption that NDK
location is set in Eclipse
, create a new Android Application Project
and do the following steps.
Add native support. Right click on the project in
Project Explorer
>Android Tools
>Add Native Support
>Finish
Add source code, i.e. put
mycommand.c
underproject_root
/jni
folder.Edit
Android.mk
underproject_root
/jni
as follows:LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mycommand
LOCAL_SRC_FILES := mycommand.c
include $(BUILD_EXECUTABLE)Create
Application.mk
* under theproject_root
/jni
folder:APP_ABI := all
Build executable and find it under
project_root/libs/<abi>/mycommand
.
*Binaries for all
supported CPU architectures are generated here. Use adb shell cat /proc/cpuinfo
to find out the CPU architecture and set APP_ABI
as per Supported ABIs.
Android Studio and ndk-build
The steps are as follows.
Add
mycommand.c
,Android.mk
(same as in theEclipse
section above) to the/app/src/main/cpp
folder.Edit
build.gradle
:android {
...
defaultConfig {
...
externalNativeBuild {
ndkBuild {
targets "mycommand"
// use a specific ABI filter if needed
// abiFilters "armeabi-v7a"
}
}
}
externalNativeBuild {
ndkBuild {
path "src/main/cpp/Android.mk"
}
}
}Build project and find the executable under
/app/.externalNativeBuild/ndkBuild/debug/obj/local/<abi>/mycommand
Android Studio and CMake
Create a project using the Native C++ template.
Add
mycommand.c
to the/app/src/main/cpp
folder and editCMakeLists.txt
:cmake_minimum_required(VERSION x.x.x)
add_executable(mycommand
mycommand.c )Edit
build.gradle
:android {
...
defaultConfig {
...
externalNativeBuild {
cmake {
targets "mycommand"
// use a specific ABI filter if needed
// abiFilters "armeabi-v7a"
}
}
}
...
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
}
}
}Build project and find the executable under
/app/build/intermediates/cmake/debug/obj/<abi>/mycommand
III. PUSH BINARY INTO DEVICE
Push mycommand
binary from where it is located into your device. Keep in mind that files on SD card aren't executable by default, so the binary should be pushed into the device's internal storage. Depending of whether device is rooted or not you have the following options:
On non-rooted device you can push the binary to
/data/local/tmp
:adb push mycommand /data/local/tmp
On rooted device you can push the binary to SD card and then copy it to
/system/bin
(after remounting the partition in read-write mode) along with the other executable files:adb push mycommand /path/to/sdcard
adb shell
su
mount -o rw,remount /system
cp /path/to/sdcard/mycommand /system/bin
IV. SET EXECUTABLE PERMISSION (optional)
Set the permission of the binary to be executable (this might not be needed in case of /data/local/tmp
). Below chmod 555
(r-xr-xr-x) is used:
adb shell chmod 555 /path/to/mycommand
V. RUN COMMAND
Now you can shell into your device (with adb shell
) and execute the command.
On non-rooted device use the absolute path to the command:
$ /data/local/tmp/mycommand
My Command!On rooted device, in case the binary has been copied to
/system/bin
, you can call it by the file name:$ mycommand
My Command!
How do I build a native (command line) executable to run on Android?
As of NDK r8d, this can be solved in a much simpler way.
Create a project with the following directory hierarchy:
project/
jni/
Android.mk
Application.mk
*.c, *.cpp, *.h, etc.Fill in Android.mk with the following content. The most important thing is the last line. Check the NDK doc for the meaning of the other variables.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := name-of-your-executable
LOCAL_SRC_FILES := a.cpp b.cpp c.cpp etc.cpp
LOCAL_CPPFLAGS := -std=gnu++0x -Wall -fPIE # whatever g++ flags you like
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog -fPIE -pie # whatever ld flags you like
include $(BUILD_EXECUTABLE) # <-- Use this to build an executable.Go to the
project/
directory, and simply typendk-build
The result will be placed in
project/libs/<arch>/name-of-your-executable
.
I need root permissions to execute a native application under Android?
No, you don't need to root a device to use executable binaries. You cannot put it on /sdcard but on most devices there is a directory /data/tmp or /data/local/tmp where you can push files with adb and execute with adb shell.
The robust option is to package an executable in an APK and get it on device by installing the APK, see Is it possible to run a native arm binary on a non-rooted android phone? or How to package native commandline application in apk?.
Note that you cannot change the LD_LIBRARY_PATH, so be careful if your executable depends on some shared libs that are not part of /system/lib.
Related Topics
How to Store Image Retrieved from Url in a SQLite Database
Using Intent.Action_Pick for Specific Path
Listview Items Are Not Clickable. Why
Checking My App Version Programmatically in Android Market
Android 3.1.1 - Failed Resolution Of: Lcom/Google/Android/Gms/Common/Internal/Zzbq;
Android: How to Change the Datepicker View Date Format from Mm/Dd/Yyyy to Dd/Mm/Yyyy
Http Post Method Passing Null Values to the Server
What's the Purpose of Item-Id's in Android Listview Adapter
What Is the Real World Accuracy of Phone Accelerometers When Used for Positioning
Retrieve Contact Phone Number from Uri in Android
Broadcast Receiver Not Working in Ics If the App Is Not Started Atleast Once
How to Change Images on Imageview After Some Interval
Android Emulator Not Receiving Push Notifications
Android - Margins Specified in Custom Style Not Taking Effect
How to Give Notifications on Android on Specific Time