深入浅出 - Android系统移植与平台开发(五)- 编译Android源码(转)
2.3编译Android源码
Android源码体积非常庞大,由Dalvik虚拟机、Linux内核、编译系统、框架代码、Android定制C库、测试套件、系统应用程序等部分组成,在编译Android源码之前,必须要先掌握Android源码的组成。
2.3.1Android源码目录结构
在Android源码中,按照不同功能代码被放在不同的目录下:
|
目录 |
描述 |
|
bionic |
针对Android系统定制的仿生标准C库、链接器等所在目录,Android系统并没有使用Linux的glibc库,bioinc C库针对嵌入式系统做了优化,添加了一些Android特定的函数API同时大大减少库的体积,也避免了LGPL版权的问题。 |
|
bootable |
Android系统引导启动代码,用来引导系统、更新系统、恢复系统。 |
|
build |
Android的编译系统目录,里面包含大量的Makefile,用来编译目标系统、Host主机开发环境等。 |
|
cts |
兼容性测试工具目录。 |
|
dalvik |
Dalvik虚拟机,Android系统得以运行的虚拟执行环境。 |
|
development |
程序开发所需要的模板和工具。 |
|
external |
Android系统使用的其它开源代码目录,如jpeg图片解码开源库、opencore开源代码等。 |
|
frameworks |
框架层代码,frameworks/base目录下存放目标系统的框架库,frameworks/policies/base下存放应用程序框架代码。 |
|
hardware |
HAL(Hardware Abstraction Layer)硬件抽象层代码。 |
|
kernel |
Linux内核目录,默认下载的Android源码里没有,需单独下载。 |
|
packages |
Android系统级应用程序源码目录,如摄像应用、电话应用等。 |
|
prebuilt |
主机编译工具目录,如arm-linux-gcc交叉系统工具链等。 |
|
sdk |
SDK及模拟器。 |
|
system |
init进程、蓝牙、无线WIFI工具、uevent进程目录。 |
|
devices |
厂商设备配置目录,针对不同设备,由不同的子目录来分别管理,用来裁剪实现不同设备上Android目标系统。 |
在external目录下存放着大量的外部开源代码:
|
外部开源项目 |
描述 |
外部开源项目 |
描述 |
|
aes |
AES加密 |
libxml2 |
xml解析库 |
|
apache-http |
网页服务器 |
make |
|
|
asm |
netbeans-visual |
||
|
bluez |
蓝牙相关、协议栈 |
netcat |
simple Unix utility which reads and writes dataacross network connections |
|
ccache |
netperf |
网络性能测量工具 |
|
|
clearsilver |
neven |
看代码和JNI相关 |
|
|
dbus |
低延时、低开销、高可用性的IPC机制 |
opencore |
多媒体框架 |
|
dhcpcd |
DHCP服务 |
openssl |
SSL加密相关 |
|
dropbear |
SSH2的server |
oprofile |
OProfile是Linux内核支持的一种性能分析机制 |
|
eclipse |
ppp |
pppd拨号命令,好像还没有chat |
|
|
elfcopy |
复制ELF的工具 |
protobuf |
a flexible, efficient, automated mechanism for serializing structured data |
|
elfutils |
ELF工具 |
qemu |
arm模拟器 |
|
embunit |
Embedded Unit Project |
safe-iop |
functions for performing safe integer operations |
|
emma |
Java代码覆盖率统计工具 |
sdl |
|
|
esd |
Enlightened Sound Daemon,将多种音频流混合在一个设备上播放 |
skia |
skia图形引擎 |
|
expat |
Expat is a stream-oriented XML parser |
sonivox |
sole MIDI solution for Google Android Mobile Phone Platform |
|
fdlibm |
FDLIBM (Freely Distributable LIBM) |
sqlite |
数据库 |
|
Flex |
srec |
Nuance 公司提供的开源连续非特定人语音识别 |
|
|
freetype |
字体库 |
strace |
trace工具 |
|
gdata |
google的无线数据相关 |
swing-worker |
|
|
diflib |
swt |
||
|
googleclient |
google用户库 |
tagsoup |
TagSoup是一个Java开发符合SAX的HTML解析器 |
|
icu4c |
ICU(International Component for Unicode)在C/C++下的版本 |
tcpdump |
抓TCP包的软件 |
|
iptables |
防火墙 |
tinyxml |
TinyXml is a simple, small, C++ XML parser |
|
Jdiff |
generate a report describing the difference between two public Java APIs |
toolchain |
|
|
jfreechart |
tremor |
I stream and file decoder provides an embeddable,integer-only library |
|
|
jpeg |
jpeg库 |
webkit |
浏览器核心 |
|
kxml2 |
wpa_supplicant |
无线网卡管理 |
|
|
libffi |
libffi is a foreign function interface library. |
yaffs2 |
yaffs文件系统 |
|
libpcap |
网络数据包捕获函数 |
zlib |
a general purpose data compression library |
在packages/app目录下存放着大量系统级应用程序,我们可以拿到这些应用程序代码分析、理解,编写出效率更高,性能更好的应用:
|
系统应用程序 |
描述 |
|
AlarmClock |
闹钟 |
|
Browser |
浏览器 |
|
Calculator |
计算器 |
|
Calendar |
日历 |
|
Camera |
摄像头 |
|
Contacts |
联系人 |
|
|
邮件 |
|
GoogleSearch |
Google搜索 |
|
HTML Viewer |
浏览器附属界面,被浏览器应用调用,同时提供存储记录功能 |
|
IM |
即时通讯,为手机提供信号发送、接收、通信的服务 |
|
Launcher |
Android的桌面 |
|
Mms |
彩信业务 |
|
Music |
音乐播放器 |
|
PackageInstaller |
应用程序安装、卸载器 |
|
Phone |
电话应用 |
|
Settings |
系统设置 |
|
SoundRecorder |
录音机 |
|
Stk |
短信接收和发送 |
|
Sync |
同步数据 |
|
Updater |
更新 |
|
VoiceDialer |
语音识别通话 |
在package/providers目录下存放的是系统级内容提供器(Content Provider):
|
系统内容提供器 |
描述 |
|
CalendarProvider |
日历提供器 |
|
ContactsProvider |
联系人提供器 |
|
DownloadProvider |
下载管理提供器 |
|
DrmProvider |
DRM受保护数据存储服务,创建和更新数据库时调用 |
|
GoogleContactsProvider |
谷歌联系人提供器 |
|
GoogleSubscribedFeedsProvider |
Google同步功能 |
|
ImProvider |
即时通讯提供器 |
|
MediaProvider |
媒体提供器、提供存储数据 |
|
SettingsProvider |
系统设置提供器 |
|
SubscribedFeedsProvider |
|
|
TelephonyProvider |
彩信提供器 |
2.3.2编译Android
按照Android官方网站给出的步骤,编译Android源码过程如下:
Ø 初始化编译环境
在编译Android之前,编译系统需要加载一些编译脚本命令到环境变量中,通过下面的指令来初始化编译环境:
- $ sourcebuild/envsetup.sh
在执行完上述命令后,可以通过执行help命令来查看所有加载的命令。
- $ help
- Invoke ". build/envsetup.sh" from your shell to add the following functions to your environment:
- - croot: Changes directory to the top of the tree.
- - m: Makes from the top of the tree.
- - mm: Builds all of the modules in the current directory.
- - mmm: Builds all of the modules in the supplied directories.
- - cgrep: Greps on all local C/C++ files.
- - jgrep: Greps on all local Java files.
- - resgrep: Greps on all local res/*.xml files.
- - godir: Go to the directory containing a file.
- Look at the source to view more functions. The complete list is:
- add_lunch_combo cgrep check_product check_variant choosecombo chooseproduct choosetype choosevariant cproj croot findmakefile gdbclient get_abs_build_var getbugreports get_build_var getprebuilt gettop godir help isviewserverstarted jgrep lunch m mm mmm pid printconfig print_lunch_menu resgrep runhat runtest setpaths set_sequence_number set_stuff_for_environment settitle smoketest startviewserver stopviewserver systemstack tapas tracedmdump
常用脚本命令:
|
脚本命令 |
描述 |
|
Help |
帮助信息,打印所有命令 |
|
add_lunch_combo |
添加新目标编译项 |
|
print_lunch_menu |
打印所有目标编译项 |
|
lunch |
选择目标编译项 |
|
m |
从源码树顶级目录向下编译源码,相当于执行make |
|
mm |
从当前目录向下编译源码 |
|
mmm |
从指定目录向下编译源码,通常用来编译某个模块 |
|
cgrep |
从所有的C,C++文件里查找指定字符串 |
|
jgrep |
从所有的Java文件里查找指定字符串 |
Ø 选择编译选项
由于Android源码是一个开源的系统,然要匹配很多设备产品,也就是说一个版本的Android源码,可以编译出针对不同产品的系统。通过选择一个目标编译项,来决定编译出针对哪个产品的系统,我们可以通过执行下面的命令来选择要编译的目标系统:
- $ lunch
- You're building on Linux
- generic-eng simulator
- Lunch menu... pick a combo:
- 1. generic-eng
- 2. simulator
- Which would you like? [generic-eng]
通过lunch命令可知,让用户输入目标编译项,我们可以选择编译项前的数字,也可以直接输入编译项的名字。
…接前面终端输出信息
- Which would you like? [generic-eng]1 [回车]
- ============================================
- PLATFORM_VERSION_CODENAME=REL
- PLATFORM_VERSION=2.1-update1
- TARGET_PRODUCT=generic
- TARGET_BUILD_VARIANT=eng
- TARGET_SIMULATOR=false
- TARGET_BUILD_TYPE=release
- TARGET_ARCH=arm
- HOST_ARCH=x86
- HOST_OS=linux
- HOST_BUILD_TYPE=release
- BUILD_ID=ERE27
- ============================================
由上面结果可知,当用户输入:1或generic-eng时,会打印出上面的信息,这些信息是Android的编译系统必须依赖的环境变量,只有设置了这些变量,才能决定Android系统如何编译,编译成什么平台,编译成什么版本。
目标编译项格式:产品名-版本变量名,目标编译项可以由用户添加(见xxx章节),产品名是目标设备的产品名,由厂商自己定义,generic产品是通用产品,它是Android默认设备的产品名,它包含了常用的手机的所有功能,自己定义的产品可以继承generic,并重写它的功能,达到定制产品的目的(见xxx章节)。
版本变量名由以下几个组成:
- eng:工程版本,
- user:最终用户版本
- userdebug:调试版本
- tests:测试版本
其中,eng版本产品其实就是手机行业的工程机,它不是最终销售的产品,而是产品在定型下线之前放出的一些测试用机器,用于检测和标准的认证,这些工程机上安装的系统为eng版本,user是最终用户机发行版本,userdebug是调试版本,它比用户机添加了一些调试功能,如adb调试默认打开等,tests测试版本,该版本会安装一些测试程序,用于测试系统。
上述四种版本的分类作用,其一:用于区分目标系统里的所有的应用程序、库、测试程序等,将它们打上对应的Tags,当选择一个版本编译时,拥有对应Tags及低级别的Tags的程序会被编译安装到目标设备上,应用程序Tags的包含关系如下图:。其二:根据不同的版本,系统会有不同的设置,如adbd在用户版本里是关闭的,在其它版本中是默认打开的,ro.secure属性用户版本值为1,其它版本为0。
Ø 编译源码
执行完前面的命令后,我们可以输入make指令开始编译目标系统:
- $make
编译的时长与机器的硬件配置有关系,当第一次编译时一般需要数小时以上。后续编译,相对快多了,编译完的效果如下图所示:
通过上面的输出信息可知,Android系统编译完后,在out/target/product/generic/目录下产出了三个文件:system.img、ramdisk.img、userdata.img。
- system.img:android系统的文件系统,里面包含了android系统的应用程序(apk),系统用到的各种库(jar, so)和资源,配置文件(etc目录下),系统命令(bin,usr/bin, xbin),该映像文件是由out/target/product/generic/system目录打包生成的,我们可以对这个目录里的东西进行定制化,比如,你要想让android系统默认安装一个应用程序,那么可以将要安装的apk文件拷贝到out/target/product/generic/system/app目录下。
- userdata.img:用户数据映像,里面包含有程序安装信息等,好比如是windows的C:/Program Files/目录。
- ramdisk.img:内存磁盘映像。linux内核启动起来,要挂载一个文件系统作为自己的根文件系统,里面含有Linux内核启动过程中依赖的一些程序和配置文件。ramdisk.img就是一个最小化的根文件系统,它被加载到内存中作为Android的根文件系统。该映像是由out/target/product/generic/root目录打包生成的。前面所述的userdata.img和system.img映像,在linux系统启动起来后挂载到ramdisk.img中的data,system目录下。
其实,Android手机的ROM包(通常为update.zip文件),就是主要由上述三个映像文件构成的:
|
ROM包文件 |
说明 |
|
android-info.txt |
ROM版本及刷写配置信息 |
|
boot.img |
Linux内核zImage、ramdisk.img |
|
system.img |
Android系统映像 |
|
userdata.img |
用户数据映像 |
|
… |
其它映像 |
只要我们拿到手机的源码,就可以自己编译出自己的ROM,不过,一般手机厂商不会开源自己产品源码,都是第三方爱好者自己下载,修改编译的,如:业界著名的CM团队:http://www.cyanogenmod.com/。
由于完全编译Android系统耗时很长,并且Android源码由很多模块组成,我们可以通过下面一些编译命令来减少编译时间:
|
编译命令 |
说明 |
|
make snod |
打包生成system.img,不检查依赖关系 |
|
make bootimage |
打包生成ramdisk.img |
|
mmm |
指定编译某个目录下的模块 |
上述三个命令经常在我们源码开发时使用,希望大家记住。
2.3.3编译Linux内核
Android使用Linux内核,在源码级开发过程中,有时要修改内核代码,通常内核代码是和目标设备相关的,我们使用的是模拟器的内核,即使没有硬件设备也可以完成实验。
编译Android的内核,需要用到交叉编译器,我们可以直接使用Android源码里自带的arm-eabi-gcc编译器,为了编译出针对模拟器的内核(模拟器的CPU为Goldfish),还要配置内核(如果不知道如何配置内核,请读者阅读内核裁剪相关资料),为了方便我们编译Goldfish内核,我们编写了如下脚本,方便编译。
- $ cd /home/linux/android/android_source/kernel/goldfish/
- $ vi build_kernel.sh
添加如下内容:
@ /home/linux/android/android_source/kernel/goldfish/build_kernel.sh
- #!/bin/bash
- export PATH=/home/linux/android/android_source/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin:$PATH
- export ARCH=arm
- export SUBARCH=arm
- export CROSS_COMPILE=arm-eabi-
- if [ ! –f .config ] ; then
- make goldfish_armv7_defconfig
- fi
- make
注:当Andorid源码目录发生改变时,要修改PATH的路径,让它指向对应的交叉编译器。
给脚本加上可执行权限,然后执行该脚本:
- $ chmod a+x build_kernel.sh
- $ ./build_kernel.sh
内核编译完成如图x-x所示:
图 内核编译结果
转自:http://blog.csdn.net/mr_raptor/article/details/20934501
深入浅出 - Android系统移植与平台开发(五)- 编译Android源码(转)的更多相关文章
- 深入浅出 - Android系统移植与平台开发(一)
深入浅出 - Android系统移植与平台开发(一) 分类: Android移植2012-09-05 14:16 16173人阅读 评论(12) 收藏 举报 androidgitgooglejdkub ...
- 深入浅出 - Android系统移植与平台开发(五)- 定制手机模拟器ROM
一. 修改化定制Android4.0系统 Android系统启动时,先加载Linux内核,在Linux的framebuffer驱动里可以定制开 机界面,Linux内核启动成功后,挂载根文件系统,启动A ...
- 深入浅出 - Android系统移植与平台开发(三)- 编译并运行Android4.0模拟器
作者:唐老师,华清远见嵌入式学院讲师. 1. 编译Android模拟器 在Ubuntu下,我们可以在源码里编译出自己的模拟器及SDK等编译工具,当然这个和在windows里下载的看起来没有什么区别 ...
- 深入浅出 - Android系统移植与平台开发(二) - 准备Android开发环境
作者:唐老师,华清远见嵌入式学院讲师. 编译Android源码 关于android系统的编译,Android的官方网站上也给出了详细的说明.http://source.android.com/sour ...
- 深入浅出-Android系统移植与平台开发(一)- Android4.0系统的下载与编译
作者:唐老师,华清远见嵌入式学院讲师. 一.Android4.0系统的下载与编译 Android系统的下载与编译,Google的官方网站上已经给出了详细的说明,请参照Android的官方网址: htt ...
- 深入浅出 - Android系统移植与平台开发(十)- Android编译系统与定制Android平台系统(瘋耔修改篇二)
第四章.Android编译系统与定制Android平台系统 4.1Android编译系统 Android的源码由几十万个文件构成,这些文件之间有的相互依赖,有的又相互独立,它们按功能或类型又被放到不同 ...
- 深入浅出 - Android系统移植与平台开发(十一)- Android系统的定制(瘋耔修改篇一)
首先非常感谢原文作者为我们提供的知识库,因为有你们的贡献,我们的开发难度更显简单 原文 : http://blog.csdn.net/mr_raptor/article/details/30113 ...
- 深入浅出 - Android系统移植与平台开发(十二)- Android JNI机制
第五章.JNI机制 4.1 JNI概述 由前面基础知识可知,Android的应用层由Java语言编写,Framework框架层则是由Java代码与C/C++语言实现,之所以由两种不同的语言组合开发框架 ...
- 深入浅出 - Android系统移植与平台开发(六)- 为Android启动加速
作者:唐老师,华清远见嵌入式学院讲师. Android的启动速度一直以来是他的诟病,虽然现在Android设备的硬件速度越来越快,但是随着新 版本的出现,其启动速度一直都比较慢,当然,作为程序员,我们 ...
随机推荐
- JavaScript标记上的defer与async的作用与区别
当浏览器遇到 script 标签时,文档的解析将停止,并立即下载并执行脚本,脚本执行完毕后将继续解析文档.但是我们可以将脚本标记为 defer,这样就不会停止文档解析,等到文档解析完成才执行脚本,也可 ...
- Java第一次实验
北京电子科技学院(BESTI) 实验报告 课程: java实验 班级:1352 姓名:吕松鸿 学号:20135229 成绩: 指导教师: 娄嘉鹏 实验日期及时间:20 ...
- 20145312 GDB调试汇编堆栈过程分析
20145312 GDB调试汇编堆栈过程分析 参考资料 卢肖明同学的博客:<GDB调试汇编堆栈过程分析>: http://www.cnblogs.com/lxm20145215----/p ...
- 数据挖掘系列(4)使用weka做关联规则挖掘
前面几篇介绍了关联规则的一些基本概念和两个基本算法,但实际在商业应用中,写算法反而比较少,理解数据,把握数据,利用工具才是重要的,前面的基础篇是对算法的理解,这篇将介绍开源利用数据挖掘工具weka进行 ...
- 关闭Outlook时最小化 dll
用Outlook时最让我感觉不爽的就是不小心点了关闭按钮就会把Outlook关闭. 我们用软件的时候都希望软件有一个关闭时最小化功能,更希望Outlook也有这个功能 但让我很失望的是把设置里看了一个 ...
- CUDA编程学习(三)
我们知道一个grid包含多个block,而一个block又包含多个thread,下面将是如何进行下thread中的并行. /**** Splot a block into parallel threa ...
- 一种仿照Asp.net Mvc思维构建WebSocket服务器的方法
问题场景 Asp.net Mvc提供了DependencyResolver.Routing.Filter. Modelbinder等webForm所没有新概念,提高Web服务编写的便利性,记得很久之前 ...
- LinuxMint下Apache Http源码安装过程
1. 源码包下载 Apache Http安装要求必须安装APR.APR-Util.PCRE等包. Apache Http包下载地址:http://httpd.apache.org/download.c ...
- JavaScript和html5 canvas生成圆形印章
代码: function createSeal(id,company,name){ var canvas = document.getElementById(id); var context = ca ...
- 在ubuntu server上安装沸腾时刻环境
1. 安装php5.6 http://phpave.com/upgrade-to-php-56-on-ubuntu-1404-lts/ 按照这篇文章的顺序来做,可以安装最新5.6版本php 安装好了以 ...