不然你要我怎么样

彪悍的代码不需要注释

Archive for the ‘Android’ Category

使用gdb在Android Emulator中进行调试c程序

8 comments

参考文章:Debug Native c/c++ Application for Android(Step by Step)

Google Android Debugging Utilities

首先,我们需要一个含有调试信息的exe文件,一般这个文件存在于out/target/product/generic/obj/EXECUTABLES/yourexefile_intermediates/LINKED/libomstts目录下,这里以我们前面文章中生成的helloworld为例。

1. 下载Android Debugging Utilities

gdb and gdb-server (6.8)

2. 启动Android Emulator模拟器

$ emulator @1.5_R2

3. 把gdb和调试文件以及源代码放到模拟器上

$ adb push gdb /data/bin

$ adb push helloworld /data/bin

以helloworld为例,源代码要放在/data/bin/development/hello目录下。

有的文章说将以上文件放在/system/bin目录下,但后果是一旦关掉模拟器,这些的文件就消失了,下次又要重传~所以推荐放在/data/bin目录下。

4. 启动shell

$adb shell

如果提示文件系统不可写的话,执行:

#mount -o remount

5. 因为Android文件系统没有/bin/sh, 所以这里有两种解决方法(推荐第二种方法):

(1). 拷贝一个bash文件(点击下载)到/bin目录下:

#mkdir /bin

$adb push bash /bin

(2). 或者设置SHELL的路径:

#export SHELL=/system/bin/sh

6. 进入/data/bin目录,运行gdb,可以开始调试程序了

#cd /data/bin

#./gdb helloworld

转载请注明: 转载自不然你要我怎么样
本文链接地址: 使用gdb在Android Emulator中进行调试c程序

Written by xiangmocheng

六月 14th, 2009 at 9:42 下午

Posted in Android

Tagged with ,

【转贴】Android编译环境(2) – 手工编译C模块

leave a comment

原文点击这里

——————————————-

Android编译环境提供了”showcommands”选项来显示编译命令行,我们可以通过打开这个选项来查看一些编译时的细节。当然,在这之前要把上一篇中的helloworld模块clean:

# make clean-helloworld

上面的“make clean-$(LOCAL_MODULE)”是Android编译环境提供的make clean的方式。

接下来使用showcommands选项重新编译helloworld:

# make helloworld showcommands

build/core/product_config.mk:229: WARNING: adding test OTA key

target thumb C: helloworld <= development/hello/hello.c

prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-gcc  -I system/core/include   -I hardware/libhardware/include   -I hardware/ril/include   -I dalvik/libnativehelper/include   -I frameworks/base/include   -I external/skia/include   -I out/target/product/generic/obj/include   -I bionic/libc/arch-arm/include   -I bionic/libc/include   -I bionic/libstdc++/include   -I bionic/libc/kernel/common   -I bionic/libc/kernel/arch-arm   -I bionic/libm/include   -I bionic/libm/include/arch/arm   -I bionic/libthread_db/include   -I development/hello   -I out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates  -c  -fno-exceptions
-Wno-multichar -march=armv5te -mtune=xscale -msoft-float -fpic
-mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector
-D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__
-include system/core/include/arch/linux-arm/AndroidConfig.h -DANDROID
-fmessage-length=0 -W -Wall -Wno-unused -DSK_RELEASE -DNDEBUG -O2 -g
-Wstrict-aliasing=2 -finline-functions
-fno-inline-functions-called-once -fgcse-after-reload
-frerun-cse-after-loop -frename-registers -DNDEBUG -UDEBUG -mthumb -Os
-fomit-frame-pointer -fno-strict-aliasing -finline-limit=64      -MD -o out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/hello.o development/hello/hello.c

target Executable: helloworld (out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld)

prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-g++
-nostdlib -Bdynamic -Wl,-T,build/core/armelf.x
-Wl,-dynamic-linker,/system/bin/linker -Wl,–gc-sections
-Wl,-z,nocopyreloc -o
out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld
-Lout/target/product/generic/obj/lib
-Wl,-rpath-link=out/target/product/generic/obj/lib -lc -lstdc++ -lm  out/target/product/generic/obj/lib/crtbegin_dynamic.o         out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/hello.o       -Wl,–no-undefined
prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/interwork/libgcc.a
out/target/product/generic/obj/lib/crtend_android.o

target Non-prelinked: helloworld (out/target/product/generic/symbols/system/bin/helloworld)

out/host/linux-x86/bin/acp
-fpt
out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld
out/target/product/generic/symbols/system/bin/helloworld

target Strip: helloworld (out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/helloworld)

out/host/linux-x86/bin/soslim
–strip –shady –quiet
out/target/product/generic/symbols/system/bin/helloworld –outfile
out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/helloworld

Install: out/target/product/generic/system/bin/helloworld

out/host/linux-x86/bin/acp
-fpt
out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/helloworld
out/target/product/generic/system/bin/helloworld

从上面的命令行可以看到,Android编译环境所用的交叉编译工具链是prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-gcc,-I和-L参数指定了所用的C库头文件和动态库文件路径分别是bionic/libc/include 和out/target/product/generic/obj/lib,其他还包括很多编译选项以及-D所定义的预编译宏。

我们可以利用上面的编译命令,稍加简化来手工编译helloworld程序。先手工删除上次编译得到的helloworld程序:

# rm out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/hello.o

# rm out/target/product/generic/system/bin/helloworld

再用gcc编译,生成目标文件:

