一 .build/envsetup.sh中定义的常用函数
croot 切换到源码树的根目录
m 在源码树的根目录执行 make
mm Build 当前目录下的模块
mmm Build 指定目录下的模块 mmm system/core/init
cgrep 在所有 C/C++ 文件上执行 grep
jgrep 在所有 Java 文件上执行 grep
resgrep 在所有 res/*.xml 文件上执行 grep
godir 转到包含某个文件的目录路径
printconfig 显示当前 Build 的配置信息
add_lunch_combo 在 lunch 函数的菜单中添加一个条目
二. out目录
/out/host/:该目录下包含了针对主机的 Android 开发工具的产物。即 SDK 中的各种工具,例如:emulator,adb,aapt 等。
/out/target/common/:该目录下包含了针对设备的共通的编译产物,主要是 Java 应用代码和 Java 库。
/out/target/product/<product_name>/:包含了针对特定设备的编译结果以及平台相关的 C/C++ 库和二进制文件。其中,<product_name>是具体目标设备的名称。
三.mk 文件
main.mk 最主要的 Make 文件,该文件中首先将对编译环境进行检查,同时引入其他的 Make 文件。另外,该文件中还定义了几个最主要的 Make 目标,例如 droid,sdk,等。
help.mk 包含了名称为 help 的 Make 目标的定义,该目标将列出主要的 Make 目标及其说明。
pathmap.mk 将许多头文件的路径通过名值对的方式定义为映射表,并提供 include-path-for 函数来获取。
例如,通过 $(call include-path-for, frameworks-native)便可以获取到 framework 本地代码需要的头文件路径。
envsetup.mk 配置 Build 系统需要的环境变量,例如:TARGET_PRODUCT,TARGET_BUILD_VARIANT,HOST_OS,HOST_ARCH 等。
当前编译的主机平台信息(例如操作系统,CPU 类型等信息)就是在这个文件中确定的。
combo/select.mk 根据当前编译器的平台选择平台相关的 Make 文件。
config.mk 整个 Build 系统的配置文件,最重要的 Make 文件之一。该文件中主要包含以下内容:
定义了许多的常量来负责不同类型模块的编译。
定义编译器参数以及常见文件后缀,例如 .zip,.jar.apk。
根据 BoardConfig.mk 文件,配置产品相关的参数。
设置一些常用工具的路径,例如 flex,e2fsck,dx。
definitions.mk 最重要的 Make 文件之一,在其中定义了大量的函数。这些函数都是 Build 系统的其他文件将用到的。
例如:my-dir,all-subdir-makefiles,find-subdir-files,sign-package 等,关于这些函数的说明请参见每个函数的代码注释。
${ONE_SHOT_MAKEFILE} ONE_SHOT_MAKEFILE 是一个变量,当使用“mm”编译某个目录下的模块时,此变量的值即为当前指定路径下的 Make 文件的路径。
四,模块
Android 源码中包含了许多的模块,模块的类型有很多种,例如:Java 库,C/C++ 库,APK 应用,以及可执行文件等 .
Java 或者 C/C++ 库还可以分为静态的或者动态的,库或可执行文件既可能是针对设备(本文的“设备”指的是 Android 系统将被安装的设备,例如某个型号的手机或平板)的也可能是针对主机
在 config.mk 中定义了许多的常量,这其中的每个常量描述了一种类型模块的编译方式,这些常量有:
BUILD_HOST_STATIC_LIBRARY
BUILD_HOST_SHARED_LIBRARY
BUILD_STATIC_LIBRARY
BUILD_SHARED_LIBRARY
BUILD_EXECUTABLE
BUILD_HOST_EXECUTABLE
BUILD_PACKAGE
BUILD_PREBUILT
BUILD_MULTI_PREBUILT
BUILD_HOST_PREBUILT
BUILD_JAVA_LIBRARY
BUILD_STATIC_JAVA_LIBRARY
BUILD_HOST_JAVA_LIBRARY
host_static_library.mk 定义了如何编译主机上的静态库。
host_shared_library.mk 定义了如何编译主机上的共享库。
make snod 从已经编译出的包快速重建系统镜像。
make libandroid_runtime 编译所有 JNI framework 内容。
makeframework 编译所有 Java framework 内容。
makeservices 编译系统服务和相关内容。
五.依赖
在 Android Build 系统中,编译是以模块(而不是文件)作为单位的,每个模块都有一个唯一的名称,一个模块的依赖对象只能是另外一个模块,而不能是其他类型的对象。对于已经编译好的二进制库,如果要用来被当作是依赖对象,那么应当将这些已经编译好的库作为单独的模块。
对于这些已经编译好的库使用 BUILD_PREBUILT 或 BUILD_MULTI_PREBUILT。例如:当编译某个 Java 库需要依赖一些 Jar 包时,并不能直接指定 Jar 包的路径作为依赖,
而必须首先将这些 Jar 包定义为一个模块,然后在编译 Java 库的时候通过模块的名称来依赖这些 Jar 包。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
设置当前模块的编译路径为当前文件夹路径。
清理(可能由其他模块设置过的)编译环境中用到的变量。
LOCAL_SRC_FILES:当前模块包含的所有源代码文件。
LOCAL_MODULE:当前模块的名称,这个名称应当是唯一的,模块间的依赖关系就是通过这个名称来引用的。
LOCAL_C_INCLUDES:C 或 C++ 语言需要的头文件的路径。
LOCAL_STATIC_LIBRARIES:当前模块在静态链接时需要的库的名称。
LOCAL_SHARED_LIBRARIES:当前模块在运行时依赖的动态库的名称。
LOCAL_CFLAGS:提供给 C/C++ 编译器的额外编译参数。
LOCAL_JAVA_LIBRARIES:当前模块依赖的 Java 共享库。
LOCAL_STATIC_JAVA_LIBRARIES:当前模块依赖的 Java 静态库。
LOCAL_PACKAGE_NAME:当前 APK 应用的名称。
LOCAL_CERTIFICATE:签署当前应用的证书名称。
LOCAL_MODULE_TAGS:当前模块所包含的标签,一个模块可以包含多个标签。标签的值可能是 debug, eng, user,development 或者 optional。其中,optional 是默认标签。标签是提供给编译类型使用的。不同的编译类型会安装包含不同标签的模块
六 打包
make_ext4fs
制作ext4文件系统的镜像
make_ext4fs -l 512M -s -a system system.ext4img system
之后再使用simg2img制作镜像。
使用这样制作的镜像,system分区文件的权限都是预定的,即使先修改system目录文件权限后在制作镜像,烧入设备后,其权限仍未改变。关键问题在make_ext4fs工具,在制作ext4fs时更改了权限,其依据为system/core/private/android_ilesystem_config.h所定义的权限。
-s 就是生成ext4的S模式制作;
"-a system",是指这个img用于android系统,挂载点是/system,
使用这个参数,make_ext4fs会根据private/android_filesystem_config.h里定义好的权限来给文件夹里的所有文件重新设置权限
file system_new.img
system_new.img: data
simg2img
./simg2img system_new.img system_out.img
file system_out.img
system_out.img: Linux rev 1.0 ext4 filesystem data, UUID=57f8f4bc-abf4-655f-bf67-946fc0f9f25b (extents) (large files)
用来将system.img还原来ext4镜像(通过make_ext4fs制作的ext4镜像包含了spare数据,无法以loop方式mount)
raw和sparse。
一种是raw ext4 image,即经常说的raw image,使用file观察它: 其特点是完整的ext4分区镜像(包含很多全零的无效填充区),可以直接使用mount进行挂载,因此比较大。
sparse 将raw ext4进行稀疏描述,因此尺寸比较小.
七. ccache
$ export USE_CCACHE=1
默认cache存储在~/.ccache.
可以使用下列命令来设置路径
$ export CCACHE_DIR=<path-to-your-cache-directory>
推荐的cache大小为50-100GB.
可以使用下列命令来设置cache size
$ prebuilt/linux-x86/ccache/ccache -M 50G (工程目录下运行)
可以使用以下命令来查看ccache的运行状况:
$ watch -n1 -d prebuilt/linux-x86/ccache/ccache -s (工程目录下运行)
八 编译错误
- 拷贝目录
我們想把Vender/a_folder/files/目錄下的所有檔案copy到out/target/product/target_product/system/data/example/目錄下該如血Android.mk呢?
PRODUCT_COPY_FILES += \
$(call find-copy-subdir-files,*,$(LOCAL_PATH)/files,system/data/example)
*如果文件名中包含空格,会导致无法拷贝
unreported exception java.rmi.RemoteException; must be caught or declared t
native 调用需要在try/catch中。