目录
AOSP-envsetup.sh里的lunch到底干了啥事情呢?

编译操作过程

我们先梳理清楚我们在编译的时候,这个过得干了啥!!

首次我们是设置环境

shell
复制代码
aosp@ubuntu:~/android5.1$ source build/envsetup.sh 
including device/lge/hammerhead/vendorsetup.sh
including device/lge/mako/vendorsetup.sh
including device/samsung/manta/vendorsetup.sh
including device/generic/mini-emulator-arm64/vendorsetup.sh
including device/generic/mini-emulator-x86_64/vendorsetup.sh
including device/generic/mini-emulator-armv7-a-neon/vendorsetup.sh
including device/generic/mini-emulator-x86/vendorsetup.sh
including device/generic/mini-emulator-mips/vendorsetup.sh
including device/moto/shamu/vendorsetup.sh
including device/asus/flo/vendorsetup.sh
including device/asus/tilapia/vendorsetup.sh
including device/asus/deb/vendorsetup.sh
including device/asus/grouper/vendorsetup.sh
including device/asus/fugu/vendorsetup.sh
including device/htc/flounder/vendorsetup.sh
including sdk/bash_completion/adb.bash

然后加载编译目标

shell
复制代码
aosp@ubuntu:~/android5.1$ lunch

You're building on Linux

Lunch menu... pick a combo:
     1. aosp_arm-eng
     2. aosp_arm64-eng
     3. aosp_mips-eng
     4. aosp_mips64-eng
     5. aosp_x86-eng
     6. aosp_x86_64-eng
     7. aosp_hammerhead-userdebug
     8. aosp_mako-userdebug
     9. aosp_manta-userdebug
     10. mini_emulator_arm64-userdebug
     11. mini_emulator_x86_64-userdebug
     12. m_e_arm-userdebug
     13. mini_emulator_x86-userdebug
     14. mini_emulator_mips-userdebug
     15. aosp_shamu-userdebug
     16. aosp_flo-userdebug
     17. aosp_tilapia-userdebug
     18. aosp_deb-userdebug
     19. aosp_grouper-userdebug
     20. full_fugu-userdebug
     21. aosp_fugu-userdebug
     22. aosp_flounder-userdebug

Which would you like? [aosp_arm-eng] 

okay,到这里,我们的疑问就来了,这些构建目标是怎么来的呢?

lunch

首先是我们的lunch命令,如果不source build/envsetup.sh是没有这个命令的。

我们可以看一下build/envsetup.sh脚本的代码,可以发现lunch就在里面

shell
复制代码
function lunch()
{
	# 选项结果,也就是我们前面输入的5
    local answer
	
	# 有携带参数,直接结果就是参数了
    if [ "$1" ] ; then
        answer=$1
    else
    # 没有携带参数,那么就输出lunch列表
    #print_lunch_menu就是我们看到的列表了
        print_lunch_menu
        echo -n "Which would you like? [aosp_arm-eng] "
        # 读取选项值
        read answer
    fi
    ....省略代码....
}

先看到这里,我们就知道了,列表是print_lunch_menu输出的

我们接下来的课程,创建属于自己的产品,就是在这里有个编译选项,然后去编译我们自己的内容。

print_lunch_menu

所以呢,我们看看这个输出列表是怎么来的。

shell
复制代码
function print_lunch_menu()
{
    local uname=$(uname)
    echo
    echo "You're building on" $uname
    echo
    echo "Lunch menu... pick a combo:"

    local i=1
    local choice
    # 列表在这里:
    for choice in ${LUNCH_MENU_CHOICES[@]}
    do
        echo "     $i. $choice"
        i=$(($i+1))
    done

    echo
}

那么我们就看看LUNCH_MENU_CHOICES这个是在哪里赋值的

add_lunch_combo

shell
复制代码
# 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
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)
}

# add the default one here
add_lunch_combo aosp_arm-eng
add_lunch_combo aosp_arm64-eng
add_lunch_combo aosp_mips-eng
add_lunch_combo aosp_mips64-eng
add_lunch_combo aosp_x86-eng
add_lunch_combo aosp_x86_64-eng

这样子,前6个就有了,我们可以做一下实验,注释掉看看。

修改了envsetup.sh文件,需要重新载入到环境中,再lunch一次,我们就会发现没了。

okay,到这里可以确定,这个是在这里添加了。

