1. 程式人生 > >Android build(6) -- shell指令碼的學習

Android build(6) -- shell指令碼的學習

雖然接觸她很久了,但只能說認識,。說道很熟,熟到稱兄道弟,這是我的目標。想要混熟總得經歷些事情,那麼現在開始吧。最近在學習android,還是從android開始吧!

android原始碼中的build/envsetup.sh

顧名思義,這個指令碼的主要作用是初始化編譯環境,如環境變數。提供一些需要用到的函式,可作為指令呼叫。

我們看一下build/envsetup.sh 都幹了什麼事情。

1. 下面是剝離指令碼中的函式部分:(寫該指令碼的老大,不明白為什麼把執行的指令碼和函式混在一塊些?)

轉自:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 01.build/envsetup.sh 指令碼主體部分  02.  03.看原始碼之前需要了解程式碼分佈和結構,分析Makefile應該是最好的方法。在Blog記錄之以備以後檢視,也供有興趣朋友參考。  04.  05.在編譯donut之前,需要執行  06.  07.cd ~/mydroid  08.. build/envsetup.sh  09.lunch aosp_dream_us-eng  10.make  11.  12.build/envsetup.sh 是編譯android的入口。該shell指令碼定義了一些函式,並設定了編譯的環境變數。  13.  14.lunch aosp_dream_us-eng 配置使用者需要編譯的目標產品(target product)和變體(variant)。 
15.  16.aosp_dream_us-eng 字串包含了target product  和variant,它們用減號-隔開,aosp_dream_us是target product,eng是variant。  17.  18.variant 有三種選擇user userdebug eng,可以從字面上看出其意義,但具體的差別還不是特別清楚,待後面分析之。  19.  20.lunch 的入口是讓使用者指定或者選擇需要編譯的target product 和 variant,出口是設定編譯相關的環境變數。  21.  22.build/envsetup.sh 定義了很多函式,並且執行的指令碼很分散,因此下面將所有的函式都刪除掉了,剩餘下指令碼的主體,便於程式碼分析和走讀。 
23.  24.該主體主要做的事情是:  25.  26.1. 首先指令碼設定了兩個預設的target product,一個是generic-eng,一個是simulator  27.  28.2. 執行所有vendor下的 vendorsetup.sh檔案,在google官方的 donut原始碼中,為vendor/aosp/vendorsetup.sh,內容如下:  29.  30.add_lunch_combo aosp_emulator_us-eng  31.add_lunch_combo aosp_emulator_eu-eng  32.add_lunch_combo aosp_dream_us-userdebug  33.add_lunch_combo aosp_dream_eu-userdebug  34.add_lunch_combo aosp_dream_us-eng  35.add_lunch_combo aosp_dream_eu-eng  36.add_lunch_combo aosp_sapphire_us-userdebug  37.add_lunch_combo aosp_sapphire_eu-userdebug  38.add_lunch_combo aosp_sapphire_us-eng  39.add_lunch_combo aosp_sapphire_eu-eng  40.  41.可以看出,又添加了一些 和 aosp 相關的 target product 和 variant。  42.  43.下面是指令碼主體,用藍色添加了一下注釋,便於閱讀:  44.  45.# 定義了 variant的字元範圍  46.VARIANT_CHOICES=(user userdebug eng)  47.  48.# 如果是Linux環境,定義了幾個和simulator相關的函式  49.case `uname -s` in  50.    Linux)  51.        function choosesim()  52.        {  53.            echo "Build for the simulator or the device?"  54.            echo "     1. Device"  55.            echo "     2. Simulator"  56.            echo  57.  58.            export TARGET_SIMULATOR=  59.            local ANSWER  60.            while [ -z $TARGET_SIMULATOR ]  61.            do  62.                echo -n "Which would you like? [1] "  63.                if [ -z "$1" ] ; then  64.                    read ANSWER  65.                else  66.                    echo $1  67.                    ANSWER=$1  68.                fi  69.                case $ANSWER in  70.                "" 71.                    export TARGET_SIMULATOR=false  72.                    ;;  73.                1)  74.                    export TARGET_SIMULATOR=false  75.                    ;;  76.                Device)  77.                    export TARGET_SIMULATOR=false  78.                    ;;  79.                2)  80.                    export TARGET_SIMULATOR=true  81.                    ;;  82.                Simulator)  83.                    export TARGET_SIMULATOR=true  84.                    ;;  85.                *)  86.                    echo  87.                    echo "I didn't understand your response.  Please try again."  88.                    echo  89.                    ;;  90.                esac  91.                if [ -n "$1" ] ; then  92.                    break  93.                fi  94.            done  95.  96.            set_stuff_for_environment  97.        }  98.        ;;  99.    *)  100.        function choosesim()  101.        {  102.            echo "Only device builds are supported for" `uname -s`  103.            echo "     Forcing TARGET_SIMULATOR=false"  104.            echo  105.            if [ -z "$1" 106.            then  107.                echo -n "Press enter: "  108.                read  109.            fi  110.  111.            export TARGET_SIMULATOR=false  112.            set_stuff_for_environment  113.        }  114.        ;;  115.esac  116.  117.  118.# 首先將 LUNCH_MENU_CHOICES 變數消除  119.# Clear this variable.  It will be built up again when the vendorsetup.sh  120.# files are included at the end of this file.  121.unset LUNCH_MENU_CHOICES            122.  123.  124.# 當前 LUNCH_MENU_CHOICES = generic-eng  125.# add the default one here  126.add_lunch_combo generic-eng           127.  128.  129.# 當前 LUNCH_MENU_CHOICES = generic-eng simulator  130.# if we're on linux, add the simulator.  There is a special case  131.# in lunch to deal with the simulator  132.if [ "$(uname)" = "Linux" ] ; then      133.    add_lunch_combo simulator         134.fi  135.  136.  137.# 這裡是MAC OS的環境,不考慮  138.case `uname -s` in    139.    Darwin)  140.        function mgrep()  141.        {  142.            find -E . -type f -iregex '.*/(Makefile|Makefile\..*|.*\.make|.*\.mak|.*\.mk)' -print0 | xargs -0 grep --color -n "[email protected]"  143.        }  144.  145.        function treegrep()  146.        {  147.            find -E . -type f -iregex '.*\.(c|h|cpp|S|java|xml)' -print0 | xargs -0 grep --color -n -i "[email protected]"  148.        }  149.  150.        ;;  151.    *)  152.        function mgrep()  153.        {  154.            find . -regextype posix-egrep -iregex '(.*\/Makefile|.*\/Makefile\..*|.*\.make|.*\.mak|.*\.mk)' -type f -print0 | xargs -0 grep --color -n "[email protected]"  155.        }  156.  157.        function treegrep()  158.        {  159.            find . -regextype posix-egrep -iregex '.*\.(c|h|cpp|S|java|xml)' -type f -print0 | xargs -0 grep --color -n -i "[email protected]"  160.        }  161.  162.        ;;  163.esac  164.  165.  166.# 設定當前shell環境的陣列下標從0開始還是1開始,並記錄在 _arrayoffset  167.# determine whether arrays are zero-based (bash) or one-based (zsh)  168._xarray=(a b c)  169.if [ -z "${_xarray[${#_xarray[@]}]}" 170.then  171.    _arrayoffset=1  172.else  173.    _arrayoffset=0  174.fi  175.unset _xarray  176.  177.  178.# 執行所有vendor下的 vendorsetup.sh檔案  179.#存在vendor/aosp/vendorsetup.sh  180.當前 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  181.  182.# Execute the contents of any vendorsetup.sh files we can find.  183.for f in `/bin/ls vendor/*/vendorsetup.sh vendor/*/build/vendorsetup.sh 2> /dev/null`   184.do  185.    echo "including $f"  186.    . $f  187.done  188.unset f  189.   [ruby] view plaincopyprint? 01.build/envsetup.sh 指令碼分析(lunch函式)  02.  03.lunch函式提供了一個選單,讓開發人員選擇需要編譯的目標產品(target product)和變體(variant),並做一些檢查,設定環境變數,並打印出主要的環境變數。  04.  05.直接執行lunch(必須先執行 build/envsetup.sh,讓lunch函式駐留到環境變數中)  06.  [email protected]:~/donut-compare/mydroid$ lunch  08.  09.You're building on Linux  10.  11.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  12.Lunch menu... pick a combo:  13.     1. generic-eng  14.     2. simulator  15.     3. aosp_emulator_us-eng  16.     4. aosp_emulator_eu-eng  17.     5. aosp_dream_us-userdebug  18.     6. aosp_dream_eu-userdebug  19.     7. aosp_dream_us-eng  20.     8. aosp_dream_eu-eng  21.     9. aosp_sapphire_us-userdebug  22.     10. aosp_sapphire_eu-userdebug  23.     11. aosp_sapphire_us-eng  24.     12. aosp_sapphire_eu-eng  25.  26.Which would you like? [generic-eng] 7  27.  28.============================================  29.PLATFORM_VERSION_CODENAME=REL  30.PLATFORM_VERSION=1.6  31.TARGET_PRODUCT=aosp_dream_us  32.TARGET_BUILD_VARIANT=eng  33.TARGET_SIMULATOR=false  34.TARGET_BUILD_TYPE=release  35.TARGET_ARCH=arm  36.HOST_ARCH=x86  37.HOST_OS=linux  38.HOST_BUILD_TYPE=release  39.BUILD_ID=Donut  40.============================================  41.  42.使用者也可以直接輸入引數,不使用選單  43.  [email protected]:~/donut-compare/mydroid$ lunch aosp_dream_us-eng  45.  46.============================================  47.PLATFORM_VERSION_CODENAME=REL  48.PLATFORM_VERSION=1.6  49.TARGET_PRODUCT=aosp_dream_us  50.TARGET_BUILD_VARIANT=eng  51.TARGET_SIMULATOR=false  52.TARGET_BUILD_TYPE=release  53.TARGET_ARCH=arm  54.HOST_ARCH=x86  55.HOST_OS=linux  56.HOST_BUILD_TYPE=release  57.BUILD_ID=Donut  58.============================================  59.  60.下面是lunch函式原始碼,用藍色添加了一下注釋,便於閱讀:  61.  62.function lunch()  63.{  64.    local answer  65.  66.    if [ "$1" ] ; then  67.       # lunch後面直接帶引數  68.        answer=$1  69.    else  70.       # lunch後面不帶引數,則列印處所有的target product和variant選單提供使用者選擇  71.        print_lunch_menu     72.        echo -n "Which would you like? [generic-eng] "  73.        read answer  74.    fi  75.  76.    local selection=  77.  78.    if [ -z "$answer" 79.    then  80.           # 如果使用者在選單中沒有選擇,直接回車,則為系統預設的generic-eng  81.        selection=generic-eng  82.    elif [ "$answer" = "simulator" 83.    then  84.        # 如果是模擬器  85.        selection=simulator  86.    elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$" 87.    then  88.        # 如果answer是選擇選單的數字,則獲取該數字對應的字串  89.        if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]  90.        then  91.            selection=${LUNCH_MENU_CHOICES[$(($answer-$_arrayoffset))]}  92.        fi  93.        # 如果 answer字串匹配 *-*模式(*的開頭不能為-)  94.    elif (echo -n $answer | grep -q -e "^[^\-][^\-]*-[^\-][^\-]*$" 95.    then  96.        selection=$answer  97.    fi  98.  99.    if [ -z "$selection" 100.    then  101.        echo  102.        echo "Invalid lunch combo: $answer"  103.        return 104.    fi  105.  106.    # special case the simulator  107.    if [ "$selection" = "simulator" 108.    then  109.        # 模擬器模式  110.        export TARGET_PRODUCT=sim  111.        export TARGET_BUILD_VARIANT=eng  112.        export TARGET_SIMULATOR=true  113.        export TARGET_BUILD_TYPE=debug  114.    else  115.  116.        # 將 product-variant模式種的product分離出來  117.        local product=$(echo -n $selection | sed -e "s/-.*$//" 118.  119.        # 檢查之,呼叫關係 check_product()->get_build_var()->build/core/config.mk比較羅嗦,不展開了  120.        check_product $product  121.        if [ $? -ne 0 ]  122.        then  123.            echo  124.            echo "** Don't have a product spec for: '$product'"  125.            echo "** Do you have the right repo manifest?"  126.            product=  127.        fi  128.  129.        # 將 product-variant模式種的variant分離出來  130.        local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//" 131.  132.        # 檢查之,看看是否在 (user userdebug eng) 範圍內  133.        check_variant $variant  134.        if [ $? -ne 0 ]  135.        then  136.            echo  137.            echo "** Invalid variant: '$variant'"  138.            echo "** Must be one of ${VARIANT_CHOICES[@]}"  139.            variant=  140.        fi  141.  142.        if [ -z "$product" -o -z "$variant" 143.        then  144.            echo  145.            return 146.        fi  147.  148.        export TARGET_PRODUCT=$product  149.        export TARGET_BUILD_VARIANT=$variant  150.        export TARGET_SIMULATOR=false  151.        export