目录
- 一、应用预置
- 二、应用预置分区
- 三、编译规则
- 3.1 Android.mk
- 3.2 Android.bp
一、应用预置
预置指智能终端设备出厂前,将文件预先安装到系统中。预置对象包括应用程序、可执行文件、so库(.so 文件)、jar 包等。
预置方式有以下两种:
- 预编译方式
-如果文件有明确的预编译规则,且预编译不破坏当前程序完整性,则可使用预编译方式。
-如果文件有其他模块编译依赖,或需要系统签名,则需要定义一个预编译模块,例如一些 so库、apk 文件、jar 包等。
预置应用时,可使用变量 LOCAL_CERTIFICATE 指定签名类型Android.mk。- 复制方式
-将文件复制到目标目录,参与打包即可实现预置。
-使用 shell 命令“cp”进行复制。
-如果文件只需预置到指定目录,将该文件添加到 PRODUCT_COPY_FILES 变量中即可。例如一些 bin 文件、配置文件
二、应用预置分区
应用预置目录常见的应用预置分区包括 system、system_ext、product、vendor、odm、data 等。不同的分区下安装路径所对应的权限和域不相同,如 system,system_ext 属于 system 域,data 主要用于在线安装第三方的应用,除 data 外其余分区都属于 vendor 域。
定义宏 PARTITION 为 system_ext、product、vendor、odm 中的任意一个分区。应用预置目录说明如下图所示
三、编译规则
编译规则有 Android.mk 和 Android.bp 两种,可根据需求选择编译规则。Android.mk 在 Android 13.0 之后的安卓版本中会被淘汰,建议使用 Android.bp作为编译规则
3.1 Android.mk
Android.mk 中,每个编译模块都以 include $(CLEAR_VARS)开始,以 include $(BUILD_xxx)结束,示例如下。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := myapp
LOCAL_SRC_FILES := app/myapp.apk
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/app
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_TAGS := optional
LOCAL_CERTIFICATE := platfrom
LOCAL_SHARED_LIBRARIES := liba libc
LOCAL_MULTILIB := 64
include $(BUILD_PREBUILT)
LOCAL_PATH
模块编译路径,需要与 Android.mk 脚本在同一目录。每一个 Android.mk 文件必须先定义LOCAL_PATH。my-dir 是系统提供的宏函数,$(call my-dir)将返回当前目录(Android.mk 文件本身所在的目录)的路径。
Build 系统中还定义了一些便捷的函数以便在 Android.mk 中使用,例如:
−$(call all-java-files-under,xxx):获取指定目录下的所有 Java 文件。
−$(call all-c-files-under,xxx):获取指定目录下的所有 C 文件。
−$(call all-Iaidl-files-under,xxx):获取指定目录下的所有 AIDL 文件。
−$(call all-makefiles-under,xxx):获取指定目录下的所有 make 文件。
**include $(CLEAR_VARS)**CLEAR_VARS 是系统提供的宏变量,用于清理除 LOCAL_PATH 以外的所有 LOCAL_XXX 变量。整个编译上下文中,所有的变量都是全局变量,CLEAR_VARS 可以保证这些变量只在局部范围内起作用。LOCAL_PATH 要求在每个模块中都要设置,无需清空。
LOCAL_MODULE
模块名称,是模块在编译中的唯一标识,该值必须唯一且不包含空格。模块间的依赖关系通过模块名称进行引用。编译系统会根据编译类型自动添加适当的后缀,例如要编译成一个 apk,则生成myapp.apk。
LOCAL_SRC_FILES
模块生成目标文件所需要的所有 C 和/或 C++源文件列表,多个文件用空格隔开。
LOCAL_MODULE_PATH
指定模块编译产物的输出路径,都是 out 目录下的子目录。如果 Android.mk 中没有指定该值,系统会根据“LOCAL_MODULE_CLASS”的值来生成。“LOCAL_MODULE_PATH”赋值主要应用在“BUILD_PREBUILT”模块的编译上,其他情况尽量采用默认值。常用值包括:
−TARGET_OUT:/system 目录
−TARGET_OUT_ETC:/system/etc 目录
−TARGET_OUT_VENDOR:/vendor 目录
−TARGET_OUT_DATA:/data 目录
以上目录均在 build/core/envsetup.mk 中有定义。
LOCAL_MODULE_CLASS
模块编译类型,用于定制 LOCAL_MODULE_PATH 的路径。当模块 include 不同编译类型选项时,系统会默认指定当前的 LOCAL_MODULE_CLASS 的值。但 include BUILD_PREBUILT 编译选项时,需要明确指定 LOCAL_MODULE_CLASS 的值,帮助系统确定 LOCAL_MODULE_PATH 的值。
如果不指定 LOCAL_MODULE_CLASS,编译产物不会放到系统中,会放在最后的 obj 目录下的对应目录。常用值包括:
−APPS:system/app 目录
−SHARED_LIBRARIES:system/lib 目录
−ETC:system/etc 目录
LOCAL_MODULE_TAGS
模块标签,表明该模块在什么版本下才编译。常用值包括:
−eng:工程师版本,用于开发调试
−user:用户发布版本
−userdebug:用户调试版本
−test:测试版本
−optional:所有版本,默认值
LOCAL_CERTIFICATE
模块签名方式,常用值包括:
−PERSIGNED:源 apk 自带的签名,编译过程不再重新签名。
−testkey:非 user 版本默认签名
−releasekey:user 版本默认签名
−platform:平台的核心应用签名,使用该签名的 apk 需要获取 platform signature,例如 Settings
−shared:使用该签名方式的 apk 需要和 home/contacts 进程共享数据,例如 Launcher
−media:使用该签名方式的 apk 是 media/download 系统中的一环,例如 Gallery
LOCAL_SHARED_LIBRARIES
模块在编译时依赖的动态库。模块的外部依赖一般包括:
−LOCAL_STATIC_LIBRARIES:模块所依赖的静态库
−LOCAL_STATIC_JAVA_LIBRARIES:模块所依赖的 Java 静态库(jar 包等)
−LOCAL_JAVA_LIBRARIES:模块所依赖的 Java 动态(共享)库
LOCAL_MULTILIB
使用 LOCAL_MULTILIB 变量可以配置要编译的 arch 架构。若不指定,系统根据模块类型和其他LOCAL_XXX 变量,决定构建的架构,如 LOCAL_MODULE_TARGET_ARCH。常用值包括:
−both:同时构建 32 位和 64 位架构
−32:仅构建 32 位架构
−64:仅构建 64 位架构
−first:仅构建第一个架构(在 32 位设备中构建 32 位架构,在 64 位设备中构建 64 位架构)
include $(BUILD_PREBUILT)
表示该模块的编译类型,它指向一个 NDK(Native Development Kit,Native 开发工具集)的默认脚本,会收集从上次调用 include $(CLEAR_VARS)后所有定义的 LOCAL_XXX 变量,然后根据它们定义模块的目标、依赖关系、编译命令和编译参数等。常用值包括:
−BUILD_PREBUILT:编译成一个预置程序
−BUILD_PACKAGE:编译成一个 apk 或者资源包文件
−BUILD_JAVA_LIARARY:编译成一个 Java 共享库
−BUILD_STATIC_JAVA_LIARARY:编译成一个 Java 静态库
−BUILD_EXECUTABLE:编译成一个可执行文件
−BUILD_SHARED_LIARARY:编译成一个 native 共享库,前缀为 lib,后缀为.so
3.2 Android.bp
Android.bp 定义一个模块类型,模块中包含的属性示例如下。
android_app_import {
name: "myapp",
src: "app/myapp.apk"
uses_libs: ["liba","libc"],
compile_multilib: "64",
vendor: true,
certificate: "platform",
}
android_app_import
模块编译类型,类似 Android.mk 中的“BUILD_XXX”。
name
:模块名称,唯一且必须存在,类似 Android.mk 中的“LOCAL_MODULE”。
src
:模块源文件,类似 Android.mk 中的“LOCAL_SRC_FILES”。
uses_libs
:模块在编译时依赖的动态库列表,类似 Android.mk 中的“LOCAL_USES_LIBRARIES”。
compile_multilib
:使用 compile_multilib 变量控制此模块是为 32 位、64 位还是两者都编译。常用值包括:
−both:同时构建 32 位和 64 位架构
−32:仅构建 32 位架构
−64:仅构建 64 位架构
−first:仅构建第一个架构
vendor
:当 vendor 设置为 true 时,安装该模块至/vendor 目录,如果 vendor 分区不存在,则安装到/system/vendor 目录。
certificate
:模块签名方式,类似 Android.mk 中的“LOCAL_CERTIFICATE”。