下面按照AOSP的编译步骤来分析每一步的具体过程。
(一)首先是:
source build/envsetup.sh
这条命令是将build/envsetup.sh加载到终端中,终端的输出结果为:
including device/samsung/manta/vendorsetup.sh
including device/asus/deb/vendorsetup.sh
including device/asus/grouper/vendorsetup.sh
including device/asus/fugu/vendorsetup.sh
including device/asus/tilapia/vendorsetup.sh
including device/asus/flo/vendorsetup.sh
including device/nubia/nx40x/vendorsetup.sh
including device/xiaomi/aries/vendorsetup.sh
including device/moto/shamu/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/vendorsetup.sh
including device/generic/mini-emulator-mips/vendorsetup.sh
including device/generic/mini-emulator-x86_64/vendorsetup.sh
including device/lge/mako/vendorsetup.sh
including device/lge/hammerhead/vendorsetup.sh
including sdk/bash_completion/adb.bash
查看build/envsetuo.sh文件,发现其中定义了很多function,但真正执行的部分为:
VARIANT_CHOICES=(user userdebug eng)
# Clear this variable. It will be built up again when the vendorsetup.sh
# files are included at the end of this file.
unset LUNCH_MENU_CHOICES
# add the default one here
add_lunch_combo aosp_arm-eng
add_lunch_combo aosp_arm64-eng
add_lunch_combo aosp_mips-eng
add_lunch_combo aosp_mips64-eng
add_lunch_combo aosp_x86-eng
add_lunch_combo aosp_x86_64-eng
if [ "x$SHELL" != "x/bin/bash" ]; then
case `ps -o command -p $$` in
*bash*)
;;
*)
echo "WARNING: Only bash is supported, use of other shell would lead to erroneous results"
;;
esac
fi
# Execute the contents of any vendorsetup.sh files we can find.
for f in `test -d device && find -L device -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null` \
`test -d vendor && find -L vendor -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null`
do
echo "including $f"
. $f
done
unset f
addcompletions
除了调用的add_lunch_combo和addcompletions两个函数外,上面代码段中的if部分当shell不是bash的时候输出警告信息,for循环部分将device和endor目录中的最多到四级子目录下的vendorsetup.sh文件加载到终端中,并在终端中打印加载了哪些文件。
vendorsetup.sh的内容一般为:
#
# Copyright 2013 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
add_lunch_combo aosp_hammerhead-userdebug
这个文件的设立目的是通过add_lunch_combo函数将设定的全部编译目标加载到终端中。add_lunch_combo函数即为build/envsetup.sh中定义的诸多function中的一个,内容如下。
function add_lunch_combo()
{
local new_combo=$1
local c
for c in ${LUNCH_MENU_CHOICES[@]} ; do
if [ "$new_combo" = "$c" ] ; then
return
fi
done
LUNCH_MENU_CHOICES=(${LUNCH_MENU_CHOICES[@]} $new_combo)
}
从上面的代码可以看出这个函数的目的就是单纯的将调用时的第一个参数加到由空格分隔的数组LUNCH_MENU_CHOICES中,其中的for循环保证了同一个变量在数组中只出现一次。
build/envsetup.sh中还调用了一个函数是addcompletions,它也是定义在build/envsetup.sh中,内容如下。
function addcompletions()
{
local T dir f
# Keep us from trying to run in something that isn't bash.
if [ -z "${BASH_VERSION}" ]; then
return
fi
# Keep us from trying to run in bash that's too old.
if [ ${BASH_VERSINFO[0]} -lt 3 ]; then
return
fi
dir="sdk/bash_completion"
if [ -d ${dir} ]; then
for f in `/bin/ls ${dir}/[a-z]*.bash 2> /dev/null`; do
echo "including $f"
. $f
done
fi
}
可以看出addcompletions的作用是将sdk/bash_completion目录中的*.bash文件加载到终端中,并在终端中打印加载了哪些文件,这构成了build/envsetup.sh输出中的后一部分。
这个目录中的README文件说明了这些*.bash文件的作用。
This directory contains scripts that are intended to be used with
Bourne Again SHell (bash)'s programmable completion.
See http://www.gnu.org/s/bash/manual/bash.html#Programmable-Completion for
more information on programmable completion in bash.
To use the scripts, simply source them into your environment. Example:
source sdk/bash_completion/adb
or:
. sdk/bash_completion/adb
综上所述,build/envsetup.sh主要实现了三个功能:第一,定义了一些在之后的编译过程中要用到的shell命令;第二,将默认的编译目标和由在device和vendor目录及其不超过4层的子目录中的vendorsetup.sh文件中自定义的编译目标保存到变量LUNCH_MENU_CHOICES中;第三,将sdk/bah_completion目录中的*.bash文件加载到终端中,以实现bash的programmable completion功能。
因此,可以看到build/envsetup.sh为我们提供了控制AOSP编译过程的第一步,通过device及vendor目录中的vendorsetup.sh文件增加自定义的编译目标。之后我们可以围绕这个自定义的编译目标来填充具体的编译配置信息和必须的源代码及二进制文件,从而最终编译出一个自定义的Android系统。