接下来呢,我们探讨一下其他的是在哪里添加的。同学们凭借着自己的经验,知道如何寻找出来吗?

如果你不知道的,可以搜索,如果你代码经验,第一反映应该是这些地方调用了add_lunch_combo

shell
复制代码
aosp@ubuntu:~/android5.1$ source build/envsetup.sh 
including device/lge/hammerhead/vendorsetup.sh
including device/lge/mako/vendorsetup.sh
including device/samsung/manta/vendorsetup.sh
including device/generic/mini-emulator-arm64/vendorsetup.sh
including device/generic/mini-emulator-x86_64/vendorsetup.sh
including device/generic/mini-emulator-armv7-a-neon/vendorsetup.sh
including device/generic/mini-emulator-x86/vendorsetup.sh
including device/generic/mini-emulator-mips/vendorsetup.sh
including device/moto/shamu/vendorsetup.sh
including device/asus/flo/vendorsetup.sh
including device/asus/tilapia/vendorsetup.sh
including device/asus/deb/vendorsetup.sh
including device/asus/grouper/vendorsetup.sh
including device/asus/fugu/vendorsetup.sh
including device/htc/flounder/vendorsetup.sh
including sdk/bash_completion/adb.bash

那这些又是在哪里include的呢?

shell
复制代码
# Execute the contents of any vendorsetup.sh files we can find.
for f in `test -d device && find -L device -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null` \
         `test -d vendor && find -L vendor -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null`
do
    echo "including $f"
    . $f
done
unset f

在我们的device目录下第一层

image-20211123222504246

最深不超过4层,找到vendorsetup.sh,以及vendor目录下,一般厂商定义的会在vendor目录下。但是我们平时开发一般不遵守的,因为打开文件的时候真的麻烦。打开两个地方。

到这里,我们随便找一个vendorsetup.sh文件查看一下。

比如说:

including device/lge/hammerhead/vendorsetup.sh

我们就发现

shell
复制代码
add_lunch_combo aosp_hammerhead-userdebug

卧草,这不就是跟前面一样,okay,这样子就添加进列表里去了。那添加进去只是个名字呀,这个名字怎么样起作用呢?

我们双回到最开始lunch的命令下,看看我们选择了5以后,干了啥。

shell
复制代码
function lunch()
{
    local answer

 	....省略代码,目标列表已经输出,answer值也得到了....

	# 定义一个选项变量
    local selection=

	# 如果答案长度为0,那默认是aosp_arm-eng
    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
        # 如果输入的是名字串,直接就等于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

	# 到这里selection是有值的了
	# 把环境中的TARGET_BUILD_APPS设置为空
    export TARGET_BUILD_APPS=
	
	# 对名字串里的-xxx替换掉
	# aosp_x86-eng变成aosp_x86
    local product=$(echo -n $selection | sed -e "s/-.*$//")
    # 检查产品是否有的,如果返回值不为0,说明产品不对,也就是选择的/输入的不对。
    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
    ....省略代码....
}

到这里我们先去看一个分支,检查产品,看看检查产品干了啥

check_product

shell
复制代码
# check to see if the supplied product is one we can build
function check_product()
{
	# 获取到工作目录/home/aosp/android5.1
    T=$(gettop)
    if [ ! "$T" ]; then
        echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
        return
    fi
        TARGET_PRODUCT=$1 \
        TARGET_BUILD_VARIANT= \
        TARGET_BUILD_TYPE= \
        TARGET_BUILD_APPS= \
        get_build_var TARGET_DEVICE > /dev/null
    # hide successful answers, but allow the errors to show
}

设置TARGET_PRODUCT变量值,$1就是我们前面传进来的第一个参数$product

然后调用get_build_var

get_build_var

shell
复制代码
# Get the exact value of a build variable.
function get_build_var()
{
    T=$(gettop)
    if [ ! "$T" ]; then
        echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
        return
    fi
    # 设置变量,载入config.mk文件,mk文件由make去解析
    (\cd $T; CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
      command make --no-print-directory -f build/core/config.mk dumpvar-$1)
}

也没干啥,设置变量,执行config.mk

我们回到lunch上继续看

shell
复制代码
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 product=$(echo -n $selection | sed -e "s/-.*$//")
	
	# 如果返回值不为0,那么就输出提示信息
    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

	# aosp_x86-eng变成eng了,也就是获取到构建类型是user版本,还是userdebug版本,又或者debug版本
	# 详情请看下方的构建类型说明
    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
	...省略代码...
}

