(文章出处:http://www.lupaworld.com/131820/viewspace-204608.html)

build/envsetup.sh 脚本主体部分

看源代码之前需要了解代码分布和结构,分析Makefile应该是最好的方法。在Blog记录之以备以后查看,也供有兴趣朋友参考。

在编译donut之前,需要运行

cd ~/mydroid
. build/envsetup.sh
lunch aosp_dream_us-eng
make

build/envsetup.sh 是编译android的入口。该shell脚本定义了一些函数,并设定了编译的环境变量。

lunch aosp_dream_us-eng 配置用户需要编译的目标产品(target product)和变体(variant)。

aosp_dream_us-eng 字符串包含了target product 和variant,它们用减号-隔开,aosp_dream_us是target product,eng是variant。

variant 有三种选择user userdebug eng,可以从字面上看出其意义,但具体的差别还不是特别清楚,待后面分析之。

lunch 的入口是让用户指定或者选择需要编译的target product 和 variant,出口是设定编译相关的环境变量。

build/envsetup.sh 定义了很多函数,并且执行的脚本很分散,因此下面将所有的函数都删除掉了,剩余下脚本的主体,便于代码分析和走读。

该主体主要做的事情是:

1. 首先脚本设定了两个缺省的target product,一个是generic-eng,一个是simulator

2. 运行所有vendor下的 vendorsetup.sh文件,在google官方的 donut源代码中,为vendor/aosp/vendorsetup.sh,内容如下:

add_lunch_combo aosp_emulator_us-eng
add_lunch_combo aosp_emulator_eu-eng
add_lunch_combo aosp_dream_us-userdebug
add_lunch_combo aosp_dream_eu-userdebug
add_lunch_combo aosp_dream_us-eng
add_lunch_combo aosp_dream_eu-eng
add_lunch_combo aosp_sapphire_us-userdebug
add_lunch_combo aosp_sapphire_eu-userdebug
add_lunch_combo aosp_sapphire_us-eng
add_lunch_combo aosp_sapphire_eu-eng

可以看出,又添加了一些 和 aosp 相关的 target product 和 variant。

下面是脚本主体,用蓝色添加了一下注释,便于阅读:

# 定义了 variant的字符范围
VARIANT_CHOICES=(user userdebug eng)

# 如果是Linux环境,定义了几个和simulator相关的函数
case `uname -s` in
Linux)
function choosesim()
{
echo "Build for the simulator or the device?"
echo " 1. Device"
echo " 2. Simulator"
echo

export TARGET_SIMULATOR=
local ANSWER
while [ -z $TARGET_SIMULATOR ]
do
echo -n "Which would you like? [1] "
if [ -z "$1" ] ; then
read ANSWER
else
echo $1
ANSWER=$1
fi
case $ANSWER in
"")
export TARGET_SIMULATOR=false
;;
1)
export TARGET_SIMULATOR=false
;;
Device)
export TARGET_SIMULATOR=false
;;
2)
export TARGET_SIMULATOR=true
;;
Simulator)
export TARGET_SIMULATOR=true
;;
*)
echo
echo "I didn't understand your response. Please try again."
echo
;;
esac
if [ -n "$1" ] ; then
break
fi
done

set_stuff_for_environment
}
;;
*)
function choosesim()
{
echo "Only device builds are supported for" `uname -s`
echo " Forcing TARGET_SIMULATOR=false"
echo
if [ -z "$1" ]
then
echo -n "Press enter: "
read
fi

export TARGET_SIMULATOR=false
set_stuff_for_environment
}
;;
esac


# 首先将 LUNCH_MENU_CHOICES 变量消除
# 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


# 当前 LUNCH_MENU_CHOICES = generic-eng
# add the default one here
add_lunch_combo generic-eng


# 当前 LUNCH_MENU_CHOICES = generic-eng simulator
# if we're on linux, add the simulator. There is a special case
# in lunch to deal with the simulator
if [ "$(uname)" = "Linux" ] ; then
add_lunch_combo simulator
fi


# 这里是MAC OS的环境,不考虑
case `uname -s` in
Darwin)
function mgrep()
{
find -E . -type f -iregex '.*/(Makefile|Makefile/..*|.*/.make|.*/.mak|.*/.mk)' -print0 | xargs -0 grep --color -n "$@"
}

function treegrep()
{
find -E . -type f -iregex '.*/.(c|h|cpp|S|java|xml)' -print0 | xargs -0 grep --color -n -i "$@"
}

;;
*)
function mgrep()
{
find . -regextype posix-egrep -iregex '(.*//Makefile|.*//Makefile/..*|.*/.make|.*/.mak|.*/.mk)' -type f -print0 | xargs -0 grep --color -n "$@"
}

function treegrep()
{
find . -regextype posix-egrep -iregex '.*/.(c|h|cpp|S|java|xml)' -type f -print0 | xargs -0 grep --color -n -i "$@"
}

;;
esac


# 设定当前shell环境的数组下标从0开始还是1开始,并记录在 _arrayoffset
# determine whether arrays are zero-based (bash) or one-based (zsh)
_xarray=(a b c)
if [ -z "${_xarray[${#_xarray[@]}]}" ]
then
_arrayoffset=1
else
_arrayoffset=0
fi
unset _xarray


# 运行所有vendor下的 vendorsetup.sh文件
#存在vendor/aosp/vendorsetup.sh
当 前 LUNCH_MENU_CHOICES = generic-eng simulator aosp_emulator_us-eng aosp_emulator_eu-eng aosp_dream_us-userdebug aosp_dream_eu-userdebug aosp_dream_us-eng aosp_dream_eu-eng aosp_sapphire_us-userdebug aosp_sapphire_eu-userdebug aosp_sapphire_us-eng aosp_sapphire_eu-eng

# Execute the contents of any vendorsetup.sh files we can find.
for f in `/bin/ls vendor/*/vendorsetup.sh vendor/*/build/vendorsetup.sh 2> /dev/null`
do
echo "including $f"
. $f
done
unset f

明天接下来看 lunch()函数

lunch函数提供了一个菜单,让开发人员选择需要编译的目标产品(target product)和变体(variant),并做一些检查,设置环境变量,并打印出主要的环境变量。

直接运行lunch(必须先运行 build/envsetup.sh,让lunch函数驻留到环境变量中)

ning@ning-desktop:~/donut-compare/mydroid$ lunch

You're building on Linux

generic-eng simulator aosp_emulator_us-eng aosp_emulator_eu-eng aosp_dream_us-userdebug aosp_dream_eu-userdebug aosp_dream_us-eng aosp_dream_eu-eng aosp_sapphire_us-userdebug aosp_sapphire_eu-userdebug aosp_sapphire_us-eng aosp_sapphire_eu-eng
Lunch menu... pick a combo:
1. generic-eng
2. simulator
3. aosp_emulator_us-eng
4. aosp_emulator_eu-eng
5. aosp_dream_us-userdebug
6. aosp_dream_eu-userdebug
7. aosp_dream_us-eng
8. aosp_dream_eu-eng
9. aosp_sapphire_us-userdebug
10. aosp_sapphire_eu-userdebug
11. aosp_sapphire_us-eng
12. aosp_sapphire_eu-eng

Which would you like? [generic-eng] 7

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=1.6
TARGET_PRODUCT=aosp_dream_us
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=false
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=Donut
============================================

用户也可以直接输入参数,不使用菜单

ning@ning-desktop:~/donut-compare/mydroid$ lunch aosp_dream_us-eng

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=1.6
TARGET_PRODUCT=aosp_dream_us
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=false
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=Donut
============================================

下面是lunch函数源代码,用蓝色添加了一下注释,便于阅读:


function lunch()
{
local answer

if [ "$1" ] ; then
# lunch后面直接带参数
answer=$1
else
# lunch后面不带参数,则打印处所有的target product和variant菜单提供用户选择
print_lunch_menu
echo -n "Which would you like? [generic-eng] "
read answer
fi

local selection=

if [ -z "$answer" ]
then
# 如果用户在菜单中没有选择,直接回车,则为系统缺省的generic-eng
selection=generic-eng
elif [ "$answer" = "simulator" ]
then
# 如果是模拟器
selection=simulator
elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")
then
# 如果answer是选择菜单的数字,则获取该数字对应的字符串
if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]
then
selection=${LUNCH_MENU_CHOICES[$(($answer-$_arrayoffset))]}
fi
# 如果 answer字符串匹配 *-*模式(*的开头不能为-)
elif (echo -n $answer | grep -q -e "^[^/-][^/-]*-[^/-][^/-]*$")
then
selection=$answer
fi

if [ -z "$selection" ]
then
echo
echo "Invalid lunch combo: $answer"
return 1
fi

# special case the simulator
if [ "$selection" = "simulator" ]
then
# 模拟器模式
export TARGET_PRODUCT=sim
export TARGET_BUILD_VARIANT=eng
export TARGET_SIMULATOR=true
export TARGET_BUILD_TYPE=debug
else

# 将 product-variant模式种的product分离出来
local product=$(echo -n $selection | sed -e "s/-.*$//")

# 检查之, 调用关系 check_product()->get_build_var()->build/core/config.mk 比较罗嗦,不展开了
check_product $product
if [ $? -ne 0 ]
then
echo
echo "** Don't have a product spec for: '$product'"
echo "** Do you have the right repo manifest?"
product=
fi

# 将 product-variant模式种的variant分离出来
local variant=$(echo -n $selection | sed -e "s/^[^/-]*-//")

# 检查之,看看是否在 (user userdebug eng) 范围内
check_variant $variant
if [ $? -ne 0 ]
then
echo
echo "** Invalid variant: '$variant'"
echo "** Must be one of ${VARIANT_CHOICES[@]}"
variant=
fi

if [ -z "$product" -o -z "$variant" ]
then
echo
return 1
fi

export TARGET_PRODUCT=$product
export TARGET_BUILD_VARIANT=$variant
export TARGET_SIMULATOR=false
export TARGET_BUILD_TYPE=release
fi # !simulator

echo

# 设置到环境变量 ,比较多,不再一一列出,最 简单的方法 set >env.txt 可获得
set_stuff_for_environment
# 打印一些主要的变量, 调用关系 printconfig()->get_build_var()->build/core/config.mk->build/core/envsetup.mk 比较罗嗦,不展开了
printconfig
}

更多相关文章

  1. android反编译工具Apktool安装与使用
  2. Rexsee API介绍:Android视频播放,Rexsee的VideoPlayer函数说明与源
  3. Android(安卓)Studio导入Fresco项目编译报错unable to expand TA
  4. 用 Eclipse + GDB调试Android中C/C++程序
  5. Compile a native C Android(安卓)application
  6. android suspend and resume
  7. Android跨进程通信IPC之6——Parcel--Binder对象的写入和读出
  8. 编译安卓源码以及下载Android内核
  9. Android.mk超全详细用法

随机推荐

  1. JavaEE还是Android?
  2. 2018 Android 框架汇总(转)
  3. Android 加速度传感器 (G-Sensor) 收
  4. android之Menu 实例与详解
  5. maven 学习笔记(二)-创建简单的eclipse+and
  6. android菜鸟学习笔记15----Android Junit
  7. android 4.4.3 css hack 写法
  8. AndroidStudio-Eat-Guide—— 1.下载安装
  9. 通过Titanium Studio为Android APK签名
  10. xUtils3注解方式编程