Add container property to aconfig_declarations.
Bug: 311155208
Test: Unit test
Change-Id: I7b187138856d0144203961e82b6dad5e2f8eed9d
diff --git a/aconfig/Android.bp b/aconfig/Android.bp
index faa4ddb..04de919 100644
--- a/aconfig/Android.bp
+++ b/aconfig/Android.bp
@@ -12,28 +12,19 @@
"soong",
"soong-android",
"soong-bazel",
- "soong-android",
- "soong-java",
- "soong-rust",
],
srcs: [
"aconfig_declarations.go",
"aconfig_values.go",
"aconfig_value_set.go",
"all_aconfig_declarations.go",
- "cc_aconfig_library.go",
"init.go",
- "java_aconfig_library.go",
"testing.go",
- "rust_aconfig_library.go",
],
testSrcs: [
"aconfig_declarations_test.go",
"aconfig_values_test.go",
"aconfig_value_set_test.go",
- "java_aconfig_library_test.go",
- "cc_aconfig_library_test.go",
- "rust_aconfig_library_test.go",
],
pluginFor: ["soong_build"],
}
diff --git a/aconfig/aconfig_declarations.go b/aconfig/aconfig_declarations.go
index 897f892..e662f1d 100644
--- a/aconfig/aconfig_declarations.go
+++ b/aconfig/aconfig_declarations.go
@@ -38,6 +38,9 @@
// Values from TARGET_RELEASE / RELEASE_ACONFIG_VALUE_SETS
Values []string `blueprint:"mutated"`
+
+ // Container(system/vendor/apex) that this module belongs to
+ Container string
}
intermediatePath android.WritablePath
@@ -69,6 +72,8 @@
if len(module.properties.Package) == 0 {
ctx.PropertyErrorf("package", "missing package property")
}
+ // TODO(b/311155208): Add mandatory check for container after all pre-existing
+ // ones are changed.
// Add a dependency on the aconfig_value_sets defined in
// RELEASE_ACONFIG_VALUE_SETS, and add any aconfig_values that
@@ -110,12 +115,21 @@
}
// Provider published by aconfig_value_set
-type declarationsProviderData struct {
+type DeclarationsProviderData struct {
Package string
+ Container string
IntermediatePath android.WritablePath
}
-var declarationsProviderKey = blueprint.NewProvider(declarationsProviderData{})
+var DeclarationsProviderKey = blueprint.NewProvider(DeclarationsProviderData{})
+
+// This is used to collect the aconfig declarations info on the transitive closure,
+// the data is keyed on the container.
+type TransitiveDeclarationsInfo struct {
+ AconfigFiles map[string]*android.DepSet[android.Path]
+}
+
+var TransitiveDeclarationsInfoProvider = blueprint.NewProvider(TransitiveDeclarationsInfo{})
func (module *DeclarationsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// Get the values that came from the global RELEASE_ACONFIG_VALUE_SETS flag
@@ -156,13 +170,49 @@
},
})
- ctx.SetProvider(declarationsProviderKey, declarationsProviderData{
+ ctx.SetProvider(DeclarationsProviderKey, DeclarationsProviderData{
Package: module.properties.Package,
+ Container: module.properties.Container,
IntermediatePath: intermediatePath,
})
}
+func CollectTransitiveAconfigFiles(ctx android.ModuleContext, transitiveAconfigFiles *map[string]*android.DepSet[android.Path]) {
+ if *transitiveAconfigFiles == nil {
+ *transitiveAconfigFiles = make(map[string]*android.DepSet[android.Path])
+ }
+ ctx.VisitDirectDeps(func(module android.Module) {
+ if dep := ctx.OtherModuleProvider(module, DeclarationsProviderKey).(DeclarationsProviderData); dep.IntermediatePath != nil {
+ aconfigMap := make(map[string]*android.DepSet[android.Path])
+ aconfigMap[dep.Container] = android.NewDepSet(android.POSTORDER, []android.Path{dep.IntermediatePath}, nil)
+ mergeTransitiveAconfigFiles(aconfigMap, *transitiveAconfigFiles)
+ return
+ }
+ if dep := ctx.OtherModuleProvider(module, TransitiveDeclarationsInfoProvider).(TransitiveDeclarationsInfo); len(dep.AconfigFiles) > 0 {
+ mergeTransitiveAconfigFiles(dep.AconfigFiles, *transitiveAconfigFiles)
+ }
+ })
+
+ ctx.SetProvider(TransitiveDeclarationsInfoProvider, TransitiveDeclarationsInfo{
+ AconfigFiles: *transitiveAconfigFiles,
+ })
+}
+
+func mergeTransitiveAconfigFiles(from, to map[string]*android.DepSet[android.Path]) {
+ for fromKey, fromValue := range from {
+ if fromValue == nil {
+ continue
+ }
+ toValue, ok := to[fromKey]
+ if !ok {
+ to[fromKey] = fromValue
+ } else {
+ to[fromKey] = android.NewDepSet(android.POSTORDER, toValue.ToList(), []*android.DepSet[android.Path]{fromValue})
+ }
+ }
+}
+
type bazelAconfigDeclarationsAttributes struct {
Srcs bazel.LabelListAttribute
Package string
diff --git a/aconfig/aconfig_declarations_test.go b/aconfig/aconfig_declarations_test.go
index e0d8f7d..e6bd87c 100644
--- a/aconfig/aconfig_declarations_test.go
+++ b/aconfig/aconfig_declarations_test.go
@@ -26,6 +26,7 @@
aconfig_declarations {
name: "module_name",
package: "com.example.package",
+ container: "com.android.foo",
srcs: [
"foo.aconfig",
"bar.aconfig",
@@ -37,8 +38,9 @@
module := result.ModuleForTests("module_name", "").Module().(*DeclarationsModule)
// Check that the provider has the right contents
- depData := result.ModuleProvider(module, declarationsProviderKey).(declarationsProviderData)
+ depData := result.ModuleProvider(module, DeclarationsProviderKey).(DeclarationsProviderData)
android.AssertStringEquals(t, "package", depData.Package, "com.example.package")
+ android.AssertStringEquals(t, "container", depData.Container, "com.android.foo")
if !strings.HasSuffix(depData.IntermediatePath.String(), "/intermediate.pb") {
t.Errorf("Missing intermediates path in provider: %s", depData.IntermediatePath.String())
}
diff --git a/aconfig/all_aconfig_declarations.go b/aconfig/all_aconfig_declarations.go
index 6096c6c..7ccb81a 100644
--- a/aconfig/all_aconfig_declarations.go
+++ b/aconfig/all_aconfig_declarations.go
@@ -37,17 +37,17 @@
// Find all of the aconfig_declarations modules
var cacheFiles android.Paths
ctx.VisitAllModules(func(module android.Module) {
- if !ctx.ModuleHasProvider(module, declarationsProviderKey) {
+ if !ctx.ModuleHasProvider(module, DeclarationsProviderKey) {
return
}
- decl := ctx.ModuleProvider(module, declarationsProviderKey).(declarationsProviderData)
+ decl := ctx.ModuleProvider(module, DeclarationsProviderKey).(DeclarationsProviderData)
cacheFiles = append(cacheFiles, decl.IntermediatePath)
})
// Generate build action for aconfig
this.intermediatePath = android.PathForIntermediates(ctx, "all_aconfig_declarations.pb")
ctx.Build(pctx, android.BuildParams{
- Rule: allDeclarationsRule,
+ Rule: AllDeclarationsRule,
Inputs: cacheFiles,
Output: this.intermediatePath,
Description: "all_aconfig_declarations",
diff --git a/aconfig/codegen/Android.bp b/aconfig/codegen/Android.bp
new file mode 100644
index 0000000..494f7e6
--- /dev/null
+++ b/aconfig/codegen/Android.bp
@@ -0,0 +1,32 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+bootstrap_go_package {
+ name: "soong-aconfig-codegen",
+ pkgPath: "android/soong/aconfig/codegen",
+ deps: [
+ "blueprint",
+ "blueprint-pathtools",
+ "sbox_proto",
+ "soong",
+ "soong-aconfig",
+ "soong-android",
+ "soong-bazel",
+ "soong-java",
+ "soong-rust",
+ ],
+ srcs: [
+ "cc_aconfig_library.go",
+ "init.go",
+ "java_aconfig_library.go",
+ "rust_aconfig_library.go",
+ "testing.go",
+ ],
+ testSrcs: [
+ "java_aconfig_library_test.go",
+ "cc_aconfig_library_test.go",
+ "rust_aconfig_library_test.go",
+ ],
+ pluginFor: ["soong_build"],
+}
diff --git a/aconfig/cc_aconfig_library.go b/aconfig/codegen/cc_aconfig_library.go
similarity index 96%
rename from aconfig/cc_aconfig_library.go
rename to aconfig/codegen/cc_aconfig_library.go
index 210a581..7b68844 100644
--- a/aconfig/cc_aconfig_library.go
+++ b/aconfig/codegen/cc_aconfig_library.go
@@ -12,9 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package aconfig
+package codegen
import (
+ "android/soong/aconfig"
"android/soong/android"
"android/soong/bazel"
"android/soong/cc"
@@ -92,7 +93,7 @@
if len(declarationsModules) != 1 {
panic(fmt.Errorf("Exactly one aconfig_declarations property required"))
}
- declarations := ctx.OtherModuleProvider(declarationsModules[0], declarationsProviderKey).(declarationsProviderData)
+ declarations := ctx.OtherModuleProvider(declarationsModules[0], aconfig.DeclarationsProviderKey).(aconfig.DeclarationsProviderData)
// Figure out the generated file paths. This has to match aconfig's codegen_cpp.rs.
this.generatedDir = android.PathForModuleGen(ctx)
@@ -122,7 +123,7 @@
if len(declarationsModules) != 1 {
panic(fmt.Errorf("Exactly one aconfig_declarations property required"))
}
- declarations := ctx.OtherModuleProvider(declarationsModules[0], declarationsProviderKey).(declarationsProviderData)
+ declarations := ctx.OtherModuleProvider(declarationsModules[0], aconfig.DeclarationsProviderKey).(aconfig.DeclarationsProviderData)
mode := proptools.StringDefault(this.properties.Mode, "production")
if !isModeSupported(mode) {
diff --git a/aconfig/cc_aconfig_library_test.go b/aconfig/codegen/cc_aconfig_library_test.go
similarity index 99%
rename from aconfig/cc_aconfig_library_test.go
rename to aconfig/codegen/cc_aconfig_library_test.go
index ba27250..0c8a969 100644
--- a/aconfig/cc_aconfig_library_test.go
+++ b/aconfig/codegen/cc_aconfig_library_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package aconfig
+package codegen
import (
"fmt"
diff --git a/aconfig/codegen/init.go b/aconfig/codegen/init.go
new file mode 100644
index 0000000..0bff9d2
--- /dev/null
+++ b/aconfig/codegen/init.go
@@ -0,0 +1,83 @@
+// Copyright 2023 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 codegen
+
+import (
+ "android/soong/android"
+
+ "github.com/google/blueprint"
+)
+
+var (
+ pctx = android.NewPackageContext("android/soong/aconfig/codegen")
+
+ // For java_aconfig_library: Generate java library
+ javaRule = pctx.AndroidStaticRule("java_aconfig_library",
+ blueprint.RuleParams{
+ Command: `rm -rf ${out}.tmp` +
+ ` && mkdir -p ${out}.tmp` +
+ ` && ${aconfig} create-java-lib` +
+ ` --mode ${mode}` +
+ ` --cache ${in}` +
+ ` --out ${out}.tmp` +
+ ` && $soong_zip -write_if_changed -jar -o ${out} -C ${out}.tmp -D ${out}.tmp` +
+ ` && rm -rf ${out}.tmp`,
+ CommandDeps: []string{
+ "$aconfig",
+ "$soong_zip",
+ },
+ Restat: true,
+ }, "mode")
+
+ // For cc_aconfig_library: Generate C++ library
+ cppRule = pctx.AndroidStaticRule("cc_aconfig_library",
+ blueprint.RuleParams{
+ Command: `rm -rf ${gendir}` +
+ ` && mkdir -p ${gendir}` +
+ ` && ${aconfig} create-cpp-lib` +
+ ` --mode ${mode}` +
+ ` --cache ${in}` +
+ ` --out ${gendir}`,
+ CommandDeps: []string{
+ "$aconfig",
+ },
+ }, "gendir", "mode")
+
+ // For rust_aconfig_library: Generate Rust library
+ rustRule = pctx.AndroidStaticRule("rust_aconfig_library",
+ blueprint.RuleParams{
+ Command: `rm -rf ${gendir}` +
+ ` && mkdir -p ${gendir}` +
+ ` && ${aconfig} create-rust-lib` +
+ ` --mode ${mode}` +
+ ` --cache ${in}` +
+ ` --out ${gendir}`,
+ CommandDeps: []string{
+ "$aconfig",
+ },
+ }, "gendir", "mode")
+)
+
+func init() {
+ RegisterBuildComponents(android.InitRegistrationContext)
+ pctx.HostBinToolVariable("aconfig", "aconfig")
+ pctx.HostBinToolVariable("soong_zip", "soong_zip")
+}
+
+func RegisterBuildComponents(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("cc_aconfig_library", CcAconfigLibraryFactory)
+ ctx.RegisterModuleType("java_aconfig_library", JavaDeclarationsLibraryFactory)
+ ctx.RegisterModuleType("rust_aconfig_library", RustAconfigLibraryFactory)
+}
diff --git a/aconfig/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go
similarity index 94%
rename from aconfig/java_aconfig_library.go
rename to aconfig/codegen/java_aconfig_library.go
index eedb3c3..e2fb15b 100644
--- a/aconfig/java_aconfig_library.go
+++ b/aconfig/codegen/java_aconfig_library.go
@@ -12,11 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package aconfig
+package codegen
import (
"fmt"
+ "android/soong/aconfig"
"android/soong/android"
"android/soong/bazel"
"android/soong/java"
@@ -73,7 +74,7 @@
if len(declarationsModules) != 1 {
panic(fmt.Errorf("Exactly one aconfig_declarations property required"))
}
- declarations := ctx.OtherModuleProvider(declarationsModules[0], declarationsProviderKey).(declarationsProviderData)
+ declarations := ctx.OtherModuleProvider(declarationsModules[0], aconfig.DeclarationsProviderKey).(aconfig.DeclarationsProviderData)
// Generate the action to build the srcjar
srcJarPath := android.PathForModuleGen(ctx, ctx.ModuleName()+".srcjar")
@@ -93,10 +94,6 @@
},
})
- // Tell the java module about the .aconfig files, so they can be propagated up the dependency chain.
- // TODO: It would be nice to have that propagation code here instead of on java.Module and java.JavaInfo.
- module.AddAconfigIntermediate(declarations.IntermediatePath)
-
return srcJarPath
}
diff --git a/aconfig/java_aconfig_library_test.go b/aconfig/codegen/java_aconfig_library_test.go
similarity index 82%
rename from aconfig/java_aconfig_library_test.go
rename to aconfig/codegen/java_aconfig_library_test.go
index a803672..cbfdc21 100644
--- a/aconfig/java_aconfig_library_test.go
+++ b/aconfig/codegen/java_aconfig_library_test.go
@@ -12,11 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package aconfig
+package codegen
import (
"fmt"
- "strings"
"testing"
"android/soong/android"
@@ -34,14 +33,25 @@
ExtendWithErrorHandler(android.FixtureExpectsNoErrors).
RunTestWithBp(t, bp+`
aconfig_declarations {
- name: "my_aconfig_declarations",
+ name: "my_aconfig_declarations_foo",
package: "com.example.package",
srcs: ["foo.aconfig"],
}
java_aconfig_library {
- name: "my_java_aconfig_library",
- aconfig_declarations: "my_aconfig_declarations",
+ name: "my_java_aconfig_library_foo",
+ aconfig_declarations: "my_aconfig_declarations_foo",
+ }
+
+ aconfig_declarations {
+ name: "my_aconfig_declarations_bar",
+ package: "com.example.package",
+ srcs: ["bar.aconfig"],
+ }
+
+ java_aconfig_library {
+ name: "my_java_aconfig_library_bar",
+ aconfig_declarations: "my_aconfig_declarations_bar",
}
`)
@@ -50,10 +60,9 @@
entry := android.AndroidMkEntriesForTest(t, result.TestContext, module)[0]
makeVar := entry.EntryMap["LOCAL_ACONFIG_FILES"]
- android.AssertIntEquals(t, "len(LOCAL_ACONFIG_FILES)", 1, len(makeVar))
- if !strings.HasSuffix(makeVar[0], "intermediate.pb") {
- t.Errorf("LOCAL_ACONFIG_FILES should end with /intermediates.pb, instead it is: %s", makeVar[0])
- }
+ android.AssertIntEquals(t, "len(LOCAL_ACONFIG_FILES)", 2, len(makeVar))
+ android.EnsureListContainsSuffix(t, makeVar, "my_aconfig_declarations_foo/intermediate.pb")
+ android.EnsureListContainsSuffix(t, makeVar, "my_aconfig_declarations_bar/intermediate.pb")
}
func TestAndroidMkJavaLibrary(t *testing.T) {
@@ -64,7 +73,8 @@
"src/foo.java",
],
static_libs: [
- "my_java_aconfig_library",
+ "my_java_aconfig_library_foo",
+ "my_java_aconfig_library_bar",
],
platform_apis: true,
}
@@ -81,7 +91,8 @@
"src/foo.java",
],
static_libs: [
- "my_java_aconfig_library",
+ "my_java_aconfig_library_foo",
+ "my_java_aconfig_library_bar",
],
platform_apis: true,
}
@@ -98,7 +109,8 @@
"src/foo.java",
],
static_libs: [
- "my_java_aconfig_library",
+ "my_java_aconfig_library_foo",
+ "my_java_aconfig_library_bar",
],
platform_apis: true,
main_class: "foo",
@@ -116,7 +128,8 @@
"src/foo.java",
],
static_libs: [
- "my_java_aconfig_library",
+ "my_java_aconfig_library_foo",
+ "my_java_aconfig_library_bar",
],
platform_apis: true,
}
@@ -134,7 +147,8 @@
"src/foo.java",
],
static_libs: [
- "my_java_aconfig_library",
+ "my_java_aconfig_library_foo",
+ "my_java_aconfig_library_bar",
],
platform_apis: true,
}
diff --git a/aconfig/rust_aconfig_library.go b/aconfig/codegen/rust_aconfig_library.go
similarity index 96%
rename from aconfig/rust_aconfig_library.go
rename to aconfig/codegen/rust_aconfig_library.go
index 265685e..3525de1 100644
--- a/aconfig/rust_aconfig_library.go
+++ b/aconfig/codegen/rust_aconfig_library.go
@@ -1,8 +1,9 @@
-package aconfig
+package codegen
import (
"fmt"
+ "android/soong/aconfig"
"android/soong/android"
"android/soong/rust"
@@ -64,7 +65,7 @@
if len(declarationsModules) != 1 {
panic(fmt.Errorf("Exactly one aconfig_declarations property required"))
}
- declarations := ctx.OtherModuleProvider(declarationsModules[0], declarationsProviderKey).(declarationsProviderData)
+ declarations := ctx.OtherModuleProvider(declarationsModules[0], aconfig.DeclarationsProviderKey).(aconfig.DeclarationsProviderData)
mode := proptools.StringDefault(a.Properties.Mode, "production")
if !isModeSupported(mode) {
diff --git a/aconfig/rust_aconfig_library_test.go b/aconfig/codegen/rust_aconfig_library_test.go
similarity index 99%
rename from aconfig/rust_aconfig_library_test.go
rename to aconfig/codegen/rust_aconfig_library_test.go
index 3aeab76..c09f701 100644
--- a/aconfig/rust_aconfig_library_test.go
+++ b/aconfig/codegen/rust_aconfig_library_test.go
@@ -1,4 +1,4 @@
-package aconfig
+package codegen
import (
"fmt"
diff --git a/aconfig/codegen/testing.go b/aconfig/codegen/testing.go
new file mode 100644
index 0000000..3e1c22e
--- /dev/null
+++ b/aconfig/codegen/testing.go
@@ -0,0 +1,25 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package codegen
+
+import (
+ "android/soong/aconfig"
+ "android/soong/android"
+)
+
+var PrepareForTestWithAconfigBuildComponents = android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("aconfig_declarations", aconfig.DeclarationsFactory)
+ RegisterBuildComponents(ctx)
+})
diff --git a/aconfig/init.go b/aconfig/init.go
index 626e66d..79bf002 100644
--- a/aconfig/init.go
+++ b/aconfig/init.go
@@ -40,54 +40,8 @@
Restat: true,
}, "release_version", "package", "declarations", "values", "default-permission")
- // For java_aconfig_library: Generate java library
- javaRule = pctx.AndroidStaticRule("java_aconfig_library",
- blueprint.RuleParams{
- Command: `rm -rf ${out}.tmp` +
- ` && mkdir -p ${out}.tmp` +
- ` && ${aconfig} create-java-lib` +
- ` --mode ${mode}` +
- ` --cache ${in}` +
- ` --out ${out}.tmp` +
- ` && $soong_zip -write_if_changed -jar -o ${out} -C ${out}.tmp -D ${out}.tmp` +
- ` && rm -rf ${out}.tmp`,
- CommandDeps: []string{
- "$aconfig",
- "$soong_zip",
- },
- Restat: true,
- }, "mode")
-
- // For cc_aconfig_library: Generate C++ library
- cppRule = pctx.AndroidStaticRule("cc_aconfig_library",
- blueprint.RuleParams{
- Command: `rm -rf ${gendir}` +
- ` && mkdir -p ${gendir}` +
- ` && ${aconfig} create-cpp-lib` +
- ` --mode ${mode}` +
- ` --cache ${in}` +
- ` --out ${gendir}`,
- CommandDeps: []string{
- "$aconfig",
- },
- }, "gendir", "mode")
-
- // For rust_aconfig_library: Generate Rust library
- rustRule = pctx.AndroidStaticRule("rust_aconfig_library",
- blueprint.RuleParams{
- Command: `rm -rf ${gendir}` +
- ` && mkdir -p ${gendir}` +
- ` && ${aconfig} create-rust-lib` +
- ` --mode ${mode}` +
- ` --cache ${in}` +
- ` --out ${gendir}`,
- CommandDeps: []string{
- "$aconfig",
- },
- }, "gendir", "mode")
-
// For all_aconfig_declarations: Combine all parsed_flags proto files
- allDeclarationsRule = pctx.AndroidStaticRule("all_aconfig_declarations_dump",
+ AllDeclarationsRule = pctx.AndroidStaticRule("All_aconfig_declarations_dump",
blueprint.RuleParams{
Command: `${aconfig} dump --format protobuf --out ${out} ${cache_files}`,
CommandDeps: []string{
@@ -106,8 +60,5 @@
ctx.RegisterModuleType("aconfig_declarations", DeclarationsFactory)
ctx.RegisterModuleType("aconfig_values", ValuesFactory)
ctx.RegisterModuleType("aconfig_value_set", ValueSetFactory)
- ctx.RegisterModuleType("cc_aconfig_library", CcAconfigLibraryFactory)
- ctx.RegisterModuleType("java_aconfig_library", JavaDeclarationsLibraryFactory)
- ctx.RegisterModuleType("rust_aconfig_library", RustAconfigLibraryFactory)
ctx.RegisterParallelSingletonType("all_aconfig_declarations", AllAconfigDeclarationsFactory)
}
diff --git a/android/testing.go b/android/testing.go
index da3b75a..c596468 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -1293,3 +1293,10 @@
func StringsRelativeToTop(config Config, command []string) []string {
return normalizeStringArrayRelativeToTop(config, command)
}
+
+func EnsureListContainsSuffix(t *testing.T, result []string, expected string) {
+ t.Helper()
+ if !SuffixInList(result, expected) {
+ t.Errorf("%q is not found in %v", expected, result)
+ }
+}
diff --git a/apex/Android.bp b/apex/Android.bp
index 0791497..0a5063f 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -8,6 +8,8 @@
deps: [
"blueprint",
"soong",
+ "soong-aconfig",
+ "soong-aconfig-codegen",
"soong-android",
"soong-bazel",
"soong-bpf",
diff --git a/apex/apex.go b/apex/apex.go
index ecc794b..56f3367 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -24,6 +24,7 @@
"sort"
"strings"
+ "android/soong/aconfig"
"android/soong/bazel/cquery"
"github.com/google/blueprint"
@@ -482,6 +483,8 @@
nativeApisUsedByModuleFile android.ModuleOutPath
nativeApisBackedByModuleFile android.ModuleOutPath
javaApisUsedByModuleFile android.ModuleOutPath
+
+ aconfigFiles []android.Path
}
// apexFileClass represents a type of file that can be included in APEX.
@@ -2008,6 +2011,8 @@
// visitor skips these from this list of module names
unwantedTransitiveDeps []string
+
+ aconfigFiles []android.Path
}
func (vctx *visitorContext) normalizeFileInfo(mctx android.ModuleContext) {
@@ -2067,6 +2072,7 @@
fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
fi.isJniLib = isJniLib
vctx.filesInfo = append(vctx.filesInfo, fi)
+ addAconfigFiles(vctx, ctx, child)
// Collect the list of stub-providing libs except:
// - VNDK libs are only for vendors
// - bootstrap bionic libs are treated as provided by system
@@ -2090,6 +2096,7 @@
switch ch := child.(type) {
case *cc.Module:
vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
+ addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
case *rust.Module:
vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
@@ -2132,6 +2139,7 @@
return false
}
vctx.filesInfo = append(vctx.filesInfo, af)
+ addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
default:
ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
@@ -2140,6 +2148,7 @@
switch ap := child.(type) {
case *java.AndroidApp:
vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
+ addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
case *java.AndroidAppImport:
vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
@@ -2298,6 +2307,7 @@
}
vctx.filesInfo = append(vctx.filesInfo, af)
+ addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
} else if rm, ok := child.(*rust.Module); ok {
af := apexFileForRustLibrary(ctx, rm)
@@ -2378,6 +2388,13 @@
return false
}
+func addAconfigFiles(vctx *visitorContext, ctx android.ModuleContext, module blueprint.Module) {
+ dep := ctx.OtherModuleProvider(module, aconfig.TransitiveDeclarationsInfoProvider).(aconfig.TransitiveDeclarationsInfo)
+ if len(dep.AconfigFiles) > 0 && dep.AconfigFiles[ctx.ModuleName()] != nil {
+ vctx.aconfigFiles = append(vctx.aconfigFiles, dep.AconfigFiles[ctx.ModuleName()].ToList()...)
+ }
+}
+
func (a *apexBundle) shouldCheckDuplicate(ctx android.ModuleContext) bool {
// TODO(b/263308293) remove this
if a.properties.IsCoverageVariant {
@@ -2459,6 +2476,7 @@
// 3) some fields in apexBundle struct are configured
a.installDir = android.PathForModuleInstall(ctx, "apex")
a.filesInfo = vctx.filesInfo
+ a.aconfigFiles = android.FirstUniquePaths(vctx.aconfigFiles)
a.setPayloadFsType(ctx)
a.setSystemLibLink(ctx)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index ddb9a40..af643a0 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -25,6 +25,7 @@
"strings"
"testing"
+ "android/soong/aconfig/codegen"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -151,6 +152,7 @@
prebuilt_etc.PrepareForTestWithPrebuiltEtc,
rust.PrepareForTestWithRustDefaultModules,
sh.PrepareForTestWithShBuildComponents,
+ codegen.PrepareForTestWithAconfigBuildComponents,
PrepareForTestWithApexBuildComponents,
@@ -10756,3 +10758,437 @@
inputs.Strings(),
"out/soong/.intermediates/libbar/android_arm64_armv8-a_shared/libbar.so")
}
+
+var apex_default_bp = `
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ filegroup {
+ name: "myapex.manifest",
+ srcs: ["apex_manifest.json"],
+ }
+
+ filegroup {
+ name: "myapex.androidmanifest",
+ srcs: ["AndroidManifest.xml"],
+ }
+`
+
+func TestAconfigFilesJavaDeps(t *testing.T) {
+ ctx := testApex(t, apex_default_bp+`
+ apex {
+ name: "myapex",
+ manifest: ":myapex.manifest",
+ androidManifest: ":myapex.androidmanifest",
+ key: "myapex.key",
+ java_libs: [
+ "my_java_library_foo",
+ "my_java_library_bar",
+ ],
+ updatable: false,
+ }
+
+ java_library {
+ name: "my_java_library_foo",
+ srcs: ["foo/bar/MyClass.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ static_libs: ["my_java_aconfig_library_foo"],
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+
+ java_library {
+ name: "my_java_library_bar",
+ srcs: ["foo/bar/MyClass.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ static_libs: ["my_java_aconfig_library_bar"],
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+
+ aconfig_declarations {
+ name: "my_aconfig_declarations_foo",
+ package: "com.example.package",
+ container: "myapex",
+ srcs: ["foo.aconfig"],
+ }
+
+ java_aconfig_library {
+ name: "my_java_aconfig_library_foo",
+ aconfig_declarations: "my_aconfig_declarations_foo",
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+
+ aconfig_declarations {
+ name: "my_aconfig_declarations_bar",
+ package: "com.example.package",
+ container: "myapex",
+ srcs: ["bar.aconfig"],
+ }
+
+ java_aconfig_library {
+ name: "my_java_aconfig_library_bar",
+ aconfig_declarations: "my_aconfig_declarations_bar",
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+ `)
+
+ mod := ctx.ModuleForTests("myapex", "android_common_myapex")
+ s := mod.Rule("apexRule").Args["copy_commands"]
+ copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
+ if len(copyCmds) != 5 {
+ t.Fatalf("Expected 5 commands, got %d in:\n%s", len(copyCmds), s)
+ }
+
+ ensureMatches(t, copyCmds[4], "^cp -f .*/aconfig_flags.pb .*/image.apex$")
+
+ combineAconfigRule := mod.Rule("All_aconfig_declarations_dump")
+ s = " " + combineAconfigRule.Args["cache_files"]
+ aconfigArgs := regexp.MustCompile(" --cache ").Split(s, -1)[1:]
+ if len(aconfigArgs) != 2 {
+ t.Fatalf("Expected 2 commands, got %d in:\n%s", len(aconfigArgs), s)
+ }
+ android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_foo/intermediate.pb")
+ android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_bar/intermediate.pb")
+
+ buildParams := combineAconfigRule.BuildParams
+ android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_foo/intermediate.pb")
+ android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_bar/intermediate.pb")
+ ensureContains(t, buildParams.Output.String(), "android_common_myapex/aconfig_flags.pb")
+}
+
+func TestAconfigFilesJavaAndCcDeps(t *testing.T) {
+ ctx := testApex(t, apex_default_bp+`
+ apex {
+ name: "myapex",
+ manifest: ":myapex.manifest",
+ androidManifest: ":myapex.androidmanifest",
+ key: "myapex.key",
+ java_libs: [
+ "my_java_library_foo",
+ ],
+ native_shared_libs: [
+ "my_cc_library_bar",
+ ],
+ binaries: [
+ "my_cc_binary_baz",
+ ],
+ updatable: false,
+ }
+
+ java_library {
+ name: "my_java_library_foo",
+ srcs: ["foo/bar/MyClass.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ static_libs: ["my_java_aconfig_library_foo"],
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+
+ cc_library {
+ name: "my_cc_library_bar",
+ srcs: ["foo/bar/MyClass.cc"],
+ static_libs: ["my_cc_aconfig_library_bar"],
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+
+ cc_binary {
+ name: "my_cc_binary_baz",
+ srcs: ["foo/bar/MyClass.cc"],
+ static_libs: ["my_cc_aconfig_library_baz"],
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+
+ aconfig_declarations {
+ name: "my_aconfig_declarations_foo",
+ package: "com.example.package",
+ container: "myapex",
+ srcs: ["foo.aconfig"],
+ }
+
+ java_aconfig_library {
+ name: "my_java_aconfig_library_foo",
+ aconfig_declarations: "my_aconfig_declarations_foo",
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+
+ aconfig_declarations {
+ name: "my_aconfig_declarations_bar",
+ package: "com.example.package",
+ container: "myapex",
+ srcs: ["bar.aconfig"],
+ }
+
+ cc_aconfig_library {
+ name: "my_cc_aconfig_library_bar",
+ aconfig_declarations: "my_aconfig_declarations_bar",
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+
+ aconfig_declarations {
+ name: "my_aconfig_declarations_baz",
+ package: "com.example.package",
+ container: "myapex",
+ srcs: ["baz.aconfig"],
+ }
+
+ cc_aconfig_library {
+ name: "my_cc_aconfig_library_baz",
+ aconfig_declarations: "my_aconfig_declarations_baz",
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+
+ cc_library {
+ name: "server_configurable_flags",
+ srcs: ["server_configurable_flags.cc"],
+ }
+ `)
+
+ mod := ctx.ModuleForTests("myapex", "android_common_myapex")
+ s := mod.Rule("apexRule").Args["copy_commands"]
+ copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
+ if len(copyCmds) != 9 {
+ t.Fatalf("Expected 9 commands, got %d in:\n%s", len(copyCmds), s)
+ }
+
+ ensureMatches(t, copyCmds[8], "^cp -f .*/aconfig_flags.pb .*/image.apex$")
+
+ combineAconfigRule := mod.Rule("All_aconfig_declarations_dump")
+ s = " " + combineAconfigRule.Args["cache_files"]
+ aconfigArgs := regexp.MustCompile(" --cache ").Split(s, -1)[1:]
+ if len(aconfigArgs) != 3 {
+ t.Fatalf("Expected 3 commands, got %d in:\n%s", len(aconfigArgs), s)
+ }
+ android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_foo/intermediate.pb")
+ android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_bar/intermediate.pb")
+ android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_baz/intermediate.pb")
+
+ buildParams := combineAconfigRule.BuildParams
+ if len(buildParams.Inputs) != 3 {
+ t.Fatalf("Expected 3 input, got %d", len(buildParams.Inputs))
+ }
+ android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_foo/intermediate.pb")
+ android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_bar/intermediate.pb")
+ android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_baz/intermediate.pb")
+ ensureContains(t, buildParams.Output.String(), "android_common_myapex/aconfig_flags.pb")
+}
+
+func TestAconfigFilesOnlyMatchCurrentApex(t *testing.T) {
+ ctx := testApex(t, apex_default_bp+`
+ apex {
+ name: "myapex",
+ manifest: ":myapex.manifest",
+ androidManifest: ":myapex.androidmanifest",
+ key: "myapex.key",
+ java_libs: [
+ "my_java_library_foo",
+ "other_java_library_bar",
+ ],
+ updatable: false,
+ }
+
+ java_library {
+ name: "my_java_library_foo",
+ srcs: ["foo/bar/MyClass.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ static_libs: ["my_java_aconfig_library_foo"],
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+
+ java_library {
+ name: "other_java_library_bar",
+ srcs: ["foo/bar/MyClass.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ static_libs: ["other_java_aconfig_library_bar"],
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+
+ aconfig_declarations {
+ name: "my_aconfig_declarations_foo",
+ package: "com.example.package",
+ container: "myapex",
+ srcs: ["foo.aconfig"],
+ }
+
+ java_aconfig_library {
+ name: "my_java_aconfig_library_foo",
+ aconfig_declarations: "my_aconfig_declarations_foo",
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+
+ aconfig_declarations {
+ name: "other_aconfig_declarations_bar",
+ package: "com.example.package",
+ container: "otherapex",
+ srcs: ["bar.aconfig"],
+ }
+
+ java_aconfig_library {
+ name: "other_java_aconfig_library_bar",
+ aconfig_declarations: "other_aconfig_declarations_bar",
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+ `)
+
+ mod := ctx.ModuleForTests("myapex", "android_common_myapex")
+ combineAconfigRule := mod.Rule("All_aconfig_declarations_dump")
+ s := " " + combineAconfigRule.Args["cache_files"]
+ aconfigArgs := regexp.MustCompile(" --cache ").Split(s, -1)[1:]
+ if len(aconfigArgs) != 1 {
+ t.Fatalf("Expected 1 commands, got %d in:\n%s", len(aconfigArgs), s)
+ }
+ android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_foo/intermediate.pb")
+
+ buildParams := combineAconfigRule.BuildParams
+ if len(buildParams.Inputs) != 1 {
+ t.Fatalf("Expected 1 input, got %d", len(buildParams.Inputs))
+ }
+ android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_foo/intermediate.pb")
+ ensureContains(t, buildParams.Output.String(), "android_common_myapex/aconfig_flags.pb")
+}
+
+func TestAconfigFilesRemoveDuplicates(t *testing.T) {
+ ctx := testApex(t, apex_default_bp+`
+ apex {
+ name: "myapex",
+ manifest: ":myapex.manifest",
+ androidManifest: ":myapex.androidmanifest",
+ key: "myapex.key",
+ java_libs: [
+ "my_java_library_foo",
+ "my_java_library_bar",
+ ],
+ updatable: false,
+ }
+
+ java_library {
+ name: "my_java_library_foo",
+ srcs: ["foo/bar/MyClass.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ static_libs: ["my_java_aconfig_library_foo"],
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+
+ java_library {
+ name: "my_java_library_bar",
+ srcs: ["foo/bar/MyClass.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ static_libs: ["my_java_aconfig_library_bar"],
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+
+ aconfig_declarations {
+ name: "my_aconfig_declarations_foo",
+ package: "com.example.package",
+ container: "myapex",
+ srcs: ["foo.aconfig"],
+ }
+
+ java_aconfig_library {
+ name: "my_java_aconfig_library_foo",
+ aconfig_declarations: "my_aconfig_declarations_foo",
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+
+ java_aconfig_library {
+ name: "my_java_aconfig_library_bar",
+ aconfig_declarations: "my_aconfig_declarations_foo",
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+ `)
+
+ mod := ctx.ModuleForTests("myapex", "android_common_myapex")
+ combineAconfigRule := mod.Rule("All_aconfig_declarations_dump")
+ s := " " + combineAconfigRule.Args["cache_files"]
+ aconfigArgs := regexp.MustCompile(" --cache ").Split(s, -1)[1:]
+ if len(aconfigArgs) != 1 {
+ t.Fatalf("Expected 1 commands, got %d in:\n%s", len(aconfigArgs), s)
+ }
+ android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_foo/intermediate.pb")
+
+ buildParams := combineAconfigRule.BuildParams
+ if len(buildParams.Inputs) != 1 {
+ t.Fatalf("Expected 1 input, got %d", len(buildParams.Inputs))
+ }
+ android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_foo/intermediate.pb")
+ ensureContains(t, buildParams.Output.String(), "android_common_myapex/aconfig_flags.pb")
+}
diff --git a/apex/builder.go b/apex/builder.go
index 3f358ac..3078863 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -24,6 +24,7 @@
"strconv"
"strings"
+ "android/soong/aconfig"
"android/soong/android"
"android/soong/java"
@@ -36,6 +37,7 @@
)
func init() {
+ pctx.Import("android/soong/aconfig")
pctx.Import("android/soong/android")
pctx.Import("android/soong/cc/config")
pctx.Import("android/soong/java")
@@ -80,6 +82,7 @@
pctx.HostBinToolVariable("conv_linker_config", "conv_linker_config")
pctx.HostBinToolVariable("assemble_vintf", "assemble_vintf")
pctx.HostBinToolVariable("apex_elf_checker", "apex_elf_checker")
+ pctx.HostBinToolVariable("aconfig", "aconfig")
}
var (
@@ -574,6 +577,7 @@
installMapSet[installMapPath.String()+":"+fi.installDir+"/"+fi.builtFile.Base()] = true
}
+
implicitInputs = append(implicitInputs, a.manifestPbOut)
if len(installMapSet) > 0 {
@@ -628,10 +632,28 @@
outHostBinDir := ctx.Config().HostToolPath(ctx, "").String()
prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
+ defaultReadOnlyFiles := []string{"apex_manifest.json", "apex_manifest.pb"}
+ if len(a.aconfigFiles) > 0 {
+ apexAconfigFile := android.PathForModuleOut(ctx, "aconfig_flags.pb")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: aconfig.AllDeclarationsRule,
+ Inputs: a.aconfigFiles,
+ Output: apexAconfigFile,
+ Description: "combine_aconfig_declarations",
+ Args: map[string]string{
+ "cache_files": android.JoinPathsWithPrefix(a.aconfigFiles, "--cache "),
+ },
+ })
+
+ copyCommands = append(copyCommands, "cp -f "+apexAconfigFile.String()+" "+imageDir.String())
+ implicitInputs = append(implicitInputs, apexAconfigFile)
+ defaultReadOnlyFiles = append(defaultReadOnlyFiles, apexAconfigFile.Base())
+ }
+
////////////////////////////////////////////////////////////////////////////////////
// Step 2: create canned_fs_config which encodes filemode,uid,gid of each files
// in this APEX. The file will be used by apexer in later steps.
- cannedFsConfig := a.buildCannedFsConfig(ctx)
+ cannedFsConfig := a.buildCannedFsConfig(ctx, defaultReadOnlyFiles)
implicitInputs = append(implicitInputs, cannedFsConfig)
////////////////////////////////////////////////////////////////////////////////////
@@ -1082,8 +1104,8 @@
a.lintReports = java.BuildModuleLintReportZips(ctx, depSetsBuilder.Build())
}
-func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext) android.OutputPath {
- var readOnlyPaths = []string{"apex_manifest.json", "apex_manifest.pb"}
+func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext, defaultReadOnlyFiles []string) android.OutputPath {
+ var readOnlyPaths = defaultReadOnlyFiles
var executablePaths []string // this also includes dirs
var appSetDirs []string
appSetFiles := make(map[string]android.Path)
diff --git a/cc/Android.bp b/cc/Android.bp
index 77e96db..06e0e5e 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -9,6 +9,7 @@
"blueprint",
"blueprint-pathtools",
"soong",
+ "soong-aconfig",
"soong-aidl-library",
"soong-android",
"soong-bazel",
diff --git a/cc/cc.go b/cc/cc.go
index e215438..d2518a1 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -30,6 +30,7 @@
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
+ "android/soong/aconfig"
"android/soong/aidl_library"
"android/soong/android"
"android/soong/bazel/cquery"
@@ -923,6 +924,9 @@
apexSdkVersion android.ApiLevel
hideApexVariantFromMake bool
+
+ // Aconfig files for all transitive deps. Also exposed via TransitiveDeclarationsInfo
+ transitiveAconfigFiles map[string]*android.DepSet[android.Path]
}
func (c *Module) AddJSONData(d *map[string]interface{}) {
@@ -2335,6 +2339,8 @@
ctx.SetProvider(testing.TestModuleProviderKey, testing.TestModuleProviderData{})
}
+ aconfig.CollectTransitiveAconfigFiles(ctx, &c.transitiveAconfigFiles)
+
c.maybeInstall(ctx, apexInfo)
}
diff --git a/java/Android.bp b/java/Android.bp
index cf96871..6020d00 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -9,6 +9,7 @@
"blueprint",
"blueprint-pathtools",
"soong",
+ "soong-aconfig",
"soong-android",
"soong-bazel",
"soong-cc",
diff --git a/java/androidmk.go b/java/androidmk.go
index 84f78c8..fb3fefa 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -128,8 +128,8 @@
if library.dexpreopter.configPath != nil {
entries.SetPath("LOCAL_SOONG_DEXPREOPT_CONFIG", library.dexpreopter.configPath)
}
-
- entries.SetOptionalPaths("LOCAL_ACONFIG_FILES", library.getTransitiveAconfigFiles().ToList())
+ // TODO(b/311155208): The container here should be system.
+ entries.SetOptionalPaths("LOCAL_ACONFIG_FILES", library.getTransitiveAconfigFiles(""))
},
},
})
@@ -306,7 +306,8 @@
if len(binary.dexpreopter.builtInstalled) > 0 {
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", binary.dexpreopter.builtInstalled)
}
- entries.SetOptionalPaths("LOCAL_ACONFIG_FILES", binary.getTransitiveAconfigFiles().ToList())
+ // TODO(b/311155208): The container here should be system.
+ entries.SetOptionalPaths("LOCAL_ACONFIG_FILES", binary.getTransitiveAconfigFiles(""))
},
},
ExtraFooters: []android.AndroidMkExtraFootersFunc{
@@ -459,7 +460,8 @@
entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", app.linter.reports)
if app.Name() != "framework-res" {
- entries.SetOptionalPaths("LOCAL_ACONFIG_FILES", app.getTransitiveAconfigFiles().ToList())
+ // TODO(b/311155208): The container here should be system.
+ entries.SetOptionalPaths("LOCAL_ACONFIG_FILES", app.getTransitiveAconfigFiles(""))
}
},
},
@@ -537,7 +539,8 @@
entries.SetPath("LOCAL_FULL_MANIFEST_FILE", a.mergedManifestFile)
entries.AddStrings("LOCAL_SOONG_EXPORT_PROGUARD_FLAGS", a.exportedProguardFlagFiles.Strings()...)
entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", true)
- entries.SetOptionalPaths("LOCAL_ACONFIG_FILES", a.getTransitiveAconfigFiles().ToList())
+ // TODO(b/311155208): The container here should be system.
+ entries.SetOptionalPaths("LOCAL_ACONFIG_FILES", a.getTransitiveAconfigFiles(""))
})
return entriesList
diff --git a/java/base.go b/java/base.go
index fdc164e..3bbae2e 100644
--- a/java/base.go
+++ b/java/base.go
@@ -25,6 +25,7 @@
"github.com/google/blueprint/pathtools"
"github.com/google/blueprint/proptools"
+ "android/soong/aconfig"
"android/soong/android"
"android/soong/dexpreopt"
"android/soong/java/config"
@@ -512,13 +513,8 @@
// or the module should override Stem().
stem string
- // Aconfig "cache files" that went directly into this module. Transitive ones are
- // tracked via JavaInfo.TransitiveAconfigFiles
- // TODO: Extract to something standalone to propagate tags via GeneratedJavaLibraryModule
- aconfigIntermediates android.Paths
-
- // Aconfig files for all transitive deps. Also exposed via JavaInfo
- transitiveAconfigFiles *android.DepSet[android.Path]
+ // Aconfig files for all transitive deps. Also exposed via TransitiveDeclarationsInfo
+ transitiveAconfigFiles map[string]*android.DepSet[android.Path]
}
func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error {
@@ -1723,7 +1719,7 @@
ctx.CheckbuildFile(outputFile)
- j.collectTransitiveAconfigFiles(ctx)
+ aconfig.CollectTransitiveAconfigFiles(ctx, &j.transitiveAconfigFiles)
ctx.SetProvider(JavaInfoProvider, JavaInfo{
HeaderJars: android.PathsIfNonNil(j.headerJarFile),
@@ -1740,7 +1736,6 @@
ExportedPluginClasses: j.exportedPluginClasses,
ExportedPluginDisableTurbine: j.exportedDisableTurbine,
JacocoReportClassesFile: j.jacocoReportClassesFile,
- TransitiveAconfigFiles: j.transitiveAconfigFiles,
})
// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
@@ -2081,32 +2076,8 @@
return Bool(j.properties.Installable)
}
-func (j *Module) collectTransitiveAconfigFiles(ctx android.ModuleContext) {
- // Aconfig files from this module
- mine := j.aconfigIntermediates
-
- // Aconfig files from transitive dependencies
- fromDeps := []*android.DepSet[android.Path]{}
- ctx.VisitDirectDeps(func(module android.Module) {
- dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
- if dep.TransitiveAconfigFiles != nil {
- fromDeps = append(fromDeps, dep.TransitiveAconfigFiles)
- }
- })
-
- // DepSet containing aconfig files myself and from dependencies
- j.transitiveAconfigFiles = android.NewDepSet(android.POSTORDER, mine, fromDeps)
-}
-
-func (j *Module) AddAconfigIntermediate(path android.Path) {
- j.aconfigIntermediates = append(j.aconfigIntermediates, path)
-}
-
-func (j *Module) getTransitiveAconfigFiles() *android.DepSet[android.Path] {
- if j.transitiveAconfigFiles == nil {
- panic(fmt.Errorf("java.Moduile: getTransitiveAconfigFiles called before collectTransitiveAconfigFiles module=%s", j.Name()))
- }
- return j.transitiveAconfigFiles
+func (j *Module) getTransitiveAconfigFiles(container string) []android.Path {
+ return j.transitiveAconfigFiles[container].ToList()
}
type sdkLinkType int
diff --git a/java/generated_java_library_test.go b/java/generated_java_library_test.go
index 7fbbfee..ac9524e 100644
--- a/java/generated_java_library_test.go
+++ b/java/generated_java_library_test.go
@@ -37,7 +37,6 @@
}
func (callbacks *JavaGenLibTestCallbacks) GenerateSourceJarBuildActions(module *GeneratedJavaLibraryModule, ctx android.ModuleContext) android.Path {
- module.AddAconfigIntermediate(android.PathForOutput(ctx, "aconfig_cache_file"))
return android.PathForOutput(ctx, "blah.srcjar")
}
diff --git a/java/java.go b/java/java.go
index bb9357c..4962698 100644
--- a/java/java.go
+++ b/java/java.go
@@ -297,15 +297,6 @@
// JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be
// instrumented by jacoco.
JacocoReportClassesFile android.Path
-
- // set of aconfig flags for all transitive libs deps
- // TODO(joeo): It would be nice if this were over in the aconfig package instead of here.
- // In order to do that, generated_java_library would need a way doing
- // collectTransitiveAconfigFiles with one of the callbacks, and having that automatically
- // propagated. If we were to clean up more of the stuff on JavaInfo that's not part of
- // core java rules (e.g. AidlIncludeDirs), then maybe adding more framework to do that would be
- // worth it.
- TransitiveAconfigFiles *android.DepSet[android.Path]
}
var JavaInfoProvider = blueprint.NewProvider(JavaInfo{})