乐趣区

关于linux:Bash技巧一个大幅提升Android平台开发效率的Shell脚本

之前文章介绍了一个 quickcd.sh 脚本,能够指定任意的顶层目录,在顶层目录底下疾速 cd 到特定的目录。

这个 quickcd.sh 脚本是通用的,实用于各种目录构造。

如果从事 Android 开发工作,常常须要在 Android 源码目录之间切换。

同时,能够对脚本进行一些批改,反对一些跟 Android 相干的性能。

例如,指定一个选项就能够主动 source、lunch、全编译 Android 源码。

增加一些标记位指定进入某个目录时,就主动编译这个目录下的代码。等等。

本篇文章介绍一个 androidcd.sh 脚本,在 quickcd.sh 脚本的根底上增加跟 Android 相干的代码和选项。

实际上,androidcd.sh 脚本反对 quickcd.sh 的所有性能,也能够用于任意顶层目录。

只是脚本代码外面多加了一些 Android 相干的代码和选项。

如果不须要用到这些选项,应用之前文章介绍的 quickcd.sh 脚本即可,这个代码比拟独立。

上面提供具体的脚本代码、参考的配置文件内容、以及一个测试例子。

脚本代码

列出 androidcd.sh 脚本的具体代码如下所示。

在这个代码中,对大部分要害代码都提供了具体的正文,不便浏览。

这篇文章的前面也会提供一个简略的测试例子,可供参考。

#!/bin/bash
# 该脚本用于在所指定顶层目录底下的各个目录之间间接来回疾速 cd.
# 把各个目录门路和一些简略的字符对应起来, 通过解析事后配置的文本文件, 获取
# 门路简写和对应要 cd 到的目录门路. 根本配置格局为: 门路简写 | 目录门路
# 例如配置 "b|frameworks/base", 则 b 是门路简写, frameworks/base 是对应的
# 门路. 在顶层目录底下的任意一个目录外面, 都能够执行 source androidcd.sh b
# 命令来间接 cd 到 framework/base 目录下, 不须要先退回到顶层目录再执行 cd.
# 为了让脚本执行完结后, 还放弃在 cd 后的目录, 须要用 source 命令来执行
# 以后脚本. 能够在 ~/.bashrc 文件中增加如下语句来设置命令别名:
#   alias c='source androidcd.sh'
# 后续执行 c 命令, 就相当于执行 source androidcd.sh 命令.
# 这里假如 androidcd.sh 脚本放在 PATH 指定的寻址目录下. 例如 /usr/bin 目录.
# 如果 androidcd.sh 脚本没有放在默认的寻址目录下, 请指定残缺的绝对路径.

# 上面变量指定默认解析的配置文件名. 该文件配置了门路简写、以及对应的门路.
# 这个 dirinfo.txt 文件须要事后配置好, 放到 HOME 目录的 .liconfig 目录下.
DEFAULT_DIRINFO="${HOME}/.liconfig/dirinfo.txt"

# PARSECFG_filepath 是 parsecfg.sh 脚本外面的变量. 如果这个变量为空,
# 阐明还没有关上过配置文件, 进入上面的分支关上默认的配置文件. 因为以后的
# androidcd.sh 脚本和 parsecfg.sh 脚本都是通过 source 命令来调用. 只有
# source 过一次, 导出到调用者 shell 的全局变量和函数会始终无效. 所以只有
# PARSECFG_filepath 变量为空才 source parsecfg.sh, 防止屡次关上配置文件.
if [-z "$PARSECFG_filepath"]; then
    # 导入解析配置文件的脚本, 以便调用该脚本的函数来解析配置文件.
    source parsecfg.sh
    # 调用 parsecfg.sh 外面的 open_config_file() 函数解析配置文件.
    open_config_file "$DEFAULT_DIRINFO"
    # 当 parsecfg.sh 脚本解析配置文件失败时, 则退出, 不再往下执行.
    if [$? -ne 0]; then
        return 1
    fi
fi

# 因为不同源代码的目录构造可能不同, 当在不同的源代码目录中应用
# 以后脚本来切换时, 须要指定不同的配置文件. 上面函数就用于关上
# 用户指定的配置文件名. 所给的第一个参数指定配置文件名.
# 有一个非凡的文件名是 "default", 示意要关上脚本默认的配置文件.
open_user_config_file()
{if [ $# -ne 1]; then
        echo "Usage: $FUNCNAME filepath"
        return 1
    fi

    local filepath
    if ["$1" == "default"]; then
        filepath="$DEFAULT_DIRINFO"
    else
        filepath="$1"
    fi

    # 调用 parsecfg.sh 的 open_config_file 函数关上配置文件
    open_config_file "$filepath"
    # 当 return 前面不带参数时, 默认返回上一个命令的状态码.
    return
}

# 上面的 DIRECTCD_TOP_DIR 变量用于保留设置的顶层目录门路.
# 当设置顶层目录为 code/ 时, 后续理论 cd 的所有目录门路后面都会加上 code/.
# 这个设置是为了不便在指定的某个顶层目录 (例如源码根目录) 底下进行疾速 cd.
# 例如, 在一个大型项目代码中, 这些代码都放在同一个顶层目录下, 咱们只须要配置
# 顶层目录下的子目录门路即可. 理论切换目录时, 会主动加上顶层目录, 再进行 cd.
# NOTE: 不要在脚本结尾为这个变量赋初值. 每次 cd 时, 都会执行这个脚本. 但不是
#   每次 cd 都要设置顶层目录门路. 在屡次调用该脚本时, 要放弃该变量的值不变.
# DIRECTCD_TOP_DIR=""# 在门路简写后面加上字符'+' 时, 示意进入该门路简写对应的目录下进行编译.
COMPILE_PREFIX="+"
# 指定编译 Android 时默认要 lunch 的分支名. 目前设置成最罕用的 project 名称.
# 后续如有调整, 须要把 DEFAULT_LAUNCH_COMBO 批改成对应的 project 名称.
DEFAULT_LAUNCH_COMBO="K80129AA1-userdebug"

quickcd_show_help()
{
printf "USAGE
    source androidcd.sh [option] [symbol]
OPTIONS
    option: 可选的选项参数, 形容如下:
        -h: 打印以后帮忙信息.
        -f: 指定要解析的配置文件名. 前面跟着一个参数, 指定具体的文件门路.
            如果所给文件名是 'default', 示意要关上脚本默认的配置文件.
        -p: 打印以后设置的顶层目录和所解析的配置文件名.
        -s: 设置并 cd 到所给的顶层目录. 前面跟着一个参数, 指定具体的顶层目录.
        -r: 清空以后设置的顶层目录.
        -l: 查看脚本反对的门路简写及其对应的门路.
        -v: 以键值对的形式打印具体的配置文件信息.
        -i: 在配置文件中查找指定内容. 须要一个参数来指定要查找的内容.
        -e: 应用 vim 关上脚本的配置文件, 以供编辑.
        -a: 减少或批改一个门路简写和对应的门路到配置文件. 前面跟着一个参数,
            用单引号括起来, 以指定门路简写和门路. 格局为: 门路简写 | 门路
            例如: -a 'b|frameworks/base'. 如果 b 简写还不存在, 会新增
            这个配置项. 如果曾经存在, 会批改 b 简写对应的门路为新的门路.
        -d: 从脚本配置文件中删除一个门路简写和对应的门路. 前面跟着一个
            参数, 指定门路简写. 脚本将从配置文件中删除该门路简写对应的行.
            例如 -d b, 将删除门路简写为 b 的行.
        -g: 在 Android 源码下查找指定的文件. 须要提供参数来指定文件名.
        -n: 进行 source 和 lunch 的操作, 然而不编译. 须要提供参数指定 project 名称.
            无效 project 参数是 lunch 命令反对的参数.
            有一个非凡参数是 'dl', 示意编译脚本默认预置的 project.
        -m: 在 Android 源码根目录下进行全编译. 须要提供参数来指定编译的 project.
            无效 project 参数是 lunch 命令反对的参数.
            有一个非凡参数是 'dl', 示意编译脚本默认预置的 project.
    symbol: 可选参数, 指定要 cd 到的门路简写. 反对的简写能够用 - l 或 - v 选项来查看.
            在门路简写后面加上字符 '+', 示意进入该门路简写对应的目录下进行编译.

    当不提供任何参数且曾经设置过顶层目录时, 该脚本会 cd 到顶层目录下.
NOTE
    能够应用 alias c='source androidcd.sh' 设置 c 别名来不便执行.
"
}

# 打印以后设置的顶层目录到规范输入.
show_top_dir()
{echo "以后设置的顶层目录门路是: ${DIRECTCD_TOP_DIR}"
    echo "以后解析的配置文件是: ${PARSECFG_filepath}"
}

# 该函数设置顶层目录门路. 所给的第一个参数指定顶层目录门路.
# 这个顶层目录门路能够是相对路径, 或者绝对路径.
setup_top_dir()
{if [ $# -ne 1]; then
        echo "Usage: $FUNCNAME top_dir"
        return 1
    fi

    # 进入到所给的顶层目录门路底下, 并查看 cd 命令是否执行胜利.
    \cd "$1"
    if [$? -eq 0]; then
        # 所给的顶层目录能够是相对路径. 然而代码要获取该顶层目录的
        # 绝对路径, 以便后续通过绝对路径寻址, 不受工作目录的影响.
        DIRECTCD_TOP_DIR="$(pwd)"
    else
        echo "出错: 无奈进入所给的顶层目录. 请查看所给门路是否正确."
        return 2
    fi
}

# 重置 DIRECTCD_TOP_DIR 变量值为空. 勾销设置顶层目录门路.
# 因为这个脚本预期通过 source 命令调用. 只有设置过顶层目录, 在
# 以后 shell 中,DIRECTCD_TOP_DIR 变量就始终有值. 在调试脚本代码时,
# 如果想要再次测试没有设置顶层目录的状况, 只能从新关上终端, 比拟麻烦.
# 提供 -r 选项调用上面 reset_top_dir() 函数来重置所设置的顶层目录.
# 会一起设置 PARSECFG_filepath 变量值为空, 以便从新解析配置文件.
reset_top_dir()
{DIRECTCD_TOP_DIR=""PARSECFG_filepath=""}

# 如果以后门路不位于顶层目录底下, 打印一些提示信息, 以便用户关注到这一点.
# 例如, 顶层目录是 code/dev/. 而以后所在的 shell 工作目录是 code/test/,
# 可能预期执行该脚本时会 cd 到 code/test/ 目录下的子目录, 但理论会 cd
# 到 code/dev/ 目录下的子目录, 这可能会批改到不预取目录的代码文件.
# 为了防止这个问题, 这个函数打印一些提示信息, 作为揭示.
check_top_dir()
{
    # 查看 man bash 的 "Compound Commands" 大节阐明, =~ 判断右边字符串是否蕴含
    # 左边字符串. 如果右边字符串蕴含左边的字符串, 其返回状态码是 0, 否则返回 1.
    if [[! $(pwd) =~ "${DIRECTCD_TOP_DIR}" ]]; then
        # 如果以后的工作目录不蕴含所给的顶层目录, 阐明没有位于顶层目录底下.
        echo -e 以后门路 '\e[31m' $(pwd) '\e[0m' 位于设置的顶层目录之外.
        echo -e 将会跳转到顶层目录 '\e[32m' ${DIRECTCD_TOP_DIR} '\e[0m' 底下的目录!
    fi
}

# 进入 Android 源码根目录进行 source、lunch 的操作. 所给第一个参数指定要编译
# 的 project 名称. 无效的 project 参数是 lunch 命令反对的参数. 有一个非凡参数
# 是 "dl", 示意要编译脚本预置的 project, 由 DEFAULT_LAUNCH_COMBO 变量指定.
source_and_lunch()
{
    # 如果 DIRECTCD_TOP_DIR 变量为空, 则还没有设置顶层目录, 报错返回
    if [-z "${DIRECTCD_TOP_DIR}" ]; then
        echo "出错: 还没有设置顶层目录, 请应用 -h 选项查看脚本帮忙阐明."
        return 2
    fi

    if [$# -ne 1]; then
        echo "Usage: $FUNCNAME launch_combo"
        return 1
    fi

    local lunch_combo
    if ["$1" == "dl"]; then
        # "dl" 非凡参数示意要编译默认的 project
        lunch_combo="${DEFAULT_LAUNCH_COMBO}"
    else
        lunch_combo="$1"
    fi

    \cd "${DIRECTCD_TOP_DIR}"
    source build/envsetup.sh
    # 在 Android 的 "build/envsetup.sh" 脚本中, 有一个 print_lunch_menu()函数能够
    # 打印所有 lunch 分支, 格局相似于 "1. aosp_arm-eng". 其中,1 是 lunch 分支编号,
    # "aosp_arm-eng" 是 lunch 分支名. lunch 命令能够接管 lunch 分支名或者 lunch 分
    # 支编号来指定要 lunch 的分支. 上面用 grep 查找特定的分支, 并用 awk 提取出分支
    # 名, 将分支名作为参数传给 lunch 命令, 从而主动 lunch 须要的分支.
    lunch $(print_lunch_menu | grep "$lunch_combo" | awk '{print $2}')
    return
}

# 进入 Android 源码根目录全编译代码. 所给第一个参数指定要编译的 project.
# 为了简化应用, compile_android 会本人调用 source_and_lunch 函数, 而不是
# 要求用户先手动指定 -s 选项来调用 source_and_lunch 函数能力编译. 能够
# 批改成还没有 source、lunch 过, compile_android 再本人 lunch. 然而目前
# Android 没有提供查问是否曾经 lunch 过的命令. 尽管查看 envsetup.sh 的源码
# 能够找到判断办法, 但随着版本改变可能会生效, 影响以后脚本的独立性, 暂定不做.
compile_android()
{if [ $# -ne 1]; then
        echo "Usage $FUNCNAME android_lunch_combo"
        return 1
    fi

    source_and_lunch "${1}" && \
        make -j16 2>&1 | tee build_android.log
    if [$? -ne 0]; then
        echo -e '\e[31m 编译 Android 出错!\e[0m'
        return 1
    fi
}

# 保留 Android 源码各个目录和文件的名字到一个文本文件外面, 而后能够在该
# 文件中查找指定的文件名, 如果只找到一个就间接 cd 到该文件所在的目录. 如果
# 找到多个匹配项, 就弹出列表给用户抉择, 抉择之后再 cd 过来.
# 这个函数复制自 Android 源码的 build/make/envsetup.sh 文件, 进行了一些批改.
godir() {
    # 如果 DIRECTCD_TOP_DIR 变量为空, 则还没有设置顶层目录, 报错返回
    if [-z "${DIRECTCD_TOP_DIR}" ]; then
        echo "还没有设置顶层目录, 请应用 - h 选项查看脚本帮忙阐明."
        return 1
    fi
    if [[-z "$1"]]; then
        echo "Usage: godir <regex>"
        return 1
    fi
    local T="${DIRECTCD_TOP_DIR}/"
    # envsetup.sh 是把文件信息写入 filelists 文件, 批改写入的文件名
    # 为 gtags.files, 这是 gtags 要解析的文件名, 这两者须要的文件内容
    # 是一样的, 只生成一份文件即可.
    local FILELIST="gtags.files"
    if [[! -f $T/${FILELIST} ]]; then
        echo -n "Creating index..."
        \cd $T
        # 上面的 find 指定只在 bionic、build、frameworks 等目录下查找,
        # 且通过 -path 和 -prune 选项疏忽这些目录下带有 test、git 等名称的
        # 子目录, 最初通过正则表达式查找指定后缀名的文件. 应用 $ 来要求匹
        # 配开端. 上面的 -print 要写在最初面, 把最终查找的文件名打印出
        # 来, 如果写在 -prune 的前面, 它是打印 -prune 的后果, 不是打印 -regex
        # 匹配的文件后果. -regex 和 -type 之间不必加 -o, 加上反而有问题.
        find ./bionic ./build ./device ./external \
            ./frameworks ./hardware ./kernel \
            ./packages ./system ./vendor \
            \( -path "*test*" -o -path "*tools" -o -path "*docs" \
            -o -path "*git*" -o -path "*svn" \) -prune \
            -o -regex '.+\.\(c\|h\|cpp\|cc\|hpp\|java\|rc\|xml\)$' \
            -type f -print > $FILELIST
            # grep -E "\.\w+$" | grep -v -E "\.html$|\.txt$|\.so$"
        echo "Done"
    fi
    local lines
    lines=($(\grep "$1" $T/${FILELIST}|sed -e 's/\/[^/]*$//'|sort|uniq))
    if [[${#lines[@]} = 0 ]]; then
        echo "Not found"
        return
    fi
    local pathname
    local choice
    if [[${#lines[@]} > 1 ]]; then
        while [[-z "$pathname"]]; do
            local index=1
            local line
            for line in ${lines[@]}; do
                printf "%6s %s\n" "[$index]" $line
                index=$(($index + 1))
            done
            echo
            echo -n "Select one:"
            unset choice
            read choice
            if [[$choice -gt ${#lines[@]} || $choice -lt 1 ]]; then
                echo "Invalid choice"
                continue
            fi
            pathname=${lines[$(($choice-1))]}
        done
    else
        pathname=${lines[0]}
    fi
    echo -e "\033[32mFind it. Let's Go!\033[0m"
    \cd $T/$pathname
}

# 解决所给的门路简写, 看配置文件中是否保留这个门路简写.
# 如果蕴含, 就 cd 到该简写对应的目录底下.
# 所给的第一个参数指定门路简写.
handle_symbol()
{if [ $# -ne 1]; then
        echo "Usage: $FUNCNAME symbol"
        return 1
    fi
    local key="$1"

    local prefix mm_cmd
    # 获取门路简写的首字母. 如果首字母是 '+', 则进到该简写对应的目录下进行编译
    # 留神: 要先 source 之后, 能力执行 mm 命令. 为了防止屡次 source, 不会在每次 mm 之
    # 前都执行一次 source, 所以要求先 source, 再执行这个编译命令, 否则编译报错.
    prefix="${key:0:1}"
    if ["${prefix}" == "${COMPILE_PREFIX}" ]; then
        mm_cmd="mm"
        # 此时, 须要去掉 '+' 这个首字母, 该字母不属于门路简写的一部分.
        key=${key:1}
    fi

    # 调用 parsecfg.sh 的 get_value_by_key 函数获取所给的
    # 门路简写在配置文件中对应的目录门路.
    local dir_value=$(get_value_by_key "${key}")
    if test -n "${dir_value}"; then
        # 如果获取到门路简写对应的目录门路, 则在该目录门路后面
        # 主动加上顶层目录门路, 组成残缺的绝对路径, 而后进行 cd.
        \cd "${DIRECTCD_TOP_DIR}/${dir_value}"
        # 如果在门路简写后面有加号 '+', 则在对应目录下进行编译.
        if [-n "${mm_cmd}" ]; then
            echo -e "\e[32mEnter $(pwd), execute mm.\e[0m"
            ${mm_cmd}
        fi
        return 0
    fi

    echo "出错: 找不到门路简写'${key}'对应的行"
    return 2
}

# 通过验证发现, 用 source 命令来执行该脚本后,OPTIND 的值不会被重置为 1, 导致
# 再次用 source 命令执行脚本时,getopts 解析不到参数, 所以手动重置 OPTIND 为 1.
OPTIND=1
while getopts "hf:ps:rlvi:ea:d:g:n:m:" opt; do
    # 调用 parsecfg.sh 脚本解决选项的函数来解决 "lvi:ea:d:" 这几个选项.
    # 如果解决胜利, 就间接持续读取下一个选项, 不再往下解决.
    # handle_config_option()函数要求传入的选项以 '-' 结尾, 而 getopts 命令
    # 返回的选项不带有 '-', 所以上面在 ${opt} 后面加上一个 '-'.
    handle_config_option "-${opt}" "${OPTARG}"
    if [$? -ne 127]; then
        continue
    fi

    case "$opt" in
        h) quickcd_show_help ;;
        f) open_user_config_file "$OPTARG" || return ;;
        p) show_top_dir ;;
        s) setup_top_dir "$OPTARG" || return ;;
        r) reset_top_dir ;;
        g) godir "$OPTARG" ;;
        n) source_and_lunch "$OPTARG" ;;
        m) compile_android "$OPTARG" ;;
        ?) echo "出错: 异样选项, 请应用 -h 选项查看脚本的帮忙阐明." ;;
    esac
done

# $# 大于 0, 阐明提供了命令参数. $# 等于 OPTIND 减去 1, 阐明传入的参数都
# 是命令选项. 此时, 间接完结执行, 不须要执行前面解析 symbol 参数的语句.
# 上面的 -a 示意两个表达式都为真时才为真. 表达式之间不要加小括号.
# Shell 外面的小括号有非凡含意, 跟 C 语言的小括号有些区别, 加上会有问题.
if [$# -gt 0 -a $# -eq $((OPTIND-1)) ]; then
    return 0
fi

# 上面判断 DIRECTCD_TOP_DIR 变量值是否为空.
# 如果为空, 阐明还没有设置顶层目录. 此时不再往下解决, 间接报错返回.
if [-z "${DIRECTCD_TOP_DIR}" ]; then
    echo -e "\e[31m 还没有设置顶层目录, 请应用 - h 选项查看脚本帮忙阐明.\e[0m"
    return 2
fi

# 查看以后门路是否位于顶层目录下. 如果不是, 打印一些提示信息.
check_top_dir

if [$# -eq 0]; then
    # 执行该脚本不带参数时, 默认 cd 到顶层目录下.
    \cd "${DIRECTCD_TOP_DIR}"
    # 因为不带参数, 不须要往下解决, 在 cd 之后间接返回.
    return 0
fi

# 挪动脚本的参数, 去掉后面输出的选项, 只剩下示意门路简写的参数.
shift $((OPTIND-1))
# 循环遍历所有残余的参数, 能够解决传入多个参数的状况.
# 例如执行 source androidcd.sh -s topdir a 命令, 能够先设置顶层目录,
# 而后 cd 到 a 简写对应的目录下. 这种状况要留神提供的参数程序.
# 如果写为 source androidcd.sh a -s topdir 命令, 会在解析 a 简写时
# 发现还没有设置顶层目录而报错.
for arg in "$@"; do
    handle_symbol "$arg"
done

return

参考的配置文件内容

这个脚本默认会读取 HOME 目录下的 .liconfig/dirinfo.txt 文件。

这个文件外面配置了各个门路简写和对应要调整的目录门路。

参考的配置文件内容如下:

b|frameworks/base
fm|frameworks/base/media/java/android/media
fr|frameworks/base/core/res/res
fs|frameworks/base/services
sui|frameworks/base/packages/SystemUI/src/com/android/systemui
ps|packages/apps/Settings/

基于这个配置信息,无论以后位于哪个目录下,应用 fs 这个简写作为参数,androidcd.sh 脚本都会执行 cd 命令间接进入 frameworks/base/services 目录下。

测试例子

把以后的 androidcd.sh 脚本、所调用的 parsecfg.sh 脚本(具体代码能够查看之前文章)放到可寻址的 PATH 目录下。

在 bash 中设置 alias c='source androidcd.sh' 别名。

dirinfo.txt 配置文件放到 HOME 目录的 .liconfig 目录下(如果没有该目录,则手动创立)。

之后,就能够应用 c 命令来执行 androidcd.sh 脚本。

一个简略的测试例子如下所示:

$ c -s android/
[android]$ c fm
[android/frameworks/base/media/java/android/media]$ c fs
[android/frameworks/base/services]$ c sui
[android/frameworks/base/packages/SystemUI/src/com/android/systemui]$ c ps
[android/packages/apps/Settings/]$ c -m dl
...... # 省略打印的编译信息
[android]$ c +ps
Enter /home/android/packages/apps/Settings/, execute mm.

执行 c -s android/ 设置要跳转的 Android 源码根目录门路。

执行 c fm 命令跳转到 fm 门路简写对应的目录。

执行 c fs 命令跳转到 fs 门路简写对应的目录。

执行 c sui 命令跳转到 sui 门路简写对应的目录。

执行 c ps 命令跳转到 ps 门路简写对应的目录。

能够看到,应用 androidcd.sh 脚本能够间接在跨度十分大的目录之间跳转,十分不便。

只有执行过 c -s 命令指定了 Android 源码根目录门路,无论以后位于哪个目录下,执行 c -m dl 命令会主动跳转到 Android 源码根目录进行全编译。

执行 c +ps 命令,在 ps 门路简写后面加上字符‘+’。

那么会切换到 ps 对应的目录下,而后主动执行 Android 的 mm 命令编译该目录下的代码。

后面进行全编译时,曾经进行过 Android 的 source、lunch 操作。

这里能够间接应用 mm 命令进行编译。

在 Android 下进行编译,须要先进行 source、lunch 的操作。

目前 Android 没有提供能够判断是否 lunch 过的命令。

为了防止屡次 source、lunch,应用字符‘+’来指定编译时,不会主动 source、lunch。

即,要先 source、lunch,再应用字符‘+’来指定编译。

能够应用 c -n lunch_combo 命令来进行 source、lunch 操作。

下面 c -m 所给的 dl 参数示意编译默认的 project。

这个 project 由 androidcd.sh 脚本的 DEFAULT_LAUNCH_COMBO 变量指定。

默认配置为最常应用的 project 名称。

能够依据理论须要批改为对应的 project 名称。

如果想要编译其余的 project,在 -m 选项前面提供对应的 lunch 分支即可。

要查看 -m 选项、以及更多选项的用法,能够应用 c -h 命令打印具体的帮忙信息。

退出移动版