1. source build/envsetup.sh原理
会发现build/core和build/make/core文件是一样的,这是是从build/make/core链接过去的,因此修改build/make/core就好
ubuntu@ubuntu:~/work/project/Android/build$ ll
总用量 24
drwxrwxr-x 6 ubuntu ubuntu 4096 11月 18 17:19 ./
drwxrwxr-x 31 ubuntu ubuntu 4096 11月 18 17:19 ../
drwxrwxr-x 14 ubuntu ubuntu 4096 11月 1 19:13 blueprint/
lrwxrwxrwx 1 ubuntu ubuntu 25 11月 18 17:19 buildspec.mk.default -> make/buildspec.mk.default
lrwxrwxrwx 1 ubuntu ubuntu 17 11月 18 17:19 CleanSpec.mk -> make/CleanSpec.mk
lrwxrwxrwx 1 ubuntu ubuntu 9 11月 18 17:19 core -> make/core/
lrwxrwxrwx 1 ubuntu ubuntu 16 11月 18 17:19 envsetup.sh -> make/envsetup.sh*
drwxrwxr-x 6 ubuntu ubuntu 4096 11月 1 19:13 kati/
drwxrwxr-x 7 ubuntu ubuntu 4096 11月 1 19:13 make/
drwxrwxr-x 18 ubuntu ubuntu 4096 11月 1 19:13 soong/
lrwxrwxrwx 1 ubuntu ubuntu 11 11月 18 17:19 target -> make/target/
lrwxrwxrwx 1 ubuntu ubuntu 10 11月 18 17:19 tools -> make/tools/
source build/envsetup.sh是执行这个脚本,主要就是提供函数和命令给编译使用
//比如这个hmm就可以在终端直接输入
@build/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|armv5|arm64|x86_64|mips64] [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, but not their dependencies.
- mmm: Builds all of the modules in the supplied directories, but not their dependencies.
To limit the modules being built use the syntax: mmm dir/:target1,target2.
- mma: Builds all of the modules in the current directory, and their dependencies.
- mmma: Builds all of the modules in the supplied directories, and their dependencies.
- provision: Flash device with all required partitions. Options will be passed on to fastboot.
- cgrep: Greps on all local C/C++ files.
- ggrep: Greps on all local Gradle files.
- jgrep: Greps on all local Java files.
- resgrep: Greps on all local res/*.xml files.
- mangrep: Greps on all local AndroidManifest.xml files.
- mgrep: Greps on all local Makefiles files.
- sepgrep: Greps on all local sepolicy files.
- sgrep: Greps on all local source files.
- godir: Go to the directory containing a file.
Environment options:
- SANITIZE_HOST: Set to 'true' to use ASAN for all host modules. Note that
ASAN_OPTIONS=detect_leaks=0 will be set by default until the
build is leak-check clean.
Look at the source to view more functions. The complete list is:
EOF
local T=$(gettop)
local A=""
local i
for i in `cat $T/build/envsetup.sh | sed -n "/^[[:blank:]]*function /s/function \([a-z_]*\).*/\1/p" | sort | uniq`; do
A="$A $i"
done
echo $A
}
其中也包含有make编译命令
function make()
{
_wrap_build $(get_make_command) "$@"
}
function _wrap_build()
{
local start_time=$(date +"%s")
"$@" //执行传入的参数 $(get_make_command) "$@",开始编译
local ret=$?
local end_time=$(date +"%s")
local tdiff=$(($end_time-$start_time))
local hours=$(($tdiff / 3600 ))
local mins=$((($tdiff % 3600) / 60))
local secs=$(($tdiff % 60))
local ncolors=$(tput colors 2>/dev/null)
if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then
color_failed=$'\E'"[0;31m"
color_success=$'\E'"[0;32m"
color_reset=$'\E'"[00m"
else
color_failed=""
color_success=""
color_reset=""
fi
echo
if [ $ret -eq 0 ] ; then
echo -n "${color_success}#### build completed successfully "
else
echo -n "${color_failed}#### failed to build some targets "
fi
if [ $hours -gt 0 ] ; then
printf "(%02g:%02g:%02g (hh:mm:ss))" $hours $mins $secs
elif [ $mins -gt 0 ] ; then
printf "(%02g:%02g (mm:ss))" $mins $secs
elif [ $secs -gt 0 ] ; then
printf "(%s seconds)" $secs
fi
echo " ####${color_reset}"
echo
if [ $ret -eq 0 ] ; then
#编译成功后执行这里
fi
return $ret
}
2.lunch原理
source的最后会去执行 vendorsetup.sh 里面的内容,从下面是在device vendor这两个目录的所有vendorsetup.sh
@build/envsetup.sh
# Execute the contents of any vendorsetup.sh files we can find.
for f in `test -d device && find -L device -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort` \
`test -d vendor && find -L vendor -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort` \
`test -d product && find -L product -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort`
do
echo "including $f"
. $f //执行vendorsetup.sh
done
unset f
addcompletions
//执行shell
@device/qcom/common/vendorsetup.sh
add_lunch_combo msm8994-userdebug
add_lunch_combo msm8994-user
add_lunch_combo msm8996_gvmq-userdebug
add_lunch_combo msm8996_gvmq-user
@build/envsetup.sh
# Clear this variable. It will be built up again when the vendorsetup.sh
# files are included at the end of this file.
unset LUNCH_MENU_CHOICES
function add_lunch_combo()
{
local new_combo=$1
local c
for c in ${LUNCH_MENU_CHOICES[@]} ; do
if [ "$new_combo" = "$c" ] ; then
return
fi
done
LUNCH_MENU_CHOICES=(${LUNCH_MENU_CHOICES[@]} $new_combo)
}
lunch时就执行这里,先就会调用print_lunch_menu打印所有的LUNCH_MENU_CHOICES
function lunch()
{
local answer
if [ "$1" ] ; then
answer=$1
else
print_lunch_menu
echo -n "Which would you like? [aosp_arm-eng] "
read answer //通过列表选择lunch哪一个,然后传给answer
fi
//假如这里是 msm8996_gvmq-userdebug
local selection=
if [ -z "$answer" ] //如果是空的,就默认为selection=aosp_arm-eng
then
selection=aosp_arm-eng
elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")
then
if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]
then
selection=${LUNCH_MENU_CHOICES[$(($answer-1))]}
fi
else
selection=$answer //这里就为msm8996_gvmq-userdebug
fi
export TARGET_BUILD_APPS=
local product variant_and_version variant version
product=${selection%%-*} # Trim everything after first dash //取-左边,也就是msm8996_gvmq
variant_and_version=${selection#*-} # Trim everything up to first dash //右边是userdebug
if [ "$variant_and_version" != "$selection" ]; then
variant=${variant_and_version%%-*}
if [ "$variant" != "$variant_and_version" ]; then
version=${variant_and_version#*-}
fi
fi
if [ -z "$product" ] //lunch返回
then
echo
echo "Invalid lunch combo: $selection"
return 1
fi
TARGET_PRODUCT=$product \
TARGET_BUILD_VARIANT=$variant \
TARGET_PLATFORM_VERSION=$version \
build_build_var_cache
if [ $? -ne 0 ]
then
return 1
fi
export TARGET_PRODUCT=$(get_build_var TARGET_PRODUCT)
export TARGET_BUILD_VARIANT=$(get_build_var TARGET_BUILD_VARIANT)
if [ -n "$version" ]; then
export TARGET_PLATFORM_VERSION=$(get_build_var TARGET_PLATFORM_VERSION)
else
unset TARGET_PLATFORM_VERSION
fi
export TARGET_BUILD_TYPE=release
echo
export TARGET_BUILD_ADB_DEFAULT=
export TARGET_BUILD_USER_ROOT_ENABLE=
if [ $TARGET_BUILD_VARIANT == "user" ] ; then
chooseadbcomposition $2 //$2 enable 如果选择user版本,是否打开adb和root
chooseuserenableroot $3
fi
set_stuff_for_environment //设置环境变量和参数,如ANDROID_BUILD_TOP
printconfig
destroy_build_var_cache
}
分别对应 导入TARGET_BUILD_ADB_DEFAULT TARGET_BUILD_USER_ROOT_ENABLE这两个变量
function chooseadbcomposition()
{
echo "adb default:"
echo " 1. enable"
echo " 2. disable"
echo
local DEFAULT_NUM DEFAULT_VALUE
DEFAULT_NUM=2
DEFAULT_VALUE=disable
export TARGET_BUILD_ADB_DEFAULT=
local ANSWER
echo -n "Which would you like? ["$DEFAULT_NUM"] "
if [ -z "$1" ] ; then
read ANSWER
else
echo $1
ANSWER=$1
fi
case $ANSWER in
"")
export TARGET_BUILD_ADB_DEFAULT=$DEFAULT_VALUE
;;
1)
export TARGET_BUILD_ADB_DEFAULT=enable
;;
2)
export TARGET_BUILD_ADB_DEFAULT=disable
;;
*)
echo
echo "I didn't understand your response. Please try again."
echo
;;
esac
echo "TARGET_BUILD_ADB_DEFAULT=$TARGET_BUILD_ADB_DEFAULT"
}
function chooseuserenableroot()
{
...
case $ANSWER in
export TARGET_BUILD_USER_ROOT_ENABLE=enable
;;
2)
export TARGET_BUILD_USER_ROOT_ENABLE=disable
;;
*)
echo "TARGET_BUILD_USER_ROOT_ENABLE=$TARGET_BUILD_USER_ROOT_ENABLE"
}
//结果就是打印,选择,然后设置环境变量
adb default:
1. enable
2. disable
Which would you like? [2] 1
TARGET_BUILD_ADB_DEFAULT=enable
user root(closable selinux):
1. enable
2. disable
//设置些环境变量参数
function set_stuff_for_environment()
{
settitle
set_java_home
setpaths
set_sequence_number
export ANDROID_BUILD_TOP=$(gettop)
# With this environment variable new GCC can apply colors to warnings/errors
export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
export ASAN_OPTIONS=detect_leaks=0
}
function printconfig()
{
local 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
}
lunch的结果,打印了很多变量,launch应该就是导入环境变量,通过lunch选择,知道项目产品和userdebug版本等,然后make时可以通过值的不同,实现不同编译
Which would you like? [aosp_arm-eng] msm8996_gvmq-userdebug
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=8.1.0
TARGET_PRODUCT=msm8996_gvmq
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_PLATFORM_VERSION=OPM1
TARGET_BUILD_APPS=
TARGET_ARCH=arm64
TARGET_ARCH_VARIANT=armv8-a
TARGET_CPU_VARIANT=kryo
TARGET_2ND_ARCH=arm
TARGET_2ND_ARCH_VARIANT=armv7-a-neon
TARGET_2ND_CPU_VARIANT=cortex-a9
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-4.15.0-70-generic-x86_64-with-Ubuntu-16.04-xenial
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=YT.CA.17101.01100
OUT_DIR=out
AUX_OS_VARIANT_LIST=
3. lunch之后的不同产品的编译
4.添加一个新lunch编译选项
参照高通写法
xref: /device/qcom/
common/
msm8996/
msm8996_gvmq/
sepolicy/
比如产品为公司为company myproduct
创建目录
device/company/common //存放 vendorsetup.sh放入 add_lunch_combo myproduct-userdebug
device/company/myproduct //复制高通对应目录 msm8996_gvmq,修改里面的product配置
3.其他一些点
TARGET_DEVICE 控制out/target/product/msm8996_gvmq名字
env查看环境变量
ANDROID_PRODUCT_OUT=/home/wangdong/work/project/3s1/hqx/LINUX/android/out/target/product/msm8996_gvmq
@envsetup.sh
export ANDROID_PRODUCT_OUT=$(get_abs_build_var PRODUCT_OUT)
@build/core/envsetup.mk
PRODUCT_OUT := $(TARGET_PRODUCT_OUT_ROOT)/$(TARGET_DEVICE)
@device/chinatsp/bordrinb31/bordrinb31.mk
PRODUCT_NAME := bordrinb31
PRODUCT_DEVICE := msm8996_gvmq
TARGET_VENDOR := chinatsp