最近编一套代码,支持32位ubuntu系统编译。开始编译出错,停在build/core/main.mk文件的75行,应该不支持我装的64位ubuntu系统,找到出问题的点:
ifneq (i686,$(findstring i686,$(build_arch))) #停在这里
$(warning ************************************************************)
$(warning You are attempting to build on a 32-bit system.)
$(warning Only 64-bit build environments are supported beyond froyo/2.2.)
$(warning ************************************************************)
$(error stop)
endif
将i686改为i386,还是一样,纳闷。再次将i686改为64,没有报错。
再往下,还是有错误,在external/clearsilver/cgi/Android.mk 里,打开这个文件看看,哦,又要修改了。
LOCAL_CFLAGS += -m32改成 LOCAL_CFLAGS += -m64
LOCAL_LDFLAGS += -m32 改成 LOCAL_LDFLAGS += -m64
这里就pass了,下面还有错,还需要将以下三个文件同上述修改 :external/clearsilver/java-jni/Android.mk ,external/clearsilver/util/Android.mk ,external/clearsilver/cs/Android.mk 。这样就OK了。
了解一个系统架构,先了解其makefile文件,hold住编译流程。
Android系统编译后生成的目标文件在out/target/product/generic下,注意:generic是默认的TARGET_PRODUCT。在这里以TARGET_PRODUCT这一条线为目标,看看它是怎么串起来的。
在build/core/envsetup.mk文件里,有关于TARGET_PRODUCT的默认赋值说明。
ifeq ($(TARGET_PRODUCT),)
ifeq ($(TARGET_SIMULATOR),true)
TARGET_PRODUCT := sim
else
TARGET_PRODUCT := generic
endif
endif
流程走向:
顶层makefile-->build/core/main.mk-->build/core/config.mk-->build/core/ envsetup.mk--> build/core/ product_config.mk-->build/core/product.mk
一、 先看product.mk,它通过get-all-product-makefiles函数来遍历整个子目录的,去寻找子目录的AndroidProducts.mk中定义的变量,这些变量如PRODUCT_NAME,PRODUCT_MODEL,PRODUCT_PACKAGES,PRODUCT_DEVICE,PRODUCT_MANUFACTURER等。当然,不同的子目录,这些变量值也不一样。
二、由于product.mk受product_config.mk调用,product.mk完成它的任务后, product_config.mk会对product.mk的变量处理,如:
1.TARGET_DEVICE := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEVICE)
2.
ifndef PRODUCT_MODEL
PRODUCT_MODEL := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_NAME))
Endif
显然,将PRODUCT_DEVICE赋给TARGET_DEVICE。在此,只care TARGET_DEVICE。
三、回到上层调用envsetup.mk,看看TARGET_DEVICE起什么作用?
TARGET_OUT_ROOT_release := $(OUT_DIR)/target
TARGET_OUT_ROOT_debug := $(DEBUG_OUT_DIR)/target
# release,debug是编译类型
TARGET_OUT_ROOT := $(TARGET_OUT_ROOT_$(TARGET_BUILD_TYPE))
TARGET_PRODUCT_OUT_ROOT := $(TARGET_OUT_ROOT)/product
PRODUCT_OUT := $(TARGET_PRODUCT_OUT_ROOT)/$(TARGET_DEVICE)
PRODUCT_OUT,这是目标文件的输出,它由TARGET_DEVICE来决定的。
四、瞧瞧config.mk,TARGET_DEVICE干些什么事?
board_config_mk := \
$(strip $(wildcard \
$(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk \
device/*/$(TARGET_DEVICE)/BoardConfig.mk \
vendor/*/$(TARGET_DEVICE)/BoardConfig.mk \
))
BoardConfig.mk这个配置文件决定目标的编译属性。即确定要编译的板型。
include $(board_config_mk)
TARGET_DEVICE_DIR := $(patsubst %/,%,$(dir $(board_config_mk)))
TARGET_DEVICE_DIR提取BoardConfig.mk的路径。
五、 回到main.mk,首先看看:
#
# Include all of the makefiles in the system
#
# Can't use first-makefiles-under here because
# --mindepth=2 makes the prunes not work.
subdir_makefiles := \
$(shell build/tools/findleaves.py --prune=out --prune=.repo --prune=.git $(subdirs) Android.mk)
include $(subdir_makefiles)
遍历子目录,将所有的子目录的makefiles(即Android.mk)include进来。
接下来:
# The base list of modules to build for this product is specified
# by the appropriate product definition file, which was included
# by product_config.make.
user_PACKAGES := $(call module-installed-files, \ $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES))
ifeq (0,1)
$(info user packages for $(TARGET_DEVICE) ($(INTERNAL_PRODUCT)):)
$(foreach p,$(user_PACKAGES),$(info : $(p)))
$(error done)
Endif
这里根据TARGET_ PRODUCT来选择编译,即编译目标产品里的模块。这里说明,系统根据板型来选择编译,这样更有针对性。
往下看:
.PHONY: ramdisk #这里ramdisk,是编译对象,下同
ramdisk: $(INSTALLED_RAMDISK_TARGET)
.PHONY: systemtarball
systemtarball: $(INSTALLED_SYSTEMTARBALL_TARGET)
.PHONY: userdataimage
userdataimage: $(INSTALLED_USERDATAIMAGE_TARGET)
.PHONY: userdatatarball
userdatatarball: $(INSTALLED_USERDATATARBALL_TARGET)
.PHONY: bootimage
bootimage: $(INSTALLED_BOOTIMAGE_TARGET)
ifeq ($(BUILD_TINY_ANDROID), true)
INSTALLED_RECOVERYIMAGE_TARGET :=
endif
这是编译ramdisk,system,userdataimage,userdatatarball,bootimage,recoveryimage。
# TARGET_BUILD_APPS
$(call dist-for-goals, droidcore, \
$(INTERNAL_UPDATE_PACKAGE_TARGET) \
$(INTERNAL_OTA_PACKAGE_TARGET) \
$(SYMBOLS_ZIP) \
$(APPS_ZIP) \
$(INTERNAL_EMULATOR_PACKAGE_TARGET) \
$(PACKAGE_STATS_FILE) \
$(INSTALLED_FILES_FILE) \
$(INSTALLED_BUILD_PROP_TARGET) \
$(BUILT_TARGET_FILES_PACKAGE) \
$(INSTALLED_ANDROID_INFO_TXT_TARGET) \
$(INSTALLED_RAMDISK_TARGET) \
)
droid: droidcore dist_libraries#这也是编译APPS的对象
这是编译APPS。
有兴趣的话,去build\target\board和build\target\product去逛逛。至此,大概流程over了。