关于构建类型的说明:

image-20211127201332324

check_variant

check_variant $variant

shell
复制代码
VARIANT_CHOICES=(user userdebug eng)

# check to see if the supplied variant is valid
function check_variant()
{
    for v in ${VARIANT_CHOICES[@]}
    do
        if [ "$v" = "$1" ]
        then
            return 0
        fi
    done
    return 1
}

可以看出,只有三种构建类型。

okay,继续往下去看看

shell
复制代码
function lunch()
{
   	
   	...省略代码...
   	# 再对产品和构建类型进行检查
    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
}

set_stuff_for_environment

set_stuff_for_environment,这里面又分了几个分支去做其他事情

  • settitle 设置标题
  • set_java_home 设置java的路径
  • setpaths 设置环境变量
  • set_sequence_number 设置序号
shell
复制代码
function set_stuff_for_environment()
{
    settitle
    set_java_home
    setpaths
    set_sequence_number

    export ANDROID_BUILD_TOP=$(gettop)
    # With this environment variable new GCC can apply colors to warnings/errors
    export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
}

printconfig 输出配置信息

printconfig

shell
复制代码
function printconfig()
{
    T=$(gettop)
    if [ ! "$T" ]; then
        echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
        return
    fi
    get_build_var report_config
}

下面我们对比一下,lunch前后的配置信息

shell
复制代码
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=5.1
TARGET_PRODUCT=full
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a
TARGET_CPU_VARIANT=generic
TARGET_2ND_ARCH=
TARGET_2ND_ARCH_VARIANT=
TARGET_2ND_CPU_VARIANT=
HOST_ARCH=x86_64
HOST_OS=linux
HOST_OS_EXTRA=Linux-5.4.0-90-generic-x86_64-with-Ubuntu-18.04-bionic
HOST_BUILD_TYPE=release
BUILD_ID=LMY47D
OUT_DIR=out
============================================

lunch 5. aosp_x86-eng 之后

shell
复制代码
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=5.1
TARGET_PRODUCT=aosp_x86
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=x86
TARGET_ARCH_VARIANT=x86
TARGET_CPU_VARIANT=
TARGET_2ND_ARCH=
TARGET_2ND_ARCH_VARIANT=
TARGET_2ND_CPU_VARIANT=
HOST_ARCH=x86_64
HOST_OS=linux
HOST_OS_EXTRA=Linux-5.4.0-90-generic-x86_64-with-Ubuntu-18.04-bionic
HOST_BUILD_TYPE=release
BUILD_ID=LMY47D
OUT_DIR=out
============================================

环境变量前后的区别

lunch之前的环境变量内容

