Android系统启动篇

1,《android系统启动流程简介》

2,《android init进程启动流程》

3,《android zygote进程启动流程》

4,《Android SystemServer进程启动流程》

5,《android launcher启动流程》

6,《Android Activity启动过程详解》

Android系统开发准备篇

1,《Android 源码下载和编译》

2,《android 11源码编译和pixel3 刷机》

3,《Android Framework代码IDE加载和调试》

Android系统开发实践篇

1,《android设置默认输入法》

2,《android framework预制APK应用》

3,《Android系统层面限制应用开机自启动详解》

4,《android单独编译framework模块并push》

5,《Android Framework开发系统问题分析》

Android系统开发核心知识储备篇

1,《Android编译系统-envsetup和lunch代码篇》

2,《Android编译系统-概念篇》

3,《android日志系统详解》

4,《Android系统Handler详解》

5,《Android系统Binder详解》

6,《Android中Activity、View和Window关系详解》

7,《android view绘制流程详解》

8,《Android读取系统属性详解》

9,《android 窗口管理机制详解》

10,《初识Android系统》

11,《android中AMS进程通知Zygote进程fork新进程的通信方式》

Android核心功能详解篇

1,《android应用市场点击下载APK安装详解》

2,《Android 手势导航(从下往上滑动进入多任务页面)》

3,《android手势分析(应用界面左往右边滑动退出应用)》

4,《android应用安装流程详解》

5,《android11安装应用触发桌面图标刷新流程》

6,《Android系统多任务Recents详解》

7,《android系统导航栏视图分析》

———————————————————————————————————————————

目录

一, 编译环境初始化

 1.1 初始化命令

1.2 validate_current_shell

1.3 source_vendorsetup

1.4 addcompletions

二,lunch命令

2.1 build_build_var_cache()


一, 编译环境初始化

 1.1 初始化命令

  $ source build/envsetup.sh

  envsetup.sh 主要做了下面几个事情:

 envsetup.sh 文件代码,

...
validate_current_shell
source_vendorsetup
addcompletions

1.2 validate_current_shell

        从接口的名字可以看出,validate_current_shell()主要检查shell环境,

function validate_current_shell() {
    local current_sh="$(ps -o command -p $$)"
    case "$current_sh" in
        *bash*)
            function check_type() { type -t "$1"; }
            ;;
        *zsh*)
            function check_type() { type "$1"; }
            enable_zsh_completion ;;
        *)
            echo -e "WARNING: Only bash and zsh are supported.\nUse of other shell would lead to erroneous results."
            ;;
    esac
}

1.3 source_vendorsetup

          从device、vendor和product等目录遍历搜索vendorsetup.sh,并source进来,

# Execute the contents of any vendorsetup.sh files we can find.
# Unless we find an allowed-vendorsetup_sh-files file, in which case we'll only
# load those.
#
# This allows loading only approved vendorsetup.sh files
function source_vendorsetup() {
    unset VENDOR_PYTHONPATH
    allowed=
    for f in $(find -L device vendor product -maxdepth 4 -name 'allowed-vendorsetup_sh-files' 2>/dev/null | sort); do
        if [ -n "$allowed" ]; then
            echo "More than one 'allowed_vendorsetup_sh-files' file found, not including any vendorsetup.sh files:"
            echo "  $allowed"
            echo "  $f"
            return
        fi
        allowed="$f"
    done

    allowed_files=
    [ -n "$allowed" ] && allowed_files=$(cat "$allowed")
    for dir in device vendor product; do
        for f in $(test -d $dir && \
            find -L $dir -maxdepth 4 -name 'vendorsetup.sh' 2>/dev/null | sort); do

            if [[ -z "$allowed" || "$allowed_files" =~ $f ]]; then
                echo "including $f"; . "$f"
            else
                echo "ignoring $f, not in $allowed"
            fi
        done
    done
}

1.4 addcompletions

function addcompletions()
{
    local T dir f

    # Keep us from trying to run in something that's neither bash nor zsh.
    if [ -z "$BASH_VERSION" -a -z "$ZSH_VERSION" ]; then
        return
    fi

    # Keep us from trying to run in bash that's too old.
    if [ -n "$BASH_VERSION" -a ${BASH_VERSINFO[0]} -lt 3 ]; then
        return
    fi

    local completion_files=(
      system/core/adb/adb.bash
      system/core/fastboot/fastboot.bash
      tools/asuite/asuite.sh
    )
    # Completion can be disabled selectively to allow users to use non-standard completion.
    # e.g.
    # ENVSETUP_NO_COMPLETION=adb # -> disable adb completion
    # ENVSETUP_NO_COMPLETION=adb:bit # -> disable adb and bit completion
    for f in ${completion_files[*]}; do
        if [ -f "$f" ] && should_add_completion "$f"; then
            . $f
        fi
    done

    if should_add_completion bit ; then
        complete -C "bit --tab" bit
    fi
    if [ -z "$ZSH_VERSION" ]; then
        # Doesn't work in zsh.
        complete -o nospace -F _croot croot
    fi
    complete -F _lunch lunch

    complete -F _complete_android_module_names gomod
    complete -F _complete_android_module_names m
}

二,lunch命令

          lunch命令用来设置 TARGET_PRODUCT、TARGET_BUILD_VARIANT、TARGET_PLATFORM_VERSION、TARGET_BUILD_TYPE、TARGET_BUILD_APPS等环境变量。

          lunch操作流程如下:

  1.获取lunch操作的参数,如果参数不为空,参数则为指定要编译的设备型号和编译类型;如果参数为空,会调用print_lunch_menu来显示Lunch菜单项,读取用户的输入,存入answer

  2.如果answer为空,即之前在lunch菜单用,用户只敲了一个回车。会将默认选项改为aosp_arm-eng,结果存入selection

  3.如果lunch操作得到的输入是数字,则将数字转换为LUNCH_MENU_CHOICES中的字符串,结果存入selection

  4.解析selection的值,得到product = aosp_arm 和variant = eng, 把他们分别保存到TARGET_PRODUCT 和 TARGET_BUILD_VARIANT 中

  5.根据前面的设置,调用build_build_var_cache 来更新编译环境相关变量

  6.export 编译选项TARGET_PRODUCT, TARGET_BUILD_VARIANT和TARGET_BUILD_TYPE三元组

  7.调用set_stuff_for_environment 来设置其他环境变量,如PROMPT_COMMAND,编译toolchain和tools相关的路径等

  8.调用printconfig 来输出当前的设置选项

 
function lunch()
{
    local answer
        # 获取lunch操作的参数
    if [ "$1" ] ; then
        answer=$1
    else
           # lunch操作不带参数,则先显示lunch menu,然后读取用户输入
        print_lunch_menu
        echo -n "Which would you like? [aosp_arm-eng] "
        read answer
    fi
 
    local selection=
       # lunch操作得到的结果为空(例如用户直接在lunch要求输入时回车的情况)
    # 则将选项默认为"aosp_arm-eng"
    if [ -z "$answer" ]
    then
        selection=aosp_arm-eng
        # lunch操作得到的输入是数字,则将数字转换为LUNCH_MENU_CHOICES中的字符串
    elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")
    then
        local choices=($(TARGET_BUILD_APPS= get_build_var COMMON_LUNCH_CHOICES))
        if [ $answer -le ${#choices[@]} ]
        then
            # array in zsh starts from 1 instead of 0.
            if [ -n "$ZSH_VERSION" ]
            then
                selection=${choices[$(($answer))]}
            else
                selection=${choices[$(($answer-1))]}
            fi
        fi
    else
        selection=$answer
    fi
 
    export TARGET_BUILD_APPS=
 
    local product variant_and_version variant version
 
    product=${selection%%-*} # Trim everything after first dash
    variant_and_version=${selection#*-} # Trim everything up to first dash
    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" ]
    then
        echo
        echo "Invalid lunch combo: $selection"
        return 1
    fi
 
        # 设置TARGET_PRODUCT和TARGET_BUILD_VARIANT
    TARGET_PRODUCT=$product \
    TARGET_BUILD_VARIANT=$variant \
    TARGET_PLATFORM_VERSION=$version \
 
    # 根据前面的设置,更新编译环境相关变量
    build_build_var_cache     #参考[3.1.1]
    if [ $? -ne 0 ]
    then
        return 1
    fi
 
        # export 编译选项TARGET_PRODUCT, TARGET_BUILD_VARIANT和TARGET_BUILD_TYPE三元组
    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
 
    set_stuff_for_environment # 设置其他环境变量,如PROMPT_COMMAND,编译toolchain和tools相关的路径等
    printconfig        # 输出当前的设置选项
    destroy_build_var_cache
}

2.1 build_build_var_cache()

  根据前面的设置,更新编译环境相关变量

  主要通过执行 "build/soong/soong_ui.bash --dumpvars-mode" 完成

  最终执行的是 "./out/soog_ui  --dumpvars-mode"

 
function build_build_var_cache()
{
    local T=$(gettop)
    # Grep out the variable names from the script.
    cached_vars=(`cat $T/build/envsetup.sh | tr '()' '  ' | awk '{for(i=1;i<=NF;i++) if($i~/get_build_var/) print $(i+1)}' | sort -u | tr '\n' ' '`)
    cached_abs_vars=(`cat $T/build/envsetup.sh | tr '()' '  ' | awk '{for(i=1;i<=NF;i++) if($i~/get_abs_build_var/) print $(i+1)}' | sort -u | tr '\n' ' '`)
    # Call the build system to dump the "<val>=<value>" pairs as a shell script.
    build_dicts_script=`\builtin cd $T; build/soong/soong_ui.bash --dumpvars-mode \
                        --vars="${cached_vars[*]}" \
                        --abs-vars="${cached_abs_vars[*]}" \
                        --var-prefix=var_cache_ \
                        --abs-var-prefix=abs_var_cache_`
    local ret=$?
    if [ $ret -ne 0 ]
    then
        unset build_dicts_script
        return $ret
    fi
    # Execute the script to store the "<val>=<value>" pairs as shell variables.
    eval "$build_dicts_script"
    ret=$?
    unset build_dicts_script
    if [ $ret -ne 0 ]
    then
        return $ret
    fi
    BUILD_VAR_CACHE_READY="true"
}

        soong_ui 由build/soong/cmd/soong_ui/main.go编译生成

[build/soong/cmd/soong_ui/main.go]
func main() {
...
    if os.Args[1] == "--dumpvar-mode" {
        dumpVar(buildCtx, config, os.Args[2:])
    } else if os.Args[1] == "--dumpvars-mode" {
        dumpVars(buildCtx, config, os.Args[2:])
    } else {
        ...
    }
...
}
[build/soong/cmd/soong_ui/main.go]
func dumpVars(ctx build.Context, config build.Config, args []string) {
       varData, err := build.DumpMakeVars(ctx, config, nil, allVars)
}

        最后调用到了ckati执行-f build/make/core/config.mk

[/build/soong/ui/build/dumpvars.go]
func dumpMakeVars(ctx Context, config Config, goals, vars []string, write_soong_vars bool) (map[string]string, error) {
    ctx.BeginTrace(metrics.RunKati, "dumpvars")
    defer ctx.EndTrace()
 
    cmd := Command(ctx, config, "dumpvars",
        config.PrebuiltBuildTool("ckati"),
        "-f", "build/make/core/config.mk",
        "--color_warnings",
        "--kati_stats",
        "dump-many-vars",
        "MAKECMDGOALS="+strings.Join(goals, " "))
    cmd.Environment.Set("CALLED_FROM_SETUP", "true")
    if write_soong_vars {
        cmd.Environment.Set("WRITE_SOONG_VARIABLES", "true")
    }
    cmd.Environment.Set("DUMP_MANY_VARS", strings.Join(vars, " "))
    cmd.Sandbox = dumpvarsSandbox
    output := bytes.Buffer{}
    cmd.Stdout = &output
    pipe, err := cmd.StderrPipe()
    if err != nil {
        ctx.Fatalln("Error getting output pipe for ckati:", err)
    }
    cmd.StartOrFatal()
    // TODO: error out when Stderr contains any content
    status.KatiReader(ctx.Status.StartTool(), pipe)
    cmd.WaitOrFatal()
 
    ret := make(map[string]string, len(vars))
    ...
 
    return ret, nil
}

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