Android开源已经有一段时间了,一直没有去研究它,一是没有时间,二是没有Linux环境去测试,三是块头太大了(源码2G,加编译要5G左右)。
最近项目差不多近尾声了,终于可以喘口气,有时来好好研究一下Android的源码了,就在WinXP中从网上下载了Android的源码,一开始只是想看看自已感兴趣的部分(GUI、OpenGL ES、Audio等),后来在网上找到了一些在Cygwin下搭建原生开发环境的文章,于是就自已试了下,发现不要Linux、不下全部源码进行原生开发完全是可行的!

首先,要装Cygwin这个“活宝”,网上有很多相关的文章,下载包时请选择中国的镜像:http://www.cygwin.cn,比较快,如下包一定要安装:gcc、make、Flex、bison、gettext、gettext-devel、textinfo,另外一定要装git包,下源码就靠它了;

其次,Cygwin及git安装好了,进入Cygwin,输入git --version,如果能正确显示就表示git安装没有问题,就可以开始有选择地下载Android的源码了。Android的源码太多了,如果只为原生开发,只要下载bionic及build两个包,先为Android源码建一个目录,进入此目录,再按如下步骤取源码:
1. bionic,Android没有用 glibc,用的是google自已写的 bionicLibc,小是小,快是快,但有一个最大问题,对C++的兼容不好(这是后话)。命令如下:
git clone git://android.git.kernel.org/platform/bionic.git
2. build,其实我们只是要参考Android的一些编译链接选项,命令如下:
git clone git://android.git.kernel.org/platform/build.git
3.system/core,其实我们只是要一个头文件:AndroidConfig.h,也可直接从android git web上下载:http://android.git.kernel.org/?p=platform/system/core.git;a=blob_plain;f=include/arch/linux-arm/AndroidConfig.h;hb=HEAD,如果要下整个目录,命令如下:
git clone git://android.git.kernel.org/platform/system/core.git
4. frameworks/base,如果要进行 opengl es 的3D开发,一定要下载这个包,因为opengl es的头文件在这个包中,命令如下:
git clone git://android.git.kernel.org/platform/frameworks/base.git

更多Android项目信息请访问:http://android.git.kernel.org/,大家可根据自已的兴趣选择下载。

