【转】Android原生(Native)C开发之八:Toolchain环境搭建篇

来源:互联网 发布:常用数据挖掘算法 编辑:程序博客网 时间:2024/06/06 08:45

Android原生(Native)C开发之八:Toolchain环境搭建篇

(2009-04-2012:37:09)

转载

标签:

gcc

linux

android

cygwin

toolchain

分类:Android

Android开源已经有一段时间了,一直没有去研究它,一是没有时间,二是没有Linux环境去测试,三是块头太大了(源码2G,加编译要5G左右)。

最近项目差不多近尾声了,终于可以喘口气,有时来好好研究一下Android的源码了,就在WinXP中从网上下载了Android的源码,一开始只是想看看自已感兴趣的部分(GUI、OpenGLES、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++的兼容不好(这是后话)。命令如下:

gitclone git://android.git.kernel.org/platform/bionic.git

2.build,其实我们只是要参考Android的一些编译链接选项,命令如下:

gitclone git://android.git.kernel.org/platform/build.git

3. system/core,其实我们只是要一个头文件:AndroidConfig.h,也可直接从androidgit web上下载:http://android.git.kernel.org/?p=platform/system/core.git;a=blob_plain;f=include/arch/linux-arm/AndroidConfig.h;hb=HEAD,如果要下整个目录,命令如下:

gitclone git://android.git.kernel.org/platform/system/core.git

4. frameworks/base,如果要进行 opengl es 的3D开发,一定要下载这个包,因为opengles的头文件在这个包中,命令如下:

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.执行:makebuild 命令,如果有错误按提示再编译,一般没有什么大问题;

3.安装:makeinstall。

 

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上去,执行:

$adbpush busybox /dev/sample/busybox

$adbshell chmod 777 /dev/sample/busybox

$adbshell ./dev/sample/busybox tar -cf /dev/sample/libs.tar /system/lib

$adbpull /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.xarmelf.xsc 从下载的Android的源码目录的 build/core 复制到同目录。

 

至此,环境基本上搭建完成,可以试着编译一个hello world C 源码了。

#include<stdio.h>

#include<stdlib.h>

 

intmain(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 hellohello.c

得到警告:

warning:cannot find entry symbol _start; defaulting to 000082c8

没有入口函数_start,加上再编译,成功了,push至模拟器执行看一下:

$ adbshell ./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]   Segmentationfault      ./dev/sample/hello

很不幸,Segmentationfault!好象加_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

将生成的hellopush到模拟器,再执行,如下:

$adbpush hello /dev/sample/hello

$adbshell chmod 777 /dev/sample/hello

$adbshell ./dev/sample/hello A B C

输出如下:

argc     = 4

argv[0]  = ./dev/sample/hello

argv[1]  = A

argv[2]  = B

argv[3]  = C

Helloworld!

这正是我们想要看到的。

 

源文档 <http://blog.sina.com.cn/s/blog_4a0a39c30100crhl.html> 

原创粉丝点击