blob: b04ae947898d5ffcb5b36cd6172252a2b81f95a1 [file] [log] [blame]
"""Parallels variable.go to provide variables and create a platform based on converted config."""
load("//build/bazel/product_variables:constants.bzl", "constants")
load("//build/bazel/platforms/arch/variants:constants.bzl", _arch_constants = "constants")
def _product_variables_providing_rule_impl(ctx):
return [
platform_common.TemplateVariableInfo(ctx.attr.product_vars),
]
# Provides product variables for templated string replacement.
product_variables_providing_rule = rule(
implementation = _product_variables_providing_rule_impl,
attrs = {
"product_vars": attr.string_dict(),
},
)
_arch_os_only_suffix = "_arch_os"
_product_only_suffix = "_product"
def add_providing_var(providing_vars, typ, var, value):
if typ == "bool":
providing_vars[var] = "1" if value else "0"
elif typ == "list":
providing_vars[var] = ",".join(value)
elif typ == "int":
providing_vars[var] = str(value)
elif typ == "string":
providing_vars[var] = value
def product_variable_config(name, product_config_vars):
constraints = []
local_vars = dict(product_config_vars)
# Native_coverage is not set within soong.variables, but is hardcoded
# within config.go NewConfig
local_vars["Native_coverage"] = (
local_vars.get("ClangCoverage", False) or
local_vars.get("GcovCoverage", False)
)
providing_vars = {}
# Generate constraints for Soong config variables (bool, value, string typed).
vendor_vars = local_vars.pop("VendorVars", default = {})
for (namespace, variables) in vendor_vars.items():
for (var, value) in variables.items():
# All vendor vars are Starlark string-typed, even though they may be
# boxed bools/strings/arbitrary printf'd values, like numbers, so
# we'll need to do some translation work here by referring to
# soong_injection's generated data.
if value == "":
# Variable is not set so skip adding this as a constraint.
continue
# Create the identifier for the constraint var (or select key)
config_var = namespace + "__" + var
# List of all soong_config_module_type variables.
if not config_var in constants.SoongConfigVariables:
continue
# Normalize all constraint vars (i.e. select keys) to be lowercased.
constraint_var = config_var.lower()
if config_var in constants.SoongConfigBoolVariables:
constraints.append("//build/bazel/product_variables:" + constraint_var)
elif config_var in constants.SoongConfigStringVariables:
# The string value is part of the the select key.
constraints.append("//build/bazel/product_variables:" + constraint_var + "__" + value.lower())
elif config_var in constants.SoongConfigValueVariables:
# For value variables, providing_vars add support for substituting
# the value using TemplateVariableInfo.
constraints.append("//build/bazel/product_variables:" + constraint_var)
add_providing_var(providing_vars, "string", constraint_var, value)
for (var, value) in local_vars.items():
# TODO(b/187323817): determine how to handle remaining product
# variables not used in product_variables
constraint_var = var.lower()
if not constants.ProductVariables.get(constraint_var):
continue
# variable.go excludes nil values
add_constraint = (value != None)
add_providing_var(providing_vars, type(value), var, value)
if type(value) == "bool":
# variable.go special cases bools
add_constraint = value
if add_constraint:
constraints.append("//build/bazel/product_variables:" + constraint_var)
native.platform(
name = name + _product_only_suffix,
constraint_values = constraints,
)
arch = local_vars.get("DeviceArch")
arch_variant = local_vars.get("DeviceArchVariant")
cpu_variant = local_vars.get("DeviceCpuVariant")
os = "android"
native.platform(
name = name,
constraint_values = constraints + [
"//build/bazel/platforms/arch:" + arch,
"//build/bazel/platforms/os:" + os,
] + android_variant_constraints(arch, arch_variant, cpu_variant),
)
arch = local_vars.get("DeviceSecondaryArch")
arch_variant = local_vars.get("DeviceSecondaryArchVariant")
cpu_variant = local_vars.get("DeviceSecondaryCpuVariant")
if arch:
native.platform(
name = name + "_secondary",
constraint_values = constraints + [
"//build/bazel/platforms/arch:" + arch,
"//build/bazel/platforms/os:" + os,
] + android_variant_constraints(arch, arch_variant, cpu_variant),
)
product_variables_providing_rule(
name = name + "_product_vars",
product_vars = providing_vars,
)
def _is_variant_default(arch, variant):
return variant == None or variant in (arch, "generic")
def android_variant_constraints(arch, arch_variant = None, cpu_variant = None):
additional_constraints = []
if not _is_variant_default(arch, arch_variant):
additional_constraints.append("//build/bazel/platforms/arch/variants:" + arch_variant)
else:
arch_variant = ""
features = _arch_constants.AndroidArchToVariantToFeatures[arch].get(arch_variant, [])
for feature in features:
additional_constraints.append("//build/bazel/platforms/arch/variants:" + feature)
if not _is_variant_default(arch, cpu_variant):
additional_constraints.append("//build/bazel/platforms/arch/variants:" + cpu_variant)
return additional_constraints
def android_platform(name = None, constraint_values = [], product = None):
""" android_platform creates a platform with the specified constraint_values and product constraints."""
native.platform(
name = name,
constraint_values = constraint_values,
parents = [product + _product_only_suffix],
)