一、source build/envsetup.sh
1、定義函數
如 lunch croot mm mmm mma mmma cgrep make等
2、VARIANT_CHOICES=(user userdebug eng) 編譯選項值
3、unset LUNCH_MENU_CHOICES
add_lunch_combo aosp_arm-eng
add_lunch_combo aosp_arm64-eng
add_lunch_combo aosp_mips-eng
add_lunch_combo aosp_mips64-eng
add_lunch_combo aosp_x86-eng
add_lunch_combo aosp_x86_64-eng
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) //就是把add_lunch_combo後面的參數加到LUNCH_MENU_CHOICES這個值裏面
}
4、complete -F _lunch lunch 定義lunch命令的Tab補全函數
5、檢查shell是否爲bash
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
6、查找並執行device vendor product目錄下面的vendorsetup.sh
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
done
including device/generic/car/vendorsetup.sh
add_lunch_combo aosp_car_arm-userdebug
add_lunch_combo aosp_car_arm64-userdebug
add_lunch_combo aosp_car_x86-userdebug
add_lunch_combo aosp_car_x86_64-userdebug
including device/generic/mini-emulator-arm64/vendorsetup.sh
add_lunch_combo mini_emulator_arm64-userdebug
including device/generic/mini-emulator-armv7-a-neon/vendorsetup.sh
add_lunch_combo m_e_arm-userdebug
including device/generic/mini-emulator-x86_64/vendorsetup.sh
add_lunch_combo mini_emulator_x86_64-userdebug
including device/generic/mini-emulator-x86/vendorsetup.sh
add_lunch_combo mini_emulator_x86-userdebug
including device/generic/uml/vendorsetup.sh
add_lunch_combo uml-userdebug
including device/google/muskie/vendorsetup.sh
add_lunch_combo aosp_walleye-userdebug
add_lunch_combo aosp_walleye_test-userdebug
including device/google/taimen/vendorsetup.sh
add_lunch_combo aosp_taimen-userdebug
including device/qcom/common/vendorsetup.sh
add_lunch_combo xxx8974-userdebug
add_lunch_combo xxx8610-userdebug
add_lunch_combo xxx8226-userdebug
add_lunch_combo apq8084-userdebug
add_lunch_combo mpq8092-userdebug
add_lunch_combo xxx_bronze-userdebug
add_lunch_combo xxx8916_32-userdebug
add_lunch_combo xxx8916_32_512-userdebug
add_lunch_combo xxx8916_32_k64-userdebug
add_lunch_combo xxx8916_64-userdebug
add_lunch_combo xxx8994-userdebug
add_lunch_combo xxx8996-userdebug
add_lunch_combo xxx8909-userdebug
add_lunch_combo xxx8909go-userdebug
add_lunch_combo xxx8909_512-userdebug
add_lunch_combo xxx8909_512go-userdebug
add_lunch_combo xxx8992-userdebug
add_lunch_combo xxx8952_64-userdebug
add_lunch_combo xxx8952_32-userdebug
add_lunch_combo xxx8937_32-userdebug
add_lunch_combo xxx8937_32go-userdebug
add_lunch_combo xxx8937_64-userdebug
add_lunch_combo xxx8953_32-userdebug
add_lunch_combo xxx8953_64-userdebug
add_lunch_combo xxx8998-userdebug
add_lunch_combo xxx8998_32-userdebug
add_lunch_combo sdm660_64-userdebug
add_lunch_combo sdm660_32-userdebug
add_lunch_combo sdm845-userdebug
add_lunch_combo apq8098_latv-userdebug
add_lunch_combo sdm710-userdebug
add_lunch_combo xxxnile-userdebug
add_lunch_combo xxxnile_au-userdebug
add_lunch_combo xxxnile_gvmq-userdebug
add_lunch_combo qcs605-userdebug
add_lunch_combo sm6150-userdebug
add_lunch_combo sm6150_au-userdebug
add_lunch_combo sm6150_au_gvmq-userdebug
add_lunch_combo trinket-userdebug
add_lunch_combo sdmshrike_au-userdebug
including device/qcom/qssi/vendorsetup.sh
add_lunch_combo qssi-userdebug
including vendor/qcom/opensource/core-utils/vendorsetup.sh
export QTI_BUILDTOOLS_DIR=$(dirname ${BASH_SOURCE[0]})
including vendor/qcom/proprietary/common/vendorsetup.sh
export QCPATH="vendor/qcom/proprietary"
export QCPATH_COMMONSYS="${QCPATH}/commonsys"
export SDCLANG_AE_CONFIG="${QCPATH}/common-noship/etc/sdclang.json"
export SDCLANG_CONFIG="${QCPATH}/common/config/sdclang.json"
if [ -f "$(pwd)/${QCPATH}/qrsp/mpgen/mpgen.py" ]; then
export RTIC_MPGEN="python $(pwd)/${QCPATH}/qrsp/mpgen/mpgen.py"
fi
including vendor/qcom/proprietary/prebuilt_HY11/vendorsetup.sh
刪除之前下載時的鏈接文件,重新建立相對路徑的軟鏈接
links_dir="$(dirname $(readlink -e "${BASH_SOURCE[0]}"))"
links_path="$(dirname $(readlink -e "${BASH_SOURCE[0]}"))/links"
failed_links=""
count=0
if [ -f "$links_path" ];then
total_links=$(cat $links_dir/*links| wc -l)
for i in $(cat $links_dir/*links);do
src=$(echo $i | awk -F:: '{print $1}')
dest=$(echo $i | awk -F:: '{print $2}')
if [ -e "$dest" ];then
echo rm -rf $dest
rm -rf $dest
fi
if [[ -e $src && ! -e $dest ]];then
mkdir -p $(dirname $dest)
echo $src
echo $dest
ln -srf $src $dest
count=$(($count + 1))
else
failed_links="$failed_links $i"
fi
done
if [ ! -z "$failed_links" ];then
echo "*****Could not create symlink*******"
echo $failed_links | sed 's/[[:space:]]/\n/g'
echo "****************END******************"
fi
echo "Created $count symlinks out of $total_links mapped links.."
fi
Created 12 symlinks out of 12 mapped links..
7、addcompletions
function addcompletions()
{
local T dir f
# Keep us from trying to run in something that isn't bash.
if [ -z "${BASH_VERSION}" ]; then
return
fi
# Keep us from trying to run in bash that's too old.
if [ ${BASH_VERSINFO[0]} -lt 3 ]; then
return
fi
dir="sdk/bash_completion"
if [ -d ${dir} ]; then
for f in `/bin/ls ${dir}/[a-z]*.bash 2> /dev/null`; do
echo "including $f"
. $f
done
fi
complete -C "bit --tab" bit
}
including sdk/bash_completion/adb.bash
complete -F _adb adb 定義adb命令的Tab補全函數
二、lunch
function lunch()
{
local answer
if [ "$1" ] ; then
answer=$1
else
print_lunch_menu
echo -n "Which would you like? [aosp_arm-eng] "
read answer
fi
local selection=
if [ -z "$answer" ]
then
selection=aosp_arm-eng
elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$") 匹配lunch數字裏面的選項值
then
if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]
then
selection=${LUNCH_MENU_CHOICES[$(($answer-1))]}
fi
else
selection=$answer-1 直接lunch + 選項值
fi
export TARGET_BUILD_APPS=
local product variant_and_version variant version
product=${selection%%-*} # Trim everything after first dash 刪掉第一個-和其右邊的字符
variant_and_version=${selection#*-} # Trim everything up to first dash 刪除第一個-和其左邊的字符
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" ]
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
function build_build_var_cache() # Get all the build variables needed by this script in a single call to the build system.獲取所需的所有構建變量
{
local T=$(gettop) gettop函數從指定的$TOP目錄或當前目錄開始查找build/core/envsetup.mk文件,並將能找到該文件的目錄返回給調用函數作爲操作的根目錄
# Grep out the variable names from the script.
cached_vars=`cat $T/build/envsetup.sh | tr '()' ' ' | awk '{for(i=1;i<=NF;i++) if($i~/get_build_var/) print $(i+1)}' | sort -u | tr '\n' ' '`
cached_abs_vars=`cat $T/build/envsetup.sh | tr '()' ' ' | awk '{for(i=1;i<=NF;i++) if($i~/get_abs_build_var/) print $(i+1)}' | sort -u | tr '\n' ' '`
# Call the build system to dump the "<val>=<value>" pairs as a shell script.
build_dicts_script=`\builtin cd $T; build/soong/soong_ui.bash --dumpvars-mode \
--vars="$cached_vars" \
--abs-vars="$cached_abs_vars" \
--var-prefix=var_cache_ \
--abs-var-prefix=abs_var_cache_`
soong_ui.bashL:
export TRACE_BEGIN_SOONG=$(date +%s%N)
export ORIGINAL_PWD=${PWD}
export TOP=$(gettop)
source ${TOP}/build/soong/scripts/microfactory.bash
export GOROOT="${TOP}/prebuilts/go/linux-x86/"
source ${TOP}/build/blueprint/microfactory/microfactory.bash
soong_build_go soong_ui android/soong/cmd/soong_build_go 實際上執行 ${TOP}/prebuilts/go/linux-x86/bin/go run 加參數 生成soong_ui命令
cd ${TOP}
exec "$(getoutdir)/soong_ui" "$@" soong_ui入口,執行soong流程 其實從執行結果輸出來說,就是把上面的cached_vars和cached_abs_vars所有的變量值全部賦好
:
local ret=$?
if [ $ret -ne 0 ]
then
unset build_dicts_script
return $ret
fi
# Execute the script to store the "<val>=<value>" pairs as shell variables.
eval "$build_dicts_script" 再次執行上面的生成的變量,在shell上面執行,讓這些值被編譯系統知道
ret=$?
unset build_dicts_script
if [ $ret -ne 0 ]
then
return $ret
fi
BUILD_VAR_CACHE_READY="true"
}
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
set_stuff_for_environment export一些變量值
printconfig
destroy_build_var_cache unset cached_vars和cached_abs_vars這些變量
}
三、make
頂層Makefile
include build/make/core/main.mk
include $(BUILD_SYSTEM)/Makefile include build/make/core/Makefile
Makefile 中的第一個目標爲默認目標,我們可以通過 .DEFAULT_GOAL 這個特殊的僞目標來覆蓋掉默認的行爲。
.PHONY: droid
DEFAULT_GOAL := droid
$(DEFAULT_GOAL): droid_targets
.PHONY: droid_targets
droid_targets:
ifneq ($(TARGET_BUILD_APPS),)
# If this build is just for apps, only build apps and not the full system by default.
droid_targets: apps_only
else
droid_targets: droidcore dist_files
.PHONY: droidcore
droidcore: files \
systemimage \
$(INSTALLED_BOOTIMAGE_TARGET) \
$(INSTALLED_RECOVERYIMAGE_TARGET) \
$(INSTALLED_VBMETAIMAGE_TARGET) \
$(INSTALLED_USERDATAIMAGE_TARGET) \
$(INSTALLED_CACHEIMAGE_TARGET) \
$(INSTALLED_BPTIMAGE_TARGET) \
$(INSTALLED_VENDORIMAGE_TARGET) \
$(INSTALLED_PRODUCTIMAGE_TARGET) \
$(INSTALLED_SYSTEMOTHERIMAGE_TARGET) \
$(INSTALLED_FILES_FILE) \
$(INSTALLED_FILES_FILE_VENDOR) \
$(INSTALLED_FILES_FILE_PRODUCT) \
$(INSTALLED_FILES_FILE_SYSTEMOTHER) \
soong_docs
# Include all of the makefiles in the system
#
subdir_makefiles := $(SOONG_ANDROID_MK) $(file <$(OUT_DIR)/.module_paths/Android.mk.list)
modules_to_install := $(sort \
$(ALL_DEFAULT_INSTALLED_MODULES) \
$(product_FILES) \
$(foreach tag,$(tags_to_install),$($(tag)_MODULES)) \ 與當前編譯類型對應的模塊文件 (debug/userdebug 之類的)
$(CUSTOM_MODULES) \
)
board_config_mk := \
$(strip $(sort $(wildcard \
$(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk \
$(shell test -d device && find -L device -maxdepth 4 -path '*/$(TARGET_DEVICE)/BoardConfig.mk') \
$(shell test -d vendor && find -L vendor -maxdepth 4 -path '*/$(TARGET_DEVICE)/BoardConfig.mk') \
)))
# Read in all of the product definitions specified by the AndroidProducts.mk
# files in the tree.
all_product_configs := $(get-all-product-makefiles) 產品Makefie文件列表
define get-all-product-makefiles
$(call get-product-makefiles,$(_find-android-products-files))
endef
current_product_makefile 當前指定的產品所加載的Makefile文件列表
$(call import-products, $(current_product_makefile)) Import just the current product makefile
經過import-products後 全部變量都變成PRODUCTS.build/target/product/xxx.mk.PRODUCT_PACKAGE這種
所以要用下面這種格式過濾product_MODULES := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES) 要安裝的模塊名稱列表
product_FILES := $(call module-installed-files, $(product_MODULES)) module-installed-files來獲得要安裝的模塊所對應的文件,也就是要安裝的模塊經過編譯之後生成的文件,這些文件就保存在變量product_FILES中
INTERNAL_PRODUCT := $(call resolve-short-product-name, $(TARGET_PRODUCT)) 調用函數resolve-short-product-name解析環境變量TARGET_PRODUCT的值,將它變成一個Makefile文件路徑。並且保存在變量INTERNAL_PRODUCT中
TARGET_PRODUCT: lunch帶進來的
TARGET_DEVICE := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEVICE) 找到一個名稱爲PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEVICE的變量,並且將它的值保存另外一個變量TARGET_DEVICE中 用來描述當前指定的產品的名稱。
ALL_DEFAULT_INSTALLED_MODULES := $(modules_to_install)
include $(BUILD_SYSTEM)/Makefile 追加ALL_DEFAULT_INSTALLED_MODULES變量
modules_to_install := $(sort $(ALL_DEFAULT_INSTALLED_MODULES)) 追加後再賦值回modules_to_install
files: $(modules_to_install) \
$(INSTALLED_ANDROID_INFO_TXT_TARGET)
systemimage: $(INSTALLED_SYSTEMIMAGE)
$(INSTALLED_SYSTEMIMAGE): $(BUILT_SYSTEMIMAGE) $(RECOVERY_FROM_BOOT_PATCH)
@echo "Install system fs image: $@"
$(copy-file-to-target)
$(hide) $(call assert-max-image-size,$@ $(RECOVERY_FROM_BOOT_PATCH),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))
$(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE) $(BUILD_IMAGE_SRCS)
$(call build-systemimage-target,$@)
FULL_SYSTEMIMAGE_DEPS := $(INTERNAL_SYSTEMIMAGE_FILES) $(INTERNAL_USERIMAGES_DEPS)
INTERNAL_SYSTEMIMAGE_FILES := $(filter $(TARGET_OUT)/%, \
$(ALL_GENERATED_SOURCES) \
$(ALL_DEFAULT_INSTALLED_MODULES) \
$(PDK_FUSION_SYSIMG_FILES) \
$(RECOVERY_RESOURCE_ZIP)) \
$(PDK_FUSION_SYMLINK_STAMP)
要編譯的文件主要是由 filter $(TARGET_OUT)/% 從$(ALL_DEFAULT_INSTALLED_MODULES) \裏面過濾出來
例如userdata的
INTERNAL_USERDATAIMAGE_FILES := \
$(filter $(TARGET_OUT_DATA)/%,$(ALL_DEFAULT_INSTALLED_MODULES))
ALL_DEFAULT_INSTALLED_MODULES已經包含了對應產品的所有模塊
build-systemimage-target
build/make/tools/releasetools/build_image.py 主要根據system文件目錄,輸出名字等參數生成system.img
$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(AVBTOOL) $(INTERNAL_BOOTIMAGE_FILES) $(BOARD_AVB_BOOT_KEY_PATH)
$(call pretty,"Target boot image: $@")
$(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@
$(hide) $(call assert-max-image-size,$@,$(call get-hash-image-max-size,$(BOARD_BOOTIMAGE_PARTITION_SIZE)))
$(hide) $(AVBTOOL) add_hash_footer \
--image $@ \
--partition_size $(BOARD_BOOTIMAGE_PARTITION_SIZE) \
--partition_name boot $(INTERNAL_AVB_BOOT_SIGNING_ARGS) \
$(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS)