Android 编译之source和lunch

1. source build/envsetup.sh原理

会发现build/core和build/make/core文件是一样的,这是是从build/make/core链接过去的,因此修改build/make/core就好

ubuntu@ubuntu:~/work/project/Android/build$ ll
总用量 24
drwxrwxr-x  6 ubuntu ubuntu 4096 11月 18 17:19 ./
drwxrwxr-x 31 ubuntu ubuntu 4096 11月 18 17:19 ../
drwxrwxr-x 14 ubuntu ubuntu 4096 11月  1 19:13 blueprint/
lrwxrwxrwx  1 ubuntu ubuntu   25 11月 18 17:19 buildspec.mk.default -> make/buildspec.mk.default
lrwxrwxrwx  1 ubuntu ubuntu   17 11月 18 17:19 CleanSpec.mk -> make/CleanSpec.mk
lrwxrwxrwx  1 ubuntu ubuntu    9 11月 18 17:19 core -> make/core/
lrwxrwxrwx  1 ubuntu ubuntu   16 11月 18 17:19 envsetup.sh -> make/envsetup.sh*
drwxrwxr-x  6 ubuntu ubuntu 4096 11月  1 19:13 kati/
drwxrwxr-x  7 ubuntu ubuntu 4096 11月  1 19:13 make/
drwxrwxr-x 18 ubuntu ubuntu 4096 11月  1 19:13 soong/
lrwxrwxrwx  1 ubuntu ubuntu   11 11月 18 17:19 target -> make/target/
lrwxrwxrwx  1 ubuntu ubuntu   10 11月 18 17:19 tools -> make/tools/

source build/envsetup.sh是执行这个脚本,主要就是提供函数和命令给编译使用

//比如这个hmm就可以在终端直接输入

@build/envsetup.sh
function hmm() {
cat <<EOF
Invoke ". build/envsetup.sh" from your shell to add the following functions to your environment:
- lunch:     lunch <product_name>-<build_variant>
- tapas:     tapas [<App1> <App2> ...] [arm|x86|mips|armv5|arm64|x86_64|mips64] [eng|userdebug|user]
- croot:     Changes directory to the top of the tree.
- m:         Makes from the top of the tree.
- mm:        Builds all of the modules in the current directory, but not their dependencies.
- mmm:       Builds all of the modules in the supplied directories, but not their dependencies.
             To limit the modules being built use the syntax: mmm dir/:target1,target2.
- mma:       Builds all of the modules in the current directory, and their dependencies.
- mmma:      Builds all of the modules in the supplied directories, and their dependencies.
- provision: Flash device with all required partitions. Options will be passed on to fastboot.
- cgrep:     Greps on all local C/C++ files.
- ggrep:     Greps on all local Gradle files.
- jgrep:     Greps on all local Java files.
- resgrep:   Greps on all local res/*.xml files.
- mangrep:   Greps on all local AndroidManifest.xml files.
- mgrep:     Greps on all local Makefiles files.
- sepgrep:   Greps on all local sepolicy files.
- sgrep:     Greps on all local source files.
- godir:     Go to the directory containing a file.

Environment options:
- SANITIZE_HOST: Set to 'true' to use ASAN for all host modules. Note that
                 ASAN_OPTIONS=detect_leaks=0 will be set by default until the
                 build is leak-check clean.

Look at the source to view more functions. The complete list is:
EOF
    local T=$(gettop)
    local A=""
    local i
    for i in `cat $T/build/envsetup.sh | sed -n "/^[[:blank:]]*function /s/function \([a-z_]*\).*/\1/p" | sort | uniq`; do
      A="$A $i"
    done
    echo $A
}

其中也包含有make编译命令

function make()
{
    _wrap_build $(get_make_command) "$@"
}

function _wrap_build()
{

    local start_time=$(date +"%s")
    "$@"   //执行传入的参数 $(get_make_command) "$@",开始编译
    local ret=$?
    local end_time=$(date +"%s")
    local tdiff=$(($end_time-$start_time))
    local hours=$(($tdiff / 3600 ))
    local mins=$((($tdiff % 3600) / 60))
    local secs=$(($tdiff % 60))
    local ncolors=$(tput colors 2>/dev/null)
    if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then
        color_failed=$'\E'"[0;31m"
        color_success=$'\E'"[0;32m"
        color_reset=$'\E'"[00m"
    else
        color_failed=""
        color_success=""
        color_reset=""
    fi
    echo
    if [ $ret -eq 0 ] ; then
        echo -n "${color_success}#### build completed successfully "
    else
        echo -n "${color_failed}#### failed to build some targets "
    fi
    if [ $hours -gt 0 ] ; then
        printf "(%02g:%02g:%02g (hh:mm:ss))" $hours $mins $secs
    elif [ $mins -gt 0 ] ; then
        printf "(%02g:%02g (mm:ss))" $mins $secs
    elif [ $secs -gt 0 ] ; then
        printf "(%s seconds)" $secs
    fi
    echo " ####${color_reset}"
    echo


    if [ $ret -eq 0 ]  ; then
        #编译成功后执行这里
    fi


    return $ret
}

2.lunch原理

source的最后会去执行 vendorsetup.sh 里面的内容,从下面是在device vendor这两个目录的所有vendorsetup.sh

@build/envsetup.sh
# 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 | 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"
    . $f     //执行vendorsetup.sh
done
unset f

addcompletions

//执行shell

@device/qcom/common/vendorsetup.sh
add_lunch_combo msm8994-userdebug
add_lunch_combo msm8994-user
add_lunch_combo msm8996_gvmq-userdebug
add_lunch_combo msm8996_gvmq-user
@build/envsetup.sh
# 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)
}

lunch时就执行这里,先就会调用print_lunch_menu打印所有的LUNCH_MENU_CHOICES

function lunch()
{
    local answer

    if [ "$1" ] ; then
        answer=$1
    else
        print_lunch_menu
        echo -n "Which would you like? [aosp_arm-eng] "
        read answer   //通过列表选择lunch哪一个,然后传给answer
    fi

//假如这里是 msm8996_gvmq-userdebug
    local selection=

    if [ -z "$answer" ]  //如果是空的,就默认为selection=aosp_arm-eng
    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
    else
        selection=$answer    //这里就为msm8996_gvmq-userdebug
    fi

    export TARGET_BUILD_APPS=

    local product variant_and_version variant version

    product=${selection%%-*} # Trim everything after first dash   //取-左边,也就是msm8996_gvmq
    variant_and_version=${selection#*-} # Trim everything up to first dash  //右边是userdebug
    if [ "$variant_and_version" != "$selection" ]; then
        variant=${variant_and_version%%-*}
        if [ "$variant" != "$variant_and_version" ]; then
            version=${variant_and_version#*-}
        fi
    fi

    if [ -z "$product" ]  //lunch返回
    then
        echo
        echo "Invalid lunch combo: $selection"
        return 1
    fi

    TARGET_PRODUCT=$product \
    TARGET_BUILD_VARIANT=$variant \
    TARGET_PLATFORM_VERSION=$version \
    build_build_var_cache
    if [ $? -ne 0 ]
    then
        return 1
    fi

    export TARGET_PRODUCT=$(get_build_var TARGET_PRODUCT)
    export TARGET_BUILD_VARIANT=$(get_build_var TARGET_BUILD_VARIANT)
    if [ -n "$version" ]; then
      export TARGET_PLATFORM_VERSION=$(get_build_var TARGET_PLATFORM_VERSION)
    else
      unset TARGET_PLATFORM_VERSION
    fi
    export TARGET_BUILD_TYPE=release

    echo

    export TARGET_BUILD_ADB_DEFAULT=
    export TARGET_BUILD_USER_ROOT_ENABLE=
    if [ $TARGET_BUILD_VARIANT == "user" ] ; then
      chooseadbcomposition $2   //$2 enable  如果选择user版本,是否打开adb和root
      chooseuserenableroot $3
    fi

    set_stuff_for_environment   //设置环境变量和参数,如ANDROID_BUILD_TOP
    printconfig
    destroy_build_var_cache
}
分别对应 导入TARGET_BUILD_ADB_DEFAULT  TARGET_BUILD_USER_ROOT_ENABLE这两个变量
function chooseadbcomposition()
{
    echo "adb default:"
    echo "     1. enable"
    echo "     2. disable"
    echo

    local DEFAULT_NUM DEFAULT_VALUE
    DEFAULT_NUM=2
    DEFAULT_VALUE=disable
    export TARGET_BUILD_ADB_DEFAULT=

    local ANSWER
    echo -n "Which would you like? ["$DEFAULT_NUM"] "
    if [ -z "$1" ] ; then
        read ANSWER
    else
        echo $1
        ANSWER=$1
    fi
    case $ANSWER in
    "")
        export TARGET_BUILD_ADB_DEFAULT=$DEFAULT_VALUE
        ;;
    1)
        export TARGET_BUILD_ADB_DEFAULT=enable
        ;;
    2)
        export TARGET_BUILD_ADB_DEFAULT=disable
        ;;
    *)
        echo
        echo "I didn't understand your response.  Please try again."
        echo
        ;;
    esac

    echo "TARGET_BUILD_ADB_DEFAULT=$TARGET_BUILD_ADB_DEFAULT"
}

function chooseuserenableroot()
{
    ...
    case $ANSWER in
        export TARGET_BUILD_USER_ROOT_ENABLE=enable
        ;;
    2)
        export TARGET_BUILD_USER_ROOT_ENABLE=disable
        ;;
    *)
    echo "TARGET_BUILD_USER_ROOT_ENABLE=$TARGET_BUILD_USER_ROOT_ENABLE"
}

//结果就是打印,选择,然后设置环境变量
adb default:
     1. enable
     2. disable

Which would you like? [2] 1
TARGET_BUILD_ADB_DEFAULT=enable
user root(closable selinux):
     1. enable
     2. disable
//设置些环境变量参数
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'
    export ASAN_OPTIONS=detect_leaks=0
}

function printconfig()
{
    local 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的结果,打印了很多变量,launch应该就是导入环境变量,通过lunch选择,知道项目产品和userdebug版本等,然后make时可以通过值的不同,实现不同编译

Which would you like? [aosp_arm-eng] msm8996_gvmq-userdebug

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=8.1.0
TARGET_PRODUCT=msm8996_gvmq
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_PLATFORM_VERSION=OPM1
TARGET_BUILD_APPS=
TARGET_ARCH=arm64
TARGET_ARCH_VARIANT=armv8-a
TARGET_CPU_VARIANT=kryo
TARGET_2ND_ARCH=arm
TARGET_2ND_ARCH_VARIANT=armv7-a-neon
TARGET_2ND_CPU_VARIANT=cortex-a9
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-4.15.0-70-generic-x86_64-with-Ubuntu-16.04-xenial
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=YT.CA.17101.01100
OUT_DIR=out
AUX_OS_VARIANT_LIST=

3. lunch之后的不同产品的编译

4.添加一个新lunch编译选项

参照高通写法

xref: /device/qcom/
common/
msm8996/
msm8996_gvmq/
sepolicy/


比如产品为公司为company myproduct
创建目录
device/company/common   //存放 vendorsetup.sh放入 add_lunch_combo myproduct-userdebug
device/company/myproduct //复制高通对应目录 msm8996_gvmq,修改里面的product配置

3.其他一些点

TARGET_DEVICE 控制out/target/product/msm8996_gvmq名字

env查看环境变量
ANDROID_PRODUCT_OUT=/home/wangdong/work/project/3s1/hqx/LINUX/android/out/target/product/msm8996_gvmq

@envsetup.sh
export ANDROID_PRODUCT_OUT=$(get_abs_build_var PRODUCT_OUT)

@build/core/envsetup.mk
PRODUCT_OUT := $(TARGET_PRODUCT_OUT_ROOT)/$(TARGET_DEVICE)

@device/chinatsp/bordrinb31/bordrinb31.mk
PRODUCT_NAME := bordrinb31
PRODUCT_DEVICE := msm8996_gvmq
TARGET_VENDOR := chinatsp

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值