Ubuntu 14.04 LTS 下 android 2.3.5 源码编译过程 在新的Ubuntu 64位系统下去编译早期的安卓源码是会出现很多问题的,因为64位系统在安装完成后,很多32位的兼容包是没有安装的, 而早期的安卓是有不少用的32位的开发包。新手往往很难搞清楚其中的问题根源。而且安卓源码的编译又依赖了很多额外的的第三方开发包,所以编译过程会因为缺少这些包导致编译失败。另外一个问题是在新的Ubuntu系统下,因为gcc 和 g++编译器的升级原因,导致早期的代码在新的编译器下发生错误而中断。例如我的Ubuntu 14.04LTS 64位系统安装完成后gcc 和 g++的版本都是4.8,而网上很多资料都说要编译 2.3的安卓源码需要降级到 4.4。我想这是因为一些在早期版本的代码在后面的编译器看来是一种错误导致的,所以有不少地方需要修改 Android.mk文件,添加 -fpermissive 编译选项,permissive 英文意思为宽容,大概意思是宽容早期的一些语法结构的意思吧。 所以一开始先把一些需要的依赖包安装好,然后把gcc 和 g++使用软链接连接到4.4版本的gcc和g++编译器可以减少很多编译失败的问题。 这里我列出一些依赖包,但每个人的情况不同,所以一定有缺的,在网上找找应该都能解决: sudo apt-get install git-core gnupg flex bison gperf build-essential \
zip curl libc6-dev libncurses5-dev:i386 x11proto-core-dev \
libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-glx:i386 \
libgl1-mesa-dev g++-multilib mingw32 tofrodos \
python-markdown libxml2-utils xsltproc zlib1g-dev:i386
sudo apt-get install git-core gnupg flex bison gperf libsdl1.2-dev libesd0-dev libwxgtk2.6-dev squashfs-tools build-essential zip curl libncurses5-dev zlib1g-dev pngcrush schedtool libxml2 libxml2-utils xsltproc
下载 Android 源码:
有两种方法:
1. 直接下载别人已经下载打包的
百度网盘别人共享的:http://pan.baidu.com/share/link?shareid=7577&uk=4246628909 , 2.3.5版本,要先安装7z解压,然后获得一个大约2G多的tar,这个文件直接解压会出错,错误信息大概是说无法创建硬链接(hard link),使用下面的命令:
sudo tar -xf Android_Kernel.tar –exclude */.git -C /opt/android/sources
2. 使用 repo 获取
参考:http://jileniao.net/post-156.html
repo 的用法可参考 http://blog.csdn.net/sunweizhong1024/article/details/8055372
因为 repo sync 会因为网络中断,所以可以使用下面的脚本自动重新运行
#!/bin/bash
command=”repo sync”
$command result=$? echo “result = “$result until [ $result -eq 0 ] do echo “retry” $command result=$? done
编译: 开始吧… 进入源码路径,然后运行 make即开始编译过程,编译过程出现的一些错误以及解决办法列在下面 1. 错误 dalvik/vm/native/dalvik_system_Zygote.c:191:19: error: storage size of ‘rlim’ isn’t known
struct rlimit rlim;
解决方法:添加头文件#include <sys/resource.h>到以下文件
dalvik/vm/native/dalvik_system_Zygote.cpp 2. make: *** [out/host/linux-x86/obj/EXECUTABLES/mksnapshot_intermediates/src/accessors.o] 错误 1 在网上查资料,网上是说因为GCC 和 G++ 版本太高,应该使用 gcc-4.4 和 g++-4.4,通过以下命令查看我自己的版本 gcc –version (结果为4.8) g++ –version (结果为4.8) 解决方法很简单,安装 gcc 4.4 和 g++ 4.4 sudo apt-get install gcc-4.4 g++-4.4 g++-4.4-multilib 安装之后在 /usr/bin下面就会有 gcc-4.4 和 g++-4.4,然后把原来gcc 和 g++ 的符号链接删除,重新建立其指向我们安装的版本: sudo rm -f /usr/bin/gcc sudo rm -f /usr/bin/g++ sudo ln -s /usr/bin/gcc-4.4 /usr/bin/gcc sudo ln -s /usr/bin/g++-4.4 /usr/bin/g++ 3. external/srec/tools/thirdparty/OpenFst/fst/lib/cache.h:136:11: note: use ‘this->SetState’ instead
make: *** [out/host/linux-x86/obj/EXECUTABLES/grxmlcompile_intermediates/grxmlcompile.o] Error 1 解决方法: cd external/srec wget “https://github.com/CyanogenMod/android_external_srec/commit/4d7ae7b79eda47e489669fbbe1f91ec501d42fb2.diff”
patch -p1 < 4d7ae7b79eda47e489669fbbe1f91ec501d42fb2.diff
rm -f 4d7ae7b79eda47e489669fbbe1f91ec501d42fb2.diff
4. In file included from system/extras/ext4_utils/output_file.c:30: /usr/include/zlib.h:34: fatal error: zconf.h: 没有那个文件或目录 compilation terminated.
解决方法:原因是zlib1g-dev有个头文件修改了路径,及zconf.h放到了/usr/include/x86_64-linux-gnu/,所以将其拷贝到/usr/include/下即可了
5. make: *** [out/target/product/generic/obj/STATIC_LIBRARIES/libwebcore_intermediates/WebCore/HTMLNames.h] 错误 2
解决方法:安装 sudo apt-get install libswitch-perl
验证
编译完成后,尝试一下我的编译结果:
编译后生成的模拟器 emulator 在源码的 out/host/linux-x86/bin 下,而生成的系统在 out/target/product/generic 目录下,主要的是system.img、userdata.img和 ramdisk.img。有两种方法可以运行emulator
第一种: 设置 ANDROD_PRODUCT_OUT 环境变量,将其设置为生成的系统存放目录,如我的机器上 out/target/product/generic:
export ANDROD_PRODUCT_OUT=out/target/product/generic (如果只是一次行测试,在终端窗口运行该命令即可,如果希望在以后使用,那么可以写入/etc/profile 或者 ~/.bashrc)
然后进入源码目录运行: emulator
这种情况下其使用的系统映像文件均来自与 ANDROID_PRODUCT_OUT指向的目录中的 system.img、userdata.img和 ramdisk.img文件,而其内核文件会使用源码目录中的 prebuilt/android-arm/kernel/kernel-qemu的文件
第二种:使用完整的 emulator 命令参数启动模拟器
emulator -kernel /develop/sources/android/2.3.5/prebuilt/android-arm/kernel/kernel-qemu -sysdir /develop/sources/android/2.3.5/out/target/product/generic -system system.img -data userdata.img -ramdisk ramdisk.img
字体加粗部分应根据自己的源码路径进行修改。正如命令的参数的直观表示一样, -kernel 后面紧接着是指定内核文件,因为我没有编译自己的内核,所以直接使用源码提供的预先编译好的内核, -sysdir 参数后跟着的是系统的映像文件存放路径,后面的 -system、-data和-ramdisk等参数指定的文件如果没有使用绝对路径,那么就使用 -sysdir 指定的路径。
当我运行我编译好的 emulator 后出现了如下错误:
SDL init failure, reason is: No available video device
我前段时间刚好安装了最新的 Android SDK, 里面是带 emulator的,我就抱着试试看的态度,看看能不能成功:
1. 打开控制台端口,进入放置emulator 的目录
cd /opt/android/sdk/tools
2. 然后运行 emulator 命令
emulator -kernel /develop/sources/android/2.3.5/prebuilt/android-arm/kernel/kernel-qemu -sysdir /develop/sources/android/2.3.5/out/target/product/generic
成功!
如果我运行:
emulator -kernel /develop/sources/android/2.3.5/prebuilt/android-arm/kernel/kernel-qemu -sysdir /develop/sources/android/2.3.5/out/target/product/generic -system system.img -data userdata.img -ramdisk ramdisk.img
则会出现错误:
qemu: could not load initrd ‘ramdisk.img’
网上找有网友说使用完整路径来指定ramdisk路径即可,实验了一下,果真如此。 -ramdisk /develop/sources/android/2.3.5/out/target/product/generic/ramdisk.img, 还有一些帖子说 out/target/product/generic 路径需要写权限,不过我不属于这种情况,如果是使用其他用户编译的,或许会有这样的问题,把解决方法也写出来,备查:
chmod 777 out/target/product/generic
既然Android SDK的 emulator可以,但是我编译出来的 emulator不行,说明是emulator的问题,突然我想到会不会又是一个 64位和32位的问题。我编译的 emulator是 2.3.5源码的,那时候说不定是使用的32位开发包。在网上查资料,果然如我的猜测,那么解决方法很简单安装32位的开发包
我先是安装 X11 的32位开发包:
sudo apt-get install libX11-dev:i386 (注意冒号后面的 i386指示的是安装32位版本)
运行,还是一样的问题,肯定还有东西没有安装完整,再次找资料,还要安装 SDL的32位包:
sudo apt-get install libsdl1.2debian:i386
帖子还有说:
sudo apt-get install ia32-libs-sdl
(这个我没有试)
还有的说 export DISPLAY=:0
, 这个情况或许某些人会有用。
参考链接: http://stackoverflow.com/questions/4841908/sdl-init-failure-reason-is-no-available-video-device/10128566
比较不错的参考链接:
http://www.cnblogs.com/kobe8/p/3998379.html
http://www.cnblogs.com/webapplee/p/3946506.html
http://blog.csdn.net/jiangwei0910410003/article/details/37988637
http://www.omitol.com/archives/65.html
http://www.linuxidc.com/Linux/2012-09/70052p2.htm