深入浅出Android makefile(3)--LOCAL_SRC_FILES
LOCAL_SRC_FILES := acp.cLOCAL_SRC_FILES变量的意思见名知意,很明显是用来记录当前模块的源文件列表的一个变量。
############################################################# C: Compile .c files to .o.###########################################################c_arm_sources := $(patsubst %.c.arm,%.c,$(filter %.c.arm,$(LOCAL_SRC_FILES)))c_arm_objects := $(addprefix $(intermediates)/,$(c_arm_sources:.c=.o))c_normal_sources := $(filter %.c,$(LOCAL_SRC_FILES))c_normal_objects := $(addprefix $(intermediates)/,$(c_normal_sources:.c=.o))$(c_arm_objects): PRIVATE_ARM_MODE := $(arm_objects_mode)$(c_arm_objects): PRIVATE_ARM_CFLAGS := $(arm_objects_cflags)$(c_normal_objects): PRIVATE_ARM_MODE := $(normal_objects_mode)$(c_normal_objects): PRIVATE_ARM_CFLAGS := $(normal_objects_cflags)c_objects := $(c_arm_objects) $(c_normal_objects)ifneq ($(strip $(c_objects)),)$(c_objects): $(intermediates)/%.o: $(TOPDIR)$(LOCAL_PATH)/%.c $(yacc_cpps) $(proto_generated_headers) $(LOCAL_ADDITIONAL_DEPENDENCIES) $(transform-$(PRIVATE_HOST)c-to-o)-include $(c_objects:%.o=%.P)endif?分析上面的代码,1. 我们首先从LOCAL_SRC_FILES中得到所有的C文件?????c_normal_sources value acp.c2. 定义一个变量,c_normal_objects,用来表示生成的.o文件的路径? ? ?c_normal_objects value out/host/linux-x86/obj/EXECUTABLES/acp_intermediates/acp.o其中,$(c_normal_sources:.c=.o)会返回acp.o,那么c_normal_objects的关键就是$(intermediates)变量
build/core/host_java_library.mk:intermediates := $(call local-intermediates-dir)build/core/base_rules.mk:intermediates := $(call local-intermediates-dir)build/core/dynamic_binary.mk:guessed_intermediates := $(call local-intermediates-dir)build/core/java.mk:intermediates := $(call local-intermediates-dir)即,他们的都是调用local-intermediates-dir函数获取当前的intermediates的值
# Uses LOCAL_MODULE_CLASS, LOCAL_MODULE, and LOCAL_IS_HOST_MODULE# to determine the intermediates directory.## $(1): if non-empty, force the intermediates to be COMMONdefine local-intermediates-dir$(strip \ $(if $(strip $(LOCAL_MODULE_CLASS)),, \ $(error $(LOCAL_PATH): LOCAL_MODULE_CLASS not defined before call to local-intermediates-dir)) \ $(if $(strip $(LOCAL_MODULE)),, \ $(error $(LOCAL_PATH): LOCAL_MODULE not defined before call to local-intermediates-dir)) \ $(call intermediates-dir-for,$(LOCAL_MODULE_CLASS),$(LOCAL_MODULE),$(LOCAL_IS_HOST_MODULE),$(1)) \)endef根据注释,我们知道?local-intermediates-dir的定义会依赖于LOCAL_MODULE_CLASS, LOCAL_MODULE, 和 LOCAL_IS_HOST_MODULE这三个变量的值。
############################################################# The intermediates directory. Where object files go for## a given target. We could technically get away without## the "_intermediates" suffix on the directory, but it's## nice to be able to grep for that string to find out if## anyone's abusing the system.############################################################ $(1): target class, like "APPS"# $(2): target name, like "NotePad"# $(3): if non-empty, this is a HOST target.# $(4): if non-empty, force the intermediates to be COMMONdefine intermediates-dir-for$(strip \ $(eval _idfClass := $(strip $(1))) \ $(if $(_idfClass),, \ $(error $(LOCAL_PATH): Class not defined in call to intermediates-dir-for)) \ $(eval _idfName := $(strip $(2))) \ $(if $(_idfName),, \ $(error $(LOCAL_PATH): Name not defined in call to intermediates-dir-for)) \ $(eval _idfPrefix := $(if $(strip $(3)),HOST,TARGET)) \ $(if $(filter $(_idfPrefix)-$(_idfClass),$(COMMON_MODULE_CLASSES))$(4), \ $(eval _idfIntBase := $($(_idfPrefix)_OUT_COMMON_INTERMEDIATES)) \ , \ $(eval _idfIntBase := $($(_idfPrefix)_OUT_INTERMEDIATES)) \ ) \ $(_idfIntBase)/$(_idfClass)/$(_idfName)_intermediates \)endef根据注释,我们可以知道$(1),$(2),$(3),$(4)这4个参数的意义。而以下三行则是使用$(1),$(2),$(3)来定义三个临时变量:_idfClass,_idfName?和_idfPrefix?$(eval _idfClass := $(strip $(1)))?$(eval _idfName := $(strip $(2)))$(eval _idfPrefix := $(if $(strip $(3)),HOST,TARGET))在本例中这三个临时变量的值则为:EXECUTABLES、acp和HOST
$(eval _idfIntBase := $($(_idfPrefix)_OUT_INTERMEDIATES))
HOST_OUT_INTERMEDIATES := $(HOST_OUT)/obj?HOST_OUT也在本文件中定义:
HOST_OUT := $(HOST_OUT_$(HOST_BUILD_TYPE))?HOST_BUILD_TYPE默认值为release:
# the host build defaults to release, and it must be release or debugifeq ($(HOST_BUILD_TYPE),)HOST_BUILD_TYPE := releaseendif因此,
HOST_OUT := $(HOST_OUT_release)而HOST_OUT_release的定义如下:
HOST_OUT_release := $(HOST_OUT_ROOT_release)/$(HOST_OS)-$(HOST_ARCH)HOST_OUT_ROOT_release的定义:
HOST_OUT_ROOT_release := $(OUT_DIR)/host?在Linux上编译,因此HOST_OS := linux,而我们的机器采用的是Intel Xeon X3440 CPU,即x86架构,因此HOST_ARCH := x86
c_objects := $(c_arm_objects) $(c_normal_objects)ifneq ($(strip $(c_objects)),)$(c_objects): $(intermediates)/%.o: $(TOPDIR)$(LOCAL_PATH)/%.c $(yacc_cpps) $(proto_generated_headers) $(LOCAL_ADDITIONAL_DEPENDENCIES) $(transform-$(PRIVATE_HOST)c-to-o)-include $(c_objects:%.o=%.P)endif其中c_arm_objects为空,c_normal_objects的值为out/host/linux-x86/obj/EXECUTABLES/acp_intermediates/acp.o所以c_objects的值也为out/host/linux-x86/obj/EXECUTABLES/acp_intermediates/acp.o