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