赞
踩
前面文章总结了MakeFile基础语法和对Android.mk的进行了解读,这篇文章将从整体上概述下AOSP 编译时的产品配置相关知识。Android 的产品配置文件的作用是按照Build系统的要求,将生成产品的各种image文件所需要的对应信息(如版本号等各种参数)、资源(图片、字体、多媒体等)、二进制文件(apk、jar、so库等)有机组织起来,同时根据配置文件进行裁剪或增加模块,所谓系统支持在一定程度上其实就像将相应的资源添加到对应的文件中。
比如
PRODUCT_APPT_CONFIG :=normal hdpi xhdpi xxhdpi xxxhdpi
指定了系统中能够支持的屏幕密度类型(dip),在编译时就将相应的资源添加到framework_res.apk之中。
默认的编译类型,该编译类型适用于开发阶段,执行make
即make eng
,编译时以下模块将安装进系统:
LOCAL_MODULE_TAGS
变量定义了标签为 eng、debug、shell_$(TARGET_SHELL)、user和development
的模块编译后adb是默认开启的,附带以下系统属性:
该编译类型适合用于最终发布阶段,编译时以下模块将安装进系统:
LOCAL_MODULE_TAGS
变量定义了标签为 shell_$(TARGET_SHELL)和user
的模块编译后adb是默认不开启,需要自己手动打开,附带以下系统属性:
该编译类型适合用于 debug 阶段,编译时以下模块将安装进系统:
LOCAL_MODULE_TAGS
变量定义了标签为 `shell_$(TARGET_SHELL)、user和debug编译后具有root权限,adb是默认不开启,需要自己手动打开,附带以下系统属性:
系统属性的前缀含义
前缀 说明 ro. read only 只读属性,意境设置不可改变 persist. persistent 设置的值即使关机重启后依然生效,因为设置这个前缀的属性时会同时写入到/data/property下与属性同名的文件中,再次开机时会被init进程读出来使用 net. 设置这个前缀的属性时将会被自动设置为最后修改的属性名 ctl. ctl.start、ctl.stop、ctl.restart 控制类属性,同于控制服务启动或者停止。
AOSP 编译成功后会默认生成几个Image 镜像文件:boot.img、system.img、recovery.img和userdata.img。
boot.img一种Android 自定义的文件格(包含adbd和init.rc文件),包括了一个2*1024字节的文件头,接着是用gzip压缩过的linux kernel镜像,紧接着是一个ramdisk镜像,最后是BootLoader程序。
recovery.img 相当于是一个微型的文本界面Linux 系统,其作用就是恢复或升级系统,通常在sbin目录下会有一个recovery可执行程序,recovery也包含了adbd和init.rc文件,但与boot.img的不一样。
system.img就是设备系统目录system下的镜像,包含了Android主要的目录和文件。
目录名 | 说明 |
---|---|
app | 存放普通apk |
bin | 存放Linux的一些工具,大部分是toolbox的链接 |
etc | 存放系统配置文件 |
fonts | 存放系统字体文件 |
framework | 存放系统所有的jar、art、oat包和资源文件包 |
lib | 存放系统的共享库so |
media | 存放系统多媒体资源,主要是铃声 |
priv-app | 存放系统核心APK文件 |
tts | 存放系统语音合成文件 |
usr | 存放各种键盘布局、时间区域文件 |
vendor | 存放第三方厂商的配置文件、firmware及动态库 |
xbin | 存放系统管理工具,相当于是Linux下的sbin |
build.prop文件 | 系统属性的定义文件 |
userdata.img 是设备中data目录的镜像,初始化时一般不包含任何文件,是由Android系统初始化时在/data目录下创建一些子目录和文件的。
Android.mk文件可以编译出不同的模块,本质上是通过include $(BUILD_)
指令把其他模块编译文件包含进来,常见的模块编译变量(以BUILD_为前缀)有:
编译变量 | 说明 |
---|---|
BUILD_HOST_STATIC_LIBRARY | 包含host_static_library.mk文件,生成编译平台的本地静态库 |
BUILD_HOST_SHARED_LIBRARY | 包含host_shared_library.mk文件,生成编译平台的本地共享库 |
BUILD_STATIC_LIBRARY | 包含static_library.mk文件,生成目标系统的本地静态库 |
BUILD_SHARED_LIBRARY | 包含shared_library.mk文件,生成目标系统的本地共享库 |
BUILD_HOST_EXECUTABLE | 包含host_executable.mk文件,生成编译平台的Linux可执行程序 |
BUILD_EXECUTABLE | 包含executable.mk文件,生成目标系统的Linux可执行程序 |
BUILD_PACKAGE | 包含package.mk文件,生成apk |
BUILD_HOST_PREBUILT | 包含host_prebuilt.mk文件,生成编译平台的预编译模块 |
BUILD_PREBUILT | 包含prebuilt.mk文件,生成目标系统的预编译模块并将这个预编译模块引入系统 |
BUILD_MULTI_PREBUILT | 包含multi_prebuilt.mk文件,生成目标系统的多个预编译模块并将这些预编译模块引入系统 |
BUILD_JAVA_LIBRARY | 包含java_library.mk文件,生成Java 共享库 |
BUILD_STATIC_JAVA_LIBRARY | 包含java_static_library.mk文件,生成Java 静态库 |
动态链接库显示调用的方法:
Java层,使用System.loadLibrary(String libName)和System.load(String pathName),前者只需要支出动态链接库的名称,系统负责在预先设置的路径中去查找并加载正确的so库;后者允许将动态链接库存储到任何程序有权限访问的地方,由pathName给出完整的加载路径。这两个函数的实现主题在libjavacore.so库中,这个库是Runtime在启动过程中通过LoadNativeLibrary来加载的。
Native层,使用dlopen,dlsym等Linux标准的动态链接库接口。
在不同的模块定义文件中个,使用个不同的编译变量。
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_JAVA_LIBRARIES := #依赖的Java 共享库 LOCAL_SHARED_JAVA_LIBRARIES := #依赖的Java 静态库 # 使用系统函数自动搜索src 目录下的java文件形成的源码列表 LOCAL_SRC_FILES:= $(call all-java-files-under, src) #LOCAL_C_INCLUDES := #LOCAL_STATIC_LIBRARIES := #LOCAL_SHARED_LIBRARIES := LOACAL_MODULE_TAGS:= #可选的模块标签 LOCAL_CERTIFICATE:= #APK 签名方式 LOCAL_PACKAGE_NAME:= #apk名称 include $(BUILD_PACKAGE)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_JAVA_LIBRARIES := #依赖的Java 共享库
LOCAL_SHARED_JAVA_LIBRARIES := #依赖的Java 静态库
# 使用系统函数自动搜索src 目录下的java文件形成的源码列表
LOCAL_SRC_FILES:= $(call all-java-files-under, src)
LOACAL_MODULE_TAGS:= #可选的模块标签
LOCAL_MODULE:= #java库名称
include $(BUILD_JAVA_LIBRARY) #编译共享库
# include $(BUILD_STATIC_JAVA_LIBRARY) 编译静态库
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=helloworld.c #c源文件
LOCAL_MODULE:= libtest_static #库名称
LOCAL_C_INCLUDES := # 编译标志
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES :=
include $(BUILD_SHARED_LIBRARY)
# include $(BUILD_STATIC_LIBRARY) 编译静态库
在实际系统开发中,并不会向Android一样将所有的源码一起编译,事实上有很多的APK、jar包都是需要预先编译好的,编译时通过PRODUCT_COPY_FILES
变量将这些二进制文件复制到生成的image文件中。但是针对一些APK或者jar包需要使用系统签名才能正常运行或者系统所需的依赖动态库文件,这种简单复制方式就不行了。于是Android 定义预编译模块来解决之,定义一个预编译模块和定义上面那种普通模块语法相似,区别在于预编译模块的LOCAL_SRC_FILES
变量配置的是二进制文件的路径且需要配合LOCAL_MODULE_CLASS
来设置模块类型,最后再通过include $(BUILD_PREBUILT)
。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Module name should match apk name to be installed 系统唯一的名称
LOCAL_MODULE := LamyNetServer
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS #类别是APK
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := platform # 使用系统的platform级别签名
LOCAL_PROGUARD_ENABLED := disabled
LOCAL_DEX_PREOPT := false
LOCAL_PRIVILEGED_MODULE := true
include $(BUILD_PREBUILT)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := xxxxx
LOCAL_SRC_FILES :=app/$(LOCAL_MODULE)
LOCAL_MODULE_CLASS := JAVA_LIBRARIES #类别是Java静态jar包
LOCAL_CERTIFICATE := platform # 使用系统的platform级别签名
include $(BUILD_PREBUILT)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := xxxxx
LOCAL_SRC_FILES :=app/$(LOCAL_MODULE)
LOCAL_MODULE_CLASS := SHARED_LIBRARIES #类别是SHARED_LIBRARIES
include $(BUILD_PREBUILT)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := xxxxx
LOCAL_SRC_FILES :=
LOCAL_MODULE_CLASS := EXECUTABLES #类别是EXECUTABLES
include $(BUILD_PREBUILT)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。