Android Donut Makefile分析 (build/envsetup.sh)

来源:互联网 发布:mac os sierra 公测版 编辑:程序博客网 时间:2024/04/30 02:17
[ruby] view plaincopyprint?
  1.   
[ruby] view plaincopyprint?
  1. build/envsetup.sh 脚本主体部分  
  2.   
  3. 看源代码之前需要了解代码分布和结构,分析Makefile应该是最好的方法。在Blog记录之以备以后查看,也供有兴趣朋友参考。  
  4.   
  5. 在编译donut之前,需要运行  
  6.   
  7. cd ~/mydroid  
  8. . build/envsetup.sh  
  9. 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 "$@"  
  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 "$@"  
  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 "$@"  
  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 "$@"  
  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.   
  190. 明天接下来看 lunch()函数  


[ruby] view plaincopyprint?
  1. build/envsetup.sh 脚本分析(lunch函数)  
  2.   
  3. lunch函数提供了一个菜单,让开发人员选择需要编译的目标产品(target product)和变体(variant),并做一些检查,设置环境变量,并打印出主要的环境变量。  
  4.   
  5. 直接运行lunch(必须先运行 build/envsetup.sh,让lunch函数驻留到环境变量中)  
  6.   
  7. ning@ning-desktop:~/donut-compare/mydroid$ lunch  
  8.   
  9. 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.   
  44. ning@ning-desktop:~/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 1  
  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 1  
  146.         fi  
  147.   
  148.         export TARGET_PRODUCT=$product  
  149.         export TARGET_BUILD_VARIANT=$variant  
  150.         export TARGET_SIMULATOR=false  
  151.         export TARGET_BUILD_TYPE=release  
  152.     fi # !simulator  
  153.   
  154.     echo  
  155.   
  156.     # 设置到环境变量,比较多,不再一一列出,最 简单的方法 set >env.txt 可获得  
  157.     set_stuff_for_environment  
  158.     # 打印一些主要的变量, 调用关系 printconfig()->get_build_var()->build/core/config.mk->build/core/envsetup.mk 比较罗嗦,不展开了  
  159.     printconfig  
  160. }  
原文链接:http://www.lupaworld.com/home.php?mod=space&uid=131820&do=blog&id=149463
0 0
原创粉丝点击