第 1 步:BoardConfig.mk 设置 Make 变量

  # device/rockchip/rk3576/BoardConfig.mk
  BOARD_PRESSURE_SENSOR_SUPPORT := true

  这就是一个普通的 Make 变量,没什么特别的。


  第 2 步:sensors.mk 把 Make 变量注册到 Soong 命名空间  # device/rockchip/common/modules/sensors.mk

  $(call soong_config_set,sensor_rockchip,pressure,$(BOARD_PRESSURE_SENSOR_SUPPORT))

  soong_config_set 的定义在 build/make/core/config.mk:309:

  define soong_config_set
  $(call soong_config_define_internal,$1,$2) \
  $(eval SOONG_CONFIG_$(strip $1)_$(strip $2):=$3)
  endef

  执行后,实际效果是创建了两个 Make 变量:

  SOONG_CONFIG_NAMESPACES += sensor_rockchip
  SOONG_CONFIG_sensor_rockchip += pressure
  SOONG_CONFIG_sensor_rockchip_pressure := true    # ← 值在这里!


  第 3 步:soong_config.mk 把这些变量写进 JSON 文件

  这是最关键的桥梁!在 build/make/core/soong_config.mk:269-275:

  $(call add_json_map, VendorVars)
  $(foreach namespace,$(sort $(SOONG_CONFIG_NAMESPACES)),\
    $(call add_json_map, $(namespace))\
    $(foreach key,$(sort $(SOONG_CONFIG_$(namespace))),\
      $(call add_json_str,$(key),$(subst ",\",$(SOONG_CONFIG_$(namespace)_$(key)))))\
    $(call end_json_map))
  $(call end_json_map)

  翻译成人话:遍历所有 SOONG_CONFIG_NAMESPACES,把每个命名空间下的变量和值,写成 JSON。

  最终生成的 out/soong/soong.variables 文件里会有:

  {
    "VendorVars": {
      "sensor_rockchip": {
        "pressure": "true",
        "gravity": "true",
        "compass": "false",
        "light": "true"
      }
    }
  }

  这就是桥梁!Make 把值写进 JSON,Soong 从 JSON 读出来。

  
  第 4 步:Soong (Go 代码) 读取 JSON

  在 build/soong/android/variable.go:435 定义了结构体:

  type productVariables struct {
      // ...
      VendorVars map[string]map[string]string `json:",omitempty"`
      // ...
  }

  Soong 启动时解析 soong.variables JSON 文件,VendorVars 字段就自动拿到了所有命名空间的值。

  然后在 config.go:1574:

  func (c *config) VendorConfig(name string) VendorConfig {
      return soongconfig.Config(c.productVariables.VendorVars[name])
  }

  传入命名空间名 "sensor_rockchip",就能拿到 {"pressure": "true", ...}。

  
  第 5 步:Soong 根据 Android.bp 的声明决定加什么 cflags

  在 build/soong/android/soongconfig/modules.go 的 boolVariable.PropertiesToApply 方法(第 741-755 行):

  func (b boolVariable) PropertiesToApply(config SoongConfig, values reflect.Value) (interface{}, error) {
      if config.Bool(b.variable) {   // ← 读取 pressure 的值,"true" → true
          values = removeDefault(values)
          return values.Interface(), nil   // ← 返回 pressure=true 对应的 cflags
      }
      // 否则返回 conditions_default 对应的 cflags
      v := values.Elem().Elem()
      if f := conditionsDefaultField(v); f.IsValid() {
          return f.Interface(), nil
      }
      return nil, nil
  }

  然后 Soong 把返回的 cflags 合并到编译参数里,最终等价于:

  clang -DPRESSURE_SENSOR_SUPPORT=1 ...


  一图总结

  ┌──────────────────────────────────────────────────────────┐
  │  ① BoardConfig.mk                                        │
  │  BOARD_PRESSURE_SENSOR_SUPPORT := true                    │
  └─────────────────────┬────────────────────────────────────┘
                        │ Make 变量赋值
                        ▼
  ┌──────────────────────────────────────────────────────────┐
  │  ② sensors.mk                                            │
  │  $(call soong_config_set,sensor_rockchip,pressure,true)   │
  │  ↓ 产生:                                                 │
  │  SOONG_CONFIG_sensor_rockchip_pressure := true            │
  └─────────────────────┬────────────────────────────────────┘
                        │ Make 变量
                        ▼
  ┌──────────────────────────────────────────────────────────┐
  │  ③ soong_config.mk   (桥梁!)                            │
  │  遍历 SOONG_CONFIG_NAMESPACES,写 JSON:                   │
  │  ↓                                                       │
  │  out/soong/soong.variables:                               │
  │  { "VendorVars": { "sensor_rockchip": { "pressure":"true"}}}│
  └─────────────────────┬────────────────────────────────────┘
                        │ JSON 文件(磁盘)
                        ▼
  ┌──────────────────────────────────────────────────────────┐
  │  ④ Soong (Go)                                            │
  │  解析 soong.variables → productVariables.VendorVars       │
  │  config.VendorConfig("sensor_rockchip") → {"pressure":"true"}│
  └─────────────────────┬────────────────────────────────────┘
                        │ Go 代码中的 map
                        ▼
  ┌──────────────────────────────────────────────────────────┐
  │  ⑤ Android.bp 匹配                                       │
  │  soong_config_variables.pressure = true                   │
  │  → 选择 cflags: ["-DPRESSURE_SENSOR_SUPPORT=1"]          │
  │  → 编译时: clang -DPRESSURE_SENSOR_SUPPORT=1              │
  └─────────────────────┬────────────────────────────────────┘
                        │ C 宏
                        ▼
  ┌──────────────────────────────────────────────────────────┐
  │  ⑥ Sensors.h (C++ 代码)                                  │
  │  #if PRESSURE_SENSOR_SUPPORT   ← 1,生效!               │
  │      AddSensor<PressureSensor>();                         │
  │  #endif                                                   │
  └──────────────────────────────────────────────────────────┘

  核心就一句话:soong_config.mk 第 269-275 行把 Make 变量写进 soong.variables JSON 文件,Soong 从这个 JSON
  读出来,然后匹配 Android.bp 里的 soong_config_variables 决定加什么 cflags。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