android进阶——源码编译之产品配置和常用的make脚本模板(代码片段)

CrazyMo_ CrazyMo_     2023-03-01     489

关键词:

文章大纲

引言

前面文章总结了MakeFile基础语法和对Android.mk的进行了解读,这篇文章将从整体上概述下AOSP 编译时的产品配置相关知识。Android 的产品配置文件的作用是按照Build系统的要求,将生成产品的各种image文件所需要的对应信息(如版本号等各种参数)、资源(图片、字体、多媒体等)、二进制文件(apk、jar、so库等)有机组织起来,同时根据配置文件进行裁剪或增加模块,所谓系统支持在一定程度上其实就像将相应的资源添加到对应的文件中。

比如PRODUCT_APPT_CONFIG :=normal hdpi xhdpi xxhdpi xxxhdpi指定了系统中能够支持的屏幕密度类型(dip),在编译时就将相应的资源添加到framework_res.apk之中。

一、编译类型eng、user和userdebug

1、eng

默认的编译类型,该编译类型适用于开发阶段,执行makemake eng,编译时以下模块将安装进系统:

  • 在Android.mk里使用LOCAL_MODULE_TAGS变量定义了标签为 eng、debug、shell_$(TARGET_SHELL)、user和development的模块
  • 非APK模块且不带任何标签的模块
  • 所有产品配置文件中指定的APK模块

编译后adb是默认开启的,附带以下系统属性:

  • ro.secure=0
  • ro.debuggable=1
  • ro.kernel.android.checkjni=1

2、user

该编译类型适合用于最终发布阶段,编译时以下模块将安装进系统:

  • 在Android.mk里使用LOCAL_MODULE_TAGS变量定义了标签为 shell_$(TARGET_SHELL)和user的模块
  • 非APK模块且不带任何标签的模块
  • 所有产品配置文件中指定的APK模块,同时忽略其标签属性

编译后adb是默认不开启,需要自己手动打开,附带以下系统属性:

  • ro.secure=0
  • ro.debuggable=0

3、userdebug

该编译类型适合用于 debug 阶段,编译时以下模块将安装进系统:

  • 在Android.mk里使用LOCAL_MODULE_TAGS变量定义了标签为 `shell_$(TARGET_SHELL)、user和debug
  • 非APK不带任何标签的模块
  • 非APK模块且不带任何标签的模块
  • 所有产品配置文件中指定的APK模块,同时忽略其标签属性

编译后具有root权限,adb是默认不开启,需要自己手动打开,附带以下系统属性:

  • ro.secure=0
  • ro.debuggable=1

系统属性的前缀含义

前缀说明
ro.read only 只读属性,意境设置不可改变
persist.persistent 设置的值即使关机重启后依然生效,因为设置这个前缀的属性时会同时写入到/data/property下与属性同名的文件中,再次开机时会被init进程读出来使用
net.设置这个前缀的属性时将会被自动设置为最后修改的属性名
ctl.ctl.start、ctl.stop、ctl.restart 控制类属性,同于控制服务启动或者停止。

二、产物里的Image 文件

AOSP 编译成功后会默认生成几个Image 镜像文件:boot.img、system.img、recovery.img和userdata.img。

1、boot.img

boot.img一种Android 自定义的文件格(包含adbd和init.rc文件),包括了一个2*1024字节的文件头,接着是用gzip压缩过的linux kernel镜像,紧接着是一个ramdisk镜像,最后是BootLoader程序。

2、recovery.img

recovery.img 相当于是一个微型的文本界面Linux 系统,其作用就是恢复或升级系统,通常在sbin目录下会有一个recovery可执行程序,recovery也包含了adbd和init.rc文件,但与boot.img的不一样。

3、system.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文件系统属性的定义文件

4、userdata.img

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标准的动态链接库接口。

四、常用模块的Makefile脚本模板

在不同的模块定义文件中个,使用个不同的编译变量。

1、编译一个APK

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)

2、编译一个Java 共享库和静态库

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) 编译静态库

3、编译一个Native 共享库和静态库

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)

1、定义一个预编译APK

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)

2、定义一个预编译的静态jar

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)

3、定义一个预编译的动态库so

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)

4、定义一个预编译的可执行文件

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)

android进阶——源码编译之产品配置和常用的make脚本模板(代码片段)

...译的可执行文件引言前面文章总结了MakeFile基础语法和对Android.mk的进行了解读,这篇文章将从整体上概述下AOSP编译时的产品配置相关知识。Android的产品配置文件的作用是按照Build系统的要求,将生成产品的各种image文件... 查看详情

android之源码之模块编译和调试

                                 &n 查看详情

android进阶——framework核心之dumpsys命令浅析(代码片段)

文章大纲引言一、Dumpsys命令概述二、Dumpsys命令语法详解1、Package信息查询2、Activity信息查询3、网络信息查询4、其他常用服务信息查询三、Dumpsys命令实现原理1、安卓binder服务管理2、Dumpsys源码分析引言Dumpsys是安卓系统提供用来... 查看详情

android进阶——framework核心之dumpsys命令浅析(代码片段)

文章大纲引言一、Dumpsys命令概述二、Dumpsys命令语法详解1、Package信息查询2、Activity信息查询3、网络信息查询4、其他常用服务信息查询三、Dumpsys命令实现原理1、安卓binder服务管理2、Dumpsys源码分析引言Dumpsys是安卓系统提供用来... 查看详情

我的android进阶之旅ndk开发之cmake自定义搜索规则,减少每次都需要配置.cpp和.h的工作量(代码片段)

一、需求描述之前一篇文章【我的Android进阶之旅】AndroidStudio添加新的.Cpp和.h文件之后,代码不高亮,代码不可跳转的问题,写代码也没有提示写了添加一个新的.cpp和.h文件,因为路径写错了,导致代码不高亮也不可以跳转的问... 查看详情

我的android进阶之旅ndk开发之cmake自定义搜索规则,减少每次都需要配置.cpp和.h的工作量(代码片段)

一、需求描述之前一篇文章【我的Android进阶之旅】AndroidStudio添加新的.Cpp和.h文件之后,代码不高亮,代码不可跳转的问题,写代码也没有提示写了添加一个新的.cpp和.h文件,因为路径写错了,导致代码不高亮也不可以跳转的问... 查看详情

android进阶系列之percentsupportlibrary使用详解

原文链接:https://blog.csdn.net/sw5131899/article/details/53995796AndroidPercentLibrary    那么来看看都咋用吧。首先需要在Gradle里加入依赖。 compile‘com.android.support:percent:24.2.0‘ 看清楚自己的compileSdkVersion,我的版本是24。根... 查看详情

面向对象之进阶

简介:python中关于OOP的常用术语面向对象的软件开发一、Python中关于oop的常用术语抽象/实现抽象指对现实世界问题和实体的本质表现,行为和特征建模,建立一个相关的子集,可以用于绘程序结构,从而实现这种模型。抽象不仅包括... 查看详情

产品经理进阶第二课,axure实操之原型分类以及安装步骤和面板认识

〝古人学问遗无力,少壮功夫老始成〞axure作为产品经理必会的软件之一,接下来的几课将会详细教会大家如何去使用axure这个软件,助力大家在产品的道路上走的更远。常码字不易,出精品更难,没有特别幸运,那么请先特别... 查看详情

产品经理进阶第二课,axure实操之原型分类以及安装步骤和面板认识

〝古人学问遗无力,少壮功夫老始成〞axure作为产品经理必会的软件之一,接下来的几课将会详细教会大家如何去使用axure这个软件,助力大家在产品的道路上走的更远。常码字不易,出精品更难,没有特别幸运,那么请先特别... 查看详情

pytest进阶之配置文件(代码片段)

前言  pytest配置文件能够改变pytest框架代码的运行规则。比如修改pytest收集用例的规则,添加命令行参数等等!下面我们来一一讲解常用的一些配置项Help通过命令pytest--help查看配置文件中可以添加的一些参数及选项,这些选... 查看详情

androidndk——源码编译脚本之makefile基础语法和android.mk小结(代码片段)

文章大纲引言一、Android.mk概述二、Android.mk基本语法1、Makefile是以模块为单位进行组织的2、编译系统预留的部分系统变量2.1、LOCAL_PATH(必须)2.2、CLEAR_VARS(必须)2.3、LOCAL_MODULE(必须)2.4、**LOCAL_SRC_FILES**... 查看详情

androidndk——源码编译脚本之makefile基础语法和android.mk小结(代码片段)

文章大纲引言一、Android.mk概述二、Android.mk基本语法1、Makefile是以模块为单位进行组织的2、编译系统预留的部分系统变量2.1、LOCAL_PATH(必须)2.2、CLEAR_VARS(必须)2.3、LOCAL_MODULE(必须)2.4、**LOCAL_SRC_FILES**... 查看详情

rsa进阶之共模攻击(代码片段)

适用场景:同一个n,对相同的m进行了加密,e取值不一样。e1和e2互质,gcd(e1,e2)=1如果满足上述条件,那么就可以在不分解n的情况下求解m原理复杂的东西简单说:如果gcd(e1,e2)=1,那么就有e1*s1+e2*s2=1,s1和s2一正一负。最后会推出来... 查看详情

前端进阶之---常用常用再常用的缓存

在前端面试过程中,缓存几乎是必问的问题之一了,记得我有一次面试的时候,面试官让我说一下缓存的知识,我很自然就说出了localStorage,sessionStorage,cookie三者之间的不同点以及各自的特性,当我还在感觉自我回答很良好的时... 查看详情

产品经理进阶第九课,axure实操之全局变量的使用

 〝古人学问遗无力,少壮功夫老始成〞在axure的页面中共享变量,因为axure的页面中数据是无法共享的,如果想要共享,就需要用到全局变量,比如你在登陆页面中输入账号密码,另一个页面中可以知道你输入的账号和密码... 查看详情

产品经理进阶第九课,axure实操之全局变量的使用

 〝古人学问遗无力,少壮功夫老始成〞在axure的页面中共享变量,因为axure的页面中数据是无法共享的,如果想要共享,就需要用到全局变量,比如你在登陆页面中输入账号密码,另一个页面中可以知道你输入的账号和密码... 查看详情

django进阶之viewlayer(代码片段)

一基本环境1环境处理mkdirdjanadcddjanad/pyenvvirtualenv3.6.5djanadpyenvlocaldjanad结果如下2创建django和基本配置pipinstalldjango==2.1django-adminstartprojectdemo.django-adminstartappapp结果如下数据库配置如下基本时区和mysql配置及相关时区配置请看django基... 查看详情