几个重要的makefile:Android.mk:编译源码mk文件,每个module和package目录下有这么一个文件main.mk:定义了编译全部代码的依赖关系config.mk:用于配置编译系统,决定如何编译envsetup.mk:定义了编译环境配置product_config.mk:读取AndrodProducts.mk生成TARGET_DEVICE变量AndroidProducts.mk:定义某厂商所有产品文件列表BoardConfig.mk:定义开发板软件相关配置项,将来影响系统条件编译。一、Android编译步骤:二、初始化编译环境--sourcebuild/envsetup.sh在build/envsetup.sh中主要完成了三件事。添加编译目标的代码如下:forfin`/bin/lsvendor/*/vendorsetup.shvendor/*/*/vendorsetup.shdevice/*/*/vendorsetup.sh2/dev/null`doechoincluding$f.$fdoneunsetf三、选择编译目标--lunch通过lunch选择编译目标,函数定义如下:functionlunch(){localanswer//如果调用lunch时带参数就表示手动指定编译目标,否则打印选择编译目标的菜单if[$1];thenanswer=$1elseprint_lunch_menuecho-nWhichwouldyoulike?[full-eng]readanswerfilocalselection=//如果没有编译目标默认为full-eng,否则如果answer是数字就将其转换为对应的字符串表示if[-z$answer]thenselection=full-engelif(echo-n$answer|grep-q-e^[0-9][0-9]*$)thenif[$answer-le${#LUNCH_MENU_CHOICES[@]}]thenselection=${LUNCH_MENU_CHOICES[$(($answer-1))]}fielif(echo-n$answer|grep-q-e^[^\-][^\-]*-[^\-][^\-]*$)thenselection=$answerfi//如果表示编译目标的字符串是空的表示非法选择,错误返回if[-z$selection]thenechoechoInvalidlunchcombo:$answerreturn1fiexportTARGET_BUILD_APPS=//检测选择的product是否合法(只要在相应目录新建vendorsetup.sh并add_lunch_combo就可在lunchmenu中显示相应项,但如果不配置product相关信息就会Invalid)localproduct=$(echo-n$selection|sed-es/-.*$//)check_product$productif[$?-ne0]thenechoecho**Don'thaveaproductspecfor:'$product'echo**Doyouhavetherightrepomanifest?product=fi//从selection解析出product,variantlocalvariant=$(echo-n$selection|sed-es/^[^\-]*-//)check_variant$variantif[$?-ne0]thenechoecho**Invalidvariant:'$variant'echo**Mustbeoneof${VARIANT_CHOICES[@]}variant=fiif[-z$product-o-z$variant]thenechoreturn1fi//导出TARGET_PRODECT,TARGET_BUILD_VARIANT与TARGET_BUILD_TYPE,比如若选择的是full-eng,那么TARGET_PRODUCT=full,TARGET_BUILD_VARIANT=engexportTARGET_PRODUCT=$productexportTARGET_BUILD_VARIANT=$variantexportTARGET_BUILD_TYPE=releaseechoset_stuff_for_environmentprintconfig}四、编译--make-j8要make肯定有Makefile,Android根目录的Makefile只是简单地include进来了一个文件:1###DONOTEDITTHISFILE###2includebuild/core/main.mk3###DONOTEDITTHISFILE###而build/core/main.mk就比较复杂了,以下是main.mk的结构图:在main.mk中首先定义了默认编译目标并做版本检查,然后includeconfig.mk。在config.mk中定义了在Android.mk中编译目标时会用到的常量CLEAR_VARS:=$(BUILD_SYSTEM)/clear_vars.mkBUILD_HOST_STATIC_LIBRARY:=$(BUILD_SYSTEM)/host_static_library.mkBUILD_HOST_SHARED_LIBRARY:=$(BUILD_SYSTEM)/host_shared_library.mkBUILD_STATIC_LIBRARY:=$(BUILD_SYSTEM)/static_library.mkBUILD_RAW_STATIC_LIBRARY:=$(BUILD_SYSTEM)/raw_static_library.mkBUILD_SHARED_LIBRARY:=$(BUILD_SYSTEM)/shared_library.mkBUILD_EXECUTABLE:=$(BUILD_SYSTEM)/executable.mkBUILD_RAW_EXECUTABLE:=$(BUILD_SYSTEM)/raw_executable.mkBUILD_HOST_EXECUTABLE:=$(BUILD_SYSTEM)/host_executable.mkBUILD_PACKAGE:=$(BUILD_SYSTEM)/package.mkBUILD_PHONY_PACKAGE:=$(BUILD_SYSTEM)/phony_package.mkBUILD_HOST_PREBUILT:=$(BUILD_SYSTEM)/host_prebuilt.mkBUILD_PREBUILT:=$(BUILD_SYSTEM)/prebuilt.mkBUILD_MULTI_PREBUILT:=$(BUILD_SYSTEM)/multi_prebuilt.mkBUILD_JAVA_LIBRARY:=$(BUILD_SYSTEM)/java_library.mkBUILD_STATIC_JAVA_LIBRARY:=$(BUILD_SYSTEM)/static_java_library.mkBUILD_HOST_JAVA_LIBRARY:=$(BUILD_SYSTEM)/host_java_library.mkBUILD_DROIDDOC:=$(BUILD_SYSTEM)/droiddoc.mkBUILD_COPY_HEADERS:=$(BUILD_SYSTEM)/copy_headers.mkBUILD_NATIVE_TEST:=$(BUILD_SYSTEM)/native_test.mkBUILD_HOST_NATIVE_TEST:=$(BUILD_SYSTEM)/host_native_test.mk然后include进来了/build/core/envsetup.sh,在envsetup.sh中定义了HOST_OS,OUT_DIR等环境变量,并通过includeproduct_config.mk检索所有Product,并做有效性检查,然后根据lunch时选择的Product设置TARGET_DEVICE。然后在envsetup.sh中根据TARGET_DEVICE查找BoardConfig.mk文件进行Board相关配置,查找KERNEL_HEADER,配置编译工具链。在definitions.mk中定义了all_makefiles_under等用来检索文件的函数。根据TARGET_BUILD_VARIANT设置ro.secure等系统属性,设定tags_to_install等变量。接下来通过subdir_makefiles:=\$(shellbuild/tools/findleaves.py--prune=out--prune=.repo--prune=.git$(subdirs)Android.mk)include$(subdir_makefiles)找到所有子目录下的Android.mk文件并include进来,这样在Android.mk定义的LOCAL_PACKAGE_NAME与include$(BUILD_PACKAGE)就可以将相应的Android.mk中定义的目标包含进编译模块中,在config.mk中有如下定义:BUILD_PACKAGE:=$(BUILD_SYSTEM)/package.mk而package.mk又包含base_rules.mk将LOCAL_MODULE添加到ALL_MODULES中。post_clean.mk是跟ResourceOverlay相关,使们们不需要修改framework中原来的资源文件就可以定义framework-res.apk中的资源。接下来includebuild/core/Makefile文件,定义bootimage,systemimage等依赖目标,然后通过make编译droid(默认)目标就可以编译系统了。Android采用检索所有子目录中的Android.mk将所有要编译的模块收集起来的方式编译系统,而不是进入到每个子目录执行make,这样就方便了我们添加自己的模块。