• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""Parallels variable.go to provide variables and create a platform based on converted config."""
2
3load("//build/bazel/product_variables:constants.bzl", "constants")
4load("//prebuilts/clang/host/linux-x86:cc_toolchain_constants.bzl", "variant_name")
5
6def _product_variables_providing_rule_impl(ctx):
7    return [
8        platform_common.TemplateVariableInfo(ctx.attr.product_vars),
9    ]
10
11# Provides product variables for templated string replacement.
12product_variables_providing_rule = rule(
13    implementation = _product_variables_providing_rule_impl,
14    attrs = {
15        "product_vars": attr.string_dict(),
16    },
17)
18
19_arch_os_only_suffix = "_arch_os"
20_product_only_suffix = "_product"
21
22def add_providing_var(providing_vars, typ, var, value):
23    if typ == "bool":
24        providing_vars[var] = "1" if value else "0"
25    elif typ == "list":
26        providing_vars[var] = ",".join(value)
27    elif typ == "int":
28        providing_vars[var] = str(value)
29    elif typ == "string":
30        providing_vars[var] = value
31
32def product_variable_config(name, product_config_vars):
33    constraints = []
34
35    local_vars = dict(product_config_vars)
36
37    # Native_coverage is not set within soong.variables, but is hardcoded
38    # within config.go NewConfig
39    local_vars["Native_coverage"] = (
40        local_vars.get("ClangCoverage", False) or
41        local_vars.get("GcovCoverage", False)
42    )
43
44    providing_vars = {}
45
46    # Generate constraints for Soong config variables (bool, value, string typed).
47    vendor_vars = local_vars.pop("VendorVars", default = {})
48    for (namespace, variables) in vendor_vars.items():
49        for (var, value) in variables.items():
50            # All vendor vars are Starlark string-typed, even though they may be
51            # boxed bools/strings/arbitrary printf'd values, like numbers, so
52            # we'll need to do some translation work here by referring to
53            # soong_injection's generated data.
54
55            if value == "":
56                # Variable is not set so skip adding this as a constraint.
57                continue
58
59            # Create the identifier for the constraint var (or select key)
60            config_var = namespace + "__" + var
61
62            # List of all soong_config_module_type variables.
63            if not config_var in constants.SoongConfigVariables:
64                continue
65
66            # Normalize all constraint vars (i.e. select keys) to be lowercased.
67            constraint_var = config_var.lower()
68
69            if config_var in constants.SoongConfigBoolVariables:
70                constraints.append("//build/bazel/product_variables:" + constraint_var)
71            elif config_var in constants.SoongConfigStringVariables:
72                # The string value is part of the the select key.
73                constraints.append("//build/bazel/product_variables:" + constraint_var + "__" + value.lower())
74            elif config_var in constants.SoongConfigValueVariables:
75                # For value variables, providing_vars add support for substituting
76                # the value using TemplateVariableInfo.
77                constraints.append("//build/bazel/product_variables:" + constraint_var)
78                add_providing_var(providing_vars, "string", constraint_var, value)
79
80    for (var, value) in local_vars.items():
81        # TODO(b/187323817): determine how to handle remaining product
82        # variables not used in product_variables
83        constraint_var = var.lower()
84        if not constants.ProductVariables.get(constraint_var):
85            continue
86
87        # variable.go excludes nil values
88        add_constraint = (value != None)
89        add_providing_var(providing_vars, type(value), var, value)
90        if type(value) == "bool":
91            # variable.go special cases bools
92            add_constraint = value
93
94        if add_constraint:
95            constraints.append("//build/bazel/product_variables:" + constraint_var)
96
97    native.platform(
98        name = name + _product_only_suffix,
99        constraint_values = constraints,
100    )
101
102    arch = local_vars.get("DeviceArch")
103    arch_variant = local_vars.get("DeviceArchVariant")
104    cpu_variant = local_vars.get("DeviceCpuVariant")
105
106    os = "android"
107
108    native.alias(
109        name = name,
110        actual = "{os}_{arch}{variant}".format(os = os, arch = arch, variant = _variant_name(arch, arch_variant, cpu_variant)),
111    )
112
113    arch = local_vars.get("DeviceSecondaryArch")
114    arch_variant = local_vars.get("DeviceSecondaryArchVariant")
115    cpu_variant = local_vars.get("DeviceSecondaryCpuVariant")
116
117    if arch:
118        native.alias(
119            name = name + "_secondary",
120            actual = "{os}_{arch}{variant}".format(os = os, arch = arch, variant = _variant_name(arch, arch_variant, cpu_variant)),
121        )
122
123    product_variables_providing_rule(
124        name = name + "_product_vars",
125        product_vars = providing_vars,
126    )
127
128def _is_variant_default(arch, variant):
129    return variant == None or variant in (arch, "generic")
130
131def _variant_name(arch, arch_variant, cpu_variant):
132    if _is_variant_default(arch, arch_variant):
133        arch_variant = ""
134    if _is_variant_default(arch, cpu_variant):
135        cpu_variant = ""
136    variant = struct(
137        arch_variant = arch_variant,
138        cpu_variant = cpu_variant,
139    )
140    return variant_name(variant)
141
142def android_platform(name = None, constraint_values = [], product = None):
143    """ android_platform creates a platform with the specified constraint_values and product constraints."""
144    native.platform(
145        name = name,
146        constraint_values = constraint_values,
147        parents = [product + _product_only_suffix],
148    )
149