Android 编译系统
android使用自己定制的编译系统来生成工具、二进制文件和文档。本文档提供了一个android编译系统的概述,并做了一个简单的编译说明。
android的编译系统基于最近版本的GNU Make(注:android使用GNU Make一些高级的特性,这些特性可能并不一定在GNU Make官网上出现)。在继续下面的步骤前,请用make -v在检测你的Make版本。如果你的版本在3.80以下,你则需要更新你的Make。
理解Makefile
一个makefile定义了如何编译一个特定的应用程序。典型的makefile一般包括下面几个元素:
1. 名 字:给出要编译目标的名字 (LOCAL_MOUDLE := )
2. 本地变量:用CLEAR_VAR清除本地变量 (include $(CLEAR_CARS))
3. 文 件:决定你的应用所依赖的源文件 (LOCAL_SRC_FILES := main.c)
4. 标 签:必要时,定义标签 (LOCAL_MODULE_TAGS :=ENG development)
5. 库 文 件:定义你的应用程序所需链接的库文件(LOCAL_SHARED_LIBRARIES := cutils)
6. 模板 文件:针对特定目标,包含一个模板文件 (include $(BUILD_EXECUTABLE))
下面的代码片段就介绍了一个典型的makefile
- LOCAL_PATH := $(my-dir)
-
include $(CLEAR_VARS)
-
LOCAL_MODULE :=
-
LOCAL_SRC_FILES := main.c
-
LOCAL_MODULE_TAGS := eng development
-
LOCAL_SHARED_LIBRARIES := cutils
-
include $(BUILD_EXECUTABLE)
-
(HOST_)EXECUTABLE, (HOST_)JAVA_LIBRARY, (HOST_)PREBUILT, (HOST_)SHARED_LIBRARY,
-
(HOST_)STATIC_LIBRARY, PACKAGE, JAVADOC, RAW_EXECUTABLE, RAW_STATIC_LIBRARY,
-
COPY_HEADERS, KEY_CHAR_MAP
图层
下表所描述的图层是对android编译系统的抽象
每一层都涉及到它上面的一个的一个一对多的关系。例如,Arch可以有超过一个Board,每块Borad可以有一个以上的Device。您可以在一个给定的图层中定义一个与其他元素相似的元素,从而简化维护。
-------------------------------------------------------------------------------------------------------------------------------------
图层 例子 描述
-------------------------------------------------------------------------------------------------------------------------------------
Product myProduct 该图层定义了一个规格完整的产品,定义了编译哪些模块和怎样配置它们
-------------------------------------------------------------------------------------------------------------------------------------
Device myDevice 该层代表设备的物理层,例如,北美设备可能包括QWERTY键盘,
而在法国出售的设备可能包括AZERTY键盘。外设通常链接到该层。
--------------------------------------------------------------------------------------------------------------------------------------
Borad goldfish trout 该层代表一个产品的裸的原理图。你也可以连接外围设备到该层。
--------------------------------------------------------------------------------------------------------------------------------------
Arch arm x86 该层描述了你板子上跑的处理器
---------------------------------------------------------------------------------------------------------------------------------------
编译Android平台
这部分描述如何编译android的默认版本。一旦你了解了通用的编译方式,你就可以开始适配你自己的目标板了。
设备源码
编译通用版本的android,首先source build/envsetup.sh 这个文件包含了必要的变量和函数定义,如下:
$cd $TOP
$. build/envsetup.sh
$choosecombo
$make -j4 PROUDUCT-generic-user
你也可以用eng代替user进行编译,方便调试。
$make -j4 PRODUCT-generic-eng
这些选项(eng、user...)不同于调试选项和安装的包
清除
执行$m clean清除你刚刚编译出的二进制文件。你也可以执行$m clobber来清除所有组合下的二进制文件,不同的是$m clobber会把存储目标文件的out目录删除。
快速重新编译
每一个组合会存储在out子目录下,如果可以在编译组合间切换,而不是每次都把所有的源码都编译,那就可以更快地编译了
然而,如果编译系统没有捕获到环境变量或Makefile的改变,执行纯净的重新编译是还是有必要的。如果这经常发生的话,你可以这样定义环境变量:
$export USE_CCACHE=1
这样做将强制编译系统使用ccache编译cache tool。它将重新编译所有源码
ccache二进制文件在prebuilt目录下,并且不用安装到你的系统里
常见问题
一下错误很可能是由运行较早版本的java所引起的错误
device Dex: core UNEXPECTED TOP-LEVEL ERROR:
java.lang.NoSuchMethodError: method java.util.Arrays.hashCode with
signature ([Ljava.lang.Object;)I was not found.
at com.google.util.FixedSizeList.hashCode(FixedSizeList.java:66)
at com.google.rop.code.Rop.hashCode(Rop.java:245)
at java.util.HashMap.hash(libgcj.so.7)
[...]
检查你的java版本,你应该看到如下信息
$java -version
java version "1.5.0_07"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-164)
Java HotSpot(TM) Client VM (build 1.5.0_07-87, mixed mode, sharing)如果你发生了上述错误,但确实使用的java1.5或更新的,就请确认一下你的PATH变量
编译android内核
这部分描述了如何编译android默认内核,一旦你了解了通用的编译方式,你就可以为你的目标板适配android驱动了
在编译内核前,切换到device目录以建立环境变量
$. build/envsetup.sh
$partner_setup generic
然后切换到kernel目录
检查分支
默认的分支一直是android。为了检查不同的分支,执行如下命令:
$git checkout --track -b android-mydevice origin/android-mydevice
//Branch android-mydevice set up to track remote branch
$refs/remotes/origin/android-mydevice.
//Switched to a new branch "android-mydevice"
为了简化代码管理,让你当地的分支与远程它是跟踪(在上面的代码片段所示)分支名字相同,通过执行$git checkout .分支之间切换。
验证
靠执行下面的命令可以找出那些分支是存在的,那些是积极的(标有星号的)
$
git branch -a
android
* android-mydevice
origin/HEAD
origin/android
origin/android-mydevice
origin/android-mychipset略去-a参数 就可以只看到本地分支了
编译内核
$make -j4
编译选项
当编译一个特定版本时,相对最终版本经常会有些轻微的改动,这些标签就变得有用了
这些是当前定义的编译选项
eng
这是一个默认的选项,执行make 和make eng是一样的
1. 安装具有eng、user、and/or developement标签的模块
2. 安装没有标签的非apk模块
3. 根据product定义安装apk和具有标签的apk
4.ro.secure=0
5.ro.debuggable=1
6.ro.kernel.android.checkjni=1
7.adb默认可用
user
1. 安装具有user标签的模块
2. 安装没有标签的非apk模块
3. 根据product定义安装apk,apk忽略标签
4. ro.secure=1
5. ro.debuggable=0
7. adb 默认不可用
userdebug
同user,除了
1. 同时安装具有debug标签的模块
2. ro.debuggable=1
3 adb默认可用
如果你编译时是一种标签,又想编译其他的,在两次make之间 你应该运行make installclean。make clean也可以,但是会花更多的时间
译自:
阅读(4838) | 评论(1) | 转发(0) |