BruceFan's Blog

Stay hungry, stay foolish

0%

gcc手动编译Android原生程序

编译原生程序:

  • 使用gcc编译器写makefile文件手动编译
  • 使用ndk-build工具自动编译

工具

path_to/android-ndk-r10c/toolchains/arm-linux-androideabi-4.9/prebuilt/ darwin-x86_64/bin目录下保存着完整的工具链:
arm-linux-androideabi-g++ C++编译工具
arm-linux-androideabi-gcc C编译工具
arm-linux-androideabi-gdb 调试工具
arm-linux-androideabi-ld 链接器,用于生成可执行程序
arm-linux-androideabi-nm 列出目标文件中的符号
arm-linux-androideabi-objdump 输出目标文件的信息
arm-linux-androideabi-readelf 显示elf格式可执行文件信息
arm-linux-androideabi-size 列出目标文件每一段的大小
arm-linux-androideabi-strings 列出目标文件的可打印字符串
arm-linux-androideabi-strip 去除目标文件中的符号信息

编写简单的C程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
static int encrypt()
{
int i = 0;
char plaintext[128] = "abcdefg";
printf("in encrypt!");
return i;
}
int main()
{
encrypt();
return 1;
}

编写makefile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CC = arm-linux-androideabi-gcc
ANDROID_NDK=/Users/fan/Computer/Android/adt-bundle-mac-x86_64-20140702/android-ndk-r10c
NDK_TOOLS=$(ANDROID_NDK)/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin
TOOLCHAINS_INCLUDE=$(ANDROID_NDK)/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/lib/gcc/arm-linux-androideabi/4.9/include-fixed
PLATFORM_INCLUDE=$(ANDROID_NDK)/platforms/android-21/arch-arm/usr/include
PLATFORM_LIB=$(ANDROID_NDK)/platforms/android-21/arch-arm/usr/lib
FLAGS=-I$(TOOLCHAINS_INCLUDE) \
-I$(PLATFORM_INCLUDE) \
-L$(PLATFORM_LIB) \
-fPIC \
-shared \
-llog

test: test.o
$(CC) test.o $(FLAGS) -o test
test.o: test.c
$(CC) -c test.c $(FLAGS) -o test.o

主要是ANDROID_NDK NDK_TOOLS TOOLCHAINS_INCLUDE PLATFORM_INCLUDE PLATFORM_LIB几个变量的定义。
makefile的基本用法可以看我前面写过的这篇文章

1
2
3
4
5
6
$ make
arm-linux-androideabi-gcc hook1.o -I/Users/fan/Computer/Android/adt-bundle-mac-x86_64-20140702/android-ndk-r10c/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/lib/gcc/arm-linux-androideabi/4.9/include-fixed -I/Users/fan/Computer/Android/adt-bundle-mac-x86_64-20140702/android-ndk-r10c/platforms/android-21/arch-arm/usr/include -L/Users/fan/Computer/Android/adt-bundle-mac-x86_64-20140702/android-ndk-r10c/platforms/android-21/arch-arm/usr/lib -fPIC -shared -llog -o hook1
/Users/fan/Computer/Android/adt-bundle-mac-x86_64-20140702/android-ndk-r10c/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9/../../../../arm-linux-androideabi/bin/ld: error: cannot open crtbegin_so.o: No such file or directory
/Users/fan/Computer/Android/adt-bundle-mac-x86_64-20140702/android-ndk-r10c/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9/../../../../arm-linux-androideabi/bin/ld: error: cannot open crtend_so.o: No such file or directory
collect2: error: ld returned 1 exit status
make: *** [hook1] Error 1

我在Mac下编译出现这个错误,解决方法:

1
2
3
$ cd /Users/fan/Computer/Android/adt-bundle-mac-x86_64-20140702/android-ndk-r10c/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/lib/gcc/arm-linux-androideabi/4.9
$ cp crtbegin.o crtbegin_so.o
$ cp crtend.o crtend_so.o

再编译就能成功生成elf文件了,与ndk-build生成的elf文件的不同是没有去掉符号表。