diff options
38 files changed, 3081 insertions, 97 deletions
diff --git a/aconfig/codegen/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go index 1378dfece..a46ce5245 100644 --- a/aconfig/codegen/java_aconfig_library.go +++ b/aconfig/codegen/java_aconfig_library.go @@ -76,7 +76,7 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) DepsMutator(module *ja } } -func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuildActions(module *java.GeneratedJavaLibraryModule, ctx android.ModuleContext) android.Path { +func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuildActions(module *java.GeneratedJavaLibraryModule, ctx android.ModuleContext) (android.Path, android.Path) { // Get the values that came from the global RELEASE_ACONFIG_VALUE_SETS flag declarationsModules := ctx.GetDirectDepsWithTag(declarationsTag) if len(declarationsModules) != 1 { @@ -129,7 +129,11 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuild }}, }) - return srcJarPath + return srcJarPath, declarations.IntermediateCacheOutputPath +} + +func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) AconfigDeclarations() *string { + return proptools.StringPtr(callbacks.properties.Aconfig_declarations) } func isModeSupported(mode string) bool { diff --git a/android/defs.go b/android/defs.go index a34d30248..78cdea2ba 100644 --- a/android/defs.go +++ b/android/defs.go @@ -103,16 +103,6 @@ var ( Description: "concatenate files to $out", }) - // ubuntu 14.04 offcially use dash for /bin/sh, and its builtin echo command - // doesn't support -e option. Therefore we force to use /bin/bash when writing out - // content to file. - writeFile = pctx.AndroidStaticRule("writeFile", - blueprint.RuleParams{ - Command: `rm -f $out && /bin/bash -c 'echo -e -n "$$0" > $out' $content`, - Description: "writing file $out", - }, - "content") - // Used only when USE_GOMA=true is set, to restrict non-goma jobs to the local parallelism value localPool = blueprint.NewBuiltinPool("local_pool") diff --git a/android/paths.go b/android/paths.go index a40f48274..2b33f67ce 100644 --- a/android/paths.go +++ b/android/paths.go @@ -673,7 +673,8 @@ func PathsAndMissingDepsRelativeToModuleSourceDir(input SourceInput) (Paths, []s expandedSrcFiles = append(expandedSrcFiles, srcFiles...) } - return expandedSrcFiles, append(missingDeps, missingExcludeDeps...) + // TODO: b/334169722 - Replace with an error instead of implicitly removing duplicates. + return FirstUniquePaths(expandedSrcFiles), append(missingDeps, missingExcludeDeps...) } type missingDependencyError struct { diff --git a/android/variable.go b/android/variable.go index b0afd5b9b..5a079db50 100644 --- a/android/variable.go +++ b/android/variable.go @@ -139,6 +139,8 @@ type variableProperties struct { Srcs []string Exclude_srcs []string Cmd *string + + Deps []string } // eng is true for -eng builds, and can be used to turn on additional heavyweight debugging diff --git a/apex/apex_test.go b/apex/apex_test.go index 1e75948af..2441b023b 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -7114,8 +7114,9 @@ func TestJavaSDKLibrary(t *testing.T) { "etc/permissions/foo.xml", }) // Permission XML should point to the activated path of impl jar of java_sdk_library - sdkLibrary := ctx.ModuleForTests("foo.xml", "android_common_myapex").Rule("java_sdk_xml") - ensureMatches(t, sdkLibrary.RuleParams.Command, `<library\\n\s+name=\\\"foo\\\"\\n\s+file=\\\"/apex/myapex/javalib/foo.jar\\\"`) + sdkLibrary := ctx.ModuleForTests("foo.xml", "android_common_myapex").Output("foo.xml") + contents := android.ContentFromFileRuleForTests(t, ctx, sdkLibrary) + ensureMatches(t, contents, "<library\\n\\s+name=\\\"foo\\\"\\n\\s+file=\\\"/apex/myapex/javalib/foo.jar\\\"") } func TestJavaSDKLibrary_WithinApex(t *testing.T) { @@ -11404,3 +11405,121 @@ func TestInstallationRulesForMultipleApexPrebuilts(t *testing.T) { checkHideFromMake(t, ctx, tc.expectedVisibleModuleName, tc.expectedHiddenModuleNames) } } + +func TestAconfifDeclarationsValidation(t *testing.T) { + aconfigDeclarationLibraryString := func(moduleNames []string) (ret string) { + for _, moduleName := range moduleNames { + ret += fmt.Sprintf(` + aconfig_declarations { + name: "%[1]s", + package: "com.example.package", + srcs: [ + "%[1]s.aconfig", + ], + } + java_aconfig_library { + name: "%[1]s-lib", + aconfig_declarations: "%[1]s", + } + `, moduleName) + } + return ret + } + + result := android.GroupFixturePreparers( + prepareForApexTest, + java.PrepareForTestWithJavaSdkLibraryFiles, + java.FixtureWithLastReleaseApis("foo"), + android.FixtureModifyConfig(func(config android.Config) { + config.SetApiLibraries([]string{"foo"}) + }), + ).RunTestWithBp(t, ` + java_library { + name: "baz-java-lib", + static_libs: [ + "baz-lib", + ], + } + filegroup { + name: "qux-filegroup", + srcs: [ + ":qux-lib{.generated_srcjars}", + ], + } + filegroup { + name: "qux-another-filegroup", + srcs: [ + ":qux-filegroup", + ], + } + java_library { + name: "quux-java-lib", + srcs: [ + "a.java", + ], + libs: [ + "quux-lib", + ], + } + java_sdk_library { + name: "foo", + srcs: [ + ":qux-another-filegroup", + ], + api_packages: ["foo"], + system: { + enabled: true, + }, + module_lib: { + enabled: true, + }, + test: { + enabled: true, + }, + static_libs: [ + "bar-lib", + ], + libs: [ + "baz-java-lib", + "quux-java-lib", + ], + aconfig_declarations: [ + "bar", + ], + } + `+aconfigDeclarationLibraryString([]string{"bar", "baz", "qux", "quux"})) + + m := result.ModuleForTests("foo.stubs.source", "android_common") + outDir := "out/soong/.intermediates" + + // Arguments passed to aconfig to retrieve the state of the flags defined in the + // textproto files + aconfigFlagArgs := m.Output("released-flagged-apis-exportable.txt").Args["flags_path"] + + // "bar-lib" is a static_lib of "foo" and is passed to metalava as classpath. Thus the + // cache file provided by the associated aconfig_declarations module "bar" should be passed + // to aconfig. + android.AssertStringDoesContain(t, "cache file of a java_aconfig_library static_lib "+ + "passed as an input", + aconfigFlagArgs, fmt.Sprintf("%s/%s/intermediate.pb", outDir, "bar")) + + // "baz-java-lib", which statically depends on "baz-lib", is a lib of "foo" and is passed + // to metalava as classpath. Thus the cache file provided by the associated + // aconfig_declarations module "baz" should be passed to aconfig. + android.AssertStringDoesContain(t, "cache file of a lib that statically depends on "+ + "java_aconfig_library passed as an input", + aconfigFlagArgs, fmt.Sprintf("%s/%s/intermediate.pb", outDir, "baz")) + + // "qux-lib" is passed to metalava as src via the filegroup, thus the cache file provided by + // the associated aconfig_declarations module "qux" should be passed to aconfig. + android.AssertStringDoesContain(t, "cache file of srcs java_aconfig_library passed as an "+ + "input", + aconfigFlagArgs, fmt.Sprintf("%s/%s/intermediate.pb", outDir, "qux")) + + // "quux-java-lib" is a lib of "foo" and is passed to metalava as classpath, but does not + // statically depend on "quux-lib". Therefore, the cache file provided by the associated + // aconfig_declarations module "quux" should not be passed to aconfig. + android.AssertStringDoesNotContain(t, "cache file of a lib that does not statically "+ + "depend on java_aconfig_library not passed as an input", + aconfigFlagArgs, fmt.Sprintf("%s/%s/intermediate.pb", outDir, "quux")) +} diff --git a/cc/Android.bp b/cc/Android.bp index 8c86eb706..5ba94270b 100644 --- a/cc/Android.bp +++ b/cc/Android.bp @@ -91,6 +91,7 @@ bootstrap_go_package { "afdo_test.go", "binary_test.go", "cc_test.go", + "cc_test_only_property_test.go", "compiler_test.go", "gen_test.go", "genrule_test.go", @@ -845,6 +845,7 @@ type Module struct { VendorProperties VendorProperties Properties BaseProperties + sourceProperties android.SourceProperties // initialize before calling Init hod android.HostOrDeviceSupported @@ -1262,6 +1263,10 @@ func (c *Module) Init() android.Module { for _, feature := range c.features { c.AddProperties(feature.props()...) } + // Allow test-only on libraries that are not cc_test_library + if c.library != nil && !c.testLibrary() { + c.AddProperties(&c.sourceProperties) + } android.InitAndroidArchModule(c, c.hod, c.multilib) android.InitApexModule(c) @@ -2135,6 +2140,18 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { if c.testModule { android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{}) } + + // If Test_only is set on a module in bp file, respect the setting, otherwise + // see if is a known test module type. + testOnly := c.testModule || c.testLibrary() + if c.sourceProperties.Test_only != nil { + testOnly = Bool(c.sourceProperties.Test_only) + } + android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{ + TestOnly: testOnly, + TopLevelTarget: c.testModule, + }) + android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: deps.GeneratedSources.Strings()}) android.CollectDependencyAconfigFiles(ctx, &c.mergedAconfigFiles) diff --git a/cc/cc_test_only_property_test.go b/cc/cc_test_only_property_test.go new file mode 100644 index 000000000..972e86bc5 --- /dev/null +++ b/cc/cc_test_only_property_test.go @@ -0,0 +1,187 @@ +// 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 cc + +import ( + "android/soong/android" + "android/soong/android/team_proto" + "log" + "strings" + "testing" + + "github.com/google/blueprint" + "google.golang.org/protobuf/proto" +) + +func TestTestOnlyProvider(t *testing.T) { + t.Parallel() + ctx := android.GroupFixturePreparers( + prepareForCcTest, + android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { + ctx.RegisterModuleType("cc_test_host", TestHostFactory) + }), + ).RunTestWithBp(t, ` + // These should be test-only + cc_fuzz { name: "cc-fuzz" } + cc_test { name: "cc-test", gtest:false } + cc_benchmark { name: "cc-benchmark" } + cc_library { name: "cc-library-forced", + test_only: true } + cc_test_library {name: "cc-test-library", gtest: false} + cc_test_host {name: "cc-test-host", gtest: false} + + // These should not be. + cc_genrule { name: "cc_genrule", cmd: "echo foo", out: ["out"] } + cc_library { name: "cc_library" } + cc_library { name: "cc_library_false", test_only: false } + cc_library_static { name: "cc_static" } + cc_library_shared { name: "cc_library_shared" } + + cc_object { name: "cc-object" } + `) + + // Visit all modules and ensure only the ones that should + // marked as test-only are marked as test-only. + + actualTestOnly := []string{} + ctx.VisitAllModules(func(m blueprint.Module) { + if provider, ok := android.OtherModuleProvider(ctx.TestContext.OtherModuleProviderAdaptor(), m, android.TestOnlyProviderKey); ok { + if provider.TestOnly { + actualTestOnly = append(actualTestOnly, m.Name()) + } + } + }) + expectedTestOnlyModules := []string{ + "cc-test", + "cc-library-forced", + "cc-fuzz", + "cc-benchmark", + "cc-test-library", + "cc-test-host", + } + + notEqual, left, right := android.ListSetDifference(expectedTestOnlyModules, actualTestOnly) + if notEqual { + t.Errorf("test-only: Expected but not found: %v, Found but not expected: %v", left, right) + } +} + +func TestTestOnlyInTeamsProto(t *testing.T) { + t.Parallel() + ctx := android.GroupFixturePreparers( + android.PrepareForTestWithTeamBuildComponents, + prepareForCcTest, + android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { + ctx.RegisterParallelSingletonType("all_teams", android.AllTeamsFactory) + ctx.RegisterModuleType("cc_test_host", TestHostFactory) + + }), + ).RunTestWithBp(t, ` + package { default_team: "someteam"} + + // These should be test-only + cc_fuzz { name: "cc-fuzz" } + cc_test { name: "cc-test", gtest:false } + cc_benchmark { name: "cc-benchmark" } + cc_library { name: "cc-library-forced", + test_only: true } + cc_test_library {name: "cc-test-library", gtest: false} + cc_test_host {name: "cc-test-host", gtest: false} + + // These should not be. + cc_genrule { name: "cc_genrule", cmd: "echo foo", out: ["out"] } + cc_library { name: "cc_library" } + cc_library_static { name: "cc_static" } + cc_library_shared { name: "cc_library_shared" } + + cc_object { name: "cc-object" } + team { + name: "someteam", + trendy_team_id: "cool_team", + } + `) + + var teams *team_proto.AllTeams + teams = getTeamProtoOutput(t, ctx) + + // map of module name -> trendy team name. + actualTrueModules := []string{} + for _, teamProto := range teams.Teams { + if Bool(teamProto.TestOnly) { + actualTrueModules = append(actualTrueModules, teamProto.GetTargetName()) + } + } + expectedTestOnlyModules := []string{ + "cc-test", + "cc-library-forced", + "cc-fuzz", + "cc-benchmark", + "cc-test-library", + "cc-test-host", + } + + notEqual, left, right := android.ListSetDifference(expectedTestOnlyModules, actualTrueModules) + if notEqual { + t.Errorf("test-only: Expected but not found: %v, Found but not expected: %v", left, right) + } +} + +// Don't allow setting test-only on things that are always tests or never tests. +func TestInvalidTestOnlyTargets(t *testing.T) { + testCases := []string{ + ` cc_test { name: "cc-test", test_only: true, gtest: false, srcs: ["foo.cc"], } `, + ` cc_binary { name: "cc-binary", test_only: true, srcs: ["foo.cc"], } `, + ` cc_test_library {name: "cc-test-library", test_only: true, gtest: false} `, + ` cc_test_host {name: "cc-test-host", test_only: true, gtest: false} `, + ` cc_defaults {name: "cc-defaults", test_only: true} `, + } + + for i, bp := range testCases { + ctx := android.GroupFixturePreparers( + prepareForCcTest, + android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { + ctx.RegisterModuleType("cc_test_host", TestHostFactory) + })). + ExtendWithErrorHandler(android.FixtureIgnoreErrors). + RunTestWithBp(t, bp) + if len(ctx.Errs) == 0 { + t.Errorf("Expected err setting test_only in testcase #%d", i) + } + if len(ctx.Errs) > 1 { + t.Errorf("Too many errs: [%s] %v", bp, ctx.Errs) + } + + if len(ctx.Errs) == 1 { + if !strings.Contains(ctx.Errs[0].Error(), "unrecognized property \"test_only\"") { + t.Errorf("ERR: %s bad bp: %s", ctx.Errs[0], bp) + } + } + } +} + +func getTeamProtoOutput(t *testing.T, ctx *android.TestResult) *team_proto.AllTeams { + teams := new(team_proto.AllTeams) + config := ctx.SingletonForTests("all_teams") + allOutputs := config.AllOutputs() + + protoPath := allOutputs[0] + + out := config.MaybeOutput(protoPath) + outProto := []byte(android.ContentFromFileRuleForTests(t, ctx.TestContext, out)) + if err := proto.Unmarshal(outProto, teams); err != nil { + log.Fatalln("Failed to parse teams proto:", err) + } + return teams +} diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go index fb81e420f..beb68e19d 100644 --- a/cc/config/arm64_device.go +++ b/cc/config/arm64_device.go @@ -103,6 +103,8 @@ func init() { flags := arm64Cflags if ctx.Config().NoBionicPageSizeMacro() { flags = append(flags, "-D__BIONIC_NO_PAGE_SIZE_MACRO") + } else { + flags = append(flags, "-D__BIONIC_DEPRECATED_PAGE_SIZE_MACRO") } return strings.Join(flags, " ") }) diff --git a/cc/config/global.go b/cc/config/global.go index 08fcb91fa..16b5e0938 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -144,6 +144,9 @@ var ( // Make paths in deps files relative. "-no-canonical-prefixes", + + // http://b/315250603 temporarily disabled + "-Wno-error=format", } commonGlobalConlyflags = []string{} @@ -254,8 +257,6 @@ var ( "-Werror=fortify-source", // http://b/315246135 temporarily disabled "-Wno-unused-variable", - // http://b/315250603 temporarily disabled - "-Wno-error=format", // Disabled because it produces many false positives. http://b/323050926 "-Wno-missing-field-initializers", // http://b/323050889 diff --git a/cc/config/x86_64_device.go b/cc/config/x86_64_device.go index 171ab4f22..5aa2a7e3b 100644 --- a/cc/config/x86_64_device.go +++ b/cc/config/x86_64_device.go @@ -112,6 +112,8 @@ func init() { flags := x86_64Cflags if ctx.Config().NoBionicPageSizeMacro() { flags = append(flags, "-D__BIONIC_NO_PAGE_SIZE_MACRO") + } else { + flags = append(flags, "-D__BIONIC_DEPRECATED_PAGE_SIZE_MACRO") } return strings.Join(flags, " ") }) diff --git a/cmd/release_config/Android.bp b/cmd/release_config/Android.bp new file mode 100644 index 000000000..7f627ffb7 --- /dev/null +++ b/cmd/release_config/Android.bp @@ -0,0 +1,30 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +bootstrap_go_package { + name: "release-config", + pkgPath: "android/soong/cmd/release_config", + deps: [ + "golang-protobuf-encoding-prototext", + "golang-protobuf-reflect-protoreflect", + "golang-protobuf-runtime-protoimpl", + "soong-cmd-release-config-proto", + ], + srcs: [ + "main.go", + ], +} + +bootstrap_go_package { + name: "soong-cmd-release-config-proto", + pkgPath: "android/soong/cmd/release_config/release_config_proto", + deps: [ + "golang-protobuf-reflect-protoreflect", + "golang-protobuf-runtime-protoimpl", + ], + srcs: [ + "release_config_proto/build_flags_out.pb.go", + "release_config_proto/build_flags_src.pb.go", + ], +} diff --git a/cmd/release_config/main.go b/cmd/release_config/main.go new file mode 100644 index 000000000..3bb6b3dfe --- /dev/null +++ b/cmd/release_config/main.go @@ -0,0 +1,691 @@ +// 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 main + +import ( + "cmp" + "encoding/json" + "flag" + "fmt" + "io/fs" + "os" + "path/filepath" + "slices" + "strings" + + "android/soong/cmd/release_config/release_config_proto" + + "google.golang.org/protobuf/encoding/prototext" + "google.golang.org/protobuf/proto" +) + +var verboseFlag bool + +type StringList []string + +func (l *StringList) Set(v string) error { + *l = append(*l, v) + return nil +} + +func (l *StringList) String() string { + return fmt.Sprintf("%v", *l) +} + +var releaseConfigMapPaths StringList + +func DumpProtos(outDir string, message proto.Message) error { + basePath := filepath.Join(outDir, "all_release_configs") + writer := func(suffix string, marshal func() ([]byte, error)) error { + data, err := marshal() + if err != nil { + return err + } + return os.WriteFile(fmt.Sprintf("%s.%s", basePath, suffix), data, 0644) + } + err := writer("textproto", func() ([]byte, error) { return prototext.MarshalOptions{Multiline: true}.Marshal(message) }) + if err != nil { + return err + } + + err = writer("pb", func() ([]byte, error) { return proto.Marshal(message) }) + if err != nil { + return err + } + + return writer("json", func() ([]byte, error) { return json.MarshalIndent(message, "", " ") }) +} + +func LoadTextproto(path string, message proto.Message) error { + data, err := os.ReadFile(path) + if err != nil { + return err + } + ret := prototext.Unmarshal(data, message) + if verboseFlag { + debug, _ := prototext.Marshal(message) + fmt.Printf("%s: %s\n", path, debug) + } + return ret +} + +func WalkTextprotoFiles(root string, subdir string, Func fs.WalkDirFunc) error { + path := filepath.Join(root, subdir) + if _, err := os.Stat(path); err != nil { + // Missing subdirs are not an error. + return nil + } + return filepath.WalkDir(path, func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + if strings.HasSuffix(d.Name(), ".textproto") && d.Type().IsRegular() { + return Func(path, d, err) + } + return nil + }) +} + +type FlagValue struct { + // The path providing this value. + path string + + // Protobuf + proto release_config_proto.FlagValue +} + +func FlagValueFactory(protoPath string) (fv *FlagValue) { + fv = &FlagValue{path: protoPath} + if protoPath != "" { + LoadTextproto(protoPath, &fv.proto) + } + return fv +} + +// One directory's contribution to the a release config. +type ReleaseConfigContribution struct { + // Paths to files providing this config. + path string + + // The index of the config directory where this release config + // contribution was declared. + // Flag values cannot be set in a location with a lower index. + DeclarationIndex int + + // Protobufs relevant to the config. + proto release_config_proto.ReleaseConfig + + FlagValues []*FlagValue +} + +// A single release_config_map.textproto and its associated data. +// Used primarily for debugging. +type ReleaseConfigMap struct { + // The path to this release_config_map file. + path string + + // Data received + proto release_config_proto.ReleaseConfigMap + + ReleaseConfigContributions map[string]*ReleaseConfigContribution + FlagDeclarations []release_config_proto.FlagDeclaration +} + +// A generated release config. +type ReleaseConfig struct { + // the Name of the release config + Name string + + // The index of the config directory where this release config was + // first declared. + // Flag values cannot be set in a location with a lower index. + DeclarationIndex int + + // What contributes to this config. + Contributions []*ReleaseConfigContribution + + // Aliases for this release + OtherNames []string + + // The names of release configs that we inherit + InheritNames []string + + // Unmarshalled flag artifacts + FlagArtifacts FlagArtifacts + + // Generated release config + ReleaseConfigArtifact *release_config_proto.ReleaseConfigArtifact + + // We have begun compiling this release config. + compileInProgress bool +} + +type FlagArtifact struct { + FlagDeclaration *release_config_proto.FlagDeclaration + + // The index of the config directory where this flag was declared. + // Flag values cannot be set in a location with a lower index. + DeclarationIndex int + + Traces []*release_config_proto.Tracepoint + + // Assigned value + Value *release_config_proto.Value +} + +// Key is flag name. +type FlagArtifacts map[string]*FlagArtifact + +type ReleaseConfigDirMap map[string]int + +// The generated release configs. +type ReleaseConfigs struct { + // Ordered list of release config maps processed. + ReleaseConfigMaps []*ReleaseConfigMap + + // Aliases + Aliases map[string]*string + + // Dictionary of flag_name:FlagDeclaration, with no overrides applied. + FlagArtifacts FlagArtifacts + + // Dictionary of name:ReleaseConfig + ReleaseConfigs map[string]*ReleaseConfig + + // Generated release configs + Artifact release_config_proto.ReleaseConfigsArtifact + + // The list of config directories used. + ConfigDirs []string + + // A map from the config directory to its order in the list of config + // directories. + ConfigDirIndexes ReleaseConfigDirMap +} + +func (src *FlagArtifact) Clone() *FlagArtifact { + value := &release_config_proto.Value{} + proto.Merge(value, src.Value) + return &FlagArtifact{ + FlagDeclaration: src.FlagDeclaration, + Traces: src.Traces, + Value: value, + } +} + +func (src FlagArtifacts) Clone() (dst FlagArtifacts) { + if dst == nil { + dst = make(FlagArtifacts) + } + for k, v := range src { + dst[k] = v.Clone() + } + return +} + +func ReleaseConfigFactory(name string, index int) (c *ReleaseConfig) { + return &ReleaseConfig{Name: name, DeclarationIndex: index} +} + +func ReleaseConfigsFactory() (c *ReleaseConfigs) { + return &ReleaseConfigs{ + Aliases: make(map[string]*string), + FlagArtifacts: make(map[string]*FlagArtifact), + ReleaseConfigs: make(map[string]*ReleaseConfig), + ConfigDirs: []string{}, + ConfigDirIndexes: make(ReleaseConfigDirMap), + } +} + +func ReleaseConfigMapFactory(protoPath string) (m *ReleaseConfigMap) { + m = &ReleaseConfigMap{ + path: protoPath, + ReleaseConfigContributions: make(map[string]*ReleaseConfigContribution), + } + if protoPath != "" { + LoadTextproto(protoPath, &m.proto) + } + return m +} + +func FlagDeclarationFactory(protoPath string) (fd *release_config_proto.FlagDeclaration) { + fd = &release_config_proto.FlagDeclaration{} + if protoPath != "" { + LoadTextproto(protoPath, fd) + } + return fd +} + +func (configs *ReleaseConfigs) LoadReleaseConfigMap(path string, ConfigDirIndex int) error { + m := ReleaseConfigMapFactory(path) + if m.proto.Origin == nil || *m.proto.Origin == "" { + return fmt.Errorf("Release config map %s lacks origin", path) + } + if m.proto.DefaultContainer == nil { + return fmt.Errorf("Release config map %s lacks default_container", path) + } + dir := filepath.Dir(path) + // Record any aliases, checking for duplicates. + for _, alias := range m.proto.Aliases { + name := *alias.Name + oldTarget, ok := configs.Aliases[name] + if ok { + if *oldTarget != *alias.Target { + return fmt.Errorf("Conflicting alias declarations: %s vs %s", + *oldTarget, *alias.Target) + } + } + configs.Aliases[name] = alias.Target + } + var err error + err = WalkTextprotoFiles(dir, "flag_declarations", func(path string, d fs.DirEntry, err error) error { + flagDeclaration := FlagDeclarationFactory(path) + // Container must be specified. + if flagDeclaration.Container == nil { + flagDeclaration.Container = m.proto.DefaultContainer + } + // TODO: drop flag_declaration.origin from the proto. + if flagDeclaration.Origin == nil { + flagDeclaration.Origin = m.proto.Origin + } + // There is always a default value. + if flagDeclaration.Value == nil { + flagDeclaration.Value = &release_config_proto.Value{Val: &release_config_proto.Value_UnspecifiedValue{true}} + } + m.FlagDeclarations = append(m.FlagDeclarations, *flagDeclaration) + name := *flagDeclaration.Name + if def, ok := configs.FlagArtifacts[name]; !ok { + configs.FlagArtifacts[name] = &FlagArtifact{FlagDeclaration: flagDeclaration, DeclarationIndex: ConfigDirIndex} + } else if !proto.Equal(def.FlagDeclaration, flagDeclaration) { + return fmt.Errorf("Duplicate definition of %s", *flagDeclaration.Name) + } + // Set the initial value in the flag artifact. + configs.FlagArtifacts[name].UpdateValue( + FlagValue{path: path, proto: release_config_proto.FlagValue{ + Name: proto.String(name), Value: flagDeclaration.Value}}) + return nil + }) + if err != nil { + return err + } + + err = WalkTextprotoFiles(dir, "release_configs", func(path string, d fs.DirEntry, err error) error { + releaseConfigContribution := &ReleaseConfigContribution{path: path, DeclarationIndex: ConfigDirIndex} + LoadTextproto(path, &releaseConfigContribution.proto) + name := *releaseConfigContribution.proto.Name + if fmt.Sprintf("%s.textproto", name) != filepath.Base(path) { + return fmt.Errorf("%s incorrectly declares release config %s", path, name) + } + if _, ok := configs.ReleaseConfigs[name]; !ok { + configs.ReleaseConfigs[name] = ReleaseConfigFactory(name, ConfigDirIndex) + } + config := configs.ReleaseConfigs[name] + config.InheritNames = append(config.InheritNames, releaseConfigContribution.proto.Inherits...) + + // 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 { + flagValue := FlagValueFactory(path) + if fmt.Sprintf("%s.textproto", *flagValue.proto.Name) != filepath.Base(path) { + return fmt.Errorf("%s incorrectly sets value for flag %s", path, *flagValue.proto.Name) + } + releaseConfigContribution.FlagValues = append(releaseConfigContribution.FlagValues, flagValue) + return nil + }) + if err2 != nil { + return err2 + } + m.ReleaseConfigContributions[name] = releaseConfigContribution + config.Contributions = append(config.Contributions, releaseConfigContribution) + return nil + }) + if err != nil { + return err + } + configs.ReleaseConfigMaps = append(configs.ReleaseConfigMaps, m) + return nil +} + +func (configs *ReleaseConfigs) GetReleaseConfig(name string) (*ReleaseConfig, error) { + trace := []string{name} + for target, ok := configs.Aliases[name]; ok; target, ok = configs.Aliases[name] { + name = *target + trace = append(trace, name) + } + if config, ok := configs.ReleaseConfigs[name]; ok { + return config, nil + } + return nil, fmt.Errorf("Missing config %s. Trace=%v", name, trace) +} + +func (configs *ReleaseConfigs) DumpMakefile(outDir, targetRelease string) error { + outFile := filepath.Join(outDir, "release_config.mk") + makeVars := make(map[string]string) + config, err := configs.GetReleaseConfig(targetRelease) + if err != nil { + return err + } + // Sort the flags by name first. + names := []string{} + for k, _ := range config.FlagArtifacts { + names = append(names, k) + } + slices.SortFunc(names, func(a, b string) int { + return cmp.Compare(a, b) + }) + partitions := make(map[string][]string) + + vNames := []string{} + addVar := func(name, suffix, value string) { + fullName := fmt.Sprintf("_ALL_RELEASE_FLAGS.%s.%s", name, suffix) + vNames = append(vNames, fullName) + makeVars[fullName] = value + } + + for _, name := range names { + flag := config.FlagArtifacts[name] + decl := flag.FlagDeclaration + + // cName := strings.ToLower(release_config_proto.Container_name[decl.GetContainer()]) + cName := strings.ToLower(decl.Container.String()) + if cName == strings.ToLower(release_config_proto.Container_ALL.String()) { + partitions["product"] = append(partitions["product"], name) + partitions["system"] = append(partitions["system"], name) + partitions["system_ext"] = append(partitions["system_ext"], name) + partitions["vendor"] = append(partitions["vendor"], name) + } else { + partitions[cName] = append(partitions[cName], name) + } + value := MarshalValue(flag.Value) + makeVars[name] = value + addVar(name, "PARTITIONS", cName) + addVar(name, "DEFAULT", MarshalValue(decl.Value)) + addVar(name, "VALUE", value) + addVar(name, "DECLARED_IN", *flag.Traces[0].Source) + addVar(name, "SET_IN", *flag.Traces[len(flag.Traces)-1].Source) + addVar(name, "ORIGIN", *decl.Origin) + } + pNames := []string{} + for k, _ := range partitions { + pNames = append(pNames, k) + } + slices.SortFunc(pNames, func(a, b string) int { + return cmp.Compare(a, b) + }) + + // Now sort the make variables, and output them. + slices.SortFunc(vNames, func(a, b string) int { + return cmp.Compare(a, b) + }) + + // Write the flags as: + // _ALL_RELELASE_FLAGS + // _ALL_RELEASE_FLAGS.PARTITIONS.* + // all _ALL_RELEASE_FLAGS.*, sorted by name + // Final flag values, sorted by name. + data := fmt.Sprintf("_ALL_RELEASE_FLAGS :=$= %s\n", strings.Join(names, " ")) + for _, pName := range pNames { + data += fmt.Sprintf("_ALL_RELEASE_FLAGS.PARTITIONS.%s :=$= %s\n", pName, strings.Join(partitions[pName], " ")) + } + for _, vName := range vNames { + data += fmt.Sprintf("%s :=$= %s\n", vName, makeVars[vName]) + } + data += "\n\n# Values for all build flags\n" + data += fmt.Sprintf("RELEASE_ACONFIG_VALUE_SETS :=$= %s\n", + strings.Join(config.ReleaseConfigArtifact.AconfigValueSets, " ")) + for _, name := range names { + data += fmt.Sprintf("%s :=$= %s\n", name, makeVars[name]) + } + return os.WriteFile(outFile, []byte(data), 0644) +} + +func (configs *ReleaseConfigs) GenerateReleaseConfigs(targetRelease string) error { + otherNames := make(map[string][]string) + for aliasName, aliasTarget := range configs.Aliases { + if _, ok := configs.ReleaseConfigs[aliasName]; ok { + return fmt.Errorf("Alias %s is a declared release config", aliasName) + } + if _, ok := configs.ReleaseConfigs[*aliasTarget]; !ok { + if _, ok2 := configs.Aliases[*aliasTarget]; !ok2 { + return fmt.Errorf("Alias %s points to non-existing config %s", aliasName, *aliasTarget) + } + } + otherNames[*aliasTarget] = append(otherNames[*aliasTarget], aliasName) + } + for name, aliases := range otherNames { + configs.ReleaseConfigs[name].OtherNames = aliases + } + + for _, config := range configs.ReleaseConfigs { + err := config.GenerateReleaseConfig(configs) + if err != nil { + return err + } + } + + releaseConfig, err := configs.GetReleaseConfig(targetRelease) + if err != nil { + return err + } + configs.Artifact = release_config_proto.ReleaseConfigsArtifact{ + ReleaseConfig: releaseConfig.ReleaseConfigArtifact, + OtherReleaseConfigs: func() []*release_config_proto.ReleaseConfigArtifact { + orc := []*release_config_proto.ReleaseConfigArtifact{} + for name, config := range configs.ReleaseConfigs { + if name != releaseConfig.Name { + orc = append(orc, config.ReleaseConfigArtifact) + } + } + return orc + }(), + } + return nil +} + +func MarshalValue(value *release_config_proto.Value) string { + switch val := value.Val.(type) { + case *release_config_proto.Value_UnspecifiedValue: + // Value was never set. + return "" + case *release_config_proto.Value_StringValue: + return val.StringValue + case *release_config_proto.Value_BoolValue: + if val.BoolValue { + return "true" + } + // False ==> empty string + return "" + case *release_config_proto.Value_Obsolete: + return " #OBSOLETE" + default: + // Flagged as error elsewhere, so return empty string here. + return "" + } +} + +func (fa *FlagArtifact) UpdateValue(flagValue FlagValue) error { + name := *flagValue.proto.Name + fa.Traces = append(fa.Traces, &release_config_proto.Tracepoint{Source: proto.String(flagValue.path), Value: flagValue.proto.Value}) + if fa.Value.GetObsolete() { + return fmt.Errorf("Attempting to set obsolete flag %s. Trace=%v", name, fa.Traces) + } + switch val := flagValue.proto.Value.Val.(type) { + case *release_config_proto.Value_StringValue: + fa.Value = &release_config_proto.Value{Val: &release_config_proto.Value_StringValue{val.StringValue}} + case *release_config_proto.Value_BoolValue: + fa.Value = &release_config_proto.Value{Val: &release_config_proto.Value_BoolValue{val.BoolValue}} + case *release_config_proto.Value_Obsolete: + if !val.Obsolete { + return fmt.Errorf("%s: Cannot set obsolete=false. Trace=%v", name, fa.Traces) + } + fa.Value = &release_config_proto.Value{Val: &release_config_proto.Value_Obsolete{true}} + default: + return fmt.Errorf("Invalid type for flag_value: %T. Trace=%v", val, fa.Traces) + } + return nil +} + +func (fa *FlagArtifact) Marshal() (*release_config_proto.FlagArtifact, error) { + return &release_config_proto.FlagArtifact{ + FlagDeclaration: fa.FlagDeclaration, + Value: fa.Value, + Traces: fa.Traces, + }, nil +} + +func (config *ReleaseConfig) GenerateReleaseConfig(configs *ReleaseConfigs) error { + if config.ReleaseConfigArtifact != nil { + return nil + } + if config.compileInProgress { + return fmt.Errorf("Loop detected for release config %s", config.Name) + } + config.compileInProgress = true + + // Generate any configs we need to inherit. This will detect loops in + // the config. + contributionsToApply := []*ReleaseConfigContribution{} + myInherits := []string{} + myInheritsSet := make(map[string]bool) + for _, inherit := range config.InheritNames { + if _, ok := myInheritsSet[inherit]; ok { + continue + } + myInherits = append(myInherits, inherit) + myInheritsSet[inherit] = true + iConfig, err := configs.GetReleaseConfig(inherit) + if err != nil { + return err + } + iConfig.GenerateReleaseConfig(configs) + contributionsToApply = append(contributionsToApply, iConfig.Contributions...) + } + contributionsToApply = append(contributionsToApply, config.Contributions...) + + myAconfigValueSets := []string{} + myFlags := configs.FlagArtifacts.Clone() + myDirsMap := make(map[int]bool) + for _, contrib := range contributionsToApply { + myAconfigValueSets = append(myAconfigValueSets, contrib.proto.AconfigValueSets...) + myDirsMap[contrib.DeclarationIndex] = true + for _, value := range contrib.FlagValues { + fa, ok := myFlags[*value.proto.Name] + if !ok { + return fmt.Errorf("Setting value for undefined flag %s in %s\n", *value.proto.Name, value.path) + } + myDirsMap[fa.DeclarationIndex] = true + if fa.DeclarationIndex > contrib.DeclarationIndex { + // Setting location is to the left of declaration. + return fmt.Errorf("Setting value for flag %s not allowed in %s\n", *value.proto.Name, value.path) + } + if err := fa.UpdateValue(*value); err != nil { + return err + } + } + } + + directories := []string{} + for idx, confDir := range configs.ConfigDirs { + if _, ok := myDirsMap[idx]; ok { + directories = append(directories, confDir) + } + } + + config.FlagArtifacts = myFlags + config.ReleaseConfigArtifact = &release_config_proto.ReleaseConfigArtifact{ + Name: proto.String(config.Name), + OtherNames: config.OtherNames, + FlagArtifacts: func() []*release_config_proto.FlagArtifact { + ret := []*release_config_proto.FlagArtifact{} + for _, flag := range myFlags { + ret = append(ret, &release_config_proto.FlagArtifact{ + FlagDeclaration: flag.FlagDeclaration, + Traces: flag.Traces, + Value: flag.Value, + }) + } + return ret + }(), + AconfigValueSets: myAconfigValueSets, + Inherits: myInherits, + Directories: directories, + } + + config.compileInProgress = false + return nil +} + +func main() { + var targetRelease string + var outputDir string + + outEnv := os.Getenv("OUT_DIR") + if outEnv == "" { + outEnv = "out" + } + defaultOutputDir := filepath.Join(outEnv, "soong", "release-config") + var defaultMapPaths StringList + defaultLocations := StringList{ + "build/release/release_config_map.textproto", + "vendor/google_shared/build/release/release_config_map.textproto", + "vendor/google/release/release_config_map.textproto", + } + for _, path := range defaultLocations { + if _, err := os.Stat(path); err == nil { + defaultMapPaths = append(defaultMapPaths, path) + } + } + prodMaps := os.Getenv("PRODUCT_RELEASE_CONFIG_MAPS") + if prodMaps != "" { + defaultMapPaths = append(defaultMapPaths, strings.Split(prodMaps, " ")...) + } + + flag.BoolVar(&verboseFlag, "debug", false, "print debugging information") + flag.Var(&releaseConfigMapPaths, "map", "path to a release_config_map.textproto. may be repeated") + flag.StringVar(&targetRelease, "release", "trunk_staging", "TARGET_RELEASE for this build") + flag.StringVar(&outputDir, "out_dir", defaultOutputDir, "basepath for the output. Multiple formats are created") + flag.Parse() + + if len(releaseConfigMapPaths) == 0 { + releaseConfigMapPaths = defaultMapPaths + fmt.Printf("No --map argument provided. Using: --map %s\n", strings.Join(releaseConfigMapPaths, " --map ")) + } + + configs := ReleaseConfigsFactory() + for idx, releaseConfigMapPath := range releaseConfigMapPaths { + // Maintain an ordered list of release config directories. + configDir := filepath.Dir(releaseConfigMapPath) + configs.ConfigDirIndexes[configDir] = idx + configs.ConfigDirs = append(configs.ConfigDirs, configDir) + err := configs.LoadReleaseConfigMap(releaseConfigMapPath, idx) + if err != nil { + panic(err) + } + } + + // Now that we have all of the release config maps, can meld them and generate the artifacts. + err := configs.GenerateReleaseConfigs(targetRelease) + if err != nil { + panic(err) + } + err = os.MkdirAll(outputDir, 0775) + if err != nil { + panic(err) + } + err = configs.DumpMakefile(outputDir, targetRelease) + if err != nil { + panic(err) + } + DumpProtos(outputDir, &configs.Artifact) +} diff --git a/cmd/release_config/release_config_proto/Android.bp b/cmd/release_config/release_config_proto/Android.bp new file mode 100644 index 000000000..a8660c753 --- /dev/null +++ b/cmd/release_config/release_config_proto/Android.bp @@ -0,0 +1,30 @@ +// 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 { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +bootstrap_go_package { + name: "soong-release_config_proto", + pkgPath: "android/soong/release_config/release_config_proto", + deps: [ + "golang-protobuf-reflect-protoreflect", + "golang-protobuf-runtime-protoimpl", + ], + srcs: [ + "build_flags_src.pb.go", + "build_flags_out.pb.go", + ], +} 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 new file mode 100644 index 000000000..adc1ea4bd --- /dev/null +++ b/cmd/release_config/release_config_proto/build_flags_out.pb.go @@ -0,0 +1,486 @@ +// 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.33.0 +// protoc v3.21.12 +// source: build_flags_out.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 Tracepoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Path to declaration or value file relative to $TOP + Source *string `protobuf:"bytes,1,opt,name=source" json:"source,omitempty"` + Value *Value `protobuf:"bytes,201,opt,name=value" json:"value,omitempty"` +} + +func (x *Tracepoint) Reset() { + *x = Tracepoint{} + if protoimpl.UnsafeEnabled { + mi := &file_build_flags_out_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Tracepoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Tracepoint) ProtoMessage() {} + +func (x *Tracepoint) ProtoReflect() protoreflect.Message { + mi := &file_build_flags_out_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 Tracepoint.ProtoReflect.Descriptor instead. +func (*Tracepoint) Descriptor() ([]byte, []int) { + return file_build_flags_out_proto_rawDescGZIP(), []int{0} +} + +func (x *Tracepoint) GetSource() string { + if x != nil && x.Source != nil { + return *x.Source + } + return "" +} + +func (x *Tracepoint) GetValue() *Value { + if x != nil { + return x.Value + } + return nil +} + +type FlagArtifact struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The original declaration + FlagDeclaration *FlagDeclaration `protobuf:"bytes,1,opt,name=flag_declaration,json=flagDeclaration" json:"flag_declaration,omitempty"` + // Value for the flag + Value *Value `protobuf:"bytes,201,opt,name=value" json:"value,omitempty"` + // Trace of where the flag value was assigned. + Traces []*Tracepoint `protobuf:"bytes,8,rep,name=traces" json:"traces,omitempty"` +} + +func (x *FlagArtifact) Reset() { + *x = FlagArtifact{} + if protoimpl.UnsafeEnabled { + mi := &file_build_flags_out_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FlagArtifact) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FlagArtifact) ProtoMessage() {} + +func (x *FlagArtifact) ProtoReflect() protoreflect.Message { + mi := &file_build_flags_out_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 FlagArtifact.ProtoReflect.Descriptor instead. +func (*FlagArtifact) Descriptor() ([]byte, []int) { + return file_build_flags_out_proto_rawDescGZIP(), []int{1} +} + +func (x *FlagArtifact) GetFlagDeclaration() *FlagDeclaration { + if x != nil { + return x.FlagDeclaration + } + return nil +} + +func (x *FlagArtifact) GetValue() *Value { + if x != nil { + return x.Value + } + return nil +} + +func (x *FlagArtifact) GetTraces() []*Tracepoint { + if x != nil { + return x.Traces + } + return nil +} + +type ReleaseConfigArtifact struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of the release config. + // See # name for format detail + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + // Other names by which this release is known (for example, `next`) + OtherNames []string `protobuf:"bytes,2,rep,name=other_names,json=otherNames" json:"other_names,omitempty"` + // The complete set of build flags in this release config, after all + // inheritance and other processing is complete. + FlagArtifacts []*FlagArtifact `protobuf:"bytes,3,rep,name=flag_artifacts,json=flagArtifacts" json:"flag_artifacts,omitempty"` + // The (complete) list of aconfig_value_sets Soong modules to use. + AconfigValueSets []string `protobuf:"bytes,4,rep,name=aconfig_value_sets,json=aconfigValueSets" json:"aconfig_value_sets,omitempty"` + // The names of the release_config_artifacts from which we inherited. + // Included for reference only. + Inherits []string `protobuf:"bytes,5,rep,name=inherits" json:"inherits,omitempty"` + // The release config directories used for this config. + // For example, "build/release". + Directories []string `protobuf:"bytes,6,rep,name=directories" json:"directories,omitempty"` +} + +func (x *ReleaseConfigArtifact) Reset() { + *x = ReleaseConfigArtifact{} + if protoimpl.UnsafeEnabled { + mi := &file_build_flags_out_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReleaseConfigArtifact) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReleaseConfigArtifact) ProtoMessage() {} + +func (x *ReleaseConfigArtifact) ProtoReflect() protoreflect.Message { + mi := &file_build_flags_out_proto_msgTypes[2] + 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 ReleaseConfigArtifact.ProtoReflect.Descriptor instead. +func (*ReleaseConfigArtifact) Descriptor() ([]byte, []int) { + return file_build_flags_out_proto_rawDescGZIP(), []int{2} +} + +func (x *ReleaseConfigArtifact) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +func (x *ReleaseConfigArtifact) GetOtherNames() []string { + if x != nil { + return x.OtherNames + } + return nil +} + +func (x *ReleaseConfigArtifact) GetFlagArtifacts() []*FlagArtifact { + if x != nil { + return x.FlagArtifacts + } + return nil +} + +func (x *ReleaseConfigArtifact) GetAconfigValueSets() []string { + if x != nil { + return x.AconfigValueSets + } + return nil +} + +func (x *ReleaseConfigArtifact) GetInherits() []string { + if x != nil { + return x.Inherits + } + return nil +} + +func (x *ReleaseConfigArtifact) GetDirectories() []string { + if x != nil { + return x.Directories + } + return nil +} + +type ReleaseConfigsArtifact struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The active release config for this build. + ReleaseConfig *ReleaseConfigArtifact `protobuf:"bytes,1,opt,name=release_config,json=releaseConfig" json:"release_config,omitempty"` + // All other release configs defined for this TARGET_PRODUCT. + OtherReleaseConfigs []*ReleaseConfigArtifact `protobuf:"bytes,2,rep,name=other_release_configs,json=otherReleaseConfigs" json:"other_release_configs,omitempty"` +} + +func (x *ReleaseConfigsArtifact) Reset() { + *x = ReleaseConfigsArtifact{} + if protoimpl.UnsafeEnabled { + mi := &file_build_flags_out_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReleaseConfigsArtifact) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReleaseConfigsArtifact) ProtoMessage() {} + +func (x *ReleaseConfigsArtifact) ProtoReflect() protoreflect.Message { + mi := &file_build_flags_out_proto_msgTypes[3] + 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 ReleaseConfigsArtifact.ProtoReflect.Descriptor instead. +func (*ReleaseConfigsArtifact) Descriptor() ([]byte, []int) { + return file_build_flags_out_proto_rawDescGZIP(), []int{3} +} + +func (x *ReleaseConfigsArtifact) GetReleaseConfig() *ReleaseConfigArtifact { + if x != nil { + return x.ReleaseConfig + } + return nil +} + +func (x *ReleaseConfigsArtifact) GetOtherReleaseConfigs() []*ReleaseConfigArtifact { + if x != nil { + return x.OtherReleaseConfigs + } + return nil +} + +var File_build_flags_out_proto protoreflect.FileDescriptor + +var file_build_flags_out_proto_rawDesc = []byte{ + 0x0a, 0x15, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5f, 0x6f, 0x75, + 0x74, 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, 0x15, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x66, 0x6c, 0x61, + 0x67, 0x73, 0x5f, 0x73, 0x72, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x60, 0x0a, 0x0a, + 0x74, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, + 0x63, 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, 0x22, 0xe8, + 0x01, 0x0a, 0x0d, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x12, 0x59, 0x0a, 0x10, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 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, 0x52, 0x0f, 0x66, 0x6c, 0x61, 0x67, + 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 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, 0x40, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x63, 0x65, + 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 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, 0x74, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x52, 0x06, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x22, 0x8e, 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, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, + 0x6f, 0x74, 0x68, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x52, 0x0a, 0x0e, 0x66, 0x6c, + 0x61, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x03, 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, 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, 0x12, 0x2c, + 0x0a, 0x12, 0x61, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, + 0x73, 0x65, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x65, 0x74, 0x73, 0x12, 0x1a, 0x0a, 0x08, + 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x73, 0x18, 0x05, 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, 0xe3, 0x01, 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, + 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_out_proto_rawDescOnce sync.Once + file_build_flags_out_proto_rawDescData = file_build_flags_out_proto_rawDesc +) + +func file_build_flags_out_proto_rawDescGZIP() []byte { + file_build_flags_out_proto_rawDescOnce.Do(func() { + file_build_flags_out_proto_rawDescData = protoimpl.X.CompressGZIP(file_build_flags_out_proto_rawDescData) + }) + return file_build_flags_out_proto_rawDescData +} + +var file_build_flags_out_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_build_flags_out_proto_goTypes = []interface{}{ + (*Tracepoint)(nil), // 0: android.release_config_proto.tracepoint + (*FlagArtifact)(nil), // 1: android.release_config_proto.flag_artifact + (*ReleaseConfigArtifact)(nil), // 2: android.release_config_proto.release_config_artifact + (*ReleaseConfigsArtifact)(nil), // 3: android.release_config_proto.release_configs_artifact + (*Value)(nil), // 4: android.release_config_proto.value + (*FlagDeclaration)(nil), // 5: android.release_config_proto.flag_declaration +} +var file_build_flags_out_proto_depIdxs = []int32{ + 4, // 0: android.release_config_proto.tracepoint.value:type_name -> android.release_config_proto.value + 5, // 1: android.release_config_proto.flag_artifact.flag_declaration:type_name -> android.release_config_proto.flag_declaration + 4, // 2: android.release_config_proto.flag_artifact.value:type_name -> android.release_config_proto.value + 0, // 3: android.release_config_proto.flag_artifact.traces:type_name -> android.release_config_proto.tracepoint + 1, // 4: android.release_config_proto.release_config_artifact.flag_artifacts:type_name -> android.release_config_proto.flag_artifact + 2, // 5: android.release_config_proto.release_configs_artifact.release_config:type_name -> android.release_config_proto.release_config_artifact + 2, // 6: android.release_config_proto.release_configs_artifact.other_release_configs:type_name -> android.release_config_proto.release_config_artifact + 7, // [7:7] is the sub-list for method output_type + 7, // [7:7] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_build_flags_out_proto_init() } +func file_build_flags_out_proto_init() { + if File_build_flags_out_proto != nil { + return + } + file_build_flags_src_proto_init() + if !protoimpl.UnsafeEnabled { + file_build_flags_out_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Tracepoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_build_flags_out_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FlagArtifact); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_build_flags_out_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReleaseConfigArtifact); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_build_flags_out_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReleaseConfigsArtifact); 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_out_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_build_flags_out_proto_goTypes, + DependencyIndexes: file_build_flags_out_proto_depIdxs, + MessageInfos: file_build_flags_out_proto_msgTypes, + }.Build() + File_build_flags_out_proto = out.File + file_build_flags_out_proto_rawDesc = nil + file_build_flags_out_proto_goTypes = nil + file_build_flags_out_proto_depIdxs = nil +} diff --git a/cmd/release_config/release_config_proto/build_flags_out.proto b/cmd/release_config/release_config_proto/build_flags_out.proto new file mode 100644 index 000000000..fd8487bd4 --- /dev/null +++ b/cmd/release_config/release_config_proto/build_flags_out.proto @@ -0,0 +1,86 @@ +// 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_src.proto"; + +// This protobuf file defines messages used to represent the release config for +// the android build system, delivered as a build artifact for use by tools 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 tracepoint { + // Path to declaration or value file relative to $TOP + optional string source = 1; + optional value value = 201; +} + +message flag_artifact { + // The original declaration + optional flag_declaration flag_declaration = 1; + + // Value for the flag + optional value value = 201; + + // Trace of where the flag value was assigned. + repeated tracepoint traces = 8; +} + +message release_config_artifact { + // The name of the release config. + // See # name for format detail + optional string name = 1; + + // Other names by which this release is known (for example, `next`) + repeated string other_names = 2; + + // The complete set of build flags in this release config, after all + // inheritance and other processing is complete. + repeated flag_artifact flag_artifacts = 3; + + // The (complete) list of aconfig_value_sets Soong modules to use. + repeated string aconfig_value_sets = 4; + + // The names of the release_config_artifacts from which we inherited. + // Included for reference only. + repeated string inherits = 5; + + // The release config directories used for this config. + // For example, "build/release". + repeated string directories = 6; +} + +message release_configs_artifact { + // The active release config for this build. + optional release_config_artifact release_config = 1; + + // All other release configs defined for this TARGET_PRODUCT. + repeated release_config_artifact other_release_configs = 2; +} + 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 new file mode 100644 index 000000000..0f2c30b76 --- /dev/null +++ b/cmd/release_config/release_config_proto/build_flags_src.pb.go @@ -0,0 +1,855 @@ +// 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.33.0 +// protoc v3.21.12 +// source: build_flags_src.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_UNSPECIFIED_workflow 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: "UNSPECIFIED_workflow", + 1: "LAUNCH", + 2: "PREBUILT", + 3: "MANUAL", + } + Workflow_value = map[string]int32{ + "UNSPECIFIED_workflow": 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 Container int32 + +const ( + Container_UNSPECIFIED_container Container = 0 + // All containers + Container_ALL Container = 1 + // Specific containers + Container_PRODUCT Container = 2 + Container_SYSTEM Container = 3 + Container_SYSTEM_EXT Container = 4 + Container_VENDOR Container = 5 +) + +// Enum value maps for Container. +var ( + Container_name = map[int32]string{ + 0: "UNSPECIFIED_container", + 1: "ALL", + 2: "PRODUCT", + 3: "SYSTEM", + 4: "SYSTEM_EXT", + 5: "VENDOR", + } + Container_value = map[string]int32{ + "UNSPECIFIED_container": 0, + "ALL": 1, + "PRODUCT": 2, + "SYSTEM": 3, + "SYSTEM_EXT": 4, + "VENDOR": 5, + } +) + +func (x Container) Enum() *Container { + p := new(Container) + *p = x + return p +} + +func (x Container) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Container) Descriptor() protoreflect.EnumDescriptor { + return file_build_flags_src_proto_enumTypes[1].Descriptor() +} + +func (Container) Type() protoreflect.EnumType { + return &file_build_flags_src_proto_enumTypes[1] +} + +func (x Container) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *Container) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = Container(num) + return nil +} + +// Deprecated: Use Container.Descriptor instead. +func (Container) EnumDescriptor() ([]byte, []int) { + return file_build_flags_src_proto_rawDescGZIP(), []int{1} +} + +type Value struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Val: + // + // *Value_UnspecifiedValue + // *Value_StringValue + // *Value_BoolValue + // *Value_Obsolete + Val isValue_Val `protobuf_oneof:"val"` +} + +func (x *Value) Reset() { + *x = Value{} + if protoimpl.UnsafeEnabled { + mi := &file_build_flags_src_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Value) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Value) ProtoMessage() {} + +func (x *Value) ProtoReflect() protoreflect.Message { + mi := &file_build_flags_src_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 Value.ProtoReflect.Descriptor instead. +func (*Value) Descriptor() ([]byte, []int) { + return file_build_flags_src_proto_rawDescGZIP(), []int{0} +} + +func (m *Value) GetVal() isValue_Val { + if m != nil { + return m.Val + } + return nil +} + +func (x *Value) GetUnspecifiedValue() bool { + if x, ok := x.GetVal().(*Value_UnspecifiedValue); ok { + return x.UnspecifiedValue + } + return false +} + +func (x *Value) GetStringValue() string { + if x, ok := x.GetVal().(*Value_StringValue); ok { + return x.StringValue + } + return "" +} + +func (x *Value) GetBoolValue() bool { + if x, ok := x.GetVal().(*Value_BoolValue); ok { + return x.BoolValue + } + return false +} + +func (x *Value) GetObsolete() bool { + if x, ok := x.GetVal().(*Value_Obsolete); ok { + return x.Obsolete + } + return false +} + +type isValue_Val interface { + isValue_Val() +} + +type Value_UnspecifiedValue struct { + UnspecifiedValue bool `protobuf:"varint,200,opt,name=unspecified_value,json=unspecifiedValue,oneof"` +} + +type Value_StringValue struct { + StringValue string `protobuf:"bytes,201,opt,name=string_value,json=stringValue,oneof"` +} + +type Value_BoolValue struct { + BoolValue bool `protobuf:"varint,202,opt,name=bool_value,json=boolValue,oneof"` +} + +type Value_Obsolete struct { + // If true, the flag is obsolete. Assigning it further will be flagged. + Obsolete bool `protobuf:"varint,203,opt,name=obsolete,oneof"` +} + +func (*Value_UnspecifiedValue) isValue_Val() {} + +func (*Value_StringValue) isValue_Val() {} + +func (*Value_BoolValue) isValue_Val() {} + +func (*Value_Obsolete) isValue_Val() {} + +// The proto used in the source tree. +type FlagDeclaration 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"` + // Text description of the flag's purpose. + Description *string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"` + // Value for the flag + Value *Value `protobuf:"bytes,201,opt,name=value" json:"value,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. + Container *Container `protobuf:"varint,206,opt,name=container,enum=android.release_config_proto.Container" json:"container,omitempty"` + // Temporarily allow origin at the flag declaration level while we + // move flags to their own locations. + Origin *string `protobuf:"bytes,208,opt,name=origin" json:"origin,omitempty"` +} + +func (x *FlagDeclaration) Reset() { + *x = FlagDeclaration{} + if protoimpl.UnsafeEnabled { + mi := &file_build_flags_src_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FlagDeclaration) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FlagDeclaration) ProtoMessage() {} + +func (x *FlagDeclaration) ProtoReflect() protoreflect.Message { + mi := &file_build_flags_src_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 FlagDeclaration.ProtoReflect.Descriptor instead. +func (*FlagDeclaration) Descriptor() ([]byte, []int) { + return file_build_flags_src_proto_rawDescGZIP(), []int{1} +} + +func (x *FlagDeclaration) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +func (x *FlagDeclaration) GetDescription() string { + if x != nil && x.Description != nil { + return *x.Description + } + return "" +} + +func (x *FlagDeclaration) GetValue() *Value { + if x != nil { + return x.Value + } + return nil +} + +func (x *FlagDeclaration) GetWorkflow() Workflow { + if x != nil && x.Workflow != nil { + return *x.Workflow + } + return Workflow_UNSPECIFIED_workflow +} + +func (x *FlagDeclaration) GetContainer() Container { + if x != nil && x.Container != nil { + return *x.Container + } + return Container_UNSPECIFIED_container +} + +func (x *FlagDeclaration) GetOrigin() string { + if x != nil && x.Origin != nil { + return *x.Origin + } + return "" +} + +type FlagValue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name of the flag. + // See # name for format detail + Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + // Value for the flag + Value *Value `protobuf:"bytes,201,opt,name=value" json:"value,omitempty"` +} + +func (x *FlagValue) Reset() { + *x = FlagValue{} + if protoimpl.UnsafeEnabled { + mi := &file_build_flags_src_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FlagValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FlagValue) ProtoMessage() {} + +func (x *FlagValue) ProtoReflect() protoreflect.Message { + mi := &file_build_flags_src_proto_msgTypes[2] + 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 FlagValue.ProtoReflect.Descriptor instead. +func (*FlagValue) Descriptor() ([]byte, []int) { + return file_build_flags_src_proto_rawDescGZIP(), []int{2} +} + +func (x *FlagValue) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +func (x *FlagValue) GetValue() *Value { + if x != nil { + return x.Value + } + return nil +} + +// This replaces $(call declare-release-config). +type ReleaseConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of the release config. + // See # name for format detail + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + // From which other release configs does this one inherit? + Inherits []string `protobuf:"bytes,2,rep,name=inherits" json:"inherits,omitempty"` + // List of names of the aconfig_value_set soong module(s) for this + // contribution. + AconfigValueSets []string `protobuf:"bytes,3,rep,name=aconfig_value_sets,json=aconfigValueSets" json:"aconfig_value_sets,omitempty"` +} + +func (x *ReleaseConfig) Reset() { + *x = ReleaseConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_build_flags_src_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReleaseConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReleaseConfig) ProtoMessage() {} + +func (x *ReleaseConfig) ProtoReflect() protoreflect.Message { + mi := &file_build_flags_src_proto_msgTypes[3] + 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 ReleaseConfig.ProtoReflect.Descriptor instead. +func (*ReleaseConfig) Descriptor() ([]byte, []int) { + return file_build_flags_src_proto_rawDescGZIP(), []int{3} +} + +func (x *ReleaseConfig) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +func (x *ReleaseConfig) GetInherits() []string { + if x != nil { + return x.Inherits + } + return nil +} + +func (x *ReleaseConfig) GetAconfigValueSets() []string { + if x != nil { + return x.AconfigValueSets + } + return nil +} + +// Any aliases. These are used for continuous integration builder config. +type ReleaseAlias struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of the alias. + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + // The release that `name` is an alias for. + Target *string `protobuf:"bytes,2,opt,name=target" json:"target,omitempty"` +} + +func (x *ReleaseAlias) Reset() { + *x = ReleaseAlias{} + if protoimpl.UnsafeEnabled { + mi := &file_build_flags_src_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReleaseAlias) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReleaseAlias) ProtoMessage() {} + +func (x *ReleaseAlias) ProtoReflect() protoreflect.Message { + mi := &file_build_flags_src_proto_msgTypes[4] + 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 ReleaseAlias.ProtoReflect.Descriptor instead. +func (*ReleaseAlias) Descriptor() ([]byte, []int) { + return file_build_flags_src_proto_rawDescGZIP(), []int{4} +} + +func (x *ReleaseAlias) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +func (x *ReleaseAlias) GetTarget() string { + if x != nil && x.Target != nil { + return *x.Target + } + return "" +} + +// This provides the data from release_config_map.mk +type ReleaseConfigMap struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Any aliases. + Aliases []*ReleaseAlias `protobuf:"bytes,1,rep,name=aliases" json:"aliases,omitempty"` + // The origin for flags declared here. + Origin *string `protobuf:"bytes,2,opt,name=origin" json:"origin,omitempty"` + // The default container for flags declared here. + DefaultContainer *Container `protobuf:"varint,3,opt,name=default_container,json=defaultContainer,enum=android.release_config_proto.Container" json:"default_container,omitempty"` +} + +func (x *ReleaseConfigMap) Reset() { + *x = ReleaseConfigMap{} + if protoimpl.UnsafeEnabled { + mi := &file_build_flags_src_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReleaseConfigMap) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReleaseConfigMap) ProtoMessage() {} + +func (x *ReleaseConfigMap) ProtoReflect() protoreflect.Message { + mi := &file_build_flags_src_proto_msgTypes[5] + 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 ReleaseConfigMap.ProtoReflect.Descriptor instead. +func (*ReleaseConfigMap) Descriptor() ([]byte, []int) { + return file_build_flags_src_proto_rawDescGZIP(), []int{5} +} + +func (x *ReleaseConfigMap) GetAliases() []*ReleaseAlias { + if x != nil { + return x.Aliases + } + return nil +} + +func (x *ReleaseConfigMap) GetOrigin() string { + if x != nil && x.Origin != nil { + return *x.Origin + } + return "" +} + +func (x *ReleaseConfigMap) GetDefaultContainer() Container { + if x != nil && x.DefaultContainer != nil { + return *x.DefaultContainer + } + return Container_UNSPECIFIED_container +} + +var File_build_flags_src_proto protoreflect.FileDescriptor + +var file_build_flags_src_proto_rawDesc = []byte{ + 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, 0xb8, 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, 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, 0x46, 0x0a, 0x09, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0xce, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 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, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x12, 0x17, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0xd0, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, + 0x4a, 0x06, 0x08, 0xcf, 0x01, 0x10, 0xd0, 0x01, 0x22, 0x5c, 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, 0x22, 0x6e, 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, 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, 0xc9, 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, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x54, 0x0a, 0x11, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 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, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x10, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2a, + 0x4a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x18, 0x0a, 0x14, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 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, 0x2a, 0x64, 0x0a, 0x09, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x15, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4c, 0x4c, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, + 0x50, 0x52, 0x4f, 0x44, 0x55, 0x43, 0x54, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x59, 0x53, + 0x54, 0x45, 0x4d, 0x10, 0x03, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, + 0x45, 0x58, 0x54, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x56, 0x45, 0x4e, 0x44, 0x4f, 0x52, 0x10, + 0x05, 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_src_proto_rawDescOnce sync.Once + file_build_flags_src_proto_rawDescData = file_build_flags_src_proto_rawDesc +) + +func file_build_flags_src_proto_rawDescGZIP() []byte { + file_build_flags_src_proto_rawDescOnce.Do(func() { + file_build_flags_src_proto_rawDescData = protoimpl.X.CompressGZIP(file_build_flags_src_proto_rawDescData) + }) + return file_build_flags_src_proto_rawDescData +} + +var file_build_flags_src_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +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 + (Container)(0), // 1: android.release_config_proto.container + (*Value)(nil), // 2: android.release_config_proto.value + (*FlagDeclaration)(nil), // 3: android.release_config_proto.flag_declaration + (*FlagValue)(nil), // 4: android.release_config_proto.flag_value + (*ReleaseConfig)(nil), // 5: android.release_config_proto.release_config + (*ReleaseAlias)(nil), // 6: android.release_config_proto.release_alias + (*ReleaseConfigMap)(nil), // 7: android.release_config_proto.release_config_map +} +var file_build_flags_src_proto_depIdxs = []int32{ + 2, // 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_declaration.container:type_name -> android.release_config_proto.container + 2, // 3: android.release_config_proto.flag_value.value:type_name -> android.release_config_proto.value + 6, // 4: android.release_config_proto.release_config_map.aliases:type_name -> android.release_config_proto.release_alias + 1, // 5: android.release_config_proto.release_config_map.default_container:type_name -> android.release_config_proto.container + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name +} + +func init() { file_build_flags_src_proto_init() } +func file_build_flags_src_proto_init() { + if File_build_flags_src_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_build_flags_src_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Value); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_build_flags_src_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FlagDeclaration); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_build_flags_src_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FlagValue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_build_flags_src_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReleaseConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_build_flags_src_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReleaseAlias); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_build_flags_src_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReleaseConfigMap); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_build_flags_src_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*Value_UnspecifiedValue)(nil), + (*Value_StringValue)(nil), + (*Value_BoolValue)(nil), + (*Value_Obsolete)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_build_flags_src_proto_rawDesc, + NumEnums: 2, + 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 + file_build_flags_src_proto_rawDesc = nil + file_build_flags_src_proto_goTypes = nil + file_build_flags_src_proto_depIdxs = nil +} diff --git a/cmd/release_config/release_config_proto/build_flags_src.proto b/cmd/release_config/release_config_proto/build_flags_src.proto new file mode 100644 index 000000000..0662716d5 --- /dev/null +++ b/cmd/release_config/release_config_proto/build_flags_src.proto @@ -0,0 +1,154 @@ +// 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 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. +// +// 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 + +enum workflow { + UNSPECIFIED_workflow = 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; +} + +enum container { + UNSPECIFIED_container = 0; + + // All containers + ALL = 1; + + // Specific containers + PRODUCT = 2; + SYSTEM = 3; + SYSTEM_EXT = 4; + VENDOR = 5; +} + +message value { + oneof val { + bool unspecified_value = 200; + string string_value = 201; + bool bool_value = 202; + // If true, the flag is obsolete. Assigning it further will be flagged. + bool obsolete = 203; + } +} + +// The proto used in the source tree. +message flag_declaration { + // The name of the flag. + // See # name for format detail + optional string name = 1; + + // Text description of the flag's purpose. + optional string description = 3; + + // reserve this for bug, if needed. + reserved 4; + + // Value for the flag + optional value value = 201; + + // 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. + optional container container = 206; + + // The package associated with this flag. + // (when Gantry is ready for it) optional string package = 207; + reserved 207; + + // Temporarily allow origin at the flag declaration level while we + // move flags to their own locations. + optional string origin = 208; + + // TODO: do we want to include "first used in" (= ap2a)? +} + +message flag_value { + // Name of the flag. + // See # name for format detail + optional string name = 2; + + // Value for the flag + optional value value = 201; +} + +// This replaces $(call declare-release-config). +message release_config { + // The name of the release config. + // See # name for format detail + optional string name = 1; + + // From which other release configs does this one inherit? + repeated string inherits = 2; + + // List of names of the aconfig_value_set soong module(s) for this + // contribution. + repeated string aconfig_value_sets = 3; +} + +// Any aliases. These are used for continuous integration builder config. +message release_alias { + // The name of the alias. + optional string name = 1; + + // The release that `name` is an alias for. + optional string target = 2; +} + +// This provides the data from release_config_map.mk +message release_config_map { + // Any aliases. + repeated release_alias aliases = 1; + + // The origin for flags declared here. + optional string origin = 2; + + // The default container for flags declared here. + optional container default_container = 3; + + // If needed, we can add these fields instead of hardcoding the location. + // Flag declarations: `flag_declarations/*.textproto` + // Release config contributions: `release_configs/*.textproto` + // Flag values: `flag_values/{RELEASE_NAME}/*.textproto` +} diff --git a/cmd/release_config/release_config_proto/regen.sh b/cmd/release_config/release_config_proto/regen.sh new file mode 100644 index 000000000..1846c4d87 --- /dev/null +++ b/cmd/release_config/release_config_proto/regen.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +aprotoc --go_out=paths=source_relative:. build_flags_src.proto build_flags_out.proto diff --git a/java/aar.go b/java/aar.go index fef0d8c58..a36626732 100644 --- a/java/aar.go +++ b/java/aar.go @@ -922,7 +922,8 @@ func AndroidLibraryFactory() android.Module { module.Module.addHostAndDeviceProperties() module.AddProperties( &module.aaptProperties, - &module.androidLibraryProperties) + &module.androidLibraryProperties, + &module.sourceProperties) module.androidLibraryProperties.BuildAAR = true module.Module.linter.library = true @@ -978,6 +979,7 @@ type AARImport struct { headerJarFile android.WritablePath implementationJarFile android.WritablePath + implementationAndResourcesJarFile android.WritablePath proguardFlags android.WritablePath exportPackage android.WritablePath transitiveAaptResourcePackagesFile android.Path @@ -1013,7 +1015,7 @@ func (a *AARImport) OutputFiles(tag string) (android.Paths, error) { case ".aar": return []android.Path{a.aarPath}, nil case "": - return []android.Path{a.implementationJarFile}, nil + return []android.Path{a.implementationAndResourcesJarFile}, nil default: return nil, fmt.Errorf("unsupported module reference tag %q", tag) } @@ -1155,8 +1157,9 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { TransformJetifier(ctx, a.aarPath.(android.WritablePath), inputFile) } + jarName := ctx.ModuleName() + ".jar" extractedAARDir := android.PathForModuleOut(ctx, "aar") - classpathFile := extractedAARDir.Join(ctx, ctx.ModuleName()+".jar") + classpathFile := extractedAARDir.Join(ctx, jarName) a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml") a.rTxt = extractedAARDir.Join(ctx, "R.txt") a.assetsPackage = android.PathForModuleOut(ctx, "assets.zip") @@ -1272,6 +1275,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { var staticJars android.Paths var staticHeaderJars android.Paths + var staticResourceJars android.Paths ctx.VisitDirectDeps(func(module android.Module) { if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { tag := ctx.OtherModuleDependencyTag(module) @@ -1279,6 +1283,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { case staticLibTag: staticJars = append(staticJars, dep.ImplementationJars...) staticHeaderJars = append(staticHeaderJars, dep.HeaderJars...) + staticResourceJars = append(staticResourceJars, dep.ResourceJars...) } } addCLCFromDep(ctx, module, a.classLoaderContexts) @@ -1287,18 +1292,39 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { var implementationJarFile android.OutputPath if len(staticJars) > 0 { combineJars := append(android.Paths{classpathFile}, staticJars...) - implementationJarFile = android.PathForModuleOut(ctx, "combined", ctx.ModuleName()+".jar").OutputPath + implementationJarFile = android.PathForModuleOut(ctx, "combined", jarName).OutputPath TransformJarsToJar(ctx, implementationJarFile, "combine", combineJars, android.OptionalPath{}, false, nil, nil) } else { implementationJarFile = classpathFile } + var resourceJarFile android.Path + if len(staticResourceJars) > 1 { + combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName) + TransformJarsToJar(ctx, combinedJar, "for resources", staticResourceJars, android.OptionalPath{}, + false, nil, nil) + resourceJarFile = combinedJar + } else if len(staticResourceJars) == 1 { + resourceJarFile = staticResourceJars[0] + } + + // merge implementation jar with resources if necessary + implementationAndResourcesJar := implementationJarFile + if resourceJarFile != nil { + jars := android.Paths{resourceJarFile, implementationAndResourcesJar} + combinedJar := android.PathForModuleOut(ctx, "withres", jarName).OutputPath + TransformJarsToJar(ctx, combinedJar, "for resources", jars, android.OptionalPath{}, + false, nil, nil) + implementationAndResourcesJar = combinedJar + } + + a.implementationJarFile = implementationJarFile // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource - a.implementationJarFile = implementationJarFile.WithoutRel() + a.implementationAndResourcesJarFile = implementationAndResourcesJar.WithoutRel() if len(staticHeaderJars) > 0 { combineJars := append(android.Paths{classpathFile}, staticHeaderJars...) - a.headerJarFile = android.PathForModuleOut(ctx, "turbine-combined", ctx.ModuleName()+".jar") + a.headerJarFile = android.PathForModuleOut(ctx, "turbine-combined", jarName) TransformJarsToJar(ctx, a.headerJarFile, "combine header jars", combineJars, android.OptionalPath{}, false, nil, nil) } else { a.headerJarFile = classpathFile @@ -1306,9 +1332,10 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { android.SetProvider(ctx, JavaInfoProvider, JavaInfo{ HeaderJars: android.PathsIfNonNil(a.headerJarFile), + ResourceJars: android.PathsIfNonNil(resourceJarFile), TransitiveLibsHeaderJars: a.transitiveLibsHeaderJars, TransitiveStaticLibsHeaderJars: a.transitiveStaticLibsHeaderJars, - ImplementationAndResourcesJars: android.PathsIfNonNil(a.implementationJarFile), + ImplementationAndResourcesJars: android.PathsIfNonNil(a.implementationAndResourcesJarFile), ImplementationJars: android.PathsIfNonNil(a.implementationJarFile), StubsLinkType: Implementation, // TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts @@ -1346,7 +1373,7 @@ func (a *AARImport) HeaderJars() android.Paths { } func (a *AARImport) ImplementationAndResourcesJars() android.Paths { - return android.Paths{a.implementationJarFile} + return android.Paths{a.implementationAndResourcesJarFile} } func (a *AARImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath { diff --git a/java/aar_test.go b/java/aar_test.go index 3361bf929..d6dbe3c25 100644 --- a/java/aar_test.go +++ b/java/aar_test.go @@ -136,18 +136,19 @@ func TestAndroidLibraryOutputFilesRel(t *testing.T) { android_library { name: "foo", srcs: ["a.java"], + java_resources: ["foo.txt"], } android_library_import { name: "bar", - aars: ["bar.aar"], + aars: ["bar_prebuilt.aar"], } android_library_import { name: "baz", - aars: ["baz.aar"], - static_libs: ["bar"], + aars: ["baz_prebuilt.aar"], + static_libs: ["foo", "bar"], } `) @@ -160,11 +161,11 @@ func TestAndroidLibraryOutputFilesRel(t *testing.T) { bazOutputPath := android.OutputFileForModule(android.PathContext(nil), baz.Module(), "") android.AssertPathRelativeToTopEquals(t, "foo output path", - "out/soong/.intermediates/foo/android_common/javac/foo.jar", fooOutputPath) + "out/soong/.intermediates/foo/android_common/withres/foo.jar", fooOutputPath) android.AssertPathRelativeToTopEquals(t, "bar output path", "out/soong/.intermediates/bar/android_common/aar/bar.jar", barOutputPath) android.AssertPathRelativeToTopEquals(t, "baz output path", - "out/soong/.intermediates/baz/android_common/combined/baz.jar", bazOutputPath) + "out/soong/.intermediates/baz/android_common/withres/baz.jar", bazOutputPath) android.AssertStringEquals(t, "foo relative output path", "foo.jar", fooOutputPath.Rel()) diff --git a/java/app.go b/java/app.go index 7b2577538..1aa3afe8e 100755..100644 --- a/java/app.go +++ b/java/app.go @@ -329,6 +329,10 @@ func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleCon a.aapt.manifestValues.applicationId = *applicationId } a.generateAndroidBuildActions(ctx) + android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{ + TestOnly: true, + }) + } func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -1191,7 +1195,8 @@ func AndroidAppFactory() android.Module { module.AddProperties( &module.aaptProperties, &module.appProperties, - &module.overridableAppProperties) + &module.overridableAppProperties, + &module.Library.sourceProperties) module.usesLibrary.enforce = true @@ -1340,6 +1345,11 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { TestSuites: a.testProperties.Test_suites, IsHost: false, }) + android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{ + TestOnly: true, + TopLevelTarget: true, + }) + } func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path { @@ -1532,9 +1542,13 @@ type OverrideAndroidTest struct { android.OverrideModuleBase } -func (i *OverrideAndroidTest) GenerateAndroidBuildActions(_ android.ModuleContext) { +func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { // All the overrides happen in the base module. // TODO(jungjw): Check the base module type. + android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{ + TestOnly: true, + TopLevelTarget: true, + }) } // override_android_test is used to create an android_app module based on another android_test by overriding diff --git a/java/app_test.go b/java/app_test.go index 8262777b2..0c2800041 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -4432,6 +4432,44 @@ func TestNoDexpreoptOptionalUsesLibDoesNotHaveImpl(t *testing.T) { android.AssertBoolEquals(t, "dexpreopt should be disabled if optional_uses_libs does not have an implementation", true, dexpreopt == nil) } +func TestTestOnlyApp(t *testing.T) { + t.Parallel() + ctx := android.GroupFixturePreparers( + prepareForJavaTest, + ).RunTestWithBp(t, ` + // These should be test-only + android_test { + name: "android-test", + } + android_test_helper_app { + name: "helper-app", + } + override_android_test { + name: "override-test", + base: "android-app", + } + // And these should not be + android_app { + name: "android-app", + srcs: ["b.java"], + sdk_version: "current", + } + `) + + expectedTestOnly := []string{ + "android-test", + "helper-app", + "override-test", + } + + expectedTopLevel := []string{ + "android-test", + "override-test", + } + + assertTestOnlyAndTopLevel(t, ctx, expectedTestOnly, expectedTopLevel) +} + func TestAppStem(t *testing.T) { ctx := testApp(t, ` android_app { diff --git a/java/base.go b/java/base.go index e2f20cee5..ef61f1cc2 100644 --- a/java/base.go +++ b/java/base.go @@ -197,6 +197,9 @@ type CommonProperties struct { // Additional srcJars tacked in by GeneratedJavaLibraryModule Generated_srcjars []android.Path `android:"mutated"` + // intermediate aconfig cache file tacked in by GeneratedJavaLibraryModule + Aconfig_Cache_files []android.Path `android:"mutated"` + // If true, then only the headers are built and not the implementation jar. Headers_only *bool @@ -432,6 +435,7 @@ type Module struct { deviceProperties DeviceProperties overridableProperties OverridableProperties + sourceProperties android.SourceProperties // jar file containing header classes including static library dependencies, suitable for // inserting into the bootclasspath/classpath of another compile @@ -541,6 +545,11 @@ type Module struct { jarjarRenameRules map[string]string stubsLinkType StubsLinkType + + // Paths to the aconfig intermediate cache files that are provided by the + // java_aconfig_library or java_library modules that are statically linked + // to this module. Does not contain cache files from all transitive dependencies. + aconfigCacheFiles android.Paths } func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error { @@ -1197,6 +1206,8 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath // final R classes from the app. flags.classpath = append(android.CopyOf(extraClasspathJars), flags.classpath...) + j.aconfigCacheFiles = append(deps.aconfigProtoFiles, j.properties.Aconfig_Cache_files...) + // If compiling headers then compile them and skip the rest if proptools.Bool(j.properties.Headers_only) { if srcFiles.HasExt(".kt") { @@ -1736,7 +1747,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath ExportedPluginDisableTurbine: j.exportedDisableTurbine, JacocoReportClassesFile: j.jacocoReportClassesFile, StubsLinkType: j.stubsLinkType, - AconfigIntermediateCacheOutputPaths: deps.aconfigProtoFiles, + AconfigIntermediateCacheOutputPaths: j.aconfigCacheFiles, }) // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource @@ -2350,7 +2361,10 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...) } } else if dep, ok := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider); ok { - deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...) + switch tag { + case staticLibTag: + deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...) + } } else { switch tag { case bootClasspathTag: diff --git a/java/device_host_converter_test.go b/java/device_host_converter_test.go index 3413da03d..6ccc5c1b1 100644 --- a/java/device_host_converter_test.go +++ b/java/device_host_converter_test.go @@ -16,7 +16,7 @@ package java import ( "android/soong/android" - "reflect" + "slices" "strings" "testing" ) @@ -84,7 +84,7 @@ func TestDeviceForHost(t *testing.T) { deviceImportCombined.Output, } - if !reflect.DeepEqual(combined.Inputs, expectedInputs) { + if !slices.Equal(combined.Inputs.Strings(), expectedInputs.Strings()) { t.Errorf("expected host_module combined inputs:\n%q\ngot:\n%q", expectedInputs, combined.Inputs) } @@ -95,7 +95,7 @@ func TestDeviceForHost(t *testing.T) { deviceRes.Output, } - if !reflect.DeepEqual(resCombined.Inputs, expectedInputs) { + if !slices.Equal(resCombined.Inputs.Strings(), expectedInputs.Strings()) { t.Errorf("expected host_module res combined inputs:\n%q\ngot:\n%q", expectedInputs, resCombined.Inputs) } @@ -165,7 +165,7 @@ func TestHostForDevice(t *testing.T) { hostImportCombined.Output, } - if !reflect.DeepEqual(combined.Inputs, expectedInputs) { + if !slices.Equal(combined.Inputs.Strings(), expectedInputs.Strings()) { t.Errorf("expected device_module combined inputs:\n%q\ngot:\n%q", expectedInputs, combined.Inputs) } @@ -176,7 +176,7 @@ func TestHostForDevice(t *testing.T) { hostRes.Output, } - if !reflect.DeepEqual(resCombined.Inputs, expectedInputs) { + if !slices.Equal(resCombined.Inputs.Strings(), expectedInputs.Strings()) { t.Errorf("expected device_module res combined inputs:\n%q\ngot:\n%q", expectedInputs, resCombined.Inputs) } diff --git a/java/droiddoc.go b/java/droiddoc.go index aec40b312..176779eb4 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -391,12 +391,14 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps { } else if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { deps.classpath = append(deps.classpath, dep.HeaderJars...) deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...) + deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.AconfigIntermediateCacheOutputPaths...) } else if dep, ok := module.(android.SourceFileProducer); ok { checkProducesJars(ctx, dep) deps.classpath = append(deps.classpath, dep.Srcs()...) } else { ctx.ModuleErrorf("depends on non-java module %q", otherName) } + case java9LibTag: if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...) @@ -429,6 +431,19 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps { srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs) j.implicits = append(j.implicits, srcFiles...) + // Module can depend on a java_aconfig_library module using the ":module_name{.tag}" syntax. + // Find the corresponding aconfig_declarations module name for such case. + for _, src := range j.properties.Srcs { + if moduleName, tag := android.SrcIsModuleWithTag(src); moduleName != "" { + otherModule := android.GetModuleFromPathDep(ctx, moduleName, tag) + if otherModule != nil { + if dep, ok := android.OtherModuleProvider(ctx, otherModule, android.CodegenInfoProvider); ok { + deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...) + } + } + } + } + filterByPackage := func(srcs []android.Path, filterPackages []string) []android.Path { if filterPackages == nil { return srcs diff --git a/java/fuzz.go b/java/fuzz.go index dc4c6bec5..fb31ce794 100644 --- a/java/fuzz.go +++ b/java/fuzz.go @@ -64,6 +64,8 @@ func JavaFuzzFactory() android.Module { module.Module.properties.Installable = proptools.BoolPtr(true) module.Module.dexpreopter.isTest = true module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true) + module.Module.sourceProperties.Test_only = proptools.BoolPtr(true) + module.Module.sourceProperties.Top_level_test_target = true android.AddLoadHook(module, func(ctx android.LoadHookContext) { disableLinuxBionic := struct { diff --git a/java/generated_java_library.go b/java/generated_java_library.go index e8316ccc4..d5e6d8fec 100644 --- a/java/generated_java_library.go +++ b/java/generated_java_library.go @@ -34,7 +34,7 @@ type GeneratedJavaLibraryCallbacks interface { // Called from inside GenerateAndroidBuildActions. Add the build rules to // make the srcjar, and return the path to it. - GenerateSourceJarBuildActions(module *GeneratedJavaLibraryModule, ctx android.ModuleContext) android.Path + GenerateSourceJarBuildActions(module *GeneratedJavaLibraryModule, ctx android.ModuleContext) (android.Path, android.Path) } // GeneratedJavaLibraryModuleFactory provides a utility for modules that are generated @@ -103,8 +103,10 @@ func (module *GeneratedJavaLibraryModule) GenerateAndroidBuildActions(ctx androi checkPropertyEmpty(ctx, module, "plugins", module.Library.properties.Plugins) checkPropertyEmpty(ctx, module, "exported_plugins", module.Library.properties.Exported_plugins) - srcJarPath := module.callbacks.GenerateSourceJarBuildActions(module, ctx) + srcJarPath, cacheOutputPath := module.callbacks.GenerateSourceJarBuildActions(module, ctx) + module.Library.properties.Generated_srcjars = append(module.Library.properties.Generated_srcjars, srcJarPath) + module.Library.properties.Aconfig_Cache_files = append(module.Library.properties.Aconfig_Cache_files, cacheOutputPath) module.Library.GenerateAndroidBuildActions(ctx) } diff --git a/java/generated_java_library_test.go b/java/generated_java_library_test.go index be816cda9..a5c4be111 100644 --- a/java/generated_java_library_test.go +++ b/java/generated_java_library_test.go @@ -36,8 +36,8 @@ type JavaGenLibTestCallbacks struct { func (callbacks *JavaGenLibTestCallbacks) DepsMutator(module *GeneratedJavaLibraryModule, ctx android.BottomUpMutatorContext) { } -func (callbacks *JavaGenLibTestCallbacks) GenerateSourceJarBuildActions(module *GeneratedJavaLibraryModule, ctx android.ModuleContext) android.Path { - return android.PathForOutput(ctx, "blah.srcjar") +func (callbacks *JavaGenLibTestCallbacks) GenerateSourceJarBuildActions(module *GeneratedJavaLibraryModule, ctx android.ModuleContext) (android.Path, android.Path) { + return android.PathForOutput(ctx, "blah.srcjar"), android.PathForOutput(ctx, "blah.pb") } func testGenLib(t *testing.T, errorHandler android.FixtureErrorHandler, bp string) *android.TestResult { diff --git a/java/java.go b/java/java.go index fb5bb1cae..ca99e6991 100644 --- a/java/java.go +++ b/java/java.go @@ -958,6 +958,11 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { } j.installFile = ctx.InstallFile(installDir, j.Stem()+".jar", j.outputFile, extraInstallDeps...) } + + android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{ + TestOnly: Bool(j.sourceProperties.Test_only), + TopLevelTarget: j.sourceProperties.Top_level_test_target, + }) } func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) { @@ -1123,6 +1128,7 @@ func LibraryFactory() android.Module { module := &Library{} module.addHostAndDeviceProperties() + module.AddProperties(&module.sourceProperties) module.initModuleAndImport(module) @@ -1604,6 +1610,8 @@ func TestFactory() android.Module { module.Module.properties.Installable = proptools.BoolPtr(true) module.Module.dexpreopter.isTest = true module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true) + module.Module.sourceProperties.Test_only = proptools.BoolPtr(true) + module.Module.sourceProperties.Top_level_test_target = true InitJavaModule(module, android.HostAndDeviceSupported) return module @@ -1619,6 +1627,7 @@ func TestHelperLibraryFactory() android.Module { module.Module.properties.Installable = proptools.BoolPtr(true) module.Module.dexpreopter.isTest = true module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true) + module.Module.sourceProperties.Test_only = proptools.BoolPtr(true) InitJavaModule(module, android.HostAndDeviceSupported) return module @@ -1674,6 +1683,8 @@ func InitTestHost(th *TestHost, installable *bool, testSuites []string, autoGenC th.properties.Installable = installable th.testProperties.Auto_gen_config = autoGenConfig th.testProperties.Test_suites = testSuites + th.sourceProperties.Test_only = proptools.BoolPtr(true) + th.sourceProperties.Top_level_test_target = true } // @@ -1799,7 +1810,7 @@ func BinaryFactory() android.Module { module := &Binary{} module.addHostAndDeviceProperties() - module.AddProperties(&module.binaryProperties) + module.AddProperties(&module.binaryProperties, &module.sourceProperties) module.Module.properties.Installable = proptools.BoolPtr(true) @@ -2564,7 +2575,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { // header jar for this module. reuseImplementationJarAsHeaderJar := slices.Equal(staticJars, staticHeaderJars) - var headerOutputFile android.WritablePath + var headerOutputFile android.ModuleOutPath if reuseImplementationJarAsHeaderJar { headerOutputFile = outputFile } else { @@ -2587,8 +2598,12 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { headerOutputFile = outputFile } } - j.combinedHeaderFile = headerOutputFile - j.combinedImplementationFile = outputFile + + // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource. + // Also strip the relative path from the header output file so that the reuseImplementationJarAsHeaderJar check + // in a module that depends on this module considers them equal. + j.combinedHeaderFile = headerOutputFile.WithoutRel() + j.combinedImplementationFile = outputFile.WithoutRel() j.maybeInstall(ctx, jarName, outputFile) diff --git a/java/java_test.go b/java/java_test.go index 2676aa558..a1192bb5f 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -2838,6 +2838,99 @@ func TestApiLibraryAconfigDeclarations(t *testing.T) { android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "revert-annotations-exportable.txt") } +func TestTestOnly(t *testing.T) { + t.Parallel() + ctx := android.GroupFixturePreparers( + prepareForJavaTest, + ).RunTestWithBp(t, ` + // These should be test-only + java_library { + name: "lib1-test-only", + srcs: ["a.java"], + test_only: true, + } + java_test { + name: "java-test", + } + java_test_host { + name: "java-test-host", + } + java_test_helper_library { + name: "helper-library", + } + java_binary { + name: "java-data-binary", + srcs: ["foo.java"], + main_class: "foo.bar.jb", + test_only: true, + } + + // These are NOT + java_library { + name: "lib2-app", + srcs: ["b.java"], + } + java_import { + name: "bar", + jars: ["bar.jar"], + } + java_binary { + name: "java-binary", + srcs: ["foo.java"], + main_class: "foo.bar.jb", + } + `) + + expectedTestOnlyModules := []string{ + "lib1-test-only", + "java-test", + "java-test-host", + "helper-library", + "java-data-binary", + } + expectedTopLevelTests := []string{ + "java-test", + "java-test-host", + } + assertTestOnlyAndTopLevel(t, ctx, expectedTestOnlyModules, expectedTopLevelTests) +} + +// Don't allow setting test-only on things that are always tests or never tests. +func TestInvalidTestOnlyTargets(t *testing.T) { + testCases := []string{ + ` java_test { name: "java-test", test_only: true, srcs: ["foo.java"], } `, + ` java_test_host { name: "java-test-host", test_only: true, srcs: ["foo.java"], } `, + ` java_test_import { name: "java-test-import", test_only: true, } `, + ` java_api_library { name: "java-api-library", test_only: true, } `, + ` java_test_helper_library { name: "test-help-lib", test_only: true, } `, + ` java_defaults { name: "java-defaults", test_only: true, } `, + } + + for i, bp := range testCases { + android.GroupFixturePreparers(prepareForJavaTest). + ExtendWithErrorHandler( + expectOneError("unrecognized property \"test_only\"", + fmt.Sprintf("testcase: %d", i))). + RunTestWithBp(t, bp) + } +} + +// Expect exactly one that matches 'expected'. +// Append 'msg' to the Errorf that printed. +func expectOneError(expected string, msg string) android.FixtureErrorHandler { + return android.FixtureCustomErrorHandler(func(t *testing.T, result *android.TestResult) { + t.Helper() + if len(result.Errs) != 1 { + t.Errorf("Expected exactly one error, but found: %d when setting test_only on: %s", len(result.Errs), msg) + return + } + actualErrMsg := result.Errs[0].Error() + if !strings.Contains(actualErrMsg, expected) { + t.Errorf("Different error than expected. Received: [%v] on %s expected: %s", actualErrMsg, msg, expected) + } + }) +} + func TestJavaLibHostWithStem(t *testing.T) { ctx, _ := testJava(t, ` java_library_host { @@ -2872,3 +2965,79 @@ func TestJavaLibWithStem(t *testing.T) { t.Errorf("Module output does not contain expected jar %s", "foo-new.jar") } } + +func TestJavaLibraryOutputFilesRel(t *testing.T) { + result := android.GroupFixturePreparers( + PrepareForTestWithJavaDefaultModules, + ).RunTestWithBp(t, ` + java_library { + name: "foo", + srcs: ["a.java"], + } + + java_import { + name: "bar", + jars: ["bar.aar"], + + } + + java_import { + name: "baz", + jars: ["baz.aar"], + static_libs: ["bar"], + } + `) + + foo := result.ModuleForTests("foo", "android_common") + bar := result.ModuleForTests("bar", "android_common") + baz := result.ModuleForTests("baz", "android_common") + + fooOutputPath := android.OutputFileForModule(android.PathContext(nil), foo.Module(), "") + barOutputPath := android.OutputFileForModule(android.PathContext(nil), bar.Module(), "") + bazOutputPath := android.OutputFileForModule(android.PathContext(nil), baz.Module(), "") + + android.AssertPathRelativeToTopEquals(t, "foo output path", + "out/soong/.intermediates/foo/android_common/javac/foo.jar", fooOutputPath) + android.AssertPathRelativeToTopEquals(t, "bar output path", + "out/soong/.intermediates/bar/android_common/combined/bar.jar", barOutputPath) + android.AssertPathRelativeToTopEquals(t, "baz output path", + "out/soong/.intermediates/baz/android_common/combined/baz.jar", bazOutputPath) + + android.AssertStringEquals(t, "foo relative output path", + "foo.jar", fooOutputPath.Rel()) + android.AssertStringEquals(t, "bar relative output path", + "bar.jar", barOutputPath.Rel()) + android.AssertStringEquals(t, "baz relative output path", + "baz.jar", bazOutputPath.Rel()) +} + +func assertTestOnlyAndTopLevel(t *testing.T, ctx *android.TestResult, expectedTestOnly []string, expectedTopLevel []string) { + t.Helper() + actualTrueModules := []string{} + actualTopLevelTests := []string{} + addActuals := func(m blueprint.Module, key blueprint.ProviderKey[android.TestModuleInformation]) { + if provider, ok := android.OtherModuleProvider(ctx.TestContext.OtherModuleProviderAdaptor(), m, key); ok { + if provider.TestOnly { + actualTrueModules = append(actualTrueModules, m.Name()) + } + if provider.TopLevelTarget { + actualTopLevelTests = append(actualTopLevelTests, m.Name()) + } + } + } + + ctx.VisitAllModules(func(m blueprint.Module) { + addActuals(m, android.TestOnlyProviderKey) + + }) + + notEqual, left, right := android.ListSetDifference(expectedTestOnly, actualTrueModules) + if notEqual { + t.Errorf("test-only: Expected but not found: %v, Found but not expected: %v", left, right) + } + + notEqual, left, right = android.ListSetDifference(expectedTopLevel, actualTopLevelTests) + if notEqual { + t.Errorf("top-level: Expected but not found: %v, Found but not expected: %v", left, right) + } +} diff --git a/java/sdk_library.go b/java/sdk_library.go index 355654fb2..e7e53a2a8 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -3238,14 +3238,14 @@ func formattedOptionalAttribute(attrName string, value *string) string { if value == nil { return "" } - return fmt.Sprintf(` %s=\"%s\"\n`, attrName, *value) + return fmt.Sprintf(" %s=\"%s\"\n", attrName, *value) } func formattedDependenciesAttribute(dependencies []string) string { if dependencies == nil { return "" } - return fmt.Sprintf(` dependency=\"%s\"\n`, strings.Join(dependencies, ":")) + return fmt.Sprintf(" dependency=\"%s\"\n", strings.Join(dependencies, ":")) } func (module *sdkLibraryXml) permissionsContents(ctx android.ModuleContext) string { @@ -3262,28 +3262,28 @@ func (module *sdkLibraryXml) permissionsContents(ctx android.ModuleContext) stri // similarly, min_device_sdk is only understood from T. So if a library is using that, we need to use the apex-library to make sure this library is not loaded before T var libraryTag string if module.properties.Min_device_sdk != nil { - libraryTag = ` <apex-library\n` + libraryTag = " <apex-library\n" } else { - libraryTag = ` <library\n` + libraryTag = " <library\n" } return strings.Join([]string{ - `<?xml version=\"1.0\" encoding=\"utf-8\"?>\n`, - `<!-- Copyright (C) 2018 The Android Open Source Project\n`, - `\n`, - ` Licensed under the Apache License, Version 2.0 (the \"License\");\n`, - ` you may not use this file except in compliance with the License.\n`, - ` You may obtain a copy of the License at\n`, - `\n`, - ` http://www.apache.org/licenses/LICENSE-2.0\n`, - `\n`, - ` Unless required by applicable law or agreed to in writing, software\n`, - ` distributed under the License is distributed on an \"AS IS\" BASIS,\n`, - ` WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n`, - ` See the License for the specific language governing permissions and\n`, - ` limitations under the License.\n`, - `-->\n`, - `<permissions>\n`, + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n", + "<!-- Copyright (C) 2018 The Android Open Source Project\n", + "\n", + " Licensed under the Apache License, Version 2.0 (the \"License\");\n", + " you may not use this file except in compliance with the License.\n", + " You may obtain a copy of the License at\n", + "\n", + " http://www.apache.org/licenses/LICENSE-2.0\n", + "\n", + " Unless required by applicable law or agreed to in writing, software\n", + " distributed under the License is distributed on an \"AS IS\" BASIS,\n", + " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", + " See the License for the specific language governing permissions and\n", + " limitations under the License.\n", + "-->\n", + "<permissions>\n", libraryTag, libNameAttr, filePathAttr, @@ -3292,8 +3292,9 @@ func (module *sdkLibraryXml) permissionsContents(ctx android.ModuleContext) stri minSdkAttr, maxSdkAttr, dependenciesAttr, - ` />\n`, - `</permissions>\n`}, "") + " />\n", + "</permissions>\n", + }, "") } func (module *sdkLibraryXml) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -3305,12 +3306,7 @@ func (module *sdkLibraryXml) GenerateAndroidBuildActions(ctx android.ModuleConte xmlContent := module.permissionsContents(ctx) module.outputFilePath = android.PathForModuleOut(ctx, libName+".xml").OutputPath - rule := android.NewRuleBuilder(pctx, ctx) - rule.Command(). - Text("/bin/bash -c \"echo -e '" + xmlContent + "'\" > "). - Output(module.outputFilePath) - - rule.Build("java_sdk_xml", "Permission XML") + android.WriteFileRuleVerbatim(ctx, module.outputFilePath, xmlContent) module.installDirPath = android.PathForModuleInstall(ctx, "etc", module.SubDir()) } diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go index a19d3829f..5fac2556d 100644 --- a/java/sdk_library_test.go +++ b/java/sdk_library_test.go @@ -227,19 +227,21 @@ func TestJavaSdkLibrary_UpdatableLibrary(t *testing.T) { `) // test that updatability attributes are passed on correctly - fooUpdatable := result.ModuleForTests("fooUpdatable.xml", "android_common").Rule("java_sdk_xml") - android.AssertStringDoesContain(t, "fooUpdatable.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `on-bootclasspath-since=\"U\"`) - android.AssertStringDoesContain(t, "fooUpdatable.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `on-bootclasspath-before=\"V\"`) - android.AssertStringDoesContain(t, "fooUpdatable.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `min-device-sdk=\"W\"`) - android.AssertStringDoesContain(t, "fooUpdatable.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `max-device-sdk=\"X\"`) + fooUpdatable := result.ModuleForTests("fooUpdatable.xml", "android_common").Output("fooUpdatable.xml") + fooUpdatableContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooUpdatable) + android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `on-bootclasspath-since="U"`) + android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `on-bootclasspath-before="V"`) + android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `min-device-sdk="W"`) + android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `max-device-sdk="X"`) // double check that updatability attributes are not written if they don't exist in the bp file // the permissions file for the foo library defined above - fooPermissions := result.ModuleForTests("foo.xml", "android_common").Rule("java_sdk_xml") - android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooPermissions.RuleParams.Command, `on-bootclasspath-since`) - android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooPermissions.RuleParams.Command, `on-bootclasspath-before`) - android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooPermissions.RuleParams.Command, `min-device-sdk`) - android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooPermissions.RuleParams.Command, `max-device-sdk`) + fooPermissions := result.ModuleForTests("foo.xml", "android_common").Output("foo.xml") + fooPermissionsContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooPermissions) + android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `on-bootclasspath-since`) + android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `on-bootclasspath-before`) + android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `min-device-sdk`) + android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `max-device-sdk`) } func TestJavaSdkLibrary_UpdatableLibrary_Validation_ValidVersion(t *testing.T) { @@ -370,9 +372,10 @@ func TestJavaSdkLibrary_UpdatableLibrary_usesNewTag(t *testing.T) { } `) // test that updatability attributes are passed on correctly - fooUpdatable := result.ModuleForTests("foo.xml", "android_common").Rule("java_sdk_xml") - android.AssertStringDoesContain(t, "foo.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `<apex-library`) - android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `<library`) + fooUpdatable := result.ModuleForTests("foo.xml", "android_common").Output("foo.xml") + fooUpdatableContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooUpdatable) + android.AssertStringDoesContain(t, "foo.xml contents", fooUpdatableContents, `<apex-library`) + android.AssertStringDoesNotContain(t, "foo.xml contents", fooUpdatableContents, `<library`) } func TestJavaSdkLibrary_StubOrImplOnlyLibs(t *testing.T) { @@ -1707,9 +1710,9 @@ func TestSdkLibraryDependency(t *testing.T) { } `) - barPermissions := result.ModuleForTests("bar.xml", "android_common").Rule("java_sdk_xml") - - android.AssertStringDoesContain(t, "bar.xml java_sdk_xml command", barPermissions.RuleParams.Command, `dependency=\"foo\"`) + barPermissions := result.ModuleForTests("bar.xml", "android_common").Output("bar.xml") + barContents := android.ContentFromFileRuleForTests(t, result.TestContext, barPermissions) + android.AssertStringDoesContain(t, "bar.xml java_sdk_xml command", barContents, `dependency="foo"`) } func TestSdkLibraryExportableStubsLibrary(t *testing.T) { diff --git a/rust/androidmk.go b/rust/androidmk.go index 4ae907c44..021dd6067 100644 --- a/rust/androidmk.go +++ b/rust/androidmk.go @@ -62,6 +62,7 @@ func (mod *Module) AndroidMkEntries() []android.AndroidMkEntries { entries.AddStrings("LOCAL_PROC_MACRO_LIBRARIES", mod.Properties.AndroidMkProcMacroLibs...) entries.AddStrings("LOCAL_SHARED_LIBRARIES", mod.transitiveAndroidMkSharedLibs.ToList()...) entries.AddStrings("LOCAL_STATIC_LIBRARIES", mod.Properties.AndroidMkStaticLibs...) + entries.AddStrings("LOCAL_HEADER_LIBRARIES", mod.Properties.AndroidMkHeaderLibs...) entries.AddStrings("LOCAL_SOONG_LINK_TYPE", mod.makeLinkType) if mod.InVendor() { entries.SetBool("LOCAL_IN_VENDOR", true) diff --git a/rust/bindgen.go b/rust/bindgen.go index 454dd8798..11ba74d45 100644 --- a/rust/bindgen.go +++ b/rust/bindgen.go @@ -346,6 +346,6 @@ func (b *bindgenDecorator) SourceProviderDeps(ctx DepsContext, deps Deps) Deps { deps.SharedLibs = append(deps.SharedLibs, b.ClangProperties.Shared_libs...) deps.StaticLibs = append(deps.StaticLibs, b.ClangProperties.Static_libs...) - deps.HeaderLibs = append(deps.StaticLibs, b.ClangProperties.Header_libs...) + deps.HeaderLibs = append(deps.HeaderLibs, b.ClangProperties.Header_libs...) return deps } diff --git a/rust/bindgen_test.go b/rust/bindgen_test.go index 0ba0ff840..0c0a6dad0 100644 --- a/rust/bindgen_test.go +++ b/rust/bindgen_test.go @@ -17,6 +17,8 @@ package rust import ( "strings" "testing" + + "android/soong/android" ) func TestRustBindgen(t *testing.T) { @@ -31,7 +33,21 @@ func TestRustBindgen(t *testing.T) { bindgen_flags: ["--bindgen-flag.*"], cflags: ["--clang-flag()"], shared_libs: ["libfoo_shared"], + } + rust_bindgen { + name: "libbindgen_staticlib", + wrapper_src: "src/any.h", + crate_name: "bindgen_staticlib", + stem: "libbindgen_staticlib", + source_stem: "bindings", static_libs: ["libfoo_static"], + } + rust_bindgen { + name: "libbindgen_headerlib", + wrapper_src: "src/any.h", + crate_name: "bindgen_headerlib", + stem: "libbindgen_headerlib", + source_stem: "bindings", header_libs: ["libfoo_header"], } cc_library_shared { @@ -52,6 +68,9 @@ func TestRustBindgen(t *testing.T) { } `) libbindgen := ctx.ModuleForTests("libbindgen", "android_arm64_armv8-a_source").Output("bindings.rs") + libbindgenStatic := ctx.ModuleForTests("libbindgen_staticlib", "android_arm64_armv8-a_source").Output("bindings.rs") + libbindgenHeader := ctx.ModuleForTests("libbindgen_headerlib", "android_arm64_armv8-a_source").Output("bindings.rs") + libbindgenHeaderModule := ctx.ModuleForTests("libbindgen_headerlib", "android_arm64_armv8-a_source").Module().(*Module) // Ensure that the flags are present and escaped if !strings.Contains(libbindgen.Args["flags"], "'--bindgen-flag.*'") { t.Errorf("missing bindgen flags in rust_bindgen rule: flags %#v", libbindgen.Args["flags"]) @@ -62,12 +81,17 @@ func TestRustBindgen(t *testing.T) { if !strings.Contains(libbindgen.Args["cflags"], "-Ishared_include") { t.Errorf("missing shared_libs exported includes in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"]) } - if !strings.Contains(libbindgen.Args["cflags"], "-Istatic_include") { - t.Errorf("missing static_libs exported includes in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"]) + if !strings.Contains(libbindgenStatic.Args["cflags"], "-Istatic_include") { + t.Errorf("missing static_libs exported includes in rust_bindgen rule: cflags %#v", libbindgenStatic.Args["cflags"]) } - if !strings.Contains(libbindgen.Args["cflags"], "-Iheader_include") { - t.Errorf("missing static_libs exported includes in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"]) + if !strings.Contains(libbindgenHeader.Args["cflags"], "-Iheader_include") { + t.Errorf("missing header_libs exported includes in rust_bindgen rule: cflags %#v", libbindgenHeader.Args["cflags"]) } + + if android.InList("libfoo_static", libbindgenHeaderModule.Properties.AndroidMkHeaderLibs) { + t.Errorf("Static library dependency should not be in HeaderLibs list") + } + if !strings.Contains(libbindgen.Args["cflags"], "--default-flag") { t.Errorf("rust_bindgen missing cflags defined in cc_defaults: cflags %#v", libbindgen.Args["cflags"]) } diff --git a/rust/config/global.go b/rust/config/global.go index 23230492f..ba085600b 100644 --- a/rust/config/global.go +++ b/rust/config/global.go @@ -24,7 +24,7 @@ import ( var ( pctx = android.NewPackageContext("android/soong/rust/config") - RustDefaultVersion = "1.76.0" + RustDefaultVersion = "1.77.1" RustDefaultBase = "prebuilts/rust/" DefaultEdition = "2021" Stdlibs = []string{ diff --git a/rust/rust.go b/rust/rust.go index c4b89d547..c2b61515c 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -68,6 +68,7 @@ type BaseProperties struct { AndroidMkDylibs []string `blueprint:"mutated"` AndroidMkProcMacroLibs []string `blueprint:"mutated"` AndroidMkStaticLibs []string `blueprint:"mutated"` + AndroidMkHeaderLibs []string `blueprint:"mutated"` ImageVariation string `blueprint:"mutated"` VndkVersion string `blueprint:"mutated"` @@ -1399,6 +1400,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...) depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...) depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...) + mod.Properties.AndroidMkHeaderLibs = append(mod.Properties.AndroidMkHeaderLibs, makeLibName) case depTag == cc.CrtBeginDepTag: depPaths.CrtBegin = append(depPaths.CrtBegin, linkObject.Path()) case depTag == cc.CrtEndDepTag: |