图1 android 的makefile结构
android的编译文件主要依赖于mk文件,其源码编译名字是Android.mk,而不我们常见的Makefile文件。
android目录下的Makefile文件,include了build/core目录下的main.mk文件。
main.mk文件
main.mk要完成功能,主要如下:
包含build/core/config.mk:根据目标板的标准变量和主机信息,设置一些变量。确定输出目录和产品工程。
SHELL := /bin/bash, 表明用到系统bash,如果想用其他的sh,那么据此而改即可。
检测host的操作系统,编译环境。
包含definitions.mk,标准的编译系统设定参数。主要是一些宏定义,如在Android.mk常见到的all-subdir-makefiles、my-dir之类的宏。
主要内容还是在 config.mk文件。
1config.mk
首先会检测主目录下的buildspec.mk,目前此文件不存在,我们可在此设置一些参数。
这些参数,可用于envsettup.mk,如果没有buildspec.mk文件,envsettup.mk则默认一些变量,如TARGET_ARCH:= arm ,TARGET_OS := linux等。
1.1 envsettup.mk
应该说envsettup.mk是config.mk重要组成部分,设置一些主要编译工程的相关参数。
首先includeversion_defaults.mk,设置以下变量:
PLATFORM_VERSION
PLATFORM_SDK_VERSION
DEFAULT_APP_TARGET_SDK
BUILD_ID
BUILD_NUMBER
其次设定TARGET_PRODUCT,也就是在编译地时候如果没有用makePRODUCT-xxx-xxx,则会在此处设定。否则就要根据product_config.mk文件里的内容进行target和product的相关参数。
再次,设置一些输出文件路径变量,如TARGET_OUT_XXX之类的。
最后把一些简单信息显示终端上:
$(info============================================)
$(info PLATFORM_VERSION_CODENAME=$(PLATFORM_VERSION_CODENAME))
$(info PLATFORM_VERSION=$(PLATFORM_VERSION))
$(info TARGET_PRODUCT=$(TARGET_PRODUCT))
$(info TARGET_BUILD_VARIANT=$(TARGET_BUILD_VARIANT))
$(info TARGET_SIMULATOR=$(TARGET_SIMULATOR))
$(info TARGET_BUILD_TYPE=$(TARGET_BUILD_TYPE))
$(info TARGET_ARCH=$(TARGET_ARCH))
$(info HOST_ARCH=$(HOST_ARCH))
$(info HOST_OS=$(HOST_OS))
$(info HOST_BUILD_TYPE=$(HOST_BUILD_TYPE))
$(info BUILD_ID=$(BUILD_ID))
$(info============================================)
envsetup.mk里头最主要的就是product_config.mk
product_config.mk包含三个文件node_fns.mk、product.mk和device.mk。此三文件都是一些宏定义或变量定义,目的是根据make时传进来的参数,从vendor目录和build/target目录下,找到相应的product和devcie信息,即找BoardConfig.mk文件,从而设定TARGET_PRODUCT、TARGET_DEVICE等值。
1.2 pathmap.mk,一些头文件路径,及androidframework目录。
编译系统内部的一些文件:host_static_library.mk、host_shared_library.mk等
1.3 BoardConfig.mk
默认情况下是编译的board是generic。
查找build/target/board/generic目录上的内容,共有两个mk文件,AndroidBoard.mk和BoardConfig.mk。其中BoardConfig.mk定义一些硬件特性。
2 Makefile文件
build/core/Makefile文件是系统集成了,完成img,app,frameworks、模块的编译(可能有错)
3 对于framework开发,或者在系统移植时添加应用程序,每写一次代码就要进行编译,而每次用make相关参数命令时,编译的时间会比较长。这时可以考虑以下方式进行编译
cdanddroid_top_path
./build/envsetup.sh
此时就用mmm,mm和m命令进行编译:
m表示在顶层目录进行编译
mm 表示在当前目录下进行模块编译
mmm path, 编译path目录下的模块。
一般在写模块时,用mmm命令就可以了。
以下是转载内容,在framework新增加或修改代码,所谓的系统移植了,链接地址为http://xxw8393.blog.163.com/blog/static/3725683420107532137920/
“
如何向android的framework里添加新类
google对于所有的类和API,分为开放式和不开放式两种。所谓的开放式就是值javadoc所包含 的,并不是java中有public和private,而是跟javadoc有关系,代码没有关系。
在开放式的类中增加了一个变量,而又没隐藏,导致和原API的doc不一致造成的就会有错。
通过提示,有2个方法可以解决 该问题:
1、将新增加的变量或方法加上"@hide" 的注释,注意一点,加"@hide" 不是简简单单 的/*@hide */就行了,标准的javadoc要这样 /** */ 而且对于 format 变量 应该加上 { }, 也就是/**{@hide}*/
2、如果想在生成的doc中增加该变量或方法的话,必须输入:
make update-api
这样的话,系统 自动 将新增加的API添加到current.xml中了。
所以如果要加方法就是按上面的方法加。
如果需要加进新的类 这时候又分2种 :一种是原有的包下面加类 这个最简单 加完之后直接make update-api就好了 还有一种是加在framework/base下面 这个时候你make update-api是不会在current。xml里生成你的类的。 看了Android。mk才知道 原来需要修改 android源码根目录下的build/core/pathmap.mk把你的目录加进去。然后就好了。
”
事实上对于famework的开发,可以通过mmm命令生成新jar包,然后手动的方式传到模块器对应目录,一般是/system/framework/即可,当然也可以自己写个脚本,敲一命令,一步到位亦可。