Android源碼編譯有很多全局的參數(shù)当编,例如TARGET_OUT_DATA,TARGET_OUT_ROOT ,這些參數(shù)是從何而來的呢丛楚?
編譯步驟
我們通過走一下編譯步驟族壳,看一下,這些參數(shù)的來源吧趣些!
souce build/envsetup.sh
上面這句命令仿荆,是編譯前準備環(huán)境的。
/build/envsetup.sh
可以看到到引進了一堆的函數(shù)喧务,有mm赖歌,mmm等常用指令
看看跑了啥邏輯,
1.首先判斷了下shell的環(huán)境,最好使用/bin/bash功茴。
參考:https://www.douban.com/note/404726254/
2.包含廠商vendor目錄的vendorsetup.sh
#只支持shell為/bin/bash庐冯,否則會報錯,ps -o command -p $$是顯示shell的進程名坎穿。
if [ "x$SHELL" != "x/bin/bash" ]; then
case `ps -o command -p $$` in
*bash*)
;;
*)
echo "WARNING: Only bash is supported, use of other shell would lead to erroneous results"
;;
esac
fi
#引進一些廠商的verdorsetup.sh
# 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
addcompletions
包含后展父,echo打印出來,像下面這樣子~
lunch
lunch就是選擇一些編譯參數(shù)玲昧,估計就是在這里準備好這些全局的參數(shù)的栖茉。
lunch函數(shù)在envsetup.sh里面定義
function lunch()
{
local answer #定義一個本地變量answer
#獲取第一個輸入?yún)?shù),例如如果執(zhí)行l(wèi)unch mini_emulator_arm64-userdebug孵延,第一個參數(shù)就是mini_emulator_arm64-userdebug
if [ "$1" ] ; then
answer=$1
else
print_lunch_menu #如果沒有輸入第一個參數(shù)吕漂,例如直接執(zhí)行l(wèi)unch,就會打印出選項讓你選擇
echo -n "Which would you like? [full-eng] "
read answer
fi
local selection= #定義一個本地變量selection
if [ -z "$answer" ] #如果answer為空尘应,selection就是full-eng
then
selection=full-eng
elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$") #grep -q表示安靜輸出惶凝,-e為正則表達式,匹配0-99
then
if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]
then
selection=${LUNCH_MENU_CHOICES[$(($answer-1))]}
fi
elif (echo -n $answer | grep -q -e "^[^\-][^\-]*-[^\-][^\-]*$") #匹配整個名稱輸入犬钢,這個正則不太懂~
then
selection=$answer
fi
if [ -z "$selection" ] #無效輸入苍鲜,例如你輸入1000就無效啦
then
echo
echo "Invalid lunch combo: $answer"
return 1
fi
export TARGET_BUILD_APPS=
local product=$(echo -n $selection | sed -e "s/-.*$//")
check_product $product ##檢查product
if [ $? -ne 0 ]
then
echo
echo "** Don't have a product spec for: '$product'" #無效的product
echo "** Do you have the right repo manifest?"
product=
fi
local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//") ##編譯類型,例如user玷犹,debug
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
echo
set_stuff_for_environment
printconfig
}
set_stuff_for_environment
會進入set_stuff_for_environment,主要是設(shè)置title混滔,java環(huán)境,paths還有序列號歹颓。貌似沒多大用處~
function set_stuff_for_environment()
{
settitle
set_java_home
setpaths #一些交叉編譯鏈路徑
set_sequence_number
export ANDROID_BUILD_TOP=$(gettop)
}
printconfig
最后會進入printconfig坯屿,就是打印配置信息給我們看啦!
function printconfig()
{
T=$(gettop)
if [ ! "$T" ]; then
echo "Couldn't locate the top of the tree. Try setting TOP." >&2
return
fi
get_build_var report_config
}
打印一些配置晴股,可以看到TARGET_PRODUCT愿伴,TARGET_BUILD_VARIANT和TARGET_BUILD_TYPE。
printconfig包含get_build_var函數(shù),函數(shù)執(zhí)行了一句make指令电湘,make --no-print-directory -C "$T" -f build/core/config.mk dumpvar-$1
(1)make -C "$T" 就是跳轉(zhuǎn)到top目錄。
(2)make -f 來指定makefile文件build/core/config.mk,我去config.mk還是個makefile文件寂呛。
(3)dumpvary用來打印用的怎诫,就是打印第一個參數(shù)$1啦,呵呵呵
所以贷痪,主要get_build_var主要是執(zhí)行makefile config.mk幻妓。
function get_build_var()
{
T=$(gettop)
if [ ! "$T" ]; then
echo "Couldn't locate the top of the tree. Try setting TOP." >&2
return
fi
CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
make --no-print-directory -C "$T" -f build/core/config.mk dumpvar-$1
}
看看/build/core/config.mk,可以看到他進一步包含了envsetup.mk
include $(BUILD_SYSTEM)/envsetup.mk
envsetup.mk就是最后設(shè)置一些常用編譯環(huán)境參數(shù)的文件了!劫拢!
/build/core/envsetup.mk
看下面的圖肉津,可以看到他定義了很多編譯常量了!舱沧!
總結(jié)
1.通過source envsetup.sh可以引進很多函數(shù)妹沙,包含vendorsetup.sh
2.通過lunch,選擇類型后熟吏,會編譯build/core/config.mk文件距糖,進而再編譯envsetup.mk文件,而這個文件就是定義編譯常量的地方牵寺!