根据条件禁用Android.bp模块

上一篇文章我们提到了在 Android 10 之后,Android.bp 定义的模块才能加入到 bootjar 中。但是我们有个中间件模块是各平台同一套代码的。我们还有 Android 5.1 的平台在维护,而 Android 5.1 是还不支持 Android.bp 的。为了兼容各平台,我们需要同时编写 Android.mk 和 Android.bp 规则,里面都定义了中间件模块。但这样子在同时支持 mk 和 bp 的平台就会有模块重定义的问题。所以我们需要一种机制,能实现以下需求:

  • Android 版本 >= 10 时:Android.bp 的模块定义生效,Android.mk 的模块定义不生效。
  • Android 版本 < 10 时:Android.mk 的模块定义生效,Android.bp 的模块定义不生效。

Android.mk 根据 sdk 版本,禁用模块

Android.mk 是 Makefile 语法,本身就有条件判断功能,所以要实现这个功能是很简单的:

1
2
3
4
5
6
7
8
9
10
11
LOCAL_PATH := $(call my-dir)  
include $(CLEAR_VARS)
LOCAL_MODULE := hello # 模块名
LOCAL_SRC_FILES := hello.cpp    # 源文件列表
LOCAL_SHARED_LIBRARIES := liblog # 依赖关系
LOCAL_xxx := xxx

# 小于 Android 10 才在 Android.mk 中定义模块。include $(BUILD_XXX) 才会真正定义一个模块。
ifeq (1,$(filter 1,$(shell echo "$$(( $(PLATFORM_SDK_VERSION) < 29 ))" )))
include $(BUILD_EXECUTABLE) # 模块类型
endif

Android.bp 根据 sdk 版本,禁用模块

Android.bp 的条件编译,前面的文章已经有讨论过了,这里就不再展开了。
http://qiushao.net/2020/02/05/Android系统开发入门/15-Anroid.bp条件编译/
只展示一下关键配置即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func helloHook(ctx android.LoadHookContext) {
//AConfig() function is at build/soong/android/config.go
fmt.Println("PlatformSdkVersion = ", ctx.AConfig().PlatformSdkVersion())
type props struct {
Enabled *bool
}
p := &props{}
var int_platform_sdk_version int
int_platform_sdk_version = ctx.AConfig().PlatformSdkVersionInt()

var enabled bool
if int_platform_sdk_version >= 29 {
enabled = true
} else {
enabled = false
}
p.Enabled = &enabled
ctx.AppendProperties(p)
}

Android.bp 中有一个 enabled 字段,当 enabled = false 时,这个模块就不会被定义,所以我们只要根据 sdk 的版本来给 enabled 字段赋值即可。
这里需要注意的是 props struct 中定义的 Enabled 是指针类型。