GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana cara membuat native (command line) yang dapat dieksekusi untuk dijalankan di Android?

Pada NDK r8d, ini dapat diselesaikan dengan cara yang jauh lebih sederhana.

  1. Buat proyek dengan hierarki direktori berikut:

    project/
        jni/
            Android.mk
            Application.mk
            *.c, *.cpp, *.h, etc.
    
  2. Isi Android.mk dengan konten berikut. Yang paling penting adalah baris terakhir. Periksa dokumen NDK untuk arti variabel lainnya.

    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. Buka project/ direktori, dan cukup ketik

    ndk-build
    

    Hasilnya akan ditempatkan di project/libs/<arch>/name-of-your-executable .


http://www.bekatul.info/content/native-c-application-android [rusak (9 Nov 2015)]
Tautan Wayback Machine

Untuk meringkas artikel...

Kode pengujiannya adalah :

#include  <stdio.h>//for printf
#include  <stdlib.h>//for exit

int main(int argc, char **argv)
{
        int i = 1;
        i+=2;

        printf("Hello, world (i=%d)!\n", i);

        return 0;
        exit(0);
}

Makefile adalah :

APP := test
ROOT := /home/dd/android
INSTALL_DIR := /data/tmp
NDK_PLATFORM_VER := 8

ANDROID_NDK_ROOT := $(ROOT)/android-ndk-r5
ANDROID_NDK_HOST := linux-x86
ANDROID_SDK_ROOT := $(ROOT)/android-sdk-linux_86
PREBUILD := $(ANDROID_NDK_ROOT)/toolchains/arm-eabi-4.4.0/prebuilt/$(ANDROID_NDK_HOST)

BIN := $(PREBUILD)/bin/
LIB := $(ANDROID_NDK_ROOT)/platforms/android-$(NDK_PLATFORM_VER)/arch-arm/usr/lib
INCLUDE := $(ANDROID_NDK_ROOT)/platforms/android-$(NDK_PLATFORM_VER)/arch-arm/usr/include

CC := $(BIN)/arm-eabi-gcc
GDB_CLIENT := $(BIN)/arm-eabi-gdb

LIBCRT := $(LIB)/crtbegin_dynamic.o

LINKER := /system/bin/linker

DEBUG := -g

CFLAGS := $(DEBUG) -fno-short-enums -I$(INCLUDE)
CFLAGS += -Wl,-rpath-link=$(LIB),-dynamic-linker=$(LINKER) -L$(LIB)
CFLAGS += -nostdlib -lc

all: $(APP)

$(APP): $(APP).c
        $(CC) -o [email protected] $< $(CFLAGS) $(LIBCRT)

install: $(APP)
        $(ANDROID_SDK_ROOT)/platform-tools/adb push $(APP) $(INSTALL_DIR)/$(APP) 
        $(ANDROID_SDK_ROOT)/platform-tools/adb shell chmod 777 $(INSTALL_DIR)/$(APP)

shell:
        $(ANDROID_SDK_ROOT)/platform-tools/adb shell

run:
        $(ANDROID_SDK_ROOT)/platform-tools/adb shell $(INSTALL_DIR)/$(APP)

debug-install:
        $(ANDROID_SDK_ROOT)/platform-tools/adb push $(PREBUILD)/../gdbserver $(INSTALL_DIR)/gdbserver
        $(ANDROID_SDK_ROOT)/platform-tools/adb shell chmod 777 $(INSTALL_DIR)/gdbserver

debug-go:
        $(ANDROID_SDK_ROOT)/platform-tools/adb forward tcp:1234: tcp:1234
        $(ANDROID_SDK_ROOT)/platform-tools/adb shell $(INSTALL_DIR)/gdbserver :1234 $(INSTALL_DIR)/$(APP)

debug:
        $(GDB_CLIENT) $(APP)

clean:
        @rm -f $(APP).o $(APP)

Penulis menyimpan file tersebut di komputer linux lokal miliknya di:

/home/dd/android/dev/native/test.c
/home/dd/android/dev/native/Makefile

Penulis kemudian menyusun dan mengujinya dengan:

