Android Make脚本的简记(3)

来源:互联网 发布:淘宝网购物车不能加入 编辑:程序博客网 时间:2024/05/04 03:16

1.findleaves.py的分析

main.mk中调用了findleaves.py,得到所有子目录下Android.mk文件的路径。
subdir_makefiles := /
    $(shell build/tools/findleaves.py --prune=out --prune=.repo --prune=.git $(subdirs) Android.mk)
$(subdirs)一般编译中取值$(TOP)

使用方法,
Usage: %(progName)s [<options>] <dirlist> <filename>
Options:
   --mindepth=<mindepth>
       Both behave in the same way as their find(1) equivalents.
   --prune=<dirname>
       Avoids returning results from inside any directory called <dirname>
       (e.g., "*/out/*"). May be used multiple times.

程序首先依次选取dirlist中的目录,然后遍历所有子目录查找Android.mk文件,如果有,则加入到返回列表中。

 

2. pathmap.mk的分析

pathmap.mk 中定义了一个列表pathmap_INCL,列表中每项是"短名:路径"对。命令include-path-for使用这个pathmap_INCL列表,输入短名,得到路径。你可以在这个列表中添加自己的对。使用$(call include-path-for, <短名>)就可以得到路径。
另外,定义了FRAMEWORKS_BASE_JAVA_SRC_DIRS,含有frameworks/base目录下含java文件的所有目录。

 

3. config.mk的分析

首先,包含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文件。

4. buildspec.mk的分析buildspec.mk是用户应当配置的脚本文件,模板可以使用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会使用默认的参数。

5. envsetup.mk的分析


首先包含进version_defaults.mk,定义好一些版本相关的变量。参见version_defaults.mk


定义CORRECT_BUILD_ENV_SEQUENCE_NUMBER,这个数字用于buildspec.mk更新时的提醒,应该同buildspec.mk中的或环境变量中的BUILD_ENV_SEQUENCE_NUMBER相等。一般不用关注。

随后检查TARGET_PRODUCT,若为空,则置genericTARGET_PRODUCT应当在buildspec.mk或环境变量中已经定义好。

再检查TARGET_BUILD_VARIANT,若为空,则置engTARGET_BUILD_VARIANT应当在buildspec.mk或环境变量中已经定义好。

然后包含进product_config.mk

接着,检查$(TARGET_BUILD_VARIANT),取值范围是eng user userdebug tests

随后判定HOST_OS(linux)HOST_ARCH(x86)

接着,确定TARGET_ARCHTARGET_OS,若没有定义,则取默认值。
TARGET_ARCH := arm
TARGET_OS := linux

接着,确定TARGET_BUILD_TYPE,若没有定义,则取默认值。
TARGET_BUILD_TYPE := release

接着,确定OUT_DIROUT_DIR是存放中间文件和最终结果的地方。若没有定义,则取默认值。
OUT_DIR := $(TOPDIR)out

随后,定义了一些列的路径变量
DEBUG_OUT_DIRTARGET_OUT_ROOT_releaseTARGET_OUT_ROOT_debugTARGET_OUT_ROOTBUILD_OUTPRODUCT_OUTTARGET_COMMON_OUT_ROOT,等等。

6. version_defaults.mk的分析


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文件。
然后检查上述变量,如未定义则赋值默认值。

7. build_id.mk的分析


用户可以在build_id.mk中定义这样几个参数,
PLATFORM_VERSION
PLATFORM_SDK_VERSION
PLATFORM_VERSION_CODENAME
DEFAULT_APP_TARGET_SDK
BUILD_ID
BUILD_NUMBER
这些参数最终将出现build.prop中。

Froyobuild_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,则显示前者。

8. product_config.mk的分析


make PRODUCT-<prodname>-<goal>  <other>

如果使用上述形式的make命令,那么将等同于

TARGET_PRODUCT:=<prodname>
TARGET_BUILD_VARIANT:=<goal>
goal_name:=PRODUCT-<prodname>-<goal>
MAKECMDGOALS:=droid <other>

.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-<prodname>-<goal>这种形式,可以方便的指定TARGET_PRODUCT,和TARGET_BUILD_VARIANT

make APP-<appname>  <other>

如果使用上述形式的make命令,那么将等同于
TARGET_BUILD_APPS:=<appname>
unbundled_goals:=APP-<appname>
MAKECMDGOALS:=droid <other>

.PHONY: $(unbundled_goals)
$(unbundled_goals): $(MAKECMDGOALS)

使用make APP-<appname>这种形式,可以方便的指定TARGET_BUILD_APPS

注意,PRODUCT-<prodname>-<goal>APP-<appname>可以一块使用。

处理完PRODUCT-<prodname>-<goal>APP-<appname>product_config.mk会包含下面3个文件
node_fns.mk
product.mk
device.mk

上面的3mk文件定义了一些命令,用于搜寻product, device对应的目录,生成相应的PRODUCT.XXX,DEVICE.XXX变量。

接着,使用$(call import-products, $(get-all-product-makefiles))遍历Prodcut相关的AndroidProducts.mk文件,读入PRODCUTS.xxx变量。可以去掉文件中下面两句话的注释符,查看。
#$(dump-products)
#$(error done)

随后,使用PRODCUT.xxxTARGET_PRODUCT,得到INTERNAL_PRODUCT信息,即指定product的路径。

再由INTERNAL_PRODUCT得到TARGET_DEVICE PRODUCT_LOCALESPRODUCT_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中的值。
上面所说的这些值,实际上都是在productmk文件中定义。

9. node_fns.mk的分析


定义了一些命令。这些命令在product.mkdevice.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变量的值中有‘@inherit:<mk文件>’标识后面跟着 mk文件名的字串,则会把那个mk文件中相应的变量的属性添加到PRODUCTS.XXX中。'@inherit:<mk文件>' inherit-product命令添加的。参见product.mk

product_config.mk中会说明$(2)中的mk文件列表是AndroidProducts.mk中的PRODUCT_MAKEFILES定义的。

node_fns.mk的代码真的很杀伤脑细胞...

10. product.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属性名的变量。这些变量实际也是在productmk文件中要考虑定义的。
_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-nodesproduct_config.mk中用到。
define import-products
$(call import-nodes,PRODUCTS,$(1),$(_product_var_list))
endef

inherit-product命令则将在所有的PRODUCT.xxx变量值中后缀上'@inherit:<mk文件>',当import-nodes处理时,会替换成继承的属性。

check-all-products命令借助$(PRODUCTS)诸变量,会对product进行唯一性检查和PRODUCT_NAME,PRODUCT_BRAND,PRODCUT_COPY_FILES的简单检查。

resolve-short-product-name命令,给定Product的短名,返回对应mk的路径。

11. device.mk的分析


product.mk类似,device.mk构造了一些命令。有resolve-short-device-name,和import-devices

原创粉丝点击