尝试编译android-4.0.4_r2.1

本文详细记录了在Ubuntu系统中编译Android-4.0.4_r2.1的过程,包括安装JDK6、准备开发工具、下载源码、解决GCC和32位系统问题、应用补丁、单独编译模块以及生成SDK。还介绍了如何从模拟器启动编译后的镜像文件,并提供了相关资源链接。
摘要由CSDN通过智能技术生成

这几天第一次尝试编译andorid,顺利编译了android-4.0.4_r2.1和android-2.3.7_r1,这两个分别是4.0和2.3的最后版本。

也尝试编译最新的android-4.1.1_r6,但是没成功,好像android-4.1要求要在64位的系统上编译,而我的32位系统上编译没多长时间就出错了。

CPU:Intel® Pentium(R) Dual CPU E2180 @ 2.00GHz × 2 
Memory:3.0 GiB
System:Ubuntu 12.04 (precise) 32 位
GCC:4.6.3
JDK:jdk-6-linux-i586.bin (32 位)

已经非常老的机器了,编译起来慢的要死,双线程全开,CPU 100%的跑,整整5个小时才跑玩,内存一直维持在1.3GB以上,到后期达到2.4GB。



1 Andorid指南

android源代码:https://android.googlesource.com/
platform/manifest.git


android开发指南:http://source.android.com/source/index.html

Getting Started

Navigating the Source

Contributing

Reference

这个是android官方的开发指南,也是最标准的,android项目不停的更新变化,很多书和博客都已经过时了。

另外参考:http://blog.csdn.net/xnwyd/article/details/7086414




2 准备工作

Detailed instructions for Ubuntu and MacOS follow. In general you will need:

  • Python 2.5 -- 2.7, which you can download from python.org.

  • GNU Make 3.81 -- 3.82, which you can download from gnu.org,

  • JDK 6 if you wish to build Gingerbread or newer; JDK 5 for Froyo or older. You can download both from java.sun.com.

  • Git 1.7 or newer. You can find it at git-scm.com.

前两条Ubuntu 12.04系统自带,不需要安装,git后面会通过安装必须包来安装,所以只需要我们手动安装JDK。

2.1 安装JDK6

The Sun JDK is no longer in Ubuntu's main package repository. In order to download it, you need to add the appropriate repository and indicate to the system which JDK should be used.

编译android2.3以上需要JDK6,如果编译2.2以下需要JDK5。

请参看我之前的博客:http://blog.csdn.net/niyufeng/article/details/7957156

以及 Initializing the Build Environment 中关于安装JDK的部分


2.2 安装必要的开发工具

在Ubuntu 12.04上需要安装如下的开发工具:

$ sudo apt-get install git 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 openjdk-6-jdk tofrodos \
  python-markdown libxml2-utils xsltproc zlib1g-dev:i386
$ sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so
最后一步是修正OpenGL的位置。


同时,在一直linux kernel时可能还需要:

$sudo apt-get install fakeroot valgrind libsdl-dev libesd0-dev libwxgtk2.6-dev \
  liblzo2-dev uboot-mkimage libstdc++6-4.6-dev

$sudo apt-get install vim gcc  \
  fortran77-compiler make gawk automake autoconf \
  minicom lrzsz linux-headers-$(uname -r) ncurses-dev \
  libncursesw5-dev libncurses5-dev netpbm libnetpbm10 \
  libnetpbm10-dev libtool bison flex texinfo \
  binutils-dev libc6-dev linux-libc-dev \
  manpages manpages-dev manpages-posix manpages-posix-dev


2.3 USB的配置

请参看 Initializing the Build Environment 中关于USB的配置部分




3 用repo工具下载源码


3.1 下载repo脚本工具


repo是一个便于git管理的工具,它是使用 Python写的脚本,这个repo脚本工具主要就是封装了git,用于管理android的源代码。
$cd ~
$mkdir bin  
$curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo  
$chmod a+x ~/bin/repo
$exportPATH=$PATH:~/bin(导出环境变量)  
或者可以不使用curl工具,而是到