[email protected]:~/android/dev/native$ make clean; make; make install; make run
/home/dd/android/android-ndk-r5/toolchains/arm-eabi-4.4.0/prebuilt/linux-x86/bin//arm-eabi-gcc -c  -fno-short-enums -I/home/dd/android/android-ndk-r5/platforms/android-9/arch-arm/usr/include test.c -o test.o 
/home/dd/android/android-ndk-r5/toolchains/arm-eabi-4.4.0/prebuilt/linux-x86/bin//arm-eabi-g++ -Wl,--entry=main,-dynamic-linker=/system/bin/linker,-rpath-link=/home/dd/android/android-ndk-r5/platforms/android-9/arch-arm/usr/lib -L/home/dd/android/android-ndk-r5/platforms/android-9/arch-arm/usr/lib -nostdlib -lc -o test test.o
/home/dd/android/android-sdk-linux_86/platform-tools/adb push test /data/tmp/test 
45 KB/s (2545 bytes in 0.054s)
/home/dd/android/android-sdk-linux_86/platform-tools/adb shell chmod 777 /data/tmp/test
/home/dd/android/android-sdk-linux_86/platform-tools/adb shell /data/tmp/test
Hello, world (i=3)!

SDK dan NDK yang digunakan adalah:

source code: /home/dd/android/dev/native
android ndk: /home/dd/android/android-ndk-r5
android sdk: /home/dd/android/android-sdk-linux_86

Namun, panduan debug adalah bagian yang sangat bagus! Salin dan tempel ...

Tetapkan kompilasi untuk mengaktifkan debugging:

DEBUG = -g
CFLAGS := $(DEBUG) -fno-short-enums -I$(ANDROID_NDK_ROOT)/platforms/android-$(NDK_PLATFORM_VER)/arch-arm/usr/include

salin file gdbserver ($(PREBUILD)/../gdbserver) ke emulator, tambahkan target di Makefile agar mudah:

debug-install:
        $(ANDROID_SDK_ROOT)/platform-tools/adb push $(PREBUILD)/../gdbserver $(INSTALL_DIR)/gdbserver
        $(ANDROID_SDK_ROOT)/platform-tools/adb shell chmod 777 $(INSTALL_DIR)/gdbserver

Sekarang kita akan men-debugnya @ port 1234:

debug-go:
        $(ANDROID_SDK_ROOT)/platform-tools/adb forward tcp:1234: tcp:1234
        $(ANDROID_SDK_ROOT)/platform-tools/adb shell $(INSTALL_DIR)/gdbserver :1234 $(INSTALL_DIR)/$(APP)

Kemudian jalankan:

[email protected]:~/android/dev/native$ make clean; make; make install; make debug-install; make debug-go
/home/dd/android/android-ndk-r5/toolchains/arm-eabi-4.4.0/prebuilt/linux-x86/bin//arm-eabi-gcc -c  -g -fno-short-enums -I/home/dd/android/android-ndk-r5/platforms/android-9/arch-arm/usr/include test.c -o test.o 
/home/dd/android/android-ndk-r5/toolchains/arm-eabi-4.4.0/prebuilt/linux-x86/bin//arm-eabi-g++ -Wl,--entry=main,-dynamic-linker=/system/bin/linker,-rpath-link=/home/dd/android/android-ndk-r5/platforms/android-9/arch-arm/usr/lib -L/home/dd/android/android-ndk-r5/platforms/android-9/arch-arm/usr/lib -nostdlib -lc -o test test.o
/home/dd/android/android-sdk-linux_86/platform-tools/adb push test /data/tmp/test 
71 KB/s (3761 bytes in 0.051s)
/home/dd/android/android-sdk-linux_86/platform-tools/adb shell chmod 777 /data/tmp/test
/home/dd/android/android-sdk-linux_86/platform-tools/adb push /home/dd/android/android-ndk-r5/toolchains/arm-eabi-4.4.0/prebuilt/linux-x86/../gdbserver /data/tmp/gdbserver
895 KB/s (118600 bytes in 0.129s)
/home/dd/android/android-sdk-linux_86/platform-tools/adb shell chmod 777 /data/tmp/gdbserver
/home/dd/android/android-sdk-linux_86/platform-tools/adb forward tcp:1234: tcp:1234
/home/dd/android/android-sdk-linux_86/platform-tools/adb shell /data/tmp/gdbserver :1234 /data/tmp/test
Process /data/tmp/test created; pid = 472
Listening on port 1234

