从运行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等都会经历这个反复的环境初始化过程。

Android系统编译环境初始化时Product产品的import-nodes过程的更多相关文章

  1. Android系统编译环境及连接工具配置

    首先附上官网上关于环境搭建的地址:https://source.android.com/setup/build/initializing 官网目前建议的还是Ubuntu14.04,下面就是用的Ubun ...

  2. Android的编译环境--Build系统【转】

    本文转载自:http://blog.csdn.net/kitty_landon/article/details/60764232 Android是一个庞大的系统,包含太多的模块,各种模块的类型也有10 ...

  3. Android系统编译时遇到的几个.mk的疑惑。

    在Android4.2的源代码Build/prduct_config.mk里面遇到几个疑惑: # Convert a short name like "sooner" into t ...

  4. Mac下设置Android源代码编译环境

    在Mac下编译Android最麻烦的就是设置Android的编译环境了,做完这一步基本上剩下的就是近乎傻瓜式的操作了.说起来也简单就三步,设置大小写敏感的文件系统.安装编译工具.设置文件系统同时能打开 ...

  5. Android 系统编译

    最近研究了下Android 的编译系统,下面结合编译我们自己的产品 mobot 来对整个编译系统进行必要的介绍,方便大家今 后对默认编译的修改. 先列出几个觉得重要的Make 文件: build/bu ...

  6. Android系统编译【转】

    本文转载自;http://blog.csdn.net/zirconsdu/article/details/8005415 Android编译系统分析 概要 由于android编译系统的复杂和使用了不熟 ...

  7. Android系统编译脚本理解

    android源码编译步骤: 1. repo sync 代码(下载代码) 2.start branch(用哪个分支,git相关) 3. 到根目录(android目录) $cd android/ 4. ...

  8. Ubuntu14.04搭建Android O编译环境

    一.搭建环境 官方参考文档: 1.代号.标签和版本号 2.Factory Images 3.Driver Binaries 4.工具链  软硬件版本: 1.系统平台:I5-8500T+8G+1T,Ub ...

  9. H3 android 系统编译

    http://bbs.ickey.cn/group-topic-id-57981.html [Orange Pi PC试用体验]11编译android源码笔记 编译android和编译linux有点类 ...

随机推荐

  1. Android网络框架OkHttp之get请求(源码初识)

    概括 OkHttp现在很火呀.于是上个星期就一直在学习OkHttp框架,虽然说起来已经有点晚上手了,貌似是2013年就推出了.但是现在它版本更加稳定了呀.这不,说着说着,OkHttp3.3版本在这几天 ...

  2. GitHub上常用命令(工作中几乎每天用到的命令)

    查看自己当前分支 git branch 查看远程和本地分支 git branch -a 查看origin下的分支 git config -vv git config --lis 创建分支 git br ...

  3. vue-cli打包项目后,可以修改配置文件

    问题: 前端需要修改后台服务器地址url,写好的配置文件会在npm run build 后压缩在一起,传到运行的前端服务器上后,需要到前端打包的源码,找到url地址进行修改.如果不在打包的源码修改,则 ...

  4. 使用node.js+babel,支持import/export语法

    如果要在node里面支持import/export default语法步骤: 1.使用npm安装 babel的客户端工具 npm init 会生成package.json文件 2.接着安装bebel客 ...

  5. 深度解析VC中的消息

    消息是指什么? 消息系统对于一个win32程序来说十分重要,它是一个程序运行的动力源泉.一个消息,是系统定义的一个32位的值,他唯一的定义了一个事件,向Windows发出一个通知,告诉应用程序某个事情 ...

  6. iOS8: 企业开发的终结?

    iOS 8 的公布(如今是 iOS8.1),并非对全部人来说都是值得高兴的事情. 对那些使用企业部署(不经过商店公布)的 app 开发人员来说,又被苹果坑到了. 由于 iOS 8 的一个Bug.导致企 ...

  7. vuepress折腾记

    由于格式比较乱,所以直接拿图片粘贴过来了,详情请看原文链接https://lewiscutey.github.io/blog/blog/vuepress-theme-toos.html

  8. js匿名函数(变量加括号就是函数)

    js匿名函数(变量加括号就是函数) 一.总结 变量加括号就是函数,而函数的括号是用来传参的 1.类比:以正常函数去想匿名函数,匿名函数比正常函数只是少了函数名,本质还是一样,该怎么传参还是怎么传参,小 ...

  9. 10.4 android输入系统_框架、编写一个万能模拟输入驱动程序、reader/dispatcher线程启动过程源码分析

    1. 输入系统框架 android输入系统官方文档 // 需FQhttp://source.android.com/devices/input/index.html <深入理解Android 卷 ...

  10. lv resize

    # lvreduce -L -400G /dev/vg_atalinux001/lv_home # resize2fs   /dev/vg_atalinux001/lv_home resize2fs ...