#
prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-gcc -I
bionic/libc/arch-arm/include -I bionic/libc/include -I
bionic/libc/kernel/common   -I bionic/libc/kernel/arch-arm -c  -fno-exceptions
-Wno-multichar -march=armv5te -mtune=xscale -msoft-float -fpic
-mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector
-D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__
-include system/core/include/arch/linux-arm/AndroidConfig.h -DANDROID
-fmessage-length=0 -W -Wall -Wno-unused -DSK_RELEASE -DNDEBUG -O2 -g
-Wstrict-aliasing=2 -finline-functions
-fno-inline-functions-called-once -fgcse-after-reload
-frerun-cse-after-loop -frename-registers -DNDEBUG -UDEBUG -mthumb -Os
-fomit-frame-pointer -fno-strict-aliasing -finline-limit=64      -MD -o out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/hello.o development/hello/hello.c

与Android.mk编译参数比较,上面主要减少了不必要的-I参数。

接下来生成可执行文件:

#
prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-gcc -nostdlib
-Bdynamic -Wl,-T,build/core/armelf.x
-Wl,-dynamic-linker,/system/bin/linker -Wl,–gc-sections
-Wl,-z,nocopyreloc -o
out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld
-Lout/target/product/generic/obj/lib
-Wl,-rpath-link=out/target/product/generic/obj/lib -lc -lm  out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/hello.o
out/target/product/generic/obj/lib/crtbegin_dynamic.o
-Wl,–no-undefined
./prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/interwork/libgcc.a
out/target/product/generic/obj/lib/crtend_android.o

这里值得留意的是参数“-Wl,-dynamic-linker,/system/bin/linker”,它指定了Android专用的动态链接器/system/bin/linker,而不是通常所用的ld.so。

生成的可执行程序可用file和readelf命令来查看一下:

# file out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld

out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld:
ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked
(uses shared libs), not stripped

#  readelf -d out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld |grep NEEDED

0×00000001 (NEEDED)                     Shared library: [libc.so]

0×00000001 (NEEDED)                     Shared library: [libm.so]

这是ARM格式的动态链接可执行文件,运行时需要libc.so和libm.so。“not stripped”表示它还没被STRIP。嵌入式系统中为节省空间通常将编译完成的可执行文件或动态库进行STRIP,即去掉其中多余的符号表信息。在前面“make helloworld showcommands”命令的最后我们也可以看到,Android编译环境中使用了out/host/linux-x86/bin/soslim工具进行STRIP。

有关Android Toolchain的其他一些内容可参考:Android Toolchain与Bionic Libc

转载请注明: 转载自不然你要我怎么样
本文链接地址: 【转贴】Android编译环境(2) – 手工编译C模块

Written by xiangmocheng

六月 14th, 2009 at 8:51 下午

Posted in Android

Tagged with ,

【转贴】Android编译环境(1) – 编译Native C的helloworld模块

one comment

原文点击这里

———————————————————

Android 编译环境本身比较复杂,且不像普通的编译环境:只有顶层目录下才有Makefile文件,而其他的每个component都使用统一标准的 Android.mk. Android.mk文件本身是比较简单的,不过它并不是我们熟悉的Makefile,而是经过了Android自身编译系统的很多处理,因此要真正理清楚其中的联系还比较复杂,不过这种方式的好处在于,编写一个新的Android.mk来给Android增加一个新的Component会比较简单。编译Java程序可以直接采用Eclipse的集成环境来完成,这里就不重复了。我们主要针对C/C++来说明,下面通过一个小例子来说明,如何在Android 中增加一个C程序的Hello World:

1. 在$(YOUR_ANDROID)/development目录下创建hello目录,其中$(YOUR_ANDROID)指Android源代码所在的目录。

$ mkdir $(YOUR_ANDROID)/development/hello

2. 在$(YOUR_ANDROID)/development/hello/目录编写hello.c文件,hello.c的内容当然就是经典的HelloWorld程序:

int main()
{
printf("Hello World!\n");
return 0;
}

3.在$(YOUR_ANDROID)/development/hello/目录编写Android.mk文件。这是Android Makefile的标准命名,不要更改。Android.mk文件的格式和内容可以参考其他已有的Android.mk文件的写法,针对helloworld程序的Android.mk文件内容如下:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
hello.c

LOCAL_MODULE := helloworld
include $(BUILD_EXECUTABLE)

注意上面LOCAL_SRC_FILES用来指定源文件,LOCAL_MODULE指定要编译的模块的名字,下一步骤编译时就要用到。include $(BUILD_EXECUTABLE)表示要编译成一个可执行文件,如果想编译成动态库则可用BUILD_SHARED_LIBRARY,这些可以在$(YOUR_ANDROID)/build/core/config.mk查到。

4. 回到Android源代码顶层目录进行编译:

# cd $(YOUR_ANDROID) && make helloworld

注意make helloworld中的目标名helloworld就是上面Android.mk文件中由LOCAL_MODULE指定的模块名。编译结果如下:

target thumb C: helloworld <= development/hello/hello.c
target Executable: helloworld (out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld)
target Non-prelinked: helloworld (out/target/product/generic/symbols/system/bin/helloworld)
target Strip: helloworld (out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/helloworld)
Install: out/target/product/generic/system/bin/helloworld

5.如上面的编译结果所示,编译后的可执行文件存放在out/target/product/generic/system/bin/helloworld,通过”adb push”将它传送到模拟器上,再通过”adb shell”登录到模拟器终端,就可以执行了

转载请注明: 转载自不然你要我怎么样
本文链接地址: 【转贴】Android编译环境(1) – 编译Native C的helloworld模块

Written by xiangmocheng

六月 14th, 2009 at 8:37 下午

Posted in Android

Tagged with ,