Make global config depend on version defaults.

Starlark-based product configuration can now share version settings
with makefile product config (mk2rbc converts version_defaults.mk into
version_defaults.rbc which is consumed by runtime initialization).

Bug: 198995713
Test: rbcrun build/make/tests/run.rbc
Change-Id: I1d3ddfed3b15d346b3e10714a195a9f0a3a55a56
This commit is contained in:
Sasha Smundak 2021-05-04 09:01:16 -07:00
parent 1646ba0814
commit b2220c2990
4 changed files with 52 additions and 26 deletions

View File

@ -38,7 +38,7 @@ def _allowed_versions(all_versions, min_version, max_version, default_version):
return all_versions[min_i:max_i + 1] return all_versions[min_i:max_i + 1]
# This function is a manual conversion of the version_defaults.mk # This function is a manual conversion of the version_defaults.mk
def _versions_default(g, all_versions): def _versions_default(g, all_versions, v):
"""Handle various build version information. """Handle various build version information.
Guarantees that the following are defined: Guarantees that the following are defined:
@ -59,17 +59,21 @@ def _versions_default(g, all_versions):
_build_id_init(g) _build_id_init(g)
g["INTERNAL_BUILD_ID_MAKEFILE"] = "build/make/core/build_id" g["INTERNAL_BUILD_ID_MAKEFILE"] = "build/make/core/build_id"
allowed_versions = _allowed_versions(all_versions, v_min, v_max, v_default) allowed_versions = _allowed_versions(all_versions, v.min_platform_version, v.max_platform_version, v.default_platform_version)
g.setdefault("TARGET_PLATFORM_VERSION", v_default) g.setdefault("TARGET_PLATFORM_VERSION", v.default_platform_version)
if g["TARGET_PLATFORM_VERSION"] not in allowed_versions: if g["TARGET_PLATFORM_VERSION"] not in allowed_versions:
fail("% is not valid, must be one of %s" % (g["TARGET_PLATFORM_VERSION"], allowed_versions)) fail("% is not valid, must be one of %s" % (g["TARGET_PLATFORM_VERSION"], allowed_versions))
g["DEFAULT_PLATFORM_VERSION"] = v_default g["DEFAULT_PLATFORM_VERSION"] = v.default_platform_version
g["PLATFORM_VERSION_LAST_STABLE"] = 11 g["PLATFORM_VERSION_LAST_STABLE"] = v.platform_version_last_stable
g.setdefault("PLATFORM_VERSION_CODENAME", g["TARGET_PLATFORM_VERSION"]) target_platform_version = g["TARGET_PLATFORM_VERSION"]
if v.codenames[target_platform_version]:
g.setdefault("PLATFORM_VERSION_CODENAME", v.codenames[target_platform_version])
else:
g.setdefault("PLATFORM_VERSION_CODENAME", target_platform_version)
# TODO(asmundak): set PLATFORM_VERSION_ALL_CODENAMES # TODO(asmundak): set PLATFORM_VERSION_ALL_CODENAMES
g.setdefault("PLATFORM_SDK_VERSION", 30) g.setdefault("PLATFORM_SDK_VERSION", v.platform_sdk_version)
version_codename = g["PLATFORM_VERSION_CODENAME"] version_codename = g["PLATFORM_VERSION_CODENAME"]
if version_codename == "REL": if version_codename == "REL":
g.setdefault("PLATFORM_VERSION", g["PLATFORM_VERSION_LAST_STABLE"]) g.setdefault("PLATFORM_VERSION", g["PLATFORM_VERSION_LAST_STABLE"])
@ -92,7 +96,8 @@ def _versions_default(g, all_versions):
# It must be of the form "YYYY-MM-DD" on production devices. # It must be of the form "YYYY-MM-DD" on production devices.
# It must match one of the Android Security Patch Level strings of the Public Security Bulletins. # It must match one of the Android Security Patch Level strings of the Public Security Bulletins.
# If there is no $PLATFORM_SECURITY_PATCH set, keep it empty. # If there is no $PLATFORM_SECURITY_PATCH set, keep it empty.
g.setdefault("PLATFORM_SECURITY_PATCH", "2021-03-05")
g.setdefault("PLATFORM_SECURITY_PATCH", v.platform_security_patch)
dt = 'TZ="GMT" %s' % g["PLATFORM_SECURITY_PATCH"] dt = 'TZ="GMT" %s' % g["PLATFORM_SECURITY_PATCH"]
g.setdefault("PLATFORM_SECURITY_PATCH_TIMESTAMP", rblf_shell("date -d '%s' +%%s" % dt)) g.setdefault("PLATFORM_SECURITY_PATCH_TIMESTAMP", rblf_shell("date -d '%s' +%%s" % dt))
@ -116,16 +121,23 @@ def _versions_default(g, all_versions):
# in a warning being shown when any activity from the app is started. # in a warning being shown when any activity from the app is started.
g.setdefault("PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION", 23) g.setdefault("PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION", 23)
def init(g): # This is the sdk extension version of this tree.
g["PLATFORM_SDK_EXTENSION_VERSION"] = v.platform_sdk_extension_version
# This is the sdk extension version that PLATFORM_SDK_VERSION ships with.
g["PLATFORM_BASE_SDK_EXTENSION_VERSION"] = v.platform_base_sdk_extension_version
def init(g, v):
"""Initializes globals. """Initializes globals.
The code is the Starlark counterpart of the contents of the The code is the Starlark counterpart of the contents of the
envsetup.mk file. envsetup.mk file.
Args: Args:
g: globals dictionary g: globals dictionary
v: version info struct
""" """
all_versions = _all_versions() all_versions = _all_versions()
_versions_default(g, all_versions) _versions_default(g, all_versions, v)
for v in all_versions: for v in all_versions:
g["IS_AT_LEAST" + v] = True g["IS_AT_LEAST" + v] = True
if v == g["TARGET_PLATFORM_VERSION"]: if v == g["TARGET_PLATFORM_VERSION"]:
@ -210,7 +222,3 @@ def init(g):
if g.get("TARGET_BUILD_TYPE", "") != "debug": if g.get("TARGET_BUILD_TYPE", "") != "debug":
g["TARGET_BUILD_TYPE"] = "release" g["TARGET_BUILD_TYPE"] = "release"
v_default = "SP1A"
v_min = "SP1A"
v_max = "SP1A"

