编译cubieboard android 源码过程详解之(三):lunch

阅读本文前请先阅读

2014-02-26

这一步是选择要编译的产品。

2014-02-27

在文档中分析函数调用真的不是很方便,这里先试着用缩进表示函数的层次,缩进越多表示被调用的层级越深(很遗憾,插入的代码无法缩进显示)。因为有些代码片段只属于函数的一部分,所以在代码片段上都表明了所属的函数(红色背景,白色字体)。

lunch
function lunch()

{

    local answer



    if [ "$1" ] ; then

        answer=$1

    else

        print_lunch_menu

        echo -n "Which would you like? [full-eng] "

        read answer

    fi

 

如果我们调用lunch命令时传入了参数,就赋值给answer;否则就执行print_lunch_menu,并等待用户输入。

print_lunch_menu

function print_lunch_menu()

{

    local uname=$(uname)

    echo

    echo "You're building on" $uname

    echo

    echo "Lunch menu... pick a combo:"



    local i=1

    local choice

    for choice in ${LUNCH_MENU_CHOICES[@]}

    do

        echo "     $i. $choice"

        i=$(($i+1))

    done



    echo

}

这个函数功能是打印产品列表,每个产品名称前带有序号,在选择产品时可以使用。

lunch

 1 local selection=

 2 

 3     if [ -z "$answer" ] #如果没有输入

 4     then

 5         selection=full-eng #默认为 full-eng

 6     elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$") #匹配字符串:以一个数字开头,后面是任意个数字

 7     then

 8         if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ] #如果数字数值小于或等于产品列表中产品数目

 9         then

10             selection=${LUNCH_MENU_CHOICES[$(($answer-1))]} #选择对应的产品

11         fi

12     elif (echo -n $answer | grep -q -e "^[^\-][^\-]*-[^\-][^\-]*$") #匹配字符串:类似full-eng格式的字符串

13     then

14         selection=$answer 

15     fi

16 

17     if [ -z "$selection" ] #找不到对应的产品

18     then

19         echo

20         echo "Invalid lunch combo: $answer"

21         return 1

22     fi

 这段代码功能是处理用户输入,用户可以输入数字,也可以输入产品名。$selection 变量最终存储产品名称。具体分析见代码注释。

lunch

 1 local product=$(echo -n $selection | sed -e "s/-.*$//") #去除字符串中以 ‘-’ 字符开头的部分,效果是:full-eng只剩下full,也就
#是产品名
2 check_product $product 3 if [ $? -ne 0 ] 4 then 5 echo 6 echo "** Don't have a product spec for: '$product'" 7 echo "** Do you have the right repo manifest?" 8 product= 9 fi 10 11 local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//") #去除字符串中不以'-'开头但以'-'结尾的部分,效果是full-eng                                       #只剩下eng,也就是变种名 12 check_variant $variant 13 if [ $? -ne 0 ] 14 then 15 echo 16 echo "** Invalid variant: '$variant'" 17 echo "** Must be one of ${VARIANT_CHOICES[@]}" 18 variant= 19 fi 20 21 if [ -z "$product" -o -z "$variant" ] #判断是否有不满足条件的情况 22 then 23 echo 24 return 1 25 fi 26 27 export TARGET_PRODUCT=$product    #导出产品名 full 28 export TARGET_BUILD_VARIANT=$variant  #导出变种名 eng 29 export TARGET_BUILD_TYPE=release  #导出类型为 release

以上代码根据用户最终的选择分析出产品名和变种名。

 lunch

1 set_stuff_for_environment

set_stuff_for_environment

1 function set_stuff_for_environment()

2 {

3     settitle

settitle:

 1 function settitle()

 2 {

 3     if [ "$STAY_OFF_MY_LAWN" = "" ]; then

 4         local product=$TARGET_PRODUCT

 5         local variant=$TARGET_BUILD_VARIANT

 6         local apps=$TARGET_BUILD_APPS

 7         if [ -z "$apps" ]; then

 8             export PROMPT_COMMAND="echo -ne \"\033]0;[${product}-${variant}] ${USER}@${HOSTNAME}: ${PWD}\007\""

 9         else

10             export PROMPT_COMMAND="echo -ne \"\033]0;[$apps $variant] ${USER}@${HOSTNAME}: ${PWD}\007\""

11         fi

12     fi

13 }

看来主要目的是设置 PROMPT_COMMAND 变量,但是还没发现是被什么地方调用的,暂且跳过(Todo)。

set_stuff_for_environment

1 set_java_home

set_java_home:

 1 function set_java_home() {

 2     if [ ! "$JAVA_HOME" ]; then

 3         case `uname -s` in

 4             Darwin)

 5                 export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home

 6                 ;;

 7             *)

 8                 export JAVA_HOME=/usr/lib/jvm/java-6-sun

 9                 ;;

10         esac

11     fi

12 }

设置JAVA_HOME环境变量

set_stuff_for_environment

1 setpaths

setpaths

1 function setpaths()

2 {

3     T=$(gettop)

4     if [ ! "$T" ]; then

5         echo "Couldn't locate the top of the tree.  Try setting TOP."

6         return

7     fi

获取顶层目录:*/android

gettop

 1 function gettop

 2 {

 3     local TOPFILE=build/core/envsetup.mk

 4     if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then #如果已经设置过TOP,并且当前目录存在文件 "build/core/envsetup.mk"

 5         echo $TOP

 6     else

 7         if [ -f $TOPFILE ] ; then

 8             # The following circumlocution (repeated below as well) ensures

 9             # that we record the true directory name and not one that is

10             # faked up with symlink names.

11             PWD= /bin/pwd

12         else

13             # We redirect cd to /dev/null in case it's aliased to

14             # a command that prints something as a side-effect

15             # (like pushd)

16             local HERE=$PWD

17             T=

18             while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do #如果不存在$TOPFILE且还没到根目录

19                 cd .. > /dev/null #返回到上层目录

20                 T=`PWD= /bin/pwd`

21             done

22             cd $HERE > /dev/null

23             if [ -f "$T/$TOPFILE" ]; then

24                 echo $T #返回顶层目录:*/android

25             fi

26         fi

27     fi

28 }

感觉分析这个函数有点难度,不过最终目的是找到包含“build/core/envsetup.mk”文件的目录,即安卓源码的根目录:*/android

setpaths

 

1  # out with the old

2     if [ -n "$ANDROID_BUILD_PATHS" ] ; then

3         export PATH=${PATH/$ANDROID_BUILD_PATHS/}

4     fi

5     if [ -n "$ANDROID_PRE_BUILD_PATHS" ] ; then

6         export PATH=${PATH/$ANDROID_PRE_BUILD_PATHS/}

7         # strip trailing ':', if any

8         export PATH=${PATH/%:/}

9     fi

 

功能:如果之前在“PATH”中设置过“ANDROID_BUILD_PATHS”和“ANDROID_PRE_BUILD_PATHS”,则将其清除。

setpaths

 

 1  # and in with the new

 2     CODE_REVIEWS=

 3     prebuiltdir=$(getprebuilt) #获取prebuild目录,实际上返回的是:android/prebuilt/linux-x86

 4 

 5     # The gcc toolchain does not exists for windows/cygwin. In this case, do not reference it.

 6     export ANDROID_EABI_TOOLCHAIN=

 7     toolchaindir=toolchain/arm-linux-androideabi-4.4.x/bin

 8     if [ -d "$prebuiltdir/$toolchaindir" ]; then

 9         export ANDROID_EABI_TOOLCHAIN=$prebuiltdir/$toolchaindir

10     fi

11 

12     export ARM_EABI_TOOLCHAIN=

13     toolchaindir=toolchain/arm-eabi-4.4.3/bin

14     if [ -d "$prebuiltdir/$toolchaindir" ]; then

15         export ARM_EABI_TOOLCHAIN=$prebuiltdir/$toolchaindir

16     fi

17 

18     export ANDROID_TOOLCHAIN=$ANDROID_EABI_TOOLCHAIN

19     export ANDROID_QTOOLS=$T/development/emulator/qtools

20     export ANDROID_BUILD_PATHS=:$(get_build_var ANDROID_BUILD_PATHS):$ANDROID_QTOOLS:$ANDROID_TOOLCHAIN:$ARM_EABI_TOOLCHAIN$CODE_REVIEWS

21     export PATH=$PATH$ANDROID_BUILD_PATHS

22 

23     unset ANDROID_JAVA_TOOLCHAIN

24     unset ANDROID_PRE_BUILD_PATHS

25     if [ -n "$JAVA_HOME" ]; then

26         export ANDROID_JAVA_TOOLCHAIN=$JAVA_HOME/bin

27         export ANDROID_PRE_BUILD_PATHS=$ANDROID_JAVA_TOOLCHAIN:

28         export PATH=$ANDROID_PRE_BUILD_PATHS$PATH

29     fi

30 

31     unset ANDROID_PRODUCT_OUT

32     export ANDROID_PRODUCT_OUT=$(get_abs_build_var PRODUCT_OUT)

33     export OUT=$ANDROID_PRODUCT_OUT #获取产品最终文件输出目录

34 

35     unset ANDROID_HOST_OUT

36     export ANDROID_HOST_OUT=$(get_abs_build_var HOST_OUT)

37     unset ANDROID_DEVICE_CONFIG

38     tdevice=$(get_build_var TARGET_DEVICE)

39     export DEVICE=$T/device/*/$tdevice

 

这段有难度,里面涉及到了makefile,暂时先不分析(TODO)。

set_stuff_for_environment

 

1 set_sequence_number

 

set_sequence_number

function set_sequence_number()

{

    export BUILD_ENV_SEQUENCE_NUMBER=10

}

做什么用的,不知道。

set_stuff_for_environment

1     export ANDROID_BUILD_TOP=$(gettop)

2 }

终于完了。

lunch

1  printconfig

2 }

printconfig

1 function printconfig()

2 {

3     T=$(gettop)

4     if [ ! "$T" ]; then

5         echo "Couldn't locate the top of the tree.  Try setting TOP." >&2

6         return

7     fi

8     get_build_var report_config #get_build_var report_config 参考 “android/build/core/dumpvar.mk"

9 }

通过make输出当前的配置。 

 

lunch吃完了,真难消化,编写这些脚本的大神真叫人佩服啊!!!

你可能感兴趣的:(android)