Android中如何不编译源生模块

时间:2024-05-21 19:20:40

来源:

http://blog.****.net/shift_wwx/article/details/78951896


前言:

最近碰到一个问题,公司内部的app需要替换源生的app,也就是说不编译源生的app,而编译后的out下只能由公司指定的app,没有源生的app。例如,源生的Launcher2。

网上搜了一下,并没有多少相关的文章,后来就此问题研究了一下,这里做个总结,如果有哪里不对的请不吝赐教。


对于这个问题,有三种解决方案:

1、直接删掉Launcher2这个目录方案

2、Android中源生给出的替换方案

3、统一管理方案


1、直接删掉Launcher2这个目录方案

这是个暴力的解决办法,但是移植性、维护性差一些。如果有的板卡需要,有的不需要,这样就不能删除了。

这个方案有利有弊,结合工程管理方便来。


2、Android中源生给出的替换方案

这个方案Android源生是存在的,仔细看下build/core/*.mk 就会发现有个变量叫LOCAL_OVERRIDES_PACKAGES

这个变量跟LOCAL_PACKAGE_NAME一样,在app的Android.mk中添加需要替换掉什么app(让此app不参与编译)只需要设定这个变量即可。

例如,

Android中如何不编译源生模块

这里设定好LOCAL_OVERRIDES_PACKAGES 就可以让Launcher2不参与编译。


3、统一管理方案

对于第2点的方案似乎已经达到目的了,但是如果不是替换,而是简单的控制不让其参与编译,这个变量是无法设定的。

来看下这里统一管理的方案,在Android中的makefile中有个变量PRODUCT_PACKAGES,这个变量是控制模块是否参与编译,我们在device目录下看到很多这样的设定,这时候如果为了项目或者板卡维护,直接修改device下的PRODUCT_PACKAGES变量就可以了。但是有时候会看到有些模块不是在device下面控制,而是放在了build下面,这个时候为了项目维护性,不能直接修改build下的变量。

有了这样的顾虑,为了以后项目维护性,想了一个办法,那就是用一个变量统一管理,以后不管是什么项目不需要源生的或者device下面已经设定好的PRODUCT_PACKAGES,只需要设定这个变量就可以了。


首先来看下PRODUCT_PACKAGES是怎么使用的。

在build/core/product.mk中看到这样的一个变量:

Android中如何不编译源生模块

在makefile 中会将定义PRODUCT_PACKAGES的makefile通过 inherit-product或者 inherit-product-if-exists的函数传入。


来看下 inherit-product 函数:

Android中如何不编译源生模块

首先,通过normalize-paths 确定想要的path,这个函数最终调用的是一个python脚本,感兴趣可以跟一下。

接着,将_product_var_list中定义的字符串中每个子串为名字的变量后面加上后缀,这个后缀就是需要inherit的makefile的路径。

例如,这个makefile的路径为device/common/hehe.mk,那最后变量的后面会加上@inherit:device/common/hehe.mk,表示该变量继承自哪里。

从这里看,以后PRODUCT_PACKAGES这个变量后面会跟很多mk

第3步,将变量PRODUCTS.$(strip $(word 1,$(_include_stack))).INHERITS_FROM 加入inherit的makefile的路径(这里为device/common/hehe.mk)排序后重新赋值。

第4步,最后统一为ALL_PRODUCTS。

这其中有个地方需要另外研究,就是变量 _include_stack,详细看build/core/node_fns.mk 中的处理部分。


函数inherit-product-if-exists:

Android中如何不编译源生模块

这个函数会先判断inherit的makefile 是否存在。


上面只是前期的准备工作,主要的解析是在函数import-products中

Android中如何不编译源生模块

这里就不详细说明,有兴趣可以看下build/core/node_fns.mk 中的过程。


最终在main.mk中会做一个过滤:

Android中如何不编译源生模块

上面的第2点就是这样来的,详细第2点的解析可以看下package.mk中的运行过程。


所以,最后如果想要达到统一的管理,可以在这里做一个过滤,用一个变量统一管理。

假定这个变量的名字为PRODUCT_DEL_PACKAGES,表示需要删掉的module,那添加后的过滤代码为:

Android中如何不编译源生模块

添加后编译就会把不需要编译的module去掉。

当然,这个变量是需要跟PRODUCT_PACKAGES添加到 _product_var_list 中,详细看 build/core/product.mk中:

Android中如何不编译源生模块


Android 的build 过程比较复杂,这里只针对这3中办法做个简单的总结,后期后持续总结build下编译过程。请大神不吝赐教。



参考:

http://blog.****.net/lewif/article/details/50014827