Sekarang buka konsol lain dan jalankan debugger:

[email protected]:~/android/dev/native$ make debug
/home/dd/android/android-ndk-r5/toolchains/arm-eabi-4.4.0/prebuilt/linux-x86/bin//arm-eabi-gdb test
GNU gdb 6.6
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "--host=x86_64-linux-gnu --target=arm-elf-linux"...
(gdb) target remote :1234
Remote debugging using :1234
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
0xb0001000 in ?? ()
(gdb) b main
Breakpoint 1 at 0x82fc: file test.c, line 6.
(gdb) c
Continuing.
Error while mapping shared library sections:
/system/bin/linker: No such file or directory.
Error while mapping shared library sections:
libc.so: Success.

Breakpoint 1, main (argc=33512, argv=0x0) at test.c:6
6               int i = 1;
(gdb) n
7               i+=2;
(gdb) p i
$1 = 1
(gdb) n
9               printf("Hello, world (i=%d)!\n", i);
(gdb) p i
$2 = 3
(gdb) c
Continuing.

Program exited normally.
(gdb) quit

Yah tidak apa-apa. Dan konsol lainnya akan memberikan keluaran tambahan seperti:

Remote debugging from host 127.0.0.1
gdb: Unable to get location for thread creation breakpoint: requested event is not supported
Hello, world (i=3)!

Child exited with retcode = 0 

Child exited with status 0
GDBserver exiting

Inilah contoh proyek yang mengikuti jawaban KennyTM. Anda dapat membuatnya dari awal atau memodifikasi proyek lain, misalnya, hello-jni dalam sampel NDK.

jni/main.c:

#include <stdio.h>
int main() {
    printf("hello\n");
    return 0;
}

jni/Application.mk:

#APP_ABI := all
APP_ABI := armeabi-v7a

jni/Android.mk:

LOCAL_PATH := $(call my-dir)

# first target: the hello-jni example
# it shows how to build multiple targets
# {{ you may comment it out
include $(CLEAR_VARS)

LOCAL_MODULE    := hello-jni
LOCAL_SRC_FILES := hello-jni.c
LOCAL_LDLIBS := -llog -L$(LOCAL_PATH)/lib -lmystuff # link to libmystuff.so

include $(BUILD_SHARED_LIBRARY)
#}} you may comment it out


# second target
include $(CLEAR_VARS)

LOCAL_MODULE := hello
LOCAL_SRC_FILES := main.c

include $(BUILD_EXECUTABLE)    # <-- Use this to build an executable.

Saya harus mencatat bahwa Anda tidak akan melihat log apa pun di output stdout, Anda harus menggunakan adb logcat untuk melihatnya.

Jadi jika Anda ingin masuk:

jni/main.c:

#include <stdio.h>
#include <android/log.h>
int main() {
    printf("hello\n");
    __android_log_print(ANDROID_LOG_DEBUG  , "~~~~~~", "log %i", 0); // the 3rd arg is a printf-style format string
    return 0;
}

dan bagian terkait di jni/Android.mk menjadi:

LOCAL_PATH := $(call my-dir)

#...

include $(CLEAR_VARS)

LOCAL_MODULE := hello
LOCAL_SRC_FILES := main.c
LOCAL_LDLIBS := -llog   # no need to specify path for liblog.so

include $(BUILD_EXECUTABLE)    # <-- Use this to build an executable.

Linux
  1. Cara Reboot Linux Menggunakan Command Line

  2. Bagaimana saya bisa menjalankan skrip baris perintah Perl one liner dengan benar?

  3. Bagaimana cara menginstal skrip untuk dijalankan di mana saja dari baris perintah?

  1. Bagaimana cara membuka manajer AVD di Ubuntu Linux dari baris perintah?

  2. Cara menjalankan TeX dari antarmuka baris perintah di Linux

  3. Bagaimana saya bisa menjalankan pemeriksaan nagios secara manual dari baris perintah?

  1. Cara Menjalankan Query MySQL/MariaDB Langsung dari Command Line Linux

  2. Cara Menghapus Riwayat Baris Perintah BASH di Linux

  3. Bagaimana saya bisa menjalankan fungsi dari skrip di baris perintah?