Switch T+ sdk snapshots to use use_source_config_var property am: db3a3c7df6

Original change: https://android-review.googlesource.com/c/platform/packages/modules/common/+/2165043

Change-Id: I17a489e2def737629711be6bc10f49a3e4a8ebd8
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Paul Duffin
2022-07-26 19:36:17 +00:00
committed by Automerger Merge Worker
4 changed files with 341 additions and 45 deletions

View File

@@ -21,6 +21,7 @@ the APEXes in it are built, otherwise all configured SDKs are built.
import argparse
import dataclasses
import datetime
import enum
import functools
import io
import json
@@ -72,21 +73,41 @@ class FileTransformation:
path: str
def apply(self, producer, path):
"""Apply the transformation to the src_path to produce the dest_path."""
"""Apply the transformation to the path; changing it in place."""
with open(path, "r+", encoding="utf8") as file:
self._apply_transformation(producer, file)
def _apply_transformation(self, producer, file):
"""Apply the transformation to the file.
The file has been opened in read/write mode so the implementation of
this must read the contents and then reset the file to the beginning
and write the altered contents.
"""
raise NotImplementedError
@dataclasses.dataclass(frozen=True)
class SoongConfigBoilerplateInserter(FileTransformation):
class SoongConfigVarTransformation(FileTransformation):
# The configuration variable that will control the prefer setting.
configVar: ConfigVar
# The line containing the prefer property.
PREFER_LINE = " prefer: false,"
def _apply_transformation(self, producer, file):
raise NotImplementedError
@dataclasses.dataclass(frozen=True)
class SoongConfigBoilerplateInserter(SoongConfigVarTransformation):
"""Transforms an Android.bp file to add soong config boilerplate.
The boilerplate allows the prefer setting of the modules to be controlled
through a Soong configuration variable.
"""
# The configuration variable that will control the prefer setting.
configVar: ConfigVar
# The bp file containing the definitions of the configuration module types
# to use in the sdk.
configBpDefFile: str
@@ -94,6 +115,9 @@ class SoongConfigBoilerplateInserter(FileTransformation):
# The prefix to use for the soong config module types.
configModuleTypePrefix: str
def config_module_type(self, module_type):
return self.configModuleTypePrefix + module_type
def apply(self, producer, path):
with open(path, "r+", encoding="utf8") as file:
self._apply_transformation(producer, file)
@@ -144,7 +168,7 @@ class SoongConfigBoilerplateInserter(FileTransformation):
# unversioned relies on the fact that the unversioned modules
# set "prefer: false", while the versioned modules do not. That
# is a little bit fragile so may require some additional checks.
if module_line != " prefer: false,":
if module_line != self.PREFER_LINE:
# The line does not indicate that the module needs the
# soong config boilerplate so add the line and skip to the
# next one.
@@ -170,7 +194,7 @@ class SoongConfigBoilerplateInserter(FileTransformation):
# Change the module type to the corresponding soong config
# module type by adding the prefix.
module_type = self.configModuleTypePrefix + module_type
module_type = self.config_module_type(module_type)
# Generate the module, possibly with the new module type and
# containing the soong config variables entry.
@@ -183,7 +207,7 @@ class SoongConfigBoilerplateInserter(FileTransformation):
# imports the soong config module types into this bp file to the
# header lines so that they appear before any uses.
module_types = "\n".join([
f' "{self.configModuleTypePrefix}{mt}",'
f' "{self.config_module_type(mt)}",'
for mt in sorted(config_module_types)
])
header_lines.append(f"""
@@ -202,7 +226,7 @@ soong_config_module_type_import {{
for module_type in sorted(config_module_types):
# Create the corresponding soong config module type name by
# adding the prefix.
config_module_type = self.configModuleTypePrefix + module_type
config_module_type = self.config_module_type(module_type)
header_lines.append(f"""
// Soong config variable module type added by {producer.script}.
soong_config_module_type {{
@@ -220,6 +244,33 @@ soong_config_module_type {{
file.write("\n".join(header_lines + content_lines) + "\n")
@dataclasses.dataclass(frozen=True)
class UseSourceConfigVarTransformation(SoongConfigVarTransformation):
def _apply_transformation(self, producer, file):
lines = []
for line in file:
line = line.rstrip("\n")
if line != self.PREFER_LINE:
lines.append(line)
continue
# Replace "prefer: false" with "use_source_config_var {...}".
namespace = self.configVar.namespace
name = self.configVar.name
lines.append(f"""\
// Do not prefer prebuilt if the Soong config variable "{name}" in namespace "{namespace}" is true.
use_source_config_var: {{
config_namespace: "{namespace}",
var_name: "{name}",
}},""")
# Overwrite the file with the updated contents.
file.seek(0)
file.truncate()
file.write("\n".join(lines) + "\n")
@dataclasses.dataclass()
class SubprocessRunner:
"""Runs subprocesses"""
@@ -565,6 +616,19 @@ SDK_VERSIONS = [
ALL_BUILD_RELEASES = []
class PreferHandling(enum.Enum):
"""Enumeration of the various ways of handling prefer properties"""
# No special prefer property handling is required.
NONE = enum.auto()
# Apply the SoongConfigBoilerplateInserter transformation.
SOONG_CONFIG = enum.auto()
# Use the use_source_config_var property added in T.
USE_SOURCE_CONFIG_VAR_PROPERTY = enum.auto()
@dataclasses.dataclass(frozen=True)
@functools.total_ordering
class BuildRelease:
@@ -601,7 +665,8 @@ class BuildRelease:
# Whether this build release supports the Soong config boilerplate that is
# used to control the prefer setting of modules via a Soong config variable.
supports_soong_config_boilerplate: bool = True
preferHandling: PreferHandling = \
PreferHandling.USE_SOURCE_CONFIG_VAR_PROPERTY
def __post_init__(self):
# The following use object.__setattr__ as this object is frozen and
@@ -663,6 +728,8 @@ Q = BuildRelease(
name="Q",
# At the moment we do not generate a snapshot for Q.
creator=create_no_dist_snapshot,
# This does not support or need any special prefer property handling.
preferHandling=PreferHandling.NONE,
)
R = BuildRelease(
name="R",
@@ -673,17 +740,23 @@ R = BuildRelease(
# unlikely to) support building an sdk snapshot for R so create an empty
# environment to pass to Soong instead.
soong_env={},
# R does not support or need Soong config boilerplate.
supports_soong_config_boilerplate=False)
# This does not support or need any special prefer property handling.
preferHandling=PreferHandling.NONE,
)
S = BuildRelease(
name="S",
# Generate a snapshot for S using Soong.
creator=create_sdk_snapshots_in_soong,
# This requires the SoongConfigBoilerplateInserter transformation to be
# applied.
preferHandling=PreferHandling.SOONG_CONFIG,
)
Tiramisu = BuildRelease(
name="Tiramisu",
# Generate a snapshot for Tiramisu using Soong.
creator=create_sdk_snapshots_in_soong,
# This supports the use_source_config_var property.
preferHandling=PreferHandling.USE_SOURCE_CONFIG_VAR_PROPERTY,
)
# Insert additional BuildRelease definitions for following releases here,
@@ -801,31 +874,37 @@ class MainlineModule:
def transformations(self, build_release):
"""Returns the transformations to apply to this module's snapshot(s)."""
transformations = []
if build_release.supports_soong_config_boilerplate:
config_var = self.configVar
config_module_type_prefix = self.configModuleTypePrefix
config_bp_def_file = self.configBpDefFile
config_var = self.configVar
config_module_type_prefix = self.configModuleTypePrefix
config_bp_def_file = self.configBpDefFile
# If the module is optional then it needs its own Soong config
# variable to allow it to be managed separately from other modules.
if (self.last_optional_release and
self.last_optional_release > build_release):
config_var = ConfigVar(
namespace=f"{self.short_name}_module",
name="source_build",
)
config_module_type_prefix = f"{self.short_name}_prebuilt_"
# Optional modules don't have their own config_bp_def_file so
# they have to generate the soong_config_module_types inline.
config_bp_def_file = ""
# If the module is optional then it needs its own Soong config
# variable to allow it to be managed separately from other modules.
if (self.last_optional_release and
self.last_optional_release > build_release):
config_var = ConfigVar(
namespace=f"{self.short_name}_module",
name="source_build",
)
config_module_type_prefix = f"{self.short_name}_prebuilt_"
# Optional modules don't have their own config_bp_def_file so
# they have to generate the soong_config_module_types inline.
config_bp_def_file = ""
prefer_handling = build_release.preferHandling
if prefer_handling == PreferHandling.SOONG_CONFIG:
inserter = SoongConfigBoilerplateInserter(
"Android.bp",
configVar=config_var,
configModuleTypePrefix=config_module_type_prefix,
configBpDefFile=config_bp_def_file)
transformations.append(inserter)
elif prefer_handling == PreferHandling.USE_SOURCE_CONFIG_VAR_PROPERTY:
transformation = UseSourceConfigVarTransformation(
"Android.bp", configVar=config_var)
transformations.append(transformation)
return transformations
def is_required_for(self, target_build_release):