背景
系统需要支持多个产品,SystemUI 在各个产品中有一些差异,需要像gradle中多渠道打包一样,动态的添加产品的资源,代码和依赖
当前主要有以下几个问题
- 动态添加产品资源
- 动态添加产品代码
- 动态添加产品依赖项
在参考了众多大神的博客以及在大神的引导下,阅读了build/soong目录下的部分代码后,使用如下方法解决了这几个问题。以下是主要步骤
1、在系统编译中添加环境变量,标识编译的产品
TARGET_PRODUCT
2、在SystemUI的 Android.bp 文件中声明 go 模块引入,在srcs中配置代码文件路径
Android.bp
/// add start
bootstrap_go_package {
// name and pkgPath need to according to your module
name: "soong-CarSystemUI",
pkgPath: "android/soong/CarSystemUI",
deps: [
"blueprint",
"blueprint-pathtools",
"soong",
"soong-android",
"soong-java",
"soong-genrule",
],
srcs: [
// include new add .go file
"overlay/CarSystemUI.go",
],
pluginFor: ["soong_build"],
}
3、编写 CarSystemUI.go
以下脚本,分别注册了 AARImportFactory 与 DefaultsFactory 类型的Module
AARImportFactory 实现了动态声明 "android_library_import" 配置的能力,从而解决了上面的第三个问题
DefaultsFactory 实现了动态添加 src 与 res 目录的能力,从而解决了上面的第一和第二个问题
package CarSystemUI
import (
"android/soong/android"
"android/soong/java"
"fmt"
)
func init() {
fmt.Println("init start")
android.RegisterModuleType("product_default_source", productDefaultsSourceFactory)
android.RegisterModuleType("product_library_import", productLibraryImportFactory)
}
func productLibraryImportFactory() (android.Module) {
fmt.Println("productLibraryImportFactory")
module := java.AARImportFactory()
android.AddLoadHook(module, productLibraryProperty)
return module
}
func productLibraryProperty(ctx android.LoadHookContext) {
type props struct {
// Name string
Aars []string
Sdk_version *string
}
p := &props{}
product := ctx.AConfig().Getenv("TARGET_PRODUCT");
fmt.Println("TARGET_PRODUCT: ", product)
var aars []string
switch(product) {
case "producta":
fmt.Println("import property for producta")
aars = append(aars, "overlay/common/libs/prodducta.aar")
case "prodductb":
fmt.Println("import property for prodductb")
aars = append(aars, "overlay/common/libs/prodductb.aar")
case "productc":
fmt.Println("import property for productc")
aars = append(aars, "overlay/common/libs/prodductc.aar")
}
// p.Name := "vehicle_service_property"
p.Aars = aars
verson := "current"
p.Sdk_version = &verson
ctx.AppendProperties(p)
}
func productDefaultsSourceFactory() (android.Module) {
fmt.Println("productDefaultsSourceFactory")
module := java.DefaultsFactory()
android.AddLoadHook(module, vendorDefaults)
return module
}
func vendorDefaults(ctx android.LoadHookContext) {
type props struct {
Resource_dirs []string
Srcs []string
// Static_libs []string
}
p := &props{}
product := ctx.AConfig().Getenv("TARGET_PRODUCT");
fmt.Println("TARGET_PRODUCT: ", product)
p.Resource_dirs = resourceDirsDefaults(product)
p.Srcs = scrsDefaults(product)
// p.Static_libs = libsDefaults(product)
ctx.AppendProperties(p)
}
func resourceDirsDefaults(product string) ([]string) {
var resource_dirs []string
switch(product) {
case "producta":
fmt.Println("append resource for producta")
resource_dirs = append(resource_dirs, "overlay/common/src/main/res-producta")
case "productb":
fmt.Println("append resource for productb")
resource_dirs = append(resource_dirs, "overlay/common/src/main/res-productb")
case "van233":
fmt.Println("append resource for productc")
resource_dirs = append(resource_dirs, "overlay/common/src/main/res-productc")
}
return resource_dirs
}
func scrsDefaults(product string) ([]string) {
var srcs []string
switch(product) {
case "producta":
fmt.Println("append src for producta")
srcs = append(srcs, "overlay/common/src/main/java-producta/**/*.java")
case "productb":
fmt.Println("append src for productb")
srcs = append(srcs, "overlay/common/src/main/java-productb/**/*.java")
case "productc":
fmt.Println("append src for productc")
srcs = append(srcs, "overlay/common/src/main/java-productc/**/*.java")
}
return srcs
}
最后要在Android.bp中声明这两个模块,并使用
// Product Default Source
product_default_source {
name: "product_default",
}
// Product Library Import
product_library_import {
name: "product_library"
}
android_library {
name: "CarSystemUI-core",
// defaults 设置为添加了产品相关代码资源参数的配置
defaults: ["product_default"],
// 在static_libs中,添加上面声明的module name
static_libs: [
"product_library"
]
}
三个问题圆满解决,读到且有帮助的同学点个赞