shell
复制代码
aosp@ubuntu:~$ export
declare -x CLUTTER_IM_MODULE="xim"
declare -x COLORTERM="truecolor"
declare -x DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
declare -x DESKTOP_AUTOSTART_ID="10d28aafa23347d7f3163801459414654300000034500007"
declare -x DESKTOP_SESSION="ubuntu"
declare -x DISPLAY=":0"
declare -x GDMSESSION="ubuntu"
declare -x GNOME_DESKTOP_SESSION_ID="this-is-deprecated"
declare -x GNOME_SHELL_SESSION_MODE="ubuntu"
declare -x GNOME_TERMINAL_SCREEN="/org/gnome/Terminal/screen/c3085c45_2cae_4799_afb9_524095904c0b"
declare -x GNOME_TERMINAL_SERVICE=":1.88"
declare -x GPG_AGENT_INFO="/run/user/1000/gnupg/S.gpg-agent:0:1"
declare -x GTK_IM_MODULE="ibus"
declare -x GTK_MODULES="gail:atk-bridge"
declare -x HOME="/home/aosp"
declare -x IM_CONFIG_PHASE="2"
declare -x JAVA_HOME="/home/aosp/devTools/jdk1.7.0_80"
declare -x LANG="en_US.UTF-8"
declare -x LESSCLOSE="/usr/bin/lesspipe %s %s"
declare -x LESSOPEN="| /usr/bin/lesspipe %s"
declare -x LIBVIRT_DEFAULT_URI="qemu:///system"
declare -x LOGNAME="aosp"
declare -x LS_COLORS="rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:"
declare -x OLDPWD
declare -x PATH="/home/aosp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/aosp/devTools/jdk1.7.0_80/bin"
declare -x PWD="/home/aosp"
declare -x QT4_IM_MODULE="xim"
declare -x QT_ACCESSIBILITY="1"
declare -x QT_IM_MODULE="ibus"
declare -x REPO_URL="https://mirrors.tuna.tsinghua.edu.cn/git/git-repo"
declare -x SESSION_MANAGER="local/ubuntu:@/tmp/.ICE-unix/3450,unix/ubuntu:/tmp/.ICE-unix/3450"
declare -x SHELL="/bin/bash"
declare -x SHLVL="1"
declare -x SSH_AGENT_PID="3552"
declare -x SSH_AUTH_SOCK="/run/user/1000/keyring/ssh"
declare -x TERM="xterm-256color"
declare -x TEXTDOMAIN="im-config"
declare -x TEXTDOMAINDIR="/usr/share/locale/"
declare -x USER="aosp"
declare -x USERNAME="aosp"
declare -x VTE_VERSION="5202"
declare -x WINDOWPATH="2"
declare -x XAUTHORITY="/run/user/1000/gdm/Xauthority"
declare -x XDG_CONFIG_DIRS="/etc/xdg/xdg-ubuntu:/etc/xdg"
declare -x XDG_CURRENT_DESKTOP="ubuntu:GNOME"
declare -x XDG_DATA_DIRS="/usr/share/ubuntu:/usr/local/share/:/usr/share/:/var/lib/snapd/desktop"
declare -x XDG_MENU_PREFIX="gnome-"
declare -x XDG_RUNTIME_DIR="/run/user/1000"
declare -x XDG_SEAT="seat0"
declare -x XDG_SESSION_DESKTOP="ubuntu"
declare -x XDG_SESSION_ID="2"
declare -x XDG_SESSION_TYPE="x11"
declare -x XDG_VTNR="2"
declare -x XMODIFIERS="@im=ibus"
aosp@ubuntu:~$ 

lunch之后

