转载请注明出处:http://blog.csdn.net/droyon/article/details/8644177
今天6:40在去西二旗地铁的路上,一个哥们背着旅行包,面前铺着一张纸,在向路人求助。
“钱包被偷了,实在太饿了,求助餐费和住宿费,请体谅”
当时于心不忍,可自己多大能力只有自己知道,300、400百块对毕业不久的我不是小数,只能选择默默离开,在这里为你祈福,也为自己的良心救赎。社会通过无数的故事教会了我们行善,可我还是愿意相信好人多。小时候他乡落难之人路过家门口,不管家里怎么样,奶奶都会给俩馒头。在这里同时也祝好人一生平安。
---------------------------------------------------------------------------------------------------------------------------------------
build/core/main.mk继续往下执行,包含dex_preopt.mk文件,Dalvik虚拟机执行的是dex文件,为了最大化Dalvik的性能,根据cpu的性能对dex做优化。
然后检查product的类型的合法性,在然后检查product的PRODUCT_TAGS是否包含dalvik.gc.type-precise,对ADDITIONAL_BUILD_PROPERTIES进行赋值。
ifneq ($(filter dalvik.gc.type-precise,$(PRODUCT_TAGS)),)
# Enabling type-precise GC results in larger optimized DEX files. The
# additional storage requirements for ".odex" files can cause /system
# to overflow on some devices, so this is configured separately for
# each product.
ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.dexopt-flags=m=y
endif
然后检查是否包含pans-conf.xml文件,如果没有使用默认的文件apns-conf.xml
ifeq (,$(filter %:system/etc/apns-conf.xml, $(PRODUCT_COPY_FILES)))
PRODUCT_COPY_FILES += \
development/data/etc/apns-conf_sdk.xml:system/etc/apns-conf.xml
ifeq ($(filter eng tests,$(TARGET_BUILD_VARIANT)),)
$(warning implicitly installing apns-conf_sdk.xml)
endif
endif
apns-conf.xml文件定义了中国移动、中国电信、中国联通的apn信息,到时根据手机的网络模式选择特定的apn进行网络连接。
再往下,定义了sdk一些配置。
这个时候编译系统已经了解了系统中存在的所有的product,那么我们就可以通过make product进行系统编译。再往下执行,通过加载build/tools/findleaves.py脚本产生subdir_makefiles的内容。
subdir_makefiles := \
$(shell build/tools/findleaves.py --prune=out --prune=.repo --prune=.git $(subdirs) Android.mk)
include $(subdir_makefiles)
再往下:如果是全编译模式,那么忽略文件PolicyConfig.mk
ifdef FULL_BUILD
# Only include this during a full build, otherwise we can't be
# guaranteed that any policies were included.
-include frameworks/policies/base/PolicyConfig.mk
endif
include $(BUILD_SYSTEM)/Makefile
最后定义target,并且定义生成的目标。比如boot.img,编译生成boot。img的压缩文件
.PHONY: bootimage
bootimage: $(INSTALLED_BOOTIMAGE_TARGET)
如果编译的是apps,那么
ifneq ($(TARGET_BUILD_APPS),)
# If this build is just for apps, only build apps and not the full system by default.
unbundled_build_modules :=
ifneq ($(filter all,$(TARGET_BUILD_APPS)),)
# If they used the magic goal "all" then build all apps in the source tree.
unbundled_build_modules := $(foreach m,$(sort $(ALL_MODULES)),$(if $(filter APPS,$(ALL_MODULES.$(m).CLASS)),$(m)))
else
unbundled_build_modules := $(TARGET_BUILD_APPS)
endif
# dist the unbundled app.
$(call dist-for-goals,apps_only, \
$(foreach m,$(unbundled_build_modules),$(ALL_MODULES.$(m).INSTALLED)) \
)
.PHONY: apps_only
apps_only: $(unbundled_build_modules)
$(ALL_MODULES)变量很重要,它记载了编译系统能够认识的所有的target。
这就是编译系统的整个过程。
这个时候编译系统已经了解了所有的product以及target子项目,可以通过make、make target、make product 以及make sdk进行编译系统。
1、看书重在解惑,我们可以通过 make target进行编译,比如make Contacts,那么Contacts什么时候被build系统认识的那?
总结:子项目在build系统中叫做target,是在上文中的通过加载findleaves.py脚本执行时,将sub_dirs目录下的所有的Android.mk文件加载并执行,在Android.mk文件中定义了LOCAL_PACKAGE_NAME或者LOCAL_MODULE,他就是我们make的target的名字。
再往下执行,通过加载build/tools/findleaves.py脚本产生subdir_makefiles的内容,并执行subdir_makefiles。
subdir_makefiles := \
$(shell build/tools/findleaves.py --prune=out --prune=.repo --prune=.git $(subdirs) Android.mk)
include $(subdir_makefiles)
上面就是findleaves.py脚本执行的脚本。他会搜索subdirs下的所有的Android.mk文件,subdirs包含那些路径?
subdirs := \
prebuilt \
build/libs/host \
build/tools/zipalign \
dalvik/dexdump \
dalvik/libdex \
dalvik/tools/dmtracedump \
dalvik/tools/hprof-conv \
development/host \
development/tools/etc1tool \
development/tools/line_endings \
development/tools/emulator/opengl \
external/clang \
external/easymock \
external/expat \
external/libpng \
external/llvm \
external/qemu \
external/sqlite/dist \
external/zlib \
frameworks/base \
frameworks/compile \
sdk/avdlauncher \
sdk/emulator/mksdcard \
sdk/sdklauncher \
system/core/adb \
system/core/fastboot \
system/core/libcutils \
system/core/liblog \
system/core/libzipfile
subdirs += \
build/tools/signapk \
dalvik/dx \
libcore \
sdk/archquery \
sdk/androidprefs \
sdk/apkbuilder \
sdk/assetstudio \
sdk/common \
sdk/ddms \
sdk/hierarchyviewer2 \
sdk/ide_common \
sdk/jarutils \
sdk/layoutlib_api \
sdk/layoutopt \
sdk/ninepatch \
sdk/rule_api \
sdk/lint \
sdk/sdkstats \
sdk/sdkmanager \
sdk/swtmenubar \
sdk/traceview \
development/apps \
development/tools/mkstubs \
packages
subdirs := \
bionic \
system/core \
system/extras/ext4_utils \
system/extras/su \
build/libs \
build/target \
build/tools/acp \
external/mksh \
external/yaffs2 \
external/zlib
TOP := .
subdirs := $(TOP)
如上所示,android加载了我们常用的目录,想framework以及package等。同时,Android系统会尽可能的加载所有的Android.mk文件。
加载完Android.mk要进行其中的内容:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := Mms
# Builds against the public SDK
#LOCAL_SDK_VERSION := current
LOCAL_STATIC_JAVA_LIBRARIES += android-common jsr305
LOCAL_REQUIRED_MODULES := SoundRecorder
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
include $(BUILD_PACKAGE)
这是Mms下的Android.mk文件内容,由于要编译成apk,除了复写LOCAL_PACKAGE_NAME以及LOCAL_SRC_FILES等一些命令外,最后调用了BUILD_PACKAGE。关于这个命令,我们在上篇文章中介绍过,他是在config.mk文件中定义的命令宏。
BUILD_PACKAGE:= $(BUILD_SYSTEM)/package.mk
会执行package.mk文件。这个文件会定义一系列的属性,包括给apk进行签名的属性,定义输出路径,有些属性,我们会在Android.mk文件中进行复写。我们在mm某个项目时可以通过mm showcommand命令看到编译apk的全过程,其中就用到了好多这里定义的属性。
ifeq ($(strip $(LOCAL_MANIFEST_FILE)),)
LOCAL_MANIFEST_FILE := AndroidManifest.xml
endif
ifneq ($(strip $(LOCAL_MODULE_CLASS)),)
$(error $(LOCAL_PATH): Package modules may not set LOCAL_MODULE_CLASS)
endif
LOCAL_MODULE_CLASS := APPS
# Package LOCAL_MODULE_TAGS default to optional
LOCAL_MODULE_TAGS := $(strip $(LOCAL_MODULE_TAGS))
ifeq ($(LOCAL_MODULE_TAGS),)
LOCAL_MODULE_TAGS := optional
endif
ifeq ($(filter tests, $(LOCAL_MODULE_TAGS)),)
# Force localization check if it's not tagged as tests.
LOCAL_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS) -z
endif
ifeq (,$(LOCAL_ASSET_DIR))
LOCAL_ASSET_DIR := $(LOCAL_PATH)/assets
endif
ifeq (,$(LOCAL_RESOURCE_DIR))
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
endif
$(R_file_stamp): PRIVATE_RESOURCE_PUBLICS_OUTPUT := \
$(intermediates.COMMON)/public_resources.xml
进行给apk签名的属性
private_key := $(LOCAL_CERTIFICATE).pk8
certificate := $(LOCAL_CERTIFICATE).x509.pem
其中很重要的是会加载java.mk
#################################
include $(BUILD_SYSTEM)/java.mk
#################################
在java.mk文件中:调用java编译环境,也就是javac,java等,将源文件打包成class.jar,同时还会包含base_rules.mk文件
#######################################
include $(BUILD_SYSTEM)/base_rules.mk
#######################################
在base_rules.mk文件中,
###########################################################
## Register with ALL_MODULES
###########################################################
ALL_MODULES += $(LOCAL_MODULE)
这样编译系统就认识了Mms,我们就可以在package/app/Mms/目录下mm或者make Mms。
其实所有的编译命令宏都会执行base_rules.mk文件。这样以来,编译系统就可以知道了工程下所有的要编译的模块。
2、我们编译生成了各种文件,包括system.img,boot.img等,他们如何生成的
总结,在我们执行make命令时,和i产生一些依赖,这些以来和一步一步的包含*.mk文件,以及定义将某目录下的所有文件,打包压缩成xx.imk文件。
我们的输出目录定义,我们在前面也提过,也就是在envstup.mk文件执行时,定义了输出路径。
3、Android在编译项目时可以包含那些apk文件到system.img中,也就是说厂商自带apk如何编译到system.img中
不知不觉又很晚了,明天在写笔记吧。