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

View File

@@ -391,7 +391,7 @@ def read_test_data(relative_path):
return f.read() return f.read()
class TestSoongConfigBoilerplateInserter(unittest.TestCase): class TestAndroidBpTransformations(unittest.TestCase):
def apply_transformations(self, src, transformations, expected): def apply_transformations(self, src, transformations, expected):
producer = mm.SdkDistProducer( producer = mm.SdkDistProducer(
@@ -414,9 +414,9 @@ class TestSoongConfigBoilerplateInserter(unittest.TestCase):
self.assertEqual(expected, result) self.assertEqual(expected, result)
def test_common_mainline_module(self): def test_common_mainline_module(self):
"""Tests the transformations applied to a common mainline module. """Tests the transformations applied to a common mainline sdk on S.
This uses ipsec as an example of a common mainline module. This checks This uses ipsec as an example of a common mainline sdk. This checks
that the correct Soong config module types and variables are used and that the correct Soong config module types and variables are used and
that it imports the definitions from the correct location. that it imports the definitions from the correct location.
""" """
@@ -429,17 +429,25 @@ class TestSoongConfigBoilerplateInserter(unittest.TestCase):
self.apply_transformations(src, transformations, expected) self.apply_transformations(src, transformations, expected)
# Check that Tiramisu provides the same transformations as S. def test_common_mainline_module_tiramisu(self):
tiramisu_transformations = module.transformations(mm.Tiramisu) """Tests the transformations applied to a common mainline sdk on T.
self.assertEqual(
transformations, This uses ipsec as an example of a common mainline sdk. This checks
tiramisu_transformations, that the use_source_config_var property is inserted.
msg="Tiramisu must use the same transformations as S") """
src = read_test_data("ipsec_Android.bp.input")
expected = read_test_data("ipsec_tiramisu_Android.bp.expected")
module = MAINLINE_MODULES_BY_APEX["com.android.ipsec"]
transformations = module.transformations(mm.Tiramisu)
self.apply_transformations(src, transformations, expected)
def test_optional_mainline_module(self): def test_optional_mainline_module(self):
"""Tests the transformations applied to an optional mainline module. """Tests the transformations applied to an optional mainline sdk on S.
This uses wifi as an example of a optional mainline module. This checks This uses wifi as an example of a optional mainline sdk. This checks
that the module specific Soong config module types and variables are that the module specific Soong config module types and variables are
used. used.
""" """
@@ -452,12 +460,20 @@ class TestSoongConfigBoilerplateInserter(unittest.TestCase):
self.apply_transformations(src, transformations, expected) self.apply_transformations(src, transformations, expected)
# Check that Tiramisu provides the same transformations as S. def test_optional_mainline_module_tiramisu(self):
tiramisu_transformations = module.transformations(mm.Tiramisu) """Tests the transformations applied to an optional mainline sdk on T.
self.assertEqual(
transformations, This uses wifi as an example of a optional mainline sdk. This checks
tiramisu_transformations, that the use_source_config_var property is inserted.
msg="Tiramisu must use the same transformations as S") """
src = read_test_data("wifi_Android.bp.input")
expected = read_test_data("wifi_tiramisu_Android.bp.expected")
module = MAINLINE_MODULES_BY_APEX["com.android.wifi"]
transformations = module.transformations(mm.Tiramisu)
self.apply_transformations(src, transformations, expected)
def test_art(self): def test_art(self):
"""Tests the transformations applied to a the ART mainline module. """Tests the transformations applied to a the ART mainline module.

View File

@@ -0,0 +1,77 @@
// This is auto-generated. DO NOT EDIT.
package {
// A default list here prevents the license LSC from adding its own list which would
// be unnecessary as every module in the sdk already has its own licenses property.
default_applicable_licenses: ["Android-Apache-2.0"],
}
prebuilt_bootclasspath_fragment {
name: "com.android.ipsec-bootclasspath-fragment",
// Do not prefer prebuilt if the Soong config variable "module_build_from_source" in namespace "ANDROID" is true.
use_source_config_var: {
config_namespace: "ANDROID",
var_name: "module_build_from_source",
},
visibility: ["//visibility:public"],
apex_available: ["com.android.ipsec"],
licenses: ["ipsec-module-sdk_Android-Apache-2.0"],
contents: ["android.net.ipsec.ike"],
hidden_api: {
stub_flags: "hiddenapi/stub-flags.csv",
annotation_flags: "hiddenapi/annotation-flags.csv",
metadata: "hiddenapi/metadata.csv",
index: "hiddenapi/index.csv",
all_flags: "hiddenapi/all-flags.csv",
},
}
java_sdk_library_import {
name: "android.net.ipsec.ike",
// Do not prefer prebuilt if the Soong config variable "module_build_from_source" in namespace "ANDROID" is true.
use_source_config_var: {
config_namespace: "ANDROID",
var_name: "module_build_from_source",
},
visibility: ["//visibility:public"],
apex_available: [
"com.android.ipsec",
"test_com.android.ipsec",
],
licenses: ["ipsec-module-sdk_Android-Apache-2.0"],
shared_library: true,
compile_dex: true,
permitted_packages: [
"com.android.internal.net",
"android.net.ipsec.ike",
"android.net.eap",
],
public: {
jars: ["sdk_library/public/android.net.ipsec.ike-stubs.jar"],
stub_srcs: ["sdk_library/public/android.net.ipsec.ike.srcjar"],
current_api: "sdk_library/public/android.net.ipsec.ike.txt",
removed_api: "sdk_library/public/android.net.ipsec.ike-removed.txt",
sdk_version: "module_current",
},
system: {
jars: ["sdk_library/system/android.net.ipsec.ike-stubs.jar"],
stub_srcs: ["sdk_library/system/android.net.ipsec.ike.srcjar"],
current_api: "sdk_library/system/android.net.ipsec.ike.txt",
removed_api: "sdk_library/system/android.net.ipsec.ike-removed.txt",
sdk_version: "module_current",
},
module_lib: {
jars: ["sdk_library/module-lib/android.net.ipsec.ike-stubs.jar"],
stub_srcs: ["sdk_library/module-lib/android.net.ipsec.ike.srcjar"],
current_api: "sdk_library/module-lib/android.net.ipsec.ike.txt",
removed_api: "sdk_library/module-lib/android.net.ipsec.ike-removed.txt",
sdk_version: "module_current",
},
}
license {
name: "ipsec-module-sdk_Android-Apache-2.0",
visibility: ["//visibility:private"],
license_kinds: ["SPDX-license-identifier-Apache-2.0"],
license_text: ["licenses/build/soong/licenses/LICENSE"],
}

View File

@@ -0,0 +1,124 @@
// This is auto-generated. DO NOT EDIT.
package {
// A default list here prevents the license LSC from adding its own list which would
// be unnecessary as every module in the sdk already has its own licenses property.
default_applicable_licenses: ["Android-Apache-2.0"],
}
prebuilt_bootclasspath_fragment {
name: "com.android.wifi-bootclasspath-fragment",
// Do not prefer prebuilt if the Soong config variable "source_build" in namespace "wifi_module" is true.
use_source_config_var: {
config_namespace: "wifi_module",
var_name: "source_build",
},
visibility: ["//visibility:public"],
apex_available: ["com.android.wifi"],
licenses: ["wifi-module-sdk_Android-Apache-2.0"],
contents: ["framework-wifi"],
fragments: [
{
apex: "com.android.art",
module: "art-bootclasspath-fragment",
},
],
hidden_api: {
unsupported: ["hiddenapi/hiddenapi-unsupported.txt"],
max_target_r_low_priority: ["hiddenapi/hiddenapi-max-target-r-low-priority.txt"],
max_target_o_low_priority: ["hiddenapi/hiddenapi-max-target-o-low-priority.txt"],
annotation_flags: "hiddenapi/annotation-flags.csv",
metadata: "hiddenapi/metadata.csv",
index: "hiddenapi/index.csv",
signature_patterns: "hiddenapi/signature-patterns.csv",
filtered_stub_flags: "hiddenapi/filtered-stub-flags.csv",
filtered_flags: "hiddenapi/filtered-flags.csv",
},
}
java_sdk_library_import {
name: "framework-wifi",
// Do not prefer prebuilt if the Soong config variable "source_build" in namespace "wifi_module" is true.
use_source_config_var: {
config_namespace: "wifi_module",
var_name: "source_build",
},
visibility: ["//visibility:public"],
apex_available: [
"com.android.wifi",
"test_com.android.wifi",
],
licenses: ["wifi-module-sdk_Android-Apache-2.0"],
shared_library: false,
permitted_packages: [
"android.hardware.wifi",
"android.net.wifi",
"com.android.wifi.x",
],
public: {
jars: ["sdk_library/public/framework-wifi-stubs.jar"],
stub_srcs: ["sdk_library/public/framework-wifi_stub_sources"],
current_api: "sdk_library/public/framework-wifi.txt",
removed_api: "sdk_library/public/framework-wifi-removed.txt",
annotations: "sdk_library/public/framework-wifi_annotations.zip",
sdk_version: "module_current",
},
system: {
jars: ["sdk_library/system/framework-wifi-stubs.jar"],
stub_srcs: ["sdk_library/system/framework-wifi_stub_sources"],
current_api: "sdk_library/system/framework-wifi.txt",
removed_api: "sdk_library/system/framework-wifi-removed.txt",
annotations: "sdk_library/system/framework-wifi_annotations.zip",
sdk_version: "module_current",
},
module_lib: {
jars: ["sdk_library/module-lib/framework-wifi-stubs.jar"],
stub_srcs: ["sdk_library/module-lib/framework-wifi_stub_sources"],
current_api: "sdk_library/module-lib/framework-wifi.txt",
removed_api: "sdk_library/module-lib/framework-wifi-removed.txt",
annotations: "sdk_library/module-lib/framework-wifi_annotations.zip",
sdk_version: "module_current",
},
}
java_import {
name: "service-wifi",
// Do not prefer prebuilt if the Soong config variable "source_build" in namespace "wifi_module" is true.
use_source_config_var: {
config_namespace: "wifi_module",
var_name: "source_build",
},
visibility: [
"//frameworks/opt/net/wifi/service/apex",
"//frameworks/opt/net/wifi/tests/wifitests/apex",
"//packages/modules/Wifi/apex",
"//packages/modules/Wifi/service",
"//packages/modules/Wifi/service/tests/wifitests/apex",
],
apex_available: [
"com.android.wifi",
"test_com.android.wifi",
],
licenses: ["wifi-module-sdk_Android-Apache-2.0"],
jars: ["java_systemserver_libs/snapshot/jars/are/invalid/service-wifi.jar"],
}
license {
name: "wifi-module-sdk_Android-Apache-2.0",
visibility: ["//visibility:private"],
license_kinds: ["SPDX-license-identifier-Apache-2.0"],
license_text: ["licenses/build/soong/licenses/LICENSE"],
}
prebuilt_systemserverclasspath_fragment {
name: "com.android.wifi-systemserverclasspath-fragment",
// Do not prefer prebuilt if the Soong config variable "source_build" in namespace "wifi_module" is true.
use_source_config_var: {
config_namespace: "wifi_module",
var_name: "source_build",
},
visibility: ["//visibility:public"],
apex_available: ["com.android.wifi"],
licenses: ["wifi-module-sdk_Android-Apache-2.0"],
standalone_contents: ["service-wifi"],
}