不同厂商在编译Android系统时,会选择不同产品和编译版本。在Android编译过程中,通过source,lunch来选择。
1、souuce build/envsetup.sh:加载命令
2、lunch:选择平台等编译选项
3、make:编译
我们按照编译步骤分析编译过程,最终添加自己的平台编译选项。
1、souuce build/envsetup.sh
envsetup.sh定义了众多命令,在执行该脚本是向编译系统添加编译指令。
function help() # 显示帮助信息
function get_abs_build_var() # 获取绝对变量
function get_build_var() # 获取绝对变量
function check_product() # 检查product
function check_variant() # 检查变量
function setpaths() # 设置文件路径
function printconfig() # 打印配置
function set_stuff_for_environment() # 设置环境变量
function set_sequence_number() # 设置序号
function settitle() # 设置标题
function choosetype() # 设置type
function chooseproduct() # 设置product
function choosevariant() # 设置variant
function tapas() # 功能同choosecombo
function choosecombo() # 设置编译参数
function add_lunch_combo() # 添加lunch项目
function print_lunch_menu() # 打印lunch列表
function lunch() # 配置lunch
function m() # make from top
function findmakefile() # 查找makefile
function mm() # make from current directory
function mmm() # make the supplied directories
function croot() # 回到根目录
function cproj()
function pid()
function systemstack()
function gdbclient()
function jgrep() # 查找java文件
function cgrep() # 查找c/cpp文件
function resgrep()
function tracedmdump()
首先关注add_lunch_combo函数,用来用lunch列表添加编译选项。
# 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
# 保存编译选项
function add_lunch_combo()
{
local new_combo=$1 # 获得add_lunch_combo被调用时的参数
# 依次遍历LUNCH_MENU_CHOICES里的值,其实该函数第一次调用时,该值为空
local c
for c in ${LUNCH_MENU_CHOICES[@]} ; do
if [ "$new_combo" = "$c" ] ; then
return
fi
done
# 如果参数的值不存在,则添加到LUNCH_MENU_CHOICES变量里
LUNCH_MENU_CHOICES=(${LUNCH_MENU_CHOICES[@]} $new_combo)
}
在执行source build/envsetup.sh时,会设置默认的一些编译选项:
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
同时,各个厂商会在/device目录下定义自己的编译选项,如Android/device/qocm/msm8909w/common/vendorsetup.sh.
add_lunch_combo msm8909w-userdebug
add_lunch_combo msm8909w-user
所以,envsetup.sh作用如下:
- 加载了编译时使用到的函数命令,如:help,lunch,m,mm,mmm等
- 添加了默认编译选项:aosp_arm-eng等系统默认选项
- 查找build/<-厂商目录>/和build/<厂商目录>/build/目录下的vendorsetup.sh,如果存在的话,加载执行它,添加厂商自己定义产品的编译选项
2、lunch
当我们source build/envsetup.sh后,将执行lunch,单纯执行lunch将这样输出:
zl@ubuntud:~/Android$ lunch
You're building on Linux
Lunch menu... pick a combo:
1. aosp_arm-eng
2. aosp_arm64-eng
3. aosp_mips-eng
4. aosp_mips64-eng
5. aosp_x86-eng
6. aosp_x86_64-eng
7. mini_emulator_arm64-userdebug
8. m_e_arm-userdebug
9. mini_emulator_x86_64-userdebug
10. mini_emulator_x86-userdebug
11. msm8909_512-userdebug
12. msm8909_LMT-userdebug
13. msm8909w-userdebug
14. msm8909w-user
Which would you like? [aosp_arm-eng]
lunch函数在envsetup.sh中定位为:
function lunch()
{
local answer
if [ "$1" ] ; then
# lunch 后面加了参数,变量answer赋值为参数
answer=$1
else
# lunch没有参数,则打印
# lunch menu,即从LUNCH_MENU_CHOICES输出不同选项
print_lunch_menu
echo -n "Which would you like? [aosp_arm-eng] "
# 等待输入
read answer
fi
local selection=
if [ -z "$answer" ]
then
# 用户输入空,在使用默认的选项
selection=aosp_arm-eng
# 用户输入0-9或者某个编译选项
elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")
then
if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]
then
selection=${LUNCH_MENU_CHOICES[$(($answer-1))]}
fi
elif (echo -n $answer | grep -q -e "^[^\-][^\-]*-[^\-][^\-]*$")
then
selection=$answer
fi
if [ -z "$selection" ]
then
echo
echo "Invalid lunch combo: $answer"
return 1
fi
export TARGET_BUILD_APPS=
# 取出variant
local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//")
check_variant $variant
if [ $? -ne 0 ]
then
echo
echo "** Invalid variant: '$variant'"
echo "** Must be one of ${VARIANT_CHOICES[@]}"
variant=
fi
# 取出product
local product=$(echo -n $selection | sed -e "s/-.*$//")
TARGET_PRODUCT=$product \
TARGET_BUILD_VARIANT=$variant \
build_build_var_cache
if [ $? -ne 0 ]
then
echo
echo "** Don't have a product spec for: '$product'"
echo "** Do you have the right repo manifest?"
product=
fi
if [ -z "$product" -o -z "$variant" ]
then
echo
return 1
fi
# 从编译选项获得PRODUCT和VARIANT
# PRODUCT为msm8909w,VARIANT为userdebug
# 到处为全局环境变量
export TARGET_PRODUCT=$product
export TARGET_BUILD_VARIANT=$variant
export TARGET_BUILD_TYPE=release
echo
#设置其他环境变量
set_stuff_for_environment
# 打印配置信息
printconfig
destroy_build_var_cache
}
因此,lunch影响到的环境变量有以下四个:
TARGET_PRODUCT=msm8909w
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
这里我们可以看到,通过TARGET_BUILD_VARIANT这个全局变量,可以区分编译选项时user还是userdebug。
这个工将在/device/qcom/msm8909/base.mk这样的base.mk中设置一个prop,来限制adb这个daemon进程获取root权限:
ifeq ($(TARGET_BUILD_VARIANT),user)
PRODUCT_DEFAULT_PROPERTY_OVERRIDES+= \
ro.adb.secure=1
endif
adb的deamon进程通过base.mk中设置的prop来确定是否可以给adb root权限。user版adb将无法获取root权限而受到限制。
@/system/core/adb/daemon/main.cpp
int adbd_main(int server_port) {
umask(0);
signal(SIGPIPE, SIG_IGN);
init_transport_registration();
// We need to call this even if auth isn't enabled because the file
// descriptor will always be open.
adbd_cloexec_auth_socket();
if (ALLOW_ADBD_NO_AUTH && property_get_bool("ro.adb.secure", 0) == 0) {
auth_required = false;
}
if(check_adb_root_enable())
auth_required = false;
adbd_auth_init();
...
}