Android Build System

http://source.android.com/porting/build_system.html#top Android 是用一个客制化的编译系统来产生工具,二进制代码,文件系统(documentation)。本文档提供一个Android系统编译的简介以及简单的范例。

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).

android system setup and building (1) 代码 LOCAL_PATH:=$(my-dir)
include$(CLEAR_VARS)
LOCAL_MODULE:=<buil_name>
LOCAL_SRC_FILES:=main.c
LOCAL_MODULE_TAGS:=engdevelopment
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

The snippet(片段) above includes artificial(人为修改) line breaks to maintain a print-friendly document.

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

本段描述怎样编译默认的android版本。一旦当你能熟悉编译一般的版本,那么你就可以开始修改Anadroid编译成适合你自己目标设备的版本。

Device Code

为编译一个普通版本的android,请使用build/envsetup.sh脚本设置环境变量(source build/envsetup.sh)。这个脚本包含了必要的变量和功能定义,描述如下:

%cd$TOP

%.build/envsetup.sh

#pickaconfigurationusingchoosecombo
%choosecombo

%make-j4PRODUCT-generic-user

你也可以用eng 替换 user 编译成一个调试工程(you can also replace user with eng for a debug engineering build):

%make-j4PRODUCT-generic- eng

这些变种编译(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环境变量:

%exportUSE_CCACHE=1

这样就会强制编译系统使用编译器缓存工具(ccache:compiler cache),这个工具可以减少重新编译的代码。ccache二进制执行文件已经在//prebuilt/...目录下(如:prebuilt/linux-x86/ccache)而不需要再在系统中安装。

Troubleshooting

下面问题很有可能就是使用了过时的Java版本引起的。

android system setup and building (1) 代码 deviceDex:coreUNEXPECTEDTOP-LEVELERROR:
java.lang.NoSuchMethodError:methodjava.util.Arrays.hashCodewith
signature([Ljava.lang.Object;)Iwasnotfound.
atcom.google.util.FixedSizeList.hashCode(FixedSizeList.java:66)
atcom.google.rop.code.Rop.hashCode(Rop.java:245)
atjava.util.HashMap.hash(libgcj.so.7)
[...]

dx 是一个java程序,有用的工具,最先是在Java version 1.5中使用。通过执行% java -version 命令来确认用来编译的Java版本。然后你也许会看到如下信息:

javaversion"1.5.0_07"
Java(TM)2RuntimeEnvironment,StandardEdition(build1.5.0_07-164)
JavaHotSpot(TM)ClientVM(build1.5.0_07-87,mixedmode,sharing)

如果你的Java 版本不小于1.5但还出现上面错误,那么请确认你已经完好的更新了你的PATH变量。

Building the Android Kernel

本段描述怎样编译Android的默认内核。当你熟悉一般的编译后,那么你就可以开始为你的目标设备更改Android 驱动。为了编译基本的内核,切换到设备目录(/home/joe/android/device)为了建立相关变量请执行如下命令:

%.build/envsetup.sh
%partner_setupgeneric

然后切换到kernel目录/home/joe/android/kernel

Checking Out a Branch

The default branch is always android. To check out a different branch, execute the following:

android system setup and building (1) 代码 %gitcheckout--track-bandroid-mydeviceorigin/android-mydevice
//Branchandroid-mydevicesetuptotrackremotebranch
%refs/remotes/origin/android-mydevice.
//Switchedtoanewbranch"android-mydevice"

To simplify code management, give your local branch the same name as the remote branch it is tracking (as illustrated in the snippet above). Switch between branches by executing % git checkout <branchname> .

Verifying Location

Find out which branches exist (both locally and remotely) and which one is active (marked with an asterisk[星号]) by executing the following:

%gitbranch-a
android
*android-mydevice
origin/HEAD
origin/android
origin/android-mydevice
origin/android-mychipset

To only see local branches, omit[忽略] the -a flag.

Building the Kernel

%make-j4

Build Variants

当编译一个特定的产品,在最终编译版本中使用一些少量的可变参数是很有用的(it's often useful to have minor variations on what is ultimately the final release build)。下面都是目前被定义的一些编译变量:

eng This is the default flavor(原版). A plain(普通) make is the same as make eng.
  • Installs modules tagged with: eng, debug, user, and/or development.
  • Installs non-APK modules that have no tags specified.
  • Installs APKs according to the product definition files, in addition to tagged APKs.
  • ro.secure=0
  • ro.debuggable=1
  • ro.kernel.android.checkjni=1
  • adb is enabled by default.
user make user

This is the flavor intended to be the final release bits.

  • Installs modules tagged with user.
  • Installs non-APK modules that have no tags specified.
  • Installs APKs according to the product definition files; tags are ignored for APK modules.
  • ro.secure=1
  • ro.debuggable=0
  • adb is disabled by default.
userdebug make userdebug

The same as user, except:

  • Also installs modules tagged with debug.
  • ro.debuggable=1
  • adb is enabled by default.
如果你编译了某种特殊(flavor)的版本,然后要编译其它特殊版本,你必须在两次执行 make之间执行 make installclean来担保(guarantee)你不会使用前一个特殊版本安装的文件。 make clean 同样可以满足要求(suffice),但是将会消耗更多的时间。

更多相关文章

  1. Android的Camera架构介绍
  2. Android版本问题记录:Android 8.0下异常Only fullscreen opaque a
  3. 自定义View系列教程01--常用工具介绍
  4. Android中自己定义一个shade.xml
  5. Android四款系统架构工具
  6. Android 自定义View自定义属性的声明
  7. 2017年起至今的android各版本占比(持续更新)

随机推荐

  1. Android之Android(安卓)N多窗口
  2. Android之——多线程断点续传下载示例
  3. Android基础_页面布局_TableLayout(表格
  4. Android之AsyncTask异步任务详解总结
  5. 20180502_从零开始的android持久库room其
  6. Android 推送通知指南
  7. Android(安卓)控件框架
  8. ELIPS Studio 3 Beta 6支持iPhone和Andro
  9. android SDK安装出现Failed to fetch URL
  10. 【Android(安卓)界面效果34】Android里Se