Build Layers描述的是产品的硬件配置情况,据此make时选择不同的配置和模块。按照从上到下的顺序,Build Layer分成4层。
Layer sample Note
Arch arm, x86 处理器的种类
Board - 板子类型的代号
Device - device配置的类型代号
Product - 具体产品的代号
以calculator为例,app代码可以放到packages/apps/目录下边,一个app对应一个目录,此例,pakcages/apps/Calculator/。Android.mk,已去除多余的注释行。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_JAVA_LIBRARIES := libarity
LOCAL_SRC_FILES := $(call all-Java-files-under, src)
LOCAL_SDK_VERSION := current
LOCAL_PACKAGE_NAME := Calculator
include $(BUILD_PACKAGE)
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := libarity:arity-2.1.2.jar
include $(BUILD_MULTI_PREBUILT)
# Use the folloing include to make our test apk.
include $(call all-makefiles-under,$(LOCAL_PATH))
至少有一个子目录,src下放源码。
android.mk中需要赋值的几个LOCAL_XXX变量
LOCAL_PATH
,调用my-dir
(在defination.mk中定义),得到当前路径,即,
LOCAL_MODULE_TAGS
,取值范围debug eng tests optional samples shell_ash shell_mksh
,注意不能取值user
,如果要预装,则应定义core.mk。
LOCAL_SRC_FILES
,app的所有源码,如果是java源码的话,可以调用all-java-files-under
得到。
LOCAL_PACKAGE_NAME
,package的名字,这个名字在脚本中将标识这个app或package。
$(CLEAR_VARS)
指的是clear_vars.mk,脚本会清空所有LOCAL_xxx的变量,不影响后面这些变量的使用。
$(BUILD_PACKAGE)
指的是package.mk
最后一句all-makefiles-under将会 包含 当前目录下 所有的mk脚本 文件。
说明:
必须定义, 在app或package的Android.mk中必须给定值。
可选定义,在app或package的Android.mk中可以也可以不给定值。
不用定义,在app或package的Android.mk中不要给定值,脚本自动指定值。
LOCAL_PATH
, 当前路径,必须定义
。
LOCAL_PACKAGE_NAME
, 必须定义,package的名字,这个名字在脚本中将标识app或package。
LOCAL_MODULE_SUFFIX
, 不用定义,module的后缀,=.apk。
LOCAL_MODULE
, 不用定义,=$(LOCAL_PACKAGE_NAME)。
LOCAL_JAVA_RESOURCE_DIRS
, 不用定义。
LOCAL_JAVA_RESOURCE_FILES
, 不用定义。
LOCAL_MODULE_CLASS
, 不用定义。
LOCAL_MODULE_TAGS
, 可选定义。默认optional。取值范围user debug eng tests optional samples shell_ash shell_mksh
LOCAL_ASSET_DIR
, 可选定义,推荐不定义。默认$(LOCAL_PATH)/assets
LOCAL_RESOURCE_DIR
, 可选定义,推荐不定义。默认product package和device package相应的res路径和$(LOCAL_PATH)/res。
LOCAL_PROGUARD_ENABLED
, 可选定义,默认为full,如果是user或userdebug。取值full, disabled, custom, full_android_manifest
, 不用定义
=$(LOCAL_PATH)/AndroidManifest.xml。
LOCAL_EXPORT_PACKAGE_RESOURCES
, 可选定义,默认null。如果允许app的资源被其它模块使用,则设置true。
LOCAL_CERTIFICATE
, 可选定义,默认为testkey。最终
private_key := $(LOCAL_CERTIFICATE).pk8
certificate := $(LOCAL_CERTIFICATE).x509.pem
以Calculator为例,
由LOCAL_PATH
,LOCAL_PACKAGE_NAME
导出变量LOCAL_MODULE
,all_assets
,all_resources
。
设置LOCAL_MODULE_CLASS=APPS
,此值local-intermediates-dir
会用到。
设置中间生成目录路径,中间路径将放置R.stamp文件。
package_expected_intermediates_COMMON := $(call local-intermediates-dir,COMMON)
这里COMMON
是null,而LOCAL_MODULE_CLASS=APPS
,所以
package_expected_intermediates_COMMON=out/target/common/obj/$(LOCAL_MODULE_CLASS)/$(LOCAL_MODULE)_intermediates
即
package_expected_intermediates_COMMON=out/target/common/obj/APPS/Calculator_intermediates
设置
LOCAL_BUILT_MODULE_STEM := package.apk
而
LOCAL_BUILT_MODULE := $(built_module_path)/$(LOCAL_BUILT_MODULE_STEM) @base_rules.mk
built_module_path := $(intermediates) @base_rules.mk
intermediates := $(call local-intermediates-dir) @java.mk
最终
LOCAL_BUILT_MODULE=out/target/product/<PRODUCT>/obj/$(LOCAL_MODULE_CLASS)/$(LOCAL_MODULE)_intermediates/$(LOCAL_BUILT_MODULE_STEM)
即
LOCAL_BUILT_MODULE=out/target/product/generic/obj/APPS/Calculator_intermediates/package.apk
由LOCAL_CERTIFICATE
导出
private_key := $(SRC_TARGET_DIR)/product/security/$(LOCAL_CERTIFICATE).pk8
certificate := $(SRC_TARGET_DIR)/product/security/$(LOCAL_CERTIFICATE).x509.pem
LOCAL_CERTIFICATE默认为testkey。
PACKAGES.$(LOCAL_PACKAGE_NAME).PRIVATE_KEY := $(private_key)
PACKAGES.$(LOCAL_PACKAGE_NAME).CERTIFICATE := $(certificate)
PACKAGES.$(LOCAL_PACKAGE_NAME).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))
PACKAGES.$(LOCAL_PACKAGE_NAME).RESOURCE_FILES := $(all_resources)
PACKAGES := $(PACKAGES) $(LOCAL_PACKAGE_NAME)
全编译时,PACKAGES变量将会记录遍历到的packages。
选取APPS场景,以Calculator为例说明。
LOCAL_JAVA_LIBRARIES=true
时,Android.mk中不能定义LOCAL_SDK_VERSION
。
当LOCAL_SDK_VERSION=current
时,LOCAL_JAVA_LIBRARIES=android_stubs_current
。
package.mk中定义LOCAL_BUILT_MODULE_STEM=package.apk
。
两个中间目录的路径,即对应的obj目录下
APPS/_intermediates/。
intermediates=out/target/product/generic/obj/APPS/Calculator_intermediates
intermediates.COMMON=out/target/common/obj/APPS/Calculator_intermediates
LOCAL_INTERMEDIATE_TARGETS
先前package.mk中已经定义了R.stamp,java.mk有增添了7个。
LOCAL_INTERMEDIATE_TARGETS += \
$(full_classes_jar) \
$(full_classes_compiled_jar) \
$(full_classes_emma_jar) \
$(full_classes_full_names_jar) \
$(full_classes_stubs_jar) \
$(full_classes_jarjar_jar) \
$(built_dex)
此例中,具体值是
LOCAL_INTERMEDIATE_TARGETS=
out/target/common/obj/APPS/Calculator_intermediates/src/R.stamp @defined in package.mk
out/target/common/obj/APPS/Calculator_intermediates/classes.jar @full_classes_jar
out/target/common/obj/APPS/Calculator_intermediates/classes-full-debug.jar @full_classes_compiled_jar
out/target/common/obj/APPS/Calculator_intermediates/emma_out/lib/classes-full-debug.jar @full_classes_emma_jar
out/target/common/obj/APPS/Calculator_intermediates/classes-full-names.jar @full_classes_full_names_jar
out/target/common/obj/APPS/Calculator_intermediates/stubs.jar @full_classes_stubs_jar
out/target/common/obj/APPS/Calculator_intermediates/classes-jarjar.jar @full_classes_jarjar_jar
out/target/common/obj/APPS/Calculator_intermediates/classes.dex @built_dex
java.mk随后include base_rules.mk
后面处理了EMMA,PROGUARD在enable/disable情况下的动作
最后定义的target, $(LOCAL_MODULE)-findbugs
因为prebuilt/common下还没有findbugs,目前不可用。
java.mk还定义了几个特别的变量,
ALL_MODULES.$(LOCAL_MODULE).PROGUARD_ENABLED:=$(LOCAL_PROGUARD_ENABLED)
ALL_MODULES.$(LOCAL_MODULE).CHECKED := $(full_classes_compiled_jar)
ALL_MODULES.$(LOCAL_MODULE).STUBS := $(full_classes_stubs_jar)
续1的场景。
提取变量
my_prefix:=TARGET_LOCAL_MODULE_TAGS
在Android.mk或package.mk中已经设定,默认是optional。
确认LOCAL_MODULE_PATH
,默认$($(my_prefix)OUT$(use_data)_$(LOCAL_MODULE_CLASS))
,此例中是out/target/product/generic/system/app
设定module_id := MODULE.$(TARGET).$(LOCAL_MODULE_CLASS).$(LOCAL_MODULE)
,此例MODULE.TARGET.APPS.Calculator。
设定中间目录路径intermediates,intermediates.COMMON,参见1.
设定LOCAL_MODULE_STEM=$(LOCAL_MODULE)
,此例,Calculator。LOCAL_INSTALLED_MODULE_STEM=Calculator.apk。
LOCAL_INTERMEDIATE_TARGETS
追加上package.apk,参见1.
处理aidl,转为java,放在intermediates.COMMON下的目录中。
处理logtag,转为java,放在intermediates.COMMON下的目录中。
确定java_sources,这包括android.mk中包含的,aidl和logtag生成的。
处理java_resource_files
处理了Java lib相关
定义clean-$(LOCAL_MODULE) target
, 可以删除app/package的生成文件,包括
$(PRIVATE_CLEAN_FILES),$(LOCAL_BUILT_MODULE),$(LOCAL_INSTALLED_MODULE),$(intermediates),$(intermediates.COMMON)
还定义了$(LOCAL_MODULE) target,
几个变量的值
LOCAL_MODULE=Calculator
LOCAL_BUILT_MODULE=out/target/product/generic/obj/APPS/Calculator_intermediates/package.apk
LOCAL_INSTALLED_MODULE=out/target/product/generic/system/app/Calculator.apk
最后定义了几个ALL_MODULES
变量。
ALL_MODULES.$(LOCAL_MODULE).CLASS
ALL_MODULES.$(LOCAL_MODULE).PATH
ALL_MODULES.$(LOCAL_MODULE).TAGS
ALL_MODULES.$(LOCAL_MODULE).CHECKED
ALL_MODULES.$(LOCAL_MODULE).BUILT
ALL_MODULES.$(LOCAL_MODULE).INSTALLED
ALL_MODULES.$(LOCAL_MODULE).REQUIRED
ALL_MODULES.$(LOCAL_MODULE).EVENT_LOG_TAGS
续1的场景。
mulit_prebuilt.mk顾名思义就是多次调用prebuilt.mk,对几种明确的prebuilt library完成需要的copy操作。
multi_prebuilt.mk定义了命令auto-prebuilt-boilerplate。入口有6个参数
# $(1): file list, ":"
# $(2): IS_HOST_MODULE
# $(3): MODULE_CLASS
# $(4): OVERRIDE_BUILT_MODULE_PATH
# $(5): UNINSTALLABLE_MODULE
# $(6): BUILT_MODULE_STEM
根据这6个参数,命令确定
LOCAL_IS_HOST_MODULE
LOCAL_MODULE_CLASS
OVERRIDE_BUILT_MODULE_PATH
LOCAL_UNINSTALLABLE_MODULE
LOCAL_MODULE
LOCAL_SRC_FILES
LOCAL_BUILT_MODULE_STEM
LOCAL_MODULE_SUFFIX
并调用prebuilt.mk
multi_prebuilt.mk中分别对下面5中lib调用了auto-prebuilt-boilerplate
。
prebuilt_static_libs := $(filter %.a,$(LOCAL_PREBUILT_LIBS))
prebuilt_shared_libs := $(filter-out %.a,$(LOCAL_PREBUILT_LIBS))
prebuilt_executables := $(LOCAL_PREBUILT_EXECUTABLES)
prebuilt_java_libraries := $(LOCAL_PREBUILT_JAVA_LIBRARIES)
prebuilt_static_java_libraries := $(LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES)
续1的场景。
首先,include base_rules.mk
定义
PACKAGES.$(LOCAL_MODULE).OVERRIDES
第二步,如果是APPS类型,则zipalign,并拷贝到中间路径$(intermediates)
。不是APPS,则不做zipalign。
本例是JAVA_LIBRARY
类型,目的路径out/target/common/obj/JAVA_LIBRARIES/libarity_intermediates/javalib.jar
,注意其中的libarity和javalib.jar。
最后检查 signed情况。
1.检查版本号,设置环境变量(BUILD_SYSTEM)和 缺省的目标BUILD_SYSTEM= build/core
2.包含文件BUILD_SYSTEM/config.mk。根据配置信息和主机目标机信息,设置一些变量。
3.包含文件BUILD_SYSTEM/cleanbuild.mk。如果当前配置改变,强制删除上次的编译结果
4.包含文件OUT_DIR/version_check.mk
。就设置了VERSIONS_CHECKED
。如果版本序号改变,即VERSION_CHECK_SEQUENCE_NUMBER!=VERSIONS_CHECKED
,检查文件系统是否大小写不敏感。文件路径上是否没有空格。JAVA,JAVAC的版本是否是1.6。
5.包含文件BUILD_SYSTEM/definitions.mk
。定义了很多函数供makefile文件系统使用。
主要的是transform-xxx-to-xxx
的形式,比如transform-cpp-to-o
。并定义了一个make目标dist,额外的拷贝一些重要的文件到目标文件夹。
6.检查MAKECMDGOALS
和TARGE_BUILD_VARIANT
.根据MAKECMDGOALS
设置标量is_sdk_build
,是否编译SDK。
7.根据TARGE_BUILD_VARIANT
,设置
tags_to_install,ADDITIONAL_DEFAULT_PROPERTIES
TARGE_BUILD_VARIANT tags_to_install ADDITIONAL_DEFAULT_PROPERTIES
user user ro.secure=1 ro.allow.mock.location=0
eng user debug eng ro.setupwizard.mode=OPTIONAL
tests user debug eng
sdk user debug eng xmpp.auto-presence=true ro.config.nocheckin=yes
user debug user debug ro.sercure=1 dalvik.vm.lockprof.threshold=500
ro.allow.mock.location=0
ro.debuggable=1 persist.service.adb=1
8.检查PARDUCT_TAG
是否包含dalvik.gc.type-precise
,如果包含设置ADDITIONAL_DEFAULT_PROPERTIES+=dalvik.vm.dexopt-flags=m=y
9.判断PRODUCT_COPY_FILES。为空就安装apns-conf.xml文件
PRODUCT_COPY_FILE=development/data/etc/apns-conf_sdk.xml:system/etc/apns-conf.xml
如果TARGE_BUILD_VARIANT
包含eng,tests
但不包含sdk
,且vendor/google/etc/apns-conf.xml
文件存在,则PRODUCT_COPY_FILE=vendor/google/etc/apns-conf.xml:system/etc/apns-conf.xml
ADDITIONAL_BUILD_PROPERTIES+= net.bt.name=Android
dalvik.vm.stack-trace-file=/data/anr/traces.txt
11.如果MAKECMDGOALS
仅包含showcommands
或checkbuild
,设置make目标为DEFAULT_GOALS
12.如果MAKECMDGOALS
不包含clean,clobber,dataclean,installclean
,根据不同的主机平台和处理器品平台,包含进要编译的模块,设置subdirs
。
13.通过build/tools/findleaves.py
,把subdirs
目录下的Android.mk存在subdirs_makefiles。并包含这些文件。如果使用mm命令,只包含当前目录下的Android.mk。
14.若是全部编译,包含frameworks/policies/base/PolicyConfig.mk
。生成android.policy模块,并定义了自己的make删除操作policy_installclean
。
15.根据tags_to_install
和is_sdk_build
,设置哪些模块需要安装,并存入modules_to_install
.
这里主要有两个函数要说明一下:
get-tagged-modules $1 $2
这两个参数一般都是ALL_MODULE_TAGS=debug eng gnuoptional samples testsuser
里面的值,取得$1
中不包括$2
的列表,比如tests user
,返回$(ALL_MODULE_TAGS.user)$(ALL_MODULE_TAGS.tests)
即带有user
或tests
标记模块的目标文件路径列表。
Module-installed-files $1 $1
一般的是一个短的模块名,比如framework
,Browers
,返回这个模块的目标文件路径
16.包含:$(BUILD_SYSTEM)/Makefile
。主要是定义了一些伪目标。
17.定义modules_to_check,文件路径列表,若模块没有定义LOCAL_DONT_CHECK_MODULE,会把生成目标的规则加入到这个变量,以便在modules_to_install后检查目标是否生成成功,目标不存在的话再次生成目标。
18.定义一些make target
target 说明
.PHONY:checkbuilt
checkbuilt: $(modules-to-check)
生成没有定义LOCAL_DONT_CHECK_MODULE的模块并拷贝到系统目录
.PHONY:prebuilt
prebuit: $(ALL_PREBUILT)
拷贝预遍野的文件(比如用include prebuild.mk编译的)到系统目录
.PHONY: files
files: prebuilt checkbuilt moduls-to-install $(INSTALLED_ANDROID_INFO_TXT_TARGET)
生成所有目标文件(包括:prebuile,modules-to-install,modules-to-check,INSTALLED_ANDROID_INFO_TXT_TARGET)并拷贝到系统目录。INSTALLED_ANDROID_INFO_TXT_TARGET在build/target/board/Android.mk定义=out/target/product/**/android-info.txt
.PHONY: ramdisk
ramdisk: $(INSTALL_RAMDISK_TARGET)
生成ramdisk.img
$(HOST_OUT_EXECUTABLES)/mkbootfs $(PRODUCT_OUT)/root|$(HOST_OUT_EXECUTABLES)/minizip > $(PRODUCT_OUT)/ramdisk.img
.PHONY: systemimage
systemimage: $(INSTALL_SYSTEMIMAGE)
生成system.img
$(INSTALLED_SYSTEMIMAGE): $(BUILT_SYSTEMIMAGE)
$(HOST_OUT_EXECUTABLES)/mkyaffs2image$(PRODUCT_OUT)/system$(PRODUCT_OUT)/obj/PACKING/systemimage_unopt_intermediates/system.img
cp **/system.img (PRODUCT_OUT)/system.img
.PHONY: userdataimage
userdataimage:$(INSTALL_USERDATAIMAGE_TARGET)
生成data.img
$(HOST_OUT_EXECUTABLES)/mkyaffs2image $(PRODUCT_OUT)/data $(PRODUCT_OUT)/data.img
.PHONY: bootimage
bootimage: $(INSTALL_BOOTIMAGE_TARGET)
生成boot.img
if(TARGET_NO_KERNEL=true), INSTALL_BOOTIMAGE_TARGET=$(PRODUCT_OUT)/boot.img else $(PRODUCT_OUT)/boot.img=.
参数:
INTERNAL_BOOTIMAGE_ARGS := \
$(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) \
--kernel $(INSTALLED_KERNEL_TARGET) \
--ramdisk $(INSTALLED_RAMDISK_TARGET)
$(HOST_OUT_EXECUTABLES)/mkbootimg --kernel $(PRODUCT_OUT)/kernel –ramdisk $(PRODUCT_OUT)/ramdisk.img >$(PRODUCT_OUT)/boot.img
.PHONY: recoveryimage
recoveryimage:$(INSTALL_RECOVERYIMAGE_TARGET)
生成ramdisk-recovery.img recovery.img
目录$(PRODUCT_OUT)
rm -rf recovery
mkdir -p recovery
mkdir -p recovery/root
mkdir -p recovery/root/etc
mkdir -p recovery/root/tmp
cp -R root recovery/root
cp -f /bootable/recovery/init.rc recovery/root/
cp -f obj/EXECUTABLES/recovery_intermediates/recovery recovery/root/sbin/
cp -rf /bootable/recovery/res recovery/root/
$(foreach item,/build/target/product/**/recovery/res
cp -rf $(item) recovery/root/)
cp /obj/PACKAGING/ota_keys_ intermediates/keys recovery/res/keys
cat root/default.prop system/build.prop > recovery/root/default.prop
$(HOST_OUT_EXECUTABLES)/mkbootfs$(PRODUCT_OUT)/recovery/root|$(HOST_OUT_EXECUTABLES)/minizip > $(PRODUCT_OUT)/ramdisk-recovery.img
$(HOST_OUT_EXECUTABLES)/mkbootimg --kernel $(PRODUCT_OUT)/kernel –ramdisk$(PRODUCT_OUT)/ramdisk-recovery.img > $(PRODUCT_OUT)/recovery.img
.PHONY: droidcore
droidcore: files \
systemimage \
$(INSTALLED_BOOTIMAGE_TARGET) \
$(INSTALLED_RECOVERYIMAGE_TARGET) \
$(INSTALLED_USERDATAIMAGE_TARGET) \
$(INSTALLED_FILES_FILE)
生成整个系统
system.img ramdisk.img/boot.img ramdisk-recovery.img recovery.img userdata.img installed-files.txt
.PHONY: apps_only
生成TARGET_BUILD_APPS指定的APPS模块.
若TARGET_BUILD_APPS包含all就编译全部APPS模块
droid
默认target。
ifneq ($(TARGET_BUILD_APPS),)
droid: apps_only
else
droid:droidcore
.PHONY: sdk
生成sdk
.PHONY: clean
.PHONY: clobber
删除生成文件
.PHONY: modules
显示所有模块名
.PHONY: showcommands
显示命令
首先,包含pathmap.mk, 其次,定义了一些变量,例如通用的编译参数,package的后缀名等。
随后包含buildspec.mk。
接着包含envsetup.mk。
然后包含$(board_config_mk)
。$(board_config_mk)
是位于build/target/board /$(TARGET_DEVICE)/
,device/*/$(TARGET_DEVICE)/
,或vendor/*/$(TARGET_DEVICE) /
目录下的BoardConfig.mk文件。
2.包含文件$(BUILD_SYSTEM)/pathmap.mk
,定义了一些短名到长路径名的影射,
存放在pathmap_INCL
,通过include-path-for $1
根据短名获取到长路径名FRAMEWORKS_BASE_JAVA_SRC_DIRS
保存了所有要编进Android.jar的framework/base
下的文件路径。
3.设置编译目标,.jar,.bin,.so,.a,.apk,…。以BUILD_开头,指向具体的mk文件。比如BUILD_STATIC_LIBRARY:= $(BUILD_SYSTEM)/static_library.mk
4.设置一般编译选项和不同类型的文件后缀名。以COMMON_
开头。COMMON_GLOBAL_CFLAGS,COMMON_RELEASE_CFLAGS。COMMON_PACKAGE_SUFFIX:=.zip
5.包含include$(TOPDIR)buildspec.mk
。设置一些主要的变量,比如目标产品名称。这些都要我们在make之前设置。这个文件有个模版是build/buildspec.mk.default。
6.包含include$(BUILD_SYSTEM)/envsetup.mk
。设置一些跟product相关的变量。
7.包含$(board_config_mk)
,在build/target/board/$(TARGET_DEVICE)/BroadConfig.mk
,device/*/$(TARGET_DEVICE)/BroadConfig.mk
, veror/*/$(TARGET_DEVICE)/BroadConfig.mk
这三个路径下,查找product的目标设备的BroadConfig.mk文件。并包含进来。BroadConfig.mk设置了每个设备的自己的一些变量值,来区别编译时的行为。TARGET_CPU_ABI
必须要设置。这些设备是被product.mk中 TARGET_DEVICE
指定,一个设备信息可以被很多个product使用。
8.设置combo_target := HOST_
,包含include $(BUILD_SYSTEM)/combo/select.mk。
根据操作系统和CPU类型设置以HOST_开头的变量,并包含include$(BUILD_SYSTEM)/combo/HOST_$(HOST_OS)_$(HOST_ARCH).mk
,其中HOST_OS
是主机操作系统,HOST_ARCH
是主机CPU类型,比如HOST_linux_x86.mk
.在这个文件里修改以HOST_开头的变量,主要是向HOST_GLOBAL_CFLAGS
添加标志。
combo_target := TARGET_
,包含include $(BUILD_SYSTEM)/combo/select.mk
。根据操作系统和CPU类型设置以TARGET_
开头的变量,并包含include$(BUILD_SYSTEM)/combo/TARGET_$(TARGET_OS)_$(TARGET_ARCH).mk
,其中TARGET_OS
是目标操作系统,TARGET_ARCH
是目标CPU类型,比如TARGET_linux_arm.mk
.在这个文件里修改以TARGET_开头的变量,主要是设置交叉编译工具和参数和基本的系统头文件。定义了transform-o-to-shared-lib-inner,transform-o-to-executable-inner,transform-o-to-static-executable-inner三个函数,把.o文件分别转化成共享库文件,可执行文件,静态库文件。
include$(BUILD_SYSTEM)/combo/javac.mk
。得到一个JAVAC编译器CUSTOM_JAVA_COMPILER
COMMON_JAVAC
eclipse
=java -Xmx256m -jar prebuilt/common/ecj/ecj.jar -5 \ -maxProblems 9999999 -nowarn
openjdk
= prebuilt/common/openjdk/bin/javac -target 1.5 \ -Xmaxerrs 9999999
others
Windows: = development/host/windows/prebuilt/javawrap.exe -J-Xmx256m \ -target 1.5 -Xmaxerrs 9999999
Other:=javac -J-Xmx512M -target 1.5 -Xmaxerrs 9999999
11.检查BUILD_ENV_SEQUENCE_NUMBER
,这个是在前面的buildspec.mk设置或者通过envsetup.sh脚本设置。
12.设置主机通用工具变量。其中一些是主机自带的
LEX:= flex
YACC:=bison -d DOXYGEN:= doxygen
,还有一些是在/out/target/$($(HOST_OS)-$(HOST_ARCH))/bin
下的程序,MKBOOTIMG:=$(HOST_OUT_EXECUTABLES)/mkbootimg。
HOST_GLOBAL_CFLAGS, HOST_RELEASE_CFLAGS, HOST_GLOBAL_CPPFLAGS,
HOST_RELEASE_CPPFLAGS, TARGET_GLOBAL_CFLAGS, TARGET_RELEASE_CFLAGS,
TARGET_GLOBAL_CPPFLAGS,TARGET_RELEASE_CPPFLAGS, HOST_GLOBAL_LD_DIRS,
TARGET_GLOBAL_LD_DIRS, HOST_PROJECT_INCLUDES, TARGET_PROJECT_INCLUDES,
TARGET_AVAILABLE_SDK_VERSIONS
和TARGET_AVAILABLE_NDK_VERSIONS
include$(BUILD_SYSTEM)/version_defaults.mk
,设置那些我们需要设置的变量的缺省值。这个文件我们不因该改动,改动应该在build_id.mk里。PLATFORM_VERSION
2.2.1
PLATFORM_SDK_VERSION
8
PLATFORM_VERSION_CODENAME
REL
DEFAULT_APP_TARGET_SDK
PLATFORM_SDK_VERSION
BUILD_ID
MASTER
BUILD_NUMBER
eng.$(USER).$(date)
TARGET_PRODUCT
generic(TARGET_SIMULATOR := false)
sim(TARGET_SIMULATOR:=false)
TARGET_BUILD_VARIANT
eng
HOST_OS
windows/Linux/darwin
HOST_ARCH
x86/ppc
HOST_BUILD_TYPE
release
TARGET_OS
linux
TARGET_ARCH
arm
TARGET_BUILD_TYPE
release
3.包含:include$(BUILD_SYSTEM)/product_config.mk
。定义了两种MAKECMDGOALS
参数形式,根据product和device目录下的mk文件生成相应的PRODUCTS_xxx_xxx
和DEVICES_xxx_xxx
变量。中间的是文件的路径,后面的是文件里定义的变量。
4.设置一些列路径变量。主机路径以HOST_OUT_*
或HOST_*_OUT_*
形式,目标机路径以TARGET_OUT_*
或TARGET_*_OUT_*
形式。
5.根据MAKECMDGOALS
,若其中包含dumpvar-%
或dumpvar-abs-%
,就生成一个以dumpvar-%
或dumpvar-abs-%
命名的make目标。实现是打印出%所表示的变量的值。这个变量必须要在这之前已经定义了,后一种在前面还打印出当前的路径。这两种情况必须要先设置CALLED_FROM_SETUP=true
。envsetup.sh的get_build_var
和get_abs_build_var(
)函数就是运用的这个原理打印变量的值。
view plain
# Get the exact value of a buildvariable.
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=trueBUILD_SYSTEM=build/core \
make--no-print-directory -C "$T" -f build/core/config.mk dumpvar-$1
}
# Get the value of a build variable asan absolute path.
function get_abs_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=trueBUILD_SYSTEM=build/core \
make --no-print-directory -C "$T"-f build/core/config.mk dumpvar-abs-$1
}
makePRODUCT-<prodname>-<goal>
TARGET_PRODUCT := prodname TARGET_BUILD_VARIANT := goal
make APP-<appnames>
TARGET_BUILD_APPS := appnames
include$(BUILD_SYSTEM)/node_fns.mk
include $(BUILD_SYSTEM)/product.mk
include $(BUILD_SYSTEM)/device.mk
这三个文件主要是定义了一些函数来相互调用或供product_config.mk文件调用
函数名
说明
node_fns.mk Import- nodes $(1) $(2) $(3)
import-nodes
需要3个入口参数:
$(1)
是一个字串,是输出变量的主干名。例如PRODUCTS
和DEVICES
。
$(2)是一个makefile
文件列表,这些文件中应该含有对$(3)
中变量的定义。
$(3)
是一个变量列表。
import- nodes
会创建这样形式的变量,以$(1)="PRODUCTS",$(2)中含有
“build/target/product/core.mk”,
$(3)中含有
“PRODUCT_NAME”,而且core.mk中定义了
PRODUCT_NAME:=core`为例,
PRODUCT.build/target/product/core.mk.PRODUCT_NAME:=core
import-nodes中还考虑了inherit的问题,如果某个PRODUCT.xxx.xxx变量的值中有@inherit:
标识后面跟的是mk文件名,则会把那个mk文件中相应的变量的属性添加到PRODUCT.xxx.xxx
中。@inherit:
是inherit-product
命令添加的。这个函数在product.mk。
product.mk
_find-android-products-files
得到device/和vendor/, 包括子目录,以及build/target/product/下的AndroidProducts.mk文件列表
product.mk
get-all-product-makefiles
得到所有AndroidProducts.mk文件中 PRODUCT_MAKEFILES变量定义的mk文件列表
product.mk
import-products
调用import-nodes(node_fns.mk),设置$1=PRODUCTS,
设置$3=$(_product_var_list)
,_product_var_list
是以PRODUCT_
开头的变量名。
product.mk
inherit-product
将在所有的PRODUCT_xxx
变量值后缀加上@inherit:
product.mk
check-all-products
检查PRODUCT_NAME,PRODUCT_BRAND,PRODUCT_COPY_FILES
定义的是否正确
product.mk
resolve-short-product-name
根据product的名字,得到定义它的mk文件路径
(resolve-short-product-name generic → /build/target/product/generic.mk)
device.mk
import-devices
调用import-nodes(node_fns.mk)
,设置$1=DEVICES,
设置$3=$(_device_var_list),_device_var_list
是以DEVICE_
开头的变量名。
device.mk
inherit-device
将在所有的DEVICE_变量值后缀加上’@inherit:
device.mk
resolve-short-device-name
根据device的名字,得到定义它的mk文件路径
TARGET_BUILD_APPS
是否为空,若为空,只导入$(SRC_TARGET_DIR)/product/AndroidProducts.mk
里的mk文件。否则调用get-all-product-makefiles
,导入全部mk文件。再调用check-all-products检查变量设置的正确性。
TARGET_PRODUCT
,通过调用resolve-short-product-name
得到mk文件,结果存放在INTERNAL_PRODUCT
变量里。再将PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_xxx
的值赋值给PRODUCT_xxx。ADDITIONAL_BUILD_PROPERTIES
追加PRODUCT_PROPERTY_OVERRIDES
。这些PRODUCT_
变量都在product
下的mk文件里定义。如下:TARGET_DEVICE,PRODUCT_LOCALES ,PRODUCT_BRAND, PRODUCT_MODEL, PRODUCT_MANUFACTURER, PRODUCT_DEFAULT_WIFI_CHANNELS, PRODUCT_POLICY,PRODUCT_COPY_FILES, PRODUCT_PROPERTY_OVERRIDES, PRODUCT_PACKAGE_OVERLAYS, DEVICE_PACKAGE_OVERLAYS, PRODUCT_TAGS,PRODUCT_OTA_PUBLIC_KEYS
add-clean-step
函数。有一个入口参数$(1)
,执行删除操作的具体shell命令。 add-clean-step
应当在%/cleanspec.mk
脚本中使用,命令会为$(1)
定义一个变量保存,变量的名字是INTERNAL_STEP.$(_acs_id)
,所有的$(_acs_id)保存在INTERNAL_STEPS
中。$(_acs_id)
的值分成3个部分构造: 第二部分是$(INTERNAL_CLEAN_BUILD_VERSION)
,默认是4。
第三部分是有’@’组成,cleanspec.mk中的第几个add- clean-step就用几个@。
例如,packages/apps/Camera/cleanspec.mk
中定义了两个删除动作
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/Camera*)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/Camera*)
那么,对应的生成变量有:
INTERNAL_STEP.packages_apps_Camera_CleanSpec-mk_acs4@:= rm -rf $(PRODUCT_OUT)/obj/APPS/Camera*
INTERNAL_STEP.packages_apps_Camera_CleanSpec-mk_acs4@@ := rm -rf$(OUT_DIR)/target/common/obj/APPS/Camera*
INTERNAL_CLEAN_STEPS+=packages_apps_Camera_CleanSpec-mk_acs4@:
INTERNAL_CLEAN_STEPS+packages_apps_Camera_CleanSpec-mk_acs4@@:
2.包含:$(BUILD_SYSTEM)/cleanspec.mk
。设置INTERNAL_CLEAN_BUILD_VERSION :=3
,并通过add-clean-step
函数,加进一些默认的删除操作,在通过build/tools/findleaves.py
枚举所有的CleanSpec.mk
文件,并把它们包含进来。在这些文件里根据具体的模块加删除操作。
3.包含:$(PRODUCT_OUT)/clean_steps.mk
。这个文件是自动生成的,设置CURRENT_CLEAN_BUILD_VERSION:=INTERNAL_CLEAN_BUILD_VERSION
4.比较CURRENT_CLEAN_BUILD_VERSION
和INTERNAL_CLEAN_BUILD_VERSION
若相等执行INTERNAL_CLEAN_STEPS
里的命令,否则表示我们修改过cleanspec.mk, 删除整个$(OUT_DIR)
。
5.包含:$(PRODUCT_OUT)/previous_build_config.mk
。这个文件也是自动生成的,查看PREVIOUS_BUILD_CONFIG
是否于当前的编译选项一致。不相同就强制删除中间文件,并将当前的编译选项写入文件。删除的文件是由installclean_files,dataclean_files
定义。PREVIOUS_BUILD_CONFIG
的格式是$(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)$(building_sdk)-{$(locale_list)}
。
6.定义两个make目标installclean
和dataclean
。分别用来删除安装文件和数据文件。
1.生成一些记录文件
(1).生成$(OUT_DOCS)/index.html
文件,将frameworks/base/docs/docs-redirect-index.html
文件内容拷贝进去。
(2).生成$(TARGET_ROOT_OUT)/default.prop
文件,将ADDITIONAL_DEFAULT_PROPERTIES
的值写入文件。生成$(TARGET_OUT)/build.prop
文件,主要存放的是build.properties,
主要来自于三个方面:
1,通过执行build/tools/buildinfo.sh
根据PRODUCT_NAME
变量值…获得
2.文件$(TARGET_DEVICE_DIR)/system.prop
3.ADDITIONAL_BUILD_PROPERTIES
变量值
(3).生成文件$(PRODUCT_OUT)/sdk/sdk-build.prop
,拷贝$(TARGET_OUT)/build.prop
内容,并修改sdk_build_prop_remove
定义的属性列表值都为generic
。
(4).生成文件$(PRODUCT_OUT)/module-info.txt
,列出全部模块的信息,需声明CREATE_MODULE_INFO_FILE
。
2.定义一些make target
3.包含$(BUILD_SYSTEM)/tasks
目录下的所有.mk文件。
pathmap.mk 中定义了一个列表pathmap_INCL
,列表中每项是”短名:路径”对。命令include-path-for
使用这个pathmap_INCL
列表,输入短名,得到路径。你可以在这个列表中添加自己的对。使用$(call include-path-for, <短名>)
就可以得到路径。
另外,定义了FRAMEWORKS_BASE_JAVA_SRC_DIRS
,含有frameworks/base目录下含java文件的所有目录。
buildspec.mk是用户应当配置的脚本文件,模板可以使用build/buildspec.mk.default
,放到$(TOP)
下。
在 buildspec.mk
中,用户应该配置好主要的参数,例如 TARGET_PRODUCT
,TARGET_BUILD_VARIANT
,CUSTOM_MODULES
, TARGET_SIMULATOR
,TARGET_BUILD_TYPE
,CUSTOM_LOCALES
, 和BUILD_ENV_SEQUENCE_NUMBER
等。
如果不使用buildspec.mk配置参数,也可以使用环境变量的形式。若不配置参数,那么android会使用默认的参数。
首先包含进version_defaults.mk
,定义好一些版本相关的变量。参见version_defaults.mk
。
定义CORRECT_BUILD_ENV_SEQUENCE_NUMBER
,这个数字用于buildspec.mk更新时的提醒,应该同buildspec.mk中的或环境变量中的BUILD_ENV_SEQUENCE_NUMBER
相等。一般不用关注。
随后检查TARGET_PRODUCT
,若为空,则置generic。TARGET_PRODUCT
应当在buildspec.mk
或环境变量中已经定义好。
再检查TARGET_BUILD_VARIANT
,若为空,则置eng。TARGET_BUILD_VARIANT
应当在buildspec.mk或环境变量中已经定义好。
然后包含进product_config.mk。
接着,检查$(TARGET_BUILD_VARIANT)
,取值范围是eng user userdebug tests。
随后判定
HOST_OS(linux),HOST_ARCH(x86)
接着,确定TARGET_ARCH
和TARGET_OS
,若没有定义,则取默认值。
TARGET_ARCH := arm
TARGET_OS := linux
接着,确定TARGET_BUILD_TYPE
,若没有定义,则取默认值。
TARGET_BUILD_TYPE := release
接着,确定OUT_DIR
。OUT_DIR
是存放中间文件和最终结果的地方。若没有定义,则取默认值。
OUT_DIR := $(TOPDIR)out
随后,定义了一些列的路径变量
DEBUG_OUT_DIR,TARGET_OUT_ROOT_release,TARGET_OUT_ROOT_debug,TARGET_OUT_ROOT,BUILD_OUT,PRODUCT_OUT,TARGET_COMMON_OUT_ROOT,等等
。
version_defaults.mk是检查一些跟版本相关的变量是否定义,如果未定义,则使用默认值。这些变量包括
PLATFORM_VERSION,默认AOSP
PLATFORM_SDK_VERSION,默认8
PLATFORM_VERSION_CODENAME,默认AOSP
DEFAULT_APP_TARGET_SDK,默认AOSP
BUILD_ID,默认UNKNOWN
BUILD_NUMBER,默认eng.$(USER).$(shell date +%Y%m%d.%H%M%S)的形式。
version_defaults.mk首先包含进build_id.mk。用户应当配置build_id.mk,而不应该改动version_defaults.mk文件。
然后检查上述变量,如未定义则赋值默认值。
用户可以在build_id.mk中定义这样几个参数,
PLATFORM_VERSION
PLATFORM_SDK_VERSION
PLATFORM_VERSION_CODENAME
DEFAULT_APP_TARGET_SDK
BUILD_ID
BUILD_NUMBER
这些参数最终将出现build.prop
中。
Froyo
的build_id.mk
中定义了2个变量,
BUILD_ID
,通常用于说明分支branch的,默认的是OPENMASTER
,用户应该配置这个参数。
DISPLAY_BUILD_NUMBER
,在TARGET_BUILD_VARIANT=user
的版本中,build.prop
中是ro.build.id
是显示成$(BUILD_ID).$(BUILD_NUMBER)
,还是显示成$(BUILD_ID)
形式。设成true,则显示前者。
make PRODUCT-<prodname>-<goal> <other>
如果使用上述形式的make命令,那么将等同于
TARGET_PRODUCT:=
TARGET_BUILD_VARIANT:=
goal_name:=PRODUCT--
MAKECMDGOALS:=droid
.PHONY: $(goal_name)
$(goal_name): $(MAKECMDGOALS)
endif
注意,goal
的取值范围是user userdebug eng tests
,如果不属于上述范围,则将算入MAKECMDGOALS
中,此时, TARGET_BUILD_VARIANT := eng
。例如
make PRODUCT-dream-installclean
等同于
TARGET_PRODUCT=dream make installclean
使用make PRODUCT-
这种形式,可以方便的指定TARGET_PRODUCT
,和TARGET_BUILD_VARIANT。
make APP-<appname> <other>
如果使用上述形式的make命令,那么将等同于
TARGET_BUILD_APPS:=
unbundled_goals:=APP-
MAKECMDGOALS:=droid
.PHONY: $(unbundled_goals)
$(unbundled_goals): $(MAKECMDGOALS)
使用make APP-
这种形式,可以方便的指定TARGET_BUILD_APPS。
注意,PRODUCT-
和APP-
可以一块使用。
处理完PRODUCT-
和APP-
,product_config.mk会包含下面3个文件
node_fns.mk
product.mk
device.mk
上面的3个mk文件定义了一些命令,用于搜寻product, device对应的目录,生成相应的PRODUCT.XXX
,和DEVICE.XXX
变量。
接着,使用$(call import-products, $(get-all-product-makefiles))
遍历Prodcut相关的AndroidProducts.mk文件,读入PRODCUTS.xxx
变量。可以去掉文件中下面两句话的注释符,查看。
#$(dump-products)
#$(error done)
随后,使用PRODCUT.xxx
和TARGET_PRODUCT
,得到INTERNAL_PRODUCT
信息,即指定product
的路径。
再由INTERNAL_PRODUCT
得到TARGET_DEVICE, PRODUCT_LOCALES, PRODUCT_BRAND, PRODUCT_MODEL, PRODUCT_MANUFACTURER, PRODUCT_DEFAULT_WIFI_CHANNELS, PRODUCT_POLICY, PRODUCT_COPY_FILES, PRODUCT_PROPERTY_OVERRIDES, PRODUCT_PACKAGE_OVERLAYS, DEVICE_PACKAGE_OVERLAYS, PRODUCT_TAGS, PRODUCT_OTA_PUBLIC_KEYS。
由PRODUCT_LOCALES
导出PRODUCT_AAPT_CONFIG
。
ADDITIONAL_BUILD_PROPERTIES
中追加PRODUCT_PROPERTY_OVERRIDES
中的值。
上面所说的这些值,实际上都是在product的mk文件中定义。
定义了一些命令。这些命令在product.mk,device.mk,和product_config.mk中会使用。这里重点说明import-nodes。
import-nodes需要3个入口参数:
$(1)
是一个字串,是输出变量的主干名。例如”PRODUCTS”和”DEVICES“。
$(2)
是一个makefile文件列表,这些文件中应该含有对$(3)
中变量的定义。
$(3)
是一个变量列表。
import- nodes会创建这样形式的变量,以$(1)="PRODUCTS"
, $(2)
中含有”build/target/product/core.mk
“, $(3)
中含有”PRODUCT_NAME
“, 而且core.mk中定义了PRODUCT_NAME:=core
为例,
PRODUCT.build/target/product/core.mk.PRODUCT_NAME:=core
import- nodes中还考虑了inherit的问题,如果某个PRODUCTS.XXX
变量的值中有文件>’标识后面跟着 mk文件名的字串,则会把那个mk文件中相应的变量的属性添加到PRODUCTS.XXX
中。文件>’是 inherit-product命令添加的。参见product.mk。
在product_config.mk中会说明$(2)中的mk文件列表是AndroidProducts.mk中的PRODUCT_MAKEFILES定义的。
node_fns.mk的代码真的很杀伤脑细胞…
product.mk构造了一些命令,供product_config.mk中使用。
_find-android-products-files
这个命令会得到device/和vendor/, 包括子目录,以及build/target/product/下的AndroidProducts.mk文件列表。
get-all-product-makefiles
这个命令会得到所有$(_find-android-products-files)
的AndroidProducts.mk文件中PRODUCT_MAKEFILES
变量定义的mk文件。
_product_var_list
对应的是import-nodes命令的$(3)
, 定义了会生成那些PRODUCT属性名的变量。这些变量实际也是在product的mk文件中要考虑定义的。
_product_var_list := \
PRODUCT_NAME \
PRODUCT_MODEL \
PRODUCT_LOCALES \
PRODUCT_PACKAGES \
PRODUCT_DEVICE \
PRODUCT_MANUFACTURER \
PRODUCT_BRAND \
PRODUCT_PROPERTY_OVERRIDES \
PRODUCT_COPY_FILES \
PRODUCT_OTA_PUBLIC_KEYS \
PRODUCT_POLICY \
PRODUCT_PACKAGE_OVERLAYS \
DEVICE_PACKAGE_OVERLAYS \
PRODUCT_CONTRIBUTORS_FILE \
PRODUCT_TAGS \
PRODUCT_SDK_ADDON_NAME \
PRODUCT_SDK_ADDON_COPY_FILES \
PRODUCT_SDK_ADDON_COPY_MODULES \
PRODUCT_SDK_ADDON_DOC_MODULE \
PRODUCT_DEFAULT_WIFI_CHANNELS
import-products会调用import-nodes。product_config.mk中用到。
define import-products
$(call import-nodes,PRODUCTS,$(1),$(_product_var_list))
endef
inherit-product命令则将在所有的PRODUCT.xxx变量值中后缀上文件>’,当import-nodes处理时,会替换成继承的属性。
check-all-products命令借助$(PRODUCTS)
诸变量,会对product进行唯一性检查和PRODUCT_NAME
,PRODUCT_BRAND
,PRODCUT_COPY_FILES
的简单检查。
resolve-short-product-name
命令,给定Product
的短名,返回对应mk的路径。
同product.mk类似,device.mk构造了一些命令。有resolve-short-device-name,和import-devices。
首先,包含pathmap.mk, 其次,定义了一些变量,例如通用的编译参数,package的后缀名等。
随后包含buildspec.mk。
接着包含envsetup.mk。envsetup.mk中会遍历所有product相关的路径,载入所有支持的product的信息到变量集 PRODUCT..中,一个product对应一个。最后根据TARGET_PRODUCT的值,定义各种跟product相关的变量,包括 TARGET_DEVICE变量。
然后包含$(board_config_mk)
。$(board_config_mk)
是位于 build/target/board/$(TARGET_DEVICE)/,device/*/$(TARGET_DEVICE)/
,或vendor /*/$(TARGET_DEVICE)/
目录下的BoardConfig.mk文件。 $(TARGET_DEVICE)
已经在product_config.mk中定义了。在包含$(board_config_mk)
之前,会做检查,多个$(board_config_mk)
存在则报错。
定义TARGET_DEVICE_DIR
,TARGET_BOOTLOADER_BOARD_NAME
,TARGET_CPU_ABI
等跟board相关的变量。
接着,依次以HOST_和TARGET_条件包含select.mk。这里说明TARGET_的select.mk。先定义combo_os_arch,通常是linux-arm,然后定义各种跟编译链接相关的一些变量,最后再包含进build/core/combo/TARGET_linux- arm.mk。
再包含javac.mk,定义javac的命令和通用参数。
随后,定义一些变量,指向通用工具,其中一些是os提供的,例如YACC;一些是froyo编译生成,放在out/host/linux-x86/bin/下,一些是预定义的脚本和工具,例如MKTARBALL。
最后定义了一些编译链接变量,这里专门列出,
HOST_GLOBAL_CFLAGS += $(COMMON_GLOBAL_CFLAGS)
HOST_RELEASE_CFLAGS += $(COMMON_RELEASE_CFLAGS)
HOST_GLOBAL_CPPFLAGS += $(COMMON_GLOBAL_CPPFLAGS)
HOST_RELEASE_CPPFLAGS += $(COMMON_RELEASE_CPPFLAGS)
TARGET_GLOBAL_CFLAGS += $(COMMON_GLOBAL_CFLAGS)
TARGET_RELEASE_CFLAGS += $(COMMON_RELEASE_CFLAGS)
TARGET_GLOBAL_CPPFLAGS += $(COMMON_GLOBAL_CPPFLAGS)
TARGET_RELEASE_CPPFLAGS += $(COMMON_RELEASE_CPPFLAGS)
HOST_GLOBAL_LD_DIRS += -L$(HOST_OUT_INTERMEDIATE_LIBRARIES)
TARGET_GLOBAL_LD_DIRS += -L$(TARGET_OUT_INTERMEDIATE_LIBRARIES)
HOST_PROJECT_INCLUDES:= $(SRC_HEADERS) $(SRC_HOST_HEADERS) $(HOST_OUT_HEADERS)
TARGET_PROJECT_INCLUDES:= $(SRC_HEADERS) $(TARGET_OUT_HEADERS)
ifneq ($(TARGET_SIMULATOR),true)
TARGET_GLOBAL_CFLAGS += $(TARGET_ERROR_FLAGS)
TARGET_GLOBAL_CPPFLAGS += $(TARGET_ERROR_FLAGS)
endif
HOST_GLOBAL_CFLAGS += $(HOST_RELEASE_CFLAGS)
HOST_GLOBAL_CPPFLAGS += $(HOST_RELEASE_CPPFLAGS)
TARGET_GLOBAL_CFLAGS += $(TARGET_RELEASE_CFLAGS)
TARGET_GLOBAL_CPPFLAGS += $(TARGET_RELEASE_CPPFLAGS)
其中的TARGET_PROJECT_INCLUDES包含了SRC_HEADERS,添加头文件路径的话,可以改动SRC_HEADERS。
最后包含进dumpvar.mk
javac.mk中会定义javac的编译命令和通用参数。
CUSTOM_JAVA_COMPILER做为javac.mk的入口参数,可以考虑openjdk,eclipse。不定义时则使用默认的javac。另外定义为openjdk时,因为prebuilt/对应目录下没有相应的工具,所以还不可用。
依次一般忽略定义CUSTOM_JAVA_COMPILER,只要直接配置自己编译环境的path,指向使用的javac就可以了。
javac在linux平台的定义是
javac -J-Xmx512M -target 1.5 -Xmaxerrs 9999999
-J-Xmx512M,传递给vm launcher参数-Xmx512M,告知起始空间设定为512M。
-target 1.5,编译的结果适用1.5版本。
-Xmaxerrs 9999999,最大输出的错误数是9999999。
dumpvar.mk 支持两种target: dumpvar-,和dumpvar-abs-。envsetup.sh中的 get_build_var和get_abs_build_var就使用了这些target。
使用方法:假设位于$(TOPDIR)路径,
CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core make -f build/core/config.mk dumpvar-
或
CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core make -f build/core/config.mk dumpvar-abs-<varName>
第一种形式,返回varName的值。第二种形式,返回varName的值,前缀上路径。考虑到android脚本中广泛使用’:=’的变量定义方法,因此,基本上只能显示dumpvar.mk之前定义的变量值。LOCAL_xxxx的变量也不适用。
main.mk在包含了config.mk后,会包含进cleanbuild.mk。
定义了add-clean-step命令。有一个入口参数
$(1)
,执行删除操作的具体shell命令。
一般add-clean-step应当在%/cleanspec.mk脚本中使用,命令会为$(1)
定义一个变量保存,变量的名字是 INTERNAL_STEP.$(_acs_id),所有的$(_acs_id)
保存在INTERNAL_STEPS
中。$(_acs_id)
的值分成3 个部分构造
第一部分是有cleanspec.mk的路径转化而来,用’_’替代’/’,’-‘替代’.’,后缀_acs。第二部分是$(INTERNAL_CLEAN_BUILD_VERSION)
,默认是4,第三部分是有组成,cleanspec.mk中的第几个add- clean-step就用几个@。
例如,packages/apps/Camera/cleanspec.mk中定义了两个删除动作
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/Camera*)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/Camera*)
那么,对应的有
INTERNAL_STEP.packages_apps_Camera_CleanSpec-mk_acs4@ := rm -rf $(PRODUCT_OUT)/obj/APPS/Camera*
INTERNAL_STEP.packages_apps_Camera_CleanSpec-mk_acs4@@ := rm -rf $(OUT_DIR)/target/common/obj/APPS/Camera*
接着,包扩进cleanspec.mk
包含进$(PRODUCT_OUT)/clean_steps.mk
,
接下来,检查CURRENT_CLEAN_BUILD_VERSION
是否与INTERNAL_CLEAN_BUILD_VERSION
相同,默认是4
如果相同,
执行所有在INTERNAL_STEPS
中登记的删除操作。
否则,
删除 $(OUT_DIR)
然后,重新生成$(PRODUCT_OUT)/clean_steps.mk
,写入
"CURRENT_CLEAN_BUILD_VERSION := $(INTERNAL_CLEAN_BUILD_VERSION)"和"CURRENT_CLEAN_STEPS := $(INTERNAL_CLEAN_STEPS)"。
随后,读入$(PRODUCT_OUT)/previous_build_config.mk
,看是否与当前的编译选项一致,不一致则标明上次的中间文件不可用,则删除相应的中间目录,或提示用户。接着重新将当前的信息写入$(PRODUCT_OUT)/previous_build_config.mk
,格式是,
current_build_config := \
$(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)$(building_sdk)-{$(locale_list)}
echo "PREVIOUS_BUILD_CONFIG := $(current_build_config)" > \
$(previous_build_config_file)
最后,定义了两个target, installclean和dataclean。
dataclean删除的主要是./$(PRODUCT_OUT)/data/*,
installclean的删除包括dataclean。installclean的本意是用于不同build_type编译时删除前次的中间文件。
总结cleanbuild.mk的内容,就3件事,一是载入所有的CleanSpec.mk,二是检查更新clean_steps.mk和 previous_build_config.mk,避免不同编译间的互相干扰。最后是,定义installclean和dataclean。
首先定义
INTERNAL_CLEAN_BUILD_VERSION := 4
接着使用findleaves.py遍历所有子目录,找到CleanSpec.mk,并包含进。用户可以在CleanSpec.mk中定义自己需要的删除操作。实际上还可以包含不仅仅是删除的操作。
至此,INTERNAL_STEP.XXXX包含了所有CleanSpec.mk定义的clean动作。
main.mk 在cleanbuild.mk后,会借助$(OUT_DIR)/version_checked.mk检查版本,如果版本不一致,则重新检查系统文件系统大小写敏感问题,路径上是否含有空格,java和javac的版本,没有问题,则更新version_checked.mk。
version_checked.mk中就定义了
VERSIONS_CHECKED := $(VERSION_CHECK_SEQUENCE_NUMBER)
checkbuild貌似并未使用。
showcommands必须同其它target一同使用,showcommands会详细打印出执行的具体命令内容。
definations.mk中定义了大量的命令,其它的mk文件将使用。这其中包括执行编译链接的命令,通常是transform-XXX-to-XXX的形式,例如,transform-cpp-to-o。
其中的inherit-package命令有待研究…
首先定义target, 用于生成$(OUT_DOCS)/index.html
再定义target, 用于生成$(TARGET_ROOT_OUT)/default.prop
再定义target, 用于生成$(TARGET_OUT)/build.prop
。build.prop文件记录了一系列属性值。它的内容分成两部分,第一部分是一些关于 product,device,build的一般性属性值,第二部分的属性值源自ADDITIONAL_BUILD_PROPERTIES
。 product配置mk文件中定义的PRODUCT_PROPERTY_OVERRIDES
会加入到 ADDITIONAL_BUILD_PROPERTIES
,建议增加property时,直接修改 PRODUCT_PROPERTY_OVERRIDES
。
再定义target, 用于生成$(PRODUCT_OUT)/sdk/sdk-build.prop
再定义target,package-stats,用于生成$(PRODUCT_OUT)/package-stats.txt
,这个文件包含了.jar,.apk后缀文件的信息。
再定义target,apkcerts-list,用于生成$(name)-apkcerts-$(FILE_NAME_TAG)
,描述各module的certificate和private_key文件信息。
接着,如果定义了CREATE_MODULE_INFO_FILE
,则生成$(PRODUCT_OUT)/module-info.txt
,其中包含了描述所有module的信息。
再定义target,event-log-tags。
接着,处理ramdisk.img
再处理boot.img,如果TARGET_NO_KERNEL
不是true,则将kernel和ramdisk.img组装成boot.img。
接着,定影命令combine-notice-files,用于生成target,notice_files。notice_files会抽取生成相应的声明文件。
随后,建立target,otacert,用于将.x509.pem后缀的认证文件打包存放到$(TARGET_OUT_ETC)/security/otacerts.zip。
接着,建立target,recoveryimage,处理recovery img
还有下面的target,
systemimage-nodeps, snod
systemtarball-nodeps,stnod
boottarball-nodeps,btnod
userdataimage-nodeps
userdatatarball-nodeps
otatools
target-files-package
otapackage
installed-file-list
tests-zip-package
dalvikfiles
updatepackage