Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Android系統編譯環境初始化時Product產品的import-nodes過程

Android系統編譯環境初始化時Product產品的import-nodes過程

編輯:關於android開發

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))

 

在調用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等都會經歷這個重復的環境初始化過程。

 

 


 

 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved