最近要修改product 以及buildtype,学习了一下android的编译准备工作,以此记录。


一.source build/envsetup.sh

这个命令编译过android源码的人都不会陌生,也是起始命令。 字面意思就是设置环境变量,envsetup.sh中:
function hmm() {cat <<EOFInvoke ". 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] [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.- mmm:     Builds all of the modules in the supplied directories.- cgrep:   Greps on all local C/C++ files.- jgrep:   Greps on all local Java files.- resgrep: Greps on all local res/*.xml files.- godir:   Go to the directory containing a file.Look at the source to view more functions. The complete list is:EOF    T=$(gettop)    local A    A=""    for i in `cat $T/build/envsetup.sh | sed -n "/^function /s/function \([a-z_]*\).*/\1/p" | sort`; do      A="$A $i"    done    echo $A}

依次将function *() 方法加载到环境变量中。
function get_abs_build_var()           # 获取绝对变量function get_build_var()             # 获取绝对变量function check_product()             # 检查productfunction check_variant()             # 检查变量function setpaths()                # 设置文件路径function printconfig()              # 打印配置function set_stuff_for_environment()        # 设置环境变量function set_sequence_number()            # 设置序号function settitle()                # 设置标题function choosetype()               # 设置typefunction chooseproduct()              # 设置productfunction choosevariant()              # 设置variantfunction tapas()                  # 功能同choosecombofunction choosecombo()               # 设置编译参数function add_lunch_combo()             # 添加lunch项目function print_lunch_menu()            # 打印lunch列表function lunch()                 # 配置lunchfunction m()                   # make from topfunction findmakefile()              # 查找makefilefunction mm()                   # make from current directoryfunction mmm()                   # make the supplied directoriesfunction croot()                 # 回到根目录function cproj()function pid()function systemstack()function gdbclient()function jgrep()                 # 查找java文件function cgrep()                  # 查找c/cpp文件function resgrep()function tracedmdump()function runhat()function getbugreports()function startviewserver()function stopviewserver()function isviewserverstarted()function smoketest()function runtest()function godir ()                 # 跳到指定目录

这个脚本在加载完命令函数之后,就会去加载android的编译选项:
# add the default one hereadd_lunch_combo full-engadd_lunch_combo full_x86-engadd_lunch_combo vbox_x86-engadd_lunch_combo full_mips-eng

这些都是generic-eng 普通的工程机选项。
调用的是 add_lunch_combo 函数:
function add_lunch_combo()   {     local new_combo=$1         # 获得add_lunch_combo被调用时的参数    local c     # 依次遍历LUNCH_MENU_CHOICES里的值,其实该函数第一次调用时,该值为空     for c in ${LUNCH_MENU_CHOICES[@]} ; do         if [ "$new_combo" = "$c" ] ; then    # 如果参数里的值已经存在于LUNCH_MENU_CHOICES变量里,则返回             return         fi     done     # 如果参数的值不存在,则添加到LUNCH_MENU_CHOICES变量里     LUNCH_MENU_CHOICES=(${LUNCH_MENU_CHOICES[@]} $new_combo) }

往下走 :
# Execute the contents of any vendorsetup.sh files we can find.for f in `/bin/ls vendor/*/vendorsetup.sh vendor/*/*/vendorsetup.sh device/*/*/vendorsetup.sh 2> /dev/null`do    echo "including $f"  #打印找到的脚本    . $f  #执行找到的脚本doneunset f

这是到指定的路径下去找vendorsetup.sh脚本并执行,这些脚本就是自定义的工程了,需要执行add_lunch_combo函数 将我们的产品名以及编译属性添加到LUNCH_MENU_CHOICES 以供后面lunch 时选择!
add_lunch_combo gotechcn-userdebug

我这里添加的选项结构 gotechcn 就是产品名称,编译类型就是 userdebug 中间以“-”分开
可以看到如果找到了就会打印including **,我这的工程是这样的:
including device/asus/grouper/vendorsetup.shincluding device/asus/tilapia/vendorsetup.shincluding device/generic/armv7-a-neon/vendorsetup.shincluding device/generic/armv7-a/vendorsetup.shincluding device/generic/mips/vendorsetup.shincluding device/generic/x86/vendorsetup.shincluding device/lge/mako/vendorsetup.shincluding device/mstar/gotechcn/vendorsetup.sh




二.编译选项的区别以及作用:

上面看到设置了编译选项为userdebug,android 的编译选项分3种:
eng: 工程机,user:最终用户机userdebug:调试测试机

android的android.mk 文件中有一个配置选项: LOCAL_MODULE_TAGS 配置成什么就是在什么版本的情况下才会被编译进系统!
 LOCAL_MODULE_TAGS := optional
这个代表不管编译选项是什么 都编译进去。

三种类型编译区别如下:

#1.eng,那么其编译进去的内容包括:· Intended for platform-level debugging· Installs modules tagged with: eng, debug, user, and/or development· Installs non-APK modules that have no tags specified· Installs APKs according to the product definition files, in addition to tagged APKs· Sets ro.secure=1· Sets ro.debuggable=0· Sets ro.kernel.android.checkjni=1· adbd is enabled by default#2.user,那么其编译进去的内容包括:· Intended to be the final release· Installs modules tagged as user· Installs non-APK modules that have no tags specified· Installs APKs according to the product definition files (tags are ignored for APK modules)· Sets ro.secure=1· Sets ro.debuggable=0· adbd is disabled by default#3.userdebug,那么其编译进去的内容包括:the same as user, except:· Intended for limited debugging· Installs modules tagged with debug· Sets ro.debuggable=1· adbd is enabled by default 


这是之前版本的控制,目前以我的android 4.2 分析的请参考: Android——编译安装Module的控制因素


三.lunch

在做了前面的准备之后就可以在终端运行lunch命令来选择将要编译的成品类型了。 调用到:
function lunch(){local answerif [ "$1" ] ; then# lunch后面直接带参数answer=$1else# lunch后面不带参数,则打印处所有的target product和variant菜单提供用户选择print_lunch_menu echo -n "Which would you like? [full-eng] "read answerfilocal selection=if [ -z "$answer" ]then# 如果用户在菜单中没有选择,直接回车,则为系统缺省的full-eng  为第一个选项selection=generic-engelif [ "$answer" = "simulator" ]then# 如果是模拟器selection=simulatorelif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")then# 如果answer是选择菜单的数字,则获取该数字对应的字符串if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]thenselection=${LUNCH_MENU_CHOICES[$(($answer-$_arrayoffset))]}fi# 如果 answer字符串匹配 *-*模式(*的开头不能为-)elif (echo -n $answer | grep -q -e "^[^\-][^\-]*-[^\-][^\-]*$")thenselection=$answerfiif [ -z "$selection" ]thenechoecho "Invalid lunch combo: $answer"return 1fi# special case the simulatorif [ "$selection" = "simulator" ]then# 模拟器模式export TARGET_PRODUCT=simexport TARGET_BUILD_VARIANT=engexport TARGET_SIMULATOR=trueexport TARGET_BUILD_TYPE=debugelse# 将 product-variant模式中的product分离出来local product=$(echo -n $selection | sed -e "s/-.*$//")check_product $product# 检查之,调用关系 check_product()->get_build_var()中调用了make命令 “ make --no-print-directory -C "$T" -f build/core/config.mk dumpvar-$1 ” 后面另开一篇再来详细跟进去学习!if [ $? -ne 0 ]thenechoecho "** Don't have a product spec for: '$product'"echo "** Do you have the right repo manifest?"product=fi# 将 product-variant模式中的variant分离出来local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//")# 检查之,看看是否在 (user userdebug eng) 范围内check_variant $variantif [ $? -ne 0 ]thenechoecho "** Invalid variant: '$variant'"echo "** Must be one of ${VARIANT_CHOICES[@]}"variant=fiif [ -z "$product" -o -z "$variant" ]thenechoreturn 1fi# 导出环境变量,这里很重要,因为后面的编译系统都是依赖于这里定义的几个变量的export TARGET_PRODUCT=$productexport TARGET_BUILD_VARIANT=$variantexport TARGET_BUILD_TYPE=release#调用函数设置环境变量,函数全部在envsetup.sh中set_stuff_for_environment # 打印一些主要的变量, 调用关系 printconfig()->get_build_var()->build/core/config.mk->build/core/envsetup.mk 比较罗嗦,不展开了printconfig}



当选择之后,check 和 set 成功之后 就会打印出来:

============================================PLATFORM_VERSION_CODENAME=RELPLATFORM_VERSION=4.2.1TARGET_PRODUCT=full_gotechcnTARGET_BUILD_VARIANT=userdebugTARGET_BUILD_TYPE=releaseTARGET_BUILD_APPS=TARGET_ARCH=armTARGET_ARCH_VARIANT=armv7-a-neonHOST_ARCH=x86HOST_OS=linuxHOST_OS_EXTRA=Linux-3.8.0-19-generic-x86_64-with-Ubuntu-13.04-raringHOST_BUILD_TYPE=releaseBUILD_ID=MK04OUT_DIR=out============================================



到这里,make之前的准备工作已经做完了,在上面其中对product的控制检测都是通过调用check_product()到makefile体系中去查询设置相关变量的,如果新添加product就需要牵扯到里面,另外可以在build.prop中查看这些编译选项有没有设置成功!






更多相关文章

  1. Android ViewPager实现Tabhost选项卡底部滑块动态滑动过渡
  2. [转]Android选项卡(TabWidget)例子
  3. Android Chronometer控件实现计时器函数详解
  4. Android O 下拉框增加自动亮度开关选项
  5. android tab选项卡效果
  6. Android下使用dlopen函数动态调用.so链接库
  7. 在Android中使用Application保存全局变量
  8. Android存储选项简析

随机推荐

  1. PHP命名空间
  2. php 重载与事件委托
  3. 文件上传的实例
  4. 实例演绎pdo在用户登录环节是怎么防sql注
  5. php灭绝手把手教你玩文件上传
  6. mysql简单处理表格与pdo预处理的作用
  7. 前端、后端、测试、研发经理必备技能-Api
  8. react源码解读 getNextLanes
  9. [emerg] bind() to 0.0.0.0:XXXX failed
  10. 08-11 作业 面对对象和自动加载 封装 继