目录
主要用来配置product、board,以及根据你的Host和Target选择相应的工具以及设定相应的通用编译选项:
config文件
说明
build/core/config.mk Config文件的概括性配置
build/core/envsetup.mk generate目录构成等配置build/target/product 产品相关的配置
build/target/board 硬件相关的配置
build/core/combo 编译选项配置
这里解释下这里的board和product。board主要是设计到硬件芯片的配置, 比如是否提供硬件的某些功能,比如说GPU等等,或者芯片支持浮点运算等等。product是指针对当前的芯片配置定义你将要生产产品的个性配置,主要是 指APK方面的配置,哪些APK会包含在哪个product中,哪些APK在当前product中是不提供的。
config.mk是一个总括性的东西,它里面定义了各种module编译所需要使用的 HOST工具以及如何来编译各种模块,比如说 BUILT_PREBUILT就定义了如何来编译预编译模块。
envsetup.mk主要会读取由envsetup.sh写入环境变量中的一些变量来配置 编译过程中的输出目录,
combo里面主要定义了各种Host和Target结合的编译器和编译选项。
2. 模块组织类
这类文件主要定义了如何来处理Module的Android.mk,以及采用何种方式来生成目标模块,这些模块生成规则都定义在config.mk里面。我们可以看看:
CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk
BUILD_HOST_STATIC_LIBRARY:=$(BUILD_SYSTEM)/host_static_library.mk
BUILD_HOST_SHARED_LIBRARY:=$(BUILD_SYSTEM)/host_shared_library.mk
BUILD_STATIC_LIBRARY:=$(BUILD_SYSTEM)/static_library.mk
BUILD_RAW_STATIC_LIBRARY :=$(BUILD_SYSTEM)/raw_static_library.mk
BUILD_SHARED_LIBRARY:=$(BUILD_SYSTEM)/shared_library.mk
BUILD_EXECUTABLE:= $(BUILD_SYSTEM)/executable.mk
BUILD_RAW_EXECUTABLE:=$(BUILD_SYSTEM)/raw_executable.mk
BUILD_HOST_EXECUTABLE:=$(BUILD_SYSTEM)/host_executable.mk
BUILD_PACKAGE:= $(BUILD_SYSTEM)/package.mk
BUILD_HOST_PREBUILT:=$(BUILD_SYSTEM)/host_prebuilt.mk
BUILD_PREBUILT:= $(BUILD_SYSTEM)/prebuilt.mk
BUILD_MULTI_PREBUILT:=$(BUILD_SYSTEM)/multi_prebuilt.mk
BUILD_JAVA_LIBRARY:= $(BUILD_SYSTEM)/java_library.mk
BUILD_STATIC_JAVA_LIBRARY:=$(BUILD_SYSTEM)/static_java_library.mk
BUILD_HOST_JAVA_LIBRARY:=$(BUILD_SYSTEM)/host_java_library.mk
BUILD_DROIDDOC:= $(BUILD_SYSTEM)/droiddoc.mk
BUILD_COPY_HEADERS := $(BUILD_SYSTEM)/copy_headers.mk
BUILD_KEY_CHAR_MAP :=$(BUILD_SYSTEM)/key_char_map.mk
除了CLEAR_VARS是清楚本地变量之外,其他所有的都对应了一种模块的生成规则, 每一个本地模块最后都会include其中的一种来生成目标模块。大部分上面的.mk都会包含base_rules.mk,这是对模块进行处理的基础文 件,建议要写本地模块的都去看看,看明白了为什么 Android.mk要这么写就会大致明白了。
3.单个模块编译类
本地模块的Makefile文件就是我们在Android里面几乎上随处可见的 Android.mk。Android进行编译的时候会通过下面的函数来遍历所有子目录中的Android.mk,一旦找到就不会再往层子目录继续寻找 (所有你的模块定义的顶层Android.mk必须包含自己定义的子目录中的 Android.mk)。 subdir_makefiles += / $(shellbuild/tools/findleaves.sh --prune="./out" $(subdirs) Android.mk) 不同类型的本地模块具有不同的语法,但基本上是相通的,只有个别变量的不同,如何添加模块在前面的帖子已经说过了,大家可以参考。 Android通过LOCAL_MODULE_TAGS来决定哪些本地模块会不会编译进 系统,通过PRODUCT和LOCAL_MODULE_TAGS来决定哪些应用包会编译进系统,如果用户不指定LOCAL_MODULE_TAGS,默认 它的值是user。此外用户可以通过buildspec.mk来指定你需要编译进系统的模块。用户也可以通过mm来编译指定模块,或者通过make clean-module_name来删除指定模块。
4.系统生成类
这主要指的是build/core/Makefile这个文件,它定义了生成各种img 的方式,包括ramdisk.img userdata.img system.img update.zip recover.img等。我们可以看看这些img都是如何生成的,对应着我们常用的几个make goals。在实际的过程中,我们也可以自己编辑out目录下的生成文件,然后手工打包相应生成相应的img,最常用的是加入一些需要集成进的prebuilt file。所有的Makefile都通过build/core/main.mk这个文件组织在一起,它定义了一个默认goals:droid,当我们在 TOP目录下敲Make实际上就等同于我们执行make droid。当Make include所有的文件,完成对所有make文件的解析以后就会寻找生成droid的规则,依次生成它的依赖,直到所有满足的模块被编译好,然后使用相 应的工具打包成相应的img。
控制整个android系统编译的make文件。其内容如下:
### DO NOT EDIT THIS FILE ###
include build/core/main.mk
### DO NOT EDIT THIS FILE ###
可以看出,实际上控制编译的文件是:build/core/main.mk
make droid:等同于make命令。droid是默认的目标名称。
make all: make all将make所有make droid会编译的项目。同时,将编译LOCAL_MODULE_TAGS定义的不包括android tag的模块。这将确保所有的在代码树里面同时有Android.mk文件的模块。
clean-$(LOCAL_MODULE)和clean-$(LOCAL_PACKAGE_NAME):删除某个模块的目标文件。例如:clean-libutils将删除所有的libutils.so以及和它相关的中间文件;clean-Home将删除Home应用。
make clean:删除本次配置所编译输出的结果文件。类似于:rm –rf ./out/
make clobber:删除所有配置所编译输出的结果文件。类似于:rm –rf ./out/
make dataclean:类似于:rm -rf $(PRODUCT_OUT)/data/*, data-qemu/*, userdata-qemu.img
make dataclean deletes contents of the data directory inside the current combo directory. This is especially useful on the simulator and emulator, where the persistent data remains present between builds.
make showcommands:在编译的时候显示脚本的命令,而不是显示编译的简报。用于调试脚本。
make LOCAL_MODULE:编译一个单独得模块(需要有Android.mk文件存在)。
make targets:将输出所有拟可以编译的模块名称列表。
CONT.
+1
printconfig –Prints current configuration set by choosecombo commands
croot –cd to top of tree
m –Runs make from top of tree Useful for running make from within subdirectories; if TOP environment variable is set, command uses that variable; if variable is not set, command looks up tree from current directory and attempts to find top of tree
mm –Builds all modules incurrent directory
mmm –Builds all modules insupplied directories
sgrep –grep for regex you provide in all .c, .cpp, .h, .java, and .xml filesbelow the current directory
cgrep
jgrep
mgrep
Local modules –Use the following command to make a specific module:
m MODULE_NAME
+1
Howto:get kernel log by real time:
cat /proc/kmsg & 或者 dmesg -c
Howto:make boot.img quickly
make bootimage 或者 make kernel
Howto:config kernel option
in android root dir : make kernelconfig
but NOT in kernel dir : make menuconfig
+1
Howto:make lk(appsboot.mbn)
make aboot
(会调用下面的位置
./build/core/main.mk
.PHONY: bootimage
bootimage: $(INSTALLED_BOOTIMAGE_TARGET)
.PHONY: aboot
aboot: $(INSTALLED_BOOTLOADER_TARGET)
)
(L)ittle (K)ernel bootloader的mk文件是
/bootable/bootloader/lk/AndroidBoot.mk
linux kernel的mk文件是
/kernel/AndroidKernel.mk
两者在/device/qcom/msm7627_sku2/AndroidBoard.mk中被包含进来。
注:还有一些命令,从make文件里面应该可以找到。本文不做探讨。
config.mk文件的主要内容如下:
Ø 头文件的定义;(各种include文件夹的设定)在定义头文件的部分,还include了pathmap.mk,如下:
include $(BUILD_SYSTEM)/pathmap.mk 该文件设置include目录和frameworks/base下子目录等的信息。
Ø 编译系统内部mk文件的定义;
Ø 设定通用的名称;
Ø Include必要的子配置文件; buildspec.mk envsetup.mk BoardConfig.mk /combo/select.mk /combo/javac.mk
Ø 检查BUILD_ENV_SEQUENCE_NUMBER版本号;
In order to make easier for people when the build system changes, when it is necessary to make changes to buildspec.mk or to rerun the environment setup scripts, they contain a version number in the variable BUILD_ENV_SEQUENCE_NUMBER. If this variable does not match what the build system expects, it fails printing an error message explaining what happened. If you make a change that requires an update, you need to update two places so this message will be printed.
In config/envsetup.make, increment the CORRECT_BUILD_ENV_SEQUENCE_NUMBER definition.
In buildspec.mk.default, update the BUILD_ENV_SEQUENCE_DUMBER definition to match the one in config/envsetup.make
The scripts automatically get the value from the build system, so they will trigger the warning as well.
Ø 设置常用工具的常量;< Generic tools.>
Ø 设置目标选项;< Set up final options.>
Ø 遍历并设置SDK版本;
默认情况下,buildspec.mk文件是不存在的,表示使用的多少默认选项。 Android只提供了buildspec.mk文件的模板文件build/buildspec.mk.default。如果需要使用 buildspec.mk文件,请将该文件拷贝到根目录下面,并命名为buildspec.mk。同时,需要将模板文件里面 的一些必要的配置项启用或者修改为你所需要的目标选项。 buildspec.mk文件主要配置下面的选项: Ø TARGET_PRODUCT:设置编译之后的目标(产品)类型;可以设置的值在:build/target/product/中定义。比如,product目录下有下面几个mk文件:
AndroidProducts.mk
core.mk
full.mk
generic.mk
languages_full.mk
languages_small.mk
sdk.mk
sim.mk
那么,在这里可以设置的值就为上面几个mk文件的前缀名称(generic等)。
Ø TARGET_BUILD_VARIANT:设置image的类型;
包括三个选项:user、userdebug、eng。
usr:出厂时候面向用户的image;
userdebug:打开了一些debug选项的image;
eng:为了开发而包含了很多工具的image .
Ø CUSTOM_MODULES:设置额外的总是会被安装到系统的模块;这里设置的模块名称采用的是简单目标名,比如:Browser或者MyApp等。这些名字在LOCAL_MODULE或者在LOCAL_PACKAGE_NAME里面定义的。
LOCAL_MODULE is the name of what's supposed to be generated from your Android.mk. For exmample, for libkjs, the LOCAL_MODULE is "libkjs" (the build system adds the appropriate suffix -- .so .dylib .dll). For app modules, use LOCAL_PACKAGE_NAME instead of LOCAL_MODULE. We're planning on switching to ant for the apps, so this might become moot.
Ø TARGET_SIMULATOR:设置是否要编译成simulator ;
Ø TARGET_BUILD_TYPE:设置是debug还是release版本 ; Set this to debug or release if you care. Otherwise, it defaults to release for arm and debug for the simulator.
Ø HOST_BUILD_TYPE:设置Host目标是debug版还是release版;
Ø DEBUG_MODULE_ModuleName:配置单个模块的版本是debug还是release;
Ø TARGET_TOOLS_PREFIX:工具名前缀,默认为NULL
Ø HOST_CUSTOM_DEBUG_CFLAGS/ TARGET_CUSTOM_DEBUG_CFLAGS:增加额外的编译选项LOCAL_CFLAGS。 LOCAL_CFLAGS:If you have additional flags to pass into the C or C++ compiler, add them here. For example: LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1
Ø CUSTOM_LOCALES:增加额外的LOCALES到最总的image; Any locales that appear in CUSTOM_LOCALES but not in the locale list for the selected product will be added to the end of PRODUCT_LOCALES.
Ø OUT_DIR:编译之后文件保存路径。默认为/out目录;
Ø ADDITIONAL_BUILD_PROPERTIES:指定(增加)额外的属性文件;
Ø NO_FALLBACK_FONT:设置是否只支持英文(这将减少image的大小)。
Ø WEBCORE_INSTRUMENTATION:webcore支持;
Ø ENABLE_SVG:SVG支持;
Ø BUILD_ENV_SEQUENCE_NUMBER:编译系列号;
include $(BUILD_EXECUTABLE)表示编译成可执行程序
include $(BUILD_JAVA_LIBRARY)表示编译成xxx.jar(如手机中/system/framework下存的全是jar,典型的framework.jar,core.jar,ext,.jar) include $(BUILD_STATIC_JAVA_LIBRARY) ??????
模块的各种类型在(一)make文件分类 1. 配置类2. 模块组织类中有介绍,也可以参见out/target/product/msm7627_sku2/obj目录,这里是中间文件的生成位置,下面的每个目录名代表着一类模块(或者说android系统中的文件类型,如apk,so,a ,可执行程序等)。
STATIC_LIBRARIES:最终放到手机系统中的.a文件(其实就是.o文件的集合,第三方可能将不想公开的代码编译成这个提供给方案公司)
SHARED_LIBRARIES:最终放到手机系统中的.so文件(如sensor的hal层代码就是这种文件,我的是/system/lib/hw/sensors.msm7k.so)
EXECUTABLES:最终放到手机系统中的可执行文件,一般没有扩展名(如一些daemon文件,一般放到/system/bin下,如我的oem_rapi_wifimac,)
更多参考 Android编译系统makefile(Android.mk)写法(3)举例
如下的Android.mk内容
LOCAL_PATH := $(call my-dir)
include $(BUILD_SHARED_LIBRARY) #编译成共享库,.so
源码最终被编译成sensors.ami.so这个共享库模块。
有下面两个调试技巧:
1.$(error yuebao===============>test)
Android.mk或Makefile运行到这个语句make会停止,并在中断报错2.$(waring $(BUILD_PACKAGE))
可以打印信息在终端
更多参考可见:
http://groups.google.com/group/android-building/msg/56676963a5616b57