Merge "Add container property to aconfig_declarations." into main am: 9dc6b1025d am: 4d6d371aee

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/2835990

Change-Id: I71933df90865549160d9aeca34d8e74f41f58fdc
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Yu Liu 2023-11-30 22:35:04 +00:00 committed by Automerger Merge Worker
commit 34b5c38c44
26 changed files with 750 additions and 146 deletions

View file

@ -12,28 +12,19 @@ bootstrap_go_package {
"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"],
}

View file

@ -38,6 +38,9 @@ type DeclarationsModule struct {
// 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 @@ func (module *DeclarationsModule) DepsMutator(ctx android.BottomUpMutatorContext
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 @@ func optionalVariable(prefix string, value string) string {
}
// 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 @@ func (module *DeclarationsModule) GenerateAndroidBuildActions(ctx android.Module
},
})
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

View file

@ -26,6 +26,7 @@ func TestAconfigDeclarations(t *testing.T) {
aconfig_declarations {
name: "module_name",
package: "com.example.package",
container: "com.android.foo",
srcs: [
"foo.aconfig",
"bar.aconfig",
@ -37,8 +38,9 @@ func TestAconfigDeclarations(t *testing.T) {
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())
}

View file

@ -37,17 +37,17 @@ func (this *allAconfigDeclarationsSingleton) GenerateBuildActions(ctx android.Si
// 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",

View file

@ -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"],
}

View file

@ -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 @@ func (this *CcAconfigLibraryCallbacks) GeneratorSources(ctx cc.ModuleContext) cc
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 @@ func (this *CcAconfigLibraryCallbacks) GeneratorBuildActions(ctx cc.ModuleContex
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) {

View file

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package aconfig
package codegen
import (
"fmt"

83
aconfig/codegen/init.go Normal file
View file

@ -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)
}

View file

@ -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 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuild
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 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuild
},
})
// 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
}

View file

@ -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 @@ func runJavaAndroidMkTest(t *testing.T, bp string) {
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 @@ func runJavaAndroidMkTest(t *testing.T, bp string) {
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 @@ func TestAndroidMkJavaLibrary(t *testing.T) {
"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 @@ func TestAndroidMkAndroidApp(t *testing.T) {
"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 @@ func TestAndroidMkBinary(t *testing.T) {
"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 @@ func TestAndroidMkAndroidLibrary(t *testing.T) {
"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 @@ func TestAndroidMkBinaryThatLinksAgainstAar(t *testing.T) {
"src/foo.java",
],
static_libs: [
"my_java_aconfig_library",
"my_java_aconfig_library_foo",
"my_java_aconfig_library_bar",
],
platform_apis: true,
}

View file

@ -1,8 +1,9 @@
package aconfig
package codegen
import (
"fmt"
"android/soong/aconfig"
"android/soong/android"
"android/soong/rust"
@ -64,7 +65,7 @@ func (a *aconfigDecorator) GenerateSource(ctx rust.ModuleContext, deps rust.Path
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) {

View file

@ -1,4 +1,4 @@
package aconfig
package codegen
import (
"fmt"

View file

@ -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)
})

View file

@ -40,54 +40,8 @@ var (
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 @@ func RegisterBuildComponents(ctx android.RegistrationContext) {
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)
}

View file

@ -1293,3 +1293,10 @@ func StringRelativeToTop(config Config, command string) string {
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)
}
}

View file

@ -8,6 +8,8 @@ bootstrap_go_package {
deps: [
"blueprint",
"soong",
"soong-aconfig",
"soong-aconfig-codegen",
"soong-android",
"soong-bazel",
"soong-bpf",

View file

@ -24,6 +24,7 @@ import (
"sort"
"strings"
"android/soong/aconfig"
"android/soong/bazel/cquery"
"github.com/google/blueprint"
@ -482,6 +483,8 @@ type apexBundle struct {
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 @@ type visitorContext struct {
// 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 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
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 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
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 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
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 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
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 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
}
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 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
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 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// 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)

View file

@ -25,6 +25,7 @@ import (
"strings"
"testing"
"android/soong/aconfig/codegen"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@ -151,6 +152,7 @@ var prepareForApexTest = android.GroupFixturePreparers(
prebuilt_etc.PrepareForTestWithPrebuiltEtc,
rust.PrepareForTestWithRustDefaultModules,
sh.PrepareForTestWithShBuildComponents,
codegen.PrepareForTestWithAconfigBuildComponents,
PrepareForTestWithApexBuildComponents,
@ -10756,3 +10758,437 @@ func TestFileSystemShouldSkipApexLibraries(t *testing.T) {
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")
}

View file

@ -24,6 +24,7 @@ import (
"strconv"
"strings"
"android/soong/aconfig"
"android/soong/android"
"android/soong/java"
@ -36,6 +37,7 @@ var (
)
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 @@ func init() {
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 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) {
installMapSet[installMapPath.String()+":"+fi.installDir+"/"+fi.builtFile.Base()] = true
}
implicitInputs = append(implicitInputs, a.manifestPbOut)
if len(installMapSet) > 0 {
@ -628,10 +632,28 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) {
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 @@ func (a *apexBundle) buildLintReports(ctx android.ModuleContext) {
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)

View file

@ -9,6 +9,7 @@ bootstrap_go_package {
"blueprint",
"blueprint-pathtools",
"soong",
"soong-aconfig",
"soong-aidl-library",
"soong-android",
"soong-bazel",

View file

@ -30,6 +30,7 @@ import (
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
"android/soong/aconfig"
"android/soong/aidl_library"
"android/soong/android"
"android/soong/bazel/cquery"
@ -925,6 +926,9 @@ type Module struct {
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{}) {
@ -2319,6 +2323,8 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
ctx.SetProvider(testing.TestModuleProviderKey, testing.TestModuleProviderData{})
}
aconfig.CollectTransitiveAconfigFiles(ctx, &c.transitiveAconfigFiles)
c.maybeInstall(ctx, apexInfo)
}

View file

@ -9,6 +9,7 @@ bootstrap_go_package {
"blueprint",
"blueprint-pathtools",
"soong",
"soong-aconfig",
"soong-android",
"soong-bazel",
"soong-cc",

View file

@ -128,8 +128,8 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
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 @@ func (binary *Binary) AndroidMkEntries() []android.AndroidMkEntries {
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 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
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 @@ func (a *AndroidLibrary) AndroidMkEntries() []android.AndroidMkEntries {
entries.SetPath("LOCAL_FULL_MANIFEST_FILE", a.mergedManifestFile)
entries.SetPath("LOCAL_SOONG_EXPORT_PROGUARD_FLAGS", a.combinedExportedProguardFlagsFile)
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

View file

@ -25,6 +25,7 @@ import (
"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 @@ type Module struct {
// 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 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
ctx.CheckbuildFile(outputFile)
j.collectTransitiveAconfigFiles(ctx)
aconfig.CollectTransitiveAconfigFiles(ctx, &j.transitiveAconfigFiles)
ctx.SetProvider(JavaInfoProvider, JavaInfo{
HeaderJars: android.PathsIfNonNil(j.headerJarFile),
@ -1740,7 +1736,6 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
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 @@ func (j *Module) IsInstallable() bool {
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

View file

@ -37,7 +37,6 @@ func (callbacks *JavaGenLibTestCallbacks) DepsMutator(module *GeneratedJavaLibra
}
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")
}

View file

@ -297,15 +297,6 @@ type JavaInfo struct {
// 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{})