深入浅出 - Android系统移植与平台开发(五)- 编译Android源码
来源:互联网 发布:成都泰迪熊博物馆淘宝 编辑:程序博客网 时间:2024/06/05 06:08
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命令来查看所有加载的命令。
$ helpInvoke ". 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源码,可以编译出针对不同产品的系统。通过选择一个目标编译项,来决定编译出针对哪个产品的系统,我们可以通过执行下面的命令来选择要编译的目标系统:
$ lunchYou're building on Linux generic-eng simulator Lunch menu... pick a combo: 1. generic-eng 2. simulatorWhich would you like? [generic-eng]
通过lunch命令可知,让用户输入目标编译项,我们可以选择编译项前的数字,也可以直接输入编译项的名字。
…接前面终端输出信息
Which would you like? [generic-eng]1 [回车]============================================PLATFORM_VERSION_CODENAME=RELPLATFORM_VERSION=2.1-update1TARGET_PRODUCT=genericTARGET_BUILD_VARIANT=engTARGET_SIMULATOR=falseTARGET_BUILD_TYPE=releaseTARGET_ARCH=armHOST_ARCH=x86HOST_OS=linuxHOST_BUILD_TYPE=releaseBUILD_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/bashexport PATH=/home/linux/android/android_source/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin:$PATHexport ARCH=armexport SUBARCH=arm export CROSS_COMPILE=arm-eabi- if [ ! –f .config ] ; thenmake goldfish_armv7_defconfig fimake
注:当Andorid源码目录发生改变时,要修改PATH的路径,让它指向对应的交叉编译器。
给脚本加上可执行权限,然后执行该脚本:
$ chmod a+x build_kernel.sh$ ./build_kernel.sh
内核编译完成如图x-x所示:
图x-x 内核编译结果
- 深入浅出 - Android系统移植与平台开发(五)- 编译Android源码
- 深入浅出 - Android系统移植与平台开发(五)- 编译Android源码
- 深入浅出 - Android系统移植与平台开发(十)- Android编译系统与定制Android平台系统
- 深入浅出 - Android系统移植与平台开发(十)- Android编译系统与定制Android平台系统
- 深入浅出 - Android系统移植与平台开发(十)- Android编译系统与定制Android平台系统
- 深入浅出 - Android系统移植与平台开发
- 深入浅出 - Android系统移植与平台开发
- 深入浅出 - Android系统移植与平台开发(五)- 定制手机模拟器ROM
- 深入浅出 - Android系统移植与平台开发(五)- 定制手机模拟器ROM
- 深入浅出 - Android系统移植与平台开发(五)- 定制手机模拟器ROM
- 深入浅出 - Android系统移植与平台开发(五)- 定制手机模拟器ROM
- 深入浅出 - Android系统移植与平台开发(三)- 编译并运行Android4.0模拟器
- 深入浅出 - Android系统移植与平台开发(三)- 编译并运行Android4.0模拟器
- 深入浅出 - Android系统移植与平台开发(三)- 编译并运行Android4.0模拟器
- 深入浅出 - Android系统移植与平台开发(四)- 搭建Linux编译环境
- 深入浅出 - Android系统移植与平台开发(三)- 编译并运行Android4.0模拟器
- 深入浅出 - Android系统移植与平台开发(四)- 搭建Linux编译环境
- 深入浅出 - Android系统移植与平台开发(一)
- GCDAsyncSocket类库,IOS下TCP通讯使用心得
- linux2.6.31版本以后usb/devices输出信息使用usb-devices查看
- HibernateSessionFactoryUtil
- 《黑马程序员》 使用反射替换类中的变量的值
- C语言函数指针参数也是传值调用
- 深入浅出 - Android系统移植与平台开发(五)- 编译Android源码
- 深度分析如何在Hadoop中控制Map的数量
- ARP逆过程——RARP协议流程
- 纯javascript实现广告的无缝滚动
- 通用乱码解决方案
- 分时系统
- Android 向右滑动销毁(finish)Activity, 随着手势的滑动而滑动的效果
- ios 如何让TableView加入横向滑动出现删除按钮的功能
- C#之Excel文件读取