zoukankan      html  css  js  c++  java
  • Android系统编译环境初始化时Product产品的import-nodes过程

    从运行make -f config,mk文件開始,config,mk作为当前的makefile文件。将会被make解析,一般make解析Makefile文件流程首先是载入当中include的各种其它mk文件,同一时候在载入的过程中会初始化自己定义的变量,相似于预编译,在完毕各种初始化后,确定目标以及依赖关系,终于运行目标输出动作。

    在config.mk中存在多个须要include的mk文件。这里关注product相关的envsteup.mk

    在envsteup.mk从又会include product_config.mk。開始提取眼下系统中所配置的product相关型号。

    1. product import入口

    $(call import-products, $(call get-all-product-makefiles))

    能够看到该变量由一个宏定义来实现,位于之前include的product.mk文件里。

     59 define get-all-product-makefiles
     60 $(call get-product-makefiles,$(_find-android-products-files))
     61 endef

    在Makefile文件里可使用define来定义一个函数。亦或者能够理解为一个宏,假设在调用自己定义的函数时须要传入參数。则一般须要使用call函数来间接调用函数名的方式。否则能够直接以函数名的方式来直接调用(一般无该同名变量时。以函数方式处理),如上所述调用get-all-product-makefiles。


    2. get-all-product-makefiles

    get-all-product-makefiles的处理过程也相似,先是调用_find-android-products-files函数,该函数的目的是遍历系统中全部的AndroidProduct.mk文件,并把结果以空格分隔的变量形式作为返回值返回

    30 define _find-android-products-files
     31 $(shell test -d device && find -L device -maxdepth 6 -name AndroidProducts.m
        k) 
     32   $(shell test -d vendor && find vendor -maxdepth 6 -name AndroidProducts.mk
        ) 
     33   $(SRC_TARGET_DIR)/product/AndroidProducts.mk
     34 endef


    3 get-product-makefiles处理AndroidProducts.mk,后者以$(1)作为參数输入

     41 define get-product-makefiles
     42 $(sort 
     43   $(foreach f,$(1), 
     44     $(eval PRODUCT_MAKEFILES :=) 
     45     $(eval LOCAL_DIR := $(patsubst %/,%,$(dir $(f)))) 
     46     $(eval include $(f)) 
     47     $(PRODUCT_MAKEFILES) 
     48    ) 
     49   $(eval PRODUCT_MAKEFILES :=) 
     50   $(eval LOCAL_DIR :=) 
     51  )
     52 endef
     53 
    这个函数大致处理是for循环f即为之前find到的AndroidProduct,mk。也将其作为mk文件include。提取当中带有PRODUCT_MAKEFILES的变量。将每一个AndroidProduct.mk

    提取出的PRODUCT_MAKEFILES作为文件返回。

    终于该函数处理后的返回值结构大致例如以下,能够看到结果大致是定义了Product相关的mk相关于系统顶层文件夹所在的相对路径:

    build/target/product/core.mk 
    build/target/product/full.mk.PRODUCT_NAME := full

    build/target/product/full_x86.mk build/target/product/generic.mk build/target/product/generic_x86.mk build/target/product/large_emu_hw.mk build/target/product/sdk.mk build/target/product/sdk_x86.mk build/target/product/vbox_x86.mk device/asus/grouper/full_grouper.mk device/generic/armv7-a-neon/mini_armv7a_neon.mk device/generic/armv7-a/mini_armv7a.mk device/moto/stingray/full_stingray.mk device/moto/stingray/generic_stingray.mk device/moto/stingray/stingray_emu.mk device/moto/wingray/full_wingray.mk device/sample/products/sample_addon.mk device/samsung/crespo/full_crespo.mk device/samsung/crespo4g/full_crespo4g.mk device/samsung/maguro/full_maguro.mk device/samsung/toro/full_toro.mk device/samsung/tuna/full_tuna.mk device/ti/panda/full_panda.mk

    4.import-products函数

    133 define import-products
    134 $(info ssssssssssssss$(PRODUCTS)!!!!!!!!!!)
    135 $(call import-nodes,PRODUCTS,$(1),$(_product_var_list))
    136 $(info ccccccccccccc$(PRODUCTS)a----------aaa)
    137 endef
    在这里$(1)代表上述3中函数处理的返回值。是一些列带有product定义的mk文件。通过import-nodes对这个返回值进行处理:

    244 $(if 
    245   $(foreach _in,$(2), 
    246     $(eval _node_import_context := _nic.$(1).[[$(_in)]]) 
    247     $(if $(_include_stack),$(eval $(error ASSERTION FAILED: _include_stack 
    248                 should be empty here: $(_include_stack))),) 
    249     $(eval _include_stack := ) 
    250     $(call _import-nodes-inner,$(_node_import_context),$(_in),$(3)) 
    251     $(call move-var-list,$(_node_import_context).$(_in),$(1).$(_in),$(3)) 
    252     $(eval _node_import_context :=) 
    253     $(eval $(1) := $($(1)) $(_in)) 
    254     $(if $(_include_stack),$(eval $(error ASSERTION FAILED: _include_stack 
    255                 should be empty here: $(_include_stack))),) 
    256    ) 
    257 ,)
    258 endef
    该函数的处理较为复杂。但大致的含义是依据每一个mk文件所在路径,找到后将每一个mk文件里定义的变量字段,如:

    PRODUCT_NAME := full
    PRODUCT_DEVICE := generic
    PRODUCT_BRAND := Android
    PRODUCT_MODEL := Full Android on Emulator
    
    经过处理转换为全新的变量,相似例如以下:

    PRODUCT.build/target/product/full.mk.PRODUCT_NAEM := full

    此外另一点须要注意的时。运行完该函数后相关的输入參数$(2)将会返回并保存到一个全新的变量PRODUCTS.

    该变量再兴许进行target product check时,终于确定TARGET_DEVICE时。须要经过例如以下步骤:

    INTERNAL_PRODUCT := $(call resolve-short-product-name, $(TARGET_PRODUCT))

    TARGET_DEVICE := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEVICE)

    在调用resolve-short-product-name(前一博文有说明),会逐一提取这个变量中的mk文件路径并再组成一个变量名

    PRODUCT.build/target/product/full.mk.PRODUCT_NAEM
    例如以下:

    180 define _resolve-short-product-name
    181   $(eval pn := $(strip $(1)))
    182   $(eval p := 
    183       $(foreach p,$(PRODUCTS), 
    184           $(if $(filter $(pn),$(PRODUCTS.$(p).PRODUCT_NAME)), 
    185             $(p) 
    186        )) 
    187    )
    188   $(eval p := $(sort $(p)))
    189   $(if $(filter 1,$(words $(p))), 
    190     $(p), 
    191     $(if $(filter 0,$(words $(p))), 
    192       $(error No matches for product "$(pn)"), 
    193       $(error Product "$(pn)" ambiguous: matches $(p)) 
    194     ) 
    这里传入的pn值即为我们选择的TARGET_PRODUCT。仅仅有在全部的mk中找到PRODUCT_NAME和TARGET_PRODUCT相一致时,我们lunch选择的产品才是合理的,整个系统编译环境的初始化才算正常。为兴许的make/mm打下基础,并确保这是正常的,由于后面make、mm等都会经历这个反复的环境初始化过程。






  • 相关阅读:
    20201112 装饰器之函数即变量
    2月13日:毕业设计进度
    2月12日:毕业设计进度
    2月11日:毕业设计进度
    2月10日:毕业设计进度
    2月9日:毕业设计进度
    2月8日:毕业设计进度
    2月7日:毕业设计进度
    2月6日:毕业设计进度
    2月5日:毕业设计进度
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/7241660.html
Copyright © 2011-2022 走看看