Chinaunix首页 | 论坛 | 博客
  • 博客访问: 62164
  • 博文数量: 11
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 100
  • 用 户 组: 普通用户
  • 注册时间: 2015-03-24 12:34
文章分类
文章存档

2019年(3)

2018年(8)

我的朋友

分类: LINUX

2018-09-06 22:11:25

本文主要讲解 AOSP 基于Makefile实现配置,AOSP的版本 7.0。

1. 目标: 利用mk实现配置

实现配置的意义在于在AOSP中利用几个特定的makefile实现一个"Product" 的多个"配置"。例如当获取到AOSP的源码后,经过 source build/envsetup.sh; lunch # 便可以选择 "Product"; 例如 aosp_arm64-eng。此处aosp_arm64便是指一个特定的"Product"。这个"Product"具体如何编译便认为是"配置"。

2. 查看配置

在AOSP 的编译系统中,可以通过make dump-products来查看"Product" 的具体"配置"。例如实际的输出可能类似于:

    PRODUCTS.device/sample/products/sample_addon.mk.PRODUCT_NAME := aosp_arm64
    PRODUCTS.device/sample/products/sample_addon.mk.PRODUCT_MODEL
    PRODUCTS.device/sample/products/sample_addon.mk.PRODUCT_DEVICE := generic_arm64
    PRODUCTS.device/sample/products/sample_addon.mk.PRODUCT_PACKAGES := 
    输出的格式为 PRODUCTS."代表一个具体Product 的 Makefile".PRODUCT_XXX := "配置值"


在当前版本中还有一个特殊的目标  "product-graph" 可以输出 pdf文档,但是需要系统安装相应的软件包将dot格式转换为 pdf格式。

另外,在执行 make dump-products或者make product-graph还可以通过makefile配置变量
    ANDROID_DUMP_PRODUCTS := all(dump-products)
;
    ANDROID_RPODUCT-GRAPH := --all(product-graph) ;
来查看当前AOSP中所有的"Product",而不是仅仅查看当前选择的"Product"。

    具体情况:
    load_all_product_makefiles :=

    
ifneq (,$(filter dump-products,$(MAKECMDGOALS)))
        ifeq ($(ANDROID_DUMP_PRODUCTS),all)
            load_all_product_makefiles := true
        endif
    endif

    ifeq ($(load_all_product_makefiles),true)
        # 此处实际代码省略, 会将当前AOSP中所有的"Product"导入
        # Import all product makefiles.
    else
        # 会将当前AOSP中lunch 选择 的"Product"导入
    endif  # Import all or just the current product makefile

    ifneq ($(filter dump-products, $(MAKECMDGOALS)),)
        $(dump-products)  # 此处对已经导入的 "Product" 进行显示输出
        $(error done)  # 此处表示 make 执行到此结束
    endif

如果希望输出全部"Product" 的"配置"信息,可以新建文件或者在已有的makefile : "AOSP/buildspec.mk" 即AOSP顶层目录的buildspec.mk文件中写入
    ANDROID_DUMP_PRODUCTS := all 
"AOSP/buildspec.mk" 在 build/core/config.mk文件中被引入, 且在引入build/core/product_config.mk之前。
(配置涉及到makefile在之后做一个总结,此处只要注意的是变量定义在配置之前)。

3. 配置

3.1 实例 (具体的文件内容可以以 build/target/product 做参考)

    (1) 目录结构: mkidr -p device/liuz/chip/boarddir
    (2)"Product" 说明文件:  device/liuz/chip/AndroidProducts.mk
    (3)"Product" 真实Makefile : /device/liuz/chip/myproduct.mk
    (4)"Product"  "Board"子目录及其说明makefile: /device/liuz/chip/boarddir/BoardConfig.mk
    其中需要注意的boarddir这个特殊目录需要在  " /device/liuz/chip/myproduct.mk" 中用变量
        PRODUCT_DEVICE := boarddir # 来说明
    (5) 当前"Product" (myproduct)引入到 AOSP编译系统的入口SHELL脚本
        /device/liuz/vendorsetup.sh #  此文件的内容 add_lunch_combo myproduct-eng

3.2 配置解析makefile

    (1) 将"product" 引入到AOSP编译系统中:  build/envsetup.sh
    (2) 解析一个AOSP中定义的"Product":
        build/core/config.mk; build/core/envsetup.mk; build/core/product_config.mk;
        build/core/product.mk; build/core/node_fns.mk;
        build/core/dumpvar.mk

3.3 配置解析过程

        AOSP 的编译系统解析一个在AOSP中定义的 "Product",总体上是为一个所谓的"Product"的名称计算出对应一个标准的一系列变量。其中可以通过 make dump-products 来查看有哪些标准的变量。

        AOSP解析配置过程中有1个SHELL数组全局变量 LUNCH_MENU_CHOICES,2个make全局变量: PRODUCTS, ALL_PRODUCTS;
        其中PRODUCTS记录的是所有的"Product"的名称(简称),ALL_PRODUCTS则记录所有的对应的"Product" 的实际Makefile。

(1)向AOSP编译系统中加入"Product": 此功能是由build/envsetup.sh完成
        可以搜索AOSP/build/envsetup.sh中对于"vendorsetup.sh"的定位。
       
        AOSP编译系统搜索到特定目录(device, vendor, product)下特定的vendorsetup.sh并通过source命令加载。

        vendorsetup.sh 一般完成向AOSP中"注册/告知"一个"Product": add_lunch_combo
        这个SHELL函数的作用是向SHELL全局数组变量 LUNCH_MENU_CHOICES加入一个元素(即所谓的"Product")以供编译选择。

(9)当用户make时,通过lunch选择由vendorsetup.sh引入的"Product"
        通过 LUNCH_MENU_CHOICES加入一个元素解析出2个特殊变量
                TARGET_PRODUCT, TARGET_BUILD_VARIANT
        这2个变量在dumpvar或者编译时有意义,配置"Product"时意义不大,因为AOSP会解析当前AOSP中的所有"Product"。

(2)获取/解析"Product" 入口在 build/core/config.mk,中间会使用使用到
        build/core/envsetup.mk;build/core/product_config.mk; build/core/node_fns.mk; build/core/product.mk
        1. 使用find查找出 AndroidProducts.mk :
        参考: get-product-makefiles; get-all-product-makefiles;_find-android-products-files;
        2. 将搜索到的所有AndroidProducts.mk依次导入(即make解析)
                AndroidProducts.mk中定义特殊变量 PRODUCT_MAKEFILES表示"Product"的真实Makefile; 这样所有的AndroidProducts.mk就会引入多个"Product"(单个AndroidProducts.mk也允许定义多个"Product"),这样就形成一个"Product" 列表.
                "什么是Product?" : 一个"Product" 可以认为是一个Makefile, 这个Makefile由AndroidProducts.mk注册。
(3)AOSP编译系统尝试导入所有 "Product"(对应的Makeifle)
        可以参考 resolve-short-product-name; check-all-products; import-products; import-nodes;
        (核心函数import-nodes,利用栈和递归算法实现多个"Product"可以继承,并完成AOSP中所有的"Product"的解析,并记录在全局表 PRODUCTS, ALL_PRODUCTS中,以及特定的格式变量"PRODUCTS.MAKEFILE.PRODUCT_XXX")

        import-products/import-nodes实际上就是读取某个Makefile(此Makefile代表一个"Product"),并就地(make)解析此Makefile中的变量 (变量列表请参考_product_var_list,为AOSP build系统的要求/标准化)。然后将此"Product"(一个简称) 与当前Makefile、_product_var_list表中要求的变量列表关联。因此:
         "什么是Product?" : 一个"Product" 可以认为是一个Makefile及其标准化的变量列表。

(4) 检查当前AOSP总的"Product"是否合法
                $(check-all-products) # 检测名称是否定义,是否冲突,是否符合规范。

(5)解析 "Product"的中特殊变量(该变量与Board相关)
        INTERNAL_PRODUCT := $(call resolve-short-product-name, $(TARGET_PRODUCT))
        TARGET_DEVICE := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEVICE)
        TARGET_DEVICE_DIR := $(patsubst %/,%,$(dir $(board_config_mk)))

       
(6) 解析 "Product"的Board
        同样的方法查找BoardConfig.mk(board_config_mk表示搜索到的与TARGET_DEVICE紧密关联的特殊文件"BoardConfig.mk", 具体细节参考 build/core/envsetup.mk关于 "BoardConfig.mk"文件查找)。

        以"include $(board_config_mk)"语法就地导入该"BoardConfig.mk"。

(7)检测 TARGET_ARCH (即只要要求在 BoardConfig.mk中需要定义 TARGET_ARCH变量,是否可以在"product" 的Makefile中定义呢?)

          "什么是Board?" :
                  一个"Board" 存在于一个"Product"之上。

                  且这个"Board"必须以"PRODUCT_DEVICE"登记于 "Product"的Makeifle中。
                  一个"Board"代表一个目录(目录名同PRODUCT_DEVICE),且该目录下必须有特殊Makefile : "BoardConfig.mk"

(8)因为AOSP 编译只会编译一个"Product", 因此在多个"Product"共存的AOSP中,通过lunch选择用户需要的编译的"Product":  "TARGET_PRODUCT"

阅读(2810) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:AARCH64 串口调试

给主人留下些什么吧!~~