执行编译
Linux内核编译
不同产品的硬件配置,生产商,型号都可能不一样。这就涉及到了内核驱动的移植。
其他地方讨论的编译流程都只针对Android系统本身。
但是,Linux内核和Android的编译都是独立的。
对于设备开发商来说,还要 下载,修改,编译 内核版本。
make编译系统
Android 编译命令 - 狼太白 - 博客园 (cnblogs.com)
Android 编译系统是Android源码的一部分,用于编译Android系统,Android SDK以及相关文档。该编译系统是由Make文件、Shell以及Python脚本共同组成,其中最为重要的便是Make文件。关于编译系统可参考 理解 Android Build 系统。
选择编译命令 make m …
source build/envsetup.sh
命令执行成功后,我们会得到了一些有用的命令,比如
make、m、mm、mmm
对于
m、mm、mmm、mma、mmma
这些命令的实现都是通过make
方式来完成的。
-
make/mma/mmma编译时会把所有的依赖模块一同编译,但mmm/mm不会;
- mmm/mm编译的效率很高,而make/mma/mmma编译较缓慢;
- 建议:首次编译时采用make/mma/mmma编译;当依赖模块已经编译过的情况,则使用mmm/mm编译。
-
m: Makes from the top of the tree.
-
mm: Builds all of the modules in the current directory.
-
mmm: Builds all of the modules in the supplied directories.
make
make指令——开始编译整个系统
该指令通过-j参数来设置参与编译的线程数量,以提高编译速度。
-j参数
取决于开发机器的CPU数,每颗CPU的核心数,每个核心的线程数。- 通常根据cup的核心来确定:core*2,即当前cpu的核心的2倍。
# 查看相关cpu信息
cat /proc/cpuinfo
# 双核四线程的,根据公式。最快速的编译可以make -j8.
make -j8
m mm mma …
除了通过make命令编译可以整个android源码外,
Google也为我们提供了相应的命令来支持单独模块的编译.
编译指令 | 解释 |
---|---|
m | 在源码树的根目录执行make编译 |
mm | make编译当前路径下所有模块,但不包含依赖 |
mmm [module_path] | make编译指定路径下所有模块,但不包含依赖 |
mma | make编译当前路径下所有模块,且包含依赖 |
mmma [module_path] | make编译指定路径下所有模块,且包含依赖 |
make [module_name] | 无参数,则表示编译整个Android代码 |
下面列举部分模块的编译指令:
模块 | make命令 | mmm命令 |
---|---|---|
init | make init | mmm system/core/init |
zygote | make app_process | mmm frameworks/base/cmds/app_process |
system_server | make services | mmm frameworks/base/services |
java framework | make framework | mmm frameworks/base |
framework资源 | make framework-res | mmm frameworks/base/core/res |
jni framework | make libandroid_runtime | mmm frameworks/base/core/jni |
binder | make libbinder | mmm frameworks/native/libs/binder |
其他命令
代码搜索
搜索指令 | 解释 |
---|---|
croot | 回到树的根位置,AOSP工程的根目录 |
cgrep | 所有C/C++文件执行搜索操作 |
jgrep | 所有Java文件执行搜索操作 |
ggrep | 所有Gradle文件执行搜索操作 |
mangrep [keyword] | 所有AndroidManifest.xml文件执行搜索操作 |
mgrep [keyword] | 所有Android.mk文件执行搜索操作 |
sepgrep [keyword] | 所有sepolicy文件执行搜索操作 |
resgrep [keyword] | 所有本地res/*.xml文件执行搜索操作 |
sgrep [keyword] | 所有资源文件执行搜索操作 |
godir | 转到包含指定文件的目录下 |
导航指令
导航指令 | 解释 |
---|---|
croot | 切换至Android根目录 |
cproj | 切换至工程的根目录 |
godir [filename] | 跳转到包含某个文件的目录 |
Tips:
当每次修改完某个文件后需要编译时,
- 修改文件
- 执行
cproj
后会跳转到当前模块的根目录,也就是Android.mk文件所在目录, - 执行mm指令,即可编译目标模块;
当进入源码层级很深后,需要返回到根目录,
- 使用
croot
一条指令完成;
make clean/update-api
再列举两个比较常用的指令:
- make clean:执行清理操作,等价于
rm -rf out/
- make update-api:更新API,在framework API改动后需执行该指令,Api记录在目录
frameworks/base/api
;
Makefile分类
整个Build系统的Make文件分为三大类:
系统核心的Make文件:
- 文件全部位于路径
/build/core
, - 定义了Build系统的框架,
- 其他Make文件都是基于该框架编写的;
针对产品的Make文件:
-
文件路径位于
/device
-
定义了具体某个型号手机的Make文件,
-
该目录下往往又以公司名和产品名划分两个子级目录,
比如
/device/qcom/msm8916
;
针对模块的Make文件:模块编译
-
用于编译某个模块的标准。
-
整个系统分为各个独立的模块
整个产品由很多
Android.mk
生产出的“零件”组合而成。 -
每个模块都一个专门的Make文件,名称统一为”Android.mk”,该文件定义了当前模块的编译方式。
-
Build系统会扫描整个源码树中名为”Android.mk”的问题,并执行相应模块的编译工作。
解析过程
典型的解析过程:
- 变量赋值,环境检测等初始化操作
- 按照规则生成所有依赖树
- 根据被用户选择的依赖树,从叶到根逐步生成目标文件
树根节点 droid
/Makefile
make
命令对依赖树的根节点是:droid
编译系统中往往不止一颗依赖树存在。
- 显示指定编译目标——
make sdk
…- 指定部分编译目标后,对
ONE_SHOT_MAKEFILE
进行赋值(否则为空)
- 指定部分编译目标后,对
- 没有显示指定——不带任何参数的
make
- 第一个符合要求的目标,会被Make作为默认的依赖树根节点
- 在Makefile中,一定要注意各Target的排放顺序
make # make命令 执行根目录下的Makefile文件
# 默认的找名为`GNUmakefile`、`makefile`、`Makefile`的文件
./Makefile
### DO NOT EDIT THIS FILE ###
include build/make/core/main.mk
### DO NOT EDIT THIS FILE ###
main.mk
/sm8350_r_13300_dev_i7/build/core/main.mk
# This is the default target. It must be the first declared target.
.PHONY: droid
DEFAULT_GOAL := droid
$(DEFAULT_GOAL): droid_targets
droid
-
这里的
droid
是一个空的 “规则”,相当于预先占个地方 -
真正的定义在
main.mk
的其他地方, -
根据
TARGET_BUILD_APPS
值的不同,出现了两个分支# Some modules produce only host installed files when building with TARGET_BUILD_APPS ifeq ($(TARGET_BUILD_APPS),)
- 编译整个系统
- 依赖 droidcore——后续介绍
- 依赖 dist_files——在out目录下产生专门的dist文件夹,存储多种分发包
# Building a full system-- the default is to build droidcore droid_targets: droidcore dist_files
- 只依赖apps_only
apps_only: $(unbundled_build_modules) droid_targets: apps_only
- 编译整个系统
droidcore节点
在编译整个Android系统的情况下,droid依赖于droidcore,dist_files。
-
droidcore负责生成系统的所有可运行程序包
包括以下 img 文件
# Build files and then package it into the rom formats
.PHONY: droidcore
droidcore: $(filter $(HOST_OUT_ROOT)/%,$(modules_to_install)) \
$(INSTALLED_SYSTEMIMAGE_TARGET) \
$(INSTALLED_RAMDISK_TARGET) \
$(INSTALLED_BOOTIMAGE_TARGET) \
$(INSTALLED_RADIOIMAGE_TARGET) \
$(INSTALLED_DEBUG_RAMDISK_TARGET) \
$(INSTALLED_DEBUG_BOOTIMAGE_TARGET) \
$(INSTALLED_RECOVERYIMAGE_TARGET) \
# ...
.img
$(INSTALLED_SYSTEMIMAGE_TARGET)
生成 system.img
$(INSTALLED_BOOTIMAGE_TARGET)
生成 boot.img
$(INSTALLED_RECOVERYIMAGE_TARGET)
生成 recovery.img
$(INSTALLED_USERDATAIMAGE_TARGET)
生成 userdata.img
$(INSTALLED_CACHEIMAGE_TARGET)
生成 cache.img
$(INSTALLED_VENDORIMAGE_TARGET)
生成 vendor.imb
$(INSTALLED_FILES_FILE)
生成 installed-files.txt
,记录当前系统中预装的程序、库等
files
描述了系统需要安装的模块
# All the droid stuff, in directories
.PHONY: files
files: $(modules_to_install) \
$(INSTALLED_ANDROID_INFO_TXT_TARGET)
modules_to_install
描述了系统需要安装的模块
# TODO: Remove the 3 places in the tree that use ALL_DEFAULT_INSTALLED_MODULES
# and get rid of it from this list.
modules_to_install := $(sort \
$(ALL_DEFAULT_INSTALLED_MODULES) \
$(product_target_FILES) \
$(product_host_FILES) \
$(CUSTOM_MODULES) \
)
INSTALLED_ANDROID_INFO_TXT_TARGET
vendor编译
product.mk
之前内容请看 Android编译
–>定制产品
板级特性 AndroidProducts.mk中,通过
PRODUCT_MAKEFILES
来指定商品的属性的makefile
envsetup.sh::source_vendorsetup # 执行扫描到的 vendorsetup.sh 们
build/soong/ui/build/finder.go # 找到 AndroidProducts.mk
# 添加到选单, 为lunch命令添加一条加载项
AndroidProducts.mk::COMMON_LUNCH_CHOICES
# 引入产品makefile
AndroidProducts.mk::PRODUCT_MAKEFILES
lahaina.mk
pineapple.mk
pixelworks_iris.mk
AndroidProducts.mk::PRODUCT_MAKEFILES
添加 lahaina.mk
在 lahaina.mk 中,pixelworks_iris.mk
被引入编译。
pixelworks_iris.mk
设置了BOARD_HAS_PXLW_IRIS
# device/qcom/lahaina/lahaina.mk
-include vendor/pixelworks/libirisservice/config/pixelworks_iris.mk
# vendor/pixelworks/libirisservice/config/pixelworks_iris.mk
BOARD_HAS_PXLW_IRIS := true
具体内容看下一大章。
pixelworks_iris.mk
在这里从pixelworks_iris.mk
开始说起。
vendor/pixelworks/libirisservice/config/
pixelworks_iris.mk
同目录下还有很多其他 xxx_pixelworks_iris_xxx.mk
。它们都是类似的
vendor/pixelworks/libirisservice/
config/
宏
这里的宏会在其他仓库中被使用。
BOARD_HAS_PXLW_IRIS
# Comment this line to disable pixelworks iris
BOARD_HAS_PXLW_IRIS := true
表明:当前平台,是否装配了 IRIS 芯片。
以此来判别,当前平台是否具有IRIS能力。
PXLW
PXLW_IRIS_CHIP_TYPE
# This is compile option for Static Compatibility. Should be: iris5, iris7
PXLW_IRIS_CHIP_TYPE := iris7
静态兼容,使用该宏确定 IRIS版本
PXLW_HDK_ONLY
# PWLOG is debug feature for PW HDK, no need porting to customer side
# Copy Qualcomm QDCM files for PW HDK, no need porting to customer side
PXLW_HDK_ONLY := true
用于区分代码是否需要porting给客户的宏。
PXLW_AIDL_SUPPORT
# Enable IIris AIDL and IIrisFeature AIDL
PXLW_AIDL_SUPPORT := false
IIris
和IIrisFeature
,使用AIDL还是HIDL
PXLW_IRIS_SERVICE_PASSTHROUGH
PXLW_IRIS_SERVICE_PASSTHROUGH := 1
IRIS_BSP_PLATFORM
IRIS_BSP_PLATFORM := QCOM_DRM
IRIS_BSP_PLATFORM := MTK_DRM
当前平台,体现在IrisIoctlWrapper.cpp
中,
Soong namespace
PRODUCT_SOONG_NAMESPACES
添加两个Soong命名空间
PRODUCT_SOONG_NAMESPACES += vendor/pixelworks/libirisservice
PRODUCT_SOONG_NAMESPACES += vendor/pixelworks/libpwirishalwrapper
意味着,分析,有两个入口。
接下来就是 Android.bp 的世界了。
PRODUCT_PACKAGES
vendor partition
# vendor partition
PRODUCT_PACKAGES += [email protected]
PRODUCT_PACKAGES += libpwirisfeature
ifeq ($(PXLW_AIDL_SUPPORT), true)
PRODUCT_PACKAGES += vendor.pixelworks.hardware.display-V1-ndk
PRODUCT_PACKAGES += vendor.pixelworks.hardware.feature-V1-ndk
endif
vendor/odm partition
# vendor/odm partition
ifeq ($(PXLW_AIDL_SUPPORT), true)
PRODUCT_PACKAGES += vendor.pixelworks.hardware.display-impl-i7
else
PRODUCT_PACKAGES += [email protected]
endif
PRODUCT_PACKAGES += irisConfig irisdbgd irisdbgc
PRODUCT_PACKAGES += libpwirispq \
libpwirisPCS
文件copy
略过一些隐私信息。
Soong
Soong Namespcae
# Soong Namespace
SOONG_CONFIG_NAMESPACES += pxlw_iris
Soong Keys
# Soong Keys
SOONG_CONFIG_pxlw_iris := enable_iris enable_iris_dual enable_hidl enable_aidl
声明。
Soong Values
# Soong Values
SOONG_CONFIG_pxlw_iris_enable_iris := true
SOONG_CONFIG_pxlw_iris_enable_iris_dual := true
ifeq ($(PXLW_AIDL_SUPPORT), true)
SOONG_CONFIG_pxlw_iris_enable_aidl := true
SOONG_CONFIG_pxlw_iris_enable_hidl := false
else
SOONG_CONFIG_pxlw_iris_enable_aidl := false
SOONG_CONFIG_pxlw_iris_enable_hidl := true
endif
BoardConfig.mk
用于填写目标架构,硬件设备属性,编译器的条件标志,分布布局,boot地址,ramdisk等一系列参数。
- 硬件特性,底层变量
- 板级特性 CPU,WIFI,Bootloader etc
device/qcom/lahaina/BoardConfig.mk
很多变量以TARGET_
和BOARD_
开头。
# config.mk
#
# Product-specific compile-time definitions.
#
# TODO(b/124534788): Temporarily allow eng and debug LOCAL_MODULE_TAGS
BOARD_SYSTEMSDK_VERSIONS := 30
TARGET_BOARD_PLATFORM := lahaina
TARGET_BOOTLOADER_BOARD_NAME := lahaina
TARGET_ARCH := arm64
TARGET_ARCH_VARIANT := armv8-a
TARGET_CPU_ABI := arm64-v8a
TARGET_CPU_ABI2 :=
TARGET_CPU_VARIANT := kryo300
DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE
base.mk
device/qcom/vendor-common/base.mk
DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE := vendor/qcom/opensource/core-utils/vendor_framework_compatibility_matrix.xml
#if defined(PXLW_IRIS)
ifeq ($(BOARD_HAS_PXLW_IRIS), true)
DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE += vendor/pixelworks/interfaces/vendor_framework_compatibility_matrix.xml
endif
#endif /* defined(PXLW_IRIS) */
qssi.mk
device\qcom\qssi\qssi.mk
#if defined(PXLW_IRIS)
-include vendor/pixelworks/libirisservice/config/pixelworks_iris.mk
ifeq ($(BOARD_HAS_PXLW_IRIS), true)
DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE += vendor/pixelworks/interfaces/vendor_framework_compatibility_matrix.xml
endif
#endif /* defined(PXLW_IRIS) */