由坑爹的编译想起的

 

    最近编一套代码,支持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了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值