Android.bp 中 使用 go 模块 实现多产品动态编译

背景

系统需要支持多个产品,SystemUI 在各个产品中有一些差异,需要像gradle中多渠道打包一样,动态的添加产品的资源,代码和依赖

当前主要有以下几个问题

  1. 动态添加产品资源
  2. 动态添加产品代码
  3. 动态添加产品依赖项

在参考了众多大神的博客以及在大神的引导下,阅读了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"
    ]
}

三个问题圆满解决,读到且有帮助的同学点个赞

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值