Android——编译系统初始化设置
16lz
2022-08-08
最近要修改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中查看这些编译选项有没有设置成功!
更多相关文章
- android EditText设置不可写
- Android(安卓)Wifi模块分析(三)
- android“设置”里的版本号
- Android中dispatchDraw分析
- android ndk编译x264开源(用于android的ffmpeg中进行软编码)
- Android四大基本组件介绍与生命周期
- 在Fragment中设置控件点击方法,执行失败。
- Android(安卓)闹钟管理类的使用
- Android(安卓)Service AIDL