如何构建一个本机(命令行)可执行程序运行在Android上?

时间:2022-07-22 20:22:59

I've had success with building an Android app (GUI) that uses a native (JNI) library.

我成功地构建了一个使用本地(JNI)库的Android应用程序(GUI)。

However, now I would like to create an executable that runs from the command line (root privileges) and does not use a GUI at all. How do I build something like that?

但是,现在我想创建一个从命令行(root特权)运行的可执行文件,并且根本不使用GUI。我该怎么做呢?

4 个解决方案

#1


25  

As of NDK r8d, this can be solved in a much simpler way.

在NDK r8d中,可以用更简单的方法解决这个问题。

  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.

    填写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.
    
  3. Go to the project/ directory, and simply type

    转到项目/目录,然后简单地键入。

    ndk-build
    

    The result will be placed in project/libs/<arch>/name-of-your-executable.

    结果将被放置在项目/libs/ /名称-你的可执行文件中。

#2


20  

http://www.bekatul.info/content/native-c-application-android [broken (Nov 9, 2015)]

http://www.bekatul.info/content/natic -application-android [broken(2015年11月9日)]

To summarize the article...

总结这篇文章……

The test code is :

测试代码为:

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

The Makefile is :

Makefile是:

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 $@ $< $(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)

The author stored those files on his/hers local linux computer at:

作者将这些文件存储在他/她的本地linux计算机上:

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

The author then compiled and tested it with:

作者随后对其进行了编译和测试:

dd@abil:~/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 and NDK used were:

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

However, the debug guide was the really good part ! Copy and pasted ...

但是,调试指南是非常好的部分!复制和粘贴……

Set the compile for enable debugging:

为启用调试设置编译:

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

copy the gdbserver file ($(PREBUILD)/../gdbserver) to the emulator, add the target in Makefile than to make it easy:

复制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

Now we will debug it @ port 1234:

现在我们将调试它@端口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)

Then execute it:

然后执行它:

dd@abil:~/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

Now open other console and execute the debugger:

现在打开其他控制台并执行调试器:

dd@abil:~/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

Well it is ok. And the other console will give additional output like so:

这是可以的。另一个控制台会提供额外的输出:

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

#3


4  

Here's an example project that follows the KennyTM's answer. You can create it from scratch or modify another project, for example, hello-jni in the NDK samples.

下面是一个遵循KennyTM答案的示例项目。您可以从头创建或修改另一个项目,例如NDK示例中的hello-jni。

jni/main.c:

jni / c:

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

jni/Application.mk:

jni / Application.mk:

#APP_ABI := all
APP_ABI := armeabi-v7a

jni/Android.mk:

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.

I have to note that you will not see any logging in the stdout output, you will have to use adb logcat to see it.

我必须注意到,您将不会看到stdout输出中的任何日志记录,您将不得不使用adb logcat来查看它。

So if you want logging:

所以如果你想登录:

jni/main.c:

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

and the corresponding section in jni/Android.mk becomes:

以及jni/Android中的相应部分。可就变成:

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.

#4


3  

As I do not have 50 reputation I can not comment on Someone Somewhere's answer, so I do it here as an answer.

因为我没有50个名声,所以我不能对某人的答案发表评论,所以我在这里做一个回答。

I would like to quote an error/misprecision : as far as gdbserver is concerned, the adb command

我想引用一个错误/错误:就gdbserver而言,adb命令。

$(ANDROID_SDK_ROOT)/platform-tools/adb push $(PREBUILD)/../gdbserver $(INSTALL_DIR)/gdbserver

will never be able to work, for obvious reasons, because "between" directories $(PREBUILD) and gdbserver, there is the directory android-arm. It is better to set

由于显而易见的原因,由于“between”目录$(PREBUILD)和gdbserver之间的“between”目录,将永远无法工作。最好设置一下。

PREBUILDDEBUG=$(ANDROID_NDK_ROOT)/prebuilt/android-arm

and to replace the former command by

替换原来的命令。

$(ANDROID_SDK_ROOT)/platform-tools/adb push $(PREBUILDDEBUG)/gdbserver $(INSTALL_DIR)/gdbserver

With this everything works for me with an android virtual device. (No segmentation fault apparentlty.) On my real device, I do have a segmentation fault. That was the

这一切都为我提供了一个android虚拟设备。(没有apparentlty分割错误。)在我的真实设备上,我有一个分割错误。这是

make run

part. With respect to debug part, be it on emulator or on real device, I always get a "cannot access memory" when I do the

