make全编译执行过程
Android系统主要就是根据.mk文件进行编译的。

make -j8
在Android源码根目录全编译的命令为:
source build/envsetup.sh
lunch <product_name>-<build_variant>
make -j8
envsetup.sh
build/envsetup.sh是一个软连接,实际指向build/make/envsetup.sh
首先在envsetup.sh中执行make函数:
function make()
{
_wrap_build $(get_make_command "$@") "$@"
}
执行get_make_command "$@"命令:
function get_make_command()
{
# If we're in the top of an Android tree, use soong_ui.bash instead of make
if [ -f build/soong/soong_ui.bash ]; then
# Always use the real make if -C is passed in
for arg in "$@"; do
if [[ $arg == -C* ]]; then
echo command make
return
fi
done
echo build/soong/soong_ui.bash --make-mode
else
echo command make
fi
}
build/soong/soong_ui.bash
soong_ui.bash 用来配置一些资源环境,最终回退到根目录,执行out/soong_ui –make-mode进行真正的构建。
# Save the current PWD for use in soong_ui
export ORIGINAL_PWD=${PWD}
export TOP=$(gettop)
source ${TOP}/build/soong/scripts/microfactory.bash
soong_build_go soong_ui android/soong/cmd/soong_ui
soong_build_go mk2rbc android/soong/mk2rbc/cmd
soong_build_go rbcrun rbcrun/cmd
cd ${TOP}
exec "$(getoutdir)/soong_ui" "$@"
out/soong_ui
out/soong_ui是一个可执行的二进制文件,是通过编译build/soong/cmd/soong_ui/main.go得来的。
分析main.go就可以得知out/soong_ui的执行流程。
在main.go中主要执行build/soong/ui/build/build.go,build.go的执行任务为:
- runMakeProductConfig:主要配置编译参数;
- runSoong:对工具进行编译,编译出blueprint等编译工具,把*.bp 编译成 out/soong/build.ninja;
- runKatiBuild:加载 build/make/core/main.mk,搜集所有的Android.mk文件生成ninja文件out/build-aosp_arm.ninja;
- runKatiPackage:加载build/make/packaging/main.mk,编译生成out/build-aosp_arm-package.ninja;
- createCombinedBuildNinjaFile:将out/soong/build.ninja、out/build-aosp_arm.ninja和out/build-aosp_arm-package.ninja,合成为out/combined-aosp_arm.ninja;
- runNinja:运行Ninja命令,解析combined-aosp_arm.ninja,执行编译过程;
main.mk文件分析
执行runKatiBuild时,有个重要的步骤,就是加载build/make/core/main.mk,main.mk文件是Android Build系统的主控文件。从main.mk开始,将通过include命令将其所有需要的.mk文件包含进来,最终在内存中形成一个包括所有编译脚本的集合,这个相当于一个巨大Makefile文件。Makefile文件看上去很庞大,其实主要由三种内容构成: 变量定义、函数定义和目标依赖规则,此外mk文件之间的包含也很重要。