系统层面Android.bp的宏控

Android系统层面Android.bp的宏控

一. Android.bp概念

随着Android版本的不断更迭,越来越多的模块会使用Android.bp进行编译。Android.bp是Google用来替换Android.mk的配置文件,它使用Blueprint框架来解析。Blueprint是生成、解析Android.bp的工具,是Soong的一部分。Soong则是专为Android编译而设计的工具,Blueprint只是解析文件的形式,而Soong则解释内容的含义,最终转换成Ninja文件。

二.Android.mk转换成Android.bp的方法

Google既然有将Android.bp逐渐替代Android.mk的想法 ,自然是考虑到这个问题的易行性的 。 所以Google是已经提供给我们一个转换工具的,那就是androidmk。

该工具位于 out/soong/host/linux-x86/bin/androidmk:

使用命令为 

androidmk android.mk > android.bp 。 这样即可把Android.mk转换为android.bp文件了。

但是这种方法有一个弊端,就是没办法原汁原味的还原Android.mk 。就比如说这篇文章的主题 ,宏控就是它无法还原的。

三.平台Android.bp宏控

举例: 我们需要在一个Android.bp中获取 AGN_INIT_BP 的值 我们需要做以下内容:

1)  定义平台宏的值 , 在对应的BroadConfig.mk中

     + AGN_INIT_BP = BP

2)  新增string类型的Go变量  , build/soong/android/variable.go

     + INIT_BP *string `json:",omitempty"`

3)创建Go变量与mk变量的json映射关系 , build/make/core/soong_config.mk

     + $(call add_json_str,  INIT_BP,             $(strip $(AGN_INIT_BP)))  

4)定义Go方法,并且返回Go变量的值,build/soong/android/config.go

     + func (c *deviceConfig) GetInitBp() string {
  • return String(c.config.productVariables.INIT_BP)
    + }

    1. 申明并引用go文件 , 前往目标模块的Android.bp

      bootstrap_go_package {
      name: “soong-libcore”, //给你的这个go文件取名
      pkgPath: “android/soong/libcore”, //前面android/soong是固定路径 后面跟模块路径
      deps: [
      “blueprint”,
      “blueprint-pathtools”,
      “soong”,
      “soong-android”,
      “soong-cc”,
      “soong-genrule”,
      ],
      srcs: [
      “initbp.go”, //需要与你的go文件名字一致,且同级目录
      ],
      pluginFor: [“soong_build”],
      }

      libjavacoredefaults {
      name: “libjavacoredefaults”,
      }

      找到需要宏控的模块名:

      cc_library_shared {
      name: “xxx”,
      visibility: [
      “xxxx”,
      ],
      defaults: [
      “xxxx”,
      “xxxx”,
      “libjavacoredefaults”, //在defaults 里面引入上面定义的libjavacoredefaults
      ],

      ....
      

      }

    6)在Android.bp同级目录创建一个 initbp.go , 需要与上面Android.bp中的src引用的名字一致。

    package libcore                               //包名
    
    import (                                         //除非需要特定支持库,一般不需要改动
        "android/soong/android" 
        "android/soong/cc"
        "fmt"
        )   
    

    func init() {
    android.RegisterModuleType(“libjavacoredefaults”, libjavacoreDefaultsFactory) //初始化Go文件 , 这里的libjavacoredefaults 一定要与上文中Android.bp中的libjavacoredefaults一致
    }

    func libjavacoreDefaultsFactory() android.Module { //上文init引用该方法 , 所以该方法名需要与其一致
    fmt.Println(“NMF libjavacoreDefaultsFactory”) //可以使用fmt.PrintIn 打印log
    module := cc.DefaultsFactory()
    android.AddLoadHook(module, libjavacoreDefaults) //承上启下句 ,引出下文的libjavacoreDefaults
    return module
    }

    func libjavacoreDefaults(ctx android.LoadHookContext) {
    fmt.Println(“NMF libjavacoreDefaults”)
    type props struct {
    Cflags []string
    }
    p := &props{}
    p.Cflags = libjavacoreFlags(ctx) //承上启下句,引出下文的libjavacoreFlags(ctx) ,ctx是方法引入的参数android.LoadHookContext
    ctx.AppendProperties§
    }

    func libjavacoreFlags(ctx android.BaseContext) []string { //这里才是最终我们返回 init_bp值的地方!
    var cflags []string
    ret := ctx.DeviceConfig().GetInitBp() //还记得我们定义的方法GetInitBp() 吗?这就是使用的地方, 该方法返回Go变量的值,也就是宏的值
    fmt.Println(ret)
    if (ret!="") {
    cflags = append(cflags, “-DAGN_INIT_BP=”+ret) //cflags是我定义的一个string变量 , 我用它来承载宏的值
    fmt.Println(cflags)
    }
    fmt.Println(“NMF libcoreFlags AGN_INIT_BP=”+ret)
    return cflags //最终返回cflags
    }

    至此一整个Android.bp的宏控方法就完成了。

你可能感兴趣的:(Android系统开发,android,go语言)