部分。在调试部分,无论是在模拟器上还是在实际设备上,当我做的时候,我总是会得到一个“无法访问内存”。

b main

in gdb mode... Any idea ? Help would be greatly appreciated.

在gdb模式……任何想法?非常感谢您的帮助。

#1


25  

As of NDK r8d, this can be solved in a much simpler way.

在NDK r8d中,可以用更简单的方法解决这个问题。

  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.

    填写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.
    
  3. Go to the project/ directory, and simply type

    转到项目/目录,然后简单地键入。

    ndk-build
    

    The result will be placed in project/libs/<arch>/name-of-your-executable.

    结果将被放置在项目/libs/ /名称-你的可执行文件中。

#2


20  

http://www.bekatul.info/content/native-c-application-android [broken (Nov 9, 2015)]

http://www.bekatul.info/content/natic -application-android [broken(2015年11月9日)]

To summarize the article...

总结这篇文章……

The test code is :

测试代码为:

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

The Makefile is :

Makefile是:

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 $@ $< $(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)

The author stored those files on his/hers local linux computer at:

作者将这些文件存储在他/她的本地linux计算机上:

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

The author then compiled and tested it with:

作者随后对其进行了编译和测试:

dd@abil:~/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 and NDK used were:

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

However, the debug guide was the really good part ! Copy and pasted ...

但是,调试指南是非常好的部分!复制和粘贴……

Set the compile for enable debugging:

为启用调试设置编译:

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

copy the gdbserver file ($(PREBUILD)/../gdbserver) to the emulator, add the target in Makefile than to make it easy:

复制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

Now we will debug it @ port 1234:

现在我们将调试它@端口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)

Then execute it:

然后执行它:

dd@abil:~/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

Now open other console and execute the debugger:

现在打开其他控制台并执行调试器:

dd@abil:~/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

Well it is ok. And the other console will give additional output like so:

这是可以的。另一个控制台会提供额外的输出:

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

#3


4  

Here's an example project that follows the KennyTM's answer. You can create it from scratch or modify another project, for example, hello-jni in the NDK samples.

下面是一个遵循KennyTM答案的示例项目。您可以从头创建或修改另一个项目,例如NDK示例中的hello-jni。

jni/main.c:

jni / c:

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

jni/Application.mk:

jni / Application.mk:

#APP_ABI := all
APP_ABI := armeabi-v7a

jni/Android.mk:

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.

I have to note that you will not see any logging in the stdout output, you will have to use adb logcat to see it.

我必须注意到,您将不会看到stdout输出中的任何日志记录,您将不得不使用adb logcat来查看它。

So if you want logging:

所以如果你想登录:

jni/main.c:

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

and the corresponding section in jni/Android.mk becomes:

以及jni/Android中的相应部分。可就变成:

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.

#4


3  

As I do not have 50 reputation I can not comment on Someone Somewhere's answer, so I do it here as an answer.

因为我没有50个名声,所以我不能对某人的答案发表评论,所以我在这里做一个回答。

I would like to quote an error/misprecision : as far as gdbserver is concerned, the adb command

我想引用一个错误/错误:就gdbserver而言,adb命令。

$(ANDROID_SDK_ROOT)/platform-tools/adb push $(PREBUILD)/../gdbserver $(INSTALL_DIR)/gdbserver

will never be able to work, for obvious reasons, because "between" directories $(PREBUILD) and gdbserver, there is the directory android-arm. It is better to set

由于显而易见的原因,由于“between”目录$(PREBUILD)和gdbserver之间的“between”目录,将永远无法工作。最好设置一下。

PREBUILDDEBUG=$(ANDROID_NDK_ROOT)/prebuilt/android-arm

and to replace the former command by

替换原来的命令。

$(ANDROID_SDK_ROOT)/platform-tools/adb push $(PREBUILDDEBUG)/gdbserver $(INSTALL_DIR)/gdbserver

With this everything works for me with an android virtual device. (No segmentation fault apparentlty.) On my real device, I do have a segmentation fault. That was the

这一切都为我提供了一个android虚拟设备。(没有apparentlty分割错误。)在我的真实设备上,我有一个分割错误。这是

make run

part. With respect to debug part, be it on emulator or on real device, I always get a "cannot access memory" when I do the

部分。在调试部分,无论是在模拟器上还是在实际设备上,当我做的时候,我总是会得到一个“无法访问内存”。

b main

in gdb mode... Any idea ? Help would be greatly appreciated.

在gdb模式……任何想法?非常感谢您的帮助。