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

时间: 2024-08-09 10:39:13

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

Android系统编译环境搭建

之前在公司做Android系统开发时,服务器编译环境都是我来配置的,总结了一份文档,文档放着很久了,一来跟大家共享下,二来防止丢失. 1.JDK环境变量配置 将mtkoss.tar.gz上传到/目录,使用命令:#tar –xvzf mtkoss.tar.gz 修改/etc/profile文件,加入环境变量: JAVA_HOME=/mtkoss/jdk/1.6.0_45-ubuntu-10.04/x86_64 JRE_HOME=/mtkoss/jdk/1.6.0_45-ubuntu-10.04/x

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

在Android4.2的源码Build/prduct_config.mk里面遇到几个疑惑: # Convert a short name like "sooner" into the path to the product # file defining that product. # INTERNAL_PRODUCT := $(call resolve-short-product-name, $(TARGET_PRODUCT)) ifneq ($(current_product_ma

嵌入式4412开发平台Android系统开发环境搭建以及编译

本文介绍 uboot.Linux3.0.15 和 linux-3.5 内核.Android4.0.3 和Android4.2.2 编译环境的搭建以及编译. 详情了解:http://topeetboard.com更多了解:https://arm-board.taobao.com Uboot.Kernel 以及 Android 的编译环境看似复杂,用户只要抓住以下几个要点就可以 了: 第一:Uboot.Kernel 编译器.编译器在光盘中都有提供,在需要使用的步骤中,会说 明编译器在光盘中的位置.

Android之编译打包apk时几个常用的技巧

今天和大家分享一下用eclipse打包apk时的三个小技巧: 一.防止被反编译而扰乱混淆加密: 1. 请打开project.properties文件中的这句话(即将这句前面的"#"去掉即可)    proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 2. 然后可以根据自己的需求对proguard-project.txt文件做出"例外"的方法或类的规则定

(2) 搭建 Android 系统开发环境

说干就干,先按 Google 官方的指导,搭建 Android 系统开发环境.页面(需FQ):http://source.android.com/source/initializing.html 安装 ubuntu-14.04 64bit 安装系统有两种方式可选,直接装在物理机上或装在虚拟机中,区别主要就是性能了,本次是安装在虚拟机中的.之前都是装在物理机上的,但是只有一台电脑,而做开发的时候往往还要做些笔记或者其它的事情.总之,在 ubuntu 中完成这些工作并不容易,以前折腾过,也怕了.另外

realarm Android系统编译后内核无法启动的解决方法

由于之前版本使用的内核并非uImage格式,而在编译时使用的是非uImage格式编译,所以照成无法启动. 解决方法是,在编译内核时使用make uImage方式编译. 修改根目录下的build_realv210.sh文件,如下图所示 另外注意上图中CPU_JOB_NUM这个参数,要根据自己的电脑配置来选择,该参数在该文件的起始处设置,可以设置成电脑CPU核心数的2倍,例如:如果核心数为2,那么设置成4即可. 完整脚本下载地址:http://download.csdn.net/detail/u01

Ubuntu14.10上搭建Android应用开发环境和系统编译环境

android应用开发环境搭建 Java JDK安装和配置. Android NDK 下载安装配置. Android ADT 下载安装配置. Android SDK 下载. Android Elicpse安装配置. Android Studio 安装配置. ## Oracle JDK 下载安装配置 ## JDK6下载地址: http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-

Android系统编译与测试

1.Android系统分析 2.下载Android源代码(不包括Linux内核部分) 下载好了的Android_5.01.tar.gz,通过samba复制到ubuntu里,再解压之. 可以看到AndroidSrc/这个文件夹,它存放的就是Android源代码了. 3.编译 a.初始化编译环境,在build目录下面 b.选择编译目标(配置) 配置 这里有好几个小时的时间zzzzzzzzzzzzzzzzzzz c.编译目标输出 4.测试Android系统 a.创建一个模拟器来模拟设备 启动studi

【Android】Ubuntu 16.04搭建Android开发编译环境

一. 通用Android环境和工具配置 1. 系统更新升级 sudo apt-get update sudo apt-get upgrade 2. 配置ntlmaps代理上网环境(本公司网络需要代理) sudo apt-get update sudo apt-get install ntlmaps Parent proxy:cnkusisal Parent proxy port:8080 NT Windows domain:wkscn 以后如果需要重新配置ntlmaps可以用下面命令: sudo