https://dl-ssl.google.com/dl/googlesource/git-repo/repo ,或者
https://www.google.com/dl/googlesource/git-repo/repo ,直接下载repo脚本工具。


3.2 下载android最新源码

$mkdir android  
$cd android  
$ repo init -u https://android.googlesource.com/platform/manifest
...(按照提示输入用户名和邮箱名)  
$repo sync -j5

此处用5个线程开始同步、下载源码,下载过程及其漫长,需要耐心等待。最终下载完毕.repo/中的大小为11GB。

还有一步验证git tags可参照官网。下完后就可以在刚才文件夹下看见已下载的源码。


注:源码下载过程中经常会遇到下载失败的情况,非常浪费时间,所以编写一个失败重传的脚本可以减少很多不必要的麻烦。将下面的shell脚本保存为download.sh文件放到源代码目录中,执行./download.sh开始下载(替代文档中最后一步repo sync,其余步骤必须按照文档中介绍的一步一步来)

#!/bin/bash
echo "======start repo sync======"
repo sync
while [ $? == 1 ]; do
echo "======sync failed, re-sync again======"
sleep 3
repo sync
done

3.2.1 使用android-2.3.7_r1

当通过上面repo sync把源代码下载到本地PC后,可以通过-b参数来指定某一android分支,下面是android-2.3.7_r1,它是2.3的最后版本。

repo init --config-name -b android-2.3.7_r1
repo sync

最后编译完成大约为18.3GB:

.repo:11GB  
out:4.3GB  
真正的andorid-2.3.7_r1源代码才3.0GB左右的大小

3.2.2 使用android-4.0.4_r2.1

同样可以切换到android-4.0最后的版本android-4.0.4_r2.1。

repo init --config-name -b android-4.0.4_r2.1
repo sync

最后编译完成大约为29GB:

.repo:11GB
out:14GB
真正的andorid-4.0.4_r2.1源代码才4GB左右的大小




4 编译android-4.0.4_r2.1源代码

$ source build/envsetup.sh
$ lunch full-eng
$ make-j2
上面full是针对emulator编译全部包括app、输入法等,eng是指针对开发者编译,有最高权限。具体可参见官网。
CPU是奔腾双核,此处用2个线程编译。

build/envsetup.sh中定义了很多函数,例如lunch, mm, m等等

lunch 选择编译厂商版本
- m:       Makes from the top of the tree.                         m即为make
- mm:      Builds all of the modules in the current directory.     mm编译当前目录下所有模块
- mmm:     Builds all of the modules in the supplied directories.  mmm编译指定目录下所有模块


编译完成后,会看到类似的输出:

Processing target/product/generic/obj/APPS/Settings_intermediates/package.apk
Done!
Install: out/target/product/generic/system/app/Settings.odex
Install: out/target/product/generic/system/app/Settings.apk
Finding NOTICE files: out/target/product/generic/obj/NOTICE_FILES/hash-timestamp
Combining NOTICE files: out/target/product/generic/obj/NOTICE.html
Installed file list: out/target/product/generic/installed-files.txt
Target system fs image: out/target/product/generic/obj/PACKAGING/systemimage_intermediates/system.img
Install system fs image: out/target/product/generic/system.img

至此编译完毕,make编译的并不是所有内容,不包含内核kernel和SDK。


4.1 android-4.0.4_r2.1的补丁

很多情况下android是不能够一次就顺利编译成功的,而在我的机器上错误主要来自与两个方面,

一是我使用的Ubuntu版本为12.04,GCC为4.6.3,GCC及其Glibc版本稍高(比较推荐使用gcc4.4,可参考 http://blog.csdn.net/xnwyd/article/details/7086414 中关于更改gcc的部分);

二是我使用的Ubuntu是32位系统,而android的编译默认使用64位系统,特别是4.1目前只能在64位系统上编译。


针对如上的错误,我制作了5个补丁:

001-gcc4.6.x.patch

#由于使用gcc 4.6.x,最好换为4.4的gcc
--- android-4.0.4_r2.1/build/core/combo/HOST_linux-x86.mk.orig	2012-10-03 18:54:52.805379013 +0800
+++ android-4.0.4_r2.1/build/core/combo/HOST_linux-x86.mk	2012-10-03 18:56:28.773376791 +0800
@@ -53,6 +53,6 @@
 	-include $(call select-android-config-h,linux-x86)
 
 # Disable new longjmp in glibc 2.11 and later. See bug 2967937.
-HOST_GLOBAL_CFLAGS += -D_FORTIFY_SOURCE=0
+HOST_GLOBAL_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0
 
 HOST_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
--- android-4.0.4_r2.1/frameworks/base/libs/utils/Android.mk.orig	2012-10-03 19:01:32.273369759 +0800
+++ android-4.0.4_r2.1/frameworks/base/libs/utils/Android.mk	2012-10-03 19:02:27.041368492 +0800
@@ -61,7 +61,7 @@
 
 LOCAL_MODULE:= libutils
 
-LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS)
+LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS) -fpermissive
 LOCAL_C_INCLUDES += external/zlib
 
 ifeq ($(HOST_OS),windows)

002-host-libstdc++-headers.patch

#
# Problem comes from host libstdc++. Since version 4.6 <cstdio> does not include <cstddef> anymore.
# Downgrade host package to libstdc++ 4.5 or add '#include <cstddef>' into linker.cpp
#
--- android-4.0.4_r2.1/external/mesa3d/src/glsl/linker.cpp.orig	2012-10-04 12:12:52.625898520 +0800
+++ android-4.0.4_r2.1/external/mesa3d/src/glsl/linker.cpp	2012-10-04 12:14:46.209895889 +0800
@@ -67,6 +67,7 @@
 #include <cstdio>
 #include <cstdarg>
 #include <climits>
+#include <cstddef>
 
 #include <pixelflinger2/pixelflinger2_interface.h>
 
--- android-4.0.4_r2.1/external/gtest/include/gtest/internal/gtest-param-util.h.orig	2012-10-04 12:33:56.153869253 +0800
+++ android-4.0.4_r2.1/external/gtest/include/gtest/internal/gtest-param-util.h	2012-10-04 12:35:30.713867064 +0800
@@ -38,6 +38,8 @@
 #include <utility>
 #include <vector>
 
+#include <cstddef>
+
 #include <gtest/internal/gtest-port.h>
 
 #if GTEST_HAS_PARAM_TEST

003.patch

--- android-4.0.4_r2.1/frameworks/compile/slang/Android.mk.orig	2012-10-04 09:17:27.799397306 +0800
+++ android-4.0.4_r2.1/frameworks/compile/slang/Android.mk	2012-10-04 09:18:01.764370516 +0800
@@ -19,7 +19,7 @@
 
 LOCAL_PATH := $(call my-dir)
 
-local_cflags_for_slang := -Wno-sign-promo -Wall -Wno-unused-parameter -Werror
+local_cflags_for_slang := -Wno-sign-promo -Wall -Wno-unused-parameter
 ifneq ($(TARGET_BUILD_VARIANT),eng)
 local_cflags_for_slang += -D__DISABLE_ASSERTS
 endif

004.patch

--- android-4.0.4_r2.1/external/llvm/llvm-host-build.mk.orig	2012-10-04 12:39:04.209862117 +0800
+++ android-4.0.4_r2.1/external/llvm/llvm-host-build.mk	2012-10-04 12:39:58.181860867 +0800
@@ -1,3 +1,4 @@
+LOCAL_LDLIBS := -lpthread -ldl
 LOCAL_CFLAGS :=	\
 	-D_GNU_SOURCE	\
 	-D__STDC_LIMIT_MACROS	\

005.patch

