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

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

(2009-04-20 12:37:09)

转载

标签:

gcc

linux

android

cygwin

toolchain

分类:Android

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自已写的 bionic Libc,小是小,快是快,但有一个最大问题,对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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值