Merge "Drop IncludeTags" into main
diff --git a/aconfig/build_flags/Android.bp b/aconfig/build_flags/Android.bp
index 69e4316..b3c7339 100644
--- a/aconfig/build_flags/Android.bp
+++ b/aconfig/build_flags/Android.bp
@@ -14,6 +14,7 @@
],
srcs: [
"all_build_flag_declarations.go",
+ "build_flags.go",
"declarations.go",
"init.go",
],
diff --git a/aconfig/build_flags/build_flags.go b/aconfig/build_flags/build_flags.go
new file mode 100644
index 0000000..e878b5a
--- /dev/null
+++ b/aconfig/build_flags/build_flags.go
@@ -0,0 +1,71 @@
+// Copyright 2024 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package build_flags
+
+import (
+ "fmt"
+
+ "android/soong/android"
+)
+
+const (
+ outJsonFileName = "build_flags.json"
+)
+
+func init() {
+ registerBuildFlagsModuleType(android.InitRegistrationContext)
+}
+
+func registerBuildFlagsModuleType(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("build_flags_json", buildFlagsFactory)
+}
+
+type buildFlags struct {
+ android.ModuleBase
+
+ outputPath android.OutputPath
+}
+
+func buildFlagsFactory() android.Module {
+ module := &buildFlags{}
+ android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
+ return module
+}
+
+func (m *buildFlags) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ // Read the build_flags_<partition>.json file generated by soong
+ // 'release-config' command.
+ srcPath := android.PathForOutput(ctx, "release-config", fmt.Sprintf("build_flags_%s.json", m.PartitionTag(ctx.DeviceConfig())))
+ m.outputPath = android.PathForModuleOut(ctx, outJsonFileName).OutputPath
+
+ // The 'release-config' command is called for every build, and generates the
+ // build_flags_<partition>.json file.
+ // Update the output file only if the source file is changed.
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.CpIfChanged,
+ Input: srcPath,
+ Output: m.outputPath,
+ })
+
+ installPath := android.PathForModuleInstall(ctx, "etc")
+ ctx.InstallFile(installPath, outJsonFileName, m.outputPath)
+}
+
+func (m *buildFlags) AndroidMkEntries() []android.AndroidMkEntries {
+ return []android.AndroidMkEntries{android.AndroidMkEntries{
+ Class: "ETC",
+ OutputFile: android.OptionalPathForPath(m.outputPath),
+ }}
+}
diff --git a/aconfig/build_flags/init.go b/aconfig/build_flags/init.go
index 5907f4e..dc1369c 100644
--- a/aconfig/build_flags/init.go
+++ b/aconfig/build_flags/init.go
@@ -69,6 +69,7 @@
func init() {
RegisterBuildComponents(android.InitRegistrationContext)
+ pctx.Import("android/soong/android")
pctx.HostBinToolVariable("buildFlagDeclarations", "build-flag-declarations")
}
diff --git a/aconfig/codegen/cc_aconfig_library_test.go b/aconfig/codegen/cc_aconfig_library_test.go
index d01d13b..2f6c1a6 100644
--- a/aconfig/codegen/cc_aconfig_library_test.go
+++ b/aconfig/codegen/cc_aconfig_library_test.go
@@ -74,11 +74,6 @@
srcs: ["libaconfig_storage_read_api_cc.cc"],
}
- cc_library {
- name: "libaconfig_storage_protos_cc",
- srcs: ["libaconfig_storage_protos_cc.cc"],
- }
-
cc_aconfig_library {
name: "my_cc_aconfig_library",
aconfig_declarations: "my_aconfig_declarations",
@@ -137,12 +132,6 @@
srcs: ["libaconfig_storage_read_api_cc.cc"],
}
- cc_library {
- name: "libaconfig_storage_protos_cc",
- srcs: ["libaconfig_storage_protos_cc.cc"],
- }
-
-
cc_aconfig_library {
name: "my_cc_aconfig_library",
aconfig_declarations: "my_aconfig_declarations",
@@ -214,12 +203,6 @@
srcs: ["libaconfig_storage_read_api_cc.cc"],
vendor_available: true,
}
-
- cc_library {
- name: "libaconfig_storage_protos_cc",
- srcs: ["libaconfig_storage_protos_cc.cc"],
- vendor_available: true,
- }
`
result := android.GroupFixturePreparers(
PrepareForTestWithAconfigBuildComponents,
diff --git a/android/apex.go b/android/apex.go
index fcbd13e..2ac6ed0 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -350,7 +350,8 @@
// ApexModuleBase provides the default implementation for the ApexModule interface. APEX-aware
// modules are expected to include this struct and call InitApexModule().
type ApexModuleBase struct {
- ApexProperties ApexProperties
+ ApexProperties ApexProperties
+ apexPropertiesLock sync.Mutex // protects ApexProperties during parallel apexDirectlyInAnyMutator
canHaveApexVariants bool
@@ -761,18 +762,22 @@
// UpdateDirectlyInAnyApex uses the final module to store if any variant of this module is directly
// in any APEX, and then copies the final value to all the modules. It also copies the
-// DirectlyInAnyApex value to any direct dependencies with a CopyDirectlyInAnyApexTag dependency
-// tag.
+// DirectlyInAnyApex value to any transitive dependencies with a CopyDirectlyInAnyApexTag
+// dependency tag.
func UpdateDirectlyInAnyApex(mctx BottomUpMutatorContext, am ApexModule) {
base := am.apexModuleBase()
- // Copy DirectlyInAnyApex and InAnyApex from any direct dependencies with a
+ // Copy DirectlyInAnyApex and InAnyApex from any transitive dependencies with a
// CopyDirectlyInAnyApexTag dependency tag.
- mctx.VisitDirectDeps(func(dep Module) {
- if _, ok := mctx.OtherModuleDependencyTag(dep).(CopyDirectlyInAnyApexTag); ok {
- depBase := dep.(ApexModule).apexModuleBase()
+ mctx.WalkDeps(func(child, parent Module) bool {
+ if _, ok := mctx.OtherModuleDependencyTag(child).(CopyDirectlyInAnyApexTag); ok {
+ depBase := child.(ApexModule).apexModuleBase()
+ depBase.apexPropertiesLock.Lock()
+ defer depBase.apexPropertiesLock.Unlock()
depBase.ApexProperties.DirectlyInAnyApex = base.ApexProperties.DirectlyInAnyApex
depBase.ApexProperties.InAnyApex = base.ApexProperties.InAnyApex
+ return true
}
+ return false
})
if base.ApexProperties.DirectlyInAnyApex {
diff --git a/android/apex_contributions.go b/android/apex_contributions.go
index 91549e5..8b72f8e 100644
--- a/android/apex_contributions.go
+++ b/android/apex_contributions.go
@@ -106,7 +106,13 @@
// Creates a dep to each selected apex_contributions
func (a *allApexContributions) DepsMutator(ctx BottomUpMutatorContext) {
- ctx.AddDependency(ctx.Module(), AcDepTag, ctx.Config().AllApexContributions()...)
+ // Skip apex_contributions if BuildApexContributionContents is true
+ // This product config var allows some products in the same family to use mainline modules from source
+ // (e.g. shiba and shiba_fullmte)
+ // Eventually these product variants will have their own release config maps.
+ if !proptools.Bool(ctx.Config().BuildIgnoreApexContributionContents()) {
+ ctx.AddDependency(ctx.Module(), AcDepTag, ctx.Config().AllApexContributions()...)
+ }
}
// Set PrebuiltSelectionInfoProvider in post deps phase
@@ -126,19 +132,13 @@
}
p := PrebuiltSelectionInfoMap{}
- // Skip apex_contributions if BuildApexContributionContents is true
- // This product config var allows some products in the same family to use mainline modules from source
- // (e.g. shiba and shiba_fullmte)
- // Eventually these product variants will have their own release config maps.
- if !proptools.Bool(ctx.Config().BuildIgnoreApexContributionContents()) {
- ctx.VisitDirectDepsWithTag(AcDepTag, func(child Module) {
- if m, ok := child.(*apexContributions); ok {
- addContentsToProvider(&p, m)
- } else {
- ctx.ModuleErrorf("%s is not an apex_contributions module\n", child.Name())
- }
- })
- }
+ ctx.VisitDirectDepsWithTag(AcDepTag, func(child Module) {
+ if m, ok := child.(*apexContributions); ok {
+ addContentsToProvider(&p, m)
+ } else {
+ ctx.ModuleErrorf("%s is not an apex_contributions module\n", child.Name())
+ }
+ })
SetProvider(ctx, PrebuiltSelectionInfoProvider, p)
}
diff --git a/android/config.go b/android/config.go
index e1eb97b..a18cb8b 100644
--- a/android/config.go
+++ b/android/config.go
@@ -370,6 +370,7 @@
} else {
// Make a decoder for it
jsonDecoder := json.NewDecoder(configFileReader)
+ jsonDecoder.DisallowUnknownFields()
err = jsonDecoder.Decode(configurable)
if err != nil {
return fmt.Errorf("config file: %s did not parse correctly: %s", filename, err.Error())
@@ -827,6 +828,10 @@
return value == "0" || value == "n" || value == "no" || value == "off" || value == "false"
}
+func (c *config) TargetsJava21() bool {
+ return c.IsEnvTrue("EXPERIMENTAL_TARGET_JAVA_VERSION_21")
+}
+
// EnvDeps returns the environment variables this build depends on. The first
// call to this function blocks future reads from the environment.
func (c *config) EnvDeps() map[string]string {
@@ -1458,10 +1463,6 @@
return c.config.productVariables.ExtraVndkVersions
}
-func (c *deviceConfig) VndkUseCoreVariant() bool {
- return Bool(c.config.productVariables.VndkUseCoreVariant) && Bool(c.config.productVariables.KeepVndk)
-}
-
func (c *deviceConfig) SystemSdkVersions() []string {
return c.config.productVariables.DeviceSystemSdkVersions
}
@@ -1908,10 +1909,10 @@
}
func (c *deviceConfig) ShippingApiLevel() ApiLevel {
- if c.config.productVariables.ShippingApiLevel == nil {
+ if c.config.productVariables.Shipping_api_level == nil {
return NoneApiLevel
}
- apiLevel, _ := strconv.Atoi(*c.config.productVariables.ShippingApiLevel)
+ apiLevel, _ := strconv.Atoi(*c.config.productVariables.Shipping_api_level)
return uncheckedFinalApiLevel(apiLevel)
}
@@ -2112,6 +2113,7 @@
"RELEASE_APEX_CONTRIBUTIONS_SDKEXTENSIONS",
"RELEASE_APEX_CONTRIBUTIONS_SWCODEC",
"RELEASE_APEX_CONTRIBUTIONS_STATSD",
+ "RELEASE_APEX_CONTRIBUTIONS_TELEMETRY_TVP",
"RELEASE_APEX_CONTRIBUTIONS_TZDATA",
"RELEASE_APEX_CONTRIBUTIONS_UWB",
"RELEASE_APEX_CONTRIBUTIONS_WIFI",
diff --git a/android/filegroup.go b/android/filegroup.go
index a8326d4..ff0f74e 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -19,6 +19,7 @@
"strings"
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
)
func init() {
@@ -36,9 +37,9 @@
type fileGroupProperties struct {
// srcs lists files that will be included in this filegroup
- Srcs []string `android:"path"`
+ Srcs proptools.Configurable[[]string] `android:"path"`
- Exclude_srcs []string `android:"path"`
+ Exclude_srcs proptools.Configurable[[]string] `android:"path"`
// The base path to the files. May be used by other modules to determine which portion
// of the path to use. For example, when a filegroup is used as data in a cc_test rule,
@@ -89,7 +90,7 @@
}
func (fg *fileGroup) GenerateAndroidBuildActions(ctx ModuleContext) {
- fg.srcs = PathsForModuleSrcExcludes(ctx, fg.properties.Srcs, fg.properties.Exclude_srcs)
+ fg.srcs = PathsForModuleSrcExcludes(ctx, fg.properties.Srcs.GetOrDefault(ctx, nil), fg.properties.Exclude_srcs.GetOrDefault(ctx, nil))
if fg.properties.Path != nil {
fg.srcs = PathsWithModuleSrcSubDir(ctx, fg.srcs, String(fg.properties.Path))
}
diff --git a/android/module.go b/android/module.go
index c4cc5e6..dc585d2 100644
--- a/android/module.go
+++ b/android/module.go
@@ -915,6 +915,10 @@
// moduleInfoJSON can be filled out by GenerateAndroidBuildActions to write a JSON file that will
// be included in the final module-info.json produced by Make.
moduleInfoJSON *ModuleInfoJSON
+
+ // outputFiles stores the output of a module by tag and is used to set
+ // the OutputFilesProvider in GenerateBuildActions
+ outputFiles OutputFilesInfo
}
func (m *ModuleBase) AddJSONData(d *map[string]interface{}) {
@@ -1076,6 +1080,12 @@
return
}
+ // ... also don't make a dependency between native bridge arch and non-native bridge
+ // arches. b/342945184
+ if ctx.Target().NativeBridge != target.NativeBridge {
+ return
+ }
+
variation := target.Variations()
if ctx.OtherModuleFarDependencyVariantExists(variation, depName) {
ctx.AddFarVariationDependencies(variation, RequiredDepTag, depName)
@@ -1990,6 +2000,10 @@
m.buildParams = ctx.buildParams
m.ruleParams = ctx.ruleParams
m.variables = ctx.variables
+
+ if m.outputFiles.DefaultOutputFiles != nil || m.outputFiles.TaggedOutputFiles != nil {
+ SetProvider(ctx, OutputFilesProvider, m.outputFiles)
+ }
}
func SetJarJarPrefixHandler(handler func(ModuleContext)) {
@@ -2439,11 +2453,15 @@
}
func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) (Paths, error) {
+ outputFilesFromProvider, err := outputFilesForModuleFromProvider(ctx, module, tag)
+ if outputFilesFromProvider != nil || err != nil {
+ return outputFilesFromProvider, err
+ }
if outputFileProducer, ok := module.(OutputFileProducer); ok {
paths, err := outputFileProducer.OutputFiles(tag)
if err != nil {
- return nil, fmt.Errorf("failed to get output file from module %q: %s",
- pathContextName(ctx, module), err.Error())
+ return nil, fmt.Errorf("failed to get output file from module %q at tag %q: %s",
+ pathContextName(ctx, module), tag, err.Error())
}
return paths, nil
} else if sourceFileProducer, ok := module.(SourceFileProducer); ok {
@@ -2453,10 +2471,54 @@
paths := sourceFileProducer.Srcs()
return paths, nil
} else {
- return nil, fmt.Errorf("module %q is not an OutputFileProducer", pathContextName(ctx, module))
+ return nil, fmt.Errorf("module %q is not an OutputFileProducer or SourceFileProducer", pathContextName(ctx, module))
}
}
+// This method uses OutputFilesProvider for output files
+// *inter-module-communication*.
+// If mctx module is the same as the param module the output files are obtained
+// from outputFiles property of module base, to avoid both setting and
+// reading OutputFilesProvider before GenerateBuildActions is finished. Also
+// only empty-string-tag is supported in this case.
+// If a module doesn't have the OutputFilesProvider, nil is returned.
+func outputFilesForModuleFromProvider(ctx PathContext, module blueprint.Module, tag string) (Paths, error) {
+ // TODO: support OutputFilesProvider for singletons
+ mctx, ok := ctx.(ModuleContext)
+ if !ok {
+ return nil, nil
+ }
+ if mctx.Module() != module {
+ if outputFilesProvider, ok := OtherModuleProvider(mctx, module, OutputFilesProvider); ok {
+ if tag == "" {
+ return outputFilesProvider.DefaultOutputFiles, nil
+ } else if taggedOutputFiles, hasTag := outputFilesProvider.TaggedOutputFiles[tag]; hasTag {
+ return taggedOutputFiles, nil
+ } else {
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+ }
+ }
+ } else {
+ if tag == "" {
+ return mctx.Module().base().outputFiles.DefaultOutputFiles, nil
+ } else {
+ return nil, fmt.Errorf("unsupported tag %q for module getting its own output files", tag)
+ }
+ }
+ // TODO: Add a check for param module not having OutputFilesProvider set
+ return nil, nil
+}
+
+type OutputFilesInfo struct {
+ // default output files when tag is an empty string ""
+ DefaultOutputFiles Paths
+
+ // the corresponding output files for given tags
+ TaggedOutputFiles map[string]Paths
+}
+
+var OutputFilesProvider = blueprint.NewProvider[OutputFilesInfo]()
+
// Modules can implement HostToolProvider and return a valid OptionalPath from HostToolPath() to
// specify that they can be used as a tool by a genrule module.
type HostToolProvider interface {
diff --git a/android/module_context.go b/android/module_context.go
index 18adb30..591e270 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -212,6 +212,10 @@
// GenerateAndroidBuildActions. If it is called then the struct will be written out and included in
// the module-info.json generated by Make, and Make will not generate its own data for this module.
ModuleInfoJSON() *ModuleInfoJSON
+
+ // SetOutputFiles stores the outputFiles to outputFiles property, which is used
+ // to set the OutputFilesProvider later.
+ SetOutputFiles(outputFiles Paths, tag string)
}
type moduleContext struct {
@@ -707,6 +711,24 @@
return moduleInfoJSON
}
+func (m *moduleContext) SetOutputFiles(outputFiles Paths, tag string) {
+ if tag == "" {
+ if len(m.module.base().outputFiles.DefaultOutputFiles) > 0 {
+ m.ModuleErrorf("Module %s default OutputFiles cannot be overwritten", m.ModuleName())
+ }
+ m.module.base().outputFiles.DefaultOutputFiles = outputFiles
+ } else {
+ if m.module.base().outputFiles.TaggedOutputFiles == nil {
+ m.module.base().outputFiles.TaggedOutputFiles = make(map[string]Paths)
+ }
+ if _, exists := m.module.base().outputFiles.TaggedOutputFiles[tag]; exists {
+ m.ModuleErrorf("Module %s OutputFiles at tag %s cannot be overwritten", m.ModuleName(), tag)
+ } else {
+ m.module.base().outputFiles.TaggedOutputFiles[tag] = outputFiles
+ }
+ }
+}
+
// Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must
// be tagged with `android:"path" to support automatic source module dependency resolution.
//
diff --git a/android/override_module.go b/android/override_module.go
index 55f384f..f69f963 100644
--- a/android/override_module.go
+++ b/android/override_module.go
@@ -253,6 +253,15 @@
var overrideBaseDepTag overrideBaseDependencyTag
+// Override module should always override the source module.
+// Overrides are implemented as a variant of the overridden module, and the build actions are created in the
+// module context of the overridden module.
+// If we replace override module with the prebuilt of the overridden module, `GenerateAndroidBuildActions` for
+// the override module will have a very different meaning.
+func (tag overrideBaseDependencyTag) ReplaceSourceWithPrebuilt() bool {
+ return false
+}
+
// Adds dependency on the base module to the overriding module so that they can be visited in the
// next phase.
func overrideModuleDepsMutator(ctx BottomUpMutatorContext) {
diff --git a/android/paths.go b/android/paths.go
index 8d92aa4..edc0700 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -565,21 +565,15 @@
if aModule, ok := module.(Module); ok && !aModule.Enabled(ctx) {
return nil, missingDependencyError{[]string{moduleName}}
}
- if outProducer, ok := module.(OutputFileProducer); ok {
- outputFiles, err := outProducer.OutputFiles(tag)
- if err != nil {
- return nil, fmt.Errorf("path dependency %q: %s", path, err)
- }
- return outputFiles, nil
- } else if tag != "" {
- return nil, fmt.Errorf("path dependency %q is not an output file producing module", path)
- } else if goBinary, ok := module.(bootstrap.GoBinaryTool); ok {
+ if goBinary, ok := module.(bootstrap.GoBinaryTool); ok && tag == "" {
goBinaryPath := PathForGoBinary(ctx, goBinary)
return Paths{goBinaryPath}, nil
- } else if srcProducer, ok := module.(SourceFileProducer); ok {
- return srcProducer.Srcs(), nil
+ }
+ outputFiles, err := outputFilesForModule(ctx, module, tag)
+ if outputFiles != nil && err == nil {
+ return outputFiles, nil
} else {
- return nil, fmt.Errorf("path dependency %q is not a source file producing module", path)
+ return nil, err
}
}
diff --git a/android/selects_test.go b/android/selects_test.go
index 87ba42a..6f980ce 100644
--- a/android/selects_test.go
+++ b/android/selects_test.go
@@ -729,6 +729,55 @@
},
},
},
+ {
+ name: "Soong config value variable on configurable property",
+ bp: `
+ soong_config_module_type {
+ name: "soong_config_my_module_type",
+ module_type: "my_module_type",
+ config_namespace: "my_namespace",
+ value_variables: ["my_variable"],
+ properties: ["my_string", "my_string_list"],
+ }
+
+ soong_config_my_module_type {
+ name: "foo",
+ my_string_list: ["before.cpp"],
+ soong_config_variables: {
+ my_variable: {
+ my_string_list: ["after_%s.cpp"],
+ my_string: "%s.cpp",
+ },
+ },
+ }
+ `,
+ provider: selectsTestProvider{
+ my_string: proptools.StringPtr("foo.cpp"),
+ my_string_list: &[]string{"before.cpp", "after_foo.cpp"},
+ },
+ vendorVars: map[string]map[string]string{
+ "my_namespace": {
+ "my_variable": "foo",
+ },
+ },
+ },
+ {
+ name: "Property appending with variable",
+ bp: `
+ my_variable = ["b.cpp"]
+ my_module_type {
+ name: "foo",
+ my_string_list: ["a.cpp"] + my_variable + select(soong_config_variable("my_namespace", "my_variable"), {
+ "a": ["a.cpp"],
+ "b": ["b.cpp"],
+ default: ["c.cpp"],
+ }),
+ }
+ `,
+ provider: selectsTestProvider{
+ my_string_list: &[]string{"a.cpp", "b.cpp", "c.cpp"},
+ },
+ },
}
for _, tc := range testCases {
@@ -736,6 +785,7 @@
fixtures := GroupFixturePreparers(
PrepareForTestWithDefaults,
PrepareForTestWithArchMutator,
+ PrepareForTestWithSoongConfigModuleBuildComponents,
FixtureRegisterWithContext(func(ctx RegistrationContext) {
ctx.RegisterModuleType("my_module_type", newSelectsMockModule)
ctx.RegisterModuleType("my_defaults", newSelectsMockModuleDefaults)
@@ -790,7 +840,7 @@
myStringStr = *p.my_string
}
myNonconfigurableStringStr := "nil"
- if p.my_string != nil {
+ if p.my_nonconfigurable_string != nil {
myNonconfigurableStringStr = *p.my_nonconfigurable_string
}
return fmt.Sprintf(`selectsTestProvider {
diff --git a/android/soongconfig/modules.go b/android/soongconfig/modules.go
index c910974..87af774 100644
--- a/android/soongconfig/modules.go
+++ b/android/soongconfig/modules.go
@@ -733,11 +733,18 @@
case reflect.Bool:
// Nothing to do
case reflect.Struct:
- fieldName = append(fieldName, propStruct.Type().Field(i).Name)
- if err := s.printfIntoPropertyRecursive(fieldName, field, configValue); err != nil {
- return err
+ if proptools.IsConfigurable(field.Type()) {
+ if err := proptools.PrintfIntoConfigurable(field.Interface(), configValue); err != nil {
+ fieldName = append(fieldName, propStruct.Type().Field(i).Name)
+ return fmt.Errorf("soong_config_variables.%s.%s: %s", s.variable, strings.Join(fieldName, "."), err)
+ }
+ } else {
+ fieldName = append(fieldName, propStruct.Type().Field(i).Name)
+ if err := s.printfIntoPropertyRecursive(fieldName, field, configValue); err != nil {
+ return err
+ }
+ fieldName = fieldName[:len(fieldName)-1]
}
- fieldName = fieldName[:len(fieldName)-1]
default:
fieldName = append(fieldName, propStruct.Type().Field(i).Name)
return fmt.Errorf("soong_config_variables.%s.%s: unsupported property type %q", s.variable, strings.Join(fieldName, "."), kind)
diff --git a/android/test_config.go b/android/test_config.go
index a15343a..f251038 100644
--- a/android/test_config.go
+++ b/android/test_config.go
@@ -50,7 +50,7 @@
AAPTCharacteristics: stringPtr("nosdcard"),
AAPTPrebuiltDPI: []string{"xhdpi", "xxhdpi"},
UncompressPrivAppDex: boolPtr(true),
- ShippingApiLevel: stringPtr("30"),
+ Shipping_api_level: stringPtr("30"),
},
outDir: buildDir,
diff --git a/android/variable.go b/android/variable.go
index e6358cc..1633816 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -55,6 +55,10 @@
Base_dir *string
}
+ Shipping_api_level struct {
+ Cflags []string
+ }
+
// unbundled_build is a catch-all property to annotate modules that don't build in one or
// more unbundled branches, usually due to dependencies missing from the manifest.
Unbundled_build struct {
@@ -181,8 +185,10 @@
// release_aidl_use_unfrozen is "true" when a device can
// use the unfrozen versions of AIDL interfaces.
Release_aidl_use_unfrozen struct {
- Cflags []string
- Cmd *string
+ Cflags []string
+ Cmd *string
+ Required []string
+ Vintf_fragments []string
}
} `android:"arch_variant"`
}
@@ -362,7 +368,6 @@
PgoAdditionalProfileDirs []string `json:",omitempty"`
- VndkUseCoreVariant *bool `json:",omitempty"`
VndkSnapshotBuildArtifacts *bool `json:",omitempty"`
DirectedVendorSnapshot bool `json:",omitempty"`
@@ -439,7 +444,7 @@
PrebuiltHiddenApiDir *string `json:",omitempty"`
- ShippingApiLevel *string `json:",omitempty"`
+ Shipping_api_level *string `json:",omitempty"`
BuildBrokenPluginValidation []string `json:",omitempty"`
BuildBrokenClangAsFlags bool `json:",omitempty"`
diff --git a/apex/aconfig_test.go b/apex/aconfig_test.go
index 726041c..14c0b63 100644
--- a/apex/aconfig_test.go
+++ b/apex/aconfig_test.go
@@ -23,6 +23,7 @@
"android/soong/genrule"
"android/soong/java"
"android/soong/rust"
+
"github.com/google/blueprint/proptools"
)
@@ -173,10 +174,6 @@
name: "libaconfig_storage_read_api_cc",
srcs: ["libaconfig_storage_read_api_cc.cc"],
}
- cc_library {
- name: "libaconfig_storage_protos_cc",
- srcs: ["libaconfig_storage_protos_cc.cc"],
- }
aconfig_declarations {
name: "my_aconfig_declarations_bar",
package: "com.example.package",
@@ -436,10 +433,6 @@
name: "libaconfig_storage_read_api_cc",
srcs: ["libaconfig_storage_read_api_cc.cc"],
}
- cc_library {
- name: "libaconfig_storage_protos_cc",
- srcs: ["libaconfig_storage_protos_cc.cc"],
- }
aconfig_declarations {
name: "my_aconfig_declarations_foo",
package: "com.example.package",
@@ -501,10 +494,6 @@
name: "libaconfig_storage_read_api_cc",
srcs: ["libaconfig_storage_read_api_cc.cc"],
}
- cc_library {
- name: "libaconfig_storage_protos_cc",
- srcs: ["libaconfig_storage_protos_cc.cc"],
- }
aconfig_declarations {
name: "my_aconfig_declarations_foo",
package: "com.example.package",
diff --git a/apex/apex.go b/apex/apex.go
index 1dec61b..e79afad 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2112,7 +2112,7 @@
}
case bpfTag:
if bpfProgram, ok := child.(bpf.BpfModule); ok {
- filesToCopy, _ := bpfProgram.OutputFiles("")
+ filesToCopy := android.OutputFilesForModule(ctx, bpfProgram, "")
apex_sub_dir := bpfProgram.SubDir()
for _, bpfFile := range filesToCopy {
vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram))
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 965b4be..c60ee73 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -10709,10 +10709,6 @@
name: "libaconfig_storage_read_api_cc",
srcs: ["libaconfig_storage_read_api_cc.cc"],
}
- cc_library {
- name: "libaconfig_storage_protos_cc",
- srcs: ["libaconfig_storage_protos_cc.cc"],
- }
`)
mod := ctx.ModuleForTests("myapex", "android_common_myapex")
@@ -11675,3 +11671,38 @@
checkMinSdkVersion(t, overridingModuleDifferentMinSdkVersion, "31")
checkHasDep(t, ctx, overridingModuleDifferentMinSdkVersion.Module(), javalibApex31Variant.Module())
}
+
+func TestOverrideApexWithPrebuiltApexPreferred(t *testing.T) {
+ context := android.GroupFixturePreparers(
+ android.PrepareForIntegrationTestWithAndroid,
+ PrepareForTestWithApexBuildComponents,
+ android.FixtureMergeMockFs(android.MockFS{
+ "system/sepolicy/apex/foo-file_contexts": nil,
+ }),
+ )
+ res := context.RunTestWithBp(t, `
+ apex {
+ name: "foo",
+ key: "myapex.key",
+ apex_available_name: "com.android.foo",
+ variant_version: "0",
+ updatable: false,
+ }
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+ prebuilt_apex {
+ name: "foo",
+ src: "foo.apex",
+ prefer: true,
+ }
+ override_apex {
+ name: "myoverrideapex",
+ base: "foo",
+ }
+ `)
+
+ java.CheckModuleHasDependency(t, res.TestContext, "myoverrideapex", "android_common_myoverrideapex_myoverrideapex", "foo")
+}
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index 778c20a..af9123e 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -197,6 +197,12 @@
updatable: false,
}
+ override_apex {
+ name: "com.mycompany.android.art",
+ base: "com.android.art",
+ min_sdk_version: "33", // mycompany overrides the min_sdk_version
+ }
+
apex_key {
name: "com.android.art.key",
public_key: "testkey.avbpubkey",
@@ -325,6 +331,26 @@
checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
})
+ t.Run("boot image files from source of override apex", func(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ commonPreparer,
+
+ // Configure some libraries in the art bootclasspath_fragment that match the source
+ // bootclasspath_fragment's contents property.
+ java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
+ dexpreopt.FixtureSetTestOnlyArtBootImageJars("com.android.art:foo", "com.android.art:bar"),
+ addSource("foo", "bar"),
+ java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
+ ).RunTest(t)
+
+ ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.mycompany.android.art_com.mycompany.android.art", []string{
+ "etc/boot-image.prof",
+ "etc/classpaths/bootclasspath.pb",
+ "javalib/bar.jar",
+ "javalib/foo.jar",
+ })
+ })
+
t.Run("generate boot image profile even if dexpreopt is disabled", func(t *testing.T) {
result := android.GroupFixturePreparers(
commonPreparer,
diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go
index 9f1e1e1..4a20cf0 100644
--- a/apex/platform_bootclasspath_test.go
+++ b/apex/platform_bootclasspath_test.go
@@ -865,6 +865,36 @@
},
}
+ // Another prebuilt apex, but this is not selected during the build.
+ prebuilt_apex {
+ name: "com.google.android.myapex.v2", // mainline prebuilt selection logic in soong relies on the naming convention com.google.android
+ apex_name: "myapex",
+ source_apex_name: "myapex",
+ src: "myapex.apex",
+ exported_bootclasspath_fragments: ["apex-fragment.v2"],
+ }
+
+ java_import {
+ name: "bar",
+ jars: ["bar.jar"],
+ apex_available: ["myapex"],
+ permitted_packages: ["bar"],
+ }
+
+ prebuilt_bootclasspath_fragment {
+ name: "apex-fragment.v2",
+ contents: ["bar"], // Unlike the source fragment, this is missing foo
+ apex_available:[ "myapex" ],
+ hidden_api: {
+ annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
+ metadata: "my-bootclasspath-fragment/metadata.csv",
+ index: "my-bootclasspath-fragment/index.csv",
+ stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
+ all_flags: "my-bootclasspath-fragment/all-flags.csv",
+ },
+ }
+
+
apex_contributions {
name: "my_apex_contributions",
api_domain: "myapex",
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index b2afa39..9ad5159 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -848,7 +848,9 @@
func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// Validate contents of classpath fragments
- validateApexClasspathFragments(ctx)
+ if !p.IsHideFromMake() {
+ validateApexClasspathFragments(ctx)
+ }
p.apexKeysPath = writeApexKeys(ctx, p)
// TODO(jungjw): Check the key validity.
@@ -1074,7 +1076,9 @@
func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// Validate contents of classpath fragments
- validateApexClasspathFragments(ctx)
+ if !a.IsHideFromMake() {
+ validateApexClasspathFragments(ctx)
+ }
a.apexKeysPath = writeApexKeys(ctx, a)
a.installFilename = a.InstallFilename()
diff --git a/bin/allmod b/bin/allmod
new file mode 100755
index 0000000..f7d25e5
--- /dev/null
+++ b/bin/allmod
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# List all modules for the current device, as cached in all_modules.txt. If any build change is
+# made and it should be reflected in the output, you should run 'refreshmod' first.
+
+cat $ANDROID_PRODUCT_OUT/all_modules.txt 2>/dev/null
+
diff --git a/bin/core b/bin/core
new file mode 100755
index 0000000..01dbd13
--- /dev/null
+++ b/bin/core
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# core - send SIGV and pull the core for process
+# $1 = PID of process (e.g., $(pid mediaserver))
+#
+# NOTE: coredump_setup must be called once per boot for core dumps to be
+# enabled globally.
+
+set -e
+
+PID=$1;
+
+if [ -z "$PID" ]; then
+ printf "Expecting a PID!\n";
+ exit 1
+fi;
+
+CORENAME=core.$PID;
+COREPATH=/cores/$CORENAME;
+SIG=SEGV;
+
+coredump_enable $1;
+
+done=0;
+while [ $(adb shell "[ -d /proc/$PID ] && echo -n yes") ]; do
+ printf "\tSending SIG%s to %d...\n" $SIG $PID;
+ adb shell kill -$SIG $PID;
+ sleep 1;
+done;
+
+adb shell "while [ ! -f $COREPATH ] ; do echo waiting for $COREPATH to be generated; sleep 1; done"
+echo "Done: core is under $COREPATH on device.";
+
+
diff --git a/bin/coredump_enable b/bin/coredump_enable
new file mode 100755
index 0000000..da63a0c
--- /dev/null
+++ b/bin/coredump_enable
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# coredump_enable - enable core dumps for the specified process
+# $1 = PID of process (e.g., $(pid mediaserver))
+#
+# NOTE: coredump_setup must have been called as well for a core
+# dump to actually be generated.
+
+set -e
+
+PID=$1;
+if [ -z "$PID" ]; then
+ printf "Expecting a PID!\n";
+ exit 1
+fi;
+echo "Setting core limit for $PID to infinite...";
+adb shell /system/bin/ulimit -P $PID -c unlimited
+
diff --git a/bin/coredump_setup b/bin/coredump_setup
new file mode 100755
index 0000000..7647659
--- /dev/null
+++ b/bin/coredump_setup
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# coredump_setup - enable core dumps globally for any process
+# that has the core-file-size limit set correctly
+#
+# NOTE: You must call also coredump_enable for a specific process
+# if its core-file-size limit is not set already.
+# NOTE: Core dumps are written to ramdisk; they will not survive a reboot!
+
+set -e
+
+echo "Getting root...";
+adb root;
+adb wait-for-device;
+
+echo "Remounting root partition read-write...";
+adb shell mount -w -o remount -t rootfs rootfs;
+sleep 1;
+adb wait-for-device;
+adb shell mkdir -p /cores;
+adb shell mount -t tmpfs tmpfs /cores;
+adb shell chmod 0777 /cores;
+
+echo "Granting SELinux permission to dump in /cores...";
+adb shell restorecon -R /cores;
+
+echo "Set core pattern.";
+adb shell 'echo /cores/core.%p > /proc/sys/kernel/core_pattern';
+
+echo "Done."
+
diff --git a/bin/dirmods b/bin/dirmods
new file mode 100755
index 0000000..52d935a
--- /dev/null
+++ b/bin/dirmods
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+'''
+Lists all modules in the given directory or its decendant directories, as cached
+in module-info.json. If any build change is made, and it should be reflected in
+the output, you should run 'refreshmod' first.
+'''
+
+import sys
+sys.dont_write_bytecode = True
+
+import argparse
+import os
+
+import modinfo
+
+
+def main():
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument('path')
+ args = parser.parse_args()
+
+ d = os.path.normpath(args.path)
+ prefix = d + '/'
+
+ module_info = modinfo.ReadModuleInfo()
+
+ results = set()
+ for m in module_info.values():
+ for path in m.get(u'path', []):
+ if path == d or path.startswith(prefix):
+ name = m.get(u'module_name')
+ if name:
+ results.add(name)
+
+ for name in sorted(results):
+ print(name)
+
+if __name__ == "__main__":
+ main()
diff --git a/bin/get_abs_build_var b/bin/get_abs_build_var
new file mode 100755
index 0000000..8072cf1
--- /dev/null
+++ b/bin/get_abs_build_var
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Get the value of a build variable as an absolute path.
+
+# Common script utilities
+source $(cd $(dirname $BASH_SOURCE) &> /dev/null && pwd)/../../make/shell_utils.sh
+
+require_top
+
+$TOP/build/soong/soong_ui.bash --dumpvar-mode --abs $1
+
+exit $?
diff --git a/bin/get_build_var b/bin/get_build_var
new file mode 100755
index 0000000..9fdf55f
--- /dev/null
+++ b/bin/get_build_var
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Get the exact value of a build variable.
+
+# Common script utilities
+source $(cd $(dirname $BASH_SOURCE) &> /dev/null && pwd)/../../make/shell_utils.sh
+
+require_top
+
+$TOP/build/soong/soong_ui.bash --dumpvar-mode $1
+
+exit $?
diff --git a/bin/getlastscreenshot b/bin/getlastscreenshot
new file mode 100755
index 0000000..dfe9a6b
--- /dev/null
+++ b/bin/getlastscreenshot
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# coredump_enable - enable core dumps for the specified process
+# $1 = PID of process (e.g., $(pid mediaserver))
+#
+# NOTE: coredump_setup must have been called as well for a core
+# dump to actually be generated.
+
+set -e
+
+screenshot_path=$(getscreenshotpath)
+screenshot=`adb ${adbOptions} ls ${screenshot_path} | grep Screenshot_[0-9-]*.*\.png | sort -rk 3 | cut -d " " -f 4 | head -n 1`
+if [ "$screenshot" = "" ]; then
+ echo "No screenshots found."
+ exit 1
+fi
+echo "${screenshot}"
+adb ${adbOptions} pull ${screenshot_path}/${screenshot}
+
diff --git a/bin/getprebuilt b/bin/getprebuilt
new file mode 100755
index 0000000..68e65b4
--- /dev/null
+++ b/bin/getprebuilt
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+get_abs_build_var ANDROID_PREBUILTS
+
diff --git a/bin/getscreenshotpath b/bin/getscreenshotpath
new file mode 100755
index 0000000..ff8e327
--- /dev/null
+++ b/bin/getscreenshotpath
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# coredump_enable - enable core dumps for the specified process
+# $1 = PID of process (e.g., $(pid mediaserver))
+#
+# NOTE: coredump_setup must have been called as well for a core
+# dump to actually be generated.
+
+set -e
+
+echo "$(getsdcardpath)/Pictures/Screenshots"
+
diff --git a/bin/getsdcardpath b/bin/getsdcardpath
new file mode 100755
index 0000000..655659a
--- /dev/null
+++ b/bin/getsdcardpath
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# coredump_enable - enable core dumps for the specified process
+# $1 = PID of process (e.g., $(pid mediaserver))
+#
+# NOTE: coredump_setup must have been called as well for a core
+# dump to actually be generated.
+
+set -e
+
+adb ${adbOptions} shell echo -n \$\{EXTERNAL_STORAGE\}
+
diff --git a/bin/gettargetarch b/bin/gettargetarch
new file mode 100755
index 0000000..e53ce3f
--- /dev/null
+++ b/bin/gettargetarch
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+get_build_var TARGET_ARCH
+
diff --git a/bin/hmm b/bin/hmm
index c3d60fa..161bad6 100755
--- a/bin/hmm
+++ b/bin/hmm
@@ -1,6 +1,6 @@
#!/bin/bash
-# Copyright (C) 2022 The Android Open Source Project
+# Copyright (C) 2024 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,6 +14,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+# Common script utilities
+source $(cd $(dirname $BASH_SOURCE) &> /dev/null && pwd)/../../make/shell_utils.sh
+
cat <<EOF
Run "m help" for help with the build system itself.
@@ -56,7 +59,6 @@
- godir: Go to the directory containing a file.
- allmod: List all modules.
- gomod: Go to the directory containing a module.
-- bmod: Get the Bazel label of a Soong module if it is converted with bp2build.
- pathmod: Get the directory containing a module.
- outmod: Gets the location of a module's installed outputs with a certain extension.
- dirmods: Gets the modules defined in a given directory.
@@ -68,12 +70,12 @@
- SANITIZE_HOST: Set to 'address' to use ASAN for all host modules.
- ANDROID_QUIET_BUILD: set to 'true' to display only the essential messages.
-Look at build/make/envsetup for more functions:
+Look at the source to view more functions. The complete list is:
EOF
- local T=$(gettop)
- local A=""
- local i
- for i in `(cat $T/build/envsetup.sh | sed -n "/^[[:blank:]]*function /s/function \([a-z]*\).*/\1/p" | sort | uniq`; do
+ T=$(gettop)
+ A=""
+ for i in `cat $T/build/envsetup.sh | sed -n "/^[[:blank:]]*function /s/function \([a-z_]*\).*/\1/p" | sort | uniq`; do
A="$A $i"
done
echo $A
+
diff --git a/bin/installmod b/bin/installmod
new file mode 100755
index 0000000..1d0d836
--- /dev/null
+++ b/bin/installmod
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# adb install a module's apk, as cached in module-info.json. If any build change
+# is made, and it should be reflected in the output, you should run 'refreshmod' first.
+# Usage: installmod [adb install arguments] <module>
+# For example: installmod -r Dialer -> adb install -r /path/to/Dialer.apk
+
+if [[ $# -eq 0 ]]; then
+ echo "usage: installmod [adb install arguments] <module>" >&2
+ echo "" >&2
+ echo "Only flags to be passed after the \"install\" in adb install are supported," >&2
+ echo "with the exception of -s. If -s is passed it will be placed before the \"install\"." >&2
+ echo "-s must be the first flag passed if it exists." >&2
+ return 1
+fi
+
+local _path
+_path=$(outmod ${@:$#:1})
+if [ $? -ne 0 ]; then
+ return 1
+fi
+
+_path=$(echo "$_path" | grep -E \\.apk$ | head -n 1)
+if [ -z "$_path" ]; then
+ echo "Module '$1' does not produce a file ending with .apk (try 'refreshmod' if there have been build changes?)" >&2
+ return 1
+fi
+local serial_device=""
+if [[ "$1" == "-s" ]]; then
+ if [[ $# -le 2 ]]; then
+ echo "-s requires an argument" >&2
+ return 1
+ fi
+ serial_device="-s $2"
+ shift 2
+fi
+local length=$(( $# - 1 ))
+echo adb $serial_device install ${@:1:$length} $_path
+adb $serial_device install ${@:1:$length} $_path
+
diff --git a/bin/is64bit b/bin/is64bit
new file mode 100755
index 0000000..35bbcc3
--- /dev/null
+++ b/bin/is64bit
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Read the ELF header from /proc/$PID/exe to determine if the process is
+# 64-bit.
+
+set -e
+
+local PID="$1"
+if [ "$PID" ] ; then
+ if [[ "$(adb shell cat /proc/$PID/exe | xxd -l 1 -s 4 -p)" -eq "02" ]] ; then
+ echo "64"
+ else
+ echo ""
+ fi
+else
+ echo ""
+fi
+
diff --git a/bin/isviewserverstarted b/bin/isviewserverstarted
new file mode 100755
index 0000000..c7c82af
--- /dev/null
+++ b/bin/isviewserverstarted
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# coredump_enable - enable core dumps for the specified process
+# $1 = PID of process (e.g., $(pid mediaserver))
+#
+# NOTE: coredump_setup must have been called as well for a core
+# dump to actually be generated.
+
+set -e
+
+adb shell service call window 3
+
diff --git a/bin/key_back b/bin/key_back
new file mode 100755
index 0000000..2de8d07
--- /dev/null
+++ b/bin/key_back
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# coredump_enable - enable core dumps for the specified process
+# $1 = PID of process (e.g., $(pid mediaserver))
+#
+# NOTE: coredump_setup must have been called as well for a core
+# dump to actually be generated.
+
+set -e
+
+adb shell input keyevent 4
+
diff --git a/bin/key_home b/bin/key_home
new file mode 100755
index 0000000..653a5f9
--- /dev/null
+++ b/bin/key_home
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# coredump_enable - enable core dumps for the specified process
+# $1 = PID of process (e.g., $(pid mediaserver))
+#
+# NOTE: coredump_setup must have been called as well for a core
+# dump to actually be generated.
+
+set -e
+
+adb shell input keyevent 3
+
diff --git a/bin/key_menu b/bin/key_menu
new file mode 100755
index 0000000..29b2bc6
--- /dev/null
+++ b/bin/key_menu
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# coredump_enable - enable core dumps for the specified process
+# $1 = PID of process (e.g., $(pid mediaserver))
+#
+# NOTE: coredump_setup must have been called as well for a core
+# dump to actually be generated.
+
+set -e
+
+adb shell input keyevent 82
+
diff --git a/bin/list_products b/bin/list_products
new file mode 100755
index 0000000..cd8dd5c
--- /dev/null
+++ b/bin/list_products
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Common script utilities
+source $(cd $(dirname $BASH_SOURCE) &> /dev/null && pwd)/../../make/shell_utils.sh
+
+require_top
+
+# In almost call cases including get_build_var, TARGET_RELEASE is required,
+# but the list of available products is not dependent on the release config
+# (but note that the list of available release configs is dependent on the
+# product). So for list_products, we'll just set it to trunk_staging, which
+# exists everwhere, so we don't trigger the unspecified TARGET_RELEASE error.
+
+# We also unset TARGET_BUILD_APPS, so it doesn't interfere.
+
+TARGET_RELEASE=trunk_staging TARGET_BUILD_APPS= $TOP/build/soong/soong_ui.bash --dumpvar-mode all_named_products | sed 's/ /\n/g'
+
+exit $?
diff --git a/bin/list_releases b/bin/list_releases
new file mode 100755
index 0000000..ca18110
--- /dev/null
+++ b/bin/list_releases
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+if [[ $# -eq 1 ]]; then
+ # Override anything that's already set
+ export TARGET_PRODUCT=$1
+elif [[ -z $TARGET_PRODUCT ]]; then
+ echo "Usage: list_releases [PRODUCT]" 1>&2
+ echo "" 1>&2
+ echo "If the optional PRODUCT parameter is bit provided, then TARGET_PRODUCT" 1>&2
+ echo "must have been set, for example by lunch or banchan." 1>&2
+ exit 1
+fi
+
+
+
+# Common script utilities
+source $(cd $(dirname $BASH_SOURCE) &> /dev/null && pwd)/../../make/shell_utils.sh
+
+require_top
+
+# In almost call cases including get_build_var, TARGET_RELEASE is required,
+# but the list of available products is not dependent on the release config
+# (but note that the list of available release configs is dependent on the
+# product). So for list_products, we'll just set it to trunk_staging, which
+# exists everwhere, so we don't trigger the unspecified TARGET_RELEASE error.
+
+# We also unset TARGET_BUILD_APPS, so it doesn't interfere.
+
+TARGET_RELEASE=trunk_staging TARGET_BUILD_APPS= $TOP/build/soong/soong_ui.bash --dumpvar-mode ALL_RELEASE_CONFIGS_FOR_PRODUCT | sed 's/ /\n/g'
+
+exit $?
diff --git a/bin/list_variants b/bin/list_variants
new file mode 100755
index 0000000..ac89e6a
--- /dev/null
+++ b/bin/list_variants
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+echo user
+echo userdebug
+echo eng
+
diff --git a/bin/modinfo.py b/bin/modinfo.py
new file mode 100644
index 0000000..015129f
--- /dev/null
+++ b/bin/modinfo.py
@@ -0,0 +1,44 @@
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+import os
+import pathlib
+import sys
+
+
+def OpenModuleInfoFile():
+ product_out = os.getenv("ANDROID_PRODUCT_OUT")
+ if not product_out:
+ if os.getenv("QUIET_VERIFYMODINFO") != "true":
+ sys.stderr.write("No ANDROID_PRODUCT_OUT. Try running 'lunch' first.\n")
+ sys.exit(1)
+ try:
+ return open(pathlib.Path(product_out) / "module-info.json")
+ except (FileNotFoundError, PermissionError):
+ if os.getenv("QUIET_VERIFYMODINFO") != "true":
+ sys.stderr.write("Could not find module-info.json. Please run 'refreshmod' first.\n")
+ sys.exit(1)
+
+
+def ReadModuleInfo():
+ with OpenModuleInfoFile() as f:
+ return json.load(f)
+
+def GetModule(modules, module_name):
+ if module_name not in modules:
+ sys.stderr.write(f"Could not find module '{module_name}' (try 'refreshmod' if there have been build changes?)\n")
+ sys.exit(1)
+ return modules[module_name]
+
diff --git a/bin/outmod b/bin/outmod
new file mode 100755
index 0000000..022ff36
--- /dev/null
+++ b/bin/outmod
@@ -0,0 +1,42 @@
+#!/usr/bin/env python3
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+'''
+Lists the output files of a specific module in the android tree, as cached in
+module-info.json. If any build change is made, and it should be reflected in the
+output, you should run 'refreshmod' first.
+'''
+
+import sys
+sys.dont_write_bytecode = True
+
+import argparse
+import os
+
+import modinfo
+
+
+def main():
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument('module')
+ args = parser.parse_args()
+
+ for output in modinfo.GetModule(modinfo.ReadModuleInfo(), args.module)['installed']:
+ print(os.path.join(os.getenv("ANDROID_BUILD_TOP", ""), output))
+
+if __name__ == "__main__":
+ main()
+
diff --git a/bin/pathmod b/bin/pathmod
new file mode 100755
index 0000000..70cf958
--- /dev/null
+++ b/bin/pathmod
@@ -0,0 +1,41 @@
+#!/usr/bin/env python3
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+'''
+Get the path of a specific module in the android tree, as cached in module-info.json.
+If any build change is made, and it should be reflected in the output, you should run
+'refreshmod' first. Note: This is the inverse of dirmods.
+'''
+
+import sys
+sys.dont_write_bytecode = True
+
+import argparse
+import os
+
+import modinfo
+
+
+def main():
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument('module')
+ args = parser.parse_args()
+
+ path = modinfo.GetModule(modinfo.ReadModuleInfo(), args.module)['path'][0]
+ print(os.path.join(os.getenv("ANDROID_BUILD_TOP", ""), path))
+
+if __name__ == "__main__":
+ main()
diff --git a/bin/qpid b/bin/qpid
new file mode 100755
index 0000000..b47cb6b
--- /dev/null
+++ b/bin/qpid
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# adb install a module's apk, as cached in module-info.json. If any build change
+# is made, and it should be reflected in the output, you should run 'refreshmod' first.
+# Usage: installmod [adb install arguments] <module>
+# For example: installmod -r Dialer -> adb install -r /path/to/Dialer.apk
+
+function _impl() {
+ local prepend=''
+ local append=''
+ if [ "$1" = "--exact" ]; then
+ prepend=' '
+ append='$'
+ shift
+ elif [ "$1" = "--help" -o "$1" = "-h" ]; then
+ echo "usage: qpid [[--exact] <process name|pid>"
+ return 255
+ fi
+
+ local EXE="$1"
+ if [ "$EXE" ] ; then
+ _impl | \grep "$prepend$EXE$append"
+ else
+ adb shell ps \
+ | tr -d '\r' \
+ | sed -e 1d -e 's/^[^ ]* *\([0-9]*\).* \([^ ]*\)$/\1 \2/'
+ fi
+}
+
+_impl "$@"
diff --git a/bin/startviewserver b/bin/startviewserver
new file mode 100755
index 0000000..4d612b8
--- /dev/null
+++ b/bin/startviewserver
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# coredump_enable - enable core dumps for the specified process
+# $1 = PID of process (e.g., $(pid mediaserver))
+#
+# NOTE: coredump_setup must have been called as well for a core
+# dump to actually be generated.
+
+set -e
+
+port=4939
+if [ $# -gt 0 ]; then
+ port=$1
+fi
+adb shell service call window 1 i32 $port
+
diff --git a/bin/stopviewserver b/bin/stopviewserver
new file mode 100755
index 0000000..a734e4b
--- /dev/null
+++ b/bin/stopviewserver
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# coredump_enable - enable core dumps for the specified process
+# $1 = PID of process (e.g., $(pid mediaserver))
+#
+# NOTE: coredump_setup must have been called as well for a core
+# dump to actually be generated.
+
+set -e
+
+adb shell service call window 2
+
diff --git a/bin/systemstack b/bin/systemstack
new file mode 100755
index 0000000..b259133
--- /dev/null
+++ b/bin/systemstack
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# systemstack - dump the current stack trace of all threads in the system process
+# to the usual ANR traces file
+
+stacks system_server
+
diff --git a/bpf/bpf.go b/bpf/bpf.go
index 38fbd88..2eb869e 100644
--- a/bpf/bpf.go
+++ b/bpf/bpf.go
@@ -65,8 +65,6 @@
type BpfModule interface {
android.Module
- OutputFiles(tag string) (android.Paths, error)
-
// Returns the sub install directory if the bpf module is included by apex.
SubDir() string
}
@@ -213,6 +211,8 @@
}
android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcs.Strings()})
+
+ ctx.SetOutputFiles(bpf.objs, "")
}
func (bpf *bpf) AndroidMk() android.AndroidMkData {
@@ -255,23 +255,10 @@
}
}
-// Implements OutputFileFileProducer interface so that the obj output can be used in the data property
-// of other modules.
-func (bpf *bpf) OutputFiles(tag string) (android.Paths, error) {
- switch tag {
- case "":
- return bpf.objs, nil
- default:
- return nil, fmt.Errorf("unsupported module reference tag %q", tag)
- }
-}
-
func (bpf *bpf) SubDir() string {
return bpf.properties.Sub_dir
}
-var _ android.OutputFileProducer = (*bpf)(nil)
-
func BpfFactory() android.Module {
module := &bpf{}
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 0c6f97c..62ba4de 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -261,15 +261,6 @@
if library.coverageOutputFile.Valid() {
entries.SetString("LOCAL_PREBUILT_COVERAGE_ARCHIVE", library.coverageOutputFile.String())
}
-
- if library.useCoreVariant {
- entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
- entries.SetBool("LOCAL_NO_NOTICE_FILE", true)
- entries.SetBool("LOCAL_VNDK_DEPEND_ON_CORE_VARIANT", true)
- }
- if library.checkSameCoreVariant {
- entries.SetBool("LOCAL_CHECK_SAME_VNDK_VARIANTS", true)
- }
})
if library.shared() && !library.buildStubs() {
@@ -495,14 +486,14 @@
ctx.subAndroidMk(entries, p.libraryDecorator)
if p.shared() {
ctx.subAndroidMk(entries, &p.prebuiltLinker)
- androidMkWriteAllowUndefinedSymbols(p.baseLinker, entries)
+ androidMkWritePrebuiltOptions(p.baseLinker, entries)
}
}
func (p *prebuiltBinaryLinker) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
ctx.subAndroidMk(entries, p.binaryDecorator)
ctx.subAndroidMk(entries, &p.prebuiltLinker)
- androidMkWriteAllowUndefinedSymbols(p.baseLinker, entries)
+ androidMkWritePrebuiltOptions(p.baseLinker, entries)
}
func (a *apiLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
@@ -533,11 +524,17 @@
})
}
-func androidMkWriteAllowUndefinedSymbols(linker *baseLinker, entries *android.AndroidMkEntries) {
+func androidMkWritePrebuiltOptions(linker *baseLinker, entries *android.AndroidMkEntries) {
allow := linker.Properties.Allow_undefined_symbols
if allow != nil {
entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
entries.SetBool("LOCAL_ALLOW_UNDEFINED_SYMBOLS", *allow)
})
}
+ ignore := linker.Properties.Ignore_max_page_size
+ if ignore != nil {
+ entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+ entries.SetBool("LOCAL_IGNORE_MAX_PAGE_SIZE", *ignore)
+ })
+ }
}
diff --git a/cc/builder.go b/cc/builder.go
index d817d82..7a3394a 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -638,7 +638,7 @@
ccCmd = "${config.ClangBin}/" + ccCmd
if flags.clangVerify {
- postCmd = " && touch $$out"
+ postCmd = " && touch " + objFile.String()
}
var implicitOutputs android.WritablePaths
diff --git a/cc/cc.go b/cc/cc.go
index a64775d..cb82f86 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -374,10 +374,6 @@
// build system and source tree.
Cmake_snapshot_supported *bool
- // Even if DeviceConfig().VndkUseCoreVariant() is set, this module must use vendor variant.
- // see soong/cc/config/vndk.go
- MustUseVendorVariant bool `blueprint:"mutated"`
-
Installable *bool `android:"arch_variant"`
// Set by factories of module types that can only be referenced from variants compiled against
@@ -479,10 +475,6 @@
// IsLLNDK is set to true for the vendor variant of a cc_library module that has LLNDK stubs.
IsLLNDK bool `blueprint:"mutated"`
- // IsVNDKUsingCoreVariant is true for VNDK modules if the global VndkUseCoreVariant option is
- // set and the module is not listed in VndkMustUseVendorVariantList.
- IsVNDKUsingCoreVariant bool `blueprint:"mutated"`
-
// IsVNDKCore is set if a VNDK module does not set the vndk.support_system_process property.
IsVNDKCore bool `blueprint:"mutated"`
@@ -548,7 +540,6 @@
apexVariationName() string
apexSdkVersion() android.ApiLevel
bootstrap() bool
- mustUseVendorVariant() bool
nativeCoverage() bool
directlyInAnyApex() bool
isPreventInstall() bool
@@ -1472,10 +1463,6 @@
return c.Properties.SubName
}
-func (c *Module) MustUseVendorVariant() bool {
- return c.IsVndkSp() || c.Properties.MustUseVendorVariant
-}
-
func (c *Module) getVndkExtendsModuleName() string {
if vndkdep := c.vndkdep; vndkdep != nil {
return vndkdep.getVndkExtendsModuleName()
@@ -1768,10 +1755,6 @@
return ctx.mod.IsVendorPublicLibrary()
}
-func (ctx *moduleContextImpl) mustUseVendorVariant() bool {
- return ctx.mod.MustUseVendorVariant()
-}
-
func (ctx *moduleContextImpl) selectedStl() string {
if stl := ctx.mod.stl; stl != nil {
return stl.Properties.SelectedStl
@@ -3648,12 +3631,7 @@
}
}
- if ctx.DeviceConfig().VndkUseCoreVariant() && ccDep.IsVndk() && !ccDep.MustUseVendorVariant() &&
- !c.InRamdisk() && !c.InVendorRamdisk() && !c.InRecovery() {
- // The vendor module is a no-vendor-variant VNDK library. Depend on the
- // core module instead.
- return libName
- } else if ccDep.InVendorOrProduct() && nonSystemVariantsExist {
+ if ccDep.InVendorOrProduct() && nonSystemVariantsExist {
// The vendor and product modules in Make will have been renamed to not conflict with the
// core module, so update the dependency name here accordingly.
return libName + ccDep.SubName()
@@ -3866,8 +3844,6 @@
// TODO(b/114741097): use the correct ndk stl once build errors have been fixed
//family, link := getNdkStlFamilyAndLinkType(c)
//return fmt.Sprintf("native:ndk:%s:%s", family, link)
- } else if actx.DeviceConfig().VndkUseCoreVariant() && !c.MustUseVendorVariant() {
- return "native:platform_vndk"
} else {
return "native:platform"
}
diff --git a/cc/config/Android.bp b/cc/config/Android.bp
index fdc94ad..289409f 100644
--- a/cc/config/Android.bp
+++ b/cc/config/Android.bp
@@ -15,7 +15,6 @@
"global.go",
"tidy.go",
"toolchain.go",
- "vndk.go",
"bionic.go",
diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go
index 7dc990b..5d8c351 100644
--- a/cc/config/toolchain.go
+++ b/cc/config/toolchain.go
@@ -209,58 +209,58 @@
return list
}
-func LibclangRuntimeLibrary(t Toolchain, library string) string {
+func LibclangRuntimeLibrary(library string) string {
return "libclang_rt." + library
}
-func BuiltinsRuntimeLibrary(t Toolchain) string {
- return LibclangRuntimeLibrary(t, "builtins")
+func BuiltinsRuntimeLibrary() string {
+ return LibclangRuntimeLibrary("builtins")
}
-func AddressSanitizerRuntimeLibrary(t Toolchain) string {
- return LibclangRuntimeLibrary(t, "asan")
+func AddressSanitizerRuntimeLibrary() string {
+ return LibclangRuntimeLibrary("asan")
}
-func AddressSanitizerStaticRuntimeLibrary(t Toolchain) string {
- return LibclangRuntimeLibrary(t, "asan.static")
+func AddressSanitizerStaticRuntimeLibrary() string {
+ return LibclangRuntimeLibrary("asan.static")
}
-func AddressSanitizerCXXStaticRuntimeLibrary(t Toolchain) string {
- return LibclangRuntimeLibrary(t, "asan_cxx.static")
+func AddressSanitizerCXXStaticRuntimeLibrary() string {
+ return LibclangRuntimeLibrary("asan_cxx.static")
}
-func HWAddressSanitizerRuntimeLibrary(t Toolchain) string {
- return LibclangRuntimeLibrary(t, "hwasan")
+func HWAddressSanitizerRuntimeLibrary() string {
+ return LibclangRuntimeLibrary("hwasan")
}
-func HWAddressSanitizerStaticLibrary(t Toolchain) string {
- return LibclangRuntimeLibrary(t, "hwasan_static")
+func HWAddressSanitizerStaticLibrary() string {
+ return LibclangRuntimeLibrary("hwasan_static")
}
-func UndefinedBehaviorSanitizerRuntimeLibrary(t Toolchain) string {
- return LibclangRuntimeLibrary(t, "ubsan_standalone")
+func UndefinedBehaviorSanitizerRuntimeLibrary() string {
+ return LibclangRuntimeLibrary("ubsan_standalone")
}
-func UndefinedBehaviorSanitizerMinimalRuntimeLibrary(t Toolchain) string {
- return LibclangRuntimeLibrary(t, "ubsan_minimal")
+func UndefinedBehaviorSanitizerMinimalRuntimeLibrary() string {
+ return LibclangRuntimeLibrary("ubsan_minimal")
}
-func ThreadSanitizerRuntimeLibrary(t Toolchain) string {
- return LibclangRuntimeLibrary(t, "tsan")
+func ThreadSanitizerRuntimeLibrary() string {
+ return LibclangRuntimeLibrary("tsan")
}
-func ScudoRuntimeLibrary(t Toolchain) string {
- return LibclangRuntimeLibrary(t, "scudo")
+func ScudoRuntimeLibrary() string {
+ return LibclangRuntimeLibrary("scudo")
}
-func ScudoMinimalRuntimeLibrary(t Toolchain) string {
- return LibclangRuntimeLibrary(t, "scudo_minimal")
+func ScudoMinimalRuntimeLibrary() string {
+ return LibclangRuntimeLibrary("scudo_minimal")
}
-func LibFuzzerRuntimeLibrary(t Toolchain) string {
- return LibclangRuntimeLibrary(t, "fuzzer")
+func LibFuzzerRuntimeLibrary() string {
+ return LibclangRuntimeLibrary("fuzzer")
}
-func LibFuzzerRuntimeInterceptors(t Toolchain) string {
- return LibclangRuntimeLibrary(t, "fuzzer_interceptors")
+func LibFuzzerRuntimeInterceptors() string {
+ return LibclangRuntimeLibrary("fuzzer_interceptors")
}
diff --git a/cc/config/vndk.go b/cc/config/vndk.go
deleted file mode 100644
index dd612ce..0000000
--- a/cc/config/vndk.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2019 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package config
-
-// List of VNDK libraries that have different core variant and vendor variant.
-// For these libraries, the vendor variants must be installed even if the device
-// has VndkUseCoreVariant set.
-// Note that AIDL-generated modules must use vendor variants by default.
-var VndkMustUseVendorVariantList = []string{
- "android.hardware.nfc@1.2",
- "libbinder",
- "libcrypto",
- "libexpat",
- "libgatekeeper",
- "libgui",
- "libhidlcache",
- "libkeymaster_messages",
- "libkeymaster_portable",
- "libmedia_omx",
- "libpuresoftkeymasterdevice",
- "libselinux",
- "libsoftkeymasterdevice",
- "libsqlite",
- "libssl",
- "libstagefright_bufferpool@2.0",
- "libstagefright_bufferqueue_helper",
- "libstagefright_foundation",
- "libstagefright_omx",
- "libstagefright_omx_utils",
- "libstagefright_xmlparser",
- "libui",
- "libxml2",
-}
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 164ec99..92f2c5e 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -128,13 +128,13 @@
if ctx.Config().Getenv("FUZZ_FRAMEWORK") == "AFL" {
deps.HeaderLibs = append(deps.HeaderLibs, "libafl_headers")
} else {
- deps.StaticLibs = append(deps.StaticLibs, config.LibFuzzerRuntimeLibrary(ctx.toolchain()))
+ deps.StaticLibs = append(deps.StaticLibs, config.LibFuzzerRuntimeLibrary())
// Fuzzers built with HWASAN should use the interceptors for better
// mutation based on signals in strcmp, memcpy, etc. This is only needed for
// fuzz targets, not generic HWASAN-ified binaries or libraries.
if module, ok := ctx.Module().(*Module); ok {
if module.IsSanitizerEnabled(Hwasan) {
- deps.StaticLibs = append(deps.StaticLibs, config.LibFuzzerRuntimeInterceptors(ctx.toolchain()))
+ deps.StaticLibs = append(deps.StaticLibs, config.LibFuzzerRuntimeInterceptors())
}
}
}
diff --git a/cc/library.go b/cc/library.go
index b9018a7..b9c1466 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -419,11 +419,6 @@
postInstallCmds []string
- // If useCoreVariant is true, the vendor variant of a VNDK library is
- // not installed.
- useCoreVariant bool
- checkSameCoreVariant bool
-
skipAPIDefine bool
// Decorated interfaces
@@ -1767,27 +1762,6 @@
}
}
- // In some cases we want to use core variant for VNDK-Core libs.
- // Skip product variant since VNDKs use only the vendor variant.
- if ctx.isVndk() && !ctx.isVndkSp() && !ctx.IsVndkExt() && !ctx.inProduct() {
- mayUseCoreVariant := true
-
- if ctx.mustUseVendorVariant() {
- mayUseCoreVariant = false
- }
-
- if ctx.Config().CFIEnabledForPath(ctx.ModuleDir()) {
- mayUseCoreVariant = false
- }
-
- if mayUseCoreVariant {
- library.checkSameCoreVariant = true
- if ctx.DeviceConfig().VndkUseCoreVariant() {
- library.useCoreVariant = true
- }
- }
- }
-
// do not install vndk libs
// vndk libs are packaged into VNDK APEX
if ctx.isVndk() && !ctx.IsVndkExt() && !ctx.Config().IsVndkDeprecated() && !ctx.inProduct() {
diff --git a/cc/linkable.go b/cc/linkable.go
index 5579aae..fecc6a2 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -165,7 +165,6 @@
// IsVndkSp returns true if this is a VNDK-SP module.
IsVndkSp() bool
- MustUseVendorVariant() bool
IsVndk() bool
IsVndkExt() bool
IsVndkPrivate() bool
diff --git a/cc/linker.go b/cc/linker.go
index f325c12..1675df6 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -65,6 +65,10 @@
// This flag should only be necessary for compiling low-level libraries like libc.
Allow_undefined_symbols *bool `android:"arch_variant"`
+ // ignore max page size. By default, max page size must be the
+ // max page size set for the target.
+ Ignore_max_page_size *bool `android:"arch_variant"`
+
// don't link in libclang_rt.builtins-*.a
No_libcrt *bool `android:"arch_variant"`
@@ -431,7 +435,7 @@
if ctx.toolchain().Bionic() {
// libclang_rt.builtins has to be last on the command line
if linker.Properties.libCrt() && !ctx.header() {
- deps.UnexportedStaticLibs = append(deps.UnexportedStaticLibs, config.BuiltinsRuntimeLibrary(ctx.toolchain()))
+ deps.UnexportedStaticLibs = append(deps.UnexportedStaticLibs, config.BuiltinsRuntimeLibrary())
}
if inList("libdl", deps.SharedLibs) {
@@ -454,7 +458,7 @@
}
} else if ctx.toolchain().Musl() {
if linker.Properties.libCrt() && !ctx.header() {
- deps.UnexportedStaticLibs = append(deps.UnexportedStaticLibs, config.BuiltinsRuntimeLibrary(ctx.toolchain()))
+ deps.UnexportedStaticLibs = append(deps.UnexportedStaticLibs, config.BuiltinsRuntimeLibrary())
}
}
diff --git a/cc/makevars.go b/cc/makevars.go
index 51bcbf0..9d29aff 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -28,6 +28,16 @@
modulesWarningsAllowedKey = android.NewOnceKey("ModulesWarningsAllowed")
modulesUsingWnoErrorKey = android.NewOnceKey("ModulesUsingWnoError")
modulesMissingProfileFileKey = android.NewOnceKey("ModulesMissingProfileFile")
+ sanitizerVariables = map[string]string{
+ "ADDRESS_SANITIZER_RUNTIME_LIBRARY": config.AddressSanitizerRuntimeLibrary(),
+ "HWADDRESS_SANITIZER_RUNTIME_LIBRARY": config.HWAddressSanitizerRuntimeLibrary(),
+ "HWADDRESS_SANITIZER_STATIC_LIBRARY": config.HWAddressSanitizerStaticLibrary(),
+ "UBSAN_RUNTIME_LIBRARY": config.UndefinedBehaviorSanitizerRuntimeLibrary(),
+ "UBSAN_MINIMAL_RUNTIME_LIBRARY": config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(),
+ "TSAN_RUNTIME_LIBRARY": config.ThreadSanitizerRuntimeLibrary(),
+ "SCUDO_RUNTIME_LIBRARY": config.ScudoRuntimeLibrary(),
+ "SCUDO_MINIMAL_RUNTIME_LIBRARY": config.ScudoMinimalRuntimeLibrary(),
+ }
)
func init() {
@@ -261,43 +271,9 @@
}, " "))
if target.Os.Class == android.Device {
- sanitizerVariables := map[string]string{
- "ADDRESS_SANITIZER_RUNTIME_LIBRARY": config.AddressSanitizerRuntimeLibrary(toolchain),
- "HWADDRESS_SANITIZER_RUNTIME_LIBRARY": config.HWAddressSanitizerRuntimeLibrary(toolchain),
- "HWADDRESS_SANITIZER_STATIC_LIBRARY": config.HWAddressSanitizerStaticLibrary(toolchain),
- "UBSAN_RUNTIME_LIBRARY": config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain),
- "UBSAN_MINIMAL_RUNTIME_LIBRARY": config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(toolchain),
- "TSAN_RUNTIME_LIBRARY": config.ThreadSanitizerRuntimeLibrary(toolchain),
- "SCUDO_RUNTIME_LIBRARY": config.ScudoRuntimeLibrary(toolchain),
- "SCUDO_MINIMAL_RUNTIME_LIBRARY": config.ScudoMinimalRuntimeLibrary(toolchain),
- }
-
for variable, value := range sanitizerVariables {
ctx.Strict(secondPrefix+variable, value)
}
-
- sanitizerLibs := android.SortedStringValues(sanitizerVariables)
- var sanitizerLibStems []string
- ctx.VisitAllModules(func(m android.Module) {
- if !m.Enabled(ctx) {
- return
- }
-
- ccModule, _ := m.(*Module)
- if ccModule == nil || ccModule.library == nil || !ccModule.library.shared() {
- return
- }
-
- if android.InList(strings.TrimPrefix(ctx.ModuleName(m), "prebuilt_"), sanitizerLibs) &&
- m.Target().Os == target.Os && m.Target().Arch.ArchType == target.Arch.ArchType {
- outputFile := ccModule.outputFile
- if outputFile.Valid() {
- sanitizerLibStems = append(sanitizerLibStems, outputFile.Path().Base())
- }
- }
- })
- sanitizerLibStems = android.SortedUniqueStrings(sanitizerLibStems)
- ctx.Strict(secondPrefix+"SANITIZER_STEMS", strings.Join(sanitizerLibStems, " "))
}
// This is used by external/gentoo/...
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 1a94729..e6075ad 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -25,6 +25,7 @@
"android/soong/android"
"android/soong/cc/config"
+ "android/soong/etc"
)
var (
@@ -408,6 +409,8 @@
android.RegisterMakeVarsProvider(pctx, cfiMakeVarsProvider)
android.RegisterMakeVarsProvider(pctx, hwasanMakeVarsProvider)
android.RegisterMakeVarsProvider(pctx, memtagStackMakeVarsProvider)
+
+ RegisterSanitizerLibrariesTxtType(android.InitRegistrationContext)
}
func (sanitize *sanitize) props() []interface{} {
@@ -1316,7 +1319,7 @@
} else if s.sanitizer == cfi {
cfiStaticLibs(mctx.Config()).add(c, c.Module().Name())
} else if s.sanitizer == Memtag_stack {
- memtagStackStaticLibs(mctx.Config()).add(c, c.Module().Name());
+ memtagStackStaticLibs(mctx.Config()).add(c, c.Module().Name())
}
}
} else if c.IsSanitizerEnabled(s.sanitizer) {
@@ -1522,25 +1525,25 @@
if Bool(sanProps.Address) {
if toolchain.Musl() || (c.staticBinary() && toolchain.Bionic()) {
// Use a static runtime for musl to match what clang does for glibc.
- addStaticDeps(config.AddressSanitizerStaticRuntimeLibrary(toolchain), false)
- addStaticDeps(config.AddressSanitizerCXXStaticRuntimeLibrary(toolchain), false)
+ addStaticDeps(config.AddressSanitizerStaticRuntimeLibrary(), false)
+ addStaticDeps(config.AddressSanitizerCXXStaticRuntimeLibrary(), false)
} else {
- runtimeSharedLibrary = config.AddressSanitizerRuntimeLibrary(toolchain)
+ runtimeSharedLibrary = config.AddressSanitizerRuntimeLibrary()
}
} else if Bool(sanProps.Hwaddress) {
if c.staticBinary() {
- addStaticDeps(config.HWAddressSanitizerStaticLibrary(toolchain), true)
+ addStaticDeps(config.HWAddressSanitizerStaticLibrary(), true)
addStaticDeps("libdl", false)
} else {
- runtimeSharedLibrary = config.HWAddressSanitizerRuntimeLibrary(toolchain)
+ runtimeSharedLibrary = config.HWAddressSanitizerRuntimeLibrary()
}
} else if Bool(sanProps.Thread) {
- runtimeSharedLibrary = config.ThreadSanitizerRuntimeLibrary(toolchain)
+ runtimeSharedLibrary = config.ThreadSanitizerRuntimeLibrary()
} else if Bool(sanProps.Scudo) {
if len(diagSanitizers) == 0 && !c.sanitize.Properties.UbsanRuntimeDep {
- runtimeSharedLibrary = config.ScudoMinimalRuntimeLibrary(toolchain)
+ runtimeSharedLibrary = config.ScudoMinimalRuntimeLibrary()
} else {
- runtimeSharedLibrary = config.ScudoRuntimeLibrary(toolchain)
+ runtimeSharedLibrary = config.ScudoRuntimeLibrary()
}
} else if len(diagSanitizers) > 0 || c.sanitize.Properties.UbsanRuntimeDep ||
Bool(sanProps.Fuzzer) ||
@@ -1553,17 +1556,17 @@
// Also manually add a static runtime for musl to match what clang does for glibc.
// Otherwise dlopening libraries that depend on libclang_rt.ubsan_standalone.so fails with:
// Error relocating ...: initial-exec TLS resolves to dynamic definition
- addStaticDeps(config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain)+".static", true)
+ addStaticDeps(config.UndefinedBehaviorSanitizerRuntimeLibrary()+".static", true)
} else {
- runtimeSharedLibrary = config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain)
+ runtimeSharedLibrary = config.UndefinedBehaviorSanitizerRuntimeLibrary()
}
}
if enableMinimalRuntime(c.sanitize) || c.sanitize.Properties.MinimalRuntimeDep {
- addStaticDeps(config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(toolchain), true)
+ addStaticDeps(config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(), true)
}
if c.sanitize.Properties.BuiltinsDep {
- addStaticDeps(config.BuiltinsRuntimeLibrary(toolchain), true)
+ addStaticDeps(config.BuiltinsRuntimeLibrary(), true)
}
if runtimeSharedLibrary != "" && (toolchain.Bionic() || toolchain.Musl()) {
@@ -1787,3 +1790,126 @@
func memtagStackMakeVarsProvider(ctx android.MakeVarsContext) {
memtagStackStaticLibs(ctx.Config()).exportToMake(ctx)
}
+
+type sanitizerLibrariesTxtModule struct {
+ android.ModuleBase
+
+ outputFile android.OutputPath
+}
+
+var _ etc.PrebuiltEtcModule = (*sanitizerLibrariesTxtModule)(nil)
+var _ android.OutputFileProducer = (*sanitizerLibrariesTxtModule)(nil)
+
+func RegisterSanitizerLibrariesTxtType(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("sanitizer_libraries_txt", sanitizerLibrariesTxtFactory)
+}
+
+func sanitizerLibrariesTxtFactory() android.Module {
+ m := &sanitizerLibrariesTxtModule{}
+ android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
+ return m
+}
+
+type sanitizerLibraryDependencyTag struct {
+ blueprint.BaseDependencyTag
+}
+
+func (t sanitizerLibraryDependencyTag) AllowDisabledModuleDependency(target android.Module) bool {
+ return true
+}
+
+var _ android.AllowDisabledModuleDependency = (*sanitizerLibraryDependencyTag)(nil)
+
+func (txt *sanitizerLibrariesTxtModule) DepsMutator(actx android.BottomUpMutatorContext) {
+ targets := actx.Config().Targets[android.Android]
+ depTag := sanitizerLibraryDependencyTag{}
+
+ for _, target := range targets {
+ variation := append(target.Variations(),
+ blueprint.Variation{Mutator: "image", Variation: ""},
+ blueprint.Variation{Mutator: "sdk", Variation: ""},
+ blueprint.Variation{Mutator: "link", Variation: "shared"},
+ )
+ for _, lib := range android.SortedStringValues(sanitizerVariables) {
+ if actx.OtherModuleFarDependencyVariantExists(variation, lib) {
+ actx.AddFarVariationDependencies(variation, depTag, lib)
+ }
+
+ prebuiltLibName := "prebuilt_" + lib
+ if actx.OtherModuleFarDependencyVariantExists(variation, prebuiltLibName) {
+ actx.AddFarVariationDependencies(variation, depTag, prebuiltLibName)
+ }
+ }
+ }
+
+}
+
+func (txt *sanitizerLibrariesTxtModule) getSanitizerLibs(ctx android.ModuleContext) string {
+ var sanitizerLibStems []string
+
+ ctx.VisitDirectDepsIf(func(m android.Module) bool {
+ if !m.Enabled(ctx) {
+ return false
+ }
+
+ ccModule, _ := m.(*Module)
+ if ccModule == nil || ccModule.library == nil || !ccModule.library.shared() {
+ return false
+ }
+
+ targets := ctx.Config().Targets[android.Android]
+
+ for _, target := range targets {
+ if m.Target().Os == target.Os && m.Target().Arch.ArchType == target.Arch.ArchType {
+ return true
+ }
+ }
+
+ return false
+ }, func(m android.Module) {
+ ccModule, _ := m.(*Module)
+ outputFile := ccModule.outputFile
+ if outputFile.Valid() {
+ sanitizerLibStems = append(sanitizerLibStems, outputFile.Path().Base())
+ }
+ })
+
+ sanitizerLibStems = android.SortedUniqueStrings(sanitizerLibStems)
+ return strings.Join(sanitizerLibStems, "\n")
+}
+
+func (txt *sanitizerLibrariesTxtModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ filename := txt.Name()
+
+ txt.outputFile = android.PathForModuleOut(ctx, filename).OutputPath
+ android.WriteFileRule(ctx, txt.outputFile, txt.getSanitizerLibs(ctx))
+
+ installPath := android.PathForModuleInstall(ctx, "etc")
+ ctx.InstallFile(installPath, filename, txt.outputFile)
+}
+
+func (txt *sanitizerLibrariesTxtModule) AndroidMkEntries() []android.AndroidMkEntries {
+ return []android.AndroidMkEntries{{
+ Class: "ETC",
+ OutputFile: android.OptionalPathForPath(txt.outputFile),
+ }}
+}
+
+// PrebuiltEtcModule interface
+func (txt *sanitizerLibrariesTxtModule) OutputFile() android.OutputPath {
+ return txt.outputFile
+}
+
+// PrebuiltEtcModule interface
+func (txt *sanitizerLibrariesTxtModule) BaseDir() string {
+ return "etc"
+}
+
+// PrebuiltEtcModule interface
+func (txt *sanitizerLibrariesTxtModule) SubDir() string {
+ return ""
+}
+
+func (txt *sanitizerLibrariesTxtModule) OutputFiles(tag string) (android.Paths, error) {
+ return android.Paths{txt.outputFile}, nil
+}
diff --git a/cc/vndk.go b/cc/vndk.go
index 548992d..ea55835 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -20,7 +20,6 @@
"strings"
"android/soong/android"
- "android/soong/cc/config"
"android/soong/etc"
"github.com/google/blueprint"
@@ -219,11 +218,10 @@
type moduleListerFunc func(ctx android.SingletonContext) (moduleNames, fileNames []string)
var (
- vndkSPLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKSP })
- vndkCoreLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKCore })
- vndkPrivateLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKPrivate })
- vndkProductLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKProduct })
- vndkUsingCoreVariantLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKUsingCoreVariant })
+ vndkSPLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKSP })
+ vndkCoreLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKCore })
+ vndkPrivateLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKPrivate })
+ vndkProductLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKProduct })
)
// vndkModuleLister takes a predicate that operates on a Module and returns a moduleListerFunc
@@ -266,22 +264,6 @@
}
}
-var vndkMustUseVendorVariantListKey = android.NewOnceKey("vndkMustUseVendorVariantListKey")
-
-func vndkMustUseVendorVariantList(cfg android.Config) []string {
- return cfg.Once(vndkMustUseVendorVariantListKey, func() interface{} {
- return config.VndkMustUseVendorVariantList
- }).([]string)
-}
-
-// test may call this to override global configuration(config.VndkMustUseVendorVariantList)
-// when it is called, it must be before the first call to vndkMustUseVendorVariantList()
-func setVndkMustUseVendorVariantListForTest(config android.Config, mustUseVendorVariantList []string) {
- config.Once(vndkMustUseVendorVariantListKey, func() interface{} {
- return mustUseVendorVariantList
- })
-}
-
func processVndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
if m.InProduct() {
// We may skip the steps for the product variants because they
@@ -301,13 +283,6 @@
mctx.PropertyErrorf("vndk.enabled", "This library provides stubs. Shouldn't be VNDK. Consider making it as LLNDK")
}
- if inList(name, vndkMustUseVendorVariantList(mctx.Config())) {
- m.Properties.MustUseVendorVariant = true
- }
- if mctx.DeviceConfig().VndkUseCoreVariant() && !m.Properties.MustUseVendorVariant {
- m.VendorProperties.IsVNDKUsingCoreVariant = true
- }
-
if m.vndkdep.isVndkSp() {
m.VendorProperties.IsVNDKSP = true
} else {
@@ -356,8 +331,7 @@
if lib.buildStubs() {
return false
}
- useCoreVariant := mctx.DeviceConfig().VndkUseCoreVariant() && !m.MustUseVendorVariant()
- return lib.shared() && m.InVendor() && m.IsVndk() && !m.IsVndkExt() && !useCoreVariant
+ return lib.shared() && m.InVendor() && m.IsVndk() && !m.IsVndkExt()
}
return false
}
@@ -400,7 +374,6 @@
ctx.RegisterParallelSingletonModuleType("vndkcore_libraries_txt", vndkCoreLibrariesTxtFactory)
ctx.RegisterParallelSingletonModuleType("vndkprivate_libraries_txt", vndkPrivateLibrariesTxtFactory)
ctx.RegisterParallelSingletonModuleType("vndkproduct_libraries_txt", vndkProductLibrariesTxtFactory)
- ctx.RegisterParallelSingletonModuleType("vndkcorevariant_libraries_txt", vndkUsingCoreVariantLibrariesTxtFactory)
}
type vndkLibrariesTxt struct {
@@ -453,13 +426,6 @@
return newVndkLibrariesTxt(vndkProductLibraries, "VNDK_PRODUCT_LIBRARIES")
}
-// vndkcorevariant_libraries_txt is a singleton module whose content is a list of VNDK libraries
-// that are using the core variant, generated by Soong but can be referenced by other modules.
-// For example, apex_vndk can depend on these files as prebuilt.
-func vndkUsingCoreVariantLibrariesTxtFactory() android.SingletonModule {
- return newVndkLibrariesTxt(vndkUsingCoreVariantLibraries, "VNDK_USING_CORE_VARIANT_LIBRARIES")
-}
-
func newVndkLibrariesWithMakeVarFilter(lister moduleListerFunc, makeVarName string, filter string) android.SingletonModule {
m := &vndkLibrariesTxt{
lister: lister,
diff --git a/cmd/release_config/build_flag/main.go b/cmd/release_config/build_flag/main.go
index cc2b57a..f74784b 100644
--- a/cmd/release_config/build_flag/main.go
+++ b/cmd/release_config/build_flag/main.go
@@ -48,6 +48,11 @@
// Panic on errors.
debug bool
+
+ // Allow missing release config.
+ // If true, and we cannot find the named release config, values for
+ // `trunk_staging` will be used.
+ allowMissing bool
}
type CommandFunc func(*rc_lib.ReleaseConfigs, Flags, string, []string) error
@@ -284,7 +289,7 @@
}
// Reload the release configs.
- configs, err = rc_lib.ReadReleaseConfigMaps(commonFlags.maps, commonFlags.targetReleases[0], commonFlags.useGetBuildVar)
+ configs, err = rc_lib.ReadReleaseConfigMaps(commonFlags.maps, commonFlags.targetReleases[0], commonFlags.useGetBuildVar, commonFlags.allowMissing)
if err != nil {
return err
}
@@ -307,6 +312,7 @@
flag.Var(&commonFlags.maps, "map", "path to a release_config_map.textproto. may be repeated")
flag.StringVar(&commonFlags.outDir, "out-dir", rc_lib.GetDefaultOutDir(), "basepath for the output. Multiple formats are created")
flag.Var(&commonFlags.targetReleases, "release", "TARGET_RELEASE for this build")
+ flag.BoolVar(&commonFlags.allowMissing, "allow-missing", false, "Use trunk_staging values if release not found")
flag.BoolVar(&commonFlags.allReleases, "all-releases", false, "operate on all releases. (Ignored for set command)")
flag.BoolVar(&commonFlags.useGetBuildVar, "use-get-build-var", true, "use get_build_var PRODUCT_RELEASE_CONFIG_MAPS to get needed maps")
flag.BoolVar(&commonFlags.debug, "debug", false, "turn on debugging output for errors")
@@ -342,7 +348,7 @@
if relName == "--all" || relName == "-all" {
commonFlags.allReleases = true
}
- configs, err = rc_lib.ReadReleaseConfigMaps(commonFlags.maps, relName, commonFlags.useGetBuildVar)
+ configs, err = rc_lib.ReadReleaseConfigMaps(commonFlags.maps, relName, commonFlags.useGetBuildVar, commonFlags.allowMissing)
if err != nil {
errorExit(err)
}
diff --git a/cmd/release_config/build_flag_declarations/main.go b/cmd/release_config/build_flag_declarations/main.go
index 8315f59..cc286b6 100644
--- a/cmd/release_config/build_flag_declarations/main.go
+++ b/cmd/release_config/build_flag_declarations/main.go
@@ -6,6 +6,7 @@
"os"
rc_lib "android/soong/cmd/release_config/release_config_lib"
+ rc_proto "android/soong/cmd/release_config/release_config_proto"
)
type Flags struct {
@@ -62,18 +63,17 @@
}
flagArtifacts := rc_lib.FlagArtifactsFactory("")
+ intermediates := []*rc_proto.FlagDeclarationArtifacts{}
for _, intermediate := range flags.intermediates {
- fas := rc_lib.FlagArtifactsFactory(intermediate)
- for _, fa := range *fas {
- (*flagArtifacts)[*fa.FlagDeclaration.Name] = fa
- }
+ fda := rc_lib.FlagDeclarationArtifactsFactory(intermediate)
+ intermediates = append(intermediates, fda)
}
for _, decl := range flags.decls {
fa := rc_lib.FlagArtifactFactory(decl)
(*flagArtifacts)[*fa.FlagDeclaration.Name] = fa
}
- message := flagArtifacts.GenerateFlagArtifacts()
+ message := flagArtifacts.GenerateFlagDeclarationArtifacts(intermediates)
err = rc_lib.WriteFormattedMessage(flags.output, flags.format, message)
if err != nil {
errorExit(err)
diff --git a/cmd/release_config/release_config/main.go b/cmd/release_config/release_config/main.go
index 0617838..bd4ab49 100644
--- a/cmd/release_config/release_config/main.go
+++ b/cmd/release_config/release_config/main.go
@@ -31,10 +31,10 @@
var outputDir string
var err error
var configs *rc_lib.ReleaseConfigs
- var json, pb, textproto bool
+ var json, pb, textproto, inheritance bool
var product string
var allMake bool
- var useBuildVar bool
+ var useBuildVar, allowMissing bool
var guard bool
defaultRelease := os.Getenv("TARGET_RELEASE")
@@ -47,11 +47,13 @@
flag.BoolVar(&quiet, "quiet", false, "disable warning messages")
flag.Var(&releaseConfigMapPaths, "map", "path to a release_config_map.textproto. may be repeated")
flag.StringVar(&targetRelease, "release", defaultRelease, "TARGET_RELEASE for this build")
+ flag.BoolVar(&allowMissing, "allow-missing", false, "Use trunk_staging values if release not found")
flag.StringVar(&outputDir, "out_dir", rc_lib.GetDefaultOutDir(), "basepath for the output. Multiple formats are created")
flag.BoolVar(&textproto, "textproto", true, "write artifacts as text protobuf")
flag.BoolVar(&json, "json", true, "write artifacts as json")
flag.BoolVar(&pb, "pb", true, "write artifacts as binary protobuf")
flag.BoolVar(&allMake, "all_make", false, "write makefiles for all release configs")
+ flag.BoolVar(&inheritance, "inheritance", true, "write inheritance graph")
flag.BoolVar(&useBuildVar, "use_get_build_var", false, "use get_build_var PRODUCT_RELEASE_CONFIG_MAPS")
flag.BoolVar(&guard, "guard", true, "whether to guard with RELEASE_BUILD_FLAGS_IN_PROTOBUF")
@@ -64,7 +66,7 @@
if err = os.Chdir(top); err != nil {
panic(err)
}
- configs, err = rc_lib.ReadReleaseConfigMaps(releaseConfigMapPaths, targetRelease, useBuildVar)
+ configs, err = rc_lib.ReadReleaseConfigMaps(releaseConfigMapPaths, targetRelease, useBuildVar, allowMissing)
if err != nil {
panic(err)
}
@@ -102,6 +104,13 @@
}
}
}
+ if inheritance {
+ inheritPath := filepath.Join(outputDir, fmt.Sprintf("inheritance_graph-%s.dot", product))
+ err = configs.WriteInheritanceGraph(inheritPath)
+ if err != nil {
+ panic(err)
+ }
+ }
if json {
err = configs.WriteArtifact(outputDir, product, "json")
if err != nil {
@@ -120,7 +129,7 @@
panic(err)
}
}
- if err = config.WritePartitionBuildFlags(outputDir, product, targetRelease); err != nil {
+ if err = config.WritePartitionBuildFlags(outputDir); err != nil {
panic(err)
}
diff --git a/cmd/release_config/release_config_lib/flag_artifact.go b/cmd/release_config/release_config_lib/flag_artifact.go
index cdd5af9..6d36595 100644
--- a/cmd/release_config/release_config_lib/flag_artifact.go
+++ b/cmd/release_config/release_config_lib/flag_artifact.go
@@ -82,24 +82,46 @@
return &ret
}
-func (fa *FlagArtifact) GenerateFlagArtifact() *rc_proto.FlagArtifact {
- ret := &rc_proto.FlagArtifact{FlagDeclaration: fa.FlagDeclaration}
- if fa.Value != nil {
- ret.Value = fa.Value
+func (fa *FlagArtifact) GenerateFlagDeclarationArtifact() *rc_proto.FlagDeclarationArtifact {
+ ret := &rc_proto.FlagDeclarationArtifact{
+ Name: fa.FlagDeclaration.Name,
+ DeclarationPath: fa.Traces[0].Source,
}
- if len(fa.Traces) > 0 {
- ret.Traces = fa.Traces
+ if namespace := fa.FlagDeclaration.GetNamespace(); namespace != "" {
+ ret.Namespace = proto.String(namespace)
+ }
+ if description := fa.FlagDeclaration.GetDescription(); description != "" {
+ ret.Description = proto.String(description)
+ }
+ if workflow := fa.FlagDeclaration.GetWorkflow(); workflow != rc_proto.Workflow_Workflow_Unspecified {
+ ret.Workflow = &workflow
+ }
+ if containers := fa.FlagDeclaration.GetContainers(); containers != nil {
+ ret.Containers = containers
}
return ret
}
-func (fas *FlagArtifacts) GenerateFlagArtifacts() *rc_proto.FlagArtifacts {
- ret := &rc_proto.FlagArtifacts{FlagArtifacts: []*rc_proto.FlagArtifact{}}
- for _, fa := range *fas {
- ret.FlagArtifacts = append(ret.FlagArtifacts, fa.GenerateFlagArtifact())
+func FlagDeclarationArtifactsFactory(path string) *rc_proto.FlagDeclarationArtifacts {
+ ret := &rc_proto.FlagDeclarationArtifacts{}
+ if path != "" {
+ LoadMessage(path, ret)
+ } else {
+ ret.FlagDeclarationArtifacts = []*rc_proto.FlagDeclarationArtifact{}
}
- slices.SortFunc(ret.FlagArtifacts, func(a, b *rc_proto.FlagArtifact) int {
- return cmp.Compare(*a.FlagDeclaration.Name, *b.FlagDeclaration.Name)
+ return ret
+}
+
+func (fas *FlagArtifacts) GenerateFlagDeclarationArtifacts(intermediates []*rc_proto.FlagDeclarationArtifacts) *rc_proto.FlagDeclarationArtifacts {
+ ret := &rc_proto.FlagDeclarationArtifacts{FlagDeclarationArtifacts: []*rc_proto.FlagDeclarationArtifact{}}
+ for _, fa := range *fas {
+ ret.FlagDeclarationArtifacts = append(ret.FlagDeclarationArtifacts, fa.GenerateFlagDeclarationArtifact())
+ }
+ for _, fda := range intermediates {
+ ret.FlagDeclarationArtifacts = append(ret.FlagDeclarationArtifacts, fda.FlagDeclarationArtifacts...)
+ }
+ slices.SortFunc(ret.FlagDeclarationArtifacts, func(a, b *rc_proto.FlagDeclarationArtifact) int {
+ return cmp.Compare(*a.Name, *b.Name)
})
return ret
}
diff --git a/cmd/release_config/release_config_lib/release_config.go b/cmd/release_config/release_config_lib/release_config.go
index 547f0dc..02b693c 100644
--- a/cmd/release_config/release_config_lib/release_config.go
+++ b/cmd/release_config/release_config_lib/release_config.go
@@ -18,6 +18,7 @@
"cmp"
"fmt"
"path/filepath"
+ "regexp"
"slices"
"sort"
"strings"
@@ -80,6 +81,10 @@
// Partitioned artifacts for {partition}/etc/build_flags.json
PartitionBuildFlags map[string]*rc_proto.FlagArtifacts
+
+ // Prior stage(s) for flag advancement (during development).
+ // Once a flag has met criteria in a prior stage, it can advance to this one.
+ PriorStagesMap map[string]bool
}
func ReleaseConfigFactory(name string, index int) (c *ReleaseConfig) {
@@ -87,6 +92,7 @@
Name: name,
DeclarationIndex: index,
FilesUsedMap: make(map[string]bool),
+ PriorStagesMap: make(map[string]bool),
}
}
@@ -117,14 +123,7 @@
}
func (config *ReleaseConfig) GetSortedFileList() []string {
- ret := []string{}
- for k := range config.FilesUsedMap {
- ret = append(ret, k)
- }
- slices.SortFunc(ret, func(a, b string) int {
- return cmp.Compare(a, b)
- })
- return ret
+ return SortedMapKeys(config.FilesUsedMap)
}
func (config *ReleaseConfig) GenerateReleaseConfig(configs *ReleaseConfigs) error {
@@ -137,9 +136,15 @@
config.compileInProgress = true
isRoot := config.Name == "root"
+ // Is this a build-prefix release config, such as 'ap3a'?
+ isBuildPrefix, err := regexp.MatchString("^[a-z][a-z][0-9][0-9a-z]$", config.Name)
+ if err != nil {
+ return err
+ }
// Start with only the flag declarations.
config.FlagArtifacts = configs.FlagArtifacts.Clone()
releaseAconfigValueSets := config.FlagArtifacts["RELEASE_ACONFIG_VALUE_SETS"]
+ releasePlatformVersion := config.FlagArtifacts["RELEASE_PLATFORM_VERSION"]
// Generate any configs we need to inherit. This will detect loops in
// the config.
@@ -147,7 +152,7 @@
myInherits := []string{}
myInheritsSet := make(map[string]bool)
// If there is a "root" release config, it is the start of every inheritance chain.
- _, err := configs.GetReleaseConfig("root")
+ _, err = configs.GetReleaseConfig("root")
if err == nil && !isRoot {
config.InheritNames = append([]string{"root"}, config.InheritNames...)
}
@@ -155,6 +160,9 @@
if _, ok := myInheritsSet[inherit]; ok {
continue
}
+ if isBuildPrefix && configs.Aliases[inherit] != nil {
+ return fmt.Errorf("%s cannot inherit from alias %s", config.Name, inherit)
+ }
myInherits = append(myInherits, inherit)
myInheritsSet[inherit] = true
iConfig, err := configs.GetReleaseConfig(inherit)
@@ -179,6 +187,20 @@
workflowManual := rc_proto.Workflow(rc_proto.Workflow_MANUAL)
myDirsMap := make(map[int]bool)
+ if isBuildPrefix && releasePlatformVersion != nil {
+ if MarshalValue(releasePlatformVersion.Value) != strings.ToUpper(config.Name) {
+ value := FlagValue{
+ path: config.Contributions[0].path,
+ proto: rc_proto.FlagValue{
+ Name: releasePlatformVersion.FlagDeclaration.Name,
+ Value: UnmarshalValue(strings.ToUpper(config.Name)),
+ },
+ }
+ if err := releasePlatformVersion.UpdateValue(value); err != nil {
+ return err
+ }
+ }
+ }
for _, contrib := range contributionsToApply {
contribAconfigValueSets := []string{}
// Gather the aconfig_value_sets from this contribution, allowing duplicates for simplicity.
@@ -195,6 +217,9 @@
Value: &rc_proto.Value{Val: &rc_proto.Value_StringValue{contribAconfigValueSetsString}},
})
+ for _, priorStage := range contrib.proto.PriorStages {
+ config.PriorStagesMap[priorStage] = true
+ }
myDirsMap[contrib.DeclarationIndex] = true
if config.AconfigFlagsOnly && len(contrib.FlagValues) > 0 {
return fmt.Errorf("%s does not allow build flag overrides", config.Name)
@@ -278,19 +303,22 @@
AconfigValueSets: myAconfigValueSets,
Inherits: myInherits,
Directories: directories,
+ PriorStages: SortedMapKeys(config.PriorStagesMap),
}
config.compileInProgress = false
return nil
}
-func (config *ReleaseConfig) WritePartitionBuildFlags(outDir, product, targetRelease string) error {
+func (config *ReleaseConfig) WritePartitionBuildFlags(outDir string) error {
var err error
for partition, flags := range config.PartitionBuildFlags {
slices.SortFunc(flags.FlagArtifacts, func(a, b *rc_proto.FlagArtifact) int {
return cmp.Compare(*a.FlagDeclaration.Name, *b.FlagDeclaration.Name)
})
- if err = WriteMessage(filepath.Join(outDir, fmt.Sprintf("build_flags_%s-%s-%s.json", partition, config.Name, product)), flags); err != nil {
+ // The json file name must not be modified as this is read from
+ // build_flags_json module
+ if err = WriteMessage(filepath.Join(outDir, fmt.Sprintf("build_flags_%s.json", partition)), flags); err != nil {
return err
}
}
diff --git a/cmd/release_config/release_config_lib/release_configs.go b/cmd/release_config/release_config_lib/release_configs.go
index c62a78e..02eedc8 100644
--- a/cmd/release_config/release_config_lib/release_configs.go
+++ b/cmd/release_config/release_config_lib/release_configs.go
@@ -76,6 +76,77 @@
// A map from the config directory to its order in the list of config
// directories.
configDirIndexes ReleaseConfigDirMap
+
+ // True if we should allow a missing primary release config. In this
+ // case, we will substitute `trunk_staging` values, but the release
+ // config will not be in ALL_RELEASE_CONFIGS_FOR_PRODUCT.
+ allowMissing bool
+}
+
+func (configs *ReleaseConfigs) WriteInheritanceGraph(outFile string) error {
+ data := []string{}
+ usedAliases := make(map[string]bool)
+ priorStages := make(map[string][]string)
+ rankedStageNames := make(map[string]bool)
+ for _, config := range configs.ReleaseConfigs {
+ var fillColor string
+ inherits := []string{}
+ for _, inherit := range config.InheritNames {
+ if inherit == "root" {
+ // Only show "root" if we have no other inheritance.
+ if len(config.InheritNames) > 1 {
+ continue
+ }
+ }
+ data = append(data, fmt.Sprintf(`"%s" -> "%s"`, config.Name, inherit))
+ inherits = append(inherits, inherit)
+ // If inheriting an alias, add a link from the alias to that release config.
+ if name, found := configs.Aliases[inherit]; found {
+ if !usedAliases[inherit] {
+ usedAliases[inherit] = true
+ data = append(data, fmt.Sprintf(`"%s" -> "%s"`, inherit, *name))
+ data = append(data,
+ fmt.Sprintf(`"%s" [ label="%s\ncurrently: %s" shape=oval ]`,
+ inherit, inherit, *name))
+ }
+ }
+ }
+ // Add links for all of the advancement progressions.
+ for priorStage := range config.PriorStagesMap {
+ stageName := config.Name
+ if len(config.OtherNames) > 0 {
+ stageName = config.OtherNames[0]
+ }
+ data = append(data, fmt.Sprintf(`"%s" -> "%s" [ style=dashed color="#81c995" ]`,
+ priorStage, stageName))
+ priorStages[stageName] = append(priorStages[stageName], priorStage)
+ rankedStageNames[stageName] = true
+ }
+ label := config.Name
+ if len(inherits) > 0 {
+ label += "\\ninherits: " + strings.Join(inherits, " ")
+ }
+ if len(config.OtherNames) > 0 {
+ label += "\\nother names: " + strings.Join(config.OtherNames, " ")
+ }
+ // The active release config has a light blue fill.
+ if config.Name == *configs.Artifact.ReleaseConfig.Name {
+ fillColor = `fillcolor="#d2e3fc" `
+ }
+ data = append(data,
+ fmt.Sprintf(`"%s" [ label="%s" %s]`, config.Name, label, fillColor))
+ }
+ if len(rankedStageNames) > 0 {
+ data = append(data, fmt.Sprintf("subgraph {rank=same %s}", strings.Join(SortedMapKeys(rankedStageNames), " ")))
+ }
+ slices.Sort(data)
+ data = append([]string{
+ "digraph {",
+ "graph [ ratio=.5 ]",
+ "node [ shape=box style=filled fillcolor=white colorscheme=svg fontcolor=black ]",
+ }, data...)
+ data = append(data, "}")
+ return os.WriteFile(outFile, []byte(strings.Join(data, "\n")), 0644)
}
// Write the "all_release_configs" artifact.
@@ -256,7 +327,17 @@
}
config := configs.ReleaseConfigs[name]
config.FilesUsedMap[path] = true
- config.InheritNames = append(config.InheritNames, releaseConfigContribution.proto.Inherits...)
+ inheritNames := make(map[string]bool)
+ for _, inh := range config.InheritNames {
+ inheritNames[inh] = true
+ }
+ // If this contribution says to inherit something we already inherited, we do not want the duplicate.
+ for _, cInh := range releaseConfigContribution.proto.Inherits {
+ if !inheritNames[cInh] {
+ config.InheritNames = append(config.InheritNames, cInh)
+ inheritNames[cInh] = true
+ }
+ }
// Only walk flag_values/{RELEASE} for defined releases.
err2 := WalkTextprotoFiles(dir, filepath.Join("flag_values", name), func(path string, d fs.DirEntry, err error) error {
@@ -298,6 +379,11 @@
if config, ok := configs.ReleaseConfigs[name]; ok {
return config, nil
}
+ if configs.allowMissing {
+ if config, ok := configs.ReleaseConfigs["trunk_staging"]; ok {
+ return config, nil
+ }
+ }
return nil, fmt.Errorf("Missing config %s. Trace=%v", name, trace)
}
@@ -378,8 +464,8 @@
if targetRelease != config.Name {
data += fmt.Sprintf("# User specified TARGET_RELEASE=%s\n", targetRelease)
}
- // The variable _all_release_configs will get deleted during processing, so do not mark it read-only.
- data += fmt.Sprintf("_all_release_configs := %s\n", strings.Join(configs.GetAllReleaseNames(), " "))
+ // As it stands this list is not per-product, but conceptually it is, and will be.
+ data += fmt.Sprintf("ALL_RELEASE_CONFIGS_FOR_PRODUCT :=$= %s\n", strings.Join(configs.GetAllReleaseNames(), " "))
data += fmt.Sprintf("_used_files := %s\n", strings.Join(config.GetSortedFileList(), " "))
data += fmt.Sprintf("_ALL_RELEASE_FLAGS :=$= %s\n", strings.Join(names, " "))
for _, pName := range pNames {
@@ -445,7 +531,7 @@
return nil
}
-func ReadReleaseConfigMaps(releaseConfigMapPaths StringList, targetRelease string, useBuildVar bool) (*ReleaseConfigs, error) {
+func ReadReleaseConfigMaps(releaseConfigMapPaths StringList, targetRelease string, useBuildVar, allowMissing bool) (*ReleaseConfigs, error) {
var err error
if len(releaseConfigMapPaths) == 0 {
@@ -462,6 +548,7 @@
}
configs := ReleaseConfigsFactory()
+ configs.allowMissing = allowMissing
mapsRead := make(map[string]bool)
var idx int
for _, releaseConfigMapPath := range releaseConfigMapPaths {
diff --git a/cmd/release_config/release_config_lib/util.go b/cmd/release_config/release_config_lib/util.go
index 0af99a6..b8824d1 100644
--- a/cmd/release_config/release_config_lib/util.go
+++ b/cmd/release_config/release_config_lib/util.go
@@ -22,6 +22,7 @@
"os/exec"
"path/filepath"
"regexp"
+ "slices"
"strings"
"google.golang.org/protobuf/encoding/prototext"
@@ -159,6 +160,15 @@
return 0, nil
}
+func SortedMapKeys(inputMap map[string]bool) []string {
+ ret := []string{}
+ for k := range inputMap {
+ ret = append(ret, k)
+ }
+ slices.Sort(ret)
+ return ret
+}
+
func validContainer(container string) bool {
return containerRegexp.MatchString(container)
}
diff --git a/cmd/release_config/release_config_proto/Android.bp b/cmd/release_config/release_config_proto/Android.bp
index 8c47f2a..c34d203 100644
--- a/cmd/release_config/release_config_proto/Android.bp
+++ b/cmd/release_config/release_config_proto/Android.bp
@@ -24,6 +24,8 @@
"golang-protobuf-runtime-protoimpl",
],
srcs: [
+ "build_flags_common.pb.go",
+ "build_flags_declarations.pb.go",
"build_flags_src.pb.go",
"build_flags_out.pb.go",
],
diff --git a/cmd/release_config/release_config_proto/build_flags_common.pb.go b/cmd/release_config/release_config_proto/build_flags_common.pb.go
new file mode 100644
index 0000000..1e927db
--- /dev/null
+++ b/cmd/release_config/release_config_proto/build_flags_common.pb.go
@@ -0,0 +1,169 @@
+//
+// Copyright (C) 2024 The Android Open-Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.30.0
+// protoc v3.21.12
+// source: build_flags_common.proto
+
+package release_config_proto
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type Workflow int32
+
+const (
+ Workflow_Workflow_Unspecified Workflow = 0
+ // Boolean value flags that progress from false to true.
+ Workflow_LAUNCH Workflow = 1
+ // String value flags that get updated with new version strings to control
+ // prebuilt inclusion.
+ Workflow_PREBUILT Workflow = 2
+ // Manually managed outside flags. These are likely to be found in a
+ // different directory than flags with other workflows.
+ Workflow_MANUAL Workflow = 3
+)
+
+// Enum value maps for Workflow.
+var (
+ Workflow_name = map[int32]string{
+ 0: "Workflow_Unspecified",
+ 1: "LAUNCH",
+ 2: "PREBUILT",
+ 3: "MANUAL",
+ }
+ Workflow_value = map[string]int32{
+ "Workflow_Unspecified": 0,
+ "LAUNCH": 1,
+ "PREBUILT": 2,
+ "MANUAL": 3,
+ }
+)
+
+func (x Workflow) Enum() *Workflow {
+ p := new(Workflow)
+ *p = x
+ return p
+}
+
+func (x Workflow) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (Workflow) Descriptor() protoreflect.EnumDescriptor {
+ return file_build_flags_common_proto_enumTypes[0].Descriptor()
+}
+
+func (Workflow) Type() protoreflect.EnumType {
+ return &file_build_flags_common_proto_enumTypes[0]
+}
+
+func (x Workflow) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Do not use.
+func (x *Workflow) UnmarshalJSON(b []byte) error {
+ num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
+ if err != nil {
+ return err
+ }
+ *x = Workflow(num)
+ return nil
+}
+
+// Deprecated: Use Workflow.Descriptor instead.
+func (Workflow) EnumDescriptor() ([]byte, []int) {
+ return file_build_flags_common_proto_rawDescGZIP(), []int{0}
+}
+
+var File_build_flags_common_proto protoreflect.FileDescriptor
+
+var file_build_flags_common_proto_rawDesc = []byte{
+ 0x0a, 0x18, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5f, 0x63, 0x6f,
+ 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x61, 0x6e, 0x64, 0x72,
+ 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2a, 0x4a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b,
+ 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x18, 0x0a, 0x14, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77,
+ 0x5f, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x10, 0x00, 0x12, 0x0a,
+ 0x0a, 0x06, 0x4c, 0x41, 0x55, 0x4e, 0x43, 0x48, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x52,
+ 0x45, 0x42, 0x55, 0x49, 0x4c, 0x54, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x41, 0x4e, 0x55,
+ 0x41, 0x4c, 0x10, 0x03, 0x42, 0x33, 0x5a, 0x31, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f,
+ 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+}
+
+var (
+ file_build_flags_common_proto_rawDescOnce sync.Once
+ file_build_flags_common_proto_rawDescData = file_build_flags_common_proto_rawDesc
+)
+
+func file_build_flags_common_proto_rawDescGZIP() []byte {
+ file_build_flags_common_proto_rawDescOnce.Do(func() {
+ file_build_flags_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_build_flags_common_proto_rawDescData)
+ })
+ return file_build_flags_common_proto_rawDescData
+}
+
+var file_build_flags_common_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_build_flags_common_proto_goTypes = []interface{}{
+ (Workflow)(0), // 0: android.release_config_proto.workflow
+}
+var file_build_flags_common_proto_depIdxs = []int32{
+ 0, // [0:0] is the sub-list for method output_type
+ 0, // [0:0] is the sub-list for method input_type
+ 0, // [0:0] is the sub-list for extension type_name
+ 0, // [0:0] is the sub-list for extension extendee
+ 0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_build_flags_common_proto_init() }
+func file_build_flags_common_proto_init() {
+ if File_build_flags_common_proto != nil {
+ return
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_build_flags_common_proto_rawDesc,
+ NumEnums: 1,
+ NumMessages: 0,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_build_flags_common_proto_goTypes,
+ DependencyIndexes: file_build_flags_common_proto_depIdxs,
+ EnumInfos: file_build_flags_common_proto_enumTypes,
+ }.Build()
+ File_build_flags_common_proto = out.File
+ file_build_flags_common_proto_rawDesc = nil
+ file_build_flags_common_proto_goTypes = nil
+ file_build_flags_common_proto_depIdxs = nil
+}
diff --git a/cmd/release_config/release_config_proto/build_flags_common.proto b/cmd/release_config/release_config_proto/build_flags_common.proto
new file mode 100644
index 0000000..d5d6101
--- /dev/null
+++ b/cmd/release_config/release_config_proto/build_flags_common.proto
@@ -0,0 +1,36 @@
+//
+// Copyright (C) 2024 The Android Open-Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto2";
+package android.release_config_proto;
+option go_package = "android/soong/release_config/release_config_proto";
+
+// This protobuf file defines common messages used in the rest of the build flag
+// protos.
+
+enum workflow {
+ Workflow_Unspecified = 0;
+
+ // Boolean value flags that progress from false to true.
+ LAUNCH = 1;
+
+ // String value flags that get updated with new version strings to control
+ // prebuilt inclusion.
+ PREBUILT = 2;
+
+ // Manually managed outside flags. These are likely to be found in a
+ // different directory than flags with other workflows.
+ MANUAL = 3;
+}
diff --git a/cmd/release_config/release_config_proto/build_flags_declarations.pb.go b/cmd/release_config/release_config_proto/build_flags_declarations.pb.go
new file mode 100644
index 0000000..c0573ed
--- /dev/null
+++ b/cmd/release_config/release_config_proto/build_flags_declarations.pb.go
@@ -0,0 +1,301 @@
+//
+// Copyright (C) 2024 The Android Open-Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.30.0
+// protoc v3.21.12
+// source: build_flags_declarations.proto
+
+package release_config_proto
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type FlagDeclarationArtifact struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // The name of the flag.
+ // See # name for format detail
+ Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+ // Namespace the flag belongs to (required)
+ // See # namespace for format detail
+ Namespace *string `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"`
+ // Text description of the flag's purpose.
+ Description *string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"`
+ // Where the flag was declared.
+ DeclarationPath *string `protobuf:"bytes,5,opt,name=declaration_path,json=declarationPath" json:"declaration_path,omitempty"`
+ // Workflow for this flag.
+ Workflow *Workflow `protobuf:"varint,205,opt,name=workflow,enum=android.release_config_proto.Workflow" json:"workflow,omitempty"`
+ // The container for this flag. This overrides any default container given
+ // in the release_config_map message.
+ Containers []string `protobuf:"bytes,206,rep,name=containers" json:"containers,omitempty"`
+}
+
+func (x *FlagDeclarationArtifact) Reset() {
+ *x = FlagDeclarationArtifact{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_build_flags_declarations_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *FlagDeclarationArtifact) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FlagDeclarationArtifact) ProtoMessage() {}
+
+func (x *FlagDeclarationArtifact) ProtoReflect() protoreflect.Message {
+ mi := &file_build_flags_declarations_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use FlagDeclarationArtifact.ProtoReflect.Descriptor instead.
+func (*FlagDeclarationArtifact) Descriptor() ([]byte, []int) {
+ return file_build_flags_declarations_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *FlagDeclarationArtifact) GetName() string {
+ if x != nil && x.Name != nil {
+ return *x.Name
+ }
+ return ""
+}
+
+func (x *FlagDeclarationArtifact) GetNamespace() string {
+ if x != nil && x.Namespace != nil {
+ return *x.Namespace
+ }
+ return ""
+}
+
+func (x *FlagDeclarationArtifact) GetDescription() string {
+ if x != nil && x.Description != nil {
+ return *x.Description
+ }
+ return ""
+}
+
+func (x *FlagDeclarationArtifact) GetDeclarationPath() string {
+ if x != nil && x.DeclarationPath != nil {
+ return *x.DeclarationPath
+ }
+ return ""
+}
+
+func (x *FlagDeclarationArtifact) GetWorkflow() Workflow {
+ if x != nil && x.Workflow != nil {
+ return *x.Workflow
+ }
+ return Workflow_Workflow_Unspecified
+}
+
+func (x *FlagDeclarationArtifact) GetContainers() []string {
+ if x != nil {
+ return x.Containers
+ }
+ return nil
+}
+
+type FlagDeclarationArtifacts struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // The artifacts
+ FlagDeclarationArtifacts []*FlagDeclarationArtifact `protobuf:"bytes,1,rep,name=flag_declaration_artifacts,json=flagDeclarationArtifacts" json:"flag_declaration_artifacts,omitempty"`
+}
+
+func (x *FlagDeclarationArtifacts) Reset() {
+ *x = FlagDeclarationArtifacts{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_build_flags_declarations_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *FlagDeclarationArtifacts) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FlagDeclarationArtifacts) ProtoMessage() {}
+
+func (x *FlagDeclarationArtifacts) ProtoReflect() protoreflect.Message {
+ mi := &file_build_flags_declarations_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use FlagDeclarationArtifacts.ProtoReflect.Descriptor instead.
+func (*FlagDeclarationArtifacts) Descriptor() ([]byte, []int) {
+ return file_build_flags_declarations_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *FlagDeclarationArtifacts) GetFlagDeclarationArtifacts() []*FlagDeclarationArtifact {
+ if x != nil {
+ return x.FlagDeclarationArtifacts
+ }
+ return nil
+}
+
+var File_build_flags_declarations_proto protoreflect.FileDescriptor
+
+var file_build_flags_declarations_proto_rawDesc = []byte{
+ 0x0a, 0x1e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5f, 0x64, 0x65,
+ 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x12, 0x1c, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
+ 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x18,
+ 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5f, 0x63, 0x6f, 0x6d, 0x6d,
+ 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8e, 0x02, 0x0a, 0x19, 0x66, 0x6c, 0x61,
+ 0x67, 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x72,
+ 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61,
+ 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e,
+ 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63,
+ 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64,
+ 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x64, 0x65,
+ 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x50, 0x61, 0x74, 0x68, 0x12, 0x43, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f,
+ 0x77, 0x18, 0xcd, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f,
+ 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77,
+ 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x1f, 0x0a, 0x0a, 0x63, 0x6f,
+ 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0xce, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52,
+ 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10,
+ 0x05, 0x4a, 0x06, 0x08, 0xcf, 0x01, 0x10, 0xd0, 0x01, 0x22, 0x93, 0x01, 0x0a, 0x1a, 0x66, 0x6c,
+ 0x61, 0x67, 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61,
+ 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x75, 0x0a, 0x1a, 0x66, 0x6c, 0x61, 0x67,
+ 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x72, 0x74,
+ 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x61,
+ 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x66, 0x6c, 0x61, 0x67,
+ 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x72, 0x74,
+ 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x18, 0x66, 0x6c, 0x61, 0x67, 0x44, 0x65, 0x63, 0x6c, 0x61,
+ 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x42,
+ 0x33, 0x5a, 0x31, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67,
+ 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f,
+ 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f,
+}
+
+var (
+ file_build_flags_declarations_proto_rawDescOnce sync.Once
+ file_build_flags_declarations_proto_rawDescData = file_build_flags_declarations_proto_rawDesc
+)
+
+func file_build_flags_declarations_proto_rawDescGZIP() []byte {
+ file_build_flags_declarations_proto_rawDescOnce.Do(func() {
+ file_build_flags_declarations_proto_rawDescData = protoimpl.X.CompressGZIP(file_build_flags_declarations_proto_rawDescData)
+ })
+ return file_build_flags_declarations_proto_rawDescData
+}
+
+var file_build_flags_declarations_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_build_flags_declarations_proto_goTypes = []interface{}{
+ (*FlagDeclarationArtifact)(nil), // 0: android.release_config_proto.flag_declaration_artifact
+ (*FlagDeclarationArtifacts)(nil), // 1: android.release_config_proto.flag_declaration_artifacts
+ (Workflow)(0), // 2: android.release_config_proto.workflow
+}
+var file_build_flags_declarations_proto_depIdxs = []int32{
+ 2, // 0: android.release_config_proto.flag_declaration_artifact.workflow:type_name -> android.release_config_proto.workflow
+ 0, // 1: android.release_config_proto.flag_declaration_artifacts.flag_declaration_artifacts:type_name -> android.release_config_proto.flag_declaration_artifact
+ 2, // [2:2] is the sub-list for method output_type
+ 2, // [2:2] is the sub-list for method input_type
+ 2, // [2:2] is the sub-list for extension type_name
+ 2, // [2:2] is the sub-list for extension extendee
+ 0, // [0:2] is the sub-list for field type_name
+}
+
+func init() { file_build_flags_declarations_proto_init() }
+func file_build_flags_declarations_proto_init() {
+ if File_build_flags_declarations_proto != nil {
+ return
+ }
+ file_build_flags_common_proto_init()
+ if !protoimpl.UnsafeEnabled {
+ file_build_flags_declarations_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*FlagDeclarationArtifact); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_build_flags_declarations_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*FlagDeclarationArtifacts); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_build_flags_declarations_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 2,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_build_flags_declarations_proto_goTypes,
+ DependencyIndexes: file_build_flags_declarations_proto_depIdxs,
+ MessageInfos: file_build_flags_declarations_proto_msgTypes,
+ }.Build()
+ File_build_flags_declarations_proto = out.File
+ file_build_flags_declarations_proto_rawDesc = nil
+ file_build_flags_declarations_proto_goTypes = nil
+ file_build_flags_declarations_proto_depIdxs = nil
+}
diff --git a/cmd/release_config/release_config_proto/build_flags_declarations.proto b/cmd/release_config/release_config_proto/build_flags_declarations.proto
new file mode 100644
index 0000000..e0cf099
--- /dev/null
+++ b/cmd/release_config/release_config_proto/build_flags_declarations.proto
@@ -0,0 +1,75 @@
+//
+// Copyright (C) 2024 The Android Open-Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto2";
+package android.release_config_proto;
+option go_package = "android/soong/release_config/release_config_proto";
+
+import "build_flags_common.proto";
+
+// This protobuf file defines messages used to represent the
+// all_build_flag_declarations artifact for use in automated systems, such as
+// Gantry.
+//
+// The following format requirements apply across various message fields:
+//
+// # name: name of the flag
+//
+// format: an uppercase string in SNAKE_CASE format starting with RELEASE_,
+// no consecutive underscores, and no leading digit. For example
+// RELEASE_MY_PACKAGE_FLAG is a valid name, while MY_PACKAGE_FLAG, and
+// RELEASE_MY_PACKAGE__FLAG are invalid.
+//
+// # package: package to which the flag belongs
+//
+// format: lowercase strings in snake_case format, delimited by dots, no
+// consecutive underscores and no leading digit in each string. For example
+// com.android.mypackage is a valid name while com.android.myPackage,
+// com.android.1mypackage are invalid
+
+message flag_declaration_artifact {
+ // The name of the flag.
+ // See # name for format detail
+ optional string name = 1;
+
+ // Namespace the flag belongs to (required)
+ // See # namespace for format detail
+ optional string namespace = 2;
+
+ // Text description of the flag's purpose.
+ optional string description = 3;
+
+ // reserve this for bug, if needed.
+ reserved 4;
+
+ // Where the flag was declared.
+ optional string declaration_path = 5;
+
+ // Workflow for this flag.
+ optional workflow workflow = 205;
+
+ // The container for this flag. This overrides any default container given
+ // in the release_config_map message.
+ repeated string containers = 206;
+
+ // The package associated with this flag.
+ // (when Gantry is ready for it) optional string package = 207;
+ reserved 207;
+}
+
+message flag_declaration_artifacts {
+ // The artifacts
+ repeated flag_declaration_artifact flag_declaration_artifacts = 1;
+}
diff --git a/cmd/release_config/release_config_proto/build_flags_out.pb.go b/cmd/release_config/release_config_proto/build_flags_out.pb.go
index 73cc1dc..309ec34 100644
--- a/cmd/release_config/release_config_proto/build_flags_out.pb.go
+++ b/cmd/release_config/release_config_proto/build_flags_out.pb.go
@@ -15,7 +15,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.33.0
+// protoc-gen-go v1.30.0
// protoc v3.21.12
// source: build_flags_out.proto
@@ -226,6 +226,9 @@
// The release config directories used for this config.
// For example, "build/release".
Directories []string `protobuf:"bytes,6,rep,name=directories" json:"directories,omitempty"`
+ // Prior stage(s) for flag advancement (during development).
+ // Once a flag has met criteria in a prior stage, it can advance to this one.
+ PriorStages []string `protobuf:"bytes,7,rep,name=prior_stages,json=priorStages" json:"prior_stages,omitempty"`
}
func (x *ReleaseConfigArtifact) Reset() {
@@ -302,6 +305,13 @@
return nil
}
+func (x *ReleaseConfigArtifact) GetPriorStages() []string {
+ if x != nil {
+ return x.PriorStages
+ }
+ return nil
+}
+
type ReleaseConfigsArtifact struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -403,7 +413,7 @@
0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x2e, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74,
0x52, 0x0d, 0x66, 0x6c, 0x61, 0x67, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x22,
- 0x8e, 0x02, 0x0a, 0x17, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
+ 0xb1, 0x02, 0x0a, 0x17, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
0x1f, 0x0a, 0x0b, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02,
@@ -420,40 +430,43 @@
0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x73, 0x12, 0x20,
0x0a, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20,
0x03, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73,
- 0x22, 0xe8, 0x03, 0x0a, 0x18, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e,
- 0x66, 0x69, 0x67, 0x73, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x5c, 0x0a,
- 0x0e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e,
- 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e,
- 0x66, 0x69, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x0d, 0x72, 0x65,
- 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x69, 0x0a, 0x15, 0x6f,
- 0x74, 0x68, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e,
- 0x66, 0x69, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x61, 0x6e, 0x64,
- 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e,
- 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
- 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63,
- 0x74, 0x52, 0x13, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43,
- 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x87, 0x01, 0x0a, 0x17, 0x72, 0x65, 0x6c, 0x65, 0x61,
- 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6d, 0x61, 0x70, 0x73, 0x5f, 0x6d,
- 0x61, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x50, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f,
+ 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x67, 0x65, 0x73,
+ 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x53, 0x74, 0x61,
+ 0x67, 0x65, 0x73, 0x22, 0xe8, 0x03, 0x0a, 0x18, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f,
+ 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74,
+ 0x12, 0x5c, 0x0a, 0x0e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f,
0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f,
- 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74,
- 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4d, 0x61,
- 0x70, 0x73, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x14, 0x72, 0x65, 0x6c, 0x65,
- 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4d, 0x61, 0x70, 0x73, 0x4d, 0x61, 0x70,
- 0x1a, 0x79, 0x0a, 0x19, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x4d, 0x61, 0x70, 0x73, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
- 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
- 0x46, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30,
- 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65,
- 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65,
+ 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52,
+ 0x0d, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x69,
+ 0x0a, 0x15, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f,
+ 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e,
+ 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f,
+ 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x6c,
+ 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69,
+ 0x66, 0x61, 0x63, 0x74, 0x52, 0x13, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x6c, 0x65, 0x61,
+ 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x87, 0x01, 0x0a, 0x17, 0x72, 0x65,
0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6d, 0x61, 0x70,
- 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x33, 0x5a, 0x31, 0x61,
- 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x72, 0x65, 0x6c,
- 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65,
+ 0x73, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x50, 0x2e, 0x61, 0x6e,
+ 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61,
+ 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66,
+ 0x61, 0x63, 0x74, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x4d, 0x61, 0x70, 0x73, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x14, 0x72,
+ 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4d, 0x61, 0x70, 0x73,
+ 0x4d, 0x61, 0x70, 0x1a, 0x79, 0x0a, 0x19, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x4d, 0x61, 0x70, 0x73, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79,
+ 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
+ 0x65, 0x79, 0x12, 0x46, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x30, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65,
0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
+ 0x6d, 0x61, 0x70, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x33,
+ 0x5a, 0x31, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f,
+ 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x72,
+ 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f,
}
var (
diff --git a/cmd/release_config/release_config_proto/build_flags_out.proto b/cmd/release_config/release_config_proto/build_flags_out.proto
index 8c3be5f..0cbc157 100644
--- a/cmd/release_config/release_config_proto/build_flags_out.proto
+++ b/cmd/release_config/release_config_proto/build_flags_out.proto
@@ -83,6 +83,10 @@
// The release config directories used for this config.
// For example, "build/release".
repeated string directories = 6;
+
+ // Prior stage(s) for flag advancement (during development).
+ // Once a flag has met criteria in a prior stage, it can advance to this one.
+ repeated string prior_stages = 7;
}
message release_configs_artifact {
diff --git a/cmd/release_config/release_config_proto/build_flags_src.pb.go b/cmd/release_config/release_config_proto/build_flags_src.pb.go
index a538236..8de340e 100644
--- a/cmd/release_config/release_config_proto/build_flags_src.pb.go
+++ b/cmd/release_config/release_config_proto/build_flags_src.pb.go
@@ -15,7 +15,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.33.0
+// protoc-gen-go v1.30.0
// protoc v3.21.12
// source: build_flags_src.proto
@@ -35,73 +35,6 @@
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
-type Workflow int32
-
-const (
- Workflow_Workflow_Unspecified Workflow = 0
- // Boolean value flags that progress from false to true.
- Workflow_LAUNCH Workflow = 1
- // String value flags that get updated with new version strings to control
- // prebuilt inclusion.
- Workflow_PREBUILT Workflow = 2
- // Manually managed outside flags. These are likely to be found in a
- // different directory than flags with other workflows.
- Workflow_MANUAL Workflow = 3
-)
-
-// Enum value maps for Workflow.
-var (
- Workflow_name = map[int32]string{
- 0: "Workflow_Unspecified",
- 1: "LAUNCH",
- 2: "PREBUILT",
- 3: "MANUAL",
- }
- Workflow_value = map[string]int32{
- "Workflow_Unspecified": 0,
- "LAUNCH": 1,
- "PREBUILT": 2,
- "MANUAL": 3,
- }
-)
-
-func (x Workflow) Enum() *Workflow {
- p := new(Workflow)
- *p = x
- return p
-}
-
-func (x Workflow) String() string {
- return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
-}
-
-func (Workflow) Descriptor() protoreflect.EnumDescriptor {
- return file_build_flags_src_proto_enumTypes[0].Descriptor()
-}
-
-func (Workflow) Type() protoreflect.EnumType {
- return &file_build_flags_src_proto_enumTypes[0]
-}
-
-func (x Workflow) Number() protoreflect.EnumNumber {
- return protoreflect.EnumNumber(x)
-}
-
-// Deprecated: Do not use.
-func (x *Workflow) UnmarshalJSON(b []byte) error {
- num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
- if err != nil {
- return err
- }
- *x = Workflow(num)
- return nil
-}
-
-// Deprecated: Use Workflow.Descriptor instead.
-func (Workflow) EnumDescriptor() ([]byte, []int) {
- return file_build_flags_src_proto_rawDescGZIP(), []int{0}
-}
-
type Value struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -393,6 +326,9 @@
AconfigValueSets []string `protobuf:"bytes,3,rep,name=aconfig_value_sets,json=aconfigValueSets" json:"aconfig_value_sets,omitempty"`
// Only aconfig flags are allowed in this release config.
AconfigFlagsOnly *bool `protobuf:"varint,4,opt,name=aconfig_flags_only,json=aconfigFlagsOnly" json:"aconfig_flags_only,omitempty"`
+ // Prior stage(s) for flag advancement (during development).
+ // Once a flag has met criteria in a prior stage, it can advance to this one.
+ PriorStages []string `protobuf:"bytes,5,rep,name=prior_stages,json=priorStages" json:"prior_stages,omitempty"`
}
func (x *ReleaseConfig) Reset() {
@@ -455,6 +391,13 @@
return false
}
+func (x *ReleaseConfig) GetPriorStages() []string {
+ if x != nil {
+ return x.PriorStages
+ }
+ return nil
+}
+
// Any aliases. These are used for continuous integration builder config.
type ReleaseAlias struct {
state protoimpl.MessageState
@@ -586,75 +529,74 @@
0x0a, 0x15, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5f, 0x73, 0x72,
0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa5, 0x01, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12,
- 0x2e, 0x0a, 0x11, 0x75, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x76,
- 0x61, 0x6c, 0x75, 0x65, 0x18, 0xc8, 0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x10, 0x75,
- 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12,
- 0x24, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
- 0xc9, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
- 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x20, 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61,
- 0x6c, 0x75, 0x65, 0x18, 0xca, 0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f,
- 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1d, 0x0a, 0x08, 0x6f, 0x62, 0x73, 0x6f, 0x6c,
- 0x65, 0x74, 0x65, 0x18, 0xcb, 0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x08, 0x6f, 0x62,
- 0x73, 0x6f, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x05, 0x0a, 0x03, 0x76, 0x61, 0x6c, 0x22, 0x96, 0x02,
- 0x0a, 0x10, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70,
- 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73,
- 0x70, 0x61, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
- 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
- 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
- 0xc9, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
- 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c,
- 0x75, 0x65, 0x12, 0x43, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0xcd,
- 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e,
- 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x08, 0x77,
- 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x1f, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61,
- 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0xce, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f,
- 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x06,
- 0x08, 0xcf, 0x01, 0x10, 0xd0, 0x01, 0x22, 0x79, 0x0a, 0x0a, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x76,
- 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
- 0x65, 0x18, 0xc9, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f,
- 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76,
- 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1b, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x61, 0x63, 0x74, 0x65, 0x64,
- 0x18, 0xca, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x64, 0x61, 0x63, 0x74, 0x65,
- 0x64, 0x22, 0x9c, 0x01, 0x0a, 0x0e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f,
- 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x68, 0x65,
- 0x72, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6e, 0x68, 0x65,
- 0x72, 0x69, 0x74, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x61, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
- 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09,
- 0x52, 0x10, 0x61, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x65,
- 0x74, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x61, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x66, 0x6c,
- 0x61, 0x67, 0x73, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10,
- 0x61, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x4f, 0x6e, 0x6c, 0x79,
- 0x22, 0x3b, 0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x61,
- 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0xac, 0x01,
- 0x0a, 0x12, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
- 0x5f, 0x6d, 0x61, 0x70, 0x12, 0x45, 0x0a, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18,
- 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e,
- 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x61, 0x6c, 0x69,
- 0x61, 0x73, 0x52, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64,
- 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a,
- 0x12, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
- 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x64, 0x65, 0x66, 0x61, 0x75,
- 0x6c, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x2a, 0x4a, 0x0a, 0x08,
- 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x18, 0x0a, 0x14, 0x57, 0x6f, 0x72, 0x6b,
- 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64,
- 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x41, 0x55, 0x4e, 0x43, 0x48, 0x10, 0x01, 0x12, 0x0c,
- 0x0a, 0x08, 0x50, 0x52, 0x45, 0x42, 0x55, 0x49, 0x4c, 0x54, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06,
- 0x4d, 0x41, 0x4e, 0x55, 0x41, 0x4c, 0x10, 0x03, 0x42, 0x33, 0x5a, 0x31, 0x61, 0x6e, 0x64, 0x72,
- 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
- 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65,
- 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x18, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x66, 0x6c, 0x61,
+ 0x67, 0x73, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
+ 0xa5, 0x01, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2e, 0x0a, 0x11, 0x75, 0x6e, 0x73,
+ 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0xc8,
+ 0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x10, 0x75, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69,
+ 0x66, 0x69, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x24, 0x0a, 0x0c, 0x73, 0x74, 0x72,
+ 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0xc9, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12,
+ 0x20, 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0xca, 0x01,
+ 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75,
+ 0x65, 0x12, 0x1d, 0x0a, 0x08, 0x6f, 0x62, 0x73, 0x6f, 0x6c, 0x65, 0x74, 0x65, 0x18, 0xcb, 0x01,
+ 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x08, 0x6f, 0x62, 0x73, 0x6f, 0x6c, 0x65, 0x74, 0x65,
+ 0x42, 0x05, 0x0a, 0x03, 0x76, 0x61, 0x6c, 0x22, 0x96, 0x02, 0x0a, 0x10, 0x66, 0x6c, 0x61, 0x67,
+ 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04,
+ 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+ 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x20,
+ 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+ 0x12, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0xc9, 0x01, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x23, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61,
+ 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
+ 0x76, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x43, 0x0a, 0x08,
+ 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0xcd, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
+ 0x26, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
+ 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x77,
+ 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f,
+ 0x77, 0x12, 0x1f, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18,
+ 0xce, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
+ 0x72, 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x06, 0x08, 0xcf, 0x01, 0x10, 0xd0, 0x01,
+ 0x22, 0x79, 0x0a, 0x0a, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12,
+ 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
+ 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0xc9, 0x01, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c,
+ 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1b,
+ 0x0a, 0x08, 0x72, 0x65, 0x64, 0x61, 0x63, 0x74, 0x65, 0x64, 0x18, 0xca, 0x01, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x08, 0x72, 0x65, 0x64, 0x61, 0x63, 0x74, 0x65, 0x64, 0x22, 0xbf, 0x01, 0x0a, 0x0e,
+ 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12,
+ 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
+ 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x73, 0x18, 0x02,
+ 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x73, 0x12, 0x2c,
+ 0x0a, 0x12, 0x61, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f,
+ 0x73, 0x65, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x63, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x65, 0x74, 0x73, 0x12, 0x2c, 0x0a, 0x12,
+ 0x61, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5f, 0x6f, 0x6e,
+ 0x6c, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x61, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72,
+ 0x69, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x67, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09,
+ 0x52, 0x0b, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x67, 0x65, 0x73, 0x22, 0x3b, 0x0a,
+ 0x0d, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x12,
+ 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
+ 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0xac, 0x01, 0x0a, 0x12, 0x72,
+ 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6d, 0x61,
+ 0x70, 0x12, 0x45, 0x0a, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c,
+ 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x52,
+ 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63,
+ 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64,
+ 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x12, 0x64, 0x65,
+ 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73,
+ 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43,
+ 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x42, 0x33, 0x5a, 0x31, 0x61, 0x6e, 0x64,
+ 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61,
+ 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
+ 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
}
var (
@@ -669,22 +611,21 @@
return file_build_flags_src_proto_rawDescData
}
-var file_build_flags_src_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_build_flags_src_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_build_flags_src_proto_goTypes = []interface{}{
- (Workflow)(0), // 0: android.release_config_proto.workflow
- (*Value)(nil), // 1: android.release_config_proto.value
- (*FlagDeclaration)(nil), // 2: android.release_config_proto.flag_declaration
- (*FlagValue)(nil), // 3: android.release_config_proto.flag_value
- (*ReleaseConfig)(nil), // 4: android.release_config_proto.release_config
- (*ReleaseAlias)(nil), // 5: android.release_config_proto.release_alias
- (*ReleaseConfigMap)(nil), // 6: android.release_config_proto.release_config_map
+ (*Value)(nil), // 0: android.release_config_proto.value
+ (*FlagDeclaration)(nil), // 1: android.release_config_proto.flag_declaration
+ (*FlagValue)(nil), // 2: android.release_config_proto.flag_value
+ (*ReleaseConfig)(nil), // 3: android.release_config_proto.release_config
+ (*ReleaseAlias)(nil), // 4: android.release_config_proto.release_alias
+ (*ReleaseConfigMap)(nil), // 5: android.release_config_proto.release_config_map
+ (Workflow)(0), // 6: android.release_config_proto.workflow
}
var file_build_flags_src_proto_depIdxs = []int32{
- 1, // 0: android.release_config_proto.flag_declaration.value:type_name -> android.release_config_proto.value
- 0, // 1: android.release_config_proto.flag_declaration.workflow:type_name -> android.release_config_proto.workflow
- 1, // 2: android.release_config_proto.flag_value.value:type_name -> android.release_config_proto.value
- 5, // 3: android.release_config_proto.release_config_map.aliases:type_name -> android.release_config_proto.release_alias
+ 0, // 0: android.release_config_proto.flag_declaration.value:type_name -> android.release_config_proto.value
+ 6, // 1: android.release_config_proto.flag_declaration.workflow:type_name -> android.release_config_proto.workflow
+ 0, // 2: android.release_config_proto.flag_value.value:type_name -> android.release_config_proto.value
+ 4, // 3: android.release_config_proto.release_config_map.aliases:type_name -> android.release_config_proto.release_alias
4, // [4:4] is the sub-list for method output_type
4, // [4:4] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
@@ -697,6 +638,7 @@
if File_build_flags_src_proto != nil {
return
}
+ file_build_flags_common_proto_init()
if !protoimpl.UnsafeEnabled {
file_build_flags_src_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Value); i {
@@ -782,14 +724,13 @@
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_build_flags_src_proto_rawDesc,
- NumEnums: 1,
+ NumEnums: 0,
NumMessages: 6,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_build_flags_src_proto_goTypes,
DependencyIndexes: file_build_flags_src_proto_depIdxs,
- EnumInfos: file_build_flags_src_proto_enumTypes,
MessageInfos: file_build_flags_src_proto_msgTypes,
}.Build()
File_build_flags_src_proto = out.File
diff --git a/cmd/release_config/release_config_proto/build_flags_src.proto b/cmd/release_config/release_config_proto/build_flags_src.proto
index cb0d9d9..4fad478 100644
--- a/cmd/release_config/release_config_proto/build_flags_src.proto
+++ b/cmd/release_config/release_config_proto/build_flags_src.proto
@@ -17,6 +17,8 @@
package android.release_config_proto;
option go_package = "android/soong/release_config/release_config_proto";
+import "build_flags_common.proto";
+
// This protobuf file defines messages used to represent the build flags used by
// a release in a more human-editable form. It is used for on-disk files in the
// source tree.
@@ -42,21 +44,6 @@
// com.android.mypackage is a valid name while com.android.myPackage,
// com.android.1mypackage are invalid
-enum workflow {
- Workflow_Unspecified = 0;
-
- // Boolean value flags that progress from false to true.
- LAUNCH = 1;
-
- // String value flags that get updated with new version strings to control
- // prebuilt inclusion.
- PREBUILT = 2;
-
- // Manually managed outside flags. These are likely to be found in a
- // different directory than flags with other workflows.
- MANUAL = 3;
-}
-
message value {
oneof val {
bool unspecified_value = 200;
@@ -126,6 +113,10 @@
// Only aconfig flags are allowed in this release config.
optional bool aconfig_flags_only = 4;
+
+ // Prior stage(s) for flag advancement (during development).
+ // Once a flag has met criteria in a prior stage, it can advance to this one.
+ repeated string prior_stages = 5;
}
// Any aliases. These are used for continuous integration builder config.
diff --git a/cmd/release_config/release_config_proto/regen.sh b/cmd/release_config/release_config_proto/regen.sh
index 1846c4d..23e3115 100644
--- a/cmd/release_config/release_config_proto/regen.sh
+++ b/cmd/release_config/release_config_proto/regen.sh
@@ -1,3 +1,3 @@
#!/bin/bash
-aprotoc --go_out=paths=source_relative:. build_flags_src.proto build_flags_out.proto
+aprotoc --go_out=paths=source_relative:. build_flags_src.proto build_flags_out.proto build_flags_common.proto build_flags_declarations.proto
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index fe3f8f7..2d3156a 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -155,7 +155,6 @@
// Create a new trace file writer, making it log events to the log instance.
trace := tracer.New(log)
- defer trace.Close()
// Create a new Status instance, which manages action counts and event output channels.
stat := &status.Status{}
@@ -194,14 +193,29 @@
soongMetricsFile := filepath.Join(logsDir, c.logsPrefix+"soong_metrics")
rbeMetricsFile := filepath.Join(logsDir, c.logsPrefix+"rbe_metrics.pb")
soongBuildMetricsFile := filepath.Join(logsDir, c.logsPrefix+"soong_build_metrics.pb")
+ buildTraceFile := filepath.Join(logsDir, c.logsPrefix+"build.trace.gz")
metricsFiles := []string{
buildErrorFile, // build error strings
rbeMetricsFile, // high level metrics related to remote build execution.
soongMetricsFile, // high level metrics related to this build system.
soongBuildMetricsFile, // high level metrics related to soong build
+ buildTraceFile,
}
+ defer func() {
+ stat.Finish()
+ criticalPath.WriteToMetrics(met)
+ met.Dump(soongMetricsFile)
+ if !config.SkipMetricsUpload() {
+ build.UploadMetrics(buildCtx, config, c.simpleOutput, buildStarted, metricsFiles...)
+ }
+ }()
+
+ // This has to come after the metrics uploading function, so that
+ // build.trace.gz is closed and ready for upload.
+ defer trace.Close()
+
os.MkdirAll(logsDir, 0777)
log.SetOutput(filepath.Join(logsDir, c.logsPrefix+"soong.log"))
@@ -222,16 +236,7 @@
config = freshConfig()
}
- defer func() {
- stat.Finish()
- criticalPath.WriteToMetrics(met)
- met.Dump(soongMetricsFile)
- if !config.SkipMetricsUpload() {
- build.UploadMetrics(buildCtx, config, c.simpleOutput, buildStarted, metricsFiles...)
- }
- }()
c.run(buildCtx, config, args)
-
}
// This function must not modify config, since product config may cause us to recreate the config,
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index e168edc..fd3b27f 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -74,11 +74,11 @@
type prebuiltEtcProperties struct {
// Source file of this prebuilt. Can reference a genrule type module with the ":module" syntax.
// Mutually exclusive with srcs.
- Src *string `android:"path,arch_variant"`
+ Src proptools.Configurable[string] `android:"path,arch_variant,replace_instead_of_append"`
// Source files of this prebuilt. Can reference a genrule type module with the ":module" syntax.
// Mutually exclusive with src. When used, filename_from_src is set to true.
- Srcs []string `android:"path,arch_variant"`
+ Srcs proptools.Configurable[[]string] `android:"path,arch_variant"`
// Optional name for the installed file. If unspecified, name of the module is used as the file
// name. Only available when using a single source (src).
@@ -158,6 +158,8 @@
installDirPath android.InstallPath
additionalDependencies *android.Paths
+ usedSrcsProperty bool
+
makeClass string
}
@@ -247,10 +249,10 @@
}
func (p *PrebuiltEtc) SourceFilePath(ctx android.ModuleContext) android.Path {
- if len(p.properties.Srcs) > 0 {
+ if len(p.properties.Srcs.GetOrDefault(ctx, nil)) > 0 {
panic(fmt.Errorf("SourceFilePath not available on multi-source prebuilt %q", p.Name()))
}
- return android.PathForModuleSrc(ctx, proptools.String(p.properties.Src))
+ return android.PathForModuleSrc(ctx, p.properties.Src.GetOrDefault(ctx, ""))
}
func (p *PrebuiltEtc) InstallDirPath() android.InstallPath {
@@ -264,7 +266,7 @@
}
func (p *PrebuiltEtc) OutputFile() android.OutputPath {
- if len(p.properties.Srcs) > 0 {
+ if p.usedSrcsProperty {
panic(fmt.Errorf("OutputFile not available on multi-source prebuilt %q", p.Name()))
}
return p.outputFilePaths[0]
@@ -319,7 +321,9 @@
func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
var installs []installProperties
- if p.properties.Src != nil && len(p.properties.Srcs) > 0 {
+ srcProperty := p.properties.Src.Get(ctx)
+ srcsProperty := p.properties.Srcs.GetOrDefault(ctx, nil)
+ if srcProperty.IsPresent() && len(srcsProperty) > 0 {
ctx.PropertyErrorf("src", "src is set. Cannot set srcs")
}
@@ -331,8 +335,8 @@
filename := proptools.String(p.properties.Filename)
filenameFromSrc := proptools.Bool(p.properties.Filename_from_src)
- if p.properties.Src != nil {
- p.sourceFilePaths = android.PathsForModuleSrc(ctx, []string{proptools.String(p.properties.Src)})
+ if srcProperty.IsPresent() {
+ p.sourceFilePaths = android.PathsForModuleSrc(ctx, []string{srcProperty.Get()})
// If the source was not found, set a fake source path to
// support AllowMissingDependencies executions.
if len(p.sourceFilePaths) == 0 {
@@ -367,7 +371,8 @@
symlinks: p.properties.Symlinks,
}
installs = append(installs, ip)
- } else if len(p.properties.Srcs) > 0 {
+ } else if len(srcsProperty) > 0 {
+ p.usedSrcsProperty = true
if filename != "" {
ctx.PropertyErrorf("filename", "filename cannot be set when using srcs")
}
@@ -377,7 +382,7 @@
if p.properties.Filename_from_src != nil {
ctx.PropertyErrorf("filename_from_src", "filename_from_src is implicitly set to true when using srcs")
}
- p.sourceFilePaths = android.PathsForModuleSrc(ctx, p.properties.Srcs)
+ p.sourceFilePaths = android.PathsForModuleSrc(ctx, srcsProperty)
for _, src := range p.sourceFilePaths {
filename := src.Base()
output := android.PathForModuleOut(ctx, filename).OutputPath
diff --git a/genrule/genrule.go b/genrule/genrule.go
index dd980cb..26dad01 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -126,7 +126,7 @@
// $(out): a single output file.
// $(genDir): the sandbox directory for this tool; contains $(out).
// $$: a literal $
- Cmd *string
+ Cmd proptools.Configurable[string] `android:"replace_instead_of_append"`
// name of the modules (if any) that produces the host executable. Leave empty for
// prebuilts or scripts that do not need a module to build them.
@@ -403,7 +403,7 @@
var outputFiles android.WritablePaths
var zipArgs strings.Builder
- cmd := String(g.properties.Cmd)
+ cmd := g.properties.Cmd.GetOrDefault(ctx, "")
if g.CmdModifier != nil {
cmd = g.CmdModifier(ctx, cmd)
}
diff --git a/go.mod b/go.mod
index 1174958..13834fc 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
module android/soong
-go 1.21
+go 1.22
require (
github.com/google/blueprint v0.0.0
diff --git a/go.work b/go.work
index 7c6022b..9a7e6db 100644
--- a/go.work
+++ b/go.work
@@ -1,4 +1,4 @@
-go 1.21
+go 1.22
use (
.
diff --git a/java/app.go b/java/app.go
index d2f2d0b..a24099c 100644
--- a/java/app.go
+++ b/java/app.go
@@ -1380,6 +1380,8 @@
HostRequiredModuleNames: a.HostRequiredModuleNames(),
TestSuites: a.testProperties.Test_suites,
IsHost: false,
+ LocalCertificate: a.certificate.AndroidMkString(),
+ IsUnitTest: Bool(a.testProperties.Test_options.Unit_test),
})
android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
TestOnly: true,
diff --git a/java/base.go b/java/base.go
index d04e97c..b4f800b 100644
--- a/java/base.go
+++ b/java/base.go
@@ -716,11 +716,7 @@
apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
isJacocoAgent := ctx.ModuleName() == "jacocoagent"
- isApexVariantSdkLibImplLib := j.SdkLibraryName() != nil &&
- strings.HasSuffix(j.Name(), ".impl") &&
- len(apexInfo.InApexVariants) > 0
-
- if (j.DirectlyInAnyApex() || isApexVariantSdkLibImplLib) && !isJacocoAgent && !apexInfo.IsForPlatform() {
+ if j.DirectlyInAnyApex() && !isJacocoAgent && !apexInfo.IsForPlatform() {
if !inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
return true
} else if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
@@ -1654,11 +1650,28 @@
classesJar: implementationAndResourcesJar,
jarName: jarName,
}
- dexOutputFile = j.dexer.compileDex(ctx, params)
+ if j.GetProfileGuided() && j.optimizeOrObfuscateEnabled() && !j.EnableProfileRewriting() {
+ ctx.PropertyErrorf("enable_profile_rewriting",
+ "Enable_profile_rewriting must be true when profile_guided dexpreopt and R8 optimization/obfuscation is turned on. The attached profile should be sourced from an unoptimized/unobfuscated APK.",
+ )
+ }
+ if j.EnableProfileRewriting() {
+ profile := j.GetProfile()
+ if profile == "" || !j.GetProfileGuided() {
+ ctx.PropertyErrorf("enable_profile_rewriting", "Profile and Profile_guided must be set when enable_profile_rewriting is true")
+ }
+ params.artProfileInput = &profile
+ }
+ dexOutputFile, dexArtProfileOutput := j.dexer.compileDex(ctx, params)
if ctx.Failed() {
return
}
+ // If r8/d8 provides a profile that matches the optimized dex, use that for dexpreopt.
+ if dexArtProfileOutput != nil {
+ j.dexpreopter.SetRewrittenProfile(*dexArtProfileOutput)
+ }
+
// merge dex jar with resources if necessary
if j.resourceJar != nil {
jars := android.Paths{dexOutputFile, j.resourceJar}
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index 4d3d794..16209b7 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -524,10 +524,16 @@
}
// Bootclasspath fragment modules that are for the platform do not produce boot related files.
- apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
- for _, apex := range apexInfo.InApexVariants {
- if isProfileProviderApex(ctx, apex) {
- return apex
+ apexInfos, _ := android.ModuleProvider(ctx, android.AllApexInfoProvider)
+ if apexInfos == nil {
+ return ""
+ }
+
+ for _, apexInfo := range apexInfos.ApexInfos {
+ for _, apex := range apexInfo.InApexVariants {
+ if isProfileProviderApex(ctx, apex) {
+ return apex
+ }
}
}
diff --git a/java/dex.go b/java/dex.go
index 8cfffaf..32546d9 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -119,6 +119,10 @@
return d.resourceShrinkingEnabled(ctx) && Bool(d.Optimize.Optimized_shrink_resources)
}
+func (d *dexer) optimizeOrObfuscateEnabled() bool {
+ return d.effectiveOptimizeEnabled() && (proptools.Bool(d.dexProperties.Optimize.Optimize) || proptools.Bool(d.dexProperties.Optimize.Obfuscate))
+}
+
var d8, d8RE = pctx.MultiCommandRemoteStaticRules("d8",
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
@@ -253,17 +257,25 @@
return flags, deps
}
-func d8Flags(flags javaBuilderFlags) (d8Flags []string, d8Deps android.Paths) {
+func (d *dexer) d8Flags(ctx android.ModuleContext, dexParams *compileDexParams) (d8Flags []string, d8Deps android.Paths, artProfileOutput *android.OutputPath) {
+ flags := dexParams.flags
d8Flags = append(d8Flags, flags.bootClasspath.FormRepeatedClassPath("--lib ")...)
d8Flags = append(d8Flags, flags.dexClasspath.FormRepeatedClassPath("--lib ")...)
d8Deps = append(d8Deps, flags.bootClasspath...)
d8Deps = append(d8Deps, flags.dexClasspath...)
- return d8Flags, d8Deps
+ if flags, deps, profileOutput := d.addArtProfile(ctx, dexParams); profileOutput != nil {
+ d8Flags = append(d8Flags, flags...)
+ d8Deps = append(d8Deps, deps...)
+ artProfileOutput = profileOutput
+ }
+
+ return d8Flags, d8Deps, artProfileOutput
}
-func (d *dexer) r8Flags(ctx android.ModuleContext, flags javaBuilderFlags) (r8Flags []string, r8Deps android.Paths) {
+func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams) (r8Flags []string, r8Deps android.Paths, artProfileOutput *android.OutputPath) {
+ flags := dexParams.flags
opt := d.dexProperties.Optimize
// When an app contains references to APIs that are not in the SDK specified by
@@ -375,18 +387,44 @@
}
}
- return r8Flags, r8Deps
+ if flags, deps, profileOutput := d.addArtProfile(ctx, dexParams); profileOutput != nil {
+ r8Flags = append(r8Flags, flags...)
+ r8Deps = append(r8Deps, deps...)
+ artProfileOutput = profileOutput
+ }
+
+ return r8Flags, r8Deps, artProfileOutput
}
type compileDexParams struct {
- flags javaBuilderFlags
- sdkVersion android.SdkSpec
- minSdkVersion android.ApiLevel
- classesJar android.Path
- jarName string
+ flags javaBuilderFlags
+ sdkVersion android.SdkSpec
+ minSdkVersion android.ApiLevel
+ classesJar android.Path
+ jarName string
+ artProfileInput *string
}
-func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParams) android.OutputPath {
+// Adds --art-profile to r8/d8 command.
+// r8/d8 will output a generated profile file to match the optimized dex code.
+func (d *dexer) addArtProfile(ctx android.ModuleContext, dexParams *compileDexParams) (flags []string, deps android.Paths, artProfileOutputPath *android.OutputPath) {
+ if dexParams.artProfileInput != nil {
+ artProfileInputPath := android.PathForModuleSrc(ctx, *dexParams.artProfileInput)
+ artProfileOutputPathValue := android.PathForModuleOut(ctx, "profile.prof.txt").OutputPath
+ artProfileOutputPath = &artProfileOutputPathValue
+ flags = []string{
+ "--art-profile",
+ artProfileInputPath.String(),
+ artProfileOutputPath.String(),
+ }
+ deps = append(deps, artProfileInputPath)
+ }
+ return flags, deps, artProfileOutputPath
+
+}
+
+// Return the compiled dex jar and (optional) profile _after_ r8 optimization
+func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParams) (android.OutputPath, *android.OutputPath) {
// Compile classes.jar into classes.dex and then javalib.jar
javalibJar := android.PathForModuleOut(ctx, "dex", dexParams.jarName).OutputPath
@@ -406,6 +444,7 @@
}
useR8 := d.effectiveOptimizeEnabled()
+ var artProfileOutputPath *android.OutputPath
if useR8 {
proguardDictionary := android.PathForModuleOut(ctx, "proguard_dictionary")
d.proguardDictionary = android.OptionalPathForPath(proguardDictionary)
@@ -418,8 +457,19 @@
d.proguardUsageZip = android.OptionalPathForPath(proguardUsageZip)
resourcesOutput := android.PathForModuleOut(ctx, "package-res-shrunken.apk")
d.resourcesOutput = android.OptionalPathForPath(resourcesOutput)
- r8Flags, r8Deps := d.r8Flags(ctx, dexParams.flags)
- r8Deps = append(r8Deps, commonDeps...)
+ implicitOutputs := android.WritablePaths{
+ proguardDictionary,
+ proguardUsageZip,
+ proguardConfiguration,
+ }
+ r8Flags, r8Deps, r8ArtProfileOutputPath := d.r8Flags(ctx, dexParams)
+ if r8ArtProfileOutputPath != nil {
+ artProfileOutputPath = r8ArtProfileOutputPath
+ implicitOutputs = append(
+ implicitOutputs,
+ artProfileOutputPath,
+ )
+ }
rule := r8
args := map[string]string{
"r8Flags": strings.Join(append(commonFlags, r8Flags...), " "),
@@ -436,10 +486,6 @@
rule = r8RE
args["implicits"] = strings.Join(r8Deps.Strings(), ",")
}
- implicitOutputs := android.WritablePaths{
- proguardDictionary,
- proguardUsageZip,
- proguardConfiguration}
if d.resourcesInput.Valid() {
implicitOutputs = append(implicitOutputs, resourcesOutput)
args["resourcesOutput"] = resourcesOutput.String()
@@ -454,18 +500,27 @@
Args: args,
})
} else {
- d8Flags, d8Deps := d8Flags(dexParams.flags)
+ implicitOutputs := android.WritablePaths{}
+ d8Flags, d8Deps, d8ArtProfileOutputPath := d.d8Flags(ctx, dexParams)
+ if d8ArtProfileOutputPath != nil {
+ artProfileOutputPath = d8ArtProfileOutputPath
+ implicitOutputs = append(
+ implicitOutputs,
+ artProfileOutputPath,
+ )
+ }
d8Deps = append(d8Deps, commonDeps...)
rule := d8
if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_D8") {
rule = d8RE
}
ctx.Build(pctx, android.BuildParams{
- Rule: rule,
- Description: "d8",
- Output: javalibJar,
- Input: dexParams.classesJar,
- Implicits: d8Deps,
+ Rule: rule,
+ Description: "d8",
+ Output: javalibJar,
+ Input: dexParams.classesJar,
+ ImplicitOutputs: implicitOutputs,
+ Implicits: d8Deps,
Args: map[string]string{
"d8Flags": strings.Join(append(commonFlags, d8Flags...), " "),
"zipFlags": zipFlags,
@@ -480,5 +535,5 @@
javalibJar = alignedJavalibJar
}
- return javalibJar
+ return javalibJar, artProfileOutputPath
}
diff --git a/java/dex_test.go b/java/dex_test.go
index 1ecdae0..4862d06 100644
--- a/java/dex_test.go
+++ b/java/dex_test.go
@@ -662,3 +662,54 @@
android.AssertStringDoesContain(t, "expected aarimports's proguard flags",
appR8.Args["r8Flags"], "proguard.txt")
}
+
+func TestR8FlagsArtProfile(t *testing.T) {
+ result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
+ android_app {
+ name: "app",
+ srcs: ["foo.java"],
+ platform_apis: true,
+ dex_preopt: {
+ profile_guided: true,
+ profile: "profile.txt.prof",
+ enable_profile_rewriting: true,
+ },
+ }
+ `)
+
+ app := result.ModuleForTests("app", "android_common")
+ appR8 := app.Rule("r8")
+ android.AssertStringDoesContain(t, "expected --art-profile in app r8 flags",
+ appR8.Args["r8Flags"], "--art-profile")
+
+ appDexpreopt := app.Rule("dexpreopt")
+ android.AssertStringDoesContain(t,
+ "expected --art-profile output to be used to create .prof binary",
+ appDexpreopt.RuleParams.Command,
+ "--create-profile-from=out/soong/.intermediates/app/android_common/profile.prof.txt --output-profile-type=app",
+ )
+}
+
+// This test checks that users explicitly set `enable_profile_rewriting` to true when the following are true
+// 1. optimize or obfuscate is enabled AND
+// 2. dex_preopt.profile_guided is enabled
+//
+// The rewritten profile should be used since the dex signatures in the checked-in profile will not match the optimized binary.
+func TestEnableProfileRewritingIsRequiredForOptimizedApps(t *testing.T) {
+ testJavaError(t,
+ "Enable_profile_rewriting must be true when profile_guided dexpreopt and R8 optimization/obfuscation is turned on",
+ `
+android_app {
+ name: "app",
+ srcs: ["foo.java"],
+ platform_apis: true,
+ dex_preopt: {
+ profile_guided: true,
+ profile: "profile.txt.prof",
+ // enable_profile_rewriting is not set, this is an error
+ },
+ optimize: {
+ optimize: true,
+ }
+}`)
+}
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 4d6dbff..832b850 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -19,6 +19,8 @@
"sort"
"strings"
+ "github.com/google/blueprint/proptools"
+
"android/soong/android"
"android/soong/dexpreopt"
)
@@ -139,6 +141,10 @@
// The path to the profile that dexpreopter accepts. It must be in the binary format. If this is
// set, it overrides the profile settings in `dexpreoptProperties`.
inputProfilePathOnHost android.Path
+
+ // The path to the profile that matches the dex optimized by r8/d8. It is in text format. If this is
+ // set, it will be converted to a binary profile which will be subsequently used for dexpreopt.
+ rewrittenProfile android.Path
}
type DexpreoptProperties struct {
@@ -158,6 +164,11 @@
// defaults to searching for a file that matches the name of this module in the default
// profile location set by PRODUCT_DEX_PREOPT_PROFILE_DIR, or empty if not found.
Profile *string `android:"path"`
+
+ // If set to true, r8/d8 will use `profile` as input to generate a new profile that matches
+ // the optimized dex.
+ // The new profile will be subsequently used as the profile to dexpreopt the dex file.
+ Enable_profile_rewriting *bool
}
Dex_preopt_result struct {
@@ -421,13 +432,17 @@
if d.inputProfilePathOnHost != nil {
profileClassListing = android.OptionalPathForPath(d.inputProfilePathOnHost)
} else if BoolDefault(d.dexpreoptProperties.Dex_preopt.Profile_guided, true) && !forPrebuiltApex(ctx) {
- // If dex_preopt.profile_guided is not set, default it based on the existence of the
- // dexprepot.profile option or the profile class listing.
- if String(d.dexpreoptProperties.Dex_preopt.Profile) != "" {
+ // If enable_profile_rewriting is set, use the rewritten profile instead of the checked-in profile
+ if d.EnableProfileRewriting() {
+ profileClassListing = android.OptionalPathForPath(d.GetRewrittenProfile())
+ profileIsTextListing = true
+ } else if profile := d.GetProfile(); profile != "" {
+ // If dex_preopt.profile_guided is not set, default it based on the existence of the
+ // dexprepot.profile option or the profile class listing.
profileClassListing = android.OptionalPathForPath(
- android.PathForModuleSrc(ctx, String(d.dexpreoptProperties.Dex_preopt.Profile)))
+ android.PathForModuleSrc(ctx, profile))
profileBootListing = android.ExistentPathForSource(ctx,
- ctx.ModuleDir(), String(d.dexpreoptProperties.Dex_preopt.Profile)+"-boot")
+ ctx.ModuleDir(), profile+"-boot")
profileIsTextListing = true
} else if global.ProfileDir != "" {
profileClassListing = android.ExistentPathForSource(ctx,
@@ -588,3 +603,23 @@
func (d *dexpreopter) disableDexpreopt() {
d.shouldDisableDexpreopt = true
}
+
+func (d *dexpreopter) EnableProfileRewriting() bool {
+ return proptools.Bool(d.dexpreoptProperties.Dex_preopt.Enable_profile_rewriting)
+}
+
+func (d *dexpreopter) GetProfile() string {
+ return proptools.String(d.dexpreoptProperties.Dex_preopt.Profile)
+}
+
+func (d *dexpreopter) GetProfileGuided() bool {
+ return proptools.Bool(d.dexpreoptProperties.Dex_preopt.Profile_guided)
+}
+
+func (d *dexpreopter) GetRewrittenProfile() android.Path {
+ return d.rewrittenProfile
+}
+
+func (d *dexpreopter) SetRewrittenProfile(p android.Path) {
+ d.rewrittenProfile = p
+}
diff --git a/java/droidstubs.go b/java/droidstubs.go
index ca81343..5ca6c25 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -993,6 +993,7 @@
func (d *Droidstubs) everythingOptionalCmd(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, doApiLint bool, doCheckReleased bool) {
// Add API lint options.
+ treatDocumentationIssuesAsErrors := false
if doApiLint {
var newSince android.Paths
if d.properties.Check_api.Api_lint.New_since != nil {
@@ -1006,7 +1007,7 @@
// TODO(b/154317059): Clean up this allowlist by baselining and/or checking in last-released.
if d.Name() != "android.car-system-stubs-docs" &&
d.Name() != "android.car-stubs-docs" {
- cmd.Flag("--lints-as-errors")
+ treatDocumentationIssuesAsErrors = true
cmd.Flag("--warnings-as-errors") // Most lints are actually warnings.
}
@@ -1052,6 +1053,11 @@
cmd.FlagWithArg("--error-message:api-lint ", msg)
}
+ if !treatDocumentationIssuesAsErrors {
+ // Treat documentation issues as warnings, but error when new.
+ cmd.Flag("--error-when-new-category").Flag("Documentation")
+ }
+
// Add "check released" options. (Detect incompatible API changes from the last public release)
if doCheckReleased {
baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
@@ -1147,6 +1153,9 @@
}
}
+ // Treat documentation issues as warnings, but error when new.
+ cmd.Flag("--error-when-new-category").Flag("Documentation")
+
if params.stubConfig.generateStubs {
rule.Command().
BuiltTool("soong_zip").
diff --git a/java/java.go b/java/java.go
index e3f4824..ccccbac 100644
--- a/java/java.go
+++ b/java/java.go
@@ -567,6 +567,12 @@
return normalizeJavaVersion(ctx, javaVersion)
} else if ctx.Device() {
return defaultJavaLanguageVersion(ctx, sdkContext.SdkVersion(ctx))
+ } else if ctx.Config().TargetsJava21() {
+ // Temporary experimental flag to be able to try and build with
+ // java version 21 options. The flag, if used, just sets Java
+ // 21 as the default version, leaving any components that
+ // target an older version intact.
+ return JAVA_VERSION_21
} else {
return JAVA_VERSION_17
}
@@ -1498,6 +1504,8 @@
RequiredModuleNames: j.RequiredModuleNames(),
TestSuites: j.testProperties.Test_suites,
IsHost: true,
+ LocalSdkVersion: j.sdkVersion.String(),
+ IsUnitTest: Bool(j.testProperties.Test_options.Unit_test),
})
}
@@ -2333,7 +2341,7 @@
classesJar: al.stubsJar,
jarName: ctx.ModuleName() + ".jar",
}
- dexOutputFile := al.dexer.compileDex(ctx, dexParams)
+ dexOutputFile, _ := al.dexer.compileDex(ctx, dexParams)
uncompressed := true
al.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), al.stubsJar, &uncompressed)
dexOutputFile = al.hiddenAPIEncodeDex(ctx, dexOutputFile)
@@ -2717,7 +2725,7 @@
jarName: jarName,
}
- dexOutputFile = j.dexer.compileDex(ctx, dexParams)
+ dexOutputFile, _ = j.dexer.compileDex(ctx, dexParams)
if ctx.Failed() {
return
}
diff --git a/java/sdk.go b/java/sdk.go
index d972c19..4ef4ee2 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -65,6 +65,12 @@
return JAVA_VERSION_9
} else if sdk.FinalOrFutureInt() <= 33 {
return JAVA_VERSION_11
+ } else if ctx.Config().TargetsJava21() {
+ // Temporary experimental flag to be able to try and build with
+ // java version 21 options. The flag, if used, just sets Java
+ // 21 as the default version, leaving any components that
+ // target an older version intact.
+ return JAVA_VERSION_21
} else {
return JAVA_VERSION_17
}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 8c91288..72eb6e3 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1506,6 +1506,12 @@
var _ android.InstallNeededDependencyTag = sdkLibraryComponentTag{}
+// To satisfy the CopyDirectlyInAnyApexTag interface. Implementation library of the sdk library
+// in an apex is considered to be directly in the apex, as if it was listed in java_libs.
+func (t sdkLibraryComponentTag) CopyDirectlyInAnyApex() {}
+
+var _ android.CopyDirectlyInAnyApexTag = implLibraryTag
+
func (t sdkLibraryComponentTag) InstallDepNeeded() bool {
return t.name == "xml-permissions-file" || t.name == "impl-library"
}
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index d240e70..39f8c76 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -492,7 +492,7 @@
PrepareForTestWithJavaSdkLibraryFiles,
FixtureWithLastReleaseApis("foo"),
).
- ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": path dependency ":foo{.public.annotations.zip}": annotations.zip not available for api scope public`)).
+ ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": failed to get output file from module "foo" at tag ".public.annotations.zip": annotations.zip not available for api scope public`)).
RunTestWithBp(t, `
java_sdk_library {
name: "foo",
diff --git a/rust/compiler.go b/rust/compiler.go
index efc3dee..a2546a1 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -197,7 +197,7 @@
Features []string `android:"arch_variant"`
// list of configuration options to enable for this crate. To enable features, use the "features" property.
- Cfgs []string `android:"arch_variant"`
+ Cfgs proptools.Configurable[[]string] `android:"arch_variant"`
// specific rust edition that should be used if the default version is not desired
Edition *string `android:"arch_variant"`
@@ -338,7 +338,7 @@
}
func cfgsToFlags(cfgs []string) []string {
- flags := []string{}
+ flags := make([]string, 0, len(cfgs))
for _, cfg := range cfgs {
flags = append(flags, "--cfg '"+cfg+"'")
}
@@ -385,8 +385,9 @@
func (compiler *baseCompiler) cfgFlags(ctx ModuleContext, flags Flags) Flags {
flags = CommonDefaultCfgFlags(flags, ctx.RustModule().InVendor(), ctx.RustModule().InProduct())
- flags.RustFlags = append(flags.RustFlags, cfgsToFlags(compiler.Properties.Cfgs)...)
- flags.RustdocFlags = append(flags.RustdocFlags, cfgsToFlags(compiler.Properties.Cfgs)...)
+ cfgFlags := cfgsToFlags(compiler.Properties.Cfgs.GetOrDefault(ctx, nil))
+ flags.RustFlags = append(flags.RustFlags, cfgFlags...)
+ flags.RustdocFlags = append(flags.RustdocFlags, cfgFlags...)
return flags
}
diff --git a/rust/library.go b/rust/library.go
index 1eb0c5e..2a21263 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -504,15 +504,19 @@
flags = library.baseCompiler.cfgFlags(ctx, flags)
flags = CommonLibraryCfgFlags(ctx, flags)
+ cfgs := library.baseCompiler.Properties.Cfgs.GetOrDefault(ctx, nil)
+
if library.dylib() {
// We need to add a dependency on std in order to link crates as dylibs.
// The hack to add this dependency is guarded by the following cfg so
// that we don't force a dependency when it isn't needed.
- library.baseCompiler.Properties.Cfgs = append(library.baseCompiler.Properties.Cfgs, "android_dylib")
+ cfgs = append(cfgs, "android_dylib")
}
- flags.RustFlags = append(flags.RustFlags, cfgsToFlags(library.baseCompiler.Properties.Cfgs)...)
- flags.RustdocFlags = append(flags.RustdocFlags, cfgsToFlags(library.baseCompiler.Properties.Cfgs)...)
+ cfgFlags := cfgsToFlags(cfgs)
+
+ flags.RustFlags = append(flags.RustFlags, cfgFlags...)
+ flags.RustdocFlags = append(flags.RustdocFlags, cfgFlags...)
return flags
}
diff --git a/rust/rust.go b/rust/rust.go
index 93853e5..5790dd6 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -341,10 +341,6 @@
return Bool(mod.Properties.Bootstrap)
}
-func (mod *Module) MustUseVendorVariant() bool {
- return true
-}
-
func (mod *Module) SubName() string {
return mod.Properties.SubName
}
diff --git a/tradefed/providers.go b/tradefed/providers.go
index 66cb625..0abac12 100644
--- a/tradefed/providers.go
+++ b/tradefed/providers.go
@@ -6,7 +6,8 @@
"github.com/google/blueprint"
)
-// Output files we need from a base test that we derive from.
+// Data that test_module_config[_host] modules types will need from
+// their dependencies to write out build rules and AndroidMkEntries.
type BaseTestProviderData struct {
// data files and apps for android_test
InstalledFiles android.Paths
@@ -19,8 +20,14 @@
RequiredModuleNames []string
// List of test suites base uses.
TestSuites []string
- // Used for bases that are Host
+ // True indicates the base modules is built for Host.
IsHost bool
+ // Base's sdk version for AndroidMkEntries, generally only used for Host modules.
+ LocalSdkVersion string
+ // Base's certificate for AndroidMkEntries, generally only used for device modules.
+ LocalCertificate string
+ // Indicates if the base module was a unit test.
+ IsUnitTest bool
}
var BaseTestProviderKey = blueprint.NewProvider[BaseTestProviderData]()
diff --git a/tradefed_modules/test_module_config.go b/tradefed_modules/test_module_config.go
index b2d5631..f9622d3 100644
--- a/tradefed_modules/test_module_config.go
+++ b/tradefed_modules/test_module_config.go
@@ -5,6 +5,8 @@
"android/soong/tradefed"
"encoding/json"
"fmt"
+ "io"
+ "strings"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -23,14 +25,17 @@
type testModuleConfigModule struct {
android.ModuleBase
android.DefaultableModuleBase
- base android.Module
tradefedProperties
// Our updated testConfig.
testConfig android.OutputPath
- manifest android.InstallPath
+ manifest android.OutputPath
provider tradefed.BaseTestProviderData
+
+ supportFiles android.InstallPaths
+
+ isHost bool
}
// Host is mostly the same as non-host, just some diffs for AddDependency and
@@ -94,7 +99,6 @@
// Takes base's Tradefed Config xml file and generates a new one with the test properties
// appeneded from this module.
-// Rewrite the name of the apk in "test-file-name" to be our module's name, rather than the original one.
func (m *testModuleConfigModule) fixTestConfig(ctx android.ModuleContext, baseTestConfig android.Path) android.OutputPath {
// Test safe to do when no test_runner_options, but check for that earlier?
fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", ctx.ModuleName()+".config")
@@ -106,9 +110,8 @@
}
xmlTestModuleConfigSnippet, _ := json.Marshal(options)
escaped := proptools.NinjaAndShellEscape(string(xmlTestModuleConfigSnippet))
- command.FlagWithArg("--test-file-name=", ctx.ModuleName()+".apk").
- FlagWithArg("--orig-test-file-name=", *m.tradefedProperties.Base+".apk").
- FlagWithArg("--test-runner-options=", escaped)
+ command.FlagWithArg("--test-runner-options=", escaped)
+
rule.Build("fix_test_config", "fix test config")
return fixedConfig.OutputPath
}
@@ -190,6 +193,7 @@
module.AddProperties(&module.tradefedProperties)
android.InitAndroidMultiTargetsArchModule(module, android.HostSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
+ module.isHost = true
return module
}
@@ -198,39 +202,66 @@
var _ android.AndroidMkEntriesProvider = (*testModuleConfigModule)(nil)
func (m *testModuleConfigModule) AndroidMkEntries() []android.AndroidMkEntries {
- // We rely on base writing LOCAL_COMPATIBILITY_SUPPORT_FILES for its data files
- entriesList := m.base.(android.AndroidMkEntriesProvider).AndroidMkEntries()
- entries := &entriesList[0]
- entries.OutputFile = android.OptionalPathForPath(m.provider.OutputFile)
- entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE", m.Name()) // out module name, not base's
+ appClass := "APPS"
+ include := "$(BUILD_SYSTEM)/soong_app_prebuilt.mk"
+ if m.isHost {
+ appClass = "JAVA_LIBRARIES"
+ include = "$(BUILD_SYSTEM)/soong_java_prebuilt.mk"
+ }
+ return []android.AndroidMkEntries{{
+ Class: appClass,
+ OutputFile: android.OptionalPathForPath(m.manifest),
+ Include: include,
+ Required: []string{*m.Base},
+ ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+ entries.SetPath("LOCAL_FULL_TEST_CONFIG", m.testConfig)
+ entries.SetString("LOCAL_MODULE_TAGS", "tests")
+ entries.SetString("LOCAL_TEST_MODULE_CONFIG_BASE", *m.Base)
+ if m.provider.LocalSdkVersion != "" {
+ entries.SetString("LOCAL_SDK_VERSION", m.provider.LocalSdkVersion)
+ }
+ if m.provider.LocalCertificate != "" {
+ entries.SetString("LOCAL_CERTIFICATE", m.provider.LocalCertificate)
+ }
- // Out update config file with extra options.
- entries.SetPath("LOCAL_FULL_TEST_CONFIG", m.testConfig)
- entries.SetString("LOCAL_MODULE_TAGS", "tests")
+ entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", m.provider.IsUnitTest)
+ entries.AddCompatibilityTestSuites(m.tradefedProperties.Test_suites...)
- // Don't append to base's test-suites, only use the ones we define, so clear it before
- // appending to it.
- entries.SetString("LOCAL_COMPATIBILITY_SUITE", "")
- entries.AddCompatibilityTestSuites(m.tradefedProperties.Test_suites...)
+ // The app_prebuilt_internal.mk files try create a copy of the OutputFile as an .apk.
+ // Normally, this copies the "package.apk" from the intermediate directory here.
+ // To prevent the copy of the large apk and to prevent confusion with the real .apk we
+ // link to, we set the STEM here to a bogus name and we set OutputFile to a small file (our manifest).
+ // We do this so we don't have to add more conditionals to base_rules.mk
+ // soong_java_prebult has the same issue for .jars so use this in both module types.
+ entries.SetString("LOCAL_MODULE_STEM", fmt.Sprintf("UNUSED-%s", *m.Base))
- if len(m.provider.HostRequiredModuleNames) > 0 {
- entries.AddStrings("LOCAL_HOST_REQUIRED_MODULES", m.provider.HostRequiredModuleNames...)
- }
- if len(m.provider.RequiredModuleNames) > 0 {
- entries.AddStrings("LOCAL_REQUIRED_MODULES", m.provider.RequiredModuleNames...)
- }
-
- if m.provider.IsHost == false {
- // Not needed for jar_host_test
- //
- // Clear the JNI symbols because they belong to base not us. Either transform the names in the string
- // or clear the variable because we don't need it, we are copying bases libraries not generating
- // new ones.
- entries.SetString("LOCAL_SOONG_JNI_LIBS_SYMBOLS", "")
- }
- })
- return entriesList
+ // In normal java/app modules, the module writes LOCAL_COMPATIBILITY_SUPPORT_FILES
+ // and then base_rules.mk ends up copying each of those dependencies from .intermediates to the install directory.
+ // tasks/general-tests.mk, tasks/devices-tests.mk also use these to figure out
+ // which testcase files to put in a zip for running tests on another machine.
+ //
+ // We need our files to end up in the zip, but we don't want \.mk files to
+ // `install` files for us.
+ // So we create a new make variable to indicate these should be in the zip
+ // but not installed.
+ entries.AddStrings("LOCAL_SOONG_INSTALLED_COMPATIBILITY_SUPPORT_FILES", m.supportFiles.Strings()...)
+ },
+ },
+ // Ensure each of our supportFiles depends on the installed file in base so that our symlinks will always
+ // resolve. The provider gives us the .intermediate path for the support file in base, we change it to
+ // the installed path with a string substitution.
+ ExtraFooters: []android.AndroidMkExtraFootersFunc{
+ func(w io.Writer, name, prefix, moduleDir string) {
+ for _, f := range m.supportFiles.Strings() {
+ // convert out/.../testcases/FrameworksServicesTests_contentprotection/file1.apk
+ // to out/.../testcases/FrameworksServicesTests/file1.apk
+ basePath := strings.Replace(f, "/"+m.Name()+"/", "/"+*m.Base+"/", 1)
+ fmt.Fprintf(w, "%s: %s\n", f, basePath)
+ }
+ },
+ },
+ }}
}
func (m *testModuleConfigHostModule) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -248,7 +279,7 @@
// - written via soong_java_prebuilt.mk
//
// 4) out/host/linux-x86/testcases/derived-module/* # data dependencies from base.
-// - written via soong_java_prebuilt.mk
+// - written via our InstallSymlink
func (m *testModuleConfigHostModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
m.validateBase(ctx, &testModuleConfigHostTag, "java_test_host", true)
m.generateManifestAndConfig(ctx)
@@ -260,7 +291,6 @@
ctx.VisitDirectDepsWithTag(*depTag, func(dep android.Module) {
if provider, ok := android.OtherModuleProvider(ctx, dep, tradefed.BaseTestProviderKey); ok {
if baseShouldBeHost == provider.IsHost {
- m.base = dep
m.provider = provider
} else {
if baseShouldBeHost {
@@ -277,7 +307,9 @@
// Actions to write:
// 1. manifest file to testcases dir
-// 2. New Module.config / AndroidTest.xml file with our options.
+// 2. Symlink to base.apk under base's arch dir
+// 3. Symlink to all data dependencies
+// 4. New Module.config / AndroidTest.xml file with our options.
func (m *testModuleConfigModule) generateManifestAndConfig(ctx android.ModuleContext) {
// Keep before early returns.
android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
@@ -292,7 +324,6 @@
if m.provider.TestConfig == nil {
return
}
-
// 1) A manifest file listing the base, write text to a tiny file.
installDir := android.PathForModuleInstall(ctx, ctx.ModuleName())
manifest := android.PathForModuleOut(ctx, "test_module_config.manifest")
@@ -301,9 +332,53 @@
// Assume the primary install file is last
// so we need to Install our file last.
ctx.InstallFile(installDir, manifest.Base(), manifest)
+ m.manifest = manifest.OutputPath
- // 2) Module.config / AndroidTest.xml
+ // 2) Symlink to base.apk
+ baseApk := m.provider.OutputFile
+
+ // Typically looks like this for baseApk
+ // FrameworksServicesTests
+ // └── x86_64
+ // └── FrameworksServicesTests.apk
+ symlinkName := fmt.Sprintf("%s/%s", ctx.DeviceConfig().DeviceArch(), baseApk.Base())
+ // Only android_test, not java_host_test puts the output in the DeviceArch dir.
+ if m.provider.IsHost || ctx.DeviceConfig().DeviceArch() == "" {
+ // testcases/CtsDevicePolicyManagerTestCases
+ // ├── CtsDevicePolicyManagerTestCases.jar
+ symlinkName = baseApk.Base()
+ }
+ target := installedBaseRelativeToHere(symlinkName, *m.tradefedProperties.Base)
+ installedApk := ctx.InstallAbsoluteSymlink(installDir, symlinkName, target)
+ m.supportFiles = append(m.supportFiles, installedApk)
+
+ // 3) Symlink for all data deps
+ // And like this for data files and required modules
+ // FrameworksServicesTests
+ // ├── data
+ // │ └── broken_shortcut.xml
+ // ├── JobTestApp.apk
+ for _, f := range m.provider.InstalledFiles {
+ symlinkName := f.Rel()
+ target := installedBaseRelativeToHere(symlinkName, *m.tradefedProperties.Base)
+ installedPath := ctx.InstallAbsoluteSymlink(installDir, symlinkName, target)
+ m.supportFiles = append(m.supportFiles, installedPath)
+ }
+
+ // 4) Module.config / AndroidTest.xml
m.testConfig = m.fixTestConfig(ctx, m.provider.TestConfig)
}
var _ android.AndroidMkEntriesProvider = (*testModuleConfigHostModule)(nil)
+
+// Given a relative path to a file in the current directory or a subdirectory,
+// return a relative path under our sibling directory named `base`.
+// There should be one "../" for each subdir we descend plus one to backup to "base".
+//
+// ThisDir/file1
+// ThisDir/subdir/file2
+// would return "../base/file1" or "../../subdir/file2"
+func installedBaseRelativeToHere(targetFileName string, base string) string {
+ backup := strings.Repeat("../", strings.Count(targetFileName, "/")+1)
+ return fmt.Sprintf("%s%s/%s", backup, base, targetFileName)
+}
diff --git a/tradefed_modules/test_module_config_test.go b/tradefed_modules/test_module_config_test.go
index b2049b1..97179f5 100644
--- a/tradefed_modules/test_module_config_test.go
+++ b/tradefed_modules/test_module_config_test.go
@@ -16,6 +16,7 @@
import (
"android/soong/android"
"android/soong/java"
+ "fmt"
"strconv"
"strings"
"testing"
@@ -69,15 +70,36 @@
entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, derived.Module())[0]
// Ensure some entries from base are there, specifically support files for data and helper apps.
- assertEntryPairValues(t, entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"], []string{"HelperApp.apk", "data/testfile"})
+ // Do not use LOCAL_COMPATIBILITY_SUPPORT_FILES, but instead use LOCAL_SOONG_INSTALLED_COMPATIBILITY_SUPPORT_FILES
+ android.AssertStringPathsRelativeToTopEquals(t, "support-files", ctx.Config,
+ []string{"out/soong/target/product/test_device/testcases/derived_test/arm64/base.apk",
+ "out/soong/target/product/test_device/testcases/derived_test/HelperApp.apk",
+ "out/soong/target/product/test_device/testcases/derived_test/data/testfile"},
+ entries.EntryMap["LOCAL_SOONG_INSTALLED_COMPATIBILITY_SUPPORT_FILES"])
+ android.AssertArrayString(t, "", entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"], []string{})
+
+ android.AssertArrayString(t, "", entries.EntryMap["LOCAL_REQUIRED_MODULES"], []string{"base"})
+ android.AssertArrayString(t, "", entries.EntryMap["LOCAL_CERTIFICATE"], []string{"build/make/target/product/security/testkey.x509.pem"})
+ android.AssertStringEquals(t, "", entries.Class, "APPS")
// And some new derived entries are there.
android.AssertArrayString(t, "", entries.EntryMap["LOCAL_MODULE_TAGS"], []string{"tests"})
- // And ones we override
- android.AssertArrayString(t, "", entries.EntryMap["LOCAL_SOONG_JNI_LIBS_SYMBOLS"], []string{""})
-
android.AssertStringMatches(t, "", entries.EntryMap["LOCAL_FULL_TEST_CONFIG"][0], "derived_test/android_common/test_config_fixer/derived_test.config")
+
+ // Check the footer lines. Our support files should depend on base's support files.
+ convertedActual := make([]string, 5)
+ for i, e := range entries.FooterLinesForTests() {
+ // AssertStringPathsRelativeToTop doesn't replace both instances
+ convertedActual[i] = strings.Replace(e, ctx.Config.SoongOutDir(), "", 2)
+ }
+ android.AssertArrayString(t, fmt.Sprintf("%s", ctx.Config.SoongOutDir()), convertedActual, []string{
+ "include $(BUILD_SYSTEM)/soong_app_prebuilt.mk",
+ "/target/product/test_device/testcases/derived_test/arm64/base.apk: /target/product/test_device/testcases/base/arm64/base.apk",
+ "/target/product/test_device/testcases/derived_test/HelperApp.apk: /target/product/test_device/testcases/base/HelperApp.apk",
+ "/target/product/test_device/testcases/derived_test/data/testfile: /target/product/test_device/testcases/base/data/testfile",
+ "",
+ })
}
// Make sure we call test-config-fixer with the right args.
@@ -92,7 +114,7 @@
derived := ctx.ModuleForTests("derived_test", "android_common")
rule_cmd := derived.Rule("fix_test_config").RuleParams.Command
android.AssertStringDoesContain(t, "Bad FixConfig rule inputs", rule_cmd,
- `--test-file-name=derived_test.apk --orig-test-file-name=base.apk --test-runner-options='[{"Name":"exclude-filter","Key":"","Value":"android.test.example.devcodelab.DevCodelabTest#testHelloFail"},{"Name":"include-annotation","Key":"","Value":"android.platform.test.annotations.LargeTest"}]'`)
+ `--test-runner-options='[{"Name":"exclude-filter","Key":"","Value":"android.test.example.devcodelab.DevCodelabTest#testHelloFail"},{"Name":"include-annotation","Key":"","Value":"android.platform.test.annotations.LargeTest"}]'`)
}
// Ensure we error for a base we don't support.
@@ -195,8 +217,14 @@
name: "base",
sdk_version: "current",
srcs: ["a.java"],
+ data: [":HelperApp", "data/testfile"],
}
+ android_test_helper_app {
+ name: "HelperApp",
+ srcs: ["helper.java"],
+ }
+
test_module_config {
name: "derived_test",
base: "base",
@@ -220,8 +248,12 @@
derived := ctx.ModuleForTests("derived_test", "android_common")
entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, derived.Module())[0]
// All these should be the same in both derived tests
- assertEntryPairValues(t, entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"], []string{"HelperApp.apk", "data/testfile"})
- android.AssertArrayString(t, "", entries.EntryMap["LOCAL_SOONG_JNI_LIBS_SYMBOLS"], []string{""})
+ android.AssertStringPathsRelativeToTopEquals(t, "support-files", ctx.Config,
+ []string{"out/soong/target/product/test_device/testcases/derived_test/arm64/base.apk",
+ "out/soong/target/product/test_device/testcases/derived_test/HelperApp.apk",
+ "out/soong/target/product/test_device/testcases/derived_test/data/testfile"},
+ entries.EntryMap["LOCAL_SOONG_INSTALLED_COMPATIBILITY_SUPPORT_FILES"])
+
// Except this one, which points to the updated tradefed xml file.
android.AssertStringMatches(t, "", entries.EntryMap["LOCAL_FULL_TEST_CONFIG"][0], "derived_test/android_common/test_config_fixer/derived_test.config")
// And this one, the module name.
@@ -232,8 +264,11 @@
derived := ctx.ModuleForTests("another_derived_test", "android_common")
entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, derived.Module())[0]
// All these should be the same in both derived tests
- assertEntryPairValues(t, entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"], []string{"HelperApp.apk", "data/testfile"})
- android.AssertArrayString(t, "", entries.EntryMap["LOCAL_SOONG_JNI_LIBS_SYMBOLS"], []string{""})
+ android.AssertStringPathsRelativeToTopEquals(t, "support-files", ctx.Config,
+ []string{"out/soong/target/product/test_device/testcases/another_derived_test/arm64/base.apk",
+ "out/soong/target/product/test_device/testcases/another_derived_test/HelperApp.apk",
+ "out/soong/target/product/test_device/testcases/another_derived_test/data/testfile"},
+ entries.EntryMap["LOCAL_SOONG_INSTALLED_COMPATIBILITY_SUPPORT_FILES"])
// Except this one, which points to the updated tradefed xml file.
android.AssertStringMatches(t, "", entries.EntryMap["LOCAL_FULL_TEST_CONFIG"][0], "another_derived_test/android_common/test_config_fixer/another_derived_test.config")
// And this one, the module name.
@@ -269,6 +304,8 @@
allEntries := android.AndroidMkEntriesForTest(t, ctx.TestContext, mod)
entries := allEntries[0]
android.AssertArrayString(t, "", entries.EntryMap["LOCAL_MODULE"], []string{"derived_test"})
+ android.AssertArrayString(t, "", entries.EntryMap["LOCAL_SDK_VERSION"], []string{"private_current"})
+ android.AssertStringEquals(t, "", entries.Class, "JAVA_LIBRARIES")
if !mod.Host() {
t.Errorf("host bit is not set for a java_test_host module.")
@@ -385,16 +422,3 @@
t.Errorf("test-only: Expected but not found: %v, Found but not expected: %v", left, right)
}
}
-
-// Use for situations where the entries map contains pairs: [srcPath:installedPath1, srcPath2:installedPath2]
-// and we want to compare the RHS of the pairs, i.e. installedPath1, installedPath2
-func assertEntryPairValues(t *testing.T, actual []string, expected []string) {
- for i, e := range actual {
- parts := strings.Split(e, ":")
- if len(parts) != 2 {
- t.Errorf("Expected entry to have a value delimited by :, received: %s", e)
- return
- }
- android.AssertStringEquals(t, "", parts[1], expected[i])
- }
-}