--- android-4.0.4_r2.1/external/oprofile/libpp/format_output.h.orig	2012-10-04 12:24:24.025882506 +0800
+++ android-4.0.4_r2.1/external/oprofile/libpp/format_output.h	2012-10-04 12:25:09.349881455 +0800
@@ -91,7 +91,7 @@
 		symbol_entry const & symbol;
 		sample_entry const & sample;
 		size_t pclass;
-		mutable counts_t & counts;
+		counts_t & counts;
 		extra_images const & extra;
 		double diff;
 	};


5 从模拟器启动编译后的镜像文件

设置环境变量,启动模拟器
$ export ANDROID_PRODUCT_OUT=$PWD/out/target/product/generic
$ export PATH=$PWD/out/host/linux-x86/bin:$PATH

$ emulator
emulator:WARNING: system partition size adjusted to match image file (162 MB >66 MB)

其中linux-x86/bin存放模拟器emulator工具,product/generic存在编译后的镜像文件。



映像生成在out/target/product/generic下,android源码编译后得到system.img,ramdisk.img,userdata.img三个映像文件,emulator加载这3个映像文件。其中:
ramdisk.img是一个分区映像文件,在kernel启动时,ramdisk被用来调用init,以及把真正的rootfs mount起来;
system.img包括了主要系统,系统app等,会被挂载于/system,可对应查看./system该目录,可以发现在其下app/下有一些系统自带的应用程序。
userdata.img包括了一些用户数据,被挂载到/data下,对应可查看./data/目录。

另外还有root,system,data三个文件夹,其实就是上述三个img解压之后的内容而已。
root/对应ramdisk.img
system/对应system.img
data/对应userdata.img




6 单独编译某一模块


如果你不想编译整个系统,就想编译某一个应用程序,可以使用mmm命令,使用之前,在源码目录下先要执行:
$ build/envsetup.sh
这样会生成一些命令
m即make
mm编译当前目录下所有模块
mmm编译指定目录下所有模块

你可以单独编译packages/apps/Music应用,执行:
$ mmm packages/apps/Music
在out/target/product/generic/system/app中就可以看见Music.apk,然后执行:
$ make snod

重新生成system.img




7 编译SDK


参看:http://bbs.imp3.net/thread-10502182-1-1.html

然后再顺便把android 4.0的SDK编译出来,因为make编译并不包含kernel和SDK。
编译SDK可以得到与源码同步的SDK,还会生成一些tools,在源码根目录下:

$ make PRODUCT-sdk-sdk
编译生成的SDK在out/host/linux-x86/SDK下。


之后如果在ubuntu下使用eclipse进行开发,可以使用你编译的SDK。
下面就在模拟器中运行镜像,建议切到root用户下,首先配置几个环境变量,将自己编译的SDK设为优先级最高,在源码根目录下执行:

$ sudo update-alternatives --install /usr/bin/AndroidSDK AndroidSDK out/host/linux-x86/sdk/android-sdk_eng.root_linux-x86255
这样会在/etc/alternatives下生成一个指向该sdk目录的软连接AndroidSDK,而/usr/bin/AndroidSDK就指向这个软连接(/etc/alternatives相当于中转站)。/etc/alternatives这个目录主要存放一些系统默认打开的程序的信息和配置。


接着执行:

vi ~/.bashrc
在文件末尾添加:
export ANDROID_SDK_HOME=/usr/bin/AndroidSDK
export PATH=$ANDROID_SDK_HOME/tools:$PATH
export ANDROID_PRODUCT_OUT=$PWD/out/target/product/generic


接着就可以启动模拟器:
$ emulator
运行的就是你编译的映像。

执行emulator 命令时,如果不带任何参数,则Linux Kernel镜像默认使用prebuilt/android-arm/kernel目录下的kernel-qemu文件,而Android镜像文件则默认使用ANDROID_PRODUCT_OUT目录下的system.img,userdata.img和ramdisk.img,模拟器运行需要这四个文件。如果你编译了内核则可以使用自己的kernel镜像(如goldfish的内核镜像),可用于android移植等。


$ emulator -system system.img -data userdata.img -ramdisk ramdisk.img -kernel kernel/goldfish/arch/arm/boot/zImage
就可以看到android 4.0的虚拟机了。
分辨率貌似有点低,好吧,在eclipse下面引入刚刚编译好的SDK,配置一个android 4.0的AVC,来点有平板味道的android虚拟机。
安装ADT插件:
http://dl-ssl.google.com/android/eclipse/


看一下系统信息,可发现kernel版本是2.6.29的,可以下载新的内核3.0.1重新编译。



8 编译内核


参看:http://blog.csdn.net/xnwyd/article/details/7086414

            Building Kernels       ,      Building for Devices

AOSP中kernel和device是有对应关系的,例如:

device/generic/goldfish对应于kernel/goldfish.git
device/ti/panda对应于kernel/omap.git
device/samsung/crespo对应于kernel/samsung.git

等。


kernel/common

CommonAndroid Kernel Tree

kernel/exynos


kernel/goldfish


kernel/msm

Kerneltree for Qualcomm chipsets

kernel/omap


kernel/samsung

Kerneltree for Samsung systems on Android.

kernel/tegra

Kerneltree for NVIDIA Tegra family SOICs on Android.


下载编译goldfish内核


直接使用repo来下载kernel,这里我下载了kernel/common.git和kernel/goldfish.git,同时也定义了checkout的版本:

local_manifest.xml:

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <project path="kernel/common" name="kernel/common" revision="refs/heads/android-2.6.39" />
  <project path="kernel/goldfish" name="kernel/goldfish" revision="refs/heads/android-goldfish-2.6.29" />
</manifest>

把local_manifest.xml拷贝到.repo/下,然后使用repo来同步下来kernel
$ cp -vf local_manifest.xml .repo/
$ repo sync

编译goldfish内核:
$ export PATH=$PWD/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin:$PATH
$ make -C kernel/goldfish/ ARCH=arm SUBARCH=arm CROSS_COMPILE=arm-eabi- goldfish_armv7_defconfig
$ make -C kernel/goldfish/ ARCH=arm SUBARCH=arm CROSS_COMPILE=arm-eabi-

android2.3.7使用goldfish_defconfig;

android4.0.4使用goldfish_armv7_defconfig;

不能混乱使用!


环境变量ARCH决定了目标内核的运行架构,ARCH可为arm,mips,x86等。
环境变量SUBARCH的作用是,当环境变量ARCH没有被设定的时候,便采用SUBARCH指示的架构进行内核的编译(因此ARCH被定义时SUBARCH可不定义)。
可以看出,默认情况下SUBARCH被设定的是正在运行内核编译任务的主机所运行的架构(SUBARCH :=uname -m)。

./arch/arm/configs/goldfish_defconfig
./arch/arm/configs/goldfish_armv7_defconfig
./arch/mips/configs/goldfish_defconfig
./arch/x86/configs/goldfish_defconfig

编译完成后,可看到类似如下的输出:
OBJCOPY arch/arm/boot/zImage 
Kernel: arch/arm/boot/zImage is ready 

模拟器指定使用goldfish内核镜像:
$ export ANDROID_PRODUCT_OUT=$PWD/out/target/product/generic 
$ export PATH=$PWD/out/host/linux-x86/bin:$PATH 
$ emulator -kernel kernel/goldfish/arch/arm/boot/zImage
emulator:WARNING: system partition size adjusted to match image file (69 MB >66 MB) 

这是自己编译的goldfish内核:



这是原始prebuilt/android-arm/kernel/kernel-qemu内核:








其他参考:

http://bbs.imp3.net/thread-10502182-1-1.html

http://blog.csdn.net/xnwyd/article/details/7086414

http://blog.csdn.net/zjmdp/article/details/7737802

http://blog.csdn.net/gexueyuan/article/details/7772387

http://blog.csdn.net/hudan2714/article/details/7926924






  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值