再次,下载Android订制的toolchain的源码( http://android.git.kernel.org/pub/android-toolchain-20081019.tar.bz2),编译步骤如下:
1.解压文件,并进入目录,执行如下命令配置要编译的target及安装的目录:
./configure --target=arm-eabi --prefix=/cygdrive/d/Android/cupcake/toolchain
虽然安装目录可稍后安装配,但推荐在配置时设置好,目录一定要是绝对路径,如要装在 D:\Android\cupcake\toolchain,则为:/cygdrive/d/Android/cupcake/toolchain。
2.执行:make build 命令,如果有错误按提示再编译,一般没有什么大问题;
3.安装:make install。

Toolchain编译安装完成后,就要开始进行一些环境配置的动作了,网上说直接将bionic的一些头文件复制到 $toolchain/arm-eabi/include,一般情况是,但先执行如下看一下:
$arm-eabi-cpp -v

一般gcc会从如下3个目录去搜索头文件:
$toolchain/lib/gcc/arm-eabi/4.2.1/include
$toolchain/arm-eabi/sys-include
$toolchain/arm-eabi/include

如下头文件需从android源码目录复制到toolchain目录$toolchain/lib/gcc/arm-eabi/4.2.1/include:
bionic/libc/arch-arm/include
bionic/libc/include
bionic/libstdc++/include
bionic/libc/common
bionic/libc/arch-arm
bionic/libm/include
bionic/libm/include/arch/arm (好象找不到此目录,ignore it!)
bionic/libthread_db/include
frameworks/base/opengl/include (3D开发,一定要加此目录!)

其中,一些头文件有重复:limits.h一定要用bionic/libc/include目录的,endian.h 用 bionic/libc/arch-arm/include,再将system/core/include/arch/linux-arm目录下的AndroidConfig.h文件复制到$toolchain/lib/gcc/arm-eabi/4.2.1/include。

头文件复制完成了,接下来复制库文件,库文件因没有所有源码不能通过编译得到,只好从模拟器中pull下来,这次要用到一个工具: busybox。
从网上下载 busybox的可执行程序,启动模拟器,将busybox push上去,执行:
$adb push busybox /dev/sample/busybox
$adb shell chmod 777 /dev/sample/busybox
$adb shell ./dev/sample/busybox tar -cf /dev/sample/libs.tar /system/lib
$adb pull /dev/sample/libs.tar libs.tar
这样就将模拟器下的 /system/lib 目录的所有库(so)文件打包并下载下来了,解压libs.tar就得到了我们所需要的所有库文件,执行如下命令:
arm-eabi-ld --verbose 或 arm-eabi-ld --verbose | grep SEARCH_DIR
复制所有库文件到 SEARCH_DIR(一般是$toolchain/arm-eabi/lib)目录下,同时将 toolchain 的编译脚本 armelf.x armelf.xsc 从下载的Android的源码目录的 build/core 复制到同目录。

至此,环境基本上搭建完成,可以试着编译一个 hello world C 源码了。
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
int i;

printf("argc\t = %d\n", argc);
for (i = 0; i < argc; i++) {
printf("argv[%d]\t = %s\n", i, argv[i]);
}

printf("Hello world!\n");;

return 0;
}
编译命令如下:
$ arm-eabi-gcc -nostdlib -Bdynamic -Wl,-T,armelf.x -Wl,-dynamic-linker,/system/bin/linker -include AndroidConfig.h -lc -o hello hello.c
得到警告:
warning: cannot find entry symbol _start; defaulting to 000082c8
没有入口函数 _start,加上再编译,成功了,push至模拟器执行看一下:
$ adb shell ./dev/sample/hello
argv[0] = (null)
argv[1] = (null)
argv[2] = (null)
argv[3] = (null)
argv[4] = (null)
argv[5] = (null)
argv[6] = (null)
argv[7] = (null)
argv[8] = (null)
argv[9] = (null)
argv[10] = (null)
argv[11] = ./dev/sample/hello
argv[12] = (null)
argv[13] =
argv[14] = (null)
[1] Segmentation fault ./dev/sample/hello
很不幸,Segmentation fault!好象加_start也不是那么有用,看样子非得要象build的makefile中说的,要crtbegin_dynamic.o和crtend.o,但没有编整个源码,怎么得到这两个文件呢?
答案就在下载的Android的源码bionic的目录中,进入$android_src/bionic/libc/arch-arm/bionic,你会发现在很多汇编文件,其中我们想要的 crtbegin_dynamic.S,crtend.S就在其中,编译它们:
arm-eabi-gcc -mthumb-interwork -o crtbegin_dynamic.o -c crtbegin_dynamic.S
arm-eabi-gcc -mthumb-interwork -o crtend.o -c crtend.S
不出意外,将得到 crtbegin_dynamic.o & crtend.o,再来编译我们的hello.c
$arm-eabi-gcc -nostdlib -Bdynamic -Wl,-T,armelf.x -Wl,-dynamic-linker,/system/bin/linker -include AndroidConfig.h -lc -o hello hello.c crtbegin_dynamic.o crtend.o
将生成的hello push到模拟器,再执行,如下:
$adb push hello /dev/sample/hello
$adb shell chmod 777 /dev/sample/hello
$adb shell ./dev/sample/hello A B C
输出如下:
argc = 4
argv[0] = ./dev/sample/hello
argv[1] = A
argv[2] = B
argv[3] = C
Hello world!

这正是我们想要看到的。


转自:

http://blog.sina.com.cn/s/blog_4a0a39c30100crhl.html

更多相关文章

  1. 一款常用的 Squid 日志分析工具
  2. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  3. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  4. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  5. 关于android:sharedUserId="android.uid.system"这个系统级权限
  6. Android(安卓)SDK Document 注解【1】
  7. Android静默安装
  8. Android应用开发揭秘第3章笔记
  9. JavaScript与Android原生相互调用并传参

随机推荐

  1. Android标题栏各种设置
  2. Android FrameLayout的显示效果
  3. Dagger2在Android studio中的配置与简单
  4. android 一些小功能实现
  5. 跑马灯效果
  6. 编译cubieboard android 源码过程详解之(
  7. android 模拟器常用命令
  8. Android实现启动页停留几秒然后自动跳转
  9. android 硬解码 是否支持
  10. Android实现轮播图效果