花式吊打源码中 Android.mk 集锦

简介: 花式吊打源码中 Android.mk 集锦

一、区分版本编译 app


最近在修改 Android P 中的 Camera 应用,看到了 mk 的强大之处,特记录一下。


ifeq ($(MTK_CAMERA_APP_VERSION), 3)
LOCAL_ROOT_PATH:= $(call my-dir)
include $(LOCAL_ROOT_PATH)/host/Android.mk
include $(LOCAL_ROOT_PATH)/portability/Android.mk
include $(LOCAL_ROOT_PATH)/tests/Android.mk
include $(LOCAL_ROOT_PATH)/feature/setting/matrixdisplay/matrixdisplay_ext/Android.mk
include $(LOCAL_ROOT_PATH)/testscat/Android.mk
#include $(LOCAL_ROOT_PATH)/feature/pluginroot/Android.mk
#include $(LOCAL_ROOT_PATH)/feature/mode/panorama/Android.mk
#include $(LOCAL_ROOT_PATH)/feature/mode/pip/Android.mk
#include $(LOCAL_ROOT_PATH)/feature/mode/vsdof/Android.mk
#include $(LOCAL_ROOT_PATH)/feature/mode/slowmotion/Android.mk
endif

这是 Camera2 app 下的 mk 文件,一开始判断了宏 MTK_CAMERA_APP_VERSION,可以理解为要编译的 Camera 版本,经过搜索发现定义在 ProjectConfig.mk


aHR0cHM6Ly9zMi5heDF4LmNvbS8yMDE5LzExLzA1L01TNVBwOS5wbmc.png


编译不同版本时会选择不同的 Camera 进行编译打包,Camera1 中 mk 的 MTK_CAMERA_APP_VERSION 对应值为 2,如果你单独 mmm Camera1,则会出现如下错误


ninja: error: unknown target ‘MODULES-IN-vendor-mediatek-proprietary-packages-apps-Camera1’


aHR0cHM6Ly9zMi5heDF4LmNvbS8yMDE5LzExLzA1L01TNUlueC5wbmc.png

拓展延伸


经过测试,预装 app 编译需要在 core.mk 中增加定义,这里定义的是 app 的名称,而不是 app 的父文件夹名称,只不过我们一般都写成一样。

应用场景,


在 core.mk 中增加 AndroidDemo 定义


在 package/app/AndroidO/AndroidDemo.apk 路径下放置 app ($(DEMO_APP_VERSION), 8)


在 package/app/AndroidP/AndroidDemo.apk 路径下放置 app ($(DEMO_APP_VERSION), 9)

ifeq ($(DEMO_APP_VERSION), 8)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Module name should match apk name to be installed
LOCAL_MODULE := AndroidDemo
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)
endif


修改 ProjectConfig.mk 中的 DEMO_APP_VERSION 值编译,out 目录下 AndroidDemo 文件中生成的 apk 随之改变

吊打方式二,快来看呀, AndroidDemo 文件下的 Android.mk 原来还可这样写


20200228130814846.png


20200228130536983.png

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Module name should match apk name to be installed
LOCAL_MODULE := AndroidDemo
LOCAL_MODULE_TAGS := optional
ifeq ($(findstring YM,$(MTK_BUILD_VERNO)), YM)
LOCAL_SRC_FILES := ./AndroidO/AndroidDemo.apk
else
LOCAL_SRC_FILES := ./AndroidP/AndroidDemo.apk
endif
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := PRESIGNED
ifeq ($(findstring YM,$(MTK_BUILD_VERNO)), YM)
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
else
LOCAL_PRIVILEGED_MODULE := true
endif
include $(BUILD_PREBUILT)


写了这么大堆,让我们来康康都是什么意思,(( f i n d s t r i n g Y M , (findstring YM,(findstringYM,(MTK_BUILD_VERNO)), YM) 是 mk 中的字符串查找函数,意思就是


在 MTK_BUILD_VERNO 中查找 YM 字符串,如果找到则返回该字符串,找不到则返回空字符串,前面的查找结果再和后面的 YM 判断是否相等


MTK_BUILD_VERNO 在 ProjectConfig.mk 中定义,对应系统版本号。翻译一下就是,如果版本号中带 YM 字符串,就编译 AndroidO 文件下


的 apk,反之则编译 AndroidP 文件下。再看编译后app的存放路径,如果是 YM 版本路径为 data/app,反之路径为 system/priv-app,


如果 LOCAL_MODULE_PATH 和 LOCAL_PRIVILEGED_MODULE 都不指定,则默认路径为 system/app


二、预装可卸载等相关配置


放置到 system/app/应用名称 路径下,在 build/target/product/core.mk 中增加 WeChat \


预装不可卸载


LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Module name should match apk name to be installed
LOCAL_MODULE := WeChat
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)


预装可卸载,恢复出厂不恢复


mtk 主要通过 userdata.img 来保存预装可卸载的 app


6.0 写法

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Module name should match apk name to be installed
LOCAL_MODULE := WeChat
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)


8.1 以上写法


mk 和 6.0 的一样,都是通过 userdata.img 来实现,首先需要确保你的文件系统类型为 ext4,


然后再回退 PackageManagerService.java 中 Google 的更新, 注释 else 语句块抛出的异常即可


frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -11394,6 +11394,10 @@
                                     + " but expected at " + known.codePathString
                                     + "; ignoring.");
                         }
+                    } else {
+                        throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
+                                "Application package " + pkg.packageName
+                                + " not found; ignoring.");
                     }
                 }
             }


具体可参考为什么 Android8.1 使用f2fs文件系统的预置app到data/app不行?


预装可卸载,恢复出厂可恢复


6.0 写法

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Module name should match apk name to be installed
LOCAL_MODULE := WeChat
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)

8.1 以上写法

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Module name should match apk name to be installed
LOCAL_MODULE := WeChat
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)


还需要在


vendor/mediatek/proprietary/frameworks/base/data/etc/pms_sysapp_removable_system_list.txt


增加 WeChat 的包名,这样就可以卸载了


三、mk 中常用参数简介


LOCAL_PATH:= $(call my-dir)

宏函数’my-dir’,由编译系统提供,用于返回当前路径,在开发树中查找源文件


include $(CLEAR_VARS) 开始编译模块

include $(BUILD_XXX) 结束编译模块

一个 mk 中可以编译多个模块,可定义多组模块,但注意开始和结束需要一一对应


CLEAR_VARS 指的是 clear_vars.mk,由编译系统提供,它会让GNU MAKEFILE 为你清除除 LOCAL_PATH 以外的所有 LOCAL_XXX 变量,


如 LOCAL_MODULE,LOCAL_SRC_FILES,LOCAL_SHARED_LIBRARIES,LOCAL_STATIC_LIBRARIES 等。


LOCAL_MODULE_TAGS := eng/debug/tests/optional


该模块在 eng/debug/tests/所有版本下编译 大多 mk 中都是定义为 optional,eng 在 mtkLogger 中有定义


LOCAL_STATIC_JAVA_LIBRARIES :=

android-support-v4 当前模块依赖的Java静态库,所谓静态库,即编译完会存在于你的module里面,成为其一部分


LOCAL_SRC_FILES :=

$(call all-java-files-under, src) 当前模块需要编译的 java 文件,指定 src 目录下


LOCAL_RESOURCE_DIR :=

$(LOCAL_PATH)/res

prebuilts/sdk/current/support/v7/recyclerview/res \ 当前模块需要编译的资源文件


LOCAL_PACKAGE_NAME := MtkLauncher3


编译出对应的 app 名称


LOCAL_OVERRIDES_PACKAGES := Home Launcher2 Launcher3


当前编译模块覆盖对应的模块,Home Launcher2 Launcher3 将不再进行编译,跳过


LOCAL_CERTIFICATE := PRESIGNED/platforms


签署当前应用的证书名称,保留应用原来的/签系统签名


LOCAL_SDK_VERSION := current


标记 SDK 的 version 状态,可选值为 current system_current test_current core_current


LOCAL_PRIVATE_PLATFORM_APIS := true


模块编译时能引用 hide 的 api


LOCAL_MANIFEST_FILE := go/AndroidManifest.xml


指定当前编译选用的 AndroidManifest.xml 文件,LOCAL_MANIFEST_FILE 省略时默认采用根目录下


吊打方式三,假设你需要对 Launcher3 编译带桌面属性的版本和不带桌面属性的版本,有时候客户自己做桌面应用,就不需要系统的 Launcher  


20200228130636838.png

一般都是将 AndroidManifest.xml 中的属性配置注释


<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <!-- <category android:name="android.intent.category.HOME" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.MONKEY"/>
        <category android:name="android.intent.category.LAUNCHER_APP" /> -->
</intent-filter>

现在通过 LOCAL_MANIFEST_FILE 我们依旧可以根据版本号加载不同文件下的 xml

ifeq ($(findstring YM,$(MTK_BUILD_VERNO)), YM)
LOCAL_MANIFEST_FILE := noLauncher/AndroidManifest.xml
else
LOCAL_MANIFEST_FILE := Launcher/AndroidManifest.xml
endif


四、mk 和 shell 脚本同时编译


先来介绍一些 mk 中常用的路径,便于作为参数传递至 shell 脚本中


${LOCAL_PATH} 当前 mk 所处的路径


${OUT} 当前整编结束后 out 目录的全路径 /home/xxx/android8.1/6737_oreo/alps/out/target/product/k37tv1_64_bsp


${TARGET_OUT} 当前整编结束后 system 目录的根路径 out/target/product/k37tv1_64_bsp/system


${TARGET_OUT_ROOT} =out/target


${PRODUCT_OUT}=out/target/product/k37tv1_64_bsp


${TARGET_COPY_OUT_VENDOR}=vendor


${TARGET_PRODUCT_OUT_ROOT}=out/target/product


${TARGET_DEVICE}=k37tv1_64_bsp


上面的宏定义大多在 build\core\envsetup.mk 中可查到,通过如下 mk 进行打印查看结果

LOCAL_PATH := $(call my-dir)
$(info LOCAL_PATH=${LOCAL_PATH})
$(info OUT=${OUT})
$(info TARGET_OUT=${TARGET_OUT})
$(info TARGET_OUT_ROOT=${TARGET_OUT_ROOT})
$(info PRODUCT_OUT=${PRODUCT_OUT})
$(info TARGET_COPY_OUT_VENDOR=${TARGET_COPY_OUT_VENDOR})
$(info TARGET_PRODUCT_OUT_ROOT=${TARGET_PRODUCT_OUT_ROOT})
$(info TARGET_DEVICE=${TARGET_DEVICE})
COPY_FILES = $(shell ${LOCAL_PATH}/test.sh ${OUT} ${TARGET_DEVICE})
$(info ${COPY_FILES})


$(shell ${LOCAL_PATH}/test.sh ${OUT} ${TARGET_DEVICE}) 就是执行 sh 的命令,

传递 out 和 target_device,在 test.sh 中通过 ${1} ${2} 获取

#!/bin/bash
echo -e "out_path=${1}"
echo -e "target_device_name=${2}"
rm  ${OUT}/lk.img 
rm  ${OUT}/userdata.img 


目录
相关文章
|
1月前
|
开发工具 Android开发 git
Windows下载android2.2完整源码(转)
Windows下载android2.2完整源码(转)
43 3
|
1月前
|
JSON 编译器 开发工具
VS Code阅读Android源码
VS Code阅读Android源码
84 1
|
1月前
|
XML Java Android开发
Android实现自定义进度条(源码+解析)
Android实现自定义进度条(源码+解析)
68 1
|
1月前
|
Java Android开发
Android反编译查看源码
Android反编译查看源码
44 0
|
1月前
|
Java Android开发
Android系统 修改无源码普通应用为默认Launcher和隐藏Settings中应用信息图标
Android系统 修改无源码普通应用为默认Launcher和隐藏Settings中应用信息图标
211 0
|
1月前
|
Java 开发工具 Android开发
如何在Eclipse中查看Android源码或者第三方组件包源码(转)
如何在Eclipse中查看Android源码或者第三方组件包源码(转)
21 4
|
1月前
|
Java Android开发
Android12 双击power键启动相机源码解析
Android12 双击power键启动相机源码解析
63 0
|
3天前
|
Java API Android开发
技术经验分享:Android源码笔记——Camera系统架构
技术经验分享:Android源码笔记——Camera系统架构
|
1月前
|
JSON Java API
Android 深入Http(5)从Retrofit源码来看Http,最新Android开发面试解答
Android 深入Http(5)从Retrofit源码来看Http,最新Android开发面试解答
|
1月前
|
Android开发
在android源码中编译ADW_Launcher
在android源码中编译ADW_Launcher
19 2