View File

@ -17,7 +17,7 @@ load("//build/make/core:envsetup.rbc", _envsetup_init = "init")
"""Runtime functions.""" """Runtime functions."""
_soong_config_namespaces_key = "$SOONG_CONFIG_NAMESPACES" _soong_config_namespaces_key = "$SOONG_CONFIG_NAMESPACES"
def _global_init(): def _global_init(version_info):
"""Returns dict created from the runtime environment.""" """Returns dict created from the runtime environment."""
globals = dict() globals = dict()
@ -31,7 +31,7 @@ def _global_init():
globals.setdefault("PRODUCT_SOONG_NAMESPACES", []) globals.setdefault("PRODUCT_SOONG_NAMESPACES", [])
globals.setdefault(_soong_config_namespaces_key, {}) globals.setdefault(_soong_config_namespaces_key, {})
_envsetup_init(globals) _envsetup_init(globals, version_info)
# Variables that should be defined. # Variables that should be defined.
mandatory_vars = [ mandatory_vars = [
@ -46,10 +46,8 @@ def _global_init():
for bv in mandatory_vars: for bv in mandatory_vars:
if not bv in globals: if not bv in globals:
fail(bv, " is not defined") fail(bv, " is not defined")
return globals return globals
_globals_base = _global_init()
def __print_attr(attr, value): def __print_attr(attr, value):
if not value: if not value:
@ -69,8 +67,9 @@ def __print_attr(attr, value):
else: else:
fail("bad output format", _options.format) fail("bad output format", _options.format)
def _printvars(globals, cfg): def _printvars(state):
"""Prints known configuration variables.""" """Prints configuration and global variables."""
(globals, cfg, globals_base) = state
for attr, val in sorted(cfg.items()): for attr, val in sorted(cfg.items()):
__print_attr(attr, val) __print_attr(attr, val)
if _options.print_globals: if _options.print_globals:
@ -85,7 +84,7 @@ def _printvars(globals, cfg):
print("SOONG_CONFIG_" + nsname, ":=", " ".join(nsvars.keys())) print("SOONG_CONFIG_" + nsname, ":=", " ".join(nsvars.keys()))
for var, val in sorted(nsvars.items()): for var, val in sorted(nsvars.items()):
__print_attr("SOONG_CONFIG_%s_%s" % (nsname, var), val) __print_attr("SOONG_CONFIG_%s_%s" % (nsname, var), val)
elif attr not in _globals_base: elif attr not in globals_base:
__print_attr(attr, val) __print_attr(attr, val)
def __printvars_rearrange_list(value_list): def __printvars_rearrange_list(value_list):
@ -93,7 +92,7 @@ def __printvars_rearrange_list(value_list):
seen = {item: 0 for item in value_list} seen = {item: 0 for item in value_list}
return sorted(seen.keys()) if _options.rearrange == "sort" else seen.keys() return sorted(seen.keys()) if _options.rearrange == "sort" else seen.keys()
def _product_configuration(top_pcm_name, top_pcm): def _product_configuration(top_pcm_name, top_pcm, version_info):
"""Creates configuration.""" """Creates configuration."""
# Product configuration is created by traversing product's inheritance # Product configuration is created by traversing product's inheritance
@ -107,7 +106,8 @@ def _product_configuration(top_pcm_name, top_pcm):
# PCM means "Product Configuration Module", i.e., a Starlark file # PCM means "Product Configuration Module", i.e., a Starlark file
# whose body consists of a single init function. # whose body consists of a single init function.
globals = dict(**_globals_base) globals_base = _global_init(version_info)
globals = dict(**globals_base)
config_postfix = [] # Configs in postfix order config_postfix = [] # Configs in postfix order
@ -198,7 +198,7 @@ def _product_configuration(top_pcm_name, top_pcm):
_percolate_inherited(configs, pcm_name, cfg, children_names) _percolate_inherited(configs, pcm_name, cfg, children_names)
configs[pcm_name] = pcm, cfg, children_names, True configs[pcm_name] = pcm, cfg, children_names, True
return globals, configs[top_pcm_name][1] return (globals, configs[top_pcm_name][1], globals_base)
def _substitute_inherited(configs, pcm_name, cfg): def _substitute_inherited(configs, pcm_name, cfg):
"""Substitutes inherited values in all the attributes. """Substitutes inherited values in all the attributes.
@ -526,6 +526,8 @@ def _mkstrip(s):
That is, removes string's leading and trailing whitespace characters and That is, removes string's leading and trailing whitespace characters and
replaces any sequence of whitespace characters with with a single space. replaces any sequence of whitespace characters with with a single space.
""" """
if type(s) != "string":
return s
result = "" result = ""
was_space = False was_space = False
for ch in s.strip().elems(): for ch in s.strip().elems():

View File

@ -21,15 +21,17 @@
# * all runtime functions (wildcard, regex, etc.) work # * all runtime functions (wildcard, regex, etc.) work
load("//build/make/core:product_config.rbc", "rblf") load("//build/make/core:product_config.rbc", "rblf")
load(":version_defaults.rbc", "version_defaults")
load(":device.rbc", "init") load(":device.rbc", "init")
def assert_eq(expected, actual): def assert_eq(expected, actual):
if expected != actual: if expected != actual:
fail("Expected %s, got %s" % (expected, actual)) fail("Expected '%s', got '%s'" % (expected, actual))
# Unit tests for non-trivial runtime functions # Unit tests for non-trivial runtime functions
assert_eq("", rblf.mkstrip(" \n \t ")) assert_eq("", rblf.mkstrip(" \n \t "))
assert_eq("a b c", rblf.mkstrip(" a b \n c \t")) assert_eq("a b c", rblf.mkstrip(" a b \n c \t"))
assert_eq(1, rblf.mkstrip(1))
assert_eq("b1 b2", rblf.mksubst("a", "b", "a1 a2")) assert_eq("b1 b2", rblf.mksubst("a", "b", "a1 a2"))
assert_eq(["b1", "x2"], rblf.mksubst("a", "b", ["a1", "x2"])) assert_eq(["b1", "x2"], rblf.mksubst("a", "b", ["a1", "x2"]))
@ -50,7 +52,7 @@ assert_eq(["from/a:to/a", "from/b:to/b"], rblf.product_copy_files_by_pattern("fr
assert_eq([], rblf.filter(["a", "", "b"], "f")) assert_eq([], rblf.filter(["a", "", "b"], "f"))
assert_eq(["", "b"], rblf.filter_out(["a", "" ], ["a", "", "b"] )) assert_eq(["", "b"], rblf.filter_out(["a", "" ], ["a", "", "b"] ))
globals, config = rblf.product_configuration("test/device", init) (globals, config, globals_base) = rblf.product_configuration("test/device", init, version_defaults)
assert_eq( assert_eq(
{ {
"PRODUCT_COPY_FILES": [ "PRODUCT_COPY_FILES": [
@ -87,3 +89,6 @@ assert_eq(
}, },
{k:v for k, v in sorted(ns.items()) } {k:v for k, v in sorted(ns.items()) }
) )
assert_eq("S", globals["PLATFORM_VERSION"])
assert_eq(30, globals["PLATFORM_SDK_VERSION"])

View File

@ -0,0 +1,11 @@
version_defaults = struct(
codenames = { "SP1A" : "S" },
default_platform_version = "SP1A",
max_platform_version = "SP1A",
min_platform_version = "SP1A",
platform_base_sdk_extension_version = 0,
platform_sdk_extension_version = 1,
platform_sdk_version = 30,
platform_security_patch = "2021-08-05",
platform_version_last_stable = 11,
)