shell
复制代码
aosp@ubuntu:~/android5.1$ export
declare -x ANDROID_BUILD_PATHS="/home/aosp/android5.1/out/host/linux-x86/bin:/home/aosp/android5.1/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8/bin:/home/aosp/android5.1/prebuilts/gcc/linux-x86/:/home/aosp/android5.1/development/scripts:/home/aosp/android5.1/prebuilts/devtools/tools:/home/aosp/android5.1/prebuilts/android-emulator/linux-x86_64:"
declare -x ANDROID_BUILD_TOP="/home/aosp/android5.1"
declare -x ANDROID_DEV_SCRIPTS="/home/aosp/android5.1/development/scripts:/home/aosp/android5.1/prebuilts/devtools/tools"
declare -x ANDROID_EMULATOR_PREBUILTS="/home/aosp/android5.1/prebuilts/android-emulator/linux-x86_64"
declare -x ANDROID_HOST_OUT="/home/aosp/android5.1/out/host/linux-x86"
declare -x ANDROID_JAVA_TOOLCHAIN="/home/aosp/devTools/jdk1.7.0_80/bin"
declare -x ANDROID_PRE_BUILD_PATHS="/home/aosp/devTools/jdk1.7.0_80/bin:"
declare -x ANDROID_PRODUCT_OUT="/home/aosp/android5.1/out/target/product/generic_x86"
declare -x ANDROID_TOOLCHAIN="/home/aosp/android5.1/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8/bin"
declare -x ANDROID_TOOLCHAIN_2ND_ARCH="/home/aosp/android5.1/prebuilts/gcc/linux-x86/"
declare -x BUILD_ENV_SEQUENCE_NUMBER="10"
declare -x CLUTTER_IM_MODULE="xim"
declare -x COLORTERM="truecolor"
declare -x DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
declare -x DESKTOP_AUTOSTART_ID="10d28aafa23347d7f3163801459414654300000034500007"
declare -x DESKTOP_SESSION="ubuntu"
declare -x DISPLAY=":0"
declare -x GCC_COLORS="error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01"
declare -x GDMSESSION="ubuntu"
declare -x GNOME_DESKTOP_SESSION_ID="this-is-deprecated"
declare -x GNOME_SHELL_SESSION_MODE="ubuntu"
declare -x GNOME_TERMINAL_SCREEN="/org/gnome/Terminal/screen/c3085c45_2cae_4799_afb9_524095904c0b"
declare -x GNOME_TERMINAL_SERVICE=":1.88"
declare -x GPG_AGENT_INFO="/run/user/1000/gnupg/S.gpg-agent:0:1"
declare -x GTK_IM_MODULE="ibus"
declare -x GTK_MODULES="gail:atk-bridge"
declare -x HOME="/home/aosp"
declare -x IM_CONFIG_PHASE="2"
declare -x JAVA_HOME="/home/aosp/devTools/jdk1.7.0_80"
declare -x LANG="en_US.UTF-8"
declare -x LC_ALL="C"
declare -x LESSCLOSE="/usr/bin/lesspipe %s %s"
declare -x LESSOPEN="| /usr/bin/lesspipe %s"
declare -x LIBVIRT_DEFAULT_URI="qemu:///system"
declare -x LOGNAME="aosp"
declare -x LS_COLORS="rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:"
declare -x OLDPWD="/home/aosp"
declare -x OUT="/home/aosp/android5.1/out/target/product/generic_x86"
declare -x PATH="/home/aosp/devTools/jdk1.7.0_80/bin:/home/aosp/android5.1/out/host/linux-x86/bin:/home/aosp/android5.1/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8/bin:/home/aosp/android5.1/prebuilts/gcc/linux-x86/:/home/aosp/android5.1/development/scripts:/home/aosp/android5.1/prebuilts/devtools/tools:/home/aosp/android5.1/prebuilts/android-emulator/linux-x86_64:/home/aosp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/aosp/devTools/jdk1.7.0_80/bin"
declare -x PROMPT_COMMAND="echo -ne \"\\033]0;[x86-aosp_x86-eng] aosp@ubuntu: /home/aosp/android5.1\\007\""
declare -x PWD="/home/aosp/android5.1"
declare -x QT4_IM_MODULE="xim"
declare -x QT_ACCESSIBILITY="1"
declare -x QT_IM_MODULE="ibus"
declare -x REPO_URL="https://mirrors.tuna.tsinghua.edu.cn/git/git-repo"
declare -x SESSION_MANAGER="local/ubuntu:@/tmp/.ICE-unix/3450,unix/ubuntu:/tmp/.ICE-unix/3450"
declare -x SHELL="/bin/bash"
declare -x SHLVL="1"
declare -x SSH_AGENT_PID="3552"
declare -x SSH_AUTH_SOCK="/run/user/1000/keyring/ssh"
declare -x TARGET_BUILD_APPS=""
declare -x TARGET_BUILD_TYPE="release"
declare -x TARGET_BUILD_VARIANT="eng"
declare -x TARGET_GCC_VERSION="4.8"
declare -x TARGET_PRODUCT="aosp_x86"
declare -x TERM="xterm-256color"
declare -x TEXTDOMAIN="im-config"
declare -x TEXTDOMAINDIR="/usr/share/locale/"
declare -x USER="aosp"
declare -x USERNAME="aosp"
declare -x VTE_VERSION="5202"
declare -x WINDOWPATH="2"
declare -x XAUTHORITY="/run/user/1000/gdm/Xauthority"
declare -x XDG_CONFIG_DIRS="/etc/xdg/xdg-ubuntu:/etc/xdg"
declare -x XDG_CURRENT_DESKTOP="ubuntu:GNOME"
declare -x XDG_DATA_DIRS="/usr/share/ubuntu:/usr/local/share/:/usr/share/:/var/lib/snapd/desktop"
declare -x XDG_MENU_PREFIX="gnome-"
declare -x XDG_RUNTIME_DIR="/run/user/1000"
declare -x XDG_SEAT="seat0"
declare -x XDG_SESSION_DESKTOP="ubuntu"
declare -x XDG_SESSION_ID="2"
declare -x XDG_SESSION_TYPE="x11"
declare -x XDG_VTNR="2"
declare -x XMODIFIERS="@im=ibus"

注意观察ANDROID开关的,到这里我们就看完了lunch的过程了

接下来我们要创建属于我们自己的产品。

最后也同样重要的,lunch,不要写在了launch,我经常这么干的,哈哈!

本文由 拉大锯 原创发布于 阳光沙滩 , 未经作者授权,禁止转载
评论
0 / 1024
用户头像
链接正常,准备起飞~
2021-11-28 02:31回复
回复@断点: 这个流程需要自己去看一下
2021-11-28 03:17回复
推荐文章
一篇文章讲清楚 Android 签名:PK8、X509.PEM、JKS 是什么?它们有什么关系?
深入解析Android应用与系统签名的核心文件:PK8、X509.PEM与JKS。本文从非对称加密原理出发,厘清私钥、证书与密钥库的本质区别及相互转换方法,涵盖AOSP平台签名与普通应用发布的实际场景。通过对比V1-V4签名方案及解答常见疑难,助你掌握保障APK完整性与身份认证的关键技术,规避签名丢失或冲突风险。
系统监控运维系统
你是否也深受证书过期、磁盘满载等运维痛点的折磨?排查耗时,影响线上体验。本文分享一款自研运维系统面板,集成证书统一监测、资源预警及WebSSH等功能,实现问题快速定位与处理。附代码共享链接,欢迎参考或二次开发,提升运维效率。
断点说搞个万年历,怎么搞?
想快速拥有一个专属的程序员日历?只需一篇清晰的设计文档,剩下的交给AI!本文带你从零搭建“sob-calendar”项目,集成农历、节气及独特的程序员运势功能。通过实际案例展示如何利用AI高效生成代码并部署上线,让繁琐的开发工作变得轻松有趣,快来体验科技与传统历法的奇妙碰撞吧!
linux服务器的日志、容器清理
本手册提供了一套全面的Linux服务器磁盘清理与排查方法,帮助用户高效管理磁盘空间。通过查看磁盘使用情况、分析Docker占用、清理无用容器和日志,确保系统运行流畅。适合需要优化服务器性能的运维人员参考。
记给网站接入图形验证码
本文分享了如何为个人站点添加图形验证码以提升安全性,详细介绍了使用第三方接口实现验证码功能的过程,并通过代码示例展示了具体实现方式。对于关注网站安全的开发者来说,这篇文章提供了实用的参考价值。
Java开发环境搭建
本文是一份详细的Java开发环境搭建指南,涵盖了Java的发展历史、版本选择及安装配置过程。无论你是初学者还是有经验的开发者,都能从中找到实用的信息和步骤,帮助你快速上手Java开发。
Vue3.js项目的创建
本文详细介绍了如何使用Vue3创建项目,包括Node.js的安装和配置,以及项目的初始化过程。适合初学者学习如何快速搭建Vue3开发环境,并推荐了相关课程供进一步学习。
Network Tools : 您的运维“助手”升级了
Network Tools是一款专为解决运维难题而设计的软件,集设备管理、配置备份、性能监控和告警处理于一体。通过统一的工作台,帮助运维人员更高效地管理资产、定位故障并提升团队协作效率。无论是设备在线状态还是具体问题排查,都能得到全面支持。
Ubuntu 软件安装与彻底卸载指南
本文详细介绍了在 Ubuntu 系统中如何规范安装和彻底卸载 .deb 格式软件,包括依赖修复、残留清理以及图形化工具推荐,适合需要维护系统环境的用户。
JavaWeb开发客户程序更新特殊环境下的骚操作
本文分享了在无外网环境下,如何利用Docker和docker-compose实现高效部署的实战经验。通过基础镜像和本地jar包挂载的方式,解决了内网环境下的依赖问题,适合需要灵活部署方案的技术人员参考。
Linux 防火墙完全指南:从原理到多发行版实战
本文全面解析Linux防火墙的底层原理与主流工具配置,涵盖UFW、firewalld、iptables、nftables等方案,适合不同发行版用户。从基础概念到生产环境加固建议,助你掌握核心安全策略,确保服务器与网络的安全运行。
水上派对英语单词篇
探索FLOATOPIA水上派对的完整指南,涵盖签到流程、场地指引、安全须知、活动安排及夜场舞会等实用英语词汇与对话。无论是初学者还是老手,都能轻松掌握关键术语,享受完美水上体验。
麒麟操作系统下使用 virt-customize 重置虚拟机 root 密码实战
本文详细介绍了在麒麟操作系统环境下使用 virt-customize 工具重置 KVM 虚拟机 root 密码的完整流程,包含安装步骤、常见问题及解决方案,帮助运维人员高效处理密码遗忘或批量初始化场景,避免数据丢失。
浅析JS预编译-函数篇
本文详细讲解了JavaScript中函数的预编译过程,包括AO对象的创建、变量和函数声明的提升,以及执行阶段的变化。适合初学者了解JS执行机制,帮助深入理解代码运行逻辑。
访问Github的另一种姿势
本文介绍了如何通过Watt ToolKit等工具加速访问Github,适合对网络技术感兴趣的读者。内容涵盖工具介绍、下载和使用方法,以及一些实用技巧,值得一看。
使用Gulp压缩JS
本文详细介绍了如何使用Gulp压缩JavaScript文件,特别是支持ES6语法的处理方法。通过实际操作和效果对比,帮助开发者提升代码性能,适合对前端自动化工具感兴趣的读者。
使用Gulp压缩CSS
本文详细介绍了如何使用Gulp工具对CSS文件进行压缩,提升网页加载速度。适合需要优化静态资源的开发者,提供清晰的步骤和示例,帮助快速上手。
从0部署Nuxtjs项目
本文详细介绍了如何将Nuxt.js项目部署到公网,涵盖Node.js安装、环境配置、源码上传及使用PM2启动服务的全过程,适合开发者学习和实践。
Linux 命令行美化利器:tree 命令完全指南(安装 + 全部参数详解)
掌握 Linux 下的 `tree` 命令,快速直观地查看目录结构。本文详细讲解安装方法、参数含义及实战场景,适合开发者和系统管理员提升工作效率。
Linux常用命令(一)
本文详细介绍了Linux基础命令,包括文件操作、系统显示、网络状态、软件包管理等,适合初学者学习和查阅,是掌握Linux系统的实用指南。
大模型推理参数解码:温度、Top-p 与核采样如何塑造生成文本的灵魂
探索大语言模型的采样参数如何塑造生成内容,从温度到Top-p,从惩罚机制到熵控制,揭示背后的信息论原理与实践策略。了解如何通过参数调优,让AI既保持知识的严谨,又拥有创造力的自由。
记从0使用Claude code写代码
本文介绍了如何使用Claude Code搭配DeepSeek进行编程,详细讲解了安装Node.js、全局安装Claude、配置模型以及使用方法。对于开发者来说,这是一份实用的技术教程,尤其适合对AI编程工具感兴趣的读者。
Android-Studio-Gradle同步失败-Library为null的通用排查指南
遇到 Android Studio Gradle Sync 失败时,不要轻易删除全局缓存。本文详细解析了错误原因,并提供了一系列精准的排查步骤和解决方案,帮助开发者快速定位并解决问题,提升开发效率。
PHP实现密码加密
本文详细介绍了Bcrypt密码加密技术及其在PHP中的应用,帮助开发者提升用户密码的安全性。通过实际代码示例,展示了如何使用password_hash和password_verify函数进行密码加密与验证,是学习网络安全知识的实用指南。
WordCloud效果,滚动标签
本文详细介绍了如何在Vue项目中集成WordCloud组件,包括依赖安装、属性配置和使用方法。适合开发者学习如何实现数据可视化功能,提升项目交互体验。
从0使用WordPress搭建一个优美的网站
本文详细介绍了如何使用WordPress搭建一个美观的网站,从安装到主题配置和功能拓展,为读者提供了实用的操作指南。无论是初学者还是有一定经验的开发者,都能从中获得有价值的参考。
JS实现在网站底部添加运行时间
想知道如何在网站底部显示运行时间?本文详细讲解了通过JavaScript实现这一功能的方法,包括时间计算逻辑和代码实现。适合前端开发者学习参考,轻松为网站添加实用功能。
在Vercel上部署Hexo博客
本文详细介绍了如何在Vercel上快速部署Hexo博客,无需后端服务即可实现高效发布。相比传统方式,省去了手动生成和上传静态文件的步骤,更加便捷。适合想要搭建个人博客的开发者参考。
从0搭建一个Hexo博客
本文详细介绍了Hexo博客框架的使用方法,从安装到部署全流程讲解,适合想快速搭建个人博客的技术爱好者。内容清晰易懂,是入门Hexo的理想指南。
离线设备激活方案:古老的 Windows 光盘激活,离线算法授权等
本文深入解析了离线激活的核心原理与实现方式,从历史案例到现代技术,全面剖析了如何在无网络环境下确保软件授权的安全性。通过设备指纹、授权文件校验等手段,为开发者提供了可复用的架构设计思路,适用于工业、医疗等对网络依赖较低的场景。