android 各模块的Android.mk文件说明及如何预置app到系统中

. 常见AOSP目录

目录名 介绍
build/core/Makefile AOSP整个编译过程中核心的编译规则makefile
build/envsetup.sh 编译初始化脚本
build/target AOSP自带的Target(模拟器)的一些makefile
build/tools/ 编译中使用的shell及python写的工具脚本
packagess 系统app以及一些provider,输入法等桌面看不到的app
framework/av/ 多媒体相关的native层源码目录
framework/webview/ 浏览器内核chromium的源码目录
framework/native/ power、surface、input、binder等服务的native层实现源码目录
framework/base/core/ framework.jar、framework-res.apk、libandroid_runtime.so等的源文件
framework/base/native/ libandroid.so的源代码目录.java中的api的native实现.比如looper,assertManager
framework/base/media/ 多媒体相关的JavaApi和jni层的源文件
framework/base/packages/ SettingProviders,SystemUI等不在桌面启动的APP源码
framework/base/service/ service.jar、libandroid_service.so的源文件,wifi服务相关的JavaApi,WifiManager,WifiService等
device/(vendor_name)/(product_name) 跟某些厂商的某个硬件平台相关的内核,硬件配置等
vendor/(vendor_name)/(product_name) 厂商对AOSP进行的修改或者定制,放在vendor目录。包括但不限于framework层新增API,新增APP等业务需求,但是现在Google更推荐放在devices目录下
/out/host 该目录下包含了针对当前操作系统所编译出的Android开发工具产物,例如adb,aapt,fastboot等命令
/out/target/common/ 该目录包含了针对Android设备的通用的编译产物,主要是java应用代码和java库。Framework.jar,services.jar,android.policy.jar等等
/out/target/(product)/(product_name) 包含了针对特定设备的编译结果以及平台相关的C/C++库和二进制文件。其中,product_name是具体目标设备的名称

2. AndroidBuildSystem

andorid build系统用来编译android系统,android sdk以及相关文档.该系统主要由make文件,shell脚本以及python脚本组成,在编译时能够支持面向不同的硬件设备,不同的编译类型,且提供面向各个厂商的定制扩展

2.1 什么是makefile

makefile是一些有特定语法的,可供make命令读取并执行的脚本性质的配置文件。作用就是可以告知编译系统,对哪些源文件进行编译,怎么编译,怎么处理依赖关系。makefile可以定义变量,函数,调用系统命令,shell、python脚本,管理module之间的依赖。整个Android Build系统中的 Make 文件可以分为三类:

  1. Build系统核心 Makefile
    这类makefile定义了整个Build系统的框架,而其他所有Make文件都是在这个框架的基础上编写出来的。位于/build/core目录下。
  2. 针对某个产品的Makefile
    这类makefile是针对某个产品Make文件,这些文件通常位于device//目录下。
  3. 针对某个模块的Makefile Android.mk
    第三类是针对某个模块的makefile文件.AOSP中,不会针对某一个文件进行编译,每一个编译单位都是一个模块,每一个模块由一个名为"Android.mk"的makefile来声明。该文件中定义了如何编译当前模块。

2.2 make文件中的内容

LOCAL_PATH := $(call my-dir)表示源代码的目录在哪
include $(CLEAR_VARS)表示变量全部清空,其中CLEAR_VARS也是一个makefile文件
LOCAL_MODULE_TAGS := optional表示是哪个TAG,可为eng,user,userdebug,optional等,在哪个版本下执行编译等...

3. ABS思维导图

ABS思维导图
ps:原谅我不会在markdown上画思维导图

android 各模块的Android.mk文件说明及如何预置app到系统中_第1张图片

android编译.png

 

略丑的流程图

ps:图不是重点,重点是掌握build系统的流程

android 各模块的Android.mk文件说明及如何预置app到系统中_第2张图片

ABS流程.jpg

附上文字描述:

第一步:  在项目根目录执行 make   命令即就找到当前目录的makefile文件,文件什么也没有就引用build/core/main.mk文件:
### DO NOT EDIT THIS FILE ###
include build/core/main.mk
### DO NOT EDIT THIS FILE ###

  1. build/core/main.mk:
    1. 检查当前的编译环境inclue build/core/下的核心makefile文件从而完成编译环境的配置
    2. 检索所有的BoardConfig.mkAndroidProduct.mk载入到编译系统
    3. main.mk里会使用python脚本遍历AOSP下的所有模块(AndroidProduct.mk)并include
  2. 所有模块下的AndroidProduct.mk:
    告诉编译系统,当前module的一些配置信息(源文件,依赖库等)和编译输出类型(可执行文件,共享库,静态库,java库,app等)。根据不同的输出类型,会include不同的makefile(package.mk java_library.mk等),这些makefile会调用相关的编译工具,达到编译目的



作者:RexHuang
链接:https://www.jianshu.com/p/d6e752636ba3
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。


#必备的两行,声明LOCAL_PATH变量,也就是当前的路径
#并清除其它变量
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

#包名,这生成的apk名字。这里的话会生成Hello.apk
LOCAL_PACKAGE_NAME := Hello

LOCAL_CERTIFICATE := platform

#如果使用的系统的包,需要引入他们使用的资源文件,否则会提示编译资源找不到的错误
LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/res
LOCAL_RESOURCE_DIR += frameworks/support/v7/appcompat/res
#LOCAL_RESOURCE_DIR += frameworks/support/v7/gridlayout/res
#LOCAL_RESOURCE_DIR += frameworks/support/v7/recyclerview/res

#指定该模块的编译版本为optional
#user: 指该模块只在user版本下才编译
#eng: 指该模块只在eng版本下才编译
#tests: 指该模块只在tests版本下才编译
#optional:指该模块在所有版本下都编译
LOCAL_MODULE_TAGS := tests

#源码所在目录,这里就在当前位置的java目录下。所以直接写java
LOCAL_SRC_FILES := $(call all-java-files-under, java)

#LOCAL_SRC_FILES += \
# src/xx/xx/xx/XxxOne.aidl \
# src/xx/xx/xx/XxxTwo.aidl

#依赖的jar包,包括系统的和第三方的(放在libs目录)jar包
LOCAL_STATIC_JAVA_LIBRARIES += android-support-v4 \
android-support-v7-appcompat
#android-support-v7-recyclerview


原文有详细说明关于混淆:https://blog.csdn.net/wolfboy2/article/details/51673429
#混淆文件名
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
#关闭混淆
LOCAL_PROGUARD_ENABLED := disabled

