很久以前给4412做过安卓源码编译工作,当时也是编译源码不过如此。
但是最近阅读了一下安卓源码编译的Makefile完全被安卓的编译征服了,下面我就简单介绍一下这个过程。
首先,还是要从安卓编译一个通用的版本说起,然后结合tiny4412提供的安卓脚本分析一下不同来对比一下。
一.源码编译步骤:
我们随便编译一个安卓源码命令很简单
1. build/envsetup.sh
2. lunch
3. make
然后tiny4412文档上给的是
1. . setenv
2. make
二.对比现象看问题
我们先从命令行输出来对比一下现象有写什么区别。
我们从标准的流程看:
然后我们看tiny4412:
我们发现tiny4412貌似只做了第一个步骤,我们还是通过看脚本来看看为什么把。
这里就看出来了 build/envsetup.sh已经被包含在这个脚本中了
接着 看到了 TARGET_PRODUCT 等四个参数已经被设计到环境变量中了
这几个参数和上面打印出来的参数形成了对应
默认的我们看出 TARGET_PRODUCT ==full
TARGET_BUILD_VARIANT=eng
和默认lunch 之后menu中的 1.full-eng 我们就看出了一些端倪。
所以就得出了一些结论。
lunch做了一些事情
1.把选中的项目上的内容 - 两边的内容分割分别赋值给两个参数
2.lunch之后的列表我们是否可以人工增加,如果我也想定制一个安卓版本需要怎么做?
3.那些include到底是干什么用的?
接着我带着这些问题,就从build/envsetup.sh观察
三.从build/envsetup.sh找答案
打开这个脚本文件就惊呆了,shell写的惨不忍睹。 - -!
我们看到了一堆函数在这里实现了,原来lunch那个奇怪的命令只是一个脚本文件里定义的函数
常用的编译的命令都在这里实现了 如:m mm mmm (这些编译的时候比较常用)
我们还是直捣黄龙搜索一下lunch
function lunch()
{
local answer
if [ "$1" ] ; then
answer=$1
else
print_lunch_menu
echo -n "Which would you like? [generic-eng] "
read answer
fi
local selection=
if [ -z "$answer" ]
then
selection=generic-eng
elif [ "$answer" = "simulator" ]
then
selection=simulator
elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")
then
if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]
then
selection=${LUNCH_MENU_CHOICES[$(($answer-$_arrayoffset))]}
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=
# special case the simulator
if [ "$selection" = "simulator" ]
then
########################################## <span style="color:#3366ff;">export TARGET_PRODUCT=sim
export TARGET_BUILD_VARIANT=eng
export TARGET_SIMULATOR=true
export TARGET_BUILD_TYPE=debug
</span> else
###########<span style="color:#ff0000;">local product=$(echo -n $selection | sed -e "s/-.*$//")#关注这里
</span> 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
###### <span style="color:#ff0000;">local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//")#关注这里
</span> 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 ###########################
<span style="BACKGROUND-COLOR: #3366ff"> export TARGET_PRODUCT=$product
export TARGET_BUILD_VARIANT=$variant
export TARGET_SIMULATOR=false
export TARGET_BUILD_TYPE=release </span> fi # !simulator
echo
set_stuff_for_environment #设置比较重要的变量
printconfig
}
lunch主要就是根据选项得出4个参数的值,我们观察蓝色的代码(export 4个变量)就很容易得出这个结论
然后红色的代码(local product=xxx)
就是之前我们发现的把menu中选好的选项拆出来的神奇代码,看来要看懂android还需要很强的功底。
看完这段代码我们便解决问题1,接着我们就看看哪里有增加菜单的函数呢?
不出所料:add_lunch_combo()这个函数
unset LUNCH_MENU_CHOICES
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)
}
# add the default one here
add_lunch_combo generic-eng
我们看到这个函数下面还add 了一项
我们得出 所有的项目是存在LUNCH_MENU_CHOICES这个变量中,首先先清空他,
随着我们不断add_lunch_combo而增加,从最上面的图看出我们的列表超过了10项
那么问题3,我们add_lunch_combo xxx-xxx就可以增加一项目了,那么我们在哪里写这段代码呢?
当然只要在lunch前写就可以了。
我们先放一下这个问题,看看那些include是哪里来的吧?搜索一下include 好了
# Execute the contents of any vendorsetup.sh files we can find.
for f in `/bin/ls vendor/*/vendorsetup.sh vendor/*/build/vendorsetup.sh device/*/*/vendorsetup.sh 2> /dev/null`
do
echo "including $f"
. $f
done
unset f
原来搜索到vendor 和device下可能存在这些文件,然后打印出来并执行一下这个文件,带着好奇随意打开一个文件看看。
在device\samsung\crespo4g 目录下发现了一个打开一看,惊喜出现了这不就是问题2 的结果吗?
add_lunch_combo full_crespo4g-userdebug
四、结论
总结一下:
编译前我们需要通过build/envsetup.sh引入一些函数,和设置一些环境变量提供给make使用。
lunch 用作设置编译出产品名称和版本等一些信息(这里我们相信这个参数应该是有比较大的用处,不然何必绕那么一圈设置这个参数)
我们可以通过add_lunch_combo 增加一些选项,供lunch使用,最后我们得出了比较重要的参数
export TARGET_PRODUCT
export TARGET_BUILD_VARIANT
export TARGET_SIMULATOR
export TARGET_BUILD_TYPE
tiny4412 简化了这个步骤,直接将需要设置的参数手工的输入了,当然这样做我们就不能通过lunch 选择序号的方式选择了。
接着下一篇我们就应该分析一下这些环境变量到底是怎么影响我们的编译的.