Merge "rustc-1.75.0 Build 11471753" into main
diff --git a/aconfig/all_aconfig_declarations.go b/aconfig/all_aconfig_declarations.go
index b6c9023..3d9663c 100644
--- a/aconfig/all_aconfig_declarations.go
+++ b/aconfig/all_aconfig_declarations.go
@@ -31,7 +31,8 @@
}
type allAconfigDeclarationsSingleton struct {
- intermediatePath android.OutputPath
+ intermediateBinaryProtoPath android.OutputPath
+ intermediateTextProtoPath android.OutputPath
}
func (this *allAconfigDeclarationsSingleton) GenerateBuildActions(ctx android.SingletonContext) {
@@ -59,20 +60,35 @@
panic(fmt.Errorf("Only one aconfig_declarations allowed for each package."))
}
- // Generate build action for aconfig
- this.intermediatePath = android.PathForIntermediates(ctx, "all_aconfig_declarations.pb")
+ // Generate build action for aconfig (binary proto output)
+ this.intermediateBinaryProtoPath = android.PathForIntermediates(ctx, "all_aconfig_declarations.pb")
ctx.Build(pctx, android.BuildParams{
Rule: AllDeclarationsRule,
Inputs: cacheFiles,
- Output: this.intermediatePath,
+ Output: this.intermediateBinaryProtoPath,
Description: "all_aconfig_declarations",
Args: map[string]string{
"cache_files": android.JoinPathsWithPrefix(cacheFiles, "--cache "),
},
})
- ctx.Phony("all_aconfig_declarations", this.intermediatePath)
+ ctx.Phony("all_aconfig_declarations", this.intermediateBinaryProtoPath)
+
+ // Generate build action for aconfig (text proto output)
+ this.intermediateTextProtoPath = android.PathForIntermediates(ctx, "all_aconfig_declarations.textproto")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: AllDeclarationsRuleTextProto,
+ Inputs: cacheFiles,
+ Output: this.intermediateTextProtoPath,
+ Description: "all_aconfig_declarations_textproto",
+ Args: map[string]string{
+ "cache_files": android.JoinPathsWithPrefix(cacheFiles, "--cache "),
+ },
+ })
+ ctx.Phony("all_aconfig_declarations_textproto", this.intermediateTextProtoPath)
}
func (this *allAconfigDeclarationsSingleton) MakeVars(ctx android.MakeVarsContext) {
- ctx.DistForGoal("droid", this.intermediatePath)
+ ctx.DistForGoal("droid", this.intermediateBinaryProtoPath)
+ ctx.DistForGoalWithFilename("sdk", this.intermediateBinaryProtoPath, "flags.pb")
+ ctx.DistForGoalWithFilename("sdk", this.intermediateTextProtoPath, "flags.textproto")
}
diff --git a/aconfig/codegen/Android.bp b/aconfig/codegen/Android.bp
index 494f7e6..0c78b94 100644
--- a/aconfig/codegen/Android.bp
+++ b/aconfig/codegen/Android.bp
@@ -17,6 +17,7 @@
"soong-rust",
],
srcs: [
+ "aconfig_declarations_group.go",
"cc_aconfig_library.go",
"init.go",
"java_aconfig_library.go",
@@ -24,6 +25,7 @@
"testing.go",
],
testSrcs: [
+ "aconfig_declarations_group_test.go",
"java_aconfig_library_test.go",
"cc_aconfig_library_test.go",
"rust_aconfig_library_test.go",
diff --git a/aconfig/codegen/aconfig_declarations_group.go b/aconfig/codegen/aconfig_declarations_group.go
new file mode 100644
index 0000000..203b6be
--- /dev/null
+++ b/aconfig/codegen/aconfig_declarations_group.go
@@ -0,0 +1,129 @@
+// Copyright 2024 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package codegen
+
+import (
+ "android/soong/aconfig"
+ "android/soong/android"
+ "fmt"
+
+ "github.com/google/blueprint"
+)
+
+type dependencyTag struct {
+ blueprint.BaseDependencyTag
+ name string
+}
+
+var (
+ aconfigDeclarationsGroupTag = dependencyTag{name: "aconfigDeclarationsGroup"}
+ javaAconfigLibraryTag = dependencyTag{name: "javaAconfigLibrary"}
+ ccAconfigLibraryTag = dependencyTag{name: "ccAconfigLibrary"}
+ rustAconfigLibraryTag = dependencyTag{name: "rustAconfigLibrary"}
+)
+
+type AconfigDeclarationsGroup struct {
+ android.ModuleBase
+ android.DefaultableModuleBase
+
+ properties AconfigDeclarationsGroupProperties
+
+ aconfigDeclarationNames []string
+ intermediateCacheOutputPaths android.Paths
+ javaSrcjars android.Paths
+}
+
+type AconfigDeclarationsGroupProperties struct {
+
+ // Name of the aconfig_declarations_group modules
+ Aconfig_declarations_groups []string
+
+ // Name of the java_aconfig_library modules
+ Java_aconfig_libraries []string
+
+ // Name of the cc_aconfig_library modules
+ Cc_aconfig_libraries []string
+
+ // Name of the rust_aconfig_library modules
+ Rust_aconfig_libraries []string
+}
+
+func AconfigDeclarationsGroupFactory() android.Module {
+ module := &AconfigDeclarationsGroup{}
+ module.AddProperties(&module.properties)
+ android.InitAndroidModule(module)
+ android.InitDefaultableModule(module)
+ return module
+}
+
+func (adg *AconfigDeclarationsGroup) DepsMutator(ctx android.BottomUpMutatorContext) {
+ ctx.AddDependency(ctx.Module(), aconfigDeclarationsGroupTag, adg.properties.Aconfig_declarations_groups...)
+ ctx.AddDependency(ctx.Module(), javaAconfigLibraryTag, adg.properties.Java_aconfig_libraries...)
+ ctx.AddDependency(ctx.Module(), ccAconfigLibraryTag, adg.properties.Cc_aconfig_libraries...)
+ ctx.AddDependency(ctx.Module(), rustAconfigLibraryTag, adg.properties.Rust_aconfig_libraries...)
+}
+
+func (adg *AconfigDeclarationsGroup) VisitDeps(ctx android.ModuleContext) {
+ ctx.VisitDirectDeps(func(dep android.Module) {
+ tag := ctx.OtherModuleDependencyTag(dep)
+ if provider, ok := android.OtherModuleProvider(ctx, dep, aconfig.CodegenInfoProvider); ok {
+
+ // aconfig declaration names and cache files are collected for all aconfig library dependencies
+ adg.aconfigDeclarationNames = append(adg.aconfigDeclarationNames, provider.AconfigDeclarations...)
+ adg.intermediateCacheOutputPaths = append(adg.intermediateCacheOutputPaths, provider.IntermediateCacheOutputPaths...)
+
+ switch tag {
+ case aconfigDeclarationsGroupTag:
+ // Will retrieve outputs from another language codegen modules when support is added
+ adg.javaSrcjars = append(adg.javaSrcjars, provider.Srcjars...)
+ case javaAconfigLibraryTag:
+ adg.javaSrcjars = append(adg.javaSrcjars, provider.Srcjars...)
+ }
+ }
+ })
+}
+
+func (adg *AconfigDeclarationsGroup) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ adg.VisitDeps(ctx)
+ adg.aconfigDeclarationNames = android.FirstUniqueStrings(adg.aconfigDeclarationNames)
+ adg.intermediateCacheOutputPaths = android.FirstUniquePaths(adg.intermediateCacheOutputPaths)
+
+ android.SetProvider(ctx, aconfig.CodegenInfoProvider, aconfig.CodegenInfo{
+ AconfigDeclarations: adg.aconfigDeclarationNames,
+ IntermediateCacheOutputPaths: adg.intermediateCacheOutputPaths,
+ Srcjars: adg.javaSrcjars,
+ })
+}
+
+var _ android.OutputFileProducer = (*AconfigDeclarationsGroup)(nil)
+
+func (adg *AconfigDeclarationsGroup) OutputFiles(tag string) (android.Paths, error) {
+ switch tag {
+ case "":
+ return adg.intermediateCacheOutputPaths, nil
+ case ".srcjars":
+ return adg.javaSrcjars, nil
+ default:
+ return nil, fmt.Errorf("unsupported module reference tag %s", tag)
+ }
+}
+
+func (adg *AconfigDeclarationsGroup) Srcjars() android.Paths {
+ return adg.javaSrcjars
+}
+
+func (adg *AconfigDeclarationsGroup) AconfigDeclarations() []string {
+ return adg.aconfigDeclarationNames
+}
diff --git a/aconfig/codegen/aconfig_declarations_group_test.go b/aconfig/codegen/aconfig_declarations_group_test.go
new file mode 100644
index 0000000..ec7cea3
--- /dev/null
+++ b/aconfig/codegen/aconfig_declarations_group_test.go
@@ -0,0 +1,79 @@
+// Copyright 2024 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package codegen
+
+import (
+ "android/soong/android"
+ "android/soong/java"
+ "testing"
+)
+
+func TestAconfigDeclarationsGroup(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithAconfigBuildComponents,
+ java.PrepareForTestWithJavaDefaultModules,
+ ).RunTestWithBp(t, `
+ aconfig_declarations {
+ name: "foo-aconfig",
+ package: "com.example.package",
+ srcs: ["foo.aconfig"],
+ }
+
+ java_aconfig_library {
+ name: "foo-java",
+ aconfig_declarations: "foo-aconfig",
+ }
+
+ aconfig_declarations {
+ name: "bar-aconfig",
+ package: "com.example.package",
+ srcs: ["foo.aconfig"],
+ }
+
+ java_aconfig_library {
+ name: "bar-java",
+ aconfig_declarations: "bar-aconfig",
+ }
+
+ aconfig_declarations_group {
+ name: "my_group",
+ java_aconfig_libraries: [
+ "foo-java",
+ "bar-java",
+ ],
+ }
+
+ java_library {
+ name: "baz",
+ srcs: [
+ ":my_group{.srcjars}",
+ ],
+ }
+ `)
+
+ // Check if aconfig_declarations_group module depends on the aconfig_library modules
+ java.CheckModuleDependencies(t, result.TestContext, "my_group", "", []string{
+ `bar-java`,
+ `foo-java`,
+ })
+
+ // Check if srcjar files are correctly passed to the reverse dependency of
+ // aconfig_declarations_group module
+ bazModule := result.ModuleForTests("baz", "android_common")
+ bazJavacSrcjars := bazModule.Rule("javac").Args["srcJars"]
+ errorMessage := "baz javac argument expected to contain srcjar provided by aconfig_declrations_group"
+ android.AssertStringDoesContain(t, errorMessage, bazJavacSrcjars, "foo-java.srcjar")
+ android.AssertStringDoesContain(t, errorMessage, bazJavacSrcjars, "bar-java.srcjar")
+}
diff --git a/aconfig/codegen/init.go b/aconfig/codegen/init.go
index 0bff9d2..73a8951 100644
--- a/aconfig/codegen/init.go
+++ b/aconfig/codegen/init.go
@@ -77,6 +77,7 @@
}
func RegisterBuildComponents(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("aconfig_declarations_group", AconfigDeclarationsGroupFactory)
ctx.RegisterModuleType("cc_aconfig_library", CcAconfigLibraryFactory)
ctx.RegisterModuleType("java_aconfig_library", JavaDeclarationsLibraryFactory)
ctx.RegisterModuleType("rust_aconfig_library", RustAconfigLibraryFactory)
diff --git a/aconfig/codegen/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go
index d4c6da5..7d7296e 100644
--- a/aconfig/codegen/java_aconfig_library.go
+++ b/aconfig/codegen/java_aconfig_library.go
@@ -17,6 +17,7 @@
import (
"fmt"
+ "android/soong/aconfig"
"android/soong/android"
"android/soong/java"
@@ -118,6 +119,12 @@
module.AddJarJarRenameRule(declarations.Package+".FakeFeatureFlagsImpl", "")
}
+ android.SetProvider(ctx, aconfig.CodegenInfoProvider, aconfig.CodegenInfo{
+ AconfigDeclarations: []string{declarationsModules[0].Name()},
+ IntermediateCacheOutputPaths: android.Paths{declarations.IntermediateCacheOutputPath},
+ Srcjars: android.Paths{srcJarPath},
+ })
+
return srcJarPath
}
diff --git a/aconfig/init.go b/aconfig/init.go
index 77f5ed3..e64429f 100644
--- a/aconfig/init.go
+++ b/aconfig/init.go
@@ -20,6 +20,20 @@
"github.com/google/blueprint"
)
+type CodegenInfo struct {
+ // AconfigDeclarations is the name of the aconfig_declarations modules that
+ // the codegen module is associated with
+ AconfigDeclarations []string
+
+ // Paths to the cache files of the associated aconfig_declaration modules
+ IntermediateCacheOutputPaths android.Paths
+
+ // Paths to the srcjar files generated from the java_aconfig_library modules
+ Srcjars android.Paths
+}
+
+var CodegenInfoProvider = blueprint.NewProvider[CodegenInfo]()
+
var (
pctx = android.NewPackageContext("android/soong/aconfig")
@@ -61,6 +75,21 @@
"${aconfig}",
},
}, "cache_files")
+ AllDeclarationsRuleTextProto = pctx.AndroidStaticRule("All_aconfig_declarations_dump_textproto",
+ blueprint.RuleParams{
+ Command: `${aconfig} dump-cache --dedup --format textproto --out ${out} ${cache_files}`,
+ CommandDeps: []string{
+ "${aconfig}",
+ },
+ }, "cache_files")
+
+ CreateStorageRule = pctx.AndroidStaticRule("aconfig_create_storage",
+ blueprint.RuleParams{
+ Command: `${aconfig} create-storage --container ${container} --file ${file_type} --out ${out} ${cache_files}`,
+ CommandDeps: []string{
+ "${aconfig}",
+ },
+ }, "container", "file_type", "cache_files")
// For exported_java_aconfig_library: Generate a JAR from all
// java_aconfig_libraries to be consumed by apps built outside the
diff --git a/android/all_teams.go b/android/all_teams.go
index dd7d2db..b177e20 100644
--- a/android/all_teams.go
+++ b/android/all_teams.go
@@ -68,10 +68,6 @@
this.teams_for_mods = make(map[string]moduleTeamInfo)
ctx.VisitAllModules(func(module Module) {
- if !module.Enabled() {
- return
- }
-
bpFile := ctx.BlueprintFile(module)
// Package Modules and Team Modules are stored in a map so we can look them up by name for
diff --git a/android/apex_contributions.go b/android/apex_contributions.go
index 236abf6..89e27b9 100644
--- a/android/apex_contributions.go
+++ b/android/apex_contributions.go
@@ -98,6 +98,10 @@
func (a *allApexContributions) SetPrebuiltSelectionInfoProvider(ctx BaseModuleContext) {
addContentsToProvider := func(p *PrebuiltSelectionInfoMap, m *apexContributions) {
for _, content := range m.Contents() {
+ // Skip any apexes that have been added to the product specific ignore list
+ if InList(content, ctx.Config().BuildIgnoreApexContributionContents()) {
+ continue
+ }
if !ctx.OtherModuleExists(content) && !ctx.Config().AllowMissingDependencies() {
ctx.ModuleErrorf("%s listed in apex_contributions %s does not exist\n", content, m.Name())
}
diff --git a/android/config.go b/android/config.go
index e57bc2c..75471b9 100644
--- a/android/config.go
+++ b/android/config.go
@@ -654,6 +654,7 @@
"framework-nfc": {},
"framework-ondevicepersonalization": {},
"framework-pdf": {},
+ "framework-pdf-v": {},
"framework-permission": {},
"framework-permission-s": {},
"framework-scheduling": {},
@@ -1342,6 +1343,22 @@
return String(c.productVariables.VendorApiLevel)
}
+func (c *config) PrevVendorApiLevel() string {
+ vendorApiLevel, err := strconv.Atoi(c.VendorApiLevel())
+ if err != nil {
+ panic(fmt.Errorf("Cannot parse vendor API level %s to an integer: %s",
+ c.VendorApiLevel(), err))
+ }
+ if vendorApiLevel < 202404 || vendorApiLevel%100 != 4 {
+ panic("Unknown vendor API level " + c.VendorApiLevel())
+ }
+ // The version before trunk stable is 34.
+ if vendorApiLevel == 202404 {
+ return "34"
+ }
+ return strconv.Itoa(vendorApiLevel - 100)
+}
+
func (c *config) VendorApiLevelFrozen() bool {
return c.productVariables.GetBuildFlagBool("RELEASE_BOARD_API_LEVEL_FROZEN")
}
@@ -2044,3 +2061,7 @@
}
return ret
}
+
+func (c *config) BuildIgnoreApexContributionContents() []string {
+ return c.productVariables.BuildIgnoreApexContributionContents
+}
diff --git a/android/variable.go b/android/variable.go
index 758967e..2520020 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -494,6 +494,8 @@
BuildFlags map[string]string `json:",omitempty"`
BuildFromSourceStub *bool `json:",omitempty"`
+
+ BuildIgnoreApexContributionContents []string `json:",omitempty"`
}
type PartitionQualifiedVariablesType struct {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 5cc50dd..02dc6e6 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -11115,25 +11115,23 @@
mod := ctx.ModuleForTests("myapex", "android_common_myapex")
s := mod.Rule("apexRule").Args["copy_commands"]
copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
- if len(copyCmds) != 5 {
+ if len(copyCmds) != 8 {
t.Fatalf("Expected 5 commands, got %d in:\n%s", len(copyCmds), s)
}
ensureMatches(t, copyCmds[4], "^cp -f .*/aconfig_flags.pb .*/image.apex$")
+ ensureMatches(t, copyCmds[5], "^cp -f .*/package.map .*/image.apex$")
+ ensureMatches(t, copyCmds[6], "^cp -f .*/flag.map .*/image.apex$")
+ ensureMatches(t, copyCmds[7], "^cp -f .*/flag.val .*/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)
+ inputs := []string{
+ "my_aconfig_declarations_foo/intermediate.pb",
+ "my_aconfig_declarations_bar/intermediate.pb",
}
- 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")
+ VerifyAconfigRule(t, &mod, "combine_aconfig_declarations", inputs, "android_common_myapex/aconfig_flags.pb", "", "")
+ VerifyAconfigRule(t, &mod, "create_aconfig_package_map_file", inputs, "android_common_myapex/package.map", "myapex", "package_map")
+ VerifyAconfigRule(t, &mod, "create_aconfig_flag_map_file", inputs, "android_common_myapex/flag.map", "myapex", "flag_map")
+ VerifyAconfigRule(t, &mod, "create_aconfig_flag_val_file", inputs, "android_common_myapex/flag.val", "myapex", "flag_val")
}
func TestAconfigFilesJavaAndCcDeps(t *testing.T) {
@@ -11241,30 +11239,24 @@
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)
+ if len(copyCmds) != 12 {
+ t.Fatalf("Expected 12 commands, got %d in:\n%s", len(copyCmds), s)
}
ensureMatches(t, copyCmds[8], "^cp -f .*/aconfig_flags.pb .*/image.apex$")
+ ensureMatches(t, copyCmds[9], "^cp -f .*/package.map .*/image.apex$")
+ ensureMatches(t, copyCmds[10], "^cp -f .*/flag.map .*/image.apex$")
+ ensureMatches(t, copyCmds[11], "^cp -f .*/flag.val .*/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)
+ inputs := []string{
+ "my_aconfig_declarations_foo/intermediate.pb",
+ "my_cc_library_bar/android_arm64_armv8-a_shared_apex10000/myapex/aconfig_merged.pb",
+ "my_aconfig_declarations_baz/intermediate.pb",
}
- android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_foo/intermediate.pb")
- android.EnsureListContainsSuffix(t, aconfigArgs, "my_cc_library_bar/android_arm64_armv8-a_shared_apex10000/myapex/aconfig_merged.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_cc_library_bar/android_arm64_armv8-a_shared_apex10000/myapex/aconfig_merged.pb")
- android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_baz/intermediate.pb")
- ensureContains(t, buildParams.Output.String(), "android_common_myapex/aconfig_flags.pb")
+ VerifyAconfigRule(t, &mod, "combine_aconfig_declarations", inputs, "android_common_myapex/aconfig_flags.pb", "", "")
+ VerifyAconfigRule(t, &mod, "create_aconfig_package_map_file", inputs, "android_common_myapex/package.map", "myapex", "package_map")
+ VerifyAconfigRule(t, &mod, "create_aconfig_flag_map_file", inputs, "android_common_myapex/flag.map", "myapex", "flag_map")
+ VerifyAconfigRule(t, &mod, "create_aconfig_flag_val_file", inputs, "android_common_myapex/flag.val", "myapex", "flag_val")
}
func TestAconfigFilesRustDeps(t *testing.T) {
@@ -11388,28 +11380,43 @@
mod := ctx.ModuleForTests("myapex", "android_common_myapex")
s := mod.Rule("apexRule").Args["copy_commands"]
copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
- if len(copyCmds) != 23 {
- t.Fatalf("Expected 23 commands, got %d in:\n%s", len(copyCmds), s)
+ if len(copyCmds) != 26 {
+ t.Fatalf("Expected 26 commands, got %d in:\n%s", len(copyCmds), s)
}
ensureMatches(t, copyCmds[22], "^cp -f .*/aconfig_flags.pb .*/image.apex$")
+ ensureMatches(t, copyCmds[23], "^cp -f .*/package.map .*/image.apex$")
+ ensureMatches(t, copyCmds[24], "^cp -f .*/flag.map .*/image.apex$")
+ ensureMatches(t, copyCmds[25], "^cp -f .*/flag.val .*/image.apex$")
- combineAconfigRule := mod.Rule("All_aconfig_declarations_dump")
- s = " " + combineAconfigRule.Args["cache_files"]
+ inputs := []string{
+ "my_aconfig_declarations_foo/intermediate.pb",
+ "my_rust_binary/android_arm64_armv8-a_apex10000/myapex/aconfig_merged.pb",
+ }
+ VerifyAconfigRule(t, &mod, "combine_aconfig_declarations", inputs, "android_common_myapex/aconfig_flags.pb", "", "")
+ VerifyAconfigRule(t, &mod, "create_aconfig_package_map_file", inputs, "android_common_myapex/package.map", "myapex", "package_map")
+ VerifyAconfigRule(t, &mod, "create_aconfig_flag_map_file", inputs, "android_common_myapex/flag.map", "myapex", "flag_map")
+ VerifyAconfigRule(t, &mod, "create_aconfig_flag_val_file", inputs, "android_common_myapex/flag.val", "myapex", "flag_val")
+}
+
+func VerifyAconfigRule(t *testing.T, mod *android.TestingModule, desc string, inputs []string, output string, container string, file_type string) {
+ aconfigRule := mod.Description(desc)
+ s := " " + aconfigRule.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)
+ if len(aconfigArgs) != len(inputs) {
+ t.Fatalf("Expected %d commands, got %d in:\n%s", len(inputs), len(aconfigArgs), s)
}
- android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_foo/intermediate.pb")
- android.EnsureListContainsSuffix(t, aconfigArgs, "my_rust_binary/android_arm64_armv8-a_apex10000/myapex/aconfig_merged.pb")
- buildParams := combineAconfigRule.BuildParams
- if len(buildParams.Inputs) != 2 {
- t.Fatalf("Expected 3 input, got %d", len(buildParams.Inputs))
+ ensureEquals(t, container, aconfigRule.Args["container"])
+ ensureEquals(t, file_type, aconfigRule.Args["file_type"])
+
+ buildParams := aconfigRule.BuildParams
+ for _, input := range inputs {
+ android.EnsureListContainsSuffix(t, aconfigArgs, input)
+ android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), input)
}
- android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_foo/intermediate.pb")
- android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_rust_binary/android_arm64_armv8-a_apex10000/myapex/aconfig_merged.pb")
- ensureContains(t, buildParams.Output.String(), "android_common_myapex/aconfig_flags.pb")
+
+ ensureContains(t, buildParams.Output.String(), output)
}
func TestAconfigFilesOnlyMatchCurrentApex(t *testing.T) {
diff --git a/apex/builder.go b/apex/builder.go
index 3d61219..e49cf28 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -85,6 +85,18 @@
pctx.HostBinToolVariable("aconfig", "aconfig")
}
+type createStorageStruct struct {
+ Output_file string
+ Desc string
+ File_type string
+}
+
+var createStorageInfo = []createStorageStruct{
+ {"package.map", "create_aconfig_package_map_file", "package_map"},
+ {"flag.map", "create_aconfig_flag_map_file", "flag_map"},
+ {"flag.val", "create_aconfig_flag_val_file", "flag_val"},
+}
+
var (
apexManifestRule = pctx.StaticRule("apexManifestRule", blueprint.RuleParams{
Command: `rm -f $out && ${jsonmodify} $in ` +
@@ -648,6 +660,25 @@
copyCommands = append(copyCommands, "cp -f "+apexAconfigFile.String()+" "+imageDir.String())
implicitInputs = append(implicitInputs, apexAconfigFile)
defaultReadOnlyFiles = append(defaultReadOnlyFiles, apexAconfigFile.Base())
+
+ for _, info := range createStorageInfo {
+ outputFile := android.PathForModuleOut(ctx, info.Output_file)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: aconfig.CreateStorageRule,
+ Inputs: a.aconfigFiles,
+ Output: outputFile,
+ Description: info.Desc,
+ Args: map[string]string{
+ "container": ctx.ModuleName(),
+ "file_type": info.File_type,
+ "cache_files": android.JoinPathsWithPrefix(a.aconfigFiles, "--cache "),
+ },
+ })
+
+ copyCommands = append(copyCommands, "cp -f "+outputFile.String()+" "+imageDir.String())
+ implicitInputs = append(implicitInputs, outputFile)
+ defaultReadOnlyFiles = append(defaultReadOnlyFiles, outputFile.Base())
+ }
}
////////////////////////////////////////////////////////////////////////////////////
diff --git a/bloaty/bloaty.go b/bloaty/bloaty.go
index 43fb71d..b72b6d3 100644
--- a/bloaty/bloaty.go
+++ b/bloaty/bloaty.go
@@ -85,6 +85,9 @@
func (singleton *sizesSingleton) GenerateBuildActions(ctx android.SingletonContext) {
var deps android.Paths
ctx.VisitAllModules(func(m android.Module) {
+ if !m.ExportedToMake() {
+ return
+ }
filePaths, ok := android.SingletonModuleProvider(ctx, m, fileSizeMeasurerKey)
if !ok {
return
diff --git a/cc/check.go b/cc/check.go
index 58ff5b2..32d1f06 100644
--- a/cc/check.go
+++ b/cc/check.go
@@ -45,6 +45,8 @@
ctx.PropertyErrorf(prop, "-Weverything is not allowed in Android.bp files. "+
"Build with `m ANDROID_TEMPORARILY_ALLOW_WEVERYTHING=true` to experiment locally with -Weverything.")
}
+ } else if strings.HasPrefix(flag, "-target") || strings.HasPrefix(flag, "--target") {
+ ctx.PropertyErrorf(prop, "Bad flag: `%s`, use the correct target soong rule.", flag)
} else if strings.Contains(flag, " ") {
args := strings.Split(flag, " ")
if args[0] == "-include" {
diff --git a/cc/config/global.go b/cc/config/global.go
index d3c2658..b21d56c 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -367,8 +367,6 @@
"-Wno-gnu-offsetof-extensions",
// TODO: Enable this warning http://b/315245071
"-Wno-fortify-source",
- "-Wno-tautological-negation-compare",
- "-Wno-tautological-undefined-compare",
}
llvmNextExtraCommonGlobalCflags = []string{
diff --git a/cc/library.go b/cc/library.go
index 4684d32..e2b4d4f 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -1354,38 +1354,28 @@
fileName+".lsdump")
}
-func getRefAbiDumpDir(isNdk, isLlndk bool) string {
- var dirName string
- if isNdk {
- dirName = "ndk"
- } else if isLlndk {
- dirName = "vndk"
- } else {
- dirName = "platform"
- }
- return filepath.Join("prebuilts", "abi-dumps", dirName)
-}
-
-func prevRefAbiDumpVersion(ctx ModuleContext, dumpDir string) int {
+// Return the previous and current SDK versions for cross-version ABI diff.
+func crossVersionAbiDiffSdkVersions(ctx ModuleContext, dumpDir string) (string, string) {
sdkVersionInt := ctx.Config().PlatformSdkVersion().FinalInt()
sdkVersionStr := ctx.Config().PlatformSdkVersion().String()
if ctx.Config().PlatformSdkFinal() {
- return sdkVersionInt - 1
+ return strconv.Itoa(sdkVersionInt - 1), sdkVersionStr
} else {
// The platform SDK version can be upgraded before finalization while the corresponding abi dumps hasn't
// been generated. Thus the Cross-Version Check chooses PLATFORM_SDK_VERION - 1 as previous version.
// This situation could be identified by checking the existence of the PLATFORM_SDK_VERION dump directory.
versionedDumpDir := android.ExistentPathForSource(ctx, dumpDir, sdkVersionStr)
if versionedDumpDir.Valid() {
- return sdkVersionInt
+ return sdkVersionStr, strconv.Itoa(sdkVersionInt + 1)
} else {
- return sdkVersionInt - 1
+ return strconv.Itoa(sdkVersionInt - 1), sdkVersionStr
}
}
}
-func currRefAbiDumpVersion(ctx ModuleContext) string {
+// Return the SDK version for same-version ABI diff.
+func currRefAbiDumpSdkVersion(ctx ModuleContext) string {
if ctx.Config().PlatformSdkFinal() {
// After sdk finalization, the ABI of the latest API level must be consistent with the source code,
// so choose PLATFORM_SDK_VERSION as the current version.
@@ -1435,17 +1425,17 @@
}
func (library *libraryDecorator) sameVersionAbiDiff(ctx android.ModuleContext, referenceDump android.Path,
- baseName string, isLlndkOrNdk bool) {
+ baseName, nameExt string, isLlndkOrNdk bool) {
libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
errorMessage := "error: Please update ABI references with: $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l " + libName
- library.sourceAbiDiff(ctx, referenceDump, baseName, "",
+ library.sourceAbiDiff(ctx, referenceDump, baseName, nameExt,
isLlndkOrNdk, false /* allowExtensions */, "current", errorMessage)
}
func (library *libraryDecorator) optInAbiDiff(ctx android.ModuleContext, referenceDump android.Path,
- baseName, nameExt string, isLlndkOrNdk bool, refDumpDir string) {
+ baseName, nameExt string, refDumpDir string) {
libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
errorMessage := "error: Please update ABI references with: $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l " + libName + " -ref-dump-dir $$ANDROID_BUILD_TOP/" + refDumpDir
@@ -1455,7 +1445,7 @@
}
library.sourceAbiDiff(ctx, referenceDump, baseName, nameExt,
- isLlndkOrNdk, false /* allowExtensions */, "current", errorMessage)
+ false /* isLlndkOrNdk */, false /* allowExtensions */, "current", errorMessage)
}
func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) {
@@ -1470,38 +1460,56 @@
}
exportedHeaderFlags := strings.Join(SourceAbiFlags, " ")
headerAbiChecker := library.getHeaderAbiCheckerProperties(ctx)
- // The logic must be consistent with classifySourceAbiDump.
- isNdk := ctx.isNdk(ctx.Config())
- isLlndk := ctx.isImplementationForLLNDKPublic()
- currVersion := currRefAbiDumpVersion(ctx)
+ currSdkVersion := currRefAbiDumpSdkVersion(ctx)
+ currVendorVersion := ctx.Config().VendorApiLevel()
library.sAbiOutputFile = transformDumpToLinkedDump(ctx, objs.sAbiDumpFiles, soFile, fileName, exportedHeaderFlags,
android.OptionalPathForModuleSrc(ctx, library.symbolFileForAbiCheck(ctx)),
headerAbiChecker.Exclude_symbol_versions,
headerAbiChecker.Exclude_symbol_tags,
- currVersion)
+ currSdkVersion)
for _, tag := range classifySourceAbiDump(ctx) {
- addLsdumpPath(tag + ":" + library.sAbiOutputFile.String())
- }
+ addLsdumpPath(string(tag) + ":" + library.sAbiOutputFile.String())
- dumpDir := getRefAbiDumpDir(isNdk, isLlndk)
- binderBitness := ctx.DeviceConfig().BinderBitness()
- // Check against the previous version.
- prevVersionInt := prevRefAbiDumpVersion(ctx, dumpDir)
- prevVersion := strconv.Itoa(prevVersionInt)
- prevDumpDir := filepath.Join(dumpDir, prevVersion, binderBitness)
- prevDumpFile := getRefAbiDumpFile(ctx, prevDumpDir, fileName)
- if prevDumpFile.Valid() {
- library.crossVersionAbiDiff(ctx, prevDumpFile.Path(),
- fileName, isLlndk || isNdk,
- strconv.Itoa(prevVersionInt+1), prevVersion)
- }
- // Check against the current version.
- currDumpDir := filepath.Join(dumpDir, currVersion, binderBitness)
- currDumpFile := getRefAbiDumpFile(ctx, currDumpDir, fileName)
- if currDumpFile.Valid() {
- library.sameVersionAbiDiff(ctx, currDumpFile.Path(),
- fileName, isLlndk || isNdk)
+ dumpDirName := tag.dirName()
+ if dumpDirName == "" {
+ continue
+ }
+ dumpDir := filepath.Join("prebuilts", "abi-dumps", dumpDirName)
+ isLlndk := (tag == llndkLsdumpTag)
+ isNdk := (tag == ndkLsdumpTag)
+ binderBitness := ctx.DeviceConfig().BinderBitness()
+ nameExt := ""
+ if isLlndk {
+ nameExt = "llndk"
+ }
+ // Check against the previous version.
+ var prevVersion, currVersion string
+ // If this release config does not define VendorApiLevel, fall back to the old policy.
+ if isLlndk && currVendorVersion != "" {
+ prevVersion = ctx.Config().PrevVendorApiLevel()
+ currVersion = currVendorVersion
+ } else {
+ prevVersion, currVersion = crossVersionAbiDiffSdkVersions(ctx, dumpDir)
+ }
+ prevDumpDir := filepath.Join(dumpDir, prevVersion, binderBitness)
+ prevDumpFile := getRefAbiDumpFile(ctx, prevDumpDir, fileName)
+ if prevDumpFile.Valid() {
+ library.crossVersionAbiDiff(ctx, prevDumpFile.Path(),
+ fileName, isLlndk || isNdk, currVersion, nameExt+prevVersion)
+ }
+ // Check against the current version.
+ if isLlndk && currVendorVersion != "" {
+ currVersion = currVendorVersion
+ } else {
+ currVersion = currSdkVersion
+ }
+ currDumpDir := filepath.Join(dumpDir, currVersion, binderBitness)
+ currDumpFile := getRefAbiDumpFile(ctx, currDumpDir, fileName)
+ if currDumpFile.Valid() {
+ library.sameVersionAbiDiff(ctx, currDumpFile.Path(),
+ fileName, nameExt, isLlndk || isNdk)
+ }
}
// Check against the opt-in reference dumps.
for i, optInDumpDir := range headerAbiChecker.Ref_dump_dirs {
@@ -1513,8 +1521,7 @@
continue
}
library.optInAbiDiff(ctx, optInDumpFile.Path(),
- fileName, "opt"+strconv.Itoa(i), isLlndk || isNdk,
- optInDumpDirPath.String())
+ fileName, "opt"+strconv.Itoa(i), optInDumpDirPath.String())
}
}
}
diff --git a/cc/sabi.go b/cc/sabi.go
index 4ca9f5c..af26726 100644
--- a/cc/sabi.go
+++ b/cc/sabi.go
@@ -26,6 +26,30 @@
lsdumpPathsLock sync.Mutex
)
+type lsdumpTag string
+
+const (
+ llndkLsdumpTag lsdumpTag = "LLNDK"
+ ndkLsdumpTag lsdumpTag = "NDK"
+ platformLsdumpTag lsdumpTag = "PLATFORM"
+ productLsdumpTag lsdumpTag = "PRODUCT"
+ vendorLsdumpTag lsdumpTag = "VENDOR"
+)
+
+// Return the prebuilt ABI dump directory for a tag; an empty string for an opt-in dump.
+func (tag *lsdumpTag) dirName() string {
+ switch *tag {
+ case ndkLsdumpTag:
+ return "ndk"
+ case llndkLsdumpTag:
+ return "vndk"
+ case platformLsdumpTag:
+ return "platform"
+ default:
+ return ""
+ }
+}
+
// Properties for ABI compatibility checker in Android.bp.
type headerAbiCheckerProperties struct {
// Enable ABI checks (even if this is not an LLNDK/VNDK lib)
@@ -98,8 +122,8 @@
}
// Returns a slice of strings that represent the ABI dumps generated for this module.
-func classifySourceAbiDump(ctx android.BaseModuleContext) []string {
- result := []string{}
+func classifySourceAbiDump(ctx android.BaseModuleContext) []lsdumpTag {
+ result := []lsdumpTag{}
m := ctx.Module().(*Module)
headerAbiChecker := m.library.getHeaderAbiCheckerProperties(ctx)
if headerAbiChecker.explicitlyDisabled() {
@@ -107,21 +131,21 @@
}
if !m.InProduct() && !m.InVendor() {
if m.isImplementationForLLNDKPublic() {
- result = append(result, "LLNDK")
+ result = append(result, llndkLsdumpTag)
}
// Return NDK if the library is both NDK and APEX.
// TODO(b/309880485): Split NDK and APEX ABI.
if m.IsNdk(ctx.Config()) {
- result = append(result, "NDK")
+ result = append(result, ndkLsdumpTag)
} else if m.library.hasStubsVariants() || headerAbiChecker.enabled() {
- result = append(result, "PLATFORM")
+ result = append(result, platformLsdumpTag)
}
} else if headerAbiChecker.enabled() {
if m.InProduct() {
- result = append(result, "PRODUCT")
+ result = append(result, productLsdumpTag)
}
if m.InVendor() {
- result = append(result, "VENDOR")
+ result = append(result, vendorLsdumpTag)
}
}
return result
diff --git a/java/aar.go b/java/aar.go
index f61fc83..0edee83 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -23,6 +23,7 @@
"android/soong/android"
"android/soong/dexpreopt"
+
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -414,17 +415,11 @@
linkFlags = append(linkFlags, "--static-lib")
}
+ linkFlags = append(linkFlags, "--no-static-lib-packages")
if a.isLibrary && a.useResourceProcessorBusyBox(ctx) {
- // When building an android_library using ResourceProcessorBusyBox the resources are merged into
- // package-res.apk with --merge-only, but --no-static-lib-packages is not used so that R.txt only
- // contains resources from this library.
+ // When building an android_library using ResourceProcessorBusyBox pass --merge-only to skip resource
+ // references validation until the final app link step when all static libraries are present.
linkFlags = append(linkFlags, "--merge-only")
- } else {
- // When building and app or when building an android_library without ResourceProcessorBusyBox
- // --no-static-lib-packages is used to put all the resources into the app. If ResourceProcessorBusyBox
- // is used then the app's R.txt will be post-processed along with the R.txt files from dependencies to
- // sort resources into the right packages in R.class.
- linkFlags = append(linkFlags, "--no-static-lib-packages")
}
packageRes := android.PathForModuleOut(ctx, "package-res.apk")
@@ -808,6 +803,9 @@
func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.aapt.isLibrary = true
a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
+ if a.usesLibrary.shouldDisableDexpreopt {
+ a.dexpreopter.disableDexpreopt()
+ }
a.aapt.buildActions(ctx,
aaptBuildActionOptions{
sdkContext: android.SdkContext(a),
@@ -1177,6 +1175,7 @@
"--static-lib",
"--merge-only",
"--auto-add-overlay",
+ "--no-static-lib-packages",
}
linkFlags = append(linkFlags, "--manifest "+a.manifest.String())
@@ -1250,6 +1249,7 @@
TransitiveStaticLibsHeaderJars: a.transitiveStaticLibsHeaderJars,
ImplementationAndResourcesJars: android.PathsIfNonNil(a.classpathFile),
ImplementationJars: android.PathsIfNonNil(a.classpathFile),
+ StubsLinkType: Implementation,
// TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
})
diff --git a/java/app.go b/java/app.go
index 05f042d..9736ffd 100755
--- a/java/app.go
+++ b/java/app.go
@@ -778,6 +778,9 @@
a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir)
a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
+ if a.usesLibrary.shouldDisableDexpreopt {
+ a.dexpreopter.disableDexpreopt()
+ }
var noticeAssetPath android.WritablePath
if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
@@ -1113,6 +1116,8 @@
if a.rJar != nil {
return []android.Path{a.rJar}, nil
}
+ case ".apk":
+ return []android.Path{a.outputFile}, nil
case ".export-package.apk":
return []android.Path{a.exportPackage}, nil
case ".manifest.xml":
@@ -1207,10 +1212,10 @@
Cmd *string
}{
Name: proptools.StringPtr(rroManifestName),
- Tools: []string{"characteristics_rro_generator"},
+ Tools: []string{"characteristics_rro_generator", "aapt2"},
Out: []string{"AndroidManifest.xml"},
- Srcs: []string{":" + a.Name() + "{.manifest.xml}"},
- Cmd: proptools.StringPtr("$(location characteristics_rro_generator) $(in) $(out)"),
+ Srcs: []string{":" + a.Name() + "{.apk}"},
+ Cmd: proptools.StringPtr("$(location characteristics_rro_generator) $$($(location aapt2) dump packagename $(in)) $(out)"),
}
ctx.CreateModule(genrule.GenRuleFactory, &rroManifestProperties)
@@ -1564,6 +1569,9 @@
// Whether to enforce verify_uses_library check.
enforce bool
+
+ // Whether dexpreopt should be disabled
+ shouldDisableDexpreopt bool
}
func (u *usesLibrary) addLib(lib string, optional bool) {
@@ -1645,6 +1653,15 @@
}
}
+ // Skip java_sdk_library dependencies that provide stubs, but not an implementation.
+ // This will be restricted to optional_uses_libs
+ if sdklib, ok := m.(SdkLibraryDependency); ok {
+ if tag == usesLibOptTag && sdklib.DexJarBuildPath(ctx).PathOrNil() == nil {
+ u.shouldDisableDexpreopt = true
+ return
+ }
+ }
+
if lib, ok := m.(UsesLibraryDependency); ok {
libName := dep
if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
diff --git a/java/app_import.go b/java/app_import.go
index 12ead0a..74255b7 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -319,6 +319,9 @@
a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
a.dexpreopter.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
+ if a.usesLibrary.shouldDisableDexpreopt {
+ a.dexpreopter.disableDexpreopt()
+ }
if a.usesLibrary.enforceUsesLibraries() {
a.usesLibrary.verifyUsesLibrariesAPK(ctx, srcApk)
diff --git a/java/app_test.go b/java/app_test.go
index 362bef9..125c971 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -4378,3 +4378,26 @@
"--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
)
}
+
+// Test that dexpreopt is disabled if an optional_uses_libs exists, but does not provide an implementation.
+func TestNoDexpreoptOptionalUsesLibDoesNotHaveImpl(t *testing.T) {
+ bp := `
+ java_sdk_library_import {
+ name: "sdklib_noimpl",
+ public: {
+ jars: ["stub.jar"],
+ },
+ }
+ android_app {
+ name: "app",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ optional_uses_libs: [
+ "sdklib_noimpl",
+ ],
+ }
+ `
+ result := prepareForJavaTest.RunTestWithBp(t, bp)
+ dexpreopt := result.ModuleForTests("app", "android_common").MaybeRule("dexpreopt").Rule
+ android.AssertBoolEquals(t, "dexpreopt should be disabled if optional_uses_libs does not have an implementation", true, dexpreopt == nil)
+}
diff --git a/java/base.go b/java/base.go
index 4e2366f..7f4ea08 100644
--- a/java/base.go
+++ b/java/base.go
@@ -26,6 +26,7 @@
"github.com/google/blueprint/pathtools"
"github.com/google/blueprint/proptools"
+ "android/soong/aconfig"
"android/soong/android"
"android/soong/dexpreopt"
"android/soong/java/config"
@@ -205,6 +206,13 @@
// Note that currently not all actions implemented by android_apps are sandboxed, so you
// may only see this being necessary in lint builds.
Compile_data []string `android:"path"`
+
+ // Property signifying whether the module compiles stubs or not.
+ // Should be set to true when srcs of this module are stub files.
+ // This property does not need to be set to true when the module depends on
+ // the stubs via libs, but should be set to true when the module depends on
+ // the stubs via static libs.
+ Is_stubs_module *bool
}
// Properties that are specific to device modules. Host module factories should not add these when
@@ -532,6 +540,8 @@
// Values that will be set in the JarJarProvider data for jarjar repackaging,
// and merged with our dependencies' rules.
jarjarRenameRules map[string]string
+
+ stubsLinkType StubsLinkType
}
func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error {
@@ -1212,6 +1222,7 @@
ExportedPlugins: j.exportedPluginJars,
ExportedPluginClasses: j.exportedPluginClasses,
ExportedPluginDisableTurbine: j.exportedDisableTurbine,
+ StubsLinkType: j.stubsLinkType,
})
j.outputFile = j.headerJarFile
@@ -1729,6 +1740,7 @@
ExportedPluginClasses: j.exportedPluginClasses,
ExportedPluginDisableTurbine: j.exportedDisableTurbine,
JacocoReportClassesFile: j.jacocoReportClassesFile,
+ StubsLinkType: j.stubsLinkType,
})
// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
@@ -2372,11 +2384,26 @@
// classes until a module with jarjar_prefix is reached, and all as yet unrenamed classes will then
// be renamed from that module.
// TODO: Add another property to suppress the forwarding of
+type DependencyUse int
+
+const (
+ RenameUseInvalid DependencyUse = iota
+ RenameUseInclude
+ RenameUseExclude
+)
+
+type RenameUseElement struct {
+ DepName string
+ RenameUse DependencyUse
+ Why string // token for determining where in the logic the decision was made.
+}
+
type JarJarProviderData struct {
// Mapping of class names: original --> renamed. If the value is "", the class will be
// renamed by the next rdep that has the jarjar_prefix attribute (or this module if it has
// attribute). Rdeps of that module will inherit the renaming.
- Rename map[string]string
+ Rename map[string]string
+ RenameUse []RenameUseElement
}
func (this JarJarProviderData) GetDebugString() string {
@@ -2440,17 +2467,114 @@
func collectDirectDepsProviders(ctx android.ModuleContext) (result *JarJarProviderData) {
// Gather repackage information from deps
// If the dep jas a JarJarProvider, it is used. Otherwise, any BaseJarJarProvider is used.
+
+ module := ctx.Module()
+ moduleName := module.Name()
+
ctx.VisitDirectDepsIgnoreBlueprint(func(m android.Module) {
- if ctx.OtherModuleDependencyTag(m) == proguardRaiseTag {
- return
- }
- merge := func(theirs *JarJarProviderData) {
- for orig, renamed := range theirs.Rename {
- if result == nil {
- result = &JarJarProviderData{
- Rename: make(map[string]string),
+ tag := ctx.OtherModuleDependencyTag(m)
+ // This logic mirrors that in (*Module).collectDeps above. There are several places
+ // where we explicitly return RenameUseExclude, even though it is the default, to
+ // indicate that it has been verified to be the case.
+ //
+ // Note well: there are probably cases that are getting to the unconditional return
+ // and are therefore wrong.
+ shouldIncludeRenames := func() (DependencyUse, string) {
+ if moduleName == m.Name() {
+ return RenameUseInclude, "name" // If we have the same module name, include the renames.
+ }
+ if sc, ok := module.(android.SdkContext); ok {
+ if ctx.Device() {
+ sdkDep := decodeSdkDep(ctx, sc)
+ if !sdkDep.invalidVersion && sdkDep.useFiles {
+ return RenameUseExclude, "useFiles"
}
}
+ }
+ if IsJniDepTag(tag) || tag == certificateTag || tag == proguardRaiseTag {
+ return RenameUseExclude, "tags"
+ }
+ if _, ok := m.(SdkLibraryDependency); ok {
+ switch tag {
+ case sdkLibTag, libTag:
+ return RenameUseExclude, "sdklibdep" // matches collectDeps()
+ }
+ return RenameUseInvalid, "sdklibdep" // dep is not used in collectDeps()
+ } else if ji, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
+ switch ji.StubsLinkType {
+ case Stubs:
+ return RenameUseExclude, "info"
+ case Implementation:
+ return RenameUseInclude, "info"
+ default:
+ //fmt.Printf("LJ: %v -> %v StubsLinkType unknown\n", module, m)
+ // Fall through to the heuristic logic.
+ }
+ switch reflect.TypeOf(m).String() {
+ case "*java.GeneratedJavaLibraryModule":
+ // Probably a java_aconfig_library module.
+ // TODO: make this check better.
+ return RenameUseInclude, "reflect"
+ }
+ switch tag {
+ case bootClasspathTag:
+ return RenameUseExclude, "tagswitch"
+ case sdkLibTag, libTag, instrumentationForTag:
+ return RenameUseInclude, "tagswitch"
+ case java9LibTag:
+ return RenameUseExclude, "tagswitch"
+ case staticLibTag:
+ return RenameUseInclude, "tagswitch"
+ case pluginTag:
+ return RenameUseInclude, "tagswitch"
+ case errorpronePluginTag:
+ return RenameUseInclude, "tagswitch"
+ case exportedPluginTag:
+ return RenameUseInclude, "tagswitch"
+ case kotlinStdlibTag, kotlinAnnotationsTag:
+ return RenameUseExclude, "tagswitch"
+ case kotlinPluginTag:
+ return RenameUseInclude, "tagswitch"
+ default:
+ return RenameUseExclude, "tagswitch"
+ }
+ } else if _, ok := m.(android.SourceFileProducer); ok {
+ switch tag {
+ case sdkLibTag, libTag, staticLibTag:
+ return RenameUseInclude, "srcfile"
+ default:
+ return RenameUseExclude, "srcfile"
+ }
+ } else if _, ok := android.OtherModuleProvider(ctx, m, aconfig.CodegenInfoProvider); ok {
+ return RenameUseInclude, "aconfig_declarations_group"
+ } else {
+ switch tag {
+ case bootClasspathTag:
+ return RenameUseExclude, "else"
+ case systemModulesTag:
+ return RenameUseInclude, "else"
+ }
+ }
+ // If we got here, choose the safer option, which may lead to a build failure, rather
+ // than runtime failures on the device.
+ return RenameUseExclude, "end"
+ }
+
+ if result == nil {
+ result = &JarJarProviderData{
+ Rename: make(map[string]string),
+ RenameUse: make([]RenameUseElement, 0),
+ }
+ }
+ how, why := shouldIncludeRenames()
+ result.RenameUse = append(result.RenameUse, RenameUseElement{DepName: m.Name(), RenameUse: how, Why: why})
+ if how != RenameUseInclude {
+ // Nothing to merge.
+ return
+ }
+
+ merge := func(theirs *JarJarProviderData) {
+ for orig, renamed := range theirs.Rename {
if preexisting, exists := (*result).Rename[orig]; !exists || preexisting == "" {
result.Rename[orig] = renamed
} else if preexisting != "" && renamed != "" && preexisting != renamed {
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index efd13b8..3f8735c 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -137,6 +137,7 @@
ResourceJars: d.resourceJars,
SrcJarArgs: d.srcJarArgs,
SrcJarDeps: d.srcJarDeps,
+ StubsLinkType: Implementation,
// TODO: Not sure if aconfig flags that have been moved between device and host variants
// make sense.
})
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 9db9b1b..1cfa642 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -102,6 +102,11 @@
dexpreoptProperties DexpreoptProperties
importDexpreoptProperties ImportDexpreoptProperties
+ // If true, the dexpreopt rules will not be generated
+ // Unlike Dex_preopt.Enabled which is user-facing,
+ // shouldDisableDexpreopt is a mutated propery.
+ shouldDisableDexpreopt bool
+
installPath android.InstallPath
uncompressedDex bool
isSDKLibrary bool
@@ -197,6 +202,10 @@
return true
}
+ if d.shouldDisableDexpreopt {
+ return true
+ }
+
// If the module is from a prebuilt APEX, it shouldn't be installable, but it can still be
// dexpreopted.
if !ctx.Module().(DexpreopterInterface).IsInstallable() && !forPrebuiltApex(ctx) {
@@ -528,3 +537,7 @@
func (d *dexpreopter) OutputProfilePathOnHost() android.Path {
return d.outputProfilePathOnHost
}
+
+func (d *dexpreopter) disableDexpreopt() {
+ d.shouldDisableDexpreopt = true
+}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index cfbf2b4..6a66f45 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -21,6 +21,7 @@
"github.com/google/blueprint/proptools"
+ "android/soong/aconfig"
"android/soong/android"
"android/soong/java/config"
)
@@ -413,9 +414,12 @@
case aconfigDeclarationTag:
if dep, ok := android.OtherModuleProvider(ctx, module, android.AconfigDeclarationsProviderKey); ok {
deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPath)
+ } else if dep, ok := android.OtherModuleProvider(ctx, module, aconfig.CodegenInfoProvider); ok {
+ deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
} else {
- ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
- "flags_packages property, but %s is not aconfig_declarations module type",
+ ctx.ModuleErrorf("Only aconfig_declarations and aconfig_declarations_group "+
+ "module type is allowed for flags_packages property, but %s is neither "+
+ "of these supported module types",
module.Name(),
)
}
diff --git a/java/java.go b/java/java.go
index d7d271c..af4c3be 100644
--- a/java/java.go
+++ b/java/java.go
@@ -87,6 +87,14 @@
android.RegisterSdkMemberType(javaTestSdkMemberType)
}
+type StubsLinkType int
+
+const (
+ Unknown StubsLinkType = iota
+ Stubs
+ Implementation
+)
+
var (
// Supports adding java header libraries to module_exports and sdk.
javaHeaderLibsSdkMemberType = &librarySdkMemberType{
@@ -296,6 +304,11 @@
// JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be
// instrumented by jacoco.
JacocoReportClassesFile android.Path
+
+ // StubsLinkType provides information about whether the provided jars are stub jars or
+ // implementation jars. If the provider is set by java_sdk_library, the link type is "unknown"
+ // and selection between the stub jar vs implementation jar is deferred to SdkLibrary.sdkJars(...)
+ StubsLinkType StubsLinkType
}
var JavaInfoProvider = blueprint.NewProvider[JavaInfo]()
@@ -686,14 +699,195 @@
}
}
-func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+// list of java_library modules that set platform_apis: true
+// this property is a no-op for java_library
+// TODO (b/215379393): Remove this allowlist
+var (
+ aospPlatformApiAllowlist = map[string]bool{
+ "adservices-test-scenarios": true,
+ "aidl-cpp-java-test-interface-java": true,
+ "aidl-test-extras-java": true,
+ "aidl-test-interface-java": true,
+ "aidl-test-interface-permission-java": true,
+ "aidl_test_java_client_permission": true,
+ "aidl_test_java_client_sdk1": true,
+ "aidl_test_java_client_sdk29": true,
+ "aidl_test_java_client": true,
+ "aidl_test_java_service_permission": true,
+ "aidl_test_java_service_sdk1": true,
+ "aidl_test_java_service_sdk29": true,
+ "aidl_test_java_service": true,
+ "aidl_test_loggable_interface-java": true,
+ "aidl_test_nonvintf_parcelable-V1-java": true,
+ "aidl_test_nonvintf_parcelable-V2-java": true,
+ "aidl_test_unstable_parcelable-java": true,
+ "aidl_test_vintf_parcelable-V1-java": true,
+ "aidl_test_vintf_parcelable-V2-java": true,
+ "android.aidl.test.trunk-V1-java": true,
+ "android.aidl.test.trunk-V2-java": true,
+ "android.frameworks.location.altitude-V1-java": true,
+ "android.frameworks.location.altitude-V2-java": true,
+ "android.frameworks.stats-V1-java": true,
+ "android.frameworks.stats-V2-java": true,
+ "android.frameworks.stats-V3-java": true,
+ "android.hardware.authsecret-V1-java": true,
+ "android.hardware.authsecret-V2-java": true,
+ "android.hardware.biometrics.common-V1-java": true,
+ "android.hardware.biometrics.common-V2-java": true,
+ "android.hardware.biometrics.common-V3-java": true,
+ "android.hardware.biometrics.common-V4-java": true,
+ "android.hardware.biometrics.face-V1-java": true,
+ "android.hardware.biometrics.face-V2-java": true,
+ "android.hardware.biometrics.face-V3-java": true,
+ "android.hardware.biometrics.face-V4-java": true,
+ "android.hardware.biometrics.fingerprint-V1-java": true,
+ "android.hardware.biometrics.fingerprint-V2-java": true,
+ "android.hardware.biometrics.fingerprint-V3-java": true,
+ "android.hardware.biometrics.fingerprint-V4-java": true,
+ "android.hardware.bluetooth.lmp_event-V1-java": true,
+ "android.hardware.confirmationui-V1-java": true,
+ "android.hardware.confirmationui-V2-java": true,
+ "android.hardware.gatekeeper-V1-java": true,
+ "android.hardware.gatekeeper-V2-java": true,
+ "android.hardware.gnss-V1-java": true,
+ "android.hardware.gnss-V2-java": true,
+ "android.hardware.gnss-V3-java": true,
+ "android.hardware.gnss-V4-java": true,
+ "android.hardware.graphics.common-V1-java": true,
+ "android.hardware.graphics.common-V2-java": true,
+ "android.hardware.graphics.common-V3-java": true,
+ "android.hardware.graphics.common-V4-java": true,
+ "android.hardware.graphics.common-V5-java": true,
+ "android.hardware.identity-V1-java": true,
+ "android.hardware.identity-V2-java": true,
+ "android.hardware.identity-V3-java": true,
+ "android.hardware.identity-V4-java": true,
+ "android.hardware.identity-V5-java": true,
+ "android.hardware.identity-V6-java": true,
+ "android.hardware.keymaster-V1-java": true,
+ "android.hardware.keymaster-V2-java": true,
+ "android.hardware.keymaster-V3-java": true,
+ "android.hardware.keymaster-V4-java": true,
+ "android.hardware.keymaster-V5-java": true,
+ "android.hardware.oemlock-V1-java": true,
+ "android.hardware.oemlock-V2-java": true,
+ "android.hardware.power.stats-V1-java": true,
+ "android.hardware.power.stats-V2-java": true,
+ "android.hardware.power.stats-V3-java": true,
+ "android.hardware.power-V1-java": true,
+ "android.hardware.power-V2-java": true,
+ "android.hardware.power-V3-java": true,
+ "android.hardware.power-V4-java": true,
+ "android.hardware.power-V5-java": true,
+ "android.hardware.rebootescrow-V1-java": true,
+ "android.hardware.rebootescrow-V2-java": true,
+ "android.hardware.security.authgraph-V1-java": true,
+ "android.hardware.security.keymint-V1-java": true,
+ "android.hardware.security.keymint-V2-java": true,
+ "android.hardware.security.keymint-V3-java": true,
+ "android.hardware.security.keymint-V4-java": true,
+ "android.hardware.security.secureclock-V1-java": true,
+ "android.hardware.security.secureclock-V2-java": true,
+ "android.hardware.thermal-V1-java": true,
+ "android.hardware.thermal-V2-java": true,
+ "android.hardware.threadnetwork-V1-java": true,
+ "android.hardware.weaver-V1-java": true,
+ "android.hardware.weaver-V2-java": true,
+ "android.hardware.weaver-V3-java": true,
+ "android.security.attestationmanager-java": true,
+ "android.security.authorization-java": true,
+ "android.security.compat-java": true,
+ "android.security.legacykeystore-java": true,
+ "android.security.maintenance-java": true,
+ "android.security.metrics-java": true,
+ "android.system.keystore2-V1-java": true,
+ "android.system.keystore2-V2-java": true,
+ "android.system.keystore2-V3-java": true,
+ "android.system.keystore2-V4-java": true,
+ "binderReadParcelIface-java": true,
+ "binderRecordReplayTestIface-java": true,
+ "car-experimental-api-static-lib": true,
+ "collector-device-lib-platform": true,
+ "com.android.car.oem": true,
+ "com.google.hardware.pixel.display-V10-java": true,
+ "com.google.hardware.pixel.display-V1-java": true,
+ "com.google.hardware.pixel.display-V2-java": true,
+ "com.google.hardware.pixel.display-V3-java": true,
+ "com.google.hardware.pixel.display-V4-java": true,
+ "com.google.hardware.pixel.display-V5-java": true,
+ "com.google.hardware.pixel.display-V6-java": true,
+ "com.google.hardware.pixel.display-V7-java": true,
+ "com.google.hardware.pixel.display-V8-java": true,
+ "com.google.hardware.pixel.display-V9-java": true,
+ "conscrypt-support": true,
+ "cts-keystore-test-util": true,
+ "cts-keystore-user-auth-helper-library": true,
+ "ctsmediautil": true,
+ "CtsNetTestsNonUpdatableLib": true,
+ "DpmWrapper": true,
+ "flickerlib-apphelpers": true,
+ "flickerlib-helpers": true,
+ "flickerlib-parsers": true,
+ "flickerlib": true,
+ "hardware.google.bluetooth.ccc-V1-java": true,
+ "hardware.google.bluetooth.sar-V1-java": true,
+ "monet": true,
+ "pixel-power-ext-V1-java": true,
+ "pixel-power-ext-V2-java": true,
+ "pixel_stateresidency_provider_aidl_interface-java": true,
+ "pixel-thermal-ext-V1-java": true,
+ "protolog-lib": true,
+ "RkpRegistrationCheck": true,
+ "rotary-service-javastream-protos": true,
+ "service_based_camera_extensions": true,
+ "statsd-helper-test": true,
+ "statsd-helper": true,
+ "test-piece-2-V1-java": true,
+ "test-piece-2-V2-java": true,
+ "test-piece-3-V1-java": true,
+ "test-piece-3-V2-java": true,
+ "test-piece-3-V3-java": true,
+ "test-piece-4-V1-java": true,
+ "test-piece-4-V2-java": true,
+ "test-root-package-V1-java": true,
+ "test-root-package-V2-java": true,
+ "test-root-package-V3-java": true,
+ "test-root-package-V4-java": true,
+ "testServiceIface-java": true,
+ "wm-flicker-common-app-helpers": true,
+ "wm-flicker-common-assertions": true,
+ "wm-shell-flicker-utils": true,
+ "wycheproof-keystore": true,
+ }
+ // Union of aosp and internal allowlists
+ PlatformApiAllowlist = map[string]bool{}
+)
+
+func init() {
+ for k, v := range aospPlatformApiAllowlist {
+ PlatformApiAllowlist[k] = v
+ }
+}
+
+func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.provideHiddenAPIPropertyInfo(ctx)
j.sdkVersion = j.SdkVersion(ctx)
j.minSdkVersion = j.MinSdkVersion(ctx)
j.maxSdkVersion = j.MaxSdkVersion(ctx)
+ // SdkLibrary.GenerateAndroidBuildActions(ctx) sets the stubsLinkType to Unknown.
+ // If the stubsLinkType has already been set to Unknown, the stubsLinkType should
+ // not be overridden.
+ if j.stubsLinkType != Unknown {
+ if proptools.Bool(j.properties.Is_stubs_module) {
+ j.stubsLinkType = Stubs
+ } else {
+ j.stubsLinkType = Implementation
+ }
+ }
+
j.stem = proptools.StringDefault(j.overridableDeviceProperties.Stem, ctx.ModuleName())
proguardSpecInfo := j.collectProguardSpecInfo(ctx)
@@ -719,6 +913,9 @@
setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
+ if j.usesLibrary.shouldDisableDexpreopt {
+ j.dexpreopter.disableDexpreopt()
+ }
}
j.compile(ctx, nil, nil, nil)
@@ -2018,6 +2215,7 @@
ImplementationAndResourcesJars: android.PathsIfNonNil(al.stubsJar),
ImplementationJars: android.PathsIfNonNil(al.stubsJar),
AidlIncludeDirs: android.Paths{},
+ StubsLinkType: Stubs,
// No aconfig libraries on api libraries
})
}
@@ -2102,6 +2300,9 @@
// The name is the undecorated name of the java_sdk_library as it appears in the blueprint file
// (without any prebuilt_ prefix)
Created_by_java_sdk_library_name *string `blueprint:"mutated"`
+
+ // Property signifying whether the module provides stubs jar or not.
+ Is_stubs_module *bool
}
type Import struct {
@@ -2132,6 +2333,8 @@
sdkVersion android.SdkSpec
minSdkVersion android.ApiLevel
+
+ stubsLinkType StubsLinkType
}
var _ PermittedPackagesForUpdatableBootJars = (*Import)(nil)
@@ -2226,6 +2429,12 @@
if ctx.Windows() {
j.HideFromMake()
}
+
+ if proptools.Bool(j.properties.Is_stubs_module) {
+ j.stubsLinkType = Stubs
+ } else {
+ j.stubsLinkType = Implementation
+ }
}
func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -2359,6 +2568,7 @@
ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedClasspathFile),
ImplementationJars: android.PathsIfNonNil(j.combinedClasspathFile),
AidlIncludeDirs: j.exportAidlIncludeDirs,
+ StubsLinkType: j.stubsLinkType,
// TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
})
}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index fbde042..d532aaa 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1572,6 +1572,8 @@
// Only build an implementation library if required.
if module.requiresRuntimeImplementationLibrary() {
+ // stubsLinkType must be set before calling Library.GenerateAndroidBuildActions
+ module.Library.stubsLinkType = Unknown
module.Library.GenerateAndroidBuildActions(ctx)
}
@@ -1797,6 +1799,7 @@
Dir *string
Tag *string
}
+ Is_stubs_module *bool
}
func (module *SdkLibrary) stubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope) libraryProperties {
@@ -1821,6 +1824,7 @@
// We compile the stubs for 1.8 in line with the main android.jar stubs, and potential
// interop with older developer tools that don't support 1.9.
props.Java_version = proptools.StringPtr("1.8")
+ props.Is_stubs_module = proptools.BoolPtr(true)
return props
}
@@ -1993,8 +1997,10 @@
tag string
pattern string
}{
- {tag: ".api.txt", pattern: "%s.txt"},
- {tag: ".removed-api.txt", pattern: "%s-removed.txt"},
+ // "exportable" api files are copied to the dist directory instead of the
+ // "everything" api files.
+ {tag: ".exportable.api.txt", pattern: "%s.txt"},
+ {tag: ".exportable.removed-api.txt", pattern: "%s-removed.txt"},
} {
props.Dists = append(props.Dists, android.Dist{
Targets: []string{"sdk", "win_sdk"},
@@ -2709,6 +2715,7 @@
Libs []string
Jars []string
Compile_dex *bool
+ Is_stubs_module *bool
android.UserSuppliedPrebuiltProperties
}{}
@@ -2730,6 +2737,7 @@
compileDex = proptools.BoolPtr(true)
}
props.Compile_dex = compileDex
+ props.Is_stubs_module = proptools.BoolPtr(true)
mctx.CreateModule(ImportFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}
diff --git a/rust/testing.go b/rust/testing.go
index 0b34c97..d9cacdc 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -75,6 +75,7 @@
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
vendor_available: true,
+ host_supported: true,
recovery_available: true,
llndk: {
symbol_file: "liblog.map.txt",
diff --git a/sysprop/Android.bp b/sysprop/Android.bp
index 1d5eb31..a00a5e4 100644
--- a/sysprop/Android.bp
+++ b/sysprop/Android.bp
@@ -11,6 +11,7 @@
"soong-android",
"soong-cc",
"soong-java",
+ "soong-rust",
],
srcs: [
"sysprop_library.go",
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index 766f3e7..2258232 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -21,6 +21,7 @@
"io"
"os"
"path"
+ "strings"
"sync"
"github.com/google/blueprint"
@@ -29,6 +30,7 @@
"android/soong/android"
"android/soong/cc"
"android/soong/java"
+ "android/soong/rust"
)
type dependencyTag struct {
@@ -51,7 +53,16 @@
genSrcjars android.Paths
}
+type syspropRustGenRule struct {
+ android.ModuleBase
+
+ properties syspropGenProperties
+
+ genSrcs android.Paths
+}
+
var _ android.OutputFileProducer = (*syspropJavaGenRule)(nil)
+var _ android.OutputFileProducer = (*syspropRustGenRule)(nil)
var (
syspropJava = pctx.AndroidStaticRule("syspropJava",
@@ -64,11 +75,20 @@
"$soongZipCmd",
},
}, "scope")
+ syspropRust = pctx.AndroidStaticRule("syspropRust",
+ blueprint.RuleParams{
+ Command: `rm -rf $out_dir && mkdir -p $out_dir && ` +
+ `$syspropRustCmd --scope $scope --rust-output-dir $out_dir $in`,
+ CommandDeps: []string{
+ "$syspropRustCmd",
+ },
+ }, "scope", "out_dir")
)
func init() {
pctx.HostBinToolVariable("soongZipCmd", "soong_zip")
pctx.HostBinToolVariable("syspropJavaCmd", "sysprop_java")
+ pctx.HostBinToolVariable("syspropRustCmd", "sysprop_rust")
}
// syspropJavaGenRule module generates srcjar containing generated java APIs.
@@ -122,6 +142,56 @@
return g
}
+// syspropRustGenRule module generates rust source files containing generated rust APIs.
+// It also depends on check api rule, so api check has to pass to use sysprop_library.
+func (g *syspropRustGenRule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ var checkApiFileTimeStamp android.WritablePath
+
+ ctx.VisitDirectDeps(func(dep android.Module) {
+ if m, ok := dep.(*syspropLibrary); ok {
+ checkApiFileTimeStamp = m.checkApiFileTimeStamp
+ }
+ })
+
+ for _, syspropFile := range android.PathsForModuleSrc(ctx, g.properties.Srcs) {
+ syspropDir := strings.TrimSuffix(syspropFile.String(), syspropFile.Ext())
+ outputDir := android.PathForModuleGen(ctx, syspropDir, "src")
+ libPath := android.PathForModuleGen(ctx, syspropDir, "src", "lib.rs")
+ parsersPath := android.PathForModuleGen(ctx, syspropDir, "src", "gen_parsers_and_formatters.rs")
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: syspropRust,
+ Description: "sysprop_rust " + syspropFile.Rel(),
+ Outputs: android.WritablePaths{libPath, parsersPath},
+ Input: syspropFile,
+ Implicit: checkApiFileTimeStamp,
+ Args: map[string]string{
+ "scope": g.properties.Scope,
+ "out_dir": outputDir.String(),
+ },
+ })
+
+ g.genSrcs = append(g.genSrcs, libPath, parsersPath)
+ }
+}
+
+func (g *syspropRustGenRule) DepsMutator(ctx android.BottomUpMutatorContext) {
+ // Add a dependency from the stubs to sysprop library so that the generator rule can depend on
+ // the check API rule of the sysprop library.
+ ctx.AddFarVariationDependencies(nil, nil, proptools.String(g.properties.Check_api))
+}
+
+func (g *syspropRustGenRule) OutputFiles(_ string) (android.Paths, error) {
+ return g.genSrcs, nil
+}
+
+func syspropRustGenFactory() android.Module {
+ g := &syspropRustGenRule{}
+ g.AddProperties(&g.properties)
+ android.InitAndroidModule(g)
+ return g
+}
+
type syspropLibrary struct {
android.ModuleBase
android.ApexModuleBase
@@ -180,6 +250,12 @@
// Forwarded to java_library.min_sdk_version
Min_sdk_version *string
}
+
+ Rust struct {
+ // Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
+ // Forwarded to rust_library.min_sdk_version
+ Min_sdk_version *string
+ }
}
var (
@@ -233,6 +309,21 @@
return m.BaseModuleName() + "_java_gen_public"
}
+func (m *syspropLibrary) rustGenModuleName() string {
+ return m.rustCrateName() + "_rust_gen"
+}
+
+func (m *syspropLibrary) rustGenStubName() string {
+ return "lib" + m.rustCrateName() + "_rust"
+}
+
+func (m *syspropLibrary) rustCrateName() string {
+ moduleName := strings.ToLower(m.BaseModuleName())
+ moduleName = strings.ReplaceAll(moduleName, "-", "_")
+ moduleName = strings.ReplaceAll(moduleName, ".", "_")
+ return moduleName
+}
+
func (m *syspropLibrary) BaseModuleName() string {
return m.ModuleBase.Name()
}
@@ -436,6 +527,18 @@
Min_sdk_version *string
}
+type rustLibraryProperties struct {
+ Name *string
+ Srcs []string
+ Installable *bool
+ Crate_name string
+ Rustlibs []string
+ Vendor_available *bool
+ Product_available *bool
+ Apex_available []string
+ Min_sdk_version *string
+}
+
func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) {
if len(m.properties.Srcs) == 0 {
ctx.PropertyErrorf("srcs", "sysprop_library must specify srcs")
@@ -564,6 +667,28 @@
})
}
+ // Generate a Rust implementation library.
+ ctx.CreateModule(syspropRustGenFactory, &syspropGenProperties{
+ Srcs: m.properties.Srcs,
+ Scope: scope,
+ Name: proptools.StringPtr(m.rustGenModuleName()),
+ Check_api: proptools.StringPtr(ctx.ModuleName()),
+ })
+ rustProps := rustLibraryProperties{
+ Name: proptools.StringPtr(m.rustGenStubName()),
+ Srcs: []string{":" + m.rustGenModuleName()},
+ Installable: proptools.BoolPtr(false),
+ Crate_name: m.rustCrateName(),
+ Rustlibs: []string{
+ "librustutils",
+ },
+ Vendor_available: m.properties.Vendor_available,
+ Product_available: m.properties.Product_available,
+ Apex_available: m.ApexProperties.Apex_available,
+ Min_sdk_version: proptools.StringPtr("29"),
+ }
+ ctx.CreateModule(rust.RustLibraryFactory, &rustProps)
+
// syspropLibraries will be used by property_contexts to check types.
// Record absolute paths of sysprop_library to prevent soong_namespace problem.
if m.ExportedToMake() {
diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go
index e5b3dea..9dd696f 100644
--- a/sysprop/sysprop_test.go
+++ b/sysprop/sysprop_test.go
@@ -22,6 +22,7 @@
"android/soong/android"
"android/soong/cc"
"android/soong/java"
+ "android/soong/rust"
"github.com/google/blueprint/proptools"
)
@@ -46,18 +47,6 @@
recovery_available: true,
}
- cc_library {
- name: "liblog",
- no_libcrt: true,
- nocrt: true,
- system_shared_libs: [],
- recovery_available: true,
- host_supported: true,
- llndk: {
- symbol_file: "liblog.map.txt",
- }
- }
-
java_library {
name: "sysprop-library-stub-platform",
sdk_version: "core_current",
@@ -74,6 +63,15 @@
product_specific: true,
sdk_version: "core_current",
}
+
+ rust_library {
+ name: "librustutils",
+ crate_name: "rustutils",
+ srcs: ["librustutils/lib.rs"],
+ product_available: true,
+ vendor_available: true,
+ min_sdk_version: "29",
+ }
`
mockFS := android.MockFS{
@@ -115,11 +113,14 @@
"android/sysprop/PlatformProperties.sysprop": nil,
"com/android/VendorProperties.sysprop": nil,
"com/android2/OdmProperties.sysprop": nil,
+
+ "librustutils/lib.rs": nil,
}
result := android.GroupFixturePreparers(
cc.PrepareForTestWithCcDefaultModules,
java.PrepareForTestWithJavaDefaultModules,
+ rust.PrepareForTestWithRustDefaultModules,
PrepareForTestWithSyspropBuildComponents,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.DeviceSystemSdkVersions = []string{"28"}
@@ -356,6 +357,10 @@
javaModule := result.ModuleForTests("sysprop-platform", "android_common").Module().(*java.Library)
propFromJava := javaModule.ApexProperties.Apex_available
android.AssertDeepEquals(t, "apex_available forwarding to java module", expected, propFromJava)
+
+ rustModule := result.ModuleForTests("libsysprop_platform_rust", "android_arm64_armv8-a_rlib_rlib-std").Module().(*rust.Module)
+ propFromRust := rustModule.ApexProperties.Apex_available
+ android.AssertDeepEquals(t, "apex_available forwarding to rust module", expected, propFromRust)
}
func TestMinSdkVersionIsForwarded(t *testing.T) {
@@ -371,6 +376,9 @@
java: {
min_sdk_version: "30",
},
+ rust: {
+ min_sdk_version: "29",
+ }
}
`)
@@ -381,4 +389,8 @@
javaModule := result.ModuleForTests("sysprop-platform", "android_common").Module().(*java.Library)
propFromJava := javaModule.MinSdkVersionString()
android.AssertStringEquals(t, "min_sdk_version forwarding to java module", "30", propFromJava)
+
+ rustModule := result.ModuleForTests("libsysprop_platform_rust", "android_arm64_armv8-a_rlib_rlib-std").Module().(*rust.Module)
+ propFromRust := proptools.String(rustModule.Properties.Min_sdk_version)
+ android.AssertStringEquals(t, "min_sdk_version forwarding to rust module", "29", propFromRust)
}