Add container property to aconfig_declarations.
Bug: 311155208 Test: Unit test Change-Id: I7b187138856d0144203961e82b6dad5e2f8eed9d
This commit is contained in:
@@ -12,28 +12,19 @@ bootstrap_go_package {
|
|||||||
"soong",
|
"soong",
|
||||||
"soong-android",
|
"soong-android",
|
||||||
"soong-bazel",
|
"soong-bazel",
|
||||||
"soong-android",
|
|
||||||
"soong-java",
|
|
||||||
"soong-rust",
|
|
||||||
],
|
],
|
||||||
srcs: [
|
srcs: [
|
||||||
"aconfig_declarations.go",
|
"aconfig_declarations.go",
|
||||||
"aconfig_values.go",
|
"aconfig_values.go",
|
||||||
"aconfig_value_set.go",
|
"aconfig_value_set.go",
|
||||||
"all_aconfig_declarations.go",
|
"all_aconfig_declarations.go",
|
||||||
"cc_aconfig_library.go",
|
|
||||||
"init.go",
|
"init.go",
|
||||||
"java_aconfig_library.go",
|
|
||||||
"testing.go",
|
"testing.go",
|
||||||
"rust_aconfig_library.go",
|
|
||||||
],
|
],
|
||||||
testSrcs: [
|
testSrcs: [
|
||||||
"aconfig_declarations_test.go",
|
"aconfig_declarations_test.go",
|
||||||
"aconfig_values_test.go",
|
"aconfig_values_test.go",
|
||||||
"aconfig_value_set_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"],
|
pluginFor: ["soong_build"],
|
||||||
}
|
}
|
||||||
|
@@ -38,6 +38,9 @@ type DeclarationsModule struct {
|
|||||||
|
|
||||||
// Values from TARGET_RELEASE / RELEASE_ACONFIG_VALUE_SETS
|
// Values from TARGET_RELEASE / RELEASE_ACONFIG_VALUE_SETS
|
||||||
Values []string `blueprint:"mutated"`
|
Values []string `blueprint:"mutated"`
|
||||||
|
|
||||||
|
// Container(system/vendor/apex) that this module belongs to
|
||||||
|
Container string
|
||||||
}
|
}
|
||||||
|
|
||||||
intermediatePath android.WritablePath
|
intermediatePath android.WritablePath
|
||||||
@@ -69,6 +72,8 @@ func (module *DeclarationsModule) DepsMutator(ctx android.BottomUpMutatorContext
|
|||||||
if len(module.properties.Package) == 0 {
|
if len(module.properties.Package) == 0 {
|
||||||
ctx.PropertyErrorf("package", "missing package property")
|
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
|
// Add a dependency on the aconfig_value_sets defined in
|
||||||
// RELEASE_ACONFIG_VALUE_SETS, and add any aconfig_values that
|
// 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
|
// Provider published by aconfig_value_set
|
||||||
type declarationsProviderData struct {
|
type DeclarationsProviderData struct {
|
||||||
Package string
|
Package string
|
||||||
|
Container string
|
||||||
IntermediatePath android.WritablePath
|
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) {
|
func (module *DeclarationsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
// Get the values that came from the global RELEASE_ACONFIG_VALUE_SETS flag
|
// 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,
|
Package: module.properties.Package,
|
||||||
|
Container: module.properties.Container,
|
||||||
IntermediatePath: intermediatePath,
|
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 {
|
type bazelAconfigDeclarationsAttributes struct {
|
||||||
Srcs bazel.LabelListAttribute
|
Srcs bazel.LabelListAttribute
|
||||||
Package string
|
Package string
|
||||||
|
@@ -26,6 +26,7 @@ func TestAconfigDeclarations(t *testing.T) {
|
|||||||
aconfig_declarations {
|
aconfig_declarations {
|
||||||
name: "module_name",
|
name: "module_name",
|
||||||
package: "com.example.package",
|
package: "com.example.package",
|
||||||
|
container: "com.android.foo",
|
||||||
srcs: [
|
srcs: [
|
||||||
"foo.aconfig",
|
"foo.aconfig",
|
||||||
"bar.aconfig",
|
"bar.aconfig",
|
||||||
@@ -37,8 +38,9 @@ func TestAconfigDeclarations(t *testing.T) {
|
|||||||
module := result.ModuleForTests("module_name", "").Module().(*DeclarationsModule)
|
module := result.ModuleForTests("module_name", "").Module().(*DeclarationsModule)
|
||||||
|
|
||||||
// Check that the provider has the right contents
|
// 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, "package", depData.Package, "com.example.package")
|
||||||
|
android.AssertStringEquals(t, "container", depData.Container, "com.android.foo")
|
||||||
if !strings.HasSuffix(depData.IntermediatePath.String(), "/intermediate.pb") {
|
if !strings.HasSuffix(depData.IntermediatePath.String(), "/intermediate.pb") {
|
||||||
t.Errorf("Missing intermediates path in provider: %s", depData.IntermediatePath.String())
|
t.Errorf("Missing intermediates path in provider: %s", depData.IntermediatePath.String())
|
||||||
}
|
}
|
||||||
|
@@ -37,17 +37,17 @@ func (this *allAconfigDeclarationsSingleton) GenerateBuildActions(ctx android.Si
|
|||||||
// Find all of the aconfig_declarations modules
|
// Find all of the aconfig_declarations modules
|
||||||
var cacheFiles android.Paths
|
var cacheFiles android.Paths
|
||||||
ctx.VisitAllModules(func(module android.Module) {
|
ctx.VisitAllModules(func(module android.Module) {
|
||||||
if !ctx.ModuleHasProvider(module, declarationsProviderKey) {
|
if !ctx.ModuleHasProvider(module, DeclarationsProviderKey) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
decl := ctx.ModuleProvider(module, declarationsProviderKey).(declarationsProviderData)
|
decl := ctx.ModuleProvider(module, DeclarationsProviderKey).(DeclarationsProviderData)
|
||||||
cacheFiles = append(cacheFiles, decl.IntermediatePath)
|
cacheFiles = append(cacheFiles, decl.IntermediatePath)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Generate build action for aconfig
|
// Generate build action for aconfig
|
||||||
this.intermediatePath = android.PathForIntermediates(ctx, "all_aconfig_declarations.pb")
|
this.intermediatePath = android.PathForIntermediates(ctx, "all_aconfig_declarations.pb")
|
||||||
ctx.Build(pctx, android.BuildParams{
|
ctx.Build(pctx, android.BuildParams{
|
||||||
Rule: allDeclarationsRule,
|
Rule: AllDeclarationsRule,
|
||||||
Inputs: cacheFiles,
|
Inputs: cacheFiles,
|
||||||
Output: this.intermediatePath,
|
Output: this.intermediatePath,
|
||||||
Description: "all_aconfig_declarations",
|
Description: "all_aconfig_declarations",
|
||||||
|
32
aconfig/codegen/Android.bp
Normal file
32
aconfig/codegen/Android.bp
Normal 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"],
|
||||||
|
}
|
@@ -12,9 +12,10 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package aconfig
|
package codegen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"android/soong/aconfig"
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
"android/soong/bazel"
|
"android/soong/bazel"
|
||||||
"android/soong/cc"
|
"android/soong/cc"
|
||||||
@@ -92,7 +93,7 @@ func (this *CcAconfigLibraryCallbacks) GeneratorSources(ctx cc.ModuleContext) cc
|
|||||||
if len(declarationsModules) != 1 {
|
if len(declarationsModules) != 1 {
|
||||||
panic(fmt.Errorf("Exactly one aconfig_declarations property required"))
|
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.
|
// Figure out the generated file paths. This has to match aconfig's codegen_cpp.rs.
|
||||||
this.generatedDir = android.PathForModuleGen(ctx)
|
this.generatedDir = android.PathForModuleGen(ctx)
|
||||||
@@ -122,7 +123,7 @@ func (this *CcAconfigLibraryCallbacks) GeneratorBuildActions(ctx cc.ModuleContex
|
|||||||
if len(declarationsModules) != 1 {
|
if len(declarationsModules) != 1 {
|
||||||
panic(fmt.Errorf("Exactly one aconfig_declarations property required"))
|
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")
|
mode := proptools.StringDefault(this.properties.Mode, "production")
|
||||||
if !isModeSupported(mode) {
|
if !isModeSupported(mode) {
|
@@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package aconfig
|
package codegen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
83
aconfig/codegen/init.go
Normal file
83
aconfig/codegen/init.go
Normal 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)
|
||||||
|
}
|
@@ -12,11 +12,12 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package aconfig
|
package codegen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"android/soong/aconfig"
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
"android/soong/bazel"
|
"android/soong/bazel"
|
||||||
"android/soong/java"
|
"android/soong/java"
|
||||||
@@ -73,7 +74,7 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuild
|
|||||||
if len(declarationsModules) != 1 {
|
if len(declarationsModules) != 1 {
|
||||||
panic(fmt.Errorf("Exactly one aconfig_declarations property required"))
|
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
|
// Generate the action to build the srcjar
|
||||||
srcJarPath := android.PathForModuleGen(ctx, ctx.ModuleName()+".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
|
return srcJarPath
|
||||||
}
|
}
|
||||||
|
|
@@ -12,11 +12,10 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package aconfig
|
package codegen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
@@ -34,14 +33,25 @@ func runJavaAndroidMkTest(t *testing.T, bp string) {
|
|||||||
ExtendWithErrorHandler(android.FixtureExpectsNoErrors).
|
ExtendWithErrorHandler(android.FixtureExpectsNoErrors).
|
||||||
RunTestWithBp(t, bp+`
|
RunTestWithBp(t, bp+`
|
||||||
aconfig_declarations {
|
aconfig_declarations {
|
||||||
name: "my_aconfig_declarations",
|
name: "my_aconfig_declarations_foo",
|
||||||
package: "com.example.package",
|
package: "com.example.package",
|
||||||
srcs: ["foo.aconfig"],
|
srcs: ["foo.aconfig"],
|
||||||
}
|
}
|
||||||
|
|
||||||
java_aconfig_library {
|
java_aconfig_library {
|
||||||
name: "my_java_aconfig_library",
|
name: "my_java_aconfig_library_foo",
|
||||||
aconfig_declarations: "my_aconfig_declarations",
|
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]
|
entry := android.AndroidMkEntriesForTest(t, result.TestContext, module)[0]
|
||||||
|
|
||||||
makeVar := entry.EntryMap["LOCAL_ACONFIG_FILES"]
|
makeVar := entry.EntryMap["LOCAL_ACONFIG_FILES"]
|
||||||
android.AssertIntEquals(t, "len(LOCAL_ACONFIG_FILES)", 1, len(makeVar))
|
android.AssertIntEquals(t, "len(LOCAL_ACONFIG_FILES)", 2, len(makeVar))
|
||||||
if !strings.HasSuffix(makeVar[0], "intermediate.pb") {
|
android.EnsureListContainsSuffix(t, makeVar, "my_aconfig_declarations_foo/intermediate.pb")
|
||||||
t.Errorf("LOCAL_ACONFIG_FILES should end with /intermediates.pb, instead it is: %s", makeVar[0])
|
android.EnsureListContainsSuffix(t, makeVar, "my_aconfig_declarations_bar/intermediate.pb")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAndroidMkJavaLibrary(t *testing.T) {
|
func TestAndroidMkJavaLibrary(t *testing.T) {
|
||||||
@@ -64,7 +73,8 @@ func TestAndroidMkJavaLibrary(t *testing.T) {
|
|||||||
"src/foo.java",
|
"src/foo.java",
|
||||||
],
|
],
|
||||||
static_libs: [
|
static_libs: [
|
||||||
"my_java_aconfig_library",
|
"my_java_aconfig_library_foo",
|
||||||
|
"my_java_aconfig_library_bar",
|
||||||
],
|
],
|
||||||
platform_apis: true,
|
platform_apis: true,
|
||||||
}
|
}
|
||||||
@@ -81,7 +91,8 @@ func TestAndroidMkAndroidApp(t *testing.T) {
|
|||||||
"src/foo.java",
|
"src/foo.java",
|
||||||
],
|
],
|
||||||
static_libs: [
|
static_libs: [
|
||||||
"my_java_aconfig_library",
|
"my_java_aconfig_library_foo",
|
||||||
|
"my_java_aconfig_library_bar",
|
||||||
],
|
],
|
||||||
platform_apis: true,
|
platform_apis: true,
|
||||||
}
|
}
|
||||||
@@ -98,7 +109,8 @@ func TestAndroidMkBinary(t *testing.T) {
|
|||||||
"src/foo.java",
|
"src/foo.java",
|
||||||
],
|
],
|
||||||
static_libs: [
|
static_libs: [
|
||||||
"my_java_aconfig_library",
|
"my_java_aconfig_library_foo",
|
||||||
|
"my_java_aconfig_library_bar",
|
||||||
],
|
],
|
||||||
platform_apis: true,
|
platform_apis: true,
|
||||||
main_class: "foo",
|
main_class: "foo",
|
||||||
@@ -116,7 +128,8 @@ func TestAndroidMkAndroidLibrary(t *testing.T) {
|
|||||||
"src/foo.java",
|
"src/foo.java",
|
||||||
],
|
],
|
||||||
static_libs: [
|
static_libs: [
|
||||||
"my_java_aconfig_library",
|
"my_java_aconfig_library_foo",
|
||||||
|
"my_java_aconfig_library_bar",
|
||||||
],
|
],
|
||||||
platform_apis: true,
|
platform_apis: true,
|
||||||
}
|
}
|
||||||
@@ -134,7 +147,8 @@ func TestAndroidMkBinaryThatLinksAgainstAar(t *testing.T) {
|
|||||||
"src/foo.java",
|
"src/foo.java",
|
||||||
],
|
],
|
||||||
static_libs: [
|
static_libs: [
|
||||||
"my_java_aconfig_library",
|
"my_java_aconfig_library_foo",
|
||||||
|
"my_java_aconfig_library_bar",
|
||||||
],
|
],
|
||||||
platform_apis: true,
|
platform_apis: true,
|
||||||
}
|
}
|
@@ -1,8 +1,9 @@
|
|||||||
package aconfig
|
package codegen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"android/soong/aconfig"
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
"android/soong/rust"
|
"android/soong/rust"
|
||||||
|
|
||||||
@@ -64,7 +65,7 @@ func (a *aconfigDecorator) GenerateSource(ctx rust.ModuleContext, deps rust.Path
|
|||||||
if len(declarationsModules) != 1 {
|
if len(declarationsModules) != 1 {
|
||||||
panic(fmt.Errorf("Exactly one aconfig_declarations property required"))
|
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")
|
mode := proptools.StringDefault(a.Properties.Mode, "production")
|
||||||
if !isModeSupported(mode) {
|
if !isModeSupported(mode) {
|
@@ -1,4 +1,4 @@
|
|||||||
package aconfig
|
package codegen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
25
aconfig/codegen/testing.go
Normal file
25
aconfig/codegen/testing.go
Normal 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)
|
||||||
|
})
|
@@ -40,54 +40,8 @@ var (
|
|||||||
Restat: true,
|
Restat: true,
|
||||||
}, "release_version", "package", "declarations", "values", "default-permission")
|
}, "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
|
// 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{
|
blueprint.RuleParams{
|
||||||
Command: `${aconfig} dump --format protobuf --out ${out} ${cache_files}`,
|
Command: `${aconfig} dump --format protobuf --out ${out} ${cache_files}`,
|
||||||
CommandDeps: []string{
|
CommandDeps: []string{
|
||||||
@@ -106,8 +60,5 @@ func RegisterBuildComponents(ctx android.RegistrationContext) {
|
|||||||
ctx.RegisterModuleType("aconfig_declarations", DeclarationsFactory)
|
ctx.RegisterModuleType("aconfig_declarations", DeclarationsFactory)
|
||||||
ctx.RegisterModuleType("aconfig_values", ValuesFactory)
|
ctx.RegisterModuleType("aconfig_values", ValuesFactory)
|
||||||
ctx.RegisterModuleType("aconfig_value_set", ValueSetFactory)
|
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)
|
ctx.RegisterParallelSingletonType("all_aconfig_declarations", AllAconfigDeclarationsFactory)
|
||||||
}
|
}
|
||||||
|
@@ -1293,3 +1293,10 @@ func StringRelativeToTop(config Config, command string) string {
|
|||||||
func StringsRelativeToTop(config Config, command []string) []string {
|
func StringsRelativeToTop(config Config, command []string) []string {
|
||||||
return normalizeStringArrayRelativeToTop(config, command)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -8,6 +8,8 @@ bootstrap_go_package {
|
|||||||
deps: [
|
deps: [
|
||||||
"blueprint",
|
"blueprint",
|
||||||
"soong",
|
"soong",
|
||||||
|
"soong-aconfig",
|
||||||
|
"soong-aconfig-codegen",
|
||||||
"soong-android",
|
"soong-android",
|
||||||
"soong-bazel",
|
"soong-bazel",
|
||||||
"soong-bpf",
|
"soong-bpf",
|
||||||
|
18
apex/apex.go
18
apex/apex.go
@@ -24,6 +24,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"android/soong/aconfig"
|
||||||
"android/soong/bazel/cquery"
|
"android/soong/bazel/cquery"
|
||||||
|
|
||||||
"github.com/google/blueprint"
|
"github.com/google/blueprint"
|
||||||
@@ -482,6 +483,8 @@ type apexBundle struct {
|
|||||||
nativeApisUsedByModuleFile android.ModuleOutPath
|
nativeApisUsedByModuleFile android.ModuleOutPath
|
||||||
nativeApisBackedByModuleFile android.ModuleOutPath
|
nativeApisBackedByModuleFile android.ModuleOutPath
|
||||||
javaApisUsedByModuleFile android.ModuleOutPath
|
javaApisUsedByModuleFile android.ModuleOutPath
|
||||||
|
|
||||||
|
aconfigFiles []android.Path
|
||||||
}
|
}
|
||||||
|
|
||||||
// apexFileClass represents a type of file that can be included in APEX.
|
// 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
|
// visitor skips these from this list of module names
|
||||||
unwantedTransitiveDeps []string
|
unwantedTransitiveDeps []string
|
||||||
|
|
||||||
|
aconfigFiles []android.Path
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vctx *visitorContext) normalizeFileInfo(mctx android.ModuleContext) {
|
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 := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
|
||||||
fi.isJniLib = isJniLib
|
fi.isJniLib = isJniLib
|
||||||
vctx.filesInfo = append(vctx.filesInfo, fi)
|
vctx.filesInfo = append(vctx.filesInfo, fi)
|
||||||
|
addAconfigFiles(vctx, ctx, child)
|
||||||
// Collect the list of stub-providing libs except:
|
// Collect the list of stub-providing libs except:
|
||||||
// - VNDK libs are only for vendors
|
// - VNDK libs are only for vendors
|
||||||
// - bootstrap bionic libs are treated as provided by system
|
// - 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) {
|
switch ch := child.(type) {
|
||||||
case *cc.Module:
|
case *cc.Module:
|
||||||
vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
|
vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
|
||||||
|
addAconfigFiles(vctx, ctx, child)
|
||||||
return true // track transitive dependencies
|
return true // track transitive dependencies
|
||||||
case *rust.Module:
|
case *rust.Module:
|
||||||
vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
|
vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
|
||||||
@@ -2132,6 +2139,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
vctx.filesInfo = append(vctx.filesInfo, af)
|
vctx.filesInfo = append(vctx.filesInfo, af)
|
||||||
|
addAconfigFiles(vctx, ctx, child)
|
||||||
return true // track transitive dependencies
|
return true // track transitive dependencies
|
||||||
default:
|
default:
|
||||||
ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
|
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) {
|
switch ap := child.(type) {
|
||||||
case *java.AndroidApp:
|
case *java.AndroidApp:
|
||||||
vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
|
vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
|
||||||
|
addAconfigFiles(vctx, ctx, child)
|
||||||
return true // track transitive dependencies
|
return true // track transitive dependencies
|
||||||
case *java.AndroidAppImport:
|
case *java.AndroidAppImport:
|
||||||
vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
|
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)
|
vctx.filesInfo = append(vctx.filesInfo, af)
|
||||||
|
addAconfigFiles(vctx, ctx, child)
|
||||||
return true // track transitive dependencies
|
return true // track transitive dependencies
|
||||||
} else if rm, ok := child.(*rust.Module); ok {
|
} else if rm, ok := child.(*rust.Module); ok {
|
||||||
af := apexFileForRustLibrary(ctx, rm)
|
af := apexFileForRustLibrary(ctx, rm)
|
||||||
@@ -2378,6 +2388,13 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
|
|||||||
return false
|
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 {
|
func (a *apexBundle) shouldCheckDuplicate(ctx android.ModuleContext) bool {
|
||||||
// TODO(b/263308293) remove this
|
// TODO(b/263308293) remove this
|
||||||
if a.properties.IsCoverageVariant {
|
if a.properties.IsCoverageVariant {
|
||||||
@@ -2459,6 +2476,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
// 3) some fields in apexBundle struct are configured
|
// 3) some fields in apexBundle struct are configured
|
||||||
a.installDir = android.PathForModuleInstall(ctx, "apex")
|
a.installDir = android.PathForModuleInstall(ctx, "apex")
|
||||||
a.filesInfo = vctx.filesInfo
|
a.filesInfo = vctx.filesInfo
|
||||||
|
a.aconfigFiles = android.FirstUniquePaths(vctx.aconfigFiles)
|
||||||
|
|
||||||
a.setPayloadFsType(ctx)
|
a.setPayloadFsType(ctx)
|
||||||
a.setSystemLibLink(ctx)
|
a.setSystemLibLink(ctx)
|
||||||
|
@@ -25,6 +25,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"android/soong/aconfig/codegen"
|
||||||
"github.com/google/blueprint"
|
"github.com/google/blueprint"
|
||||||
"github.com/google/blueprint/proptools"
|
"github.com/google/blueprint/proptools"
|
||||||
|
|
||||||
@@ -151,6 +152,7 @@ var prepareForApexTest = android.GroupFixturePreparers(
|
|||||||
prebuilt_etc.PrepareForTestWithPrebuiltEtc,
|
prebuilt_etc.PrepareForTestWithPrebuiltEtc,
|
||||||
rust.PrepareForTestWithRustDefaultModules,
|
rust.PrepareForTestWithRustDefaultModules,
|
||||||
sh.PrepareForTestWithShBuildComponents,
|
sh.PrepareForTestWithShBuildComponents,
|
||||||
|
codegen.PrepareForTestWithAconfigBuildComponents,
|
||||||
|
|
||||||
PrepareForTestWithApexBuildComponents,
|
PrepareForTestWithApexBuildComponents,
|
||||||
|
|
||||||
@@ -10756,3 +10758,437 @@ func TestFileSystemShouldSkipApexLibraries(t *testing.T) {
|
|||||||
inputs.Strings(),
|
inputs.Strings(),
|
||||||
"out/soong/.intermediates/libbar/android_arm64_armv8-a_shared/libbar.so")
|
"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")
|
||||||
|
}
|
||||||
|
@@ -24,6 +24,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"android/soong/aconfig"
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
"android/soong/java"
|
"android/soong/java"
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
pctx.Import("android/soong/aconfig")
|
||||||
pctx.Import("android/soong/android")
|
pctx.Import("android/soong/android")
|
||||||
pctx.Import("android/soong/cc/config")
|
pctx.Import("android/soong/cc/config")
|
||||||
pctx.Import("android/soong/java")
|
pctx.Import("android/soong/java")
|
||||||
@@ -80,6 +82,7 @@ func init() {
|
|||||||
pctx.HostBinToolVariable("conv_linker_config", "conv_linker_config")
|
pctx.HostBinToolVariable("conv_linker_config", "conv_linker_config")
|
||||||
pctx.HostBinToolVariable("assemble_vintf", "assemble_vintf")
|
pctx.HostBinToolVariable("assemble_vintf", "assemble_vintf")
|
||||||
pctx.HostBinToolVariable("apex_elf_checker", "apex_elf_checker")
|
pctx.HostBinToolVariable("apex_elf_checker", "apex_elf_checker")
|
||||||
|
pctx.HostBinToolVariable("aconfig", "aconfig")
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -574,6 +577,7 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) {
|
|||||||
|
|
||||||
installMapSet[installMapPath.String()+":"+fi.installDir+"/"+fi.builtFile.Base()] = true
|
installMapSet[installMapPath.String()+":"+fi.installDir+"/"+fi.builtFile.Base()] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitInputs = append(implicitInputs, a.manifestPbOut)
|
implicitInputs = append(implicitInputs, a.manifestPbOut)
|
||||||
|
|
||||||
if len(installMapSet) > 0 {
|
if len(installMapSet) > 0 {
|
||||||
@@ -628,10 +632,28 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) {
|
|||||||
outHostBinDir := ctx.Config().HostToolPath(ctx, "").String()
|
outHostBinDir := ctx.Config().HostToolPath(ctx, "").String()
|
||||||
prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
|
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
|
// 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.
|
// 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)
|
implicitInputs = append(implicitInputs, cannedFsConfig)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -1082,8 +1104,8 @@ func (a *apexBundle) buildLintReports(ctx android.ModuleContext) {
|
|||||||
a.lintReports = java.BuildModuleLintReportZips(ctx, depSetsBuilder.Build())
|
a.lintReports = java.BuildModuleLintReportZips(ctx, depSetsBuilder.Build())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext) android.OutputPath {
|
func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext, defaultReadOnlyFiles []string) android.OutputPath {
|
||||||
var readOnlyPaths = []string{"apex_manifest.json", "apex_manifest.pb"}
|
var readOnlyPaths = defaultReadOnlyFiles
|
||||||
var executablePaths []string // this also includes dirs
|
var executablePaths []string // this also includes dirs
|
||||||
var appSetDirs []string
|
var appSetDirs []string
|
||||||
appSetFiles := make(map[string]android.Path)
|
appSetFiles := make(map[string]android.Path)
|
||||||
|
@@ -9,6 +9,7 @@ bootstrap_go_package {
|
|||||||
"blueprint",
|
"blueprint",
|
||||||
"blueprint-pathtools",
|
"blueprint-pathtools",
|
||||||
"soong",
|
"soong",
|
||||||
|
"soong-aconfig",
|
||||||
"soong-aidl-library",
|
"soong-aidl-library",
|
||||||
"soong-android",
|
"soong-android",
|
||||||
"soong-bazel",
|
"soong-bazel",
|
||||||
|
6
cc/cc.go
6
cc/cc.go
@@ -30,6 +30,7 @@ import (
|
|||||||
"github.com/google/blueprint"
|
"github.com/google/blueprint"
|
||||||
"github.com/google/blueprint/proptools"
|
"github.com/google/blueprint/proptools"
|
||||||
|
|
||||||
|
"android/soong/aconfig"
|
||||||
"android/soong/aidl_library"
|
"android/soong/aidl_library"
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
"android/soong/bazel/cquery"
|
"android/soong/bazel/cquery"
|
||||||
@@ -923,6 +924,9 @@ type Module struct {
|
|||||||
apexSdkVersion android.ApiLevel
|
apexSdkVersion android.ApiLevel
|
||||||
|
|
||||||
hideApexVariantFromMake bool
|
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{}) {
|
func (c *Module) AddJSONData(d *map[string]interface{}) {
|
||||||
@@ -2335,6 +2339,8 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
|
|||||||
ctx.SetProvider(testing.TestModuleProviderKey, testing.TestModuleProviderData{})
|
ctx.SetProvider(testing.TestModuleProviderKey, testing.TestModuleProviderData{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aconfig.CollectTransitiveAconfigFiles(ctx, &c.transitiveAconfigFiles)
|
||||||
|
|
||||||
c.maybeInstall(ctx, apexInfo)
|
c.maybeInstall(ctx, apexInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,6 +9,7 @@ bootstrap_go_package {
|
|||||||
"blueprint",
|
"blueprint",
|
||||||
"blueprint-pathtools",
|
"blueprint-pathtools",
|
||||||
"soong",
|
"soong",
|
||||||
|
"soong-aconfig",
|
||||||
"soong-android",
|
"soong-android",
|
||||||
"soong-bazel",
|
"soong-bazel",
|
||||||
"soong-cc",
|
"soong-cc",
|
||||||
|
@@ -128,8 +128,8 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
|
|||||||
if library.dexpreopter.configPath != nil {
|
if library.dexpreopter.configPath != nil {
|
||||||
entries.SetPath("LOCAL_SOONG_DEXPREOPT_CONFIG", library.dexpreopter.configPath)
|
entries.SetPath("LOCAL_SOONG_DEXPREOPT_CONFIG", library.dexpreopter.configPath)
|
||||||
}
|
}
|
||||||
|
// TODO(b/311155208): The container here should be system.
|
||||||
entries.SetOptionalPaths("LOCAL_ACONFIG_FILES", library.getTransitiveAconfigFiles().ToList())
|
entries.SetOptionalPaths("LOCAL_ACONFIG_FILES", library.getTransitiveAconfigFiles(""))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -306,7 +306,8 @@ func (binary *Binary) AndroidMkEntries() []android.AndroidMkEntries {
|
|||||||
if len(binary.dexpreopter.builtInstalled) > 0 {
|
if len(binary.dexpreopter.builtInstalled) > 0 {
|
||||||
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", binary.dexpreopter.builtInstalled)
|
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{
|
ExtraFooters: []android.AndroidMkExtraFootersFunc{
|
||||||
@@ -459,7 +460,8 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
|
|||||||
entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", app.linter.reports)
|
entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", app.linter.reports)
|
||||||
|
|
||||||
if app.Name() != "framework-res" {
|
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_FULL_MANIFEST_FILE", a.mergedManifestFile)
|
||||||
entries.AddStrings("LOCAL_SOONG_EXPORT_PROGUARD_FLAGS", a.exportedProguardFlagFiles.Strings()...)
|
entries.AddStrings("LOCAL_SOONG_EXPORT_PROGUARD_FLAGS", a.exportedProguardFlagFiles.Strings()...)
|
||||||
entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", true)
|
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
|
return entriesList
|
||||||
|
41
java/base.go
41
java/base.go
@@ -25,6 +25,7 @@ import (
|
|||||||
"github.com/google/blueprint/pathtools"
|
"github.com/google/blueprint/pathtools"
|
||||||
"github.com/google/blueprint/proptools"
|
"github.com/google/blueprint/proptools"
|
||||||
|
|
||||||
|
"android/soong/aconfig"
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
"android/soong/dexpreopt"
|
"android/soong/dexpreopt"
|
||||||
"android/soong/java/config"
|
"android/soong/java/config"
|
||||||
@@ -512,13 +513,8 @@ type Module struct {
|
|||||||
// or the module should override Stem().
|
// or the module should override Stem().
|
||||||
stem string
|
stem string
|
||||||
|
|
||||||
// Aconfig "cache files" that went directly into this module. Transitive ones are
|
// Aconfig files for all transitive deps. Also exposed via TransitiveDeclarationsInfo
|
||||||
// tracked via JavaInfo.TransitiveAconfigFiles
|
transitiveAconfigFiles map[string]*android.DepSet[android.Path]
|
||||||
// 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]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error {
|
func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error {
|
||||||
@@ -1723,7 +1719,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
|
|||||||
|
|
||||||
ctx.CheckbuildFile(outputFile)
|
ctx.CheckbuildFile(outputFile)
|
||||||
|
|
||||||
j.collectTransitiveAconfigFiles(ctx)
|
aconfig.CollectTransitiveAconfigFiles(ctx, &j.transitiveAconfigFiles)
|
||||||
|
|
||||||
ctx.SetProvider(JavaInfoProvider, JavaInfo{
|
ctx.SetProvider(JavaInfoProvider, JavaInfo{
|
||||||
HeaderJars: android.PathsIfNonNil(j.headerJarFile),
|
HeaderJars: android.PathsIfNonNil(j.headerJarFile),
|
||||||
@@ -1740,7 +1736,6 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
|
|||||||
ExportedPluginClasses: j.exportedPluginClasses,
|
ExportedPluginClasses: j.exportedPluginClasses,
|
||||||
ExportedPluginDisableTurbine: j.exportedDisableTurbine,
|
ExportedPluginDisableTurbine: j.exportedDisableTurbine,
|
||||||
JacocoReportClassesFile: j.jacocoReportClassesFile,
|
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
|
// 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)
|
return Bool(j.properties.Installable)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *Module) collectTransitiveAconfigFiles(ctx android.ModuleContext) {
|
func (j *Module) getTransitiveAconfigFiles(container string) []android.Path {
|
||||||
// Aconfig files from this module
|
return j.transitiveAconfigFiles[container].ToList()
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type sdkLinkType int
|
type sdkLinkType int
|
||||||
|
@@ -37,7 +37,6 @@ func (callbacks *JavaGenLibTestCallbacks) DepsMutator(module *GeneratedJavaLibra
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (callbacks *JavaGenLibTestCallbacks) GenerateSourceJarBuildActions(module *GeneratedJavaLibraryModule, ctx android.ModuleContext) android.Path {
|
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")
|
return android.PathForOutput(ctx, "blah.srcjar")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -297,15 +297,6 @@ type JavaInfo struct {
|
|||||||
// JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be
|
// JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be
|
||||||
// instrumented by jacoco.
|
// instrumented by jacoco.
|
||||||
JacocoReportClassesFile android.Path
|
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{})
|
var JavaInfoProvider = blueprint.NewProvider(JavaInfo{})
|
||||||
|
Reference in New Issue
Block a user