Android lunch分析以及产品分支构建

一、背景

随着Android应用范围越来越广泛,用户对Android的需求也越来越趋于复杂,在开发Android应用以及底层产品驱动时,往往两套产品所需要的硬件平台就大不相同,而软件功能却相差不大。在这种纷繁的情况下,是否每种产品就需要一套源代码来维护。如果真这么做的话,那工作量就太大了。所以提出了产品分支的概念。在Android源码中提供了这么一种强大的功能。

公司正在Android上针对硬件平台做调整和开发,手上现有多种方案,有的需要无线wifi,有的底层芯片不一致。在这种情况下,公司使用Android lunch的方式使用一套源代码维护多种方案。

二、文档目的

当前网络上没有成体系的对Android lunch调用关系的研究,所以将Android lunch分析以及产品分支构建这份文档共享出来以帮助对此过程不了解的开发者。如有疑问和建议,请留言。

三、Android lunch调用关系

1.      调用流程图:

2.      调用关系分析

在编译Android产品的时候我们首先会导入. build/envsetup.sh ,然后lunch,这时候我们可以看到几个基本的产品版本。

从现象回推,首先查看envsetup.sh文件中的lunch函数:

具体分析见:lunch函数分析

在envsetup.sh中,有几个比较重要的函数。Lunch(),check_product(),print_lunch_menu(),get_build_var(),gettop,add_lunch_combo(),set_stuff_for_environment(),set_java_home(),findmakefile()。

1)  lunch

functionlunch()
{local answerif [ "$1" ] ; then# lunch后面直接带参数answer=$1else# lunch后面不带参数,则打印处所有的target product和variant菜单提供用户选择print_lunch_menu  echo -n "Which would you like?[generic-eng] "read answerfilocal selection=if [ -z "$answer" ]then# 如果用户在菜单中没有选择,直接回车,则为系统缺省的generic-engselection=generic-engelif [ "$answer" ="simulator" ]then# 如果是模拟器selection=simulatorelif(echo -n $answer | grep -q -e "^[0-9][0-9]*{1}quot;)then# 如果answer是选择菜单的数字,则获取该数字对应的字符串if [ $answer -le${#LUNCH_MENU_CHOICES[@]} ]thenselection=${LUNCH_MENU_CHOICES[$(($answer-$_arrayoffset))]}fi# 如果 answer字符串匹配 *-*模式(*的开头不能为-)elif (echo -n $answer | grep -q -e"^[^\-][^\-]*-[^\-][^\-]*{1}quot;)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/-.*$//")# 检查product,调用关系 check_product()->get_build_var()->build/core/config.mkcheck_product $productif [ $? -ne 0 ]thenechoecho "** Don't have a productspec for: '$product'"echo "** Do you have the rightrepo 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 1fiexport TARGET_PRODUCT=$productexport TARGET_BUILD_VARIANT=$variantexport TARGET_SIMULATOR=falseexport TARGET_BUILD_TYPE=releasefi # !simulator

2)  Check_product:

functioncheck_product()
{T=$(gettop)if [ ! "$T" ]; thenecho "Couldn't locate the top ofthe tree.  Try setting TOP.">&2returnfiCALLED_FROM_SETUP=trueBUILD_SYSTEM=build/core \TARGET_PRODUCT=$1 TARGET_BUILD_VARIANT=\TARGET_SIMULATOR= TARGET_BUILD_TYPE= \TARGET_BUILD_APPS= \get_build_varTARGET_DEVICE > /dev/null# hide successful answers, but allow theerrors to show
}

检查指定的TARGET_PRODUCT是否允许,默认的有sim和generic。如果不允许,则输出错误信息,允许则不显示

3)  Print_lunch_menu()

functionprint_lunch_menu()
{local uname=$(uname)echoecho "You're building on" $unameechoecho "Lunch menu... pick acombo:"local i=1
local choice
#循环查找LUNCH_MENU_CHOICES中的版本for choice in ${LUNCH_MENU_CHOICES[@]}doecho "     $i. $choice"i=$(($i+1))doneecho
}

该函数负责打印已经定义的版本

4)  Get_build_var()

functionget_build_var()
{T=$(gettop)if [ ! "$T" ]; thenecho "Couldn't locate the top ofthe tree.  Try setting TOP.">&2returnfiCALLED_FROM_SETUP=trueBUILD_SYSTEM=build/core \make --no-print-directory -C"$T" -f build/core/config.mk dumpvar-$1
}

列出make脚本中某变量的值,当前为build/core/config.mk

5)  Gettop()

function gettop
{local TOPFILE=build/core/envsetup.mkif [ -n "$TOP" -a -f"$TOP/$TOPFILE" ] ; thenecho $TOP
# 如果TOP不为空,并且envsetup.mk存在,函数直接返回TOP对应路径else# 否则(指找不到envsetup.mk)如下处理if [ -f $TOPFILE ] ; then# The following circumlocution(repeated below as well) ensures# that we record the true directoryname and not one that is# faked up with symlink names.PWD= /bin/pwdelse# We redirect cd to /dev/null incase it's aliased to# a command that prints somethingas a side-effect# (like pushd)local HERE=$PWDT=while [ \( ! \( -f $TOPFILE \) \)-a \( $PWD != "/" \) ]; docd .. > /dev/nullT=`PWD= /bin/pwd`donecd $HERE > /dev/nullif [ -f "$T/$TOPFILE" ];thenecho $Tfififi
}

返回当前android代码树的顶层路径。前提是当前路径位于android代码树中

6)  Add_lunch_combo()

functionadd_lunch_combo()
{local new_combo=$1local cfor c in ${LUNCH_MENU_CHOICES[@]} ; doif [ "$new_combo" ="$c" ] ; thenreturnfidoneLUNCH_MENU_CHOICES=(${LUNCH_MENU_CHOICES[@]} $new_combo)
}

向环境变量LUNCH_MENU_CHOICES标识的列表中添加项

7)  Set_stuff_for_environment()

functionset_stuff_for_environment()
{settitleset_java_homesetpathsset_sequence_numberexport ANDROID_BUILD_TOP=$(gettop)
}

设置android编译需要的环境变量

8)  Set_java_home

functionset_java_home() {if [ ! "$JAVA_HOME" ]; thencase `uname -s` inDarwin)exportJAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home;;*)exportJAVA_HOME=/usr/lib/jvm/java-6-sun;;esacfi
}

设置java运行环境

9)  findmakefile

functionfindmakefile()
{TOPFILE=build/core/envsetup.mk# We redirect cd to /dev/null in case it's aliased to# a command that prints something as a side-effect# (like pushd)local HERE=$PWDT=while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD !="/" \) ]; doT=$PWDif [ -f "$T/Android.mk" ];thenecho$T/Android.mk# 如果找到Android.mk,echo出来的全路径将作为函数的返回值赋给某个变量cd $HERE> /dev/nullreturnficd .. > /dev/nulldonecd $HERE > /dev/null
}

此外还有一段比较重要的代码

# Execute thecontents of any vendorsetup.sh files we can find.
for f in`/bin/ls vendor/*/vendorsetup.sh vendor/*/build/vendorsetup.sh device/*/*/vendorsetup.sh2> /dev/null`
doecho "including $f". $f
done
unset f

这段代码寻找vendor,build,device指定目录下的vendorsetup.sh。在vendorsetup.sh中定义了各版本的产品。

注:/dev/null 是 Unix/Linux 里的【无底洞】,任何的 output 送去了【无底洞】就再也没了,一般情况下,要是你不想看到 output 或者output 太多太大了,有可能把硬碟给挤爆了的时候,程序的设计就会考虑把 output 送到 /dev/null 了

四、Android lunch产品分支构建

背景:南京广义软件有限公司英文名generalizesoft,所以此处使用generalize来命名总的产品目录。其中generalizex和genx则是对公司产品共性的描述。每套产品将差异性的部分定义在自己产品当中。再调用共性的部分,形成一个完整的产品。这样做日后需要维护所有产品的时候只需要维护一套代码,而不是每套产品有一套代码,修改的内容页不方便管理。

1.  目录结构:

2.  搭建步骤

1)  在device目录下创建一个名为generalize的文件夹

2)  对其中的文件分别进行编辑。generalize.mk 对应我们第一套产品的mk文件,这是差异性文件。不同的产品需要不同的mk文件。而generalizex.mk是无差异文件,意为产品的共性。所以在generalize.mk中定义如下,它需要引用generalizex.mk中定义的部分。这样做方便以后的产品差异性对比。同样的,BoardConfigCommon.mk定义了generalize一系列产品板文件的共性。在调用关系中可以看出它们之间的关系

3)  Vendorsetup文件是定义lunch内容的文件。在其中加上我们产品。

4)  上述步骤处理完之后。运行envsetup.sh:

. build/envsetup.sh

之后再使用lunch,就可以看到基础效果图:

5)  编译android

南京广义软件:Android lunch分析以及产品分支构建相关推荐

  1. Android lunch分析以及产品分支构建

    Android lunch分析以及产品分支构建 一.背景 随着Android应用范围越来越广泛,用户对Android的需求也越来越趋于复杂,在开发Android应用以及底层产品驱动时,往往两套产品所需 ...

  2. 线性时间选择_马鞍山非线性分析工具了解详情_南京凯安软件

    南京凯安软件为您带来马鞍山非线性分析工具了解详情,欢迎查看. 马鞍山非线性分析工具了解详情,在社会现实经济生活中,很多现象之间的关系并不是线性关系,对这种类型现象的分析预测一般要应用非线性回归预测,通 ...

  3. Android 编译系统分析之lunch分析

    已开通新的博客,后续文字都会发到新博客 http://www.0xfree.top Android 编译系统解析系列文档 编译系统入口envsetup.sh解析 source build/envset ...

  4. 国内外软件成分分析SCA产品评测

    1. 概述 SCA理论上来说是一种通用的分析方法,可以对任何开发语言对象进行分析,Java.C/C++.Golang.Python.JavaScript等等,它对关注的对象是从文件层面的文件内容,以及 ...

  5. FM 发射模块QN8027软件android 5.1实现分析

    FM 发射模块QN8027软件android 5.1实现分析 一,kernel层中的驱动:(主要为厂家提供,主要配置对应的I2C口线) 由三个文件组成: 1,  Makefile   /*驱动的编译文 ...

  6. android邮件系统uml建模,软件设计UML分析--邮件管理系统.ppt

    软件设计UML分析--邮件管理系统 邮件管理系统 小组成员 需求分析 1.系统的功能:邮件管理系统起着"邮局"的作用,通过电子邮件系统,用户可以与世界上任何一个角落的网络用户联系, ...

  7. [转]Android核心分析之二:方法论探讨之概念空间篇

    我们潜意识就不想用计算机的方式来思考问题,我们有自己的思维描述方式,越是接近我们思维描述方式,我们越容易接受和使用.各种计算机语言,建模工具,不外乎就是建立一个更接近人的思维方式的概念空间,再使用工具 ...

  8. Android手机开发总结——Android核心分析

    导读:对于Android开发者来说,成系列的技术文章对他们的技术成长帮助最大.如下是我们向您强烈推荐的主题为Android开发的第一个系列文章. <Android核心分析>整理如下: 1. ...

  9. Android核心分析

    导读:对于Android开发者来说,成系列的技术文章对他们的技术成长帮助最大.如下是我们向您强烈推荐的主题为Android开发的第一个系列文章. <Android核心分析>整理如下: 1. ...

最新文章

  1. ASP.NET Core身份认证服务框架IdentityServer4(2)-整体介绍
  2. 黄聪:C#编写的Word操作类,有换页,添加表格,文本功能
  3. 燃烧学往年精选真题解析2018-01-01
  4. windows环境下安装elasticsearch
  5. 看了通信领域中信息的处理的三种方式我终于知道电报能发送信息的原理了
  6. 【文末有福利】卷积学习与图像识别的技术发展
  7. fdtd中时间监视器怎么放_利用FDTD软件仿真拓扑光子(六)-单向传播仿真与软件设置...
  8. python paas_到底什么是PaaS?——【PaaS概述科普文】
  9. 搭建redis主从结构
  10. 卸载jlink驱动出现Could not open INSTALL.LOG file错误解决方案
  11. 19【推荐系统10】从POLY2、FM到FFM——自动特征交叉的解决方案
  12. C++ 前置操作符与后置操作符
  13. selenium启动火狐浏览器_selenium之nodejs入门使用
  14. 正则表达式 - php正则匹配内容?
  15. 我的大学 --- 郭天祥【2】
  16. Jquery斗地主牌型验证插件 1.0版
  17. 禅道数据库管理登录失败,使用/opt/zbox/auth/adduser.sh命令新开用户解决
  18. 【图像检测-缺陷检测】基于灰度共生矩阵实现痕迹检测matlab代码
  19. 使用KOG数据库进行注释
  20. iPhone 电池容量怎么算?

热门文章

  1. Maximum modulus principle and its corollary(Stein复分析)
  2. 怎么删除w7桌面计算机图标,桌面无法删除的图标,小编教你win7桌面图标删不掉怎么办...
  3. fiddler--通过Fiddler模拟弱网进行测试
  4. 1849 年 11 月 29 日:真空管的发明者 John Fleming 诞生
  5. 关于SAP SBO 9.1 服务器重装的注意事项
  6. 父类的对象指向子类对象,父类可以调用子类的方法吗?
  7. Typora中(Markdown语法)在符号的上方添加符号或文字
  8. linux安全之服务安全
  9. DDK for windows
  10. 计算机基础知识(基础入门小白专属)九