Android编译系统

来源:互联网 发布:ubuntu打开火狐浏览器 编辑:程序博客网 时间:2024/06/03 22:50

这篇文章对Android的编译系统做个大概的分析,希望对大家有帮助,也希望大家一起讨论。

编译系统的框架和结构网上有很多文章描述,本文后面也附了一些链接可供大家参考。

下面我们就从Android系统(以android4.2.2为例)的编译过程来分析其编译系统。

一、执行source build/envsetup.sh

      envsetup.sh其主要作用如下:

  1. 加载了编译时使用到的函数命令,如:help,lunch,m,mm,mmm等
  2. 添加默认的lunch选项
    # add the default one hereadd_lunch_combo aosp_arm-engadd_lunch_combo aosp_x86-engadd_lunch_combo aosp_mips-engadd_lunch_combo vbox_x86-eng
  3. 查找vendor/<-厂商目录>/和device/<厂商目录>/ 目录下的vendorsetup.sh,如果存在的话,加载执行它,添加厂商自己定义产品的编译选项
    # Execute the contents of any vendorsetup.sh files we can find.for f in `test -d device && find device -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null` \         `test -d vendor && find vendor -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null`do    echo "including $f"    . $fdoneunset f

二、执行lunch

       执行lunch的时候,会出现选择菜单,让您选择编译的产品和编译类型,lunch方法执行时,会等待用户输入对应的产品类型,并有缺省的产品类型,比较重要的逻辑
    local product=$(echo -n $selection | sed -e "s/-.*$//")    check_product $product
    local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//")    check_variant $variant
        check_product会调用config.mk设置一些平台无关的变量,下面有详细描述
        check_variant会校验是否为user userdebug eng之一

三、build/core/config.mk文件

       该文件定义了编译过程中需要的一些 与平台无关的变量,在该方法里被调用

# Get the exact value of a build variable.function get_build_var(){    T=$(gettop)    if [ ! "$T" ]; then        echo "Couldn't locate the top of the tree.  Try setting TOP." >&2        return    fi    CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \      make --no-print-directory -C "$T" -f build/core/config.mk dumpvar-$1}

            现列举出几个比较重要的地方:

# ---------------------------------------------------------------# Define most of the global variables.  These are the ones that# are specific to the user's build configuration.include $(BUILD_SYSTEM)/envsetup.mk
            1、envsetup.mk里定义了大部分的全局变量,可以从该文件的末尾发现定义的全局变量。包括android版本信息等。

         2、定义了board_config_mk变量,主要是板级的配置选项,比如CPU类型,外设相关        

# Boards may be defined under $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)# or under vendor/*/$(TARGET_DEVICE).  Search in both places, but# make sure only one exists.# Real boards should always be associated with an OEM vendor.board_config_mk := \        $(strip $(wildcard \                $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk \                $(shell test -d device && find device -maxdepth 4 -path '*/$(TARGET_DEVICE)/BoardConfig.mk') \                $(shell test -d vendor && find vendor -maxdepth 4 -path '*/$(TARGET_DEVICE)/BoardConfig.mk') \        ))

四、修改编译系统,适配自己的产品

如何在Android系统中添加自己的编译系统,假设厂商名称为DCODE,该厂商有两个基于ANDROID的产品,都放到一个主线上来维护,这两个产品为:apple和orange。OK,下面我们为该厂商添加编译模块:

1、在device目录下创建子目录DCODE,并在该目录下创建文件AndroidProducts.mk,该文件的内容为:

PRODUCT_MAKEFILES := \  $(LOCAL_DIR)/apple/apple.mk \  $(LOCAL_DIR)/orange/orange.mk

      那么Android系统是怎么将产品的mk文件load进来的呢,在文件build/core/product_config.mk中有如下定义:

ifneq ($(strip $(TARGET_BUILD_APPS)),)# An unbundled app build needs only the core product makefiles.all_product_configs := $(call get-product-makefiles,\    $(SRC_TARGET_DIR)/product/AndroidProducts.mk)else# Read in all of the product definitions specified by the AndroidProducts.mk# files in the tree.all_product_configs := $(get-all-product-makefiles)endif# Find the product config makefile for the current product.# all_product_configs consists items like:# <product_name>:<path_to_the_product_makefile># or just <path_to_the_product_makefile> in case the product name is the# same as the base filename of the product config makefile.current_product_makefile :=all_product_makefiles :=$(foreach f, $(all_product_configs),\    $(eval _cpm_words := $(subst :,$(space),$(f)))\    $(eval _cpm_word1 := $(word 1,$(_cpm_words)))\    $(eval _cpm_word2 := $(word 2,$(_cpm_words)))\    $(if $(_cpm_word2),\        $(eval all_product_makefiles += $(_cpm_word2))\        $(if $(filter $(TARGET_PRODUCT),$(_cpm_word1)),\            $(eval current_product_makefile += $(_cpm_word2)),),\        $(eval all_product_makefiles += $(f))\        $(if $(filter $(TARGET_PRODUCT),$(basename $(notdir $(f)))),\            $(eval current_product_makefile += $(f)),)))
      对于这段代码,解释一下几个重要的地方:

        1) get-all-product-maefiles方法,该方法定义在build//core/product.mk文件中,该方法的注释为

## Returns the sorted concatenation of all PRODUCT_MAKEFILES# variables set in all AndroidProducts.mk files.# $(call ) isn't necessary.
        从注释里面可看出,该方法用来从所有的AndroidProducts.mk文件中获取PRODUCT_MAKEFILES变量。

define get-all-product-makefiles$(call get-product-makefiles,$(_find-android-products-files))endef
            不难理解上面的代码,_find-andorid-products-files用来获得所有的AndroidProducts.mk文件,而get-product-maifles则是遍历这些文件,获取PRODUCT_MAKEFILES变量。

2) 在device/DCODE目录下创建两个子目录,分别为apple和orange,如上述AndroidProducts.mk中定义的,我们要在这两个目录下分别创建文件apple.mk和orange.mk。在产品的mk文件里我们要定义该产品的一些属性,比如PRODUCT_PACKAGES, PRODUCT_PACKAGE_RESOURCES等,这时候,apple和orange产品会有很多属性是完全一致的,在实际的系统里我们没必要定义两份重复的配置选项,我们可以定义一个common文件夹,然后apple和orange从这个common配置里派生出来,如下:

$(call inherit-product, device/DCODE/common/common.mk)

3、增加了上述两个mk文件,我们下面需要了解这两个文件中的内容,比如我现在有这样的需求,为apple产品添加一些自定义的功能模块,并将android系统中的一些资源进行替换。首先功能模块可以通过PRODUCT_PACKAGES属性包含进来,而替换系统资源,则可以通过PRODUCT_PACKAGE_OVERLAYS属性来指定。其他一些常用属性入PRODUCT_NAME,PRODUCT_DEVICE等,这里就不一一详述了。

4、在产品目录下添加board相关的配置。增加AndroidBoard.mk文件,该文件定义了如file copy,key layout files,key character-map files,init file,

5、在产品目录下添加verdorsetup.sh文件,增加如下内容:(这个是否需要添加?)

add_lunch_combo full_apple-userdebug

这个文件的作用是为lunch添加选项,这个文件由build/envsetup.sh脚本include进来

其他可参考的文章:

<span style="font-size:14px;">http://blog.csdn.net/yili_xie/article/details/4830541http://www.360doc.com/content/10/0224/11/155970_16643955.shtmlhttp://www.kandroid.org/online-pdk/guide/build_new_device.html#androidBuildSystemProductDefFileshttp://blog.csdn.net/mr_raptor/article/details/7539978</span>




原创粉丝点击