Android 4.03 编译系统-envsetup.sh

Android 4.03 编译系统------envsetup.sh

        接触Android的也快半年了,一直都忙着学习android 的framework、HAL,对Android的编译系统一点都不了解,在编译系统时带来了很多的不便,所以花时间详细的了解了一下,下面记录一下学习心得(由于时间仓促,有的地方理解有误,请不吝赐教)。

        Android编译环境的建立以及源码的下载,Android官网给了详细的说明:http://source.android.com/source/index.html ,我就不多费口舌了,好了,进入正题。

        要编译Android系统,首先再Android顶层目录下执行 : . build/envsetup.sh(注意点后有空格),. 表示执行build/envsetup.sh shell脚本。下面我们就来看看envsetup.sh都做了哪些工作:

         打开envsetup.sh文件,啊......!这都是啥啊?怎么全是函数的定义?对的,envsetup.sh一部分重要的工作就是定义了很多的函数。当然,它也执行了一些命令,为了方便我把函数体都删了,只留下函数名,envsetup.sh就成了如下所示:

/*******************************envsetup.sh*********************************************/

function help()
function get_abs_build_var()
function get_build_var()
function check_product()

VARIANT_CHOICES=(user userdebug eng)

function check_variant()
function setpaths()
function printconfig()
function set_stuff_for_environment()
function set_sequence_number()
function settitle()
function addcompletions()
function choosetype()
function chooseproduct()
function choosevariant()
function choosecombo()

unset LUNCH_MENU_CHOICES
function add_lunch_combo()

add_lunch_combo full-eng
add_lunch_combo full_x86-eng
add_lunch_combo vbox_x86-eng


function print_lunch_menu()
function lunch()

function _lunch()
complete -F _lunch lunch
function tapas()
function gettop
function m()
function findmakefile()
function mm()
function mmm()
function croot()
function cproj()
function pid()
function systemstack()
function gdbclient()

case `uname -s` in
    Darwin)
        function sgrep()
        {
            find -E . -name .repo -prune -o -name .git -prune -o  -type f -iregex '.*\.(c|h|cpp|S|java|xml|sh|mk)' -print0 | xargs -0 grep --color -n "$@"
        }

        ;;
    *)
        function sgrep()
        {
            find . -name .repo -prune -o -name .git -prune -o  -type f -iregex '.*\.\(c\|h\|cpp\|S\|java\|xml\|sh\|mk\)' -print0 | xargs -0 grep --color -n "$@"
        }
        ;;
esac

function jgrep()
function cgrep()
function resgrep()

case `uname -s` in
    Darwin)
        function mgrep()
        {
            find -E . -name .repo -prune -o -name .git -prune -o  -type f -iregex '.*/(Makefile|Makefile\..*|.*\.make|.*\.mak|.*\.mk)' -print0 | xargs -0 grep --color -n "$@"
        }

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

        ;;
    *)
        function mgrep()
        {
            find . -name .repo -prune -o -name .git -prune -o -regextype posix-egrep -iregex '(.*\/Makefile|.*\/Makefile\..*|.*\.make|.*\.mak|.*\.mk)' -type f -print0 | xargs -0 grep --color -n "$@"
        }
        function treegrep()
        {
            find . -name .repo -prune -o -name .git -prune -o -regextype posix-egrep -iregex '.*\.(c|h|cpp|S|java|xml)' -type f -print0 | xargs -0 grep --color -n -i "$@"
        }

        ;;
esac

function getprebuilt

function tracedmdump()
function runhat()
function getbugreports()
function startviewserver()
function stopviewserver()
function isviewserverstarted()
function key_home()
function key_back()
function key_menu()
function smoketest()
function runtest()
function godir ()
function set_java_home()

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

for f in `/bin/ls vendor/*/vendorsetup.sh vendor/*/*/vendorsetup.sh device/*/*/vendorsetup.sh 2> /dev/null`
do
    echo "including $f"
    . $f
done
unset f


addcompletions


/*************************************end*************************************************/

经过这样的处理后,文件小了很多,只有100多行了,看着是不是舒服多了?在这100行多一点的代码里,其实只有相当一小部分是我们需要注意的,上面用红色标记的地方,第一部分:

                add_lunch_combo full-eng
                add_lunch_combo full_x86-eng
                add_lunch_combo vbox_x86-eng


add_lunch_combo 是这个文件里定义的函数,现在我们来看看其函数体:

/*************************************begin***********************************************/

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)
}

/*************************************end*************************************************/

这个函数做的事很简单,相信大家都能看明白,如果看不懂的话,去baidu好好学习一下shell编程吧!它就是将add_lunch_combo 后面的参数加入到变量LUNCH_MENU_CHOICES中。

       红色标记的第二部分:

             for f in `/bin/ls vendor/*/vendorsetup.sh vendor/*/*/vendorsetup.sh device/*/*/vendorsetup.sh 2> /dev/null`
              do
                     echo "including $f"
                     . $f
              done
              unset f

这一段代码就是查找 vendor/*/vendor/*/*/、device/*/*/目录下的vendorsetup.sh文件,并执行找到的vendorsetup.sh文件,我们来看一个vendorsetup.sh文件:

/***************************device/ti/panda/vendorsetup.sh***************************/

#
# Copyright (C) 2011 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 full_panda-eng

/*************************************end*************************************************/

里面只有一句代码:add_lunch_combo full_panda-eng,这个前面分析了就不说了。

       总结一下,. build/envsetup.sh主要工作有:

               1. 定义很多很多的函数。

               2. 把默认的product名字full-eng、full_x86-eng、vbox_x86-eng加入到 LUNCH_MENU_CHOICES 变量中。

               3. 查找vendor/*/vendor/*/*/、device/*/*/目录下的vendorsetup.sh,将开发者的product名字加入到LUNCH_MENU_CHOICES 变量中。

       . build/envsetup.sh 后,就是lunch命令了,后续会分析,尽情期待。