一,一般编译流程演示
首先我们要先进入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版本和操作系统版本是有要求的。
注:
1)详细的Java版本和操作系统版本要求请参考,Google官网的文章:要求-操作系统和JDK
2)需要将这个脚本先复制到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则会编译它所依赖的模块,就不会产生错误。
以上是个人关于Android系统源码的编译总结,如有错误欢迎指正。