前面两节讲解了自定义Android编译项和创建Product产品配置文件,除了编译和定义产品相关环境变量外,还需要定义Board相关环境变量。
            1、 build/core/config.mk
            [plain] view plaincopy
            <pre name="code" class="plain">109 #   --------------------------------------------------------
                  110   # Define most of the global variables. These are the ones that 
                  111 #   are specific to the user's build configuration. 
                  112 include   $(BUILD_SYSTEM)/envsetup.mk 
                  113 
                  114 # Boards may be   defined under $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE) 
                  115 # or   under vendor/*/$(TARGET_DEVICE). Search in both places, but 
                  116 #   make sure only one exists. 
                  117 # Real boards should always be   associated with an OEM vendor. 
                  118 board_config_mk := \ 
                  119 $(strip $(wildcard \ 
                  120   $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk \ 
                  121   vendor/*/$(TARGET_DEVICE)/BoardConfig.mk \ 
                  122 )) 
                  123   ifeq ($(board_config_mk),) 
                  124 $(error No config file found for   TARGET_DEVICE $(TARGET_DEVICE)) 
                  125 endif 
                  126 ifneq   ($(words $(board_config_mk)),1) 
                  127 $(error Multiple board config   files for TARGET_DEVICE $(TARGET_DEVICE): $(board_config_mk)) 
                  128   endif 
                  129 include $(board_config_mk) 
                  130   TARGET_DEVICE_DIR := $(patsubst %/,%,$(dir $(board_config_mk))) 
                  131   board_config_mk := 
            上述代码在上一节已经见到过,只是分析了112行的envsetup.mk,根据上一节内容可知,envsetup.mk设置了很多OUT变量,终在build/core/product_config.mk文件里,设置了TARGET_DEVICE   = fs100。
            我们从114行继续分析。
            从114~117行解释大意可知:
            Board相关配置文件会存在于$(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/或vendor/*/$(TARGET_DEVICE)/目录中,一个Vendor厂商只能有一个对应的Board配置文件。
            118行定义board_config_mk变量:
            $(wildcard xxx)函数就是找到与xxx的匹配项放到空格列表里,前面定义TARGET_DEVICE变量 =   fs100,所以$(SRC_TARGET_DIR)/board/fs100/BoardConfig.mk不存在,必须要存在vendor/*/fs100/BoardConfig.mk文件来定义开发板配置信息。
            129行,通过include将vendor/*/fs100/BoardConfig.mk包含进来,
            130行,TARGET_DEVICE_DIR为board_config_mk的路径,即:vendor/*/fs100
            总结:
            一个vendor厂商必须要有一个对应的Board配置文件,即:vendor/*/fs100/BoardConfig.mk
            定义了TARGET_DEVICE_DIR变量,为board_config_mk的路径,即:vendor/*/fs100
            指定board 相关特性,一定要包含:TARGET_CPU_ABI := armeabi/...
            其他属性参见其他board样例.(build/target/board/XXX
            2、build/core/main.mk
            [plain] view plaincopy
            141 # Bring in standard build system definitions. 
                  142   include $(BUILD_SYSTEM)/definitions.mk 
                  ... 
                  347 ifeq   ($(SDK_ONLY),true) 
                  348 
                  349 # ----- SDK for Windows   ------ 
                  350 # These configure the build targets that are available   for the SDK under Cygwin. 
                  351 # The first section defines all the   C/C++ tools that can be compiled under Cygwin, 
                  352 # the second   section defines all the Java ones (assuming javac is available.) 
                  353 
                  354 subdirs := \ 
                  355 prebuilt \ 
                  356   build/libs/host \ 
                  357 build/tools/zipalign \ 
                  ... 
                  382 # The following can only be built if "javac" is available. 
                  383 # This check is used when building parts of the SDK under   Cygwin. 
                  384 ifneq (,$(shell which javac 2>/dev/null)) 
                  385 $(warning sdk-only: javac available.) 
                  386 subdirs +=   \ 
                  387 build/tools/signapk \ 
                  388 dalvik/dx \ 
                  389 dalvik/libcore \ 
                  ... 
                  414 else #   !SDK_ONLY 
                  415 ifeq ($(BUILD_TINY_ANDROID), true) 
                  416 
                  417 # TINY_ANDROID is a super-minimal build configuration, handy for   board 
                  418 # bringup and very low level debugging 
                  419 
                  420 subdirs := \ 
                  421 bionic \ 
                  422   system/core \ 
                  423 build/libs \ 
                  424 build/target \ 
                   ... 
                  433 else # !BUILD_TINY_ANDROID 
                  434 
                  435 # 
                  436 # Typical build; include any Android.mk files   we can find. 
                  437 # 
                  438 subdirs := $(TOP) 
                  439 
                  440 FULL_BUILD := true 
                  441 
                  442 endif #   !BUILD_TINY_ANDROID 
                  443 
                  444 endif # !SDK_ONLY 
                  ... 
                  464 # 
                  465 # Include all of the makefiles   in the system 
                  466 # 
                  467 
                  468 # Can't use   first-makefiles-under here because 
                  469 # --mindepth=2 makes the   prunes not work. 
                  470 subdir_makefiles := \ 
                  471 $(shell   build/tools/findleaves.py --prune=out --prune=.repo --prune=.git $(subdirs)   Android.mk) 
                  472 
                  473 include $(subdir_makefiles) 
            上一节只是讲了main.mk第49行中包含了config.mk,我们继续分析。
            142行包含了:build/core/definitions.mk,该文件定义了很多全局变量与函数。
            如下列常见函数:
            my-dir:返回当前路径
            all-java-files-under:获得指定目录及子目录一所有java文件
            all-subdir-c-files:获得当前目录下及子目录下所有c文件
            354~444行,定义了subdirs变量,依据不同的用户编译条件,而包含Android源码中不同的目录。
            470行,定义了subdir_makefile变量,其值为subdirs定义的目录中的Android.mk文件。
            473行,将所有编译目录中的Android.mk文件包含进来。
            3、 build/target/board/Android.mk
            [plain] view plaincopy
            26 ifeq (,$(wildcard $(TARGET_DEVICE_DIR)/AndroidBoard.mk)) 
                  27 ifeq (,$(wildcard $(TARGET_DEVICE_DIR)/Android.mk)) 
                  28 $(error Missing "$(TARGET_DEVICE_DIR)/AndroidBoard.mk") 
                  29 else 
                  30 # TODO: Remove this check after people have   had a chance to switch, 
                  31 # after April 2009. 
                  32 $(error Please rename "$(TARGET_DEVICE_DIR)/Android.mk" to   "$(TARGET_DEVICE_DIR)/AndroidBoard.mk") 
                  33 endif 
                  34   endif 
                  35 include $(TARGET_DEVICE_DIR)/AndroidBoard.mk 
            由于将所有目录中Android.mk文件include进来,build/target/board/Android.mk自然被包含进来,根据前面分析,TARGET_DEVICE_DIR   =   vendor/*/fs100,其中26~35行用来判断对应的产品目录下是否存在AndrodiBoard.mk,如果不存在,提示出错退出,如果存在,将其包含到编译脚本中。
            由此可见:我们必须要在产品目录下创建AndrodiBoard.mk文件,来描述开发板相关配置项,我们可以借鉴:build/target/board/generic/AndroidBoard.mk内容,同时根据前面所分析,还要创建BoardConfig.mk文件。
            [plain] view plaincopy
            #cp build/target/board/generic/AndroidBoard.mk   build/target/board/generic/BoardConfig.mk vendor/farsight/fs100/ 
            至此,自定义Android编译选项基本步骤已经分部分析完,细节还需要针对不同开发板具体分析。
            总结:
            build/core/main.mk包含了config.mk,它主要定义了编译全部代码的依赖关系
            build/core/config.mk 定义了大量的编译脚本命令,编译时用到的环境变量,引入了envsetup.mk   文件,加载board相关配置文件。
                  build/core/envsetup.mk   定义了编译时用到的大量OUT输出目录,加载product_config.mk文件
                  build/core/product_config.mk   定义了Vendor目录下Product相关配置文件解析脚本,读取AndrodProducts.mk生成TARGET_DEVICE变量
                  build/target/product   product config
                  build/target/board board   config
                  build/core/combo build flags config 
            这里解释下这里的board和product。borad主要是设计到硬件芯片的配置,比如是否提供硬件的某些功能,比如说GPU等等,或者芯片支持浮   点运算等等。product是指针对当前的芯片配置定义你将要生产产品的个性配置,主要是指APK方面的配置,哪些APK会包含在哪个product中,   哪些APK在当前product中是不提供的。
            config.mk是一个总括性的东西,它里面定义了各种module编译所需要使用的HOST工具以及如何来编译各种模块,比如说   BUILT_PREBUILT就定义了如何来编译预编译模块。envsetup.mk主要会读取由envsetup.sh写入环境变量中的一些变量来配置编译过程中的输出目录,combo里面主要定义了各种Host和Target结合的编译器和编译选项。
            1)在vendor目录下创建自己公司目录,然后在公司目录下创建一个新的vendorsetup.sh,在里面添加上自己的产品编译项
            [plain] view plaincopy
            #mkdir vendor/farsight/ 
                  #touch   vendor/farsight/vendorsetup.sh 
                  #echo "add_lunch_combo fs100-eng"   > vendor/farsight/vendorsetup.sh 
            2)仿着Android示例代码,在公司目录下创建products目录
            [plain] view plaincopy
            #mkdir -p vendor/farsight/products 
            3)仿着Android示例代码,在products目录下创建两个mk文件
            [plain] view plaincopy
            #touch vendor/farsight/products/AndroidProduct.mk   vendor/farsight/products/fs100.mk 
            在AndroidProduct.mk里添加如下内容:
            [sql] view plaincopy
            PRODUCT_MAKEFILES := $(LOCAL_DIR)/fs100.mk 
            在产品配置文件里添加基本信息
            [plain] view plaincopy
            PRODUCT_PACKAGES := \ 
                  IM \ 
                  VoiceDialer 
                  $(call inherit-product, build/target/product/generic.mk) 
                  # Overrides 
                  PRODUCT_MANUFACTURER := farsight 
                  PRODUCT_NAME := fs100 
                  PRODUCT_DEVICE := fs100 
            4)借鉴build/target/board/generic/AndroidBoard.mk和BoardConfig.mk,创建对应文件。
            [plain] view plaincopy
            #cp build/target/board/generic/AndroidBoard.mk   build/target/board/generic/BoardConfig.mk vendor/farsight/fs100/