Android的底层是纯粹的linux内核,可以简单的理解为上面跑了个Dalvik Java虚拟机而
已。因此,构建android上C/C++的交叉编译环境也就成为了一个很大的需求。特别是对于已经取得root权限的机器,如果能直接运行按需编译的二进制文件,那么将可以做很多有意义和有趣的事情。

  很不幸,Google没有直接给出如何建立这个交叉编译环境,但是我们可以借助Google提供的强大的NDK (Native Development Tools)来达到这一目的。NDK的本来目标是编译得到.so动态链接库文件,然后通过JNI提供给上层的Java调用,从而实现C/C++程序的简易迁移。而编译.so和编译成二进制可执行文件的过程是完全一样的,这就给了我们可以发挥的空间。

  有两种方式获取交叉编译所需的工具链:git下prebuilt这个project或者直接去下载NDK,我这里arm-eabi的版本是最新的4.4.0。

1



git clone git://android.git.kernel.org/platform/prebuilt.git

  然后创建一个helloworld.c文件。

1
2
3
4
5
6



//// [email protected]:~/android/myapp# cat helloworld.c
#include <stdio.h>
int main() {
printf("HelloWorld!n");
return 0;
}

  接下来创建Makefile文件。注意修改其中的NDK_DIR和SDKTOOL为自己的目录,修改APP为自己的待编译程序主文件名。另外注意自己的arm-eabi的版本,若有变化则也需要修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58



#### [email protected]:~/android/myapp# cat Makefile
APP=helloworld

NDK_DIR := ~/android/android-ndk-r4
NDK_HOST := linux-x86
SDKTOOL := ~/android/android-sdk-linux_86/tools

TOOLCHAIN_PREFIX := $(NDK_DIR)/build/prebuilt/$(NDK_HOST)/arm-eabi-4.4.0/bin/arm-eabi-
CC := $(TOOLCHAIN_PREFIX)gcc
CPP := $(TOOLCHAIN_PREFIX)g++
LD := $(CC)

COMMON_FLAGS := -mandroid -ffunction-sections -fdata-sections -Os -g
--sysroot=$(NDK_DIR)/build/platforms/android-5/arch-arm
-fPIC
-fvisibility=hidden
-D__NEW__

CFLAGS := $(COMMON_FLAGS)

CFLAGS += -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -DANDROID -DSK_RELEASE -DNDEBUG

CFLAGS += -UDEBUG -march=armv5te -mtune=xscale -msoft-float -mthumb-interwork -fpic -ffunction-sections -funwind-tables -fstack-protector -fmessage-length=0 -Bdynamic

CPPFLAGS := $(COMMON_FLAGS)
-fno-rtti -fno-exceptions
-fvisibility-inlines-hidden

LDFLAGS += --sysroot=$(NDK_DIR)/build/platforms/android-5/arch-arm
LDFLAGS += -Bdynamic -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,nocopyreloc
LDFLAGS += -L$(NDK_DIR)/build/prebuilt/$(NDK_HOST)/arm-eabi-4.4.0/lib/gcc/arm-eabi/4.4.0
LDFLAGS += -L$(NDK_DIR)/build/prebuilt/$(NDK_HOST)/arm-eabi-4.4.0/lib/gcc
LDFLAGS += -L$(NDK_DIR)/build/prebuilt/$(NDK_HOST)/arm-eabi-4.4.0/arm-eabi/lib
LDFLAGS += -nostdlib -lc -llog -lgcc
--no-undefined -z $(NDK_DIR)/build/platforms/android-5/arch-arm/usr/lib/crtbegin_dynamic.o $(NDK_DIR)/build/platforms/android-5/arch-arm/usr/lib/crtend_android.o

OBJS += $(APP).o

all: $(APP)

$(APP): $(OBJS)
$(LD) $(LDFLAGS) -o [email protected] $^

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

%.o: %.cpp
$(CPP) -c $(CFLAGS) $(CPPFLAGS) $< -o [email protected]

install: $(APP)
$(SDKTOOL)/adb push $(APP) /data/local/bin/$(APP)
$(SDKTOOL)/adb shell chmod 755 /data/local/bin/$(APP)

run:
$(SDKTOOL)/adb shell /data/local/bin/$(APP)

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

  最后直接make,然后make install进手机里看一下吧。通过adb shell和手机里的Terminal等软件执行的结果是一样的。

toolchain

  后记:还有一个叫Codesourcery的工具链,下载下来有130多M,我使用它来编译helloworld时无误但是放到手机上则运行不起来。不想细究了,我认为NDK提供的工具链已经非常优秀。感兴趣的朋友可以自己试试Codesourcery。

更多相关文章

  1. Android遍历本地视频文件加过滤
  2. Android生成pdf文件之PdfDocument及踩过的坑
  3. Android(Java):jni写文件打印调试信息
  4. Android UI用户界面开发辅助工具(值得一试)
  5. Android配置----DDMS 连接真机(己ROOT),用file explore看不到data/
  6. 浅析Android下的Android.mk文件
  7. 在Android下创建文件夹
  8. 关于Android SDK工具Lint的误报:Class referenced in the manifes
  9. Android Launcher开发(一)LiveFolder(实时文件夹) 完全解析

随机推荐

  1. AlarmManagerService(一)
  2. 移植android ndk c++各种兼容性问题
  3. 【059】分享我的 Android(安卓)应用
  4. Android(安卓)定时器真机测试
  5. 25个你应该阅读的Android网站
  6. IPC与Binder,Binder线程池,AIDL demo - And
  7. 关于android WebViewClient和WebChromeCl
  8. android 模拟器中启用相机API支持
  9. Android(安卓)Menu 用法
  10. Android自动化测试初探(二): Hierarchyview