Android Build System
android系统编译是基于一个较新版本的GNU Make(也许android使用的某些新特性都有可能没有在GNU Make的官方网站列出)。在编译之前,请通过执行 % make -v 来查看Make的版本号。如果版本号低于3.80,那么就需要更新你的Make版本。
Understanding the makefile
makefile 被用来编译指定的应用程序(application),makefile文件一般都会包含如下的几个元素:
1.Name: 编译的应用程序名称(LOCAL_MODULE V := <build_name>)
2.Local Variables: 使用CLEAR_VARS清除本地变量(include $(CLEAR_VARS))
3.Files: 应用程序的源码文件(LOCAL_SRC_FILES := main.c)
4.Tags: 按需给出tags定义(LOCAL_MODULE_TAGS := eng development)
5.Libraries: 定义应用程序将要连接的库(LOCAL_SHARED_LIBRARIES := cutils)
6.Template file: 包含一个make tools 下的模板文件来指定将应用编译成特定的目标(include $(BUILD_EXECUTABLE))
下面小段是一个典型的makefile举例(the following snippet illustrates a typical makefile).
include $(CLEAR_VARS)
LOCAL_MODULE := <buil_name>
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
Layers
编译层级架构(hierarchy)包括下表描述的几个抽象层。
每个层都对应上面的一个元素(element),它们是一个一对多的关系。例如:一个芯片架构(arch)可以有多余一个板级架构(board)并且每一个板级架构(board)都可以有超于一个的设备架构(device)。你可以给每一个层定义一个元素(element)作为某一个层的特别元素(element),这样就免除了拷贝并简化了维护(eliminating copying and simplifying maintenance)。
Layer | Example | Description |
---|---|---|
Product | myProduct, myProduct_eu, myProduct_eu_fr, j2, sdk | The product layer defines a complete specification of a shipping product, defining which modules to build and how to configure them. You might offer a device in several different versions based on locale, for example, or on features such as a camera.(产品层定义了一个完整的特定的销售产品,定义了那些模块会被编译和怎样配置它们。你也许会基于本机的一些情况为设备定义出几种不同版本,如,摄像头特性) |
Device | myDevice, myDevice_eu, myDevice_eu_lite | The device layer represents the physical layer of plastic on the device. For example, North American devices probably include QWERTY keyboards whereas devices sold in France probably include AZERTY keyboards. Peripherals typically connect to the device layer.(设备层描述了在设备上一些可变的物理硬件层。例如:北美设备也许包括QWERTY键盘,然而在法国售卖的设备包括AZERTY键盘。外围设备一般都被认为是与设备层相关) |
Board | sardine, trout, goldfish | The board layer represents the bare schematics of a product. You may still connect peripherals to the board layer.(板级架构描述了一个产品的基本最小核心架构。也许在板子上仍旧还接有外设。) |
Arch | arm (arm5te) (arm6), x86, 68k | The arch layer describes the processor running on your board.(架构层定义了在电路板上运行的处理器) |
Building the Android Platform
Device Code
% . build/envsetup.sh
# pick a configuration using choosecombo
% choosecombo
% make -j4 PRODUCT-generic-user
你也可以用eng 替换 user 编译成一个调试工程(you can also replace user with eng for a debug engineering build):
这些变种编译(Build Variants)区别在于调试选项和包的安装(these build variants differ in terms of debug options and packages installed)。
Cleaning Up
执行 % m clean 可以清除刚刚生成的二进制文件。同样可以执行 % m clobber 删除所有的二进制文件(the binaries of all combos)。% m clobber 相当于删除//out/目录的所有文件,这个目录也是生成文件存储的位置。
Speeding Up Rebuilds
每一种编译组合将作为一个子目录存储在//out/目录下,这样就有可能在不同组合间快速的切换编译而不需要每次都编译整个源码。
但是,执行了清除命令,编译系统没有获取到变化的环境变量或者makefiles那么就需要重新编译整个源码。如果这种情况经常发生,那么你就有必要按照如下定义USE_CCACHE环境变量:
这样就会强制编译系统使用编译器缓存工具(ccache:compiler cache),这个工具可以减少重新编译的代码。ccache二进制执行文件已经在//prebuilt/...目录下(如:prebuilt/linux-x86/ccache)而不需要再在系统中安装。
Troubleshooting
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)
[...]
dx 是一个java程序,有用的工具,最先是在Java version 1.5中使用。通过执行% java -version 命令来确认用来编译的Java版本。然后你也许会看到如下信息:
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)
如果你的Java 版本不小于1.5但还出现上面错误,那么请确认你已经完好的更新了你的PATH变量。
Building the Android Kernel
% partner_setup generic
然后切换到kernel目录/home/joe/android/kernel
Checking Out a Branch
android
. To check out a different branch, execute the following:
//Branch android-mydevice set up to track remote branch
% refs/remotes/origin/android-mydevice.
//Switched to a new branch "android-mydevice"
% git checkout <branchname>
.Verifying Location
android
* android-mydevice
origin/HEAD
origin/android
origin/android-mydevice
origin/android-mychipset
-a
flag.
Building the Kernel
Build Variants
eng | This is the default flavor(原版). A plain(普通) make is the same as make eng .
|
user | make user This is the flavor intended to be the final release bits.
|
userdebug | make userdebug The same as
|