在需要混淆的工程目录下(package/apps/下的工程)添加proguard.flags文件,该文件即为网络传说中的proguard.cfg,只是命名不一样而已,然后再Android.mk中添加如下两句:
LOCAL_PROGUARD_ENABLED := full
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
上面的full 也可以是custom,如果不写这句,那还得添加如下一句:
TARGET_BUILD_VARIANT := user或者TARGET_BUILD_VARIANT := userdebug
这样后在工程目录下执行mm便可以看到在out目录下生成了形如proguard.classes.jar的东东,这就说明已在编译中启动了proguard
但反编译一看,并未出现网络云说的abcd替代符号,其实代码并未真正混淆:
android在编译时默认关闭了混淆选项,有去研究build/core目录的同志会发现这里也有个proguard.flags文件,其实在proguard的过程中,编译器会调用包括本地目录下和系统定义了的多个proguard.flags文件,而在这个文件中混淆的选项被禁止了,故而编译出来的apk仍未混淆。因此将如下句子注释掉便可实现真正的混淆编译:
# Don't obfuscate. We only need dead code striping.
-dontobfuscate(将该句加个#号注释掉)




LOCAL_AAPT_FLAGS := --auto-add-overlay
LOCAL_AAPT_FLAGS += --extra-packages android.support.v7.appcompat
#LOCAL_AAPT_FLAGS += --extra-packages android.support.v7.gridlayout
#LOCAL_AAPT_FLAGS += --extra-packages com.android.datetimepicker
#LOCAL_AAPT_FLAGS += --extra-packages android.support.v7.recyclerview

#打包成apk
include $(BUILD_PACKAGE)
include $(call all-makefiles-under,$(LOCAL_PATH))

 

如何将一个应用编译时生成到pri-app中呢?需要在Android.mk中做如下设置即可:

LOCAL_PRIVILEGED_MODULE := true


1、带源码的apk
1)&nBSP;    在 packages/apps 下面以需要预置的 APK的 名字创建一个新文件夹,以预置一个名为Test的APK 为例
2)     将 Test APK的Source code 拷贝到 Test 文件夹下,删除 /bin 和 /gen 目录
3)     在 Test 目录下创建一个名为 android.mk的文件,内容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-subdir-Java-files)
LOCAL_PACKAGE_NAME := Test
include $(BUILD_PACKAGE) 
4)     打开文件 build/target/product/${Project}.mk (其中 ${Project} 表示工程名)或者是在build/target/product/core.mk文件 或者是 device/mediatek/productname/device.mk,因各自公司而易
将 Test 添加到 PRODUCT_PACKAGES 里面。
5)     重新 build 整个工程



2、无源码的apk
1)     在 packages/apps 下面以需要预置的 APK 名字创建文件夹,以预置一个名为Test的APK为例
2)     将 Test.apk 放到 packages/apps/Test 下面
3)     在  packages/apps/Test 下面创建文件 Android.mk,文件内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Module name should match apk name to be installed
LOCAL_MODULE := Test
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := PRESIGNED
include $(BUILD_PREBUILT)
4)     打开文件 build/target/product/${Project}.mk (其中 ${Project} 表示工程名)或者是在build/target/product/core.mk文件 或者是 device/mediatek/productname/device.mk,因各自公司而易
将 Test 添加到 PRODUCT_PACKAGES 里面。
5)     将从Test.apk解压出来的 so库拷贝到alps/vendor/mediatek/${Project}/artifacts/out/target/product/${Project}/system/lib/目录下,若无 so 库,则去掉此步;
6)     重新 build 整个工程
注:Google在KK上修改protection Level为System的permission控管机制
如果App使用System Level的permission,需要預置到/system/priv-app底下 (原在/system/app)。



3、app可以卸载但是恢复出厂设置时不能恢复
1)     在 packages/apps 下面以需要预置的 APK 名字创建文件夹,以预置一个名为Test的APK为例
2)     将 Test.apk 放到 packages/apps/Test 下面;
3)     在  packages/apps/Test 下面创建文件 Android.mk,文件内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Module name should match apk name to be installed
LOCAL_MODULE := Test
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
include $(BUILD_PREBUILT)
4)     打开文件 build/target/product/${Project}.mk (其中 ${Project} 表示工程名)或者是在build/target/product/core.mk文件 或者是 device/mediatek/productname/device.mk,因各自公司而易
将 Test 添加到 PRODUCT_PACKAGES 里面。
5)     重新 build 整个工程
注意:这个比不能卸载的多了一句
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)


4、apk可以卸载恢复出场设置时能恢复
在packages/apps下面以需要预置的 APK 名字创建文件夹,以预置一个名为Test的APK为例:
1)     将Test.apk 放到 packages/apps/Test 下面;
2)     在packages/apps/Test下面创建文件 Android.mk,文件内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Module name should match apk name to be installed
LOCAL_MODULE := Test
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/operator/app
include $(BUILD_PREBUILT) 4)     打开文件 build/target/product/${Project}.mk (其中 ${Project} 表示工程名)或者是在build/target/product/core.mk文件 或者是 device/mediatek/productname/device.mk,因各自公司而易

将 Test 添加到 PRODUCT_PACKAGES 里面
4)     重新 build 整个工程
device\mediatek\common\device.mk,将 Test 添加到 PRODUCT_PACKAGES 里面。
PRODUCT_PACKAGES += Test
若需要apk作为32bit的apk运行,则需要在Android.mk中定义
LOCAL_MULTILIB :=32
其中要注意的有:LOCAL_CERTIFICATE
LOCAL_CERTIFICATE := PRESIGNED  //适用于app已经签名的
LOCAL_CERTIFICATE := platform   //试用于app没有签名的
一定要区分清楚,不然会报错


快速合入客户APP 到系统镜像文件system.img中

在有些情况下 我们只是要合入某APK到System.img中(预制到系统中) 文件,然后刷系统调试一下该APP,最快的方法就是:

(1)将该APK  文件解压,提取 lib文件(直接复制 lib 文件),

(2)进入你要合入该APP的系统APP生成路径(如:system/app/   system/priv-app)目下,新建一个与APK文件名相同的文件夹,将该APK 文件与提取出来的 lib文件 放入此文件班夹下即可,

(3)另外需将so库文件复制一份到out目录下项目文件夹下的system/lib,要不然手机系统system/lib下无os库文件

 (4)执行 make snod 重新打包生成新的system.img文件 就OK

(备注)如果在第三步执行打包过程中异常了,则需要进入alps\vendor\mediatek\proprietary\frameworks\base\data\etc\pms_sysapp_removable_system_list.txt

将该APP的包名加入此文件中,


#################完整可用的示例 -- 不可卸载,无源码,不带OS库文件的
# APKNAME-只需要修改的你的APK文件名字参数APKNAME,直接可用
LOCAL_PATH := $(call my-dir)

my_archs := arm x86
my_src_arch := $(call get-prebuilt-src-arch, $(my_archs))

include $(CLEAR_VARS)
LOCAL_MODULE := APKNAME
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_TAGS := optional
LOCAL_BUILT_MODULE_STEM := package.apk
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
#LOCAL_PRIVILEGED_MODULE :=
LOCAL_CERTIFICATE := PRESIGNED
#LOCAL_OVERRIDES_PACKAGES :=
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
#LOCAL_REQUIRED_MODULES :=
LOCAL_MODULE_TARGET_ARCH := $(my_src_arch)
include $(BUILD_PREBUILT)

 

#######################无源码,不可卸载,带OS库文件的
#APKNAME  只需要修改APKNAME参数即可使用

LOCAL_PATH := $(call my-dir)

my_archs := arm arm64
my_src_arch := $(call get-prebuilt-src-arch, $(my_archs))

include $(CLEAR_VARS)
LOCAL_MODULE := APKNAME
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_TAGS := optional
LOCAL_BUILT_MODULE_STEM := package.apk
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
#LOCAL_PRIVILEGED_MODULE :=
LOCAL_CERTIFICATE := PRESIGNED
#LOCAL_OVERRIDES_PACKAGES :=
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk

LOCAL_PREBUILT_JNI_LIBS := \
	lib/$(my_src_arch)/libXXXX.so \
	lib/$(my_src_arch)/libXXXXX.so

LOCAL_MODULE_TARGET_ARCH := $(my_src_arch)
include $(BUILD_PREBUILT)

上面的带OS库文件的必须将项目中的lib目录的下两文件名修改成arm和arm64(如果要系统位数区别的库),

android 各模块的Android.mk文件说明及如何预置app到系统中_第3张图片

不能沿用apk解压中的文件名称

android 各模块的Android.mk文件说明及如何预置app到系统中_第4张图片

否则会报错误:

ninja: error: 'packages/apps/apkname/lib/arm64/libIxxx.so', needed by 'out/target/product/a/system/app/apkname/lib/arm64/libIxxx.so', missing and no known rule to make it

 

 

 

你可能感兴趣的:(android 各模块的Android.mk文件说明及如何预置app到系统中)