Android编译系统详解(一)——build/envsetup.sh

本文介绍编译Android ROM的常用命令,如编译、调试、代码提交等,以及sourcebuild/envsetup.sh的执行流程。

http://www.cloudchou.com/android/post-134.html


准备好编译环境后,编译Rom的第一步是 source build/envsetup.sh,该步骤把envsetup.sh里的函数声明为当前会话终端可用的命令。这些命令能让我们切换目录,提交代码,编译Rom更方便。如果记不住所有命令,只要你记住hmm就可以了,也可通过hmm命令看到支持的命令列表。

1. 命令分类:

1.1 编译用的命令

命令名称 使用方式 说明
breakfast 
别名bib 
breakfast [product] 
示例: 
breakfast i9100 
breakfast cm_i9100-userdebug 
选择产品
product格式: device 或者 device-build_variant 
先从网上下载cm支持的产品列表 
product是用户要编译的目标产品,例如find5或者i9100 
如果选择device-build_variant,并且是cm支持的device,一般会以cm_开头,比如cm_i9100 
如果未选择编译产品,那么会弹出许多product,让用户选择 
这里的product列表仅包含从网上下载的产品,不包含只有本地支持的产品 
lunch  lunch [product] 
示例: 
lunch cm_i9100-userdebug 
选择产品
product格式: build-build_variant 
不再从网上下载产品列表, 
如果[product]为空,意味着未选择编译产品,也会弹出许多product,让用户选择,
这里的product列表是用户在执行source build/envsetup.sh时,including了一些shell脚本,从而添加至产品列表的 
brunch  brunch [product]  选择产品并编译
product格式: device 或者 device-build_variant 
调用breakfast选择编译产品 
然后调用mka bacon编译 
m  m [targetlist]  编译选中目标
示例:m otatools bacon 
并没有调用schedtool 充分利用所有核编译 
mm  mm [mka] [targetlist] 
示例: 
mm mka 
编译选中目标或者当前目录所在项目
若有mka,会调用mka进行编译 
如果当前目录在顶层目录,会编译指定的所有目标 
如果不在顶层目录,会编译当前目录所在的工程 
mmm  mmm [directory:[modulist]] -arglist  编译指定目录下的模块
directory可以为以下特殊目标: 
snod dist mka showcommands 
若指定了mka,将利用mka进行编译 
示例: 
mmm bootable/recovery: recovery 
或者 
mmm bootable/recovery 
mka  mka [targetlist]  编译指定目标列表
将利用SCHED_BATCH编译指定所有目标,这样能充分利用所有CPU 
eat  eat  刷机
在/cahce/recovery/command文件写上如下命令–sideload,重启设备至recovery,等待设备进入sideload状态,调用adb sideload进行刷机 
omnom  omnmon [product]  编译ROM并刷ROM至设备
tapas  tapas [<App1> <App2> ...] [arm|x86|mips] [eng|userdebug|user]  Configures the build to build unbundled apps 
cmka  cmka [targetlist]  Cleans and builds using mka 
installboot installboot  安装boot
利用$OUT/recovery/root/etc/recovery.fstab找到boot所在分区以及分区类型,找到分区后,先将boot.img上传至/cache下,需要将内核需要加载的模块$OUT/system/lib/modules/*上传至/system/lib/modules/,然后如果是mtd分区就利用flash_image刷至相应的分区,否则利用dd刷至相应的分区 
installrecovery installrecovery  安装recovery
与安装boot类似 

1.2 查看代码时的辅助命令

命令名称 使用方式 说明
cgrep  cgrep keyword  在C,C++代码中搜索指定关键字 
调用find查找C/C++代码文件(包括头文件),并且排除了不用的文件夹,在找到的文件中用grep搜索关键字 
jgrep  jgrep keyword  在java代码中搜索指定关键字 
调用find查找java代码文件,并且排除了不用的文件夹,在找到的文件中用grep搜索关键字 
resgrep  resgrep keyword  在资源xml文件中搜索指定关键字 
调用find在当前文件夹查找下res子目录里找xml文件,并且排除了不用的文件夹,在找到的文件中用grep搜索关键字 
croot  croot  切换至Android根目录 
cout  cout  切换至prodcut的out目录 
cproj  cproj  从某个工程的非常深的子目录,可迅速切换至工程的根目录 
get_build_var  get_build_var build_var 获取某个编译变量的值, 
一般是路径 
get_abs_build_var get_abs_build_var  获取某个编译变量的值, 
是绝对路径 
findmakefile    打印当前目录所在工程的Android.mk的文件路径 
printconfig    打印各种编译变量的值 
print_lunch_menu    打印lunch可选择的各种product 
godir    切换至用户输入的文件所在的目录 
repodiff    调用git进行diff,查看当前修改的东西 

1.3 辅助函数

命令名称 使用方式 说明
add_lunch_combo   增加调用lunch命令时的选择项 
示例: 
add_lunch_combo full_galaxys2att-eng
check_product    检查产品看CM是否能支持编译 
check_variant    检查TARGET_BUILD_VARIANT,看其值是否有效,可能的值只能为user,userdebug,eng 
choosecombo    调用choosetype,chooseproduct,choosevariant等函数,确定TARGET_PRODUCT,TARGET_BUILD_TYPE,TARGET_BUILD_VARIANT 
chooseproduct    让用户输入一个product的名字,默认为full,最终确定TARGET_PRODUCT, 
choosetype    选择编译类型即TARGET_BUILD_TYPE,可能的值为debug,release 
choosevariant    让用户选择编译变量TARGET_BUILD_VARIANT,可能的值为user,userdebug,eng 
dopush    alias mmp=’dopush mm’ 
alias mmmp=’dopush mmm’ 
alias mkap=’dopush mka’ 
alias cmkap=’dopush cmka’ 
fixup_common_out_dir    建立$(OUT_DIR)/target/common目录 
getprebuilt    得到prebuilt的路径 
getsdcardpath    获取Sd卡路径 
gettargetarch    获取TARGET_ARCH的值 
gettop    获取Android源码根目录 
set_java_home    设置java的主目录 
setpaths    将编译要用到的一些路径添加到环境变量PATH里 
set_sequence_number    export BUILD_ENV_SEQUENCE_NUMBER=10
set_stuff_for_environment   设置PROMPT_COMMAND变量,java_home,PATH目录,set_sequence_number 
settitle    如果STAY_OFF_MY_LAWN为空,设置PROMPT_COMMAND变量,会改变SecureCrt终端窗口显示的名字 

1.4 调试相关

命令名称 使用方式 说明
gdbclient
gdbclient exename (progname|pid)  gdb调试 
pid
pid exename  查看某个可执行程序对应的进程id 
getbugreports    将bug报告从设备上拉到本地,bug报告存放于目录/sdcard/bugreports, 
getlastscreenshot    获取最后一张截图 
getscreenshotpath   获取屏幕截图的路径 
isviewserverstarted   判断viewserver是否已启动 
adb shell service call window 3 
key_back    模拟按返回键 
key_home    模拟按Home键 
key_menu    模拟按菜单键 
runtest    调用development/testrunner/runtest.py,进行测试 
smoketest    利用SmokeTestApp.apk,SmokeTest.apk对系统进行一个smoke test 
startviewserver    adb shell service call window 1 i32 $port 
stopviewserver    adb shell service call window 2 
systemstack    dump the current stack trace of all threads in the system process to the usual ANR traces file 
tracedmdump    调用q2dm将系统堆栈导出来,并利用dmtracedump将其转为可读的html文件 

1.5 提交代码相关命令

命令名称 使用方式 说明
aospremote    Add git remote for matching AOSP repository 
cmgerrit    从CM拉源代码,或者将源代码提交到gerrit给比人审核,直接敲这个命令可得到该命令的使用帮助,最终调用Git完成命令功能 
cmrebase    和git的rebase 衍合类似,我们不做代码提交,故此没必要 
cmremote    Add git remote for CM Gerrit Review 
makerecipe    将本地代码推送至git仓库 
repopick    Utility to fetch changes from Gerrit,可选项有–ignore-missing,–start-branch,–abandon-first,–auto-branch 
reposync    Parallel repo sync using ionice and SCHED_BATCH 

2. source build/envsetup.sh 执行流程

envsetup.sh 定义了很多函数,除此之外还执行了其它操作,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
VARIANT_CHOICES=(user userdebug eng)# TARGET_BUILD_VARIANT变量的可能值
#LUNCH_MENU_CHOICES是供用户选择的prodcut列表,
#每次source build/envsetup.sh时需重置变量LUNCH_MENU_CHOICES
#不然后续的include vendor/cm/vendorsetup.sh时会继续添加产品至变量LUNCH_MENU_CHOICES里,
#导致出现很多重复产品
unset LUNCH_MENU_CHOICES 
add_lunch_combo full-eng #默认添加full-eng,full_mips-eng等4个产品
add_lunch_combo full_x86-eng
add_lunch_combo vbox_x86-eng
add_lunch_combo full_mips-eng
alias bib=breakfast#给breakfast起别名
complete -F _lunch lunch #给lunch添加tab提示
case `uname -s` in #定义sgrep函数 在所有工程类型代码里搜索
    Darwin)
        function sgrep()
        {
            find -E . -name .repo -prune -o -name .git -prune -o  -type f \
                 -iregex '.*\.(c|h|cpp|S|java|xml|sh|mk)' -print0 \
                 | xargs -0 grep --color -n "$@"
        }
        ;;
    *)
        function sgrep()
        {
            find . -name .repo -prune -o -name .git -prune -o  -type f \
                 -iregex '.*\.\(c\|h\|cpp\|S\|java\|xml\|sh\|mk\)' -print0 \ 
                 | xargs -0 grep --color -n "$@"
        }
        ;;
esac
export -f cmremote
export -f aospremote
alias mmp='dopush mm' #定义更多编译后push到设备的函数的操作
alias mmmp='dopush mmm'
alias mkap='dopush mka'
alias cmkap='dopush cmka'
if [ "x$SHELL" != "x/bin/bash" ]; then #只支持Bash终端
    case `ps -o command -p $$` in
        *bash*)
            ;;
        *)
            echo "WARNING: Only bash is supported,"  \
                 "use of other shell would lead to erroneous results"
            ;;
    esac
fi
#Execute the contents of any vendorsetup.sh files we can find.
#source vendor和device下能找到的所有vendorsetup.sh
for f in `/bin/ls vendor/*/vendorsetup.sh vendor/*/*/vendorsetup.sh device/*/*/vendorsetup.sh 2> /dev/null`
do
    echo "including $f"
    . $f
done
unset f
#source目录 sdk/bash_completion vendor/cm/bash_completion下的bash脚本,
#能提供tab提示
addcompletions 
export ANDROID_BUILD_TOP=$(gettop)

2.1 执行的vendorsetup.sh有:

在envsetup.sh里将执行vendor和device目录及各自子目录下所有的vendorsetup.sh,这些vendorsetup.sh做的事情是调用add_lunch_combo将它们各自的产品添加到 LUNCH_MENU_CHOICES 变量里

#执行cm的vendorsetup.sh将从网上下载cm支持的产品列表,并添加至LUNCH_MENU_CHOICES

vendor/cm/vendorsetup.sh

#将添加mini_armv7a_neon产品 add_lunch_combo mini_armv7a_neon-userdebug

device/generic/armv7-a-neon/vendorsetup.sh

#add_lunch_combo mini_armv7a-userdebug

device/generic/armv7-a/vendorsetup.sh

#add_lunch_combo mini_mips-userdebug

device/generic/mips/vendorsetup.sh

#add_lunch_combo mini_x86-userdebug

device/generic/x86/vendorsetup.sh

#add_lunch_combo cm_jflteatt-eng

device/samsung/jflteatt/vendorsetup.sh

# add_lunch_combo full_panda-userdebug

device/ti/panda/vendorsetup.sh

# add_lunch_combo zte_blade-eng

#add_lunch_combo zte_blade-userdebug

device/zte/blade/vendorsetup.sh

2.2 执行的completion bash有:

在envsetup.sh里将执行sdk/bash_completion和vendor/cm/bash_completion目录下的bash脚本,这些bash脚本主要是为命令提供tab支持,有了这些tab支持,输入命令后如果某个选项忘记了,只需要敲tab键,就能获得提示,使用命令更加方便

including sdk/bash_completion/adb.bash

including vendor/cm/bash_completion/git.bash

including vendor/cm/bash_completion/repo.bash

分别对应adb,git,repo的tab提示


<think>我们正在处理Android构建环境设置的问题。用户提供的命令序列是: source build/envsetup.sh export OUT_DIR=out_system lunch ussi_arm64_full-userdebug-native 我们需要逐步解释这些命令的作用,并确保用户理解如何执行这些命令以及它们的效果。 步骤分解: 1. `source build/envsetup.sh`:这个命令用于初始化Android的构建环境。它会引入些有用的函数(如lunch、m、mm等)和设置环境变量。注意:必须在Android源码目录下执行,且build/envsetup.sh文件存在。 2. `export OUT_DIR=out_system`:设置环境变量OUT_DIR为out_system。这个变量指定了构建输出的目录。默认情况下,Android构建系统的输出目录是out,这里改为out_system。 3. `lunch ussi_arm64_full-userdebug-native`:lunch命令用于选择构建目标(即要编译的设备类型和构建类型)。这里的构建目标为ussi_arm64_full-userdebug-native,它通常表示: - ussi:可能是项目或设备的名称。 - arm64:表示目标架构为64位ARM。 - full:可能表示完整的构建配置(包含所有系统应用和服务)。 - userdebug:构建类型,表示可调试的用户版本(介于user和eng之间,通常用于测试)。 - native:可能表示使用本地编译(没有额外的解释器或模拟层)。 注意:构建目标的具体定义取决于设备厂商提供的配置,通常可以在device/<vendor>/<device>目录下找到。 执行这些命令的顺序很重要,因为必须先初始化环境(envsetup.sh)才能使用lunch命令,而设置OUT_DIR可以在source之后,但在执行lunch之前或之后都可以(因为lunch可能会重新设置些环境变量,但OUT_DIR通常会被保留)。 因此,建议用户按以下步骤操作: 1. 进入Android源码根目录。 2. 执行`source build/envsetup.sh` 3. 执行`export OUT_DIR=out_system` 4. 执行`lunch ussi_arm64_full-userdebug-native` 执行完这些命令后,环境就设置好了,然后可以使用`m`命令开始构建整个系统,或者使用`mm`构建当前目录的模块。 注意:如果OUT_DIR的设置需要在lunch之前,因为lunch可能会根据目标设备设置些路径,但通常OUT_DIR的设置会覆盖默认值。为了确保安全,可以在lunch之前设置OUT_DIR。 另外,用户需要确保设备目标(ussi_arm64_full-userdebug-native)在环境中是有效的。可以通过运行`lunch`命令后查看菜单或直接运行该命令来检查。如果目标无效,系统会列出可用的目标。 最后,我们生成相关问题,以帮助用户深入了解或解决可能遇到的问题。</think>### Android构建环境设置详解 您提供的命令序列用于配置Android构建环境,以下是分步解释: 1. **`source build/envsetup.sh`** 初始化Android构建环境,加载编译所需的函数和别名(如`m`、`mm`等)。必须在AOSP源码根目录执行[^1]。 2. **`export OUT_DIR=out_system`** 设置构建输出目录为`out_system`(替代默认的`out`目录)。常用于隔离不同构建配置的输出[^2]。 3. **`lunch ussi_arm64_full-userdebug-native`** 选择构建目标: - `ussi_arm64`:目标设备架构(64位ARM) - `full`:完整系统镜像 - `userdebug`:可调试版本(带root权限) - `native`:本地编译模式(非跨平台编译) ```bash # 完整执行流程示例 cd /path/to/android/source # 进入AOSP目录 source build/envsetup.sh # 初始化环境 export OUT_DIR=out_system # 设置输出目录 lunch ussi_arm64_full-userdebug-native # 选择目标 m -j12 # 开始编译(使用12线程) ``` ### 注意事项 1. **环境依赖**:需提前安装JDK、编译工具链等基础环境 2. **目标验证**:执行`lunch`后终端会显示: ```log ============================================ PLATFORM_VERSION_CODENAME=REL TARGET_PRODUCT=ussi_arm64_full TARGET_BUILD_VARIANT=userdebug ... ``` 3. **目录权限**:确保`out_system`目录有写入权限 4. **构建控制**:编译时可通过`-jN`参数指定并行任务数(N=CPU核心数×1.5)
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值