一,一般编译流程演示

首先我们要先进入Android源码根目录,然后执行一系列source命令来配置我们的编译环境,其次使用choosecombo命令或lunch命令来配置我们的编译目标,最后使用make命令开始编译系统。

yqm@unbuntu:cd ~/SourceCode/8909-la301
yqm@unbuntu:~/SourceCode/8909-la301$ source build/envsetup.sh 
including device/generic/car/vendorsetup.sh
including device/generic/mini-emulator-arm64/vendorsetup.sh
including device/generic/mini-emulator-armv7-a-neon/vendorsetup.sh
including device/generic/mini-emulator-x86_64/vendorsetup.sh
including device/generic/mini-emulator-x86/vendorsetup.sh
including device/generic/uml/vendorsetup.sh
including device/qcom/common/vendorsetup.sh
including vendor/qcom/proprietary/common/vendorsetup.sh
including sdk/bash_completion/adb.bash
yqm@unbuntu:~/SourceCode/8909-la301$ source java8.sh
yqm@unbuntu:~/SourceCode/8909-la301$ choosecombo
Build type choices are:
     1. release
     2. debug

Which would you like? [1] 1


Product choices are:
     1. msm8909_512go
     2. msm8909go
     3. msm8909
     4. msm8909_q20_a8
     5. msm8909_q20_g32_tigo
     6. msm8909_x20d_a8
     7. msm8909_x20_g32_go
     8. msm8996
Which product would you like? [msm8909_x20d_a8] 5


Variant choices are:
     1. user
     2. userdebug
     3. eng
Which would you like? [eng] 2

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=8.1.0
TARGET_PRODUCT=msm8909_q20_g32_tigo
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_PLATFORM_VERSION=OPM1
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a-neon
TARGET_CPU_VARIANT=cortex-a7
TARGET_2ND_ARCH=
TARGET_2ND_ARCH_VARIANT=
TARGET_2ND_CPU_VARIANT=
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-3.2.0-23-generic-x86_64-with-Ubuntu-12.04-precise
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=OPM1.171019.019
OUT_DIR=out
AUX_OS_VARIANT_LIST=
============================================
yqm@unbuntu:~/SourceCode/8909-la301$make
yqm@unbuntu:~/SourceCode/8909-la301$

二,编译流程详细解读

1,source build/envsetup.sh

很显然这个命令是用来执行环境设置脚本的,执行过后,可以直接在终端使用一些命令,如下所示:

  • croot:切换到Android源码根目录
  • m:编译整个系统
  • mm:编译当前目录下的模块(当前目录下需要有Android.mk这个makefile文件,否则就往上找最近的Android.mk文件。),而不编译它所依赖的其他模块。
  • mmm:编译指定目录下的模块,同mm不编译它所依赖的其他模块。
  • cgrep:格式化查找C(.c、.cc、.cpp、.h)文件
  • jgrep:格式化查找Java(.java)文件
  • resgrep:格式化查找资源(xml)文件
  • printconfig:打印配置信息
  • choosecombo:配置编译目标
  • lunch:配置编译目标

更多功能,请查看envsetup.sh源码

2,source java8.sh

这个命令是用来切换JDK的,因为不同的Android版本对编译系统的Java版本和操作系统版本是有要求的。

需要将这个脚本先复制到Android源码根目录。脚本内容如下:

#!/bin/sh
export JAVA_HOME=~/EnvTools/java-1.8.0-openjdk-amd64
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

3,choosecombo

这个命令会依次让我们设置:
1)TARGET_BUILD_TYPE:目标构建类型,可选择release或者debug
2)TARGET_PRODUCT:需要构建目标产品,可选择所有在根目录的device目录下定义的设备
3)TARGET_BUILD_VARIANT:目标构建类型,可选择user、userdebug、eng,这里的选择会决定生成的系统的权限大小。user就是没有root权限的,userdebug和eng都有root权限,但是eng比userdebug拥有更高级的权限。

4,make

编译整个安卓系统。
可选子命令有:
1)make clean [ModuleName]清除所有out目录下的内容或out目录下指定模块的目录
2)make [ModuleName]只编译指定模块,比如只编译系统镜像make systemimage 3)make showcommands:列出编译是详细执行的各个命令
4)make update-api:当我们修改了framework的内容需要先用这个命令生成新的API,否则之间编译将不会通过
可选的参数有:
1)-jn:使用n个线程来编译,n为整数

三,全编和增量编译

一般的编译方式都会采用增量编译,即只编译发生变化的目标文件,但有时则需要重新编译所有目标文件,那么就可以使用make 命令行的-B选项。例如:mm -B 模块名,或者mm -B、mmm -B。在mm 和 mmm内部也是调用make命令的,而make的-B选项将强制编译所有的目标文件。

四,mm、mmm和mma、mmma

mm和mmm默认是不会编译它所依赖的模块的,所以在没有全编过系统的情况下,若是初次编译,采用此种模式编译一个模块往往会报错,错误的原因就在于它依赖的其他模块没有一起编译。而使用mma和mmma则会编译它所依赖的模块,就不会产生错误。