Android Donut Makefile分析 (buildenvsetup.sh)

xiaoxiao2021-02-28  102

[ruby]  view plain  copy  print ?    [ruby]  view plain  copy  print ? build/envsetup.sh 脚本主体部分      看源代码之前需要了解代码分布和结构,分析Makefile应该是最好的方法。在Blog记录之以备以后查看,也供有兴趣朋友参考。      在编译donut之前,需要运行      cd ~/mydroid   . build/envsetup.sh   lunch aosp_dream_us-eng   make      build/envsetup.sh 是编译android的入口。该shell脚本定义了一些函数,并设定了编译的环境变量。      lunch aosp_dream_us-eng 配置用户需要编译的目标产品(target product)和变体(variant)。      aosp_dream_us-eng 字符串包含了target product  和variant,它们用减号-隔开,aosp_dream_us是target product,eng是variant。      variant 有三种选择user userdebug eng,可以从字面上看出其意义,但具体的差别还不是特别清楚,待后面分析之。      lunch 的入口是让用户指定或者选择需要编译的target product 和 variant,出口是设定编译相关的环境变量。      build/envsetup.sh 定义了很多函数,并且执行的脚本很分散,因此下面将所有的函数都删除掉了,剩余下脚本的主体,便于代码分析和走读。      该主体主要做的事情是:      1. 首先脚本设定了两个缺省的target product,一个是generic-eng,一个是simulator      2. 运行所有vendor下的 vendorsetup.sh文件,在google官方的 donut源代码中,为vendor/aosp/vendorsetup.sh,内容如下:      add_lunch_combo aosp_emulator_us-eng   add_lunch_combo aosp_emulator_eu-eng   add_lunch_combo aosp_dream_us-userdebug   add_lunch_combo aosp_dream_eu-userdebug   add_lunch_combo aosp_dream_us-eng   add_lunch_combo aosp_dream_eu-eng   add_lunch_combo aosp_sapphire_us-userdebug   add_lunch_combo aosp_sapphire_eu-userdebug   add_lunch_combo aosp_sapphire_us-eng   add_lunch_combo aosp_sapphire_eu-eng      可以看出,又添加了一些 和 aosp 相关的 target product 和 variant。      下面是脚本主体,用蓝色添加了一下注释,便于阅读:      # 定义了 variant的字符范围   VARIANT_CHOICES=(user userdebug eng)      # 如果是Linux环境,定义了几个和simulator相关的函数   case `uname -s` in       Linux)           function choosesim()           {               echo "Build for the simulator or the device?"               echo "     1. Device"               echo "     2. Simulator"               echo                  export TARGET_SIMULATOR=               local ANSWER               while [ -z $TARGET_SIMULATOR ]               do                   echo -n "Which would you like? [1] "                   if [ -z "$1" ] ; then                       read ANSWER                   else                       echo $1                       ANSWER=$1                   fi                   case $ANSWER in                   "")                       export TARGET_SIMULATOR=false                       ;;                   1)                       export TARGET_SIMULATOR=false                       ;;                   Device)                       export TARGET_SIMULATOR=false                       ;;                   2)                       export TARGET_SIMULATOR=true                       ;;                   Simulator)                       export TARGET_SIMULATOR=true                       ;;                   *)                       echo                       echo "I didn't understand your response.  Please try again."                       echo                       ;;                   esac                   if [ -n "$1" ] ; then                       break                   fi               done                  set_stuff_for_environment           }           ;;       *)           function choosesim()           {               echo "Only device builds are supported for" `uname -s`               echo "     Forcing TARGET_SIMULATOR=false"               echo               if [ -z "$1" ]               then                   echo -n "Press enter: "                   read               fi                  export TARGET_SIMULATOR=false               set_stuff_for_environment           }           ;;   esac         # 首先将 LUNCH_MENU_CHOICES 变量消除   # Clear this variable.  It will be built up again when the vendorsetup.sh   # files are included at the end of this file.   unset LUNCH_MENU_CHOICES                   # 当前 LUNCH_MENU_CHOICES = generic-eng   # add the default one here   add_lunch_combo generic-eng                  # 当前 LUNCH_MENU_CHOICES = generic-eng simulator   # if we're on linux, add the simulator.  There is a special case   # in lunch to deal with the simulator   if [ "$(uname)" = "Linux" ] ; then           add_lunch_combo simulator          fi         # 这里是MAC OS的环境,不考虑   case `uname -s` in         Darwin)           function mgrep()           {               find -E . -type f -iregex '.*/(Makefile|Makefile\..*|.*\.make|.*\.mak|.*\.mk)' -print0 | xargs -0 grep --color -n "$@"           }              function treegrep()           {               find -E . -type f -iregex '.*\.(c|h|cpp|S|java|xml)' -print0 | xargs -0 grep --color -n -i "$@"           }              ;;       *)           function mgrep()           {               find . -regextype posix-egrep -iregex '(.*\/Makefile|.*\/Makefile\..*|.*\.make|.*\.mak|.*\.mk)' -type f -print0 | xargs -0 grep --color -n "$@"           }              function treegrep()           {               find . -regextype posix-egrep -iregex '.*\.(c|h|cpp|S|java|xml)' -type f -print0 | xargs -0 grep --color -n -i "$@"           }              ;;   esac         # 设定当前shell环境的数组下标从0开始还是1开始,并记录在 _arrayoffset   # determine whether arrays are zero-based (bash) or one-based (zsh)   _xarray=(a b c)   if [ -z "${_xarray[${#_xarray[@]}]}" ]   then       _arrayoffset=1   else       _arrayoffset=0   fi   unset _xarray         # 运行所有vendor下的 vendorsetup.sh文件   #存在vendor/aosp/vendorsetup.sh   当前 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      # Execute the contents of any vendorsetup.sh files we can find.   for f in `/bin/ls vendor/*/vendorsetup.sh vendor/*/build/vendorsetup.sh 2> /dev/null`    do       echo "including $f"       . $f   done   unset f      明天接下来看 lunch()函数  

[ruby]  view plain  copy  print ? build/envsetup.sh 脚本分析(lunch函数)      lunch函数提供了一个菜单,让开发人员选择需要编译的目标产品(target product)和变体(variant),并做一些检查,设置环境变量,并打印出主要的环境变量。      直接运行lunch(必须先运行 build/envsetup.sh,让lunch函数驻留到环境变量中)      ning@ning-desktop:~/donut-compare/mydroid$ lunch      You're building on Linux      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   Lunch menu... pick a combo:        1. generic-eng        2. simulator        3. aosp_emulator_us-eng        4. aosp_emulator_eu-eng        5. aosp_dream_us-userdebug        6. aosp_dream_eu-userdebug        7. aosp_dream_us-eng        8. aosp_dream_eu-eng        9. aosp_sapphire_us-userdebug        10. aosp_sapphire_eu-userdebug        11. aosp_sapphire_us-eng        12. aosp_sapphire_eu-eng      Which would you like? [generic-eng] 7      ============================================   PLATFORM_VERSION_CODENAME=REL   PLATFORM_VERSION=1.6   TARGET_PRODUCT=aosp_dream_us   TARGET_BUILD_VARIANT=eng   TARGET_SIMULATOR=false   TARGET_BUILD_TYPE=release   TARGET_ARCH=arm   HOST_ARCH=x86   HOST_OS=linux   HOST_BUILD_TYPE=release   BUILD_ID=Donut   ============================================      用户也可以直接输入参数,不使用菜单      ning@ning-desktop:~/donut-compare/mydroid$ lunch aosp_dream_us-eng      ============================================   PLATFORM_VERSION_CODENAME=REL   PLATFORM_VERSION=1.6   TARGET_PRODUCT=aosp_dream_us   TARGET_BUILD_VARIANT=eng   TARGET_SIMULATOR=false   TARGET_BUILD_TYPE=release   TARGET_ARCH=arm   HOST_ARCH=x86   HOST_OS=linux   HOST_BUILD_TYPE=release   BUILD_ID=Donut   ============================================      下面是lunch函数源代码,用蓝色添加了一下注释,便于阅读:      function lunch()   {       local answer          if [ "$1" ] ; then          # lunch后面直接带参数           answer=$1       else          # lunch后面不带参数,则打印处所有的target product和variant菜单提供用户选择           print_lunch_menu              echo -n "Which would you like? [generic-eng] "           read answer       fi          local selection=          if [ -z "$answer" ]       then              # 如果用户在菜单中没有选择,直接回车,则为系统缺省的generic-eng           selection=generic-eng       elif [ "$answer" = "simulator" ]       then           # 如果是模拟器           selection=simulator       elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")       then           # 如果answer是选择菜单的数字,则获取该数字对应的字符串           if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]           then               selection=${LUNCH_MENU_CHOICES[$(($answer-$_arrayoffset))]}           fi           # 如果 answer字符串匹配 *-*模式(*的开头不能为-)       elif (echo -n $answer | grep -q -e "^[^\-][^\-]*-[^\-][^\-]*$")       then           selection=$answer       fi          if [ -z "$selection" ]       then           echo           echo "Invalid lunch combo: $answer"           return 1       fi          # special case the simulator       if [ "$selection" = "simulator" ]       then           # 模拟器模式           export TARGET_PRODUCT=sim           export TARGET_BUILD_VARIANT=eng           export TARGET_SIMULATOR=true           export TARGET_BUILD_TYPE=debug       else              # 将 product-variant模式种的product分离出来           local product=$(echo -n $selection | sed -e "s/-.*$//")              # 检查之,调用关系 check_product()->get_build_var()->build/core/config.mk比较罗嗦,不展开了           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              # 将 product-variant模式种的variant分离出来           local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//")              # 检查之,看看是否在 (user userdebug eng) 范围内           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              export TARGET_PRODUCT=$product           export TARGET_BUILD_VARIANT=$variant           export TARGET_SIMULATOR=false           export TARGET_BUILD_TYPE=release       fi # !simulator          echo          # 设置到环境变量,比较多,不再一一列出,最 简单的方法 set >env.txt 可获得       set_stuff_for_environment       # 打印一些主要的变量, 调用关系 printconfig()->get_build_var()->build/core/config.mk->build/core/envsetup.mk 比较罗嗦,不展开了       printconfig   }  
转载请注明原文地址: https://www.6miu.com/read-53560.html

最新回复(0)