GNU/Linux >> Linux の 問題 >  >> Linux

Android で実行するネイティブ (コマンドライン) 実行可能ファイルをビルドするにはどうすればよいですか?

NDK r8d の時点で、これははるかに簡単な方法で解決できます。

<オール>
  • 次のディレクトリ階層でプロジェクトを作成します:

    project/
        jni/
            Android.mk
            Application.mk
            *.c, *.cpp, *.h, etc.
    
  • Android.mk に次の内容を入力します。最も重要なのは最後の行です。他の変数の意味については、NDK のドキュメントを確認してください。

    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.
    
  • project/ に移動します ディレクトリに移動し、入力するだけです

    ndk-build
    

    結果は project/libs/<arch>/name-of-your-executable に配置されます .


  • http://www.bekatul.info/content/native-c-application-android [壊れた (2015 年 11 月 9 日)]
    Wayback Machine リンク

    記事を要約すると...

    テスト コードは次のとおりです:

    #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);
    }
    

    メイクファイルは次のとおりです:

    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)
    

    作成者はこれらのファイルを自分のローカル Linux コンピュータに保存しました:

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

    次に、著者はそれをコンパイルしてテストしました:

    [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 と NDK は次のとおりです:

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

    しかし、デバッグガイドは本当に良い部分でした!コピーして貼り付け ...

    コンパイルを設定してデバッグを有効にします:

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

    gdbserver ファイル ($(PREBUILD)/../gdbserver) をエミュレーターにコピーし、簡単にするために Makefile にターゲットを追加します。

    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
    

    次に、@ ポート 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)
    

    次に実行します:

    [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
    

    他のコンソールを開き、デバッガーを実行します:

    [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
    

    まあ大丈夫です。そして、他のコンソールは次のような追加の出力を提供します:

    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
    

    これは、KennyTM の回答に従うプロジェクトの例です。ゼロから作成することも、別のプロジェクトを変更することもできます (例:hello-jni)。 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.
    

    stdout 出力にログが表示されないことに注意する必要があります。 adb logcat を使用する必要があります。

    ロギングが必要な場合:

    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;
    }
    

    および jni/Android.mk の対応するセクション になります:

    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. 変数に格納されているコマンドを実行するにはどうすればよいですか?

    2. コマンドラインを使用してLinuxを再起動する方法

    3. Perl ワンライナー コマンド ライン スクリプトを正しく実行するにはどうすればよいですか?

    1. コマンド ラインから任意の場所で実行するスクリプトをインストールするにはどうすればよいですか?

    2. コマンドラインでスクリプトから関数を実行するにはどうすればよいですか?

    3. Linux:特定のディレクトリでコマンドを実行する方法

    1. Linuxコマンドラインから直接MySQL/MariaDBクエリを実行する方法

    2. Linux でコマンドライン インターフェイスから TeX を実行する方法

    3. コマンドラインからnagiosチェックを手動で実行するにはどうすればよいですか?