转自:http://www.linuxidc.com/Linux/2010-08/27880.htm


严格意义上来讲,GoogleAndroid平台只支持基于 Android Dalvik VM 的 Java 语言开发,当前的 Android 对C/C++开发的支持仅限于用C/C++开发动态链接库,然后在Java中以JNI的形式来调用,换句话说,仅仅依靠C/C++在Android平台上进行应用的开发,当前还无法实现。这对于广大在Symbian和Windows Phone平台上使用C/C++进行手机应用开发的开发者来说并不是一个好消息。对于Android本身来说,也有不利的地方,它将大量的C/C++开发主力军挡在了Android平台的门外,不利于Android的繁荣发展。

当然,作为一个被广泛装载的智能手机操作系统平台,平台本身对开发的多样性的支持将是一种趋势,类似于占市场主导地位的Symbian支持C++,Java开发。

随着AndroidNDK的推出,我们也看到了Google 对Android平台下支持C/C++开发所进行的努力,由此,Android平台的C/C++开发也进入了正规军的行列,虽然还不是主力军。尽管当前Google推出了有助于C/C++开发的NDK,但是当前版本的NDK功能上还有很多局限性:NDK并没有提供对应用程序生命周期的维护;NDK也不提供对Android系统中大量系统事件的支持;对于作为应用程序交互接口的UI API,当前版本的NDK中也没有提供,由此可见,NDK只是Google对Android平台上C/C++开发的一个初步的支持,我们期待Google可以做得更多更好。

Android平台整体架构分为4层,分别为:

Applications: 应用程序层

Application Framework: 应用程序框架层

Library &&AndroidRuntime: 底层功能库以及Android运行时

Linux Kernel: Linux 内核

Android整体架构图如下:

Android C/C++ 开发_第1张图片

Android不支持 C/C++ 开发? 虚拟机以上的程序是 JAVA开发,但是底层可以用 C/C++ 跑一些 后台 程序啊, 大不了用 soket 通信嘛. 计划在 rootfs 里存放一套自己的 busybox, 自己的 Bash, 自己的 command 等,command 完全可以做成静态的, Android 里的 shell 实在太难用了。

用Android.mk 的方式去编译 C 程序也实在是太麻烦, 打算整理出一套 其他的编译 C 程序的方法.NDK? NDK 只是 JNI 的完善,能方便的把 so 和 java 程序打包到 apk 文件中去.很多人说只能静态编译C 程序, 那是胡扯,你如果用 android 里的交叉编译工具,用它 的环境去编译,自然可以不用静态。

下面给出一套方法, 方便的用Android环境,编译 C/C++ 程序。

后续,我还会尝试移植各种 C 库到Android中去,也会分享一些 移植的经验和方法。

先自己做一个配置文件, 主要是Android的编译和 链接参数:

cat zconfig.mk


ifdef ANDDROID
Abionic=$(A)bionic/libc/
AoutLib=$(A)out/target/product/generic/obj/lib/
CFLAGS += -I $(A)bionic/libc/arch-arm/include -I $(A)bionic/libc/include -I $(A)bionic/libc/kernel/common -I $(A)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 $(A)system/core/include/arch/linux-arm/AndroidConfig.h -DANDROID -fmessage-length=0 -W -Wall -Wno-unused -DSK_RELEASE -DNDEBUG \
-O2 -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

LIBS +=-nostdlib -Bdynamic -Wl,-T,$(A)build/core/armelf.x -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,nocopyreloc

LIBS +=-L$(AoutLib) -Wl,-rpath-link=$(AoutLib) -lc -lm $(AoutLib)crtbegin_dynamic.o -Wl,--no-undefined $(A)/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/interwork/libgcc.a $(AoutLib)crtend_Android.o
endif

接下来是一个通用的 Makefile, 这个 Makefile 中需要包含 zconfig.mk

cat Makefile

ifdef TARGET
include zconfig.mk
CROSS=$(CROSS_COMPILER)-
CC=$(CROSS)gcc
AR=$(CROSS)ar
LD=$(CROSS)ld
else
CC = gcc
AR = ar
LD = ld
STRIP = strip
endif

INCLUDE+= -I../ -I./

OBJ_DIR = obj/
OBJECTS = $(OBJ_DIR)hello.o
TARGET_OUTPUT=./hello

CFLAGS +=
all: $(TARGET_OUTPUT) $(TEST_OUTPUT) $(OBJECTS)

$(OBJ_DIR)%.o: %.c
@-mkdir -p $(OBJ_DIR)
$(CC) $(INCLUDE) $(CFLAGS) -c $< -o $@

$(TARGET_OUTPUT): $(OBJECTS)
$(CC) $(LIBS) -o $(TARGET_OUTPUT) $(OBJECTS) $(LD_PATH) $(LIBOBJECTS)
@echo "make $@ finished on `date`"
clean:
@rm -f $(TARGET_OUTPUT)
@rm -rf obj

然后是一个 hello.c

#include <stdio.h>

int main()
{
printf("hello world \n");
return 0;
}

自己的编译环境变量:

cat setenv.sh

export PATH=$PATH:/Android/myandroid/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin
export CROSS_COMPILER=arm-eabi
export TARGET=1
export ANDDROID=1
export A=/Android/mydroid/

在 编译 helloworld 以前, 请确认,你已经编译过Android 源代码,

确认 out 目录下有相应的库和工具。

这套机制十分灵活,你可以轻松的编译 X86 版, ARM LINUX 版,Android版。

最后执行

make

编译成功以后, 用 adb push 把程序放到 虚拟机里。

如果要编译动态库,则有有点小小的差异, 接下来会介绍。

标准的做法是 把 src 放到 /Android/develop/ 目录下去,然后建立 Android.mk 文件,

然后 make modue ...., 但是,这种方式 太麻烦。

下面介绍一种方法,可以比较快速的编译 C 库,

和上一篇中一样,首先要设置自己的环境变量:

cat setenv.sh

export PATH=$PATH:/Android/myandroid/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin


export CROSS_COMPILER=arm-eabi
export TARGET=1
export ANDDROID=1
export A=/ Android/mydroid/

然后依然是建立一个 mk 文件:

cat zconfiglib.mk


ifdef ANDDROID
Abionic=$(A)bionic/libc/
AoutLib=$(A)out/target/product/teton_ebook/obj/lib/
CFLAGS += -I $(A)bionic/libc/arch-arm/include -I $(A)bionic/libc/include -I $(A)bionic/libc/kernel/common -I $(A)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 $(A)system/core/include/arch/linux-arm/AndroidConfig.h -DANDROID -fmessage-length=0 -W -Wall -Wno-unused -DSK_RELEASE -DNDEBUG \
-O2 -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

LIBS += -nostdlib -Wl,-soname, -Wl,-T,$(A)build/core/armelf.xsc -Wl,--gc-sections -Wl,-Bsymbolic -L$(AoutLib) -Wl,--whole-archive -Wl,--no-whole-archive -lc -lm -Wl,--no-undefined $(A)/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/interwork/libgcc.a

然后是你自己的 lib 的 makefile.

cat makefile


ifdef TARGET
include /zconfiglib.mk
CROSS=$(CROSS_COMPILER)-
CC=$(CROSS)gcc
AR=$(CROSS)ar
LD=$(CROSS)ld
else
CC = gcc
AR = ar
LD = ld
STRIP = strip
endif

INCLUDE+= -I../ -I./

LIBS+= -shared

OBJ_DIR = obj/
OBJECTS = $(OBJ_DIR)hello.o
TARGET_OUTPUT=./libhello

CFLAGS +=
all: $(TARGET_OUTPUT) $(TEST_OUTPUT) $(OBJECTS)

$(OBJ_DIR)%.o: %.c
@-mkdir -p $(OBJ_DIR)
$(CC) $(INCLUDE) $(CFLAGS) -c $< -o $@

$(TARGET_OUTPUT): $(OBJECTS)
$(CC) $(LIBS) -o $(TARGET_OUTPUT) $(OBJECTS) $(LD_PATH)
@echo "make $@ finished on `date`"
clean:
@rm -f $(TARGET_OUTPUT)
@rm -rf obj

然后 make 就可以了。


编译出来的库貌似需要放到 /system/lib 下去。




更多相关文章

  1. 英特尔® Android* USB 驱动程序安装指南
  2. 安卓外派(Android外派)提供安卓程序员外派业务(北京动点,可签合同)
  3. Android导出一个JAR库/Android如何将程序打成jar包/android 打包
  4. android全平台编译ffmpeg以及x264与fdk-aac实践
  5. Android应用程序的签名
  6. Android系统Surface机制的SurfaceFlinger服务渲染应用程序UI的过
  7. 英特尔® Android* USB 驱动程序安装说明
  8. Android的5层平台架构

随机推荐

  1. 2011.07.13——— android remote servic
  2. Android 常用工作命令mmm,mm,m,croot,cgr
  3. Android中shape 横线+竖线~虚线
  4. Android TextUtils类常用方法
  5. Android 9.0 System.loadLibrary 的源码
  6. Windows下编译使用Android(安卓)NDK,调用S
  7. Android 中屏蔽 Home 键
  8. 列出sdcard里所有.mp3文件,并且可以点击
  9. [Android][MediaRecorder] Android(安卓)
  10. 【技术直通车】ArcGIS Runtime SDK for A