Android系统新产品定制(1)

<一>配置过程分析:
jackie@jackie-host:~/svn/vimicro$ . ./build/envsetup.sh
including device/vimicro/vortex/vendorsetup.sh
------------------------------------------------------------------
build/envsetup.sh末尾有:
# Execute the contents of any vendorsetup.sh files we can find.

for f in `/bin/ls vendor/*/vendorsetup.sh vendor/*/build/vendorsetup.sh device/*/*/vendorsetup.sh 2> /dev/null`

do   
 echo "including $f"
    . $f

done

unset f
------------------------------------------------------------------
device/vimicro/vortex/vendorsetup.sh:
add_lunch_combo generic_vortex-userdebug

add_lunch_combo full_vortex-userdebug      //添加lunch项目
------------------------------------------------------------------
jackie@jackie-host:~/svn/vimicro$ lunch    //配置lunch

You're building on Linux

Lunch menu... pick a combo:
     1. generic-eng
     2. simulator
     3. generic_vortex-userdebug
     4. full_vortex-userdebug

Which would you like? [generic-eng] 3
-------------------------------------------------------------------
function lunch()
{
  
 local answer    
 if [ "$1" ] ;  then      
   answer=$1   
 else       
    print_lunch_menu
        //打印lunch列表
    echo -n "Which would you like? [generic-eng] "        
    read answer
 ………………
# 将 product-variant模式种的product分离出来
# 将 product-variant模式种的variant分离出来
# 检查之,看看是否在 (user userdebug eng) 范围内
  export TARGET_PRODUCT=$product
  export TARGET_BUILD_VARIANT=$variant
  export TARGET_SIMULATOR=false
  export TARGET_BUILD_TYPE=release
 printconfig
//打印一些主要的变量, 调用关系 printconfig()->get_build_var()->build/core/config.mk->build/core/envsetup.mk

function print_lunch_menu()
{
   
 local uname=$(uname)   
 echo   
 echo "You're building on" $uname   
 echo   
 echo "Lunch menu... pick a combo:"
 local i=1   
 local choice    
 for choice in ${LUNCH_MENU_CHOICES[@]}    
 do        
      echo "     $i. $choice"       
      i=$(($i+1))    
 done    
 echo

}
-------------------------------------------------------------------
在build/core/envsetup.mk最末尾回显:
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=2.3              //envsetup.mk->version_defaults.mk 定义了平台版本
TARGET_PRODUCT=generic_vortex
TARGET_BUILD_VARIANT=userdebug
TARGET_SIMULATOR=false            //envsetup.mk:默认当为false时,TARGET_PRODUCT=generic
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=                //lunch->export TARGET_BUILD_APPS=
TARGET_ARCH=arm                   .
HOST_ARCH=x86                     .
HOST_OS=linux                     .
HOST_BUILD_TYPE=release           .
BUILD_ID=GRH55                    //lunch->...->envsetup.mk有定义
============================================
以上在build/buildspec.mk.default 有默认宏定义

<二>Android编译系统分析:
执行:make -j2
顶层目录下的Makefile:
就只有一行:include build/core/main.mk
固实际是从main.mk开始编译的。
《1》初始化参数设置:
在 main.mk 里,简单设置几个主要编译路径的变量后,来到config.mk :
build/core/main.mk->config.mk
                             ->(0)首先设置了源文件的一系列路径,包括头文件、库文件、服务、API 已经编译工具的路径。
                             例如:SRC_HEADERS := \ ……     SRC_TARGET_DIR := $(TOPDIR)build/target 等。
                             ->(1)读取 buildspec.mk 的设置,在这里我们可以加入自己的目标产品信息:
                             直接编辑build/buildspec.mk.default并移到根目录下; device/vimicro/vortex/buildspec.mk是 一样的。          

                                               ifndef TARGET_PRODUCT
                                               TARGET_PRODUCT:=generic_vortex
                                               endif
《2》读取Product设定:                                                  
                             ->(2)接着进入envsetup.mk:
                                                    ->version_defaults.mk 中具体定义平台版本
                                                    ->product_config.mk:include $(BUILD_SYSTEM)/product.mk
                                                                        get-all-product-makefiles
                                                     product.mk:define get-all-product-makefiles来遍历整个vendor或device 的子目录, 找到vendor或device目录下所有的 AndroidProducts.mk, 不同子目录下的“产品.mk” 中定义了不同的 PRODUCT_NAME, PRODUCT_DEVICE 等信息
---------------------------------------------------------------------
device/vimicro/vortex/AndroidProducts.mk 包含所有具体“产品.mk”文件
PRODUCT_MAKEFILES := \
    $(LOCAL_DIR)/generic_vortex.mk \
    $(LOCAL_DIR)/full_vortex.mk

device/vimicro/vortex/generic_vortex.mk
    $(call inherit-product, device/vimicro/vortex/device_vortex.mk)//device_vortex.mk:PRODUCT_COPY_FILES 批量拷贝!
   
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic.mk)
    PRODUCT_NAME := generic_vortex
    PRODUCT_DEVICE := vortex     //赋值为TARGET_DEVICE
    PRODUCT_LOCALES += hdpi
---------------------------------------------------------------------
接着build/core/product_config.mk 会调用resolve-short-product-name 将TARGET_PRODUCT匹配的“产品.mk” 中定义的 PRODUCT_DEVICE 赋值给TARGET_DEVICE。

《3》读取BoardConfig:
BoardConfig.mk是和目标平台主板相关的设定,例如使用了什么装置、driver 等,或是是否需要编译bootloader 、kernel等,都是在 BoardConfig.mk 里设定。同样,每张主板可以有不同设定,存在不同目录下的。

                             ->(3)读取BoardConfig:129 board_config_mk := \……$(SRC_TARGET_DIR)/board/                                                $(TARGET_DEVICE)/BoardConfig.mk \
 device/*/$(TARGET_DEVICE)/BoardConfig.mk \
                                 这里的TARGET_DEVICE 就是 votex ,就是说为了定义我们自己的产品 votex.                                                 TARGET_DEVICE 宏也决定了TARGET_DEVICE_DIR, 因为TARGET_DEVICE_DIR 取的是上面提到的                                   BoardConfig.mk 的路径。即device/vimicro/vortex/BoardConfig.mk
                                        TARGET_DEVICE_DIR := $(patsubst %/,%,$(dir $(board_config_mk)))
                                 当然Android 的Ob目标输出也是由TARGET_DEVICE决定,见build/core/envsetup.mk。
                                 PRODUCT_OUT := $(TARGET_PRODUCT_OUT_ROOT)/$(TARGET_DEVICE)
《4》读取所有Module:
                             ->(4)读取所以Moudule (definitions.mk )
结束全局变量配置后,回到main.mk ,马上对编译工具及版本进行检查,错误便中断编译。
main.mk 160:include $(BUILD_SYSTEM)/definitions.mk包含文件 definitions.mk 这里面定义了许多变量和函数供main.mk 使用。
编译系统接着做的一个件事情是,遍历所有子目录,找到所有Android.mk文件,并将这些Android.mk文件include 进来
#

# Include all of the makefiles in the system

#
subdir_makefiles := \
 
    $(shell build/tools/findleaves.py --prune=out --prune=.repo --prune=.git $(subdirs) Android.mk)

include $(subdir_makefiles)
我们再来看其中的
./build/target/board/Android.mk
对了它引用了
include $(TARGET_DEVICE_DIR)/AndroidBoard.mk
由上面TARGET_DEVICE_DIR的定义,这下又进入了device目录下TARGET_DEVICE指向的目录了(device/vimicro/vortex/目录),这个mk文件中定义了特定Product需要编译和安装app 和 script.
我们在package/apps 下每个模块根目录都能看到 Android.mk ,里面会去定义当前本地模块的 Tag : LOCAL_MODULE_TAGS ,Android 会通过这个 Tag 来决定哪些本地模块会编译进系统,通过 PRODUCT 和 LOCAL_MODULE_TAGS 来决定哪些应用包会编译进系统。 ( 前面说过,你也能通过buildspec.mk 来制定你要编译进系统的模块 )
最后需要编译的模块路径打包到 ALL_DEFAULT_INSTALLED_MODULES:
《5》生成镜像文件images:                            
                             ->(5)产生相应的rules,生存images:
所有需要配置的准备工作都已完成,下面该决定如何生成image 输出文件了,这一过程实际上在 build/core/Makefile 中处理的。这里定义各种img 的生成方式,包括 ramdisk.img 、 userdata.img 、 system.img 、 update.zip 、 recover.img 等。 当Make include 所有的文件,完成对所有 make 文件的解析以后就会寻找生成 对应目标 的规则,依次生成它的依赖,直到所有满足的模块被编译好,然后使用相应的工具打包成相应的img 。 

kernel/Android.mk
kernel/arch/arm/configs/vc0882_vortex_nand_defconfig  ->kernel/.config
Makefile的主要流程:
以下主要流程都在build/core/main.mk 里安排。

  初始化相关的参数设置(buildspec.mk 、 envsetup.mk 、 config.mk)
  检测编译环境和目标环境
  决定目标product
  读取product 的配置信息及目标平台信息
  读取BoardConfig 的配置
  读取所有Module  的配置
  根据配置产生必要的规则(build/core/Makefile)
  生成image

你可能感兴趣的:(android,Module,Build,include,makefile,产品)