Android101111: Android Make脚本的简记(4)
Email: zcatt@163.com
Blog http://zcatt.cublog.cn
内容提要
文档简要整理Android的make脚本的内容。以供备忘和参考。
声明
仅限学习交流,禁止商业用途。转载需注明出处。
版本记录
Date Ver Note
2010-11-11 0.1 Draft. zcatt@Beijing
1. config.mk的分析
首先,包含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
2. javac.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。
3. dumpvar.mk的分析
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的值,前缀上路径。考虑到android脚本中广泛使用':=’的变量定义方法,因此,基本上只能显示dumpvar.mk之前定义的变量值。LOCAL_xxxx的变量也不适用。
4. cleanbuild.mk的分析
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。
5. cleanspec.mk的分析
首先定义
INTERNAL_CLEAN_BUILD_VERSION := 4
接着使用findleaves.py遍历所有子目录,找到CleanSpec.mk,并包含进。用户可以在CleanSpec.mk中定义自己需要的删除操作。实际上还可以包含不仅仅是删除的操作。
至此,INTERNAL_STEP.XXXX包含了所有CleanSpec.mk定义的clean动作。
6. version_checked.mk的分析
main.mk在cleanbuild.mk后,会借助$(OUT_DIR)/version_checked.mk检查版本,如果版本不一致,则重新检查系统文件系统大小写敏感问题,路径上是否含有空格,java和javac的版本,没有问题,则更新version_checked.mk。
version_checked.mk中就定义了
VERSIONS_CHECKED := $(VERSION_CHECK_SEQUENCE_NUMBER)
7. showcommands和checkbuild的说明
checkbuild貌似并未使用。
showcommands必须同其它target一同使用,showcommands会详细打印出执行的具体命令内容。
8. definations.mk的说明
definations.mk中定义了大量的命令,其它的mk文件将使用。这其中包括执行编译链接的命令,通常是transform-XXX-to-XXX的形式,例如,transform-cpp-to-o。
其中的inherit-package命令有待研究...
阅读(1820) | 评论(0) | 转发(0) |