再次在 cygwin 下编译 Android toolchain
重装系统后把 cygwin 也重新在线安装了一下,但发现 -mno-cygwin 尽然不能用了,找不到 crt2.o ,这些文件明明是存在的,搜索了一下官方的问答,说是安装顺序的问题,把mingw的几个包重新装一遍即可,试验了几次也没效果,无奈,只能自己找原因,看看 /lib/gcc/i686-pc-mingw32/3.4.4/specs 文件,很多路径指向了 /usr/i686-pc-mingw32/sys-root ,再看看 /usr/i686-pc-mingw32/lib ,也都是些指向 sys-root 的 link ,而这个目录根本就不存在,真正的文件是在 /lib/mingw 里的。在 /usr/i686-pc-mingw32 下建一个 sys-root 目录,把 lib 下的文件复制过来,再试试编译,所有问题解决! 难道说 cygwin 忘记把这些文件放到安装包里?应该不是吧,cygwin 也需要发展,并打算慢慢废弃一些陈旧的东西,gcc3应该也懒得继续维护,打算让用户全换到gcc4上去,众所周知cygwin的已经不支持-mno-cygwin了,需要编译纯windows的东西由独立的mingw64以cross toolchain方式替代。毕竟mingw是独立的,并非cygwin的一部分,而且mingw的MSYS在某些方面足以跟 cygwin 唱对台戏。要让 cygwin 花巨大精力去做 NO-CGYWIN 的东西,确实强人所难了,但遗憾的是,历史遗留下来的大量依赖-mno-cygwin的编译脚本也将被统统废弃,可惜了。
言归正题,虽然虚拟化技术在windows里跑个linux是很容易的事,但我还是喜欢用cygwin,为了继续andorid研究,在cygwin编译套新的Android toolchain是必须的。网上搜索新的教程,很是郁闷,搜到基本都是我三年前的帖子和别人转贴。算了,重新再来:
1.下载toolchain源码
repo 安装不多说了,但在cygwin下用 repo 需要装 git 和 python 包,在64位win7下,python还出异常,需要关闭cygwin,运行bin目录下的ash,并在ash提示符中运行 /bin/rebaseall 。(还可能出现windows的temp目录不可写的错误,chmod加写入权限,不知道会不会给win自身的安全带来隐患,不放心的话,rebaseall 结束后,再改回去吧)
# mkdir android-toolchain
# cd android-toolchain
# repo -u git://android.git.kernel.org/toolchain/manifest.git
# repo sync
大概需要下载280M左右的东西,但对我这下载平均不过5K的速度来说,太痛苦了...
2. 准备编译toolchain
编译前先仔细阅读刚下载的目录中 build 目录下的 README,目前的toolchain允许编译出4个目标toolchain,作为一般使用,我们只关心前两个即适合NDK使用的 arm-linux-androideabi 和 用来编译android内核的 arm-eabi 。看gcc部分也有4套版本的源码可供选择,印象中4.2.1不支持cortex-a8的指令集,所以如果要做ARMv7的代码,需要选更高的版本,当然高版本的gcc也需要高版本的gmp和mpfr库。检查一下cygwin是否装齐了各工具包,比如 gcc make flex bison gettext textinfo ,印象中 gettext-devel 一定要装的。
# mkdir arm-eabi
# cd arm-eabi
# ../android-toolchain/build/configure --target=arm-eabi --prefix=/opt/arm-eabi --disable-libstdc__-v3
# make build
# make install
没想到编译过程出奇的顺利,N个小时后,编译脚本正常结束。得到编译内核用的 arm-eabi,gcc版本4.2.1。这还不是目前真正需要的东西,把 /opt/arm-eabi 打包,备份,以后可能用的到。~/arm-eabi 目录也没什么用了,可以直接删除。我们其实需要是 gcc4.4.x 的arm-linux-androideabi 。这还需要 --with-sysroot=<path to sysroot> ,一个包含针对 android 指定版本的 sysroot 目录,在 build 目录里有个脚本 build-sysroot.sh ,可以帮助从 android 源码的编译结果中提取需要的文件创建 android toolchain 的 sys-root ,但这这个脚本很邪恶,如果你用的root账户(cygwin里基本就是root),如果你没加任何参数指行了那个脚本,呵呵,你的系统基本需要重装了,因为 /usr/lib 和 /usr/include 会被删的一干二净。务必注意!cygwin应该是不可能编译android源码的,所以只能找编译好的,比如 prebuilt/ndk/android-ndk-r4/platforms/ 下的目录。(该目录在android的源码中。也可以只 git platform/prebuilt,大概1.1G的下载量,有条件的不防把整个 platform 全部 repo 一份留之备用)。如果没有下载 android 源码,在 toolchain\benchmark\android_build\eclair 也可以找到,但只是预编译结果,需要用 build-sysroot.sh 脚本从那个目录里选择复制文件生成 sysroot。
# mkdir android-eabi
# cd android-eabi
# mkdir sys-root
把 toolchian/build/build-sysroot.sh 复制到 android-eabi 目录下打开编辑
DYNAMIC_LIBS_DIR=$PRODUCT_DIR/symbols/system/lib 改成 DYNAMIC_LIBS_DIR=$PRODUCT_DIR/obj/lib
install $BIONIC_ROOT/libm/include/arm/fenv.h $INCLUDE_ROOT 改成 install $BIONIC_ROOT/libm/arm/fenv.h $INCLUDE_ROOT
执行脚本(切记参数别搞错!!!)
# ./build-sysroot.sh ~/android-toolchain/benchmark/android_build/eclair/out/target/product/passion ~/android-eabi/sys-root
不明白为什么一个简单的文件复制脚本在 cygwin 下执行要花很常时间,总之执行完成,即可得到 eclair 的 sysroot 了。保险起见,这个build-sysroot.sh 还是删除的好 (祸端啊,害我重装N次cygwin)。
3. 开始编译,cygwin的编译器需要gcc4 (cygwin的gcc3和gcc4可以同时安装,用set-gcc-default-?.sh可切换)
# ../android-toolchain/build/configure --target=arm-linux-androideabi --prefix=/opt/arm-linux-androideabi --with-gcc-version=4.4.3 --with-binutils-version=2.20.1 --with-gmp-version=4.2.4 --with-mpfr-version=2.4.1 --with-gdb-version=7.1.x --with-gold-version=20100303 --with-sysroot=~/android-eabi/sys-root --enable-gold=both/gold
#make build
#make install
编译过程没有什么问题,但因为没有编译stdc++_v3 ,install 过程会出错,gcc 目录下 Makefile 中 install-target 节删除 maybe-install-target-libstdc++-v3 maybe-install-target-libgcc maybe-install-target-libiberty 三行可解决。安装后的编译器基本功能都有了,但跟android源码中prebuild下的toolchain似乎还有点差距