Want to Compile Native Android Binary I Can Run in Terminal on the Phone

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:

  1. ~/Library/Android/sdk/ndk/24.0.8215888/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang --target=aarch64-linux-android21 helloworld.c -o helloworld
  2. adb push helloworld /data/local/tmp/helloworld
  3. 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.

  1. Add native support. Right click on the project in Project Explorer > Android Tools > Add Native Support > Finish

  2. Add source code, i.e. put mycommand.c under project_root/jni folder.

  3. Edit Android.mk under project_root/jni as follows:

    LOCAL_PATH := $(call my-dir)

    include $(CLEAR_VARS)

    LOCAL_MODULE := mycommand
    LOCAL_SRC_FILES := mycommand.c

    include $(BUILD_EXECUTABLE)
  4. Create Application.mk * under the project_root/jni folder:

    APP_ABI := all
  5. 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.

  1. Add mycommand.c, Android.mk (same as in the Eclipse section above) to the /app/src/main/cpp folder.

  2. 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"
    }
    }
    }
  3. Build project and find the executable under /app/.externalNativeBuild/ndkBuild/debug/obj/local/<abi>/mycommand



Android Studio and CMake

  1. Create a project using the Native C++ template.

  2. Add mycommand.c to the /app/src/main/cpp folder and edit CMakeLists.txt:

    cmake_minimum_required(VERSION x.x.x)

    add_executable(mycommand
    mycommand.c )
  3. 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"
    }
    }
    }
  4. 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.

  1. Create a project with the following directory hierarchy:

    project/
    jni/
    Android.mk
    Application.mk
    *.c, *.cpp, *.h, etc.
  2. 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.
  3. Go to the project/ directory, and simply type

    ndk-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



Leave a reply



Submit