Android——编译系统初始化设置

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


一.source build/envsetup.sh

这个命令编译过android源码的人都不会陌生,也是起始命令。
字面意思就是设置环境变量,envsetup.sh中:
function hmm() {
cat <<EOF
Invoke ". 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()             # 检查product
function check_variant()             # 检查变量
function setpaths()                # 设置文件路径
function printconfig()              # 打印配置
function set_stuff_for_environment()        # 设置环境变量
function set_sequence_number()            # 设置序号
function settitle()                # 设置标题
function choosetype()               # 设置type
function chooseproduct()              # 设置product
function choosevariant()              # 设置variant
function tapas()                  # 功能同choosecombo
function choosecombo()               # 设置编译参数
function add_lunch_combo()             # 添加lunch项目
function print_lunch_menu()            # 打印lunch列表
function lunch()                 # 配置lunch
function m()                   # make from top
function findmakefile()              # 查找makefile
function mm()                   # make from current directory
function mmm()                   # make the supplied directories
function 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 here
add_lunch_combo full-eng
add_lunch_combo full_x86-eng
add_lunch_combo vbox_x86-eng
add_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  #执行找到的脚本
done
unset f

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

add_lunch_combo gotechcn-userdebug

我这里添加的选项结构   gotechcn 就是产品名称,编译类型就是 userdebug   中间以“-”分开

可以看到如果找到了就会打印including **,我这的工程是这样的:

including device/asus/grouper/vendorsetup.sh
including device/asus/tilapia/vendorsetup.sh
including device/generic/armv7-a-neon/vendorsetup.sh
including device/generic/armv7-a/vendorsetup.sh
including device/generic/mips/vendorsetup.sh
including device/generic/x86/vendorsetup.sh
including device/lge/mako/vendorsetup.sh
including 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 answer

if [ "$1" ] ; then
# lunch后面直接带参数
answer=$1
else
# lunch后面不带参数,则打印处所有的target product和variant菜单提供用户选择
print_lunch_menu 
echo -n "Which would you like? [full-eng] "
read answer
fi

local selection=

if [ -z "$answer" ]
then
# 如果用户在菜单中没有选择,直接回车,则为系统缺省的full-eng  为第一个选项
selection=generic-eng
elif [ "$answer" = "simulator" ]
then
# 如果是模拟器
selection=simulator
elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")
then
# 如果answer是选择菜单的数字,则获取该数字对应的字符串
if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]
then
selection=${LUNCH_MENU_CHOICES[$(($answer-$_arrayoffset))]}
fi
# 如果 answer字符串匹配 *-*模式(*的开头不能为-)
elif (echo -n $answer | grep -q -e "^[^\-][^\-]*-[^\-][^\-]*$")
then
selection=$answer
fi

if [ -z "$selection" ]
then
echo
echo "Invalid lunch combo: $answer"
return 1
fi

# special case the simulator
if [ "$selection" = "simulator" ]
then
# 模拟器模式
export TARGET_PRODUCT=sim
export TARGET_BUILD_VARIANT=eng
export TARGET_SIMULATOR=true
export TARGET_BUILD_TYPE=debug
else

# 将 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 ]
then
echo
echo "** 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 $variant
if [ $? -ne 0 ]
then
echo
echo "** Invalid variant: '$variant'"
echo "** Must be one of ${VARIANT_CHOICES[@]}"
variant=
fi

if [ -z "$product" -o -z "$variant" ]
then
echo
return 1
fi
# 导出环境变量,这里很重要,因为后面的编译系统都是依赖于这里定义的几个变量的
export TARGET_PRODUCT=$product
export TARGET_BUILD_VARIANT=$variant
export 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=REL
PLATFORM_VERSION=4.2.1
TARGET_PRODUCT=full_gotechcn
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a-neon
HOST_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-3.8.0-19-generic-x86_64-with-Ubuntu-13.04-raring
HOST_BUILD_TYPE=release
BUILD_ID=MK04
OUT_DIR=out
============================================



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







你可能感兴趣的:(android,Build,Lunch,product,envsetup)