Android学习笔记之编译系统(二)编译框架二

转载请注明出处: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中



不知不觉又很晚了,明天在写笔记吧。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hailushijie

您的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值