build/envsetup.sh分析
来源:互联网 发布:2013年网络炒作事件 编辑:程序博客网 时间:2024/04/30 03:52
build/envsetup.sh分析
1. 概述
通常我们是编译Android源码前要先执行
$ source build/envsetup.sh
该脚本执行后,我们就可以执行lunch等命令。怎么会这么神奇,执行了shell脚本就可以多出来几个命令了?
在研究lunch怎么出现的之前,我们先回顾一个关于shell的小知识
1.1 小知识:
当脚本中定义有函数。那么当脚本被执行后,不管脚本中定义的函数没有执行,都可以在命令行通过该函数名去调用该shell函数。
1.2 小实验
新建如下脚本,名字随意
#!/bin/bash# Author: wanghan# Created Time : Mon 15 May 2017 04:00:45 PM CST# File Name: add.sh# Description:add(){ local sum sum=$(( $1 + $2 )) echo "$1 + $2 = $sum"}
执行该脚本
$ source add.sh
像命令一样调用add函数
$ add 1 21 + 2 = 3$ add 1 31 + 3 = 4
1.3 lunch等命令出现的原因分析
由此我们可以知道,正是应为执行了”source build/envsetup.sh”命令,我们可以使用lunch等命令(实际上是shell函数)。
同样,我们也可以在Makefile中调用build/envsetup.sh中的函数如gettop等。
因此,build/envsetup.sh文件存在的意义就是,设置一些环境变量和shell函数为后续的编译工作做准备
2. 整体结构分析
envsetup.sh文件的整体结构体很清晰,主体是由shell函数构成。
2.1 整体代码布局如下
下面的伪代码中省略了所有的shell函数,只留下了envsetup.sh文件中被真正执行了的代码
...//省略一堆shell函数#设定三种编译的版本VARIANT_CHOICES=(user userdebug eng)...//省略一堆shell函数# 添加一些默认的lunch选项add_lunch_combo aosp_arm-engadd_lunch_combo aosp_arm64-engadd_lunch_combo aosp_mips-engadd_lunch_combo aosp_mips64-engadd_lunch_combo aosp_x86-engadd_lunch_combo aosp_x86_64-eng...//省略一堆shell函数# 这行代码前定义了lunch和_lunch函数,这行代码的意思是通过_lunch函数实现lunch命令的自动补全功能complete -F _lunch lunch...//省略一堆shell函数# 如果终端使用的shell使用的是Bash,则什么也不做,反之则警告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" ;; esacfi# 执行所有device、vendor以及product路径下所能找到的所有vendorsetup.sh文件for f in `test -d device && find -L device -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort` \ `test -d vendor && find -L vendor -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort` \ `test -d product && find -L product -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort`do echo "including $f" . $fdoneunset f# addcompletions是envsetup.sh文件定义的一个shell函数addcompletions # 这一行也是整个文件的最后一行
2.2 source build/envsetup.sh 执行后发生了什么?
通过2.1小节的代码,我们可以知道 ++source build/envsetup.sh++ 命令执行后,做了下面几件事。
系统先是加载了一些shell函数。这些shell函数可以在命令行,像普通命令一样被调用。也可以在别的shell脚本中被使用。
定义了VARIANT_CHOICES变量,设定三种编译的版本user、userdebug和eng
添加一些默认的lunch选项如aosp_arm-eng、aosp_arm64-eng、aosp_mips-eng、aosp_mips64-eng、aosp_x86-eng、aosp_x86_64-eng
定义了lunch函数,并实现了lunch命令的补全(定义_lucnh函数,使用complete 命令)
判断终端使用的shell使用的是不是Bash。如果是则什么也不做,如果不是就打印警告信息
执行所有源码根目录下的device、vendor以及product文件夹下所能找到的所有vendorsetup.sh文件
执行addcompletions函数(实现Linux终端下adb命令的补全)
2.3 具体函数功能分析
2.3.1 lunch 函数
lunch 函数的流程图
具体代码如下
function lunch(){ local answer if [ "$1" ] ; then answer=$1 else print_lunch_menu echo -n "Which would you like? [aosp_arm-eng] " read answer fi local selection= if [ -z "$answer" ] then selection=aosp_arm-eng elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$") then if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ] then selection=${LUNCH_MENU_CHOICES[$(($answer-1))]} fi elif (echo -n $answer | grep -q -e "^[^\-][^\-]*-[^\-][^\-]*$") then selection=$answer fi if [ -z "$selection" ] then echo echo "Invalid lunch combo: $answer" return 1 fi export TARGET_BUILD_APPS= local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//") check_variant $variant if [ $? -ne 0 ] then echo echo "** Invalid variant: '$variant'" echo "** Must be one of ${VARIANT_CHOICES[@]}" variant= fi local product=$(echo -n $selection | sed -e "s/-.*$//") TARGET_PRODUCT=$product \ TARGET_BUILD_VARIANT=$variant \ build_build_var_cache if [ $? -ne 0 ] then echo echo "** Don't have a product spec for: '$product'" echo "** Do you have the right repo manifest?" product= fi if [ -z "$product" -o -z "$variant" ] then echo return 1 fi export TARGET_PRODUCT=$product export TARGET_BUILD_VARIANT=$variant export TARGET_BUILD_TYPE=release echo set_stuff_for_environment //设置环境 printconfig //打印环境信息 destroy_build_var_cache //销毁编译变量缓存}
2.3.2 _lunch函数
实现lunch命令的补全的步骤:
首先定义了lunch函数
然后定义了_lunch函数
使用complete命令
# Tab completion for lunch.function _lunch(){ local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" COMPREPLY=( $(compgen -W "${LUNCH_MENU_CHOICES[*]}" -- ${cur}) ) return 0}complete -F _lunch lunch
++complete -F _lunch lunch++ 是上面代码中最关键的一行。
其实名字是不是lunch都没关系,关键是有这一行代码。
当bash在遇到lunch这个词的时候,会调用_lunch函数。
该函数会传入三个参数:要补全的命令名、当前的光标所在的词、当前光标所在的词的前一个词。
补全的结果需要存储到COMPREPLY变量中,以待bash获取。
2.3.3 add_lunch_combo函数
# 清除这个变量。它会在vendorsetup.sh文件中重新定义一遍# 注:文件(vendorsetup.sh)在本文件的末尾被包含(included)见2.2小节,第5步unset LUNCH_MENU_CHOICESfunction 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)}
2.3.4 addcompletions函数
具体代码:
# 如果shell使用的是Bash且版本大于3,则include"sdk/bash_completion"路径下所有以小写字母开头的.bash文件function addcompletions(){ local T dir f # Keep us from trying to run in something that isn't bash. if [ -z "${BASH_VERSION}" ]; then return fi # Keep us from trying to run in bash that's too old. if [ ${BASH_VERSINFO[0]} -lt 3 ]; then return fi dir="sdk/bash_completion" if [ -d ${dir} ]; then for f in `/bin/ls ${dir}/[a-z]*.bash 2> /dev/null`; do echo "including $f" . $f done fi}
执行过程:
如果shell使用的是Bash且版本大于3,则include”sdk/bash_completion”路径下所有以小写字母开头的.bash文件
主要是执行了adb.bash文件,来adb命令的补全
- build/envsetup.sh分析
- build/envsetup.sh分析
- build/envsetup.sh分析
- build/envsetup.sh分析
- build/envsetup.sh脚本分析
- Android build/envsetup.sh分析
- Android Makefile 分析之 (build/envsetup.sh)
- Android Makefile 分析之 (build/envsetup.sh)
- build/envsetup.sh 脚本分析(lunch函数)
- Android build system 分析之 envsetup.sh
- Android build system 分析之 envsetup.sh
- Android build system 分析之 envsetup.sh
- build/envsetup.sh 脚本分析 -- lunch函数
- Android Donut Makefile分析 (build/envsetup.sh)
- Android Donut Makefile分析 (build/envsetup.sh)
- Android Donut Makefile分析 (build/envsetup.sh)
- build/envsetup.sh简记
- build/envsetup.sh 简介
- java 目录的遍历与删除
- Java 快速排序
- Android 之自定义布局(继承控件)
- JavaScript中的函数的两种定义方式和函数变量赋值
- 关于ztree的用法
- build/envsetup.sh分析
- hadoop中输入文件用LongWritable和IntWritable的区别
- springcloud(四):熔断器Hystrix
- C语言中国大学慕课第三讲作业
- adb安装软件,monkey测试 以及如何停止monkey测试
- 如何在Linux环境下建立Git Server并设置用户
- 程序员的宇宙时间线
- access函数判断文件是否存在
- Swift项目引入第三方库的方法