Merge "Remove apex.use_file_contexts_as_is" into main
diff --git a/Android.bp b/Android.bp
index 98552a7..337545b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -150,10 +150,11 @@
arch: {
arm64: {
cflags: [
- // Prevent the compiler from optimizing code using SVE, as the
- // baremetal environment might not have configured the hardware.
- "-Xclang -target-feature",
- "-Xclang -sve",
+ // Override the global -march= flag (as set by TARGET_ARCH_VARIANT)
+ // and explicitly use the baseline architecture (ARMv8-A is the first
+ // version with 64-bit support) to avoid emitting potentially
+ // unsupported instructions.
+ "-march=armv8-a",
],
},
},
@@ -177,11 +178,10 @@
],
// Currently, only microdroid, Ravenwood, and cf system image can refer to system-build.prop
visibility: [
- "//build/make/target/product/generic",
- "//build/make/target/product/gsi",
"//build/soong/fsgen",
"//packages/modules/Virtualization/build/microdroid",
"//frameworks/base/ravenwood",
+ "//visibility:any_system_partition",
],
}
diff --git a/aconfig/Android.bp b/aconfig/Android.bp
index 402cf16..33e04a4 100644
--- a/aconfig/Android.bp
+++ b/aconfig/Android.bp
@@ -17,6 +17,7 @@
"aconfig_values.go",
"aconfig_value_set.go",
"all_aconfig_declarations.go",
+ "all_aconfig_declarations_extension.go",
"exported_java_aconfig_library.go",
"init.go",
"testing.go",
@@ -25,7 +26,24 @@
"aconfig_declarations_test.go",
"aconfig_values_test.go",
"aconfig_value_set_test.go",
- "all_aconfig_declarations_test.go",
+ "all_aconfig_declarations_extension_test.go",
],
pluginFor: ["soong_build"],
}
+
+// All FlaggedApi flags associated with platform API.
+// By default this uses the platform APIs associated with android.jar
+// but other verticals/platforms can override via soong config setting.
+all_aconfig_declarations {
+ name: "all_aconfig_declarations",
+ visibility: [
+ "//vendor:__subpackages__", // for vendor extensions
+ ],
+ api_signature_files: [
+ ":frameworks-base-api-current.txt",
+ ":frameworks-base-api-system-current.txt",
+ ":frameworks-base-api-system-server-current.txt",
+ ":frameworks-base-api-module-lib-current.txt",
+ ],
+ finalized_flags_file: ":latest-finalized-flags",
+}
diff --git a/aconfig/aconfig_declarations_test.go b/aconfig/aconfig_declarations_test.go
index e89cd31..c39008b 100644
--- a/aconfig/aconfig_declarations_test.go
+++ b/aconfig/aconfig_declarations_test.go
@@ -37,7 +37,7 @@
`
result := runTest(t, android.FixtureExpectsNoErrors, bp)
- module := result.ModuleForTests("module_name", "").Module().(*DeclarationsModule)
+ module := result.ModuleForTests(t, "module_name", "").Module().(*DeclarationsModule)
// Check that the provider has the right contents
depData, _ := android.OtherModuleProvider(result, module, android.AconfigDeclarationsProviderKey)
@@ -66,7 +66,7 @@
`
result := runTest(t, android.FixtureExpectsNoErrors, bp)
- module := result.ModuleForTests("module_name", "").Module().(*DeclarationsModule)
+ module := result.ModuleForTests(t, "module_name", "").Module().(*DeclarationsModule)
depData, _ := android.OtherModuleProvider(result, module, android.AconfigDeclarationsProviderKey)
android.AssertBoolEquals(t, "exportable", depData.Exportable, false)
}
@@ -84,7 +84,7 @@
`
result := runTest(t, android.FixtureExpectsNoErrors, bp)
- module := result.ModuleForTests("module_name", "")
+ module := result.ModuleForTests(t, "module_name", "")
rule := module.Rule("aconfig")
android.AssertStringEquals(t, "rule must contain container", rule.Args["container"], "--container com.android.foo")
}
@@ -204,7 +204,7 @@
fixture = fixture.ExtendWithErrorHandler(test.errorHandler)
}
result := fixture.RunTestWithBp(t, test.bp)
- module := result.ModuleForTests("module_name", "").Module().(*DeclarationsModule)
+ module := result.ModuleForTests(t, "module_name", "").Module().(*DeclarationsModule)
depData, _ := android.OtherModuleProvider(result, module, android.AconfigReleaseDeclarationsProviderKey)
expectedKeys := []string{""}
for _, rc := range strings.Split(test.buildFlags["RELEASE_ACONFIG_EXTRA_RELEASE_CONFIGS"], " ") {
diff --git a/aconfig/aconfig_value_set_test.go b/aconfig/aconfig_value_set_test.go
index 3b7281e..1f04244 100644
--- a/aconfig/aconfig_value_set_test.go
+++ b/aconfig/aconfig_value_set_test.go
@@ -37,7 +37,7 @@
`
result := runTest(t, android.FixtureExpectsNoErrors, bp)
- module := result.ModuleForTests("module_name", "").Module().(*ValueSetModule)
+ module := result.ModuleForTests(t, "module_name", "").Module().(*ValueSetModule)
// Check that the provider has the right contents
depData, _ := android.OtherModuleProvider(result, module, valueSetProviderKey)
@@ -88,7 +88,7 @@
checkModuleHasDependency := func(name, variant, dep string) bool {
t.Helper()
- module := result.ModuleForTests(name, variant).Module()
+ module := result.ModuleForTests(t, name, variant).Module()
depFound := false
result.VisitDirectDeps(module, func(m blueprint.Module) {
if m.Name() == dep {
diff --git a/aconfig/aconfig_values_test.go b/aconfig/aconfig_values_test.go
index ddbea57..0bec14b 100644
--- a/aconfig/aconfig_values_test.go
+++ b/aconfig/aconfig_values_test.go
@@ -30,7 +30,7 @@
`
result := runTest(t, android.FixtureExpectsNoErrors, bp)
- module := result.ModuleForTests("module_name", "").Module().(*ValuesModule)
+ module := result.ModuleForTests(t, "module_name", "").Module().(*ValuesModule)
// Check that the provider has the right contents
depData, _ := android.OtherModuleProvider(result, module, valuesProviderKey)
diff --git a/aconfig/all_aconfig_declarations.go b/aconfig/all_aconfig_declarations.go
index 3262493..3d07e16 100644
--- a/aconfig/all_aconfig_declarations.go
+++ b/aconfig/all_aconfig_declarations.go
@@ -19,6 +19,9 @@
"slices"
"android/soong/android"
+
+ "github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
)
// A singleton module that collects all of the aconfig flags declared in the
@@ -28,17 +31,36 @@
// Note that this is ALL aconfig_declarations modules present in the tree, not just
// ones that are relevant to the product currently being built, so that that infra
// doesn't need to pull from multiple builds and merge them.
-func AllAconfigDeclarationsFactory() android.Singleton {
- return &allAconfigDeclarationsSingleton{releaseMap: make(map[string]allAconfigReleaseDeclarationsSingleton)}
+func AllAconfigDeclarationsFactory() android.SingletonModule {
+ module := &allAconfigDeclarationsSingleton{releaseMap: make(map[string]allAconfigReleaseDeclarationsSingleton)}
+ module.AddProperties(&module.properties)
+ android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
+ return module
}
+type allAconfigDeclarationsInfo struct {
+ parsedFlagsFile android.Path
+}
+
+var allAconfigDeclarationsInfoProvider = blueprint.NewProvider[allAconfigDeclarationsInfo]()
+
type allAconfigReleaseDeclarationsSingleton struct {
intermediateBinaryProtoPath android.OutputPath
intermediateTextProtoPath android.OutputPath
}
+type ApiSurfaceContributorProperties struct {
+ Api_signature_files proptools.Configurable[[]string] `android:"arch_variant,path"`
+ Finalized_flags_file string `android:"arch_variant,path"`
+}
+
type allAconfigDeclarationsSingleton struct {
+ android.SingletonModuleBase
+
releaseMap map[string]allAconfigReleaseDeclarationsSingleton
+ properties ApiSurfaceContributorProperties
+
+ finalizedFlags android.OutputPath
}
func (this *allAconfigDeclarationsSingleton) sortedConfigNames() []string {
@@ -50,7 +72,41 @@
return names
}
-func (this *allAconfigDeclarationsSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+func GenerateFinalizedFlagsForApiSurface(ctx android.ModuleContext, outputPath android.WritablePath,
+ parsedFlagsFile android.Path, apiSurface ApiSurfaceContributorProperties) {
+
+ apiSignatureFiles := android.Paths{}
+ for _, apiSignatureFile := range apiSurface.Api_signature_files.GetOrDefault(ctx, nil) {
+ if path := android.PathForModuleSrc(ctx, apiSignatureFile); path != nil {
+ apiSignatureFiles = append(apiSignatureFiles, path)
+ }
+ }
+ finalizedFlagsFile := android.PathForModuleSrc(ctx, apiSurface.Finalized_flags_file)
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: RecordFinalizedFlagsRule,
+ Inputs: append(apiSignatureFiles, finalizedFlagsFile, parsedFlagsFile),
+ Output: outputPath,
+ Args: map[string]string{
+ "api_signature_files": android.JoinPathsWithPrefix(apiSignatureFiles, "--api-signature-file "),
+ "finalized_flags_file": "--finalized-flags-file " + finalizedFlagsFile.String(),
+ "parsed_flags_file": "--parsed-flags-file " + parsedFlagsFile.String(),
+ },
+ })
+}
+
+func (this *allAconfigDeclarationsSingleton) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ parsedFlagsFile := android.PathForIntermediates(ctx, "all_aconfig_declarations.pb")
+ this.finalizedFlags = android.PathForIntermediates(ctx, "finalized-flags.txt")
+ GenerateFinalizedFlagsForApiSurface(ctx, this.finalizedFlags, parsedFlagsFile, this.properties)
+ ctx.Phony("all_aconfig_declarations", this.finalizedFlags)
+
+ android.SetProvider(ctx, allAconfigDeclarationsInfoProvider, allAconfigDeclarationsInfo{
+ parsedFlagsFile: parsedFlagsFile,
+ })
+}
+
+func (this *allAconfigDeclarationsSingleton) GenerateSingletonBuildActions(ctx android.SingletonContext) {
for _, rcName := range append([]string{""}, ctx.Config().ReleaseAconfigExtraReleaseConfigs()...) {
// Find all of the aconfig_declarations modules
var packages = make(map[string]int)
@@ -106,9 +162,7 @@
})
ctx.Phony("all_aconfig_declarations_textproto", this.releaseMap[rcName].intermediateTextProtoPath)
}
-}
-func (this *allAconfigDeclarationsSingleton) MakeVars(ctx android.MakeVarsContext) {
for _, rcName := range this.sortedConfigNames() {
ctx.DistForGoal("droid", this.releaseMap[rcName].intermediateBinaryProtoPath)
for _, goal := range []string{"docs", "droid", "sdk"} {
@@ -116,4 +170,5 @@
ctx.DistForGoalWithFilename(goal, this.releaseMap[rcName].intermediateTextProtoPath, assembleFileName(rcName, "flags.textproto"))
}
}
+ ctx.DistForGoalWithFilename("sdk", this.finalizedFlags, "finalized-flags.txt")
}
diff --git a/aconfig/all_aconfig_declarations_extension.go b/aconfig/all_aconfig_declarations_extension.go
new file mode 100644
index 0000000..d5a4588
--- /dev/null
+++ b/aconfig/all_aconfig_declarations_extension.go
@@ -0,0 +1,88 @@
+// Copyright 2025 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 aconfig
+
+import (
+ "android/soong/android"
+ "path"
+
+ "github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
+)
+
+func AllAconfigDeclarationsExtensionFactory() android.Module {
+ module := &allAconfigDeclarationsExtension{}
+ module.AddProperties(&module.properties)
+ android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
+ return module
+}
+
+type allAconfigDeclarationsExtensionProperties struct {
+ // all_aconfig_declarations module that this module extends. Defaults to
+ // all_aconfig_declarations.
+ Base *string
+
+ // Directory where the dist artifact should be placed in.
+ Dist_dir *string
+
+ ApiSurfaceContributorProperties
+}
+
+type allAconfigDeclarationsExtension struct {
+ android.ModuleBase
+
+ properties allAconfigDeclarationsExtensionProperties
+
+ finalizedFlags android.ModuleOutPath
+}
+
+type allAconfigDeclarationsDependencyTagStruct struct {
+ blueprint.BaseDependencyTag
+}
+
+var allAconfigDeclarationsDependencyTag allAconfigDeclarationsDependencyTagStruct
+
+func (ext *allAconfigDeclarationsExtension) DepsMutator(ctx android.BottomUpMutatorContext) {
+ ctx.AddDependency(ctx.Module(), allAconfigDeclarationsDependencyTag, proptools.StringDefault(ext.properties.Base, "all_aconfig_declarations"))
+}
+
+func (ext *allAconfigDeclarationsExtension) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+
+ var parsedFlagsFile android.Path
+ ctx.VisitDirectDepsProxyWithTag(allAconfigDeclarationsDependencyTag, func(proxy android.ModuleProxy) {
+ if info, ok := android.OtherModuleProvider(ctx, proxy, allAconfigDeclarationsInfoProvider); ok {
+ parsedFlagsFile = info.parsedFlagsFile
+ } else {
+ ctx.PropertyErrorf("base", "base must provide allAconfigDeclarationsInfo")
+ }
+ })
+
+ ext.finalizedFlags = android.PathForModuleOut(ctx, "finalized-flags.txt")
+
+ GenerateFinalizedFlagsForApiSurface(ctx,
+ ext.finalizedFlags,
+ parsedFlagsFile,
+ ext.properties.ApiSurfaceContributorProperties,
+ )
+
+ ctx.Phony(ctx.ModuleName(), ext.finalizedFlags)
+
+ ctx.DistForGoalWithFilename("sdk", ext.finalizedFlags, path.Join(proptools.String(ext.properties.Dist_dir), "finalized-flags.txt"))
+
+ // This module must not set any provider or call `ctx.SetOutputFiles`!
+ // This module is only used to depend on the singleton module all_aconfig_declarations and
+ // generate the custom finalized-flags.txt file in dist builds, and should not be depended
+ // by other modules.
+}
diff --git a/aconfig/all_aconfig_declarations_extension_test.go b/aconfig/all_aconfig_declarations_extension_test.go
new file mode 100644
index 0000000..5bd99d0
--- /dev/null
+++ b/aconfig/all_aconfig_declarations_extension_test.go
@@ -0,0 +1,50 @@
+// Copyright 2025 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 aconfig
+
+import (
+ "strings"
+ "testing"
+
+ "android/soong/android"
+)
+
+func TestAllAconfigDeclarationsExtension(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithAconfigBuildComponents,
+ android.FixtureMergeMockFs(
+ android.MockFS{
+ "a.txt": nil,
+ "flags.txt": nil,
+ },
+ ),
+ ).RunTestWithBp(t, `
+ all_aconfig_declarations {
+ name: "all_aconfig_declarations",
+ }
+
+ all_aconfig_declarations_extension {
+ name: "custom_aconfig_declarations",
+ base: "all_aconfig_declarations",
+ api_signature_files: [
+ "a.txt",
+ ],
+ finalized_flags_file: "flags.txt",
+ }
+ `)
+
+ finalizedFlags := result.ModuleForTests(t, "custom_aconfig_declarations", "").Output("finalized-flags.txt")
+ android.AssertStringContainsEquals(t, "must depend on all_aconfig_declarations", strings.Join(finalizedFlags.Inputs.Strings(), " "), "all_aconfig_declarations.pb", true)
+}
diff --git a/aconfig/all_aconfig_declarations_test.go b/aconfig/all_aconfig_declarations_test.go
deleted file mode 100644
index 0b2021e..0000000
--- a/aconfig/all_aconfig_declarations_test.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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 aconfig
-
-import (
- "testing"
-
- "android/soong/android"
-)
-
-func TestTwoAconfigDeclarationsPerPackage(t *testing.T) {
- bp := `
- aconfig_declarations {
- name: "module_name.foo",
- package: "com.example.package",
- container: "com.android.foo",
- srcs: [
- "foo.aconfig",
- ],
- }
-
- aconfig_declarations {
- name: "module_name.bar",
- package: "com.example.package",
- container: "com.android.foo",
- srcs: [
- "bar.aconfig",
- ],
- }
- `
- errMsg := "Only one aconfig_declarations allowed for each package."
- android.GroupFixturePreparers(
- PrepareForTestWithAconfigBuildComponents).
- ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(errMsg)).
- RunTestWithBp(t, bp)
-}
diff --git a/aconfig/build_flags/build_flags_singleton.go b/aconfig/build_flags/build_flags_singleton.go
index 3b40755..e375d9c 100644
--- a/aconfig/build_flags/build_flags_singleton.go
+++ b/aconfig/build_flags/build_flags_singleton.go
@@ -16,6 +16,7 @@
import (
"android/soong/android"
+ "fmt"
)
// A singleton module that collects all of the build flags declared in the
@@ -110,9 +111,7 @@
this.configsBinaryProtoPath,
this.configsTextProtoPath,
)
-}
-func (this *allBuildFlagDeclarationsSingleton) MakeVars(ctx android.MakeVarsContext) {
ctx.DistForGoal("droid", this.flagsBinaryProtoPath)
for _, goal := range []string{"docs", "droid", "sdk", "release_config_metadata"} {
ctx.DistForGoalWithFilename(goal, this.flagsBinaryProtoPath, "build_flags/all_flags.pb")
@@ -120,4 +119,26 @@
ctx.DistForGoalWithFilename(goal, this.configsBinaryProtoPath, "build_flags/all_release_config_contributions.pb")
ctx.DistForGoalWithFilename(goal, this.configsTextProtoPath, "build_flags/all_release_config_contributions.textproto")
}
+
+ if ctx.Config().HasDeviceProduct() {
+ flagsDir := android.PathForOutput(ctx, "release-config")
+ baseAllRelease := fmt.Sprintf("all_release_configs-%s", ctx.Config().DeviceProduct())
+
+ distAllReleaseConfigsArtifact := func(ext string) {
+ ctx.DistForGoalWithFilename(
+ "droid",
+ flagsDir.Join(ctx, fmt.Sprintf("%s.%s", baseAllRelease, ext)),
+ fmt.Sprintf("build_flags/all_release_configs.%s", ext),
+ )
+ }
+
+ distAllReleaseConfigsArtifact("pb")
+ distAllReleaseConfigsArtifact("textproto")
+ distAllReleaseConfigsArtifact("json")
+ ctx.DistForGoalWithFilename(
+ "droid",
+ flagsDir.Join(ctx, fmt.Sprintf("inheritance_graph-%s.dot", ctx.Config().DeviceProduct())),
+ fmt.Sprintf("build_flags/inheritance_graph-%s.dot", ctx.Config().DeviceProduct()),
+ )
+ }
}
diff --git a/aconfig/codegen/aconfig_declarations_group_test.go b/aconfig/codegen/aconfig_declarations_group_test.go
index ef954ce..c822ef8 100644
--- a/aconfig/codegen/aconfig_declarations_group_test.go
+++ b/aconfig/codegen/aconfig_declarations_group_test.go
@@ -74,7 +74,7 @@
// Check if srcjar files are correctly passed to the reverse dependency of
// aconfig_declarations_group module
- bazModule := result.ModuleForTests("baz", "android_common")
+ bazModule := result.ModuleForTests(t, "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")
diff --git a/aconfig/codegen/cc_aconfig_library.go b/aconfig/codegen/cc_aconfig_library.go
index f9c7b8c..ce37456 100644
--- a/aconfig/codegen/cc_aconfig_library.go
+++ b/aconfig/codegen/cc_aconfig_library.go
@@ -22,7 +22,6 @@
"github.com/google/blueprint/proptools"
"fmt"
- "strconv"
"strings"
)
@@ -32,8 +31,6 @@
var ccDeclarationsTag = ccDeclarationsTagType{}
-const baseLibDep = "server_configurable_flags"
-
const libBaseDep = "libbase"
const libLogDep = "liblog"
const libAconfigStorageReadApiCcDep = "libaconfig_storage_read_api_cc"
@@ -86,15 +83,11 @@
// Add a dependency for the aconfig flags base library if it is not forced read only
if mode != "force-read-only" {
- deps.SharedLibs = append(deps.SharedLibs, baseLibDep)
-
+ deps.SharedLibs = append(deps.SharedLibs, libAconfigStorageReadApiCcDep)
+ deps.SharedLibs = append(deps.SharedLibs, libBaseDep)
+ deps.SharedLibs = append(deps.SharedLibs, libLogDep)
}
- // TODO: after storage migration is over, don't add these in force-read-only-mode.
- deps.SharedLibs = append(deps.SharedLibs, libAconfigStorageReadApiCcDep)
- deps.SharedLibs = append(deps.SharedLibs, libBaseDep)
- deps.SharedLibs = append(deps.SharedLibs, libLogDep)
-
// TODO: It'd be really nice if we could reexport this library and not make everyone do it.
return deps
@@ -156,7 +149,6 @@
Args: map[string]string{
"gendir": this.generatedDir.String(),
"mode": mode,
- "debug": strconv.FormatBool(ctx.Config().ReleaseReadFromNewStorage()),
},
})
diff --git a/aconfig/codegen/cc_aconfig_library_test.go b/aconfig/codegen/cc_aconfig_library_test.go
index c308ed4..5cb3f8b 100644
--- a/aconfig/codegen/cc_aconfig_library_test.go
+++ b/aconfig/codegen/cc_aconfig_library_test.go
@@ -81,7 +81,7 @@
}
`, bpMode))
- module := result.ModuleForTests("my_cc_aconfig_library", "android_arm64_armv8-a_shared")
+ module := result.ModuleForTests(t, "my_cc_aconfig_library", "android_arm64_armv8-a_shared")
rule := module.Rule("cc_aconfig_library")
android.AssertStringEquals(t, "rule must contain test mode", rule.Args["mode"], ruleMode)
}
@@ -209,7 +209,7 @@
cc.PrepareForTestWithCcDefaultModules).
ExtendWithErrorHandler(android.FixtureExpectsNoErrors).RunTestWithBp(t, bp)
- module := result.ModuleForTests("my_cc_library", "android_vendor_arm64_armv8-a_shared").Module()
+ module := result.ModuleForTests(t, "my_cc_library", "android_vendor_arm64_armv8-a_shared").Module()
entry := android.AndroidMkInfoForTest(t, result.TestContext, module).PrimaryInfo
@@ -254,13 +254,13 @@
}
`))
- module := result.ModuleForTests("my_cc_aconfig_library", "android_arm64_armv8-a_shared").Module()
- dependOnBaseLib := false
+ module := result.ModuleForTests(t, "my_cc_aconfig_library", "android_arm64_armv8-a_shared").Module()
+ dependOnReadLib := false
result.VisitDirectDeps(module, func(dep blueprint.Module) {
- if dep.Name() == baseLibDep {
- dependOnBaseLib = true
+ if dep.Name() == libAconfigStorageReadApiCcDep {
+ dependOnReadLib = true
}
})
- android.AssertBoolEquals(t, "should not have dependency on server_configuriable_flags",
- dependOnBaseLib, false)
+ android.AssertBoolEquals(t, "should not have dependency on libaconfig_storage_read_api_cc",
+ dependOnReadLib, false)
}
diff --git a/aconfig/codegen/init.go b/aconfig/codegen/init.go
index 34fdca3..325e367 100644
--- a/aconfig/codegen/init.go
+++ b/aconfig/codegen/init.go
@@ -26,6 +26,7 @@
// For java_aconfig_library: Generate java library
javaRule = pctx.AndroidStaticRule("java_aconfig_library",
blueprint.RuleParams{
+ // LINT.IfChange
Command: `rm -rf ${out}.tmp` +
` && mkdir -p ${out}.tmp` +
` && ${aconfig} create-java-lib` +
@@ -34,14 +35,16 @@
` --out ${out}.tmp` +
` --allow-instrumentation ${debug}` +
` --new-exported ${new_exported}` +
+ ` --check-api-level ${check_api_level}` +
` && $soong_zip -write_if_changed -jar -o ${out} -C ${out}.tmp -D ${out}.tmp` +
` && rm -rf ${out}.tmp`,
+ // LINT.ThenChange(/aconfig/init.go)
CommandDeps: []string{
"$aconfig",
"$soong_zip",
},
Restat: true,
- }, "mode", "debug", "new_exported")
+ }, "mode", "debug", "new_exported", "check_api_level")
// For cc_aconfig_library: Generate C++ library
cppRule = pctx.AndroidStaticRule("cc_aconfig_library",
@@ -51,12 +54,11 @@
` && ${aconfig} create-cpp-lib` +
` --mode ${mode}` +
` --cache ${in}` +
- ` --out ${gendir}` +
- ` --allow-instrumentation ${debug}`,
+ ` --out ${gendir}`,
CommandDeps: []string{
"$aconfig",
},
- }, "gendir", "mode", "debug")
+ }, "gendir", "mode")
// For rust_aconfig_library: Generate Rust library
rustRule = pctx.AndroidStaticRule("rust_aconfig_library",
@@ -66,12 +68,11 @@
` && ${aconfig} create-rust-lib` +
` --mode ${mode}` +
` --cache ${in}` +
- ` --allow-instrumentation ${debug}` +
` --out ${gendir}`,
CommandDeps: []string{
"$aconfig",
},
- }, "gendir", "mode", "debug")
+ }, "gendir", "mode")
)
func init() {
diff --git a/aconfig/codegen/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go
index cd1767b..7b9da8e 100644
--- a/aconfig/codegen/java_aconfig_library.go
+++ b/aconfig/codegen/java_aconfig_library.go
@@ -112,9 +112,10 @@
Output: srcJarPath,
Description: "aconfig.srcjar",
Args: map[string]string{
- "mode": mode,
- "debug": strconv.FormatBool(ctx.Config().ReleaseReadFromNewStorage()),
- "new_exported": strconv.FormatBool(newExported),
+ "mode": mode,
+ "debug": strconv.FormatBool(ctx.Config().ReleaseReadFromNewStorage()),
+ "new_exported": strconv.FormatBool(newExported),
+ "check_api_level": strconv.FormatBool(ctx.Config().ReleaseAconfigCheckApiLevel()),
},
})
diff --git a/aconfig/codegen/java_aconfig_library_test.go b/aconfig/codegen/java_aconfig_library_test.go
index d8372f3..8854369 100644
--- a/aconfig/codegen/java_aconfig_library_test.go
+++ b/aconfig/codegen/java_aconfig_library_test.go
@@ -57,7 +57,7 @@
}
`)
- module := result.ModuleForTests("my_module", "android_common").Module()
+ module := result.ModuleForTests(t, "my_module", "android_common").Module()
entry := android.AndroidMkEntriesForTest(t, result.TestContext, module)[0]
@@ -189,7 +189,7 @@
}
`, bpMode))
- module := result.ModuleForTests("my_java_aconfig_library", "android_common")
+ module := result.ModuleForTests(t, "my_java_aconfig_library", "android_common")
rule := module.Rule("java_aconfig_library")
android.AssertStringEquals(t, "rule must contain test mode", rule.Args["mode"], ruleMode)
}
@@ -282,7 +282,7 @@
}
`)
- module := result.ModuleForTests("my_module", "android_common").Module()
+ module := result.ModuleForTests(t, "my_module", "android_common").Module()
entry := android.AndroidMkEntriesForTest(t, result.TestContext, module)[0]
makeVar := entry.EntryMap["LOCAL_ACONFIG_FILES"]
android.EnsureListContainsSuffix(t, makeVar, "my_aconfig_declarations_foo/intermediate.pb")
diff --git a/aconfig/codegen/rust_aconfig_library.go b/aconfig/codegen/rust_aconfig_library.go
index 4b896c3..53818c2 100644
--- a/aconfig/codegen/rust_aconfig_library.go
+++ b/aconfig/codegen/rust_aconfig_library.go
@@ -2,7 +2,6 @@
import (
"fmt"
- "strconv"
"android/soong/android"
"android/soong/rust"
@@ -83,7 +82,6 @@
Args: map[string]string{
"gendir": generatedDir.String(),
"mode": mode,
- "debug": strconv.FormatBool(ctx.Config().ReleaseReadFromNewStorage()),
},
})
a.BaseSourceProvider.OutputFiles = android.Paths{generatedSource}
@@ -102,7 +100,6 @@
func (a *aconfigDecorator) SourceProviderDeps(ctx rust.DepsContext, deps rust.Deps) rust.Deps {
deps = a.BaseSourceProvider.SourceProviderDeps(ctx, deps)
deps.Rustlibs = append(deps.Rustlibs, "libaconfig_storage_read_api")
- deps.Rustlibs = append(deps.Rustlibs, "libflags_rust")
deps.Rustlibs = append(deps.Rustlibs, "liblazy_static")
deps.Rustlibs = append(deps.Rustlibs, "liblogger")
deps.Rustlibs = append(deps.Rustlibs, "liblog_rust")
diff --git a/aconfig/codegen/rust_aconfig_library_test.go b/aconfig/codegen/rust_aconfig_library_test.go
index 523b464..6701021 100644
--- a/aconfig/codegen/rust_aconfig_library_test.go
+++ b/aconfig/codegen/rust_aconfig_library_test.go
@@ -57,13 +57,13 @@
}
`))
- sourceVariant := result.ModuleForTests("libmy_rust_aconfig_library", "android_arm64_armv8-a_source")
+ sourceVariant := result.ModuleForTests(t, "libmy_rust_aconfig_library", "android_arm64_armv8-a_source")
rule := sourceVariant.Rule("rust_aconfig_library")
android.AssertStringEquals(t, "rule must contain production mode", rule.Args["mode"], "production")
- dylibVariant := result.ModuleForTests("libmy_rust_aconfig_library", "android_arm64_armv8-a_dylib")
- rlibRlibStdVariant := result.ModuleForTests("libmy_rust_aconfig_library", "android_arm64_armv8-a_rlib_rlib-std")
- rlibDylibStdVariant := result.ModuleForTests("libmy_rust_aconfig_library", "android_arm64_armv8-a_rlib_dylib-std")
+ dylibVariant := result.ModuleForTests(t, "libmy_rust_aconfig_library", "android_arm64_armv8-a_dylib")
+ rlibRlibStdVariant := result.ModuleForTests(t, "libmy_rust_aconfig_library", "android_arm64_armv8-a_rlib_rlib-std")
+ rlibDylibStdVariant := result.ModuleForTests(t, "libmy_rust_aconfig_library", "android_arm64_armv8-a_rlib_dylib-std")
variants := []android.TestingModule{
dylibVariant,
@@ -143,7 +143,7 @@
}
`, bpMode))
- module := result.ModuleForTests("libmy_rust_aconfig_library", "android_arm64_armv8-a_source")
+ module := result.ModuleForTests(t, "libmy_rust_aconfig_library", "android_arm64_armv8-a_source")
rule := module.Rule("rust_aconfig_library")
android.AssertStringEquals(t, "rule must contain test mode", rule.Args["mode"], ruleMode)
}
diff --git a/aconfig/exported_java_aconfig_library.go b/aconfig/exported_java_aconfig_library.go
index f7e6dcf..63d824a 100644
--- a/aconfig/exported_java_aconfig_library.go
+++ b/aconfig/exported_java_aconfig_library.go
@@ -59,11 +59,9 @@
"cache_files": android.JoinPathsWithPrefix(cacheFiles, " "),
"use_new_storage": strconv.FormatBool(newStorage),
"use_new_exported": strconv.FormatBool(newExported),
+ "check_api_level": strconv.FormatBool(ctx.Config().ReleaseAconfigCheckApiLevel()),
},
})
ctx.Phony("exported_java_aconfig_library", this.intermediatePath)
-}
-
-func (this *exportedJavaDeclarationsLibrarySingleton) MakeVars(ctx android.MakeVarsContext) {
ctx.DistForGoalWithFilename("sdk", this.intermediatePath, "android-flags.jar")
}
diff --git a/aconfig/init.go b/aconfig/init.go
index ab6ee46..b2fe5a3 100644
--- a/aconfig/init.go
+++ b/aconfig/init.go
@@ -70,6 +70,13 @@
"${aconfig}",
},
}, "cache_files")
+ RecordFinalizedFlagsRule = pctx.AndroidStaticRule("RecordFinalizedFlagsRule",
+ blueprint.RuleParams{
+ Command: `${record-finalized-flags} ${parsed_flags_file} ${finalized_flags_file} ${api_signature_files} > ${out}`,
+ CommandDeps: []string{
+ "${record-finalized-flags}",
+ },
+ }, "api_signature_files", "finalized_flags_file", "parsed_flags_file")
CreateStorageRule = pctx.AndroidStaticRule("aconfig_create_storage",
blueprint.RuleParams{
@@ -88,6 +95,7 @@
// exported flags (only). Finally collect all generated code
// into the ${out} JAR file.
blueprint.RuleParams{
+ // LINT.IfChange
Command: `rm -rf ${out}.tmp` +
`&& for cache in ${cache_files}; do ` +
` if [ -n "$$(${aconfig} dump-cache --dedup --cache $$cache --filter=is_exported:true --format='{fully_qualified_name}')" ]; then ` +
@@ -96,28 +104,33 @@
` --mode=exported` +
` --allow-instrumentation ${use_new_storage}` +
` --new-exported ${use_new_exported}` +
+ ` --single-exported-file true` +
+ ` --check-api-level ${check_api_level}` +
` --out ${out}.tmp; ` +
` fi ` +
`done` +
`&& $soong_zip -write_if_changed -jar -o ${out} -C ${out}.tmp -D ${out}.tmp` +
`&& rm -rf ${out}.tmp`,
+ // LINT.ThenChange(/aconfig/codegen/init.go)
CommandDeps: []string{
"$aconfig",
"$soong_zip",
},
- }, "cache_files", "use_new_storage", "use_new_exported")
+ }, "cache_files", "use_new_storage", "use_new_exported", "check_api_level")
)
func init() {
RegisterBuildComponents(android.InitRegistrationContext)
pctx.HostBinToolVariable("aconfig", "aconfig")
pctx.HostBinToolVariable("soong_zip", "soong_zip")
+ pctx.HostBinToolVariable("record-finalized-flags", "record-finalized-flags")
}
func RegisterBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("aconfig_declarations", DeclarationsFactory)
ctx.RegisterModuleType("aconfig_values", ValuesFactory)
ctx.RegisterModuleType("aconfig_value_set", ValueSetFactory)
- ctx.RegisterParallelSingletonType("all_aconfig_declarations", AllAconfigDeclarationsFactory)
+ ctx.RegisterSingletonModuleType("all_aconfig_declarations", AllAconfigDeclarationsFactory)
ctx.RegisterParallelSingletonType("exported_java_aconfig_library", ExportedJavaDeclarationsLibraryFactory)
+ ctx.RegisterModuleType("all_aconfig_declarations_extension", AllAconfigDeclarationsExtensionFactory)
}
diff --git a/aidl_library/aidl_library_test.go b/aidl_library/aidl_library_test.go
index 1660456..63a08b9 100644
--- a/aidl_library/aidl_library_test.go
+++ b/aidl_library/aidl_library_test.go
@@ -46,7 +46,7 @@
}.AddToFixture(),
).RunTest(t).TestContext
- foo := ctx.ModuleForTests("foo", "").Module().(*AidlLibrary)
+ foo := ctx.ModuleForTests(t, "foo", "").Module().(*AidlLibrary)
actualInfo, _ := android.OtherModuleProvider(ctx, foo, AidlLibraryProvider)
android.AssertArrayString(
@@ -95,7 +95,7 @@
}.AddToFixture(),
).RunTest(t).TestContext
- foo := ctx.ModuleForTests("foo", "").Module().(*AidlLibrary)
+ foo := ctx.ModuleForTests(t, "foo", "").Module().(*AidlLibrary)
actualInfo, _ := android.OtherModuleProvider(ctx, foo, AidlLibraryProvider)
android.AssertArrayString(
diff --git a/android/Android.bp b/android/Android.bp
index d27a8fa..1cc7ffe 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -11,6 +11,7 @@
"blueprint-depset",
"blueprint-gobtools",
"blueprint-metrics",
+ "blueprint-pool",
"sbox_proto",
"soong",
"soong-android_team_proto",
@@ -111,6 +112,7 @@
"soong_config_modules.go",
"team.go",
"test_asserts.go",
+ "test_mapping_zip.go",
"test_suites.go",
"testing.go",
"transition.go",
@@ -125,7 +127,6 @@
"all_teams_test.go",
"android_test.go",
"androidmk_test.go",
- "apex_test.go",
"arch_test.go",
"blueprint_e2e_test.go",
"build_prop_test.go",
@@ -141,6 +142,7 @@
"license_kind_test.go",
"license_test.go",
"licenses_test.go",
+ "makevars_test.go",
"module_test.go",
"mutator_test.go",
"namespace_test.go",
diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go
index b698d24..205b855 100644
--- a/android/aconfig_providers.go
+++ b/android/aconfig_providers.go
@@ -136,7 +136,7 @@
AconfigFiles: mergedAconfigFiles,
ModeInfos: mergedModeInfos,
})
- ctx.setAconfigPaths(getAconfigFilePaths(ctx.Module().base(), mergedAconfigFiles))
+ ctx.setAconfigPaths(getAconfigFilePaths(getContainer(ctx.Module()), mergedAconfigFiles))
}
}
@@ -147,7 +147,8 @@
return
}
data.Extra = append(data.Extra, func(w io.Writer, outputFile Path) {
- AndroidMkEmitAssignList(w, "LOCAL_ACONFIG_FILES", getAconfigFilePaths(mod.base(), info.AconfigFiles).Strings())
+ AndroidMkEmitAssignList(w, "LOCAL_ACONFIG_FILES", getAconfigFilePaths(
+ getContainerUsingProviders(ctx, mod), info.AconfigFiles).Strings())
})
// If there is a Custom writer, it needs to support this provider.
if data.Custom != nil {
@@ -179,24 +180,29 @@
// All of the files in the module potentially depend on the aconfig flag values.
for idx, _ := range *entries {
(*entries)[idx].ExtraEntries = append((*entries)[idx].ExtraEntries,
- func(ctx AndroidMkExtraEntriesContext, entries *AndroidMkEntries) {
- entries.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths(mod.base(), info.AconfigFiles))
+ func(_ AndroidMkExtraEntriesContext, entries *AndroidMkEntries) {
+ entries.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths(
+ getContainerUsingProviders(ctx, mod), info.AconfigFiles))
},
)
}
}
+// TODO(b/397766191): Change the signature to take ModuleProxy
+// Please only access the module's internal data through providers.
func aconfigUpdateAndroidMkInfos(ctx fillInEntriesContext, mod Module, infos *AndroidMkProviderInfo) {
info, ok := OtherModuleProvider(ctx, mod, AconfigPropagatingProviderKey)
if !ok || len(info.AconfigFiles) == 0 {
return
}
// All of the files in the module potentially depend on the aconfig flag values.
- infos.PrimaryInfo.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths(mod.base(), info.AconfigFiles))
+ infos.PrimaryInfo.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths(
+ getContainerUsingProviders(ctx, mod), info.AconfigFiles))
if len(infos.ExtraInfo) > 0 {
for _, ei := range (*infos).ExtraInfo {
- ei.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths(mod.base(), info.AconfigFiles))
+ ei.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths(
+ getContainerUsingProviders(ctx, mod), info.AconfigFiles))
}
}
}
@@ -224,19 +230,39 @@
return Paths{output}
}
-func getAconfigFilePaths(m *ModuleBase, aconfigFiles map[string]Paths) (paths Paths) {
- // TODO(b/311155208): The default container here should be system.
+func getContainer(m Module) string {
container := "system"
-
- if m.SocSpecific() {
+ base := m.base()
+ if base.SocSpecific() {
container = "vendor"
- } else if m.ProductSpecific() {
+ } else if base.ProductSpecific() {
container = "product"
- } else if m.SystemExtSpecific() {
+ } else if base.SystemExtSpecific() {
// system_ext and system partitions should be treated as one container
container = "system"
}
+ return container
+}
+
+// TODO(b/397766191): Change the signature to take ModuleProxy
+// Please only access the module's internal data through providers.
+func getContainerUsingProviders(ctx OtherModuleProviderContext, m Module) string {
+ container := "system"
+ commonInfo, _ := OtherModuleProvider(ctx, m, CommonModuleInfoKey)
+ if commonInfo.Vendor || commonInfo.Proprietary || commonInfo.SocSpecific {
+ container = "vendor"
+ } else if commonInfo.ProductSpecific {
+ container = "product"
+ } else if commonInfo.SystemExtSpecific {
+ // system_ext and system partitions should be treated as one container
+ container = "system"
+ }
+
+ return container
+}
+
+func getAconfigFilePaths(container string, aconfigFiles map[string]Paths) (paths Paths) {
paths = append(paths, aconfigFiles[container]...)
if container == "system" {
// TODO(b/311155208): Once the default container is system, we can drop this.
diff --git a/android/all_teams.go b/android/all_teams.go
index 01be396..3b20107 100644
--- a/android/all_teams.go
+++ b/android/all_teams.go
@@ -134,9 +134,6 @@
WriteFileRuleVerbatim(ctx, t.outputPath, string(data))
ctx.Phony("all_teams", t.outputPath)
-}
-
-func (t *allTeamsSingleton) MakeVars(ctx MakeVarsContext) {
ctx.DistForGoal("all_teams", t.outputPath)
}
diff --git a/android/all_teams_test.go b/android/all_teams_test.go
index fa8c048..3b200f6 100644
--- a/android/all_teams_test.go
+++ b/android/all_teams_test.go
@@ -131,7 +131,7 @@
func getTeamProtoOutput(t *testing.T, ctx *TestResult) *team_proto.AllTeams {
teams := new(team_proto.AllTeams)
- config := ctx.SingletonForTests("all_teams")
+ config := ctx.SingletonForTests(t, "all_teams")
allOutputs := config.AllOutputs()
protoPath := allOutputs[0]
diff --git a/android/android_info.go b/android/android_info.go
index 225c8f0..9a68d10 100644
--- a/android/android_info.go
+++ b/android/android_info.go
@@ -58,19 +58,17 @@
androidInfoTxtName := proptools.StringDefault(p.properties.Stem, ctx.ModuleName()+".txt")
androidInfoTxt := PathForModuleOut(ctx, androidInfoTxtName)
androidInfoProp := androidInfoTxt.ReplaceExtension(ctx, "prop")
- timestamp := PathForModuleOut(ctx, "timestamp")
if boardInfoFiles := PathsForModuleSrc(ctx, p.properties.Board_info_files); len(boardInfoFiles) > 0 {
ctx.Build(pctx, BuildParams{
- Rule: mergeAndRemoveComments,
- Inputs: boardInfoFiles,
- Output: androidInfoTxt,
- Validation: timestamp,
+ Rule: mergeAndRemoveComments,
+ Inputs: boardInfoFiles,
+ Output: androidInfoTxt,
})
} else if bootloaderBoardName := proptools.String(p.properties.Bootloader_board_name); bootloaderBoardName != "" {
- WriteFileRule(ctx, androidInfoTxt, "board="+bootloaderBoardName, timestamp)
+ WriteFileRule(ctx, androidInfoTxt, "board="+bootloaderBoardName)
} else {
- WriteFileRule(ctx, androidInfoTxt, "", timestamp)
+ WriteFileRule(ctx, androidInfoTxt, "")
}
// Create android_info.prop
@@ -82,18 +80,6 @@
ctx.SetOutputFiles(Paths{androidInfoProp}, "")
ctx.SetOutputFiles(Paths{androidInfoTxt}, ".txt")
-
- builder := NewRuleBuilder(pctx, ctx)
- builder.Command().Text("touch").Output(timestamp)
- if !ctx.Config().KatiEnabled() {
- cpPath := PathForModuleInPartitionInstall(ctx, "").Join(ctx, androidInfoTxtName)
- builder.Command().
- Text("rsync").
- Flag("-a").
- Input(androidInfoTxt).
- Text(cpPath.String())
- }
- builder.Build("copy_android_info", "Copy android-info.txt")
}
// android_info module generate a file named android-info.txt that contains various information
diff --git a/android/androidmk.go b/android/androidmk.go
index 87a93e3..d9d78f3 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -64,7 +64,6 @@
type AndroidMkData struct {
Class string
SubName string
- DistFiles TaggedDistFiles
OutputFile OptionalPath
Disabled bool
Include string
@@ -166,7 +165,7 @@
type androidMkExtraEntriesContext struct {
ctx fillInEntriesContext
- mod blueprint.Module
+ mod Module
}
func (a *androidMkExtraEntriesContext) Provider(provider blueprint.AnyProviderKey) (any, bool) {
@@ -333,9 +332,28 @@
dest string
}
+func (d *distCopy) String() string {
+ if len(d.dest) == 0 {
+ return d.from.String()
+ }
+ return fmt.Sprintf("%s:%s", d.from.String(), d.dest)
+}
+
+type distCopies []distCopy
+
+func (d *distCopies) Strings() (ret []string) {
+ if d == nil {
+ return
+ }
+ for _, dist := range *d {
+ ret = append(ret, dist.String())
+ }
+ return
+}
+
// Compute the contributions that the module makes to the dist.
-func (a *AndroidMkEntries) getDistContributions(mod blueprint.Module) *distContributions {
- amod := mod.(Module).base()
+func (a *AndroidMkEntries) getDistContributions(mod Module) *distContributions {
+ amod := mod.base()
name := amod.BaseModuleName()
// Collate the set of associated tag/paths available for copying to the dist.
@@ -372,7 +390,7 @@
// Collate the contributions this module makes to the dist.
distContributions := &distContributions{}
- if !exemptFromRequiredApplicableLicensesProperty(mod.(Module)) {
+ if !exemptFromRequiredApplicableLicensesProperty(mod) {
distContributions.licenseMetadataFile = info.LicenseMetadataFile
}
@@ -483,7 +501,7 @@
// Compute the list of Make strings to declare phony goals and dist-for-goals
// calls from the module's dist and dists properties.
-func (a *AndroidMkEntries) GetDistForGoals(mod blueprint.Module) []string {
+func (a *AndroidMkEntries) GetDistForGoals(mod Module) []string {
distContributions := a.getDistContributions(mod)
if distContributions == nil {
return nil
@@ -504,11 +522,10 @@
HasMutatorFinished(mutatorName string) bool
}
-func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) {
+func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod Module) {
a.entryContext = ctx
a.EntryMap = make(map[string][]string)
- amod := mod.(Module)
- base := amod.base()
+ base := mod.base()
name := base.BaseModuleName()
if a.OverrideName != "" {
name = a.OverrideName
@@ -517,10 +534,10 @@
if a.Include == "" {
a.Include = "$(BUILD_PREBUILT)"
}
- a.Required = append(a.Required, amod.RequiredModuleNames(ctx)...)
- a.Required = append(a.Required, amod.VintfFragmentModuleNames(ctx)...)
- a.Host_required = append(a.Host_required, amod.HostRequiredModuleNames()...)
- a.Target_required = append(a.Target_required, amod.TargetRequiredModuleNames()...)
+ a.Required = append(a.Required, mod.RequiredModuleNames(ctx)...)
+ a.Required = append(a.Required, mod.VintfFragmentModuleNames(ctx)...)
+ a.Host_required = append(a.Host_required, mod.HostRequiredModuleNames()...)
+ a.Target_required = append(a.Target_required, mod.TargetRequiredModuleNames()...)
for _, distString := range a.GetDistForGoals(mod) {
fmt.Fprintln(&a.header, distString)
@@ -536,7 +553,7 @@
a.AddStrings("LOCAL_REQUIRED_MODULES", a.Required...)
a.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...)
a.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...)
- a.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(amod))
+ a.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(mod))
// If the install rule was generated by Soong tell Make about it.
info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider)
@@ -700,22 +717,26 @@
type androidMkSingleton struct{}
-func (c *androidMkSingleton) GenerateBuildActions(ctx SingletonContext) {
- var androidMkModulesList []blueprint.Module
+func allModulesSorted(ctx SingletonContext) []Module {
+ var allModules []Module
- ctx.VisitAllModulesBlueprint(func(module blueprint.Module) {
- androidMkModulesList = append(androidMkModulesList, module)
+ ctx.VisitAllModules(func(module Module) {
+ allModules = append(allModules, module)
})
// Sort the module list by the module names to eliminate random churns, which may erroneously
// invoke additional build processes.
- sort.SliceStable(androidMkModulesList, func(i, j int) bool {
- return ctx.ModuleName(androidMkModulesList[i]) < ctx.ModuleName(androidMkModulesList[j])
+ sort.SliceStable(allModules, func(i, j int) bool {
+ return ctx.ModuleName(allModules[i]) < ctx.ModuleName(allModules[j])
})
- // If running in soong-only mode, do a different, more limited version of this singleton
+ return allModules
+}
+
+func (c *androidMkSingleton) GenerateBuildActions(ctx SingletonContext) {
+ // If running in soong-only mode, more limited version of this singleton is run as
+ // soong only androidmk singleton
if !ctx.Config().KatiEnabled() {
- c.soongOnlyBuildActions(ctx, androidMkModulesList)
return
}
@@ -726,7 +747,7 @@
moduleInfoJSON := PathForOutput(ctx, "module-info"+String(ctx.Config().productVariables.Make_suffix)+".json")
- err := translateAndroidMk(ctx, absolutePath(transMk.String()), moduleInfoJSON, androidMkModulesList)
+ err := translateAndroidMk(ctx, absolutePath(transMk.String()), moduleInfoJSON, allModulesSorted(ctx))
if err != nil {
ctx.Errorf(err.Error())
}
@@ -737,12 +758,63 @@
})
}
+type soongOnlyAndroidMkSingleton struct {
+ Singleton
+}
+
+func soongOnlyAndroidMkSingletonFactory() Singleton {
+ return &soongOnlyAndroidMkSingleton{}
+}
+
+func (so *soongOnlyAndroidMkSingleton) GenerateBuildActions(ctx SingletonContext) {
+ if !ctx.Config().KatiEnabled() {
+ so.soongOnlyBuildActions(ctx, allModulesSorted(ctx))
+ }
+}
+
// In soong-only mode, we don't do most of the androidmk stuff. But disted files are still largely
// defined through the androidmk mechanisms, so this function is an alternate implementation of
// the androidmk singleton that just focuses on getting the dist contributions
-func (c *androidMkSingleton) soongOnlyBuildActions(ctx SingletonContext, mods []blueprint.Module) {
- allDistContributions := getDistContributionsFromMods(ctx, mods)
+// TODO(b/397766191): Change the signature to take ModuleProxy
+// Please only access the module's internal data through providers.
+func (so *soongOnlyAndroidMkSingleton) soongOnlyBuildActions(ctx SingletonContext, mods []Module) {
+ allDistContributions, moduleInfoJSONs := getSoongOnlyDataFromMods(ctx, mods)
+ singletonDists := getSingletonDists(ctx.Config())
+ singletonDists.lock.Lock()
+ if contribution := distsToDistContributions(singletonDists.dists); contribution != nil {
+ allDistContributions = append(allDistContributions, *contribution)
+ }
+ singletonDists.lock.Unlock()
+
+ // Build module-info.json. Only in builds with HasDeviceProduct(), as we need a named
+ // device to have a TARGET_OUT folder.
+ if ctx.Config().HasDeviceProduct() {
+ preMergePath := PathForOutput(ctx, "module_info_pre_merging.json")
+ moduleInfoJSONPath := pathForInstall(ctx, Android, X86_64, "", "module-info.json")
+ if err := writeModuleInfoJSON(ctx, moduleInfoJSONs, preMergePath); err != nil {
+ ctx.Errorf("%s", err)
+ }
+ builder := NewRuleBuilder(pctx, ctx)
+ builder.Command().
+ BuiltTool("merge_module_info_json").
+ FlagWithOutput("-o ", moduleInfoJSONPath).
+ Input(preMergePath)
+ builder.Build("merge_module_info_json", "merge module info json")
+ ctx.Phony("module-info", moduleInfoJSONPath)
+ ctx.Phony("droidcore-unbundled", moduleInfoJSONPath)
+ allDistContributions = append(allDistContributions, distContributions{
+ copiesForGoals: []*copiesForGoals{{
+ goals: "general-tests droidcore-unbundled",
+ copies: []distCopy{{
+ from: moduleInfoJSONPath,
+ dest: "module-info.json",
+ }},
+ }},
+ })
+ }
+
+ // Build dist.mk for the packaging step to read and generate dist targets
distMkFile := absolutePath(filepath.Join(ctx.Config().katiPackageMkDir(), "dist.mk"))
var goalOutputPairs []string
@@ -793,34 +865,66 @@
}
}
-func getDistContributionsFromMods(ctx fillInEntriesContext, mods []blueprint.Module) []distContributions {
+func distsToDistContributions(dists []dist) *distContributions {
+ if len(dists) == 0 {
+ return nil
+ }
+
+ copyGoals := []*copiesForGoals{}
+ for _, dist := range dists {
+ for _, goal := range dist.goals {
+ copyGoals = append(copyGoals, &copiesForGoals{
+ goals: goal,
+ copies: dist.paths,
+ })
+ }
+ }
+
+ return &distContributions{
+ copiesForGoals: copyGoals,
+ }
+}
+
+// getSoongOnlyDataFromMods gathers data from the given modules needed in soong-only builds.
+// Currently, this is the dist contributions, and the module-info.json contents.
+func getSoongOnlyDataFromMods(ctx fillInEntriesContext, mods []Module) ([]distContributions, []*ModuleInfoJSON) {
var allDistContributions []distContributions
+ var moduleInfoJSONs []*ModuleInfoJSON
for _, mod := range mods {
- if amod, ok := mod.(Module); ok && shouldSkipAndroidMkProcessing(ctx, amod.base()) {
+ if distInfo, ok := OtherModuleProvider(ctx, mod, DistProvider); ok {
+ if contribution := distsToDistContributions(distInfo.Dists); contribution != nil {
+ allDistContributions = append(allDistContributions, *contribution)
+ }
+ }
+
+ commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoKey)
+ if commonInfo.SkipAndroidMkProcessing {
continue
}
if info, ok := OtherModuleProvider(ctx, mod, AndroidMkInfoProvider); ok {
// Deep copy the provider info since we need to modify the info later
info := deepCopyAndroidMkProviderInfo(info)
- info.PrimaryInfo.fillInEntries(ctx, mod)
+ info.PrimaryInfo.fillInEntries(ctx, mod, &commonInfo)
if info.PrimaryInfo.disabled() {
continue
}
- if contribution := info.PrimaryInfo.getDistContributions(ctx, mod); contribution != nil {
+ if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
+ moduleInfoJSONs = append(moduleInfoJSONs, moduleInfoJSON...)
+ }
+ if contribution := info.PrimaryInfo.getDistContributions(ctx, mod, &commonInfo); contribution != nil {
allDistContributions = append(allDistContributions, *contribution)
}
for _, ei := range info.ExtraInfo {
- ei.fillInEntries(ctx, mod)
+ ei.fillInEntries(ctx, mod, &commonInfo)
if ei.disabled() {
continue
}
- if contribution := ei.getDistContributions(ctx, mod); contribution != nil {
+ if contribution := ei.getDistContributions(ctx, mod, &commonInfo); contribution != nil {
allDistContributions = append(allDistContributions, *contribution)
}
}
} else {
- switch x := mod.(type) {
- case AndroidMkDataProvider:
+ if x, ok := mod.(AndroidMkDataProvider); ok {
data := x.AndroidMk()
if data.Include == "" {
@@ -831,29 +935,34 @@
if data.Entries.disabled() {
continue
}
+ if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
+ moduleInfoJSONs = append(moduleInfoJSONs, moduleInfoJSON...)
+ }
if contribution := data.Entries.getDistContributions(mod); contribution != nil {
allDistContributions = append(allDistContributions, *contribution)
}
- case AndroidMkEntriesProvider:
+ }
+ if x, ok := mod.(AndroidMkEntriesProvider); ok {
entriesList := x.AndroidMkEntries()
for _, entries := range entriesList {
entries.fillInEntries(ctx, mod)
if entries.disabled() {
continue
}
+ if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
+ moduleInfoJSONs = append(moduleInfoJSONs, moduleInfoJSON...)
+ }
if contribution := entries.getDistContributions(mod); contribution != nil {
allDistContributions = append(allDistContributions, *contribution)
}
}
- default:
- // Not exported to make so no make variables to set.
}
}
}
- return allDistContributions
+ return allDistContributions, moduleInfoJSONs
}
-func translateAndroidMk(ctx SingletonContext, absMkFile string, moduleInfoJSONPath WritablePath, mods []blueprint.Module) error {
+func translateAndroidMk(ctx SingletonContext, absMkFile string, moduleInfoJSONPath WritablePath, mods []Module) error {
buf := &bytes.Buffer{}
var moduleInfoJSONs []*ModuleInfoJSON
@@ -868,8 +977,8 @@
return err
}
- if amod, ok := mod.(Module); ok && ctx.PrimaryModule(amod) == amod {
- typeStats[ctx.ModuleType(amod)] += 1
+ if ctx.PrimaryModule(mod) == mod {
+ typeStats[ctx.ModuleType(mod)] += 1
}
}
@@ -913,7 +1022,7 @@
return nil
}
-func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, mod blueprint.Module) error {
+func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, mod Module) error {
defer func() {
if r := recover(); r != nil {
panic(fmt.Errorf("%s in translateAndroidMkModule for module %s variant %s",
@@ -944,12 +1053,11 @@
return err
}
-func (data *AndroidMkData) fillInData(ctx fillInEntriesContext, mod blueprint.Module) {
+func (data *AndroidMkData) fillInData(ctx fillInEntriesContext, mod Module) {
// Get the preamble content through AndroidMkEntries logic.
data.Entries = AndroidMkEntries{
Class: data.Class,
SubName: data.SubName,
- DistFiles: data.DistFiles,
OutputFile: data.OutputFile,
Disabled: data.Disabled,
Include: data.Include,
@@ -968,9 +1076,9 @@
// A support func for the deprecated AndroidMkDataProvider interface. Use AndroidMkEntryProvider
// instead.
func translateAndroidModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON,
- mod blueprint.Module, provider AndroidMkDataProvider) error {
+ mod Module, provider AndroidMkDataProvider) error {
- amod := mod.(Module).base()
+ amod := mod.base()
if shouldSkipAndroidMkProcessing(ctx, amod) {
return nil
}
@@ -982,7 +1090,7 @@
}
data.fillInData(ctx, mod)
- aconfigUpdateAndroidMkData(ctx, mod.(Module), &data)
+ aconfigUpdateAndroidMkData(ctx, mod, &data)
prefix := ""
if amod.ArchSpecific() {
@@ -1037,7 +1145,7 @@
if !data.Entries.disabled() {
if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
- *moduleInfoJSONs = append(*moduleInfoJSONs, moduleInfoJSON)
+ *moduleInfoJSONs = append(*moduleInfoJSONs, moduleInfoJSON...)
}
}
@@ -1063,23 +1171,28 @@
}
func translateAndroidMkEntriesModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON,
- mod blueprint.Module, provider AndroidMkEntriesProvider) error {
- if shouldSkipAndroidMkProcessing(ctx, mod.(Module).base()) {
+ mod Module, provider AndroidMkEntriesProvider) error {
+ if shouldSkipAndroidMkProcessing(ctx, mod.base()) {
return nil
}
entriesList := provider.AndroidMkEntries()
- aconfigUpdateAndroidMkEntries(ctx, mod.(Module), &entriesList)
+ aconfigUpdateAndroidMkEntries(ctx, mod, &entriesList)
+
+ moduleInfoJSON, providesModuleInfoJSON := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider)
// Any new or special cases here need review to verify correct propagation of license information.
for _, entries := range entriesList {
entries.fillInEntries(ctx, mod)
entries.write(w)
- }
- if len(entriesList) > 0 && !entriesList[0].disabled() {
- if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
- *moduleInfoJSONs = append(*moduleInfoJSONs, moduleInfoJSON)
+ if providesModuleInfoJSON && !entries.disabled() {
+ // append only the name matching moduleInfoJSON entry
+ for _, m := range moduleInfoJSON {
+ if m.RegisterNameOverride == entries.OverrideName && m.SubName == entries.SubName {
+ *moduleInfoJSONs = append(*moduleInfoJSONs, m)
+ }
+ }
}
}
@@ -1223,30 +1336,33 @@
// TODO: rename it to AndroidMkEntriesProvider after AndroidMkEntriesProvider interface is gone.
var AndroidMkInfoProvider = blueprint.NewProvider[*AndroidMkProviderInfo]()
+// TODO(b/397766191): Change the signature to take ModuleProxy
+// Please only access the module's internal data through providers.
func translateAndroidMkEntriesInfoModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON,
- mod blueprint.Module, providerInfo *AndroidMkProviderInfo) error {
- if shouldSkipAndroidMkProcessing(ctx, mod.(Module).base()) {
+ mod Module, providerInfo *AndroidMkProviderInfo) error {
+ commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoKey)
+ if commonInfo.SkipAndroidMkProcessing {
return nil
}
// Deep copy the provider info since we need to modify the info later
info := deepCopyAndroidMkProviderInfo(providerInfo)
- aconfigUpdateAndroidMkInfos(ctx, mod.(Module), &info)
+ aconfigUpdateAndroidMkInfos(ctx, mod, &info)
// Any new or special cases here need review to verify correct propagation of license information.
- info.PrimaryInfo.fillInEntries(ctx, mod)
+ info.PrimaryInfo.fillInEntries(ctx, mod, &commonInfo)
info.PrimaryInfo.write(w)
if len(info.ExtraInfo) > 0 {
for _, ei := range info.ExtraInfo {
- ei.fillInEntries(ctx, mod)
+ ei.fillInEntries(ctx, mod, &commonInfo)
ei.write(w)
}
}
if !info.PrimaryInfo.disabled() {
if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
- *moduleInfoJSONs = append(*moduleInfoJSONs, moduleInfoJSON)
+ *moduleInfoJSONs = append(*moduleInfoJSONs, moduleInfoJSON...)
}
}
@@ -1368,14 +1484,14 @@
a.AddStrings("LOCAL_COMPATIBILITY_SUITE", suites...)
}
-func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) {
+// TODO(b/397766191): Change the signature to take ModuleProxy
+// Please only access the module's internal data through providers.
+func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod Module, commonInfo *CommonModuleInfo) {
helperInfo := AndroidMkInfo{
EntryMap: make(map[string][]string),
}
- amod := mod.(Module)
- base := amod.base()
- name := base.BaseModuleName()
+ name := commonInfo.BaseModuleName
if a.OverrideName != "" {
name = a.OverrideName
}
@@ -1383,16 +1499,16 @@
if a.Include == "" {
a.Include = "$(BUILD_PREBUILT)"
}
- a.Required = append(a.Required, amod.RequiredModuleNames(ctx)...)
- a.Required = append(a.Required, amod.VintfFragmentModuleNames(ctx)...)
- a.Host_required = append(a.Host_required, amod.HostRequiredModuleNames()...)
- a.Target_required = append(a.Target_required, amod.TargetRequiredModuleNames()...)
+ a.Required = append(a.Required, commonInfo.RequiredModuleNames...)
+ a.Required = append(a.Required, commonInfo.VintfFragmentModuleNames...)
+ a.Host_required = append(a.Host_required, commonInfo.HostRequiredModuleNames...)
+ a.Target_required = append(a.Target_required, commonInfo.TargetRequiredModuleNames...)
- for _, distString := range a.GetDistForGoals(ctx, mod) {
+ for _, distString := range a.GetDistForGoals(ctx, mod, commonInfo) {
a.HeaderStrings = append(a.HeaderStrings, distString)
}
- a.HeaderStrings = append(a.HeaderStrings, fmt.Sprintf("\ninclude $(CLEAR_VARS) # type: %s, name: %s, variant: %s", ctx.ModuleType(mod), base.BaseModuleName(), ctx.ModuleSubDir(mod)))
+ a.HeaderStrings = append(a.HeaderStrings, fmt.Sprintf("\ninclude $(CLEAR_VARS) # type: %s, name: %s, variant: %s", ctx.ModuleType(mod), commonInfo.BaseModuleName, ctx.ModuleSubDir(mod)))
// Collect make variable assignment entries.
helperInfo.SetString("LOCAL_PATH", ctx.ModuleDir(mod))
@@ -1402,7 +1518,7 @@
helperInfo.AddStrings("LOCAL_REQUIRED_MODULES", a.Required...)
helperInfo.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...)
helperInfo.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...)
- helperInfo.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(amod))
+ helperInfo.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(mod))
// If the install rule was generated by Soong tell Make about it.
info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider)
@@ -1417,7 +1533,7 @@
// Soong may not have generated the install rule also when `no_full_install: true`.
// Mark this module as uninstallable in order to prevent Make from creating an
// install rule there.
- helperInfo.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", proptools.Bool(base.commonProperties.No_full_install))
+ helperInfo.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", commonInfo.NoFullInstall)
}
if info.UncheckedModule {
@@ -1432,31 +1548,31 @@
helperInfo.AddStrings("LOCAL_TEST_DATA", androidMkDataPaths(info.TestData)...)
}
- if am, ok := mod.(ApexModule); ok {
- helperInfo.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", am.NotAvailableForPlatform())
+ if commonInfo.IsApexModule {
+ helperInfo.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", commonInfo.NotAvailableForPlatform)
}
- archStr := base.Arch().ArchType.String()
+ archStr := commonInfo.Target.Arch.ArchType.String()
host := false
- switch base.Os().Class {
+ switch commonInfo.Target.Os.Class {
case Host:
- if base.Target().HostCross {
+ if commonInfo.Target.HostCross {
// Make cannot identify LOCAL_MODULE_HOST_CROSS_ARCH:= common.
- if base.Arch().ArchType != Common {
+ if commonInfo.Target.Arch.ArchType != Common {
helperInfo.SetString("LOCAL_MODULE_HOST_CROSS_ARCH", archStr)
}
} else {
// Make cannot identify LOCAL_MODULE_HOST_ARCH:= common.
- if base.Arch().ArchType != Common {
+ if commonInfo.Target.Arch.ArchType != Common {
helperInfo.SetString("LOCAL_MODULE_HOST_ARCH", archStr)
}
}
host = true
case Device:
// Make cannot identify LOCAL_MODULE_TARGET_ARCH:= common.
- if base.Arch().ArchType != Common {
- if base.Target().NativeBridge {
- hostArchStr := base.Target().NativeBridgeHostArchName
+ if commonInfo.Target.Arch.ArchType != Common {
+ if commonInfo.Target.NativeBridge {
+ hostArchStr := commonInfo.Target.NativeBridgeHostArchName
if hostArchStr != "" {
helperInfo.SetString("LOCAL_MODULE_TARGET_ARCH", hostArchStr)
}
@@ -1465,27 +1581,28 @@
}
}
- if !base.InVendorRamdisk() {
+ if !commonInfo.InVendorRamdisk {
helperInfo.AddPaths("LOCAL_FULL_INIT_RC", info.InitRcPaths)
}
if len(info.VintfFragmentsPaths) > 0 {
helperInfo.AddPaths("LOCAL_FULL_VINTF_FRAGMENTS", info.VintfFragmentsPaths)
}
- helperInfo.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", Bool(base.commonProperties.Proprietary))
- if Bool(base.commonProperties.Vendor) || Bool(base.commonProperties.Soc_specific) {
+ helperInfo.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", commonInfo.Proprietary)
+ if commonInfo.Vendor || commonInfo.SocSpecific {
helperInfo.SetString("LOCAL_VENDOR_MODULE", "true")
}
- helperInfo.SetBoolIfTrue("LOCAL_ODM_MODULE", Bool(base.commonProperties.Device_specific))
- helperInfo.SetBoolIfTrue("LOCAL_PRODUCT_MODULE", Bool(base.commonProperties.Product_specific))
- helperInfo.SetBoolIfTrue("LOCAL_SYSTEM_EXT_MODULE", Bool(base.commonProperties.System_ext_specific))
- if base.commonProperties.Owner != nil {
- helperInfo.SetString("LOCAL_MODULE_OWNER", *base.commonProperties.Owner)
+ helperInfo.SetBoolIfTrue("LOCAL_ODM_MODULE", commonInfo.DeviceSpecific)
+ helperInfo.SetBoolIfTrue("LOCAL_PRODUCT_MODULE", commonInfo.ProductSpecific)
+ helperInfo.SetBoolIfTrue("LOCAL_SYSTEM_EXT_MODULE", commonInfo.SystemExtSpecific)
+ if commonInfo.Owner != "" {
+ helperInfo.SetString("LOCAL_MODULE_OWNER", commonInfo.Owner)
}
}
if host {
- makeOs := base.Os().String()
- if base.Os() == Linux || base.Os() == LinuxBionic || base.Os() == LinuxMusl {
+ os := commonInfo.Target.Os
+ makeOs := os.String()
+ if os == Linux || os == LinuxBionic || os == LinuxMusl {
makeOs = "linux"
}
helperInfo.SetString("LOCAL_MODULE_HOST_OS", makeOs)
@@ -1543,8 +1660,10 @@
// Compute the list of Make strings to declare phony goals and dist-for-goals
// calls from the module's dist and dists properties.
-func (a *AndroidMkInfo) GetDistForGoals(ctx fillInEntriesContext, mod blueprint.Module) []string {
- distContributions := a.getDistContributions(ctx, mod)
+// TODO(b/397766191): Change the signature to take ModuleProxy
+// Please only access the module's internal data through providers.
+func (a *AndroidMkInfo) GetDistForGoals(ctx fillInEntriesContext, mod Module, commonInfo *CommonModuleInfo) []string {
+ distContributions := a.getDistContributions(ctx, mod, commonInfo)
if distContributions == nil {
return nil
}
@@ -1553,9 +1672,11 @@
}
// Compute the contributions that the module makes to the dist.
-func (a *AndroidMkInfo) getDistContributions(ctx fillInEntriesContext, mod blueprint.Module) *distContributions {
- amod := mod.(Module).base()
- name := amod.BaseModuleName()
+// TODO(b/397766191): Change the signature to take ModuleProxy
+// Please only access the module's internal data through providers.
+func (a *AndroidMkInfo) getDistContributions(ctx fillInEntriesContext, mod Module,
+ commonInfo *CommonModuleInfo) *distContributions {
+ name := commonInfo.BaseModuleName
// Collate the set of associated tag/paths available for copying to the dist.
// Start with an empty (nil) set.
@@ -1591,12 +1712,12 @@
// Collate the contributions this module makes to the dist.
distContributions := &distContributions{}
- if !exemptFromRequiredApplicableLicensesProperty(mod.(Module)) {
+ if !commonInfo.ExemptFromRequiredApplicableLicensesProperty {
distContributions.licenseMetadataFile = info.LicenseMetadataFile
}
// Iterate over this module's dist structs, merged from the dist and dists properties.
- for _, dist := range amod.Dists() {
+ for _, dist := range commonInfo.Dists {
// Get the list of goals this dist should be enabled for. e.g. sdk, droidcore
goals := strings.Join(dist.Targets, " ")
diff --git a/android/androidmk_test.go b/android/androidmk_test.go
index f63b227..0a81fb8 100644
--- a/android/androidmk_test.go
+++ b/android/androidmk_test.go
@@ -144,7 +144,7 @@
FixtureWithRootAndroidBp(bp),
).RunTest(t)
- module := result.ModuleForTests("foo", "").Module().(*customModule)
+ module := result.ModuleForTests(t, "foo", "").Module().(*customModule)
return result.TestContext, module
}
diff --git a/android/apex.go b/android/apex.go
index 08c82eb..91fa2c7 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -17,7 +17,6 @@
import (
"fmt"
"slices"
- "sort"
"strconv"
"strings"
"sync"
@@ -55,18 +54,30 @@
// to true.
UsePlatformApis bool
- // List of Apex variant names that this module is associated with. This initially is the
- // same as the `ApexVariationName` field. Then when multiple apex variants are merged in
- // mergeApexVariations, ApexInfo struct of the merged variant holds the list of apexBundles
- // that are merged together.
- InApexVariants []string
-
// True if this is for a prebuilt_apex.
//
// If true then this will customize the apex processing to make it suitable for handling
// prebuilt_apex, e.g. it will prevent ApexInfos from being merged together.
//
- // See Prebuilt.ApexInfoMutator for more information.
+ // Unlike the source apex module type the prebuilt_apex module type cannot share compatible variants
+ // across prebuilt_apex modules. That is because there is no way to determine whether two
+ // prebuilt_apex modules that export files for the same module are compatible. e.g. they could have
+ // been built from different source at different times or they could have been built with different
+ // build options that affect the libraries.
+ //
+ // While it may be possible to provide sufficient information to determine whether two prebuilt_apex
+ // modules were compatible it would be a lot of work and would not provide much benefit for a couple
+ // of reasons:
+ // - The number of prebuilt_apex modules that will be exporting files for the same module will be
+ // low as the prebuilt_apex only exports files for the direct dependencies that require it and
+ // very few modules are direct dependencies of multiple prebuilt_apex modules, e.g. there are a
+ // few com.android.art* apex files that contain the same contents and could export files for the
+ // same modules but only one of them needs to do so. Contrast that with source apex modules which
+ // need apex specific variants for every module that contributes code to the apex, whether direct
+ // or indirect.
+ // - The build cost of a prebuilt_apex variant is generally low as at worst it will involve some
+ // extra copying of files. Contrast that with source apex modules that has to build each variant
+ // from source.
ForPrebuiltApex bool
// Returns the name of the overridden apex (com.android.foo)
@@ -74,24 +85,36 @@
// Returns the value of `apex_available_name`
ApexAvailableName string
+}
+func (a ApexInfo) Variation() string {
+ return a.ApexVariationName
+}
+
+// Minimize is called during a transition from a module with a unique variation per apex to a module that should
+// share variations between apexes. It returns a minimized ApexInfo that removes any apex names and replaces
+// the variation name with one computed from the remaining properties.
+func (a ApexInfo) Minimize() ApexInfo {
+ info := ApexInfo{
+ MinSdkVersion: a.MinSdkVersion,
+ UsePlatformApis: a.UsePlatformApis,
+ }
+ info.ApexVariationName = info.mergedName()
+ return info
+}
+
+type ApexAvailableInfo struct {
// Returns the apex names that this module is available for
ApexAvailableFor []string
}
-// AllApexInfo holds the ApexInfo of all apexes that include this module.
-type AllApexInfo struct {
- ApexInfos []ApexInfo
-}
-
var ApexInfoProvider = blueprint.NewMutatorProvider[ApexInfo]("apex_mutate")
-var AllApexInfoProvider = blueprint.NewMutatorProvider[*AllApexInfo]("apex_info")
+var ApexAvailableInfoProvider = blueprint.NewMutatorProvider[ApexAvailableInfo]("apex_mutate")
func (i ApexInfo) AddJSONData(d *map[string]interface{}) {
(*d)["Apex"] = map[string]interface{}{
"ApexVariationName": i.ApexVariationName,
"MinSdkVersion": i.MinSdkVersion,
- "InApexVariants": i.InApexVariants,
"ForPrebuiltApex": i.ForPrebuiltApex,
}
}
@@ -105,6 +128,9 @@
// thus wouldn't be merged.
func (i ApexInfo) mergedName() string {
name := "apex" + strconv.Itoa(i.MinSdkVersion.FinalOrFutureInt())
+ if i.UsePlatformApis {
+ name += "_p"
+ }
return name
}
@@ -114,38 +140,24 @@
return i.ApexVariationName == ""
}
-// InApexVariant tells whether this apex variant of the module is part of the given apexVariant or
-// not.
-func (i ApexInfo) InApexVariant(apexVariant string) bool {
- for _, a := range i.InApexVariants {
- if a == apexVariant {
- return true
- }
- }
- return false
-}
-
// To satisfy the comparable interface
func (i ApexInfo) Equal(other any) bool {
otherApexInfo, ok := other.(ApexInfo)
return ok && i.ApexVariationName == otherApexInfo.ApexVariationName &&
i.MinSdkVersion == otherApexInfo.MinSdkVersion &&
i.Updatable == otherApexInfo.Updatable &&
- i.UsePlatformApis == otherApexInfo.UsePlatformApis &&
- slices.Equal(i.InApexVariants, otherApexInfo.InApexVariants)
+ i.UsePlatformApis == otherApexInfo.UsePlatformApis
}
// ApexBundleInfo contains information about the dependencies of an apex
type ApexBundleInfo struct {
}
-var ApexBundleInfoProvider = blueprint.NewMutatorProvider[ApexBundleInfo]("apex_info")
+var ApexBundleInfoProvider = blueprint.NewMutatorProvider[ApexBundleInfo]("apex_mutate")
-// DepIsInSameApex defines an interface that should be used to determine whether a given dependency
-// should be considered as part of the same APEX as the current module or not. Note: this was
-// extracted from ApexModule to make it easier to define custom subsets of the ApexModule interface
-// and improve code navigation within the IDE.
-type DepIsInSameApex interface {
+// DepInSameApexChecker defines an interface that should be used to determine whether a given dependency
+// should be considered as part of the same APEX as the current module or not.
+type DepInSameApexChecker interface {
// OutgoingDepIsInSameApex tests if the module depended on via 'tag' is considered as part of
// the same APEX as this module. For example, a static lib dependency usually returns true here, while a
// shared lib dependency to a stub library returns false.
@@ -167,6 +179,15 @@
IncomingDepIsInSameApex(tag blueprint.DependencyTag) bool
}
+// DepInSameApexInfo is a provider that wraps around a DepInSameApexChecker that can be
+// used to check if a dependency belongs to the same apex as the module when walking
+// through the dependencies of a module.
+type DepInSameApexInfo struct {
+ Checker DepInSameApexChecker
+}
+
+var DepInSameApexInfoProvider = blueprint.NewMutatorProvider[DepInSameApexInfo]("apex_unique")
+
func IsDepInSameApex(ctx BaseModuleContext, module, dep Module) bool {
depTag := ctx.OtherModuleDependencyTag(dep)
if _, ok := depTag.(ExcludeFromApexContentsTag); ok {
@@ -175,12 +196,23 @@
return false
}
- if m, ok := module.(DepIsInSameApex); ok && !m.OutgoingDepIsInSameApex(depTag) {
- return false
+ if !ctx.EqualModules(ctx.Module(), module) {
+ if moduleInfo, ok := OtherModuleProvider(ctx, module, DepInSameApexInfoProvider); ok {
+ if !moduleInfo.Checker.OutgoingDepIsInSameApex(depTag) {
+ return false
+ }
+ }
+ } else {
+ if m, ok := ctx.Module().(ApexModule); ok && !m.GetDepInSameApexChecker().OutgoingDepIsInSameApex(depTag) {
+ return false
+ }
}
- if d, ok := dep.(DepIsInSameApex); ok && !d.IncomingDepIsInSameApex(depTag) {
- return false
+ if depInfo, ok := OtherModuleProvider(ctx, dep, DepInSameApexInfoProvider); ok {
+ if !depInfo.Checker.IncomingDepIsInSameApex(depTag) {
+ return false
+ }
}
+
return true
}
@@ -199,7 +231,6 @@
// mergedName) when the two APEXes have the same min_sdk_version requirement.
type ApexModule interface {
Module
- DepIsInSameApex
apexModuleBase() *ApexModuleBase
@@ -251,16 +282,15 @@
// check-platform-availability mutator in the apex package.
SetNotAvailableForPlatform()
- // Returns nil (success) if this module should support the given sdk version. Returns an
- // error if not. No default implementation is provided for this method. A module type
- // implementing this interface should provide an implementation. A module supports an sdk
- // version when the module's min_sdk_version is equal to or less than the given sdk version.
- ShouldSupportSdkVersion(ctx BaseModuleContext, sdkVersion ApiLevel) error
+ // Returns the min sdk version that the module supports, .
+ MinSdkVersionSupported(ctx BaseModuleContext) ApiLevel
// Returns true if this module needs a unique variation per apex, effectively disabling the
// deduping. This is turned on when, for example if use_apex_name_macro is set so that each
// apex variant should be built with different macro definitions.
UniqueApexVariations() bool
+
+ GetDepInSameApexChecker() DepInSameApexChecker
}
// Properties that are common to all module types implementing ApexModule interface.
@@ -312,6 +342,61 @@
apexInfosLock sync.Mutex // protects apexInfos during parallel apexInfoMutator
}
+func (m *ApexModuleBase) ApexTransitionMutatorSplit(ctx BaseModuleContext) []ApexInfo {
+ return []ApexInfo{{}}
+}
+
+func (m *ApexModuleBase) ApexTransitionMutatorOutgoing(ctx OutgoingTransitionContext, info ApexInfo) ApexInfo {
+ if !ctx.Module().(ApexModule).GetDepInSameApexChecker().OutgoingDepIsInSameApex(ctx.DepTag()) {
+ return ApexInfo{}
+ }
+ return info
+}
+
+func (m *ApexModuleBase) ApexTransitionMutatorIncoming(ctx IncomingTransitionContext, info ApexInfo) ApexInfo {
+ module := ctx.Module().(ApexModule)
+ if !module.CanHaveApexVariants() {
+ return ApexInfo{}
+ }
+
+ if !ctx.Module().(ApexModule).GetDepInSameApexChecker().IncomingDepIsInSameApex(ctx.DepTag()) {
+ return ApexInfo{}
+ }
+
+ if info.ApexVariationName == "" {
+ return ApexInfo{}
+ }
+
+ if !ctx.Module().(ApexModule).UniqueApexVariations() && !m.ApexProperties.UniqueApexVariationsForDeps && !info.ForPrebuiltApex {
+ return info.Minimize()
+ }
+ return info
+}
+
+func (m *ApexModuleBase) ApexTransitionMutatorMutate(ctx BottomUpMutatorContext, info ApexInfo) {
+ SetProvider(ctx, ApexInfoProvider, info)
+
+ module := ctx.Module().(ApexModule)
+ base := module.apexModuleBase()
+
+ platformVariation := info.ApexVariationName == ""
+ if !platformVariation {
+ // Do some validity checks.
+ // TODO(jiyong): is this the right place?
+ base.checkApexAvailableProperty(ctx)
+
+ SetProvider(ctx, ApexAvailableInfoProvider, ApexAvailableInfo{
+ ApexAvailableFor: module.ApexAvailableFor(),
+ })
+ }
+ if platformVariation && !ctx.Host() && !module.AvailableFor(AvailableToPlatform) && module.NotAvailableForPlatform() {
+ // Do not install the module for platform, but still allow it to output
+ // uninstallable AndroidMk entries in certain cases when they have side
+ // effects. TODO(jiyong): move this routine to somewhere else
+ module.MakeUninstallable()
+ }
+}
+
// Initializes ApexModuleBase struct. Not calling this (even when inheriting from ApexModuleBase)
// prevents the module from being mutated for apexBundle.
func InitApexModule(m ApexModule) {
@@ -391,19 +476,17 @@
}
// Implements ApexModule
-func (m *ApexModuleBase) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
- // By default, if there is a dependency from A to B, we try to include both in the same
- // APEX, unless B is explicitly from outside of the APEX (i.e. a stubs lib). Thus, returning
- // true. This is overridden by some module types like apex.ApexBundle, cc.Module,
- // java.Module, etc.
+func (m *ApexModuleBase) GetDepInSameApexChecker() DepInSameApexChecker {
+ return BaseDepInSameApexChecker{}
+}
+
+type BaseDepInSameApexChecker struct{}
+
+func (m BaseDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
return true
}
-func (m *ApexModuleBase) IncomingDepIsInSameApex(tag blueprint.DependencyTag) bool {
- // By default, if there is a dependency from A to B, we try to include both in the same
- // APEX, unless B is explicitly from outside of the APEX (i.e. a stubs lib). Thus, returning
- // true. This is overridden by some module types like apex.ApexBundle, cc.Module,
- // java.Module, etc.
+func (m BaseDepInSameApexChecker) IncomingDepIsInSameApex(tag blueprint.DependencyTag) bool {
return true
}
@@ -511,194 +594,14 @@
return true
}
-// mergeApexVariations deduplicates apex variations that would build identically into a common
-// variation. It returns the reduced list of variations and a list of aliases from the original
-// variation names to the new variation names.
-func mergeApexVariations(apexInfos []ApexInfo) (merged []ApexInfo, aliases [][2]string) {
- seen := make(map[string]int)
- for _, apexInfo := range apexInfos {
- // If this is for a prebuilt apex then use the actual name of the apex variation to prevent this
- // from being merged with other ApexInfo. See Prebuilt.ApexInfoMutator for more information.
- if apexInfo.ForPrebuiltApex {
- merged = append(merged, apexInfo)
- continue
- }
-
- // Merge the ApexInfo together. If a compatible ApexInfo exists then merge the information from
- // this one into it, otherwise create a new merged ApexInfo from this one and save it away so
- // other ApexInfo instances can be merged into it.
- variantName := apexInfo.ApexVariationName
- mergedName := apexInfo.mergedName()
- if index, exists := seen[mergedName]; exists {
- // Variants having the same mergedName are deduped
- merged[index].InApexVariants = append(merged[index].InApexVariants, variantName)
- merged[index].Updatable = merged[index].Updatable || apexInfo.Updatable
- // Platform APIs is allowed for this module only when all APEXes containing
- // the module are with `use_platform_apis: true`.
- merged[index].UsePlatformApis = merged[index].UsePlatformApis && apexInfo.UsePlatformApis
- } else {
- seen[mergedName] = len(merged)
- apexInfo.ApexVariationName = mergedName
- apexInfo.InApexVariants = CopyOf(apexInfo.InApexVariants)
- merged = append(merged, apexInfo)
- }
- aliases = append(aliases, [2]string{variantName, mergedName})
- }
- return merged, aliases
-}
-
-// IncomingApexTransition is called by apexTransitionMutator.IncomingTransition on modules that can be in apexes.
-// The incomingVariation can be either the name of an apex if the dependency is coming directly from an apex
-// module, or it can be the name of an apex variation (e.g. apex10000) if it is coming from another module that
-// is in the apex.
-func IncomingApexTransition(ctx IncomingTransitionContext, incomingVariation string) string {
- module := ctx.Module().(ApexModule)
- base := module.apexModuleBase()
-
- var apexInfos []ApexInfo
- if allApexInfos, ok := ModuleProvider(ctx, AllApexInfoProvider); ok {
- apexInfos = allApexInfos.ApexInfos
- }
-
- // Dependencies from platform variations go to the platform variation.
- if incomingVariation == "" {
- return ""
- }
-
- if len(apexInfos) == 0 {
- if ctx.IsAddingDependency() {
- // If this module has no apex variations we can't do any mapping on the incoming variation, just return it
- // and let the caller get a "missing variant" error.
- return incomingVariation
- } else {
- // If this module has no apex variations the use the platform variation.
- return ""
- }
- }
-
- // Convert the list of apex infos into from the AllApexInfoProvider into the merged list
- // of apex variations and the aliases from apex names to apex variations.
- var aliases [][2]string
- if !module.UniqueApexVariations() && !base.ApexProperties.UniqueApexVariationsForDeps {
- apexInfos, aliases = mergeApexVariations(apexInfos)
- }
-
- // Check if the incoming variation matches an apex name, and if so use the corresponding
- // apex variation.
- aliasIndex := slices.IndexFunc(aliases, func(alias [2]string) bool {
- return alias[0] == incomingVariation
- })
- if aliasIndex >= 0 {
- return aliases[aliasIndex][1]
- }
-
- // Check if the incoming variation matches an apex variation.
- apexIndex := slices.IndexFunc(apexInfos, func(info ApexInfo) bool {
- return info.ApexVariationName == incomingVariation
- })
- if apexIndex >= 0 {
- return incomingVariation
- }
-
- return ""
-}
-
-func MutateApexTransition(ctx BaseModuleContext, variation string) {
- module := ctx.Module().(ApexModule)
- base := module.apexModuleBase()
- platformVariation := variation == ""
-
- var apexInfos []ApexInfo
- if allApexInfos, ok := ModuleProvider(ctx, AllApexInfoProvider); ok {
- apexInfos = allApexInfos.ApexInfos
- }
-
- // Shortcut
- if len(apexInfos) == 0 {
- return
- }
-
- // Do some validity checks.
- // TODO(jiyong): is this the right place?
- base.checkApexAvailableProperty(ctx)
-
- if !module.UniqueApexVariations() && !base.ApexProperties.UniqueApexVariationsForDeps {
- apexInfos, _ = mergeApexVariations(apexInfos)
- }
-
- if platformVariation && !ctx.Host() && !module.AvailableFor(AvailableToPlatform) && module.NotAvailableForPlatform() {
- // Do not install the module for platform, but still allow it to output
- // uninstallable AndroidMk entries in certain cases when they have side
- // effects. TODO(jiyong): move this routine to somewhere else
- module.MakeUninstallable()
- }
- if !platformVariation {
- var thisApexInfo ApexInfo
-
- apexIndex := slices.IndexFunc(apexInfos, func(info ApexInfo) bool {
- return info.ApexVariationName == variation
- })
- if apexIndex >= 0 {
- thisApexInfo = apexInfos[apexIndex]
- } else {
- panic(fmt.Errorf("failed to find apexInfo for incoming variation %q", variation))
- }
- thisApexInfo.ApexAvailableFor = module.ApexAvailableFor()
-
- SetProvider(ctx, ApexInfoProvider, thisApexInfo)
- }
-}
-
-func ApexInfoMutator(ctx TopDownMutatorContext, module ApexModule) {
- base := module.apexModuleBase()
- if len(base.apexInfos) > 0 {
- apexInfos := slices.Clone(base.apexInfos)
- slices.SortFunc(apexInfos, func(a, b ApexInfo) int {
- return strings.Compare(a.ApexVariationName, b.ApexVariationName)
- })
- SetProvider(ctx, AllApexInfoProvider, &AllApexInfo{apexInfos})
- // base.apexInfos is only needed to propagate the list of apexes from the apex module to its
- // contents within apexInfoMutator. Clear it so it doesn't accidentally get used later.
- base.apexInfos = nil
- }
-}
-
// UpdateUniqueApexVariationsForDeps sets UniqueApexVariationsForDeps if any dependencies that are
// in the same APEX have unique APEX variations so that the module can link against the right
// variant.
func UpdateUniqueApexVariationsForDeps(mctx BottomUpMutatorContext, am ApexModule) {
- // anyInSameApex returns true if the two ApexInfo lists contain any values in an
- // InApexVariants list in common. It is used instead of OutgoingDepIsInSameApex because it needs to
- // determine if the dep is in the same APEX due to being directly included, not only if it
- // is included _because_ it is a dependency.
- anyInSameApex := func(a, b ApexModule) bool {
- collectApexes := func(m ApexModule) []string {
- if allApexInfo, ok := OtherModuleProvider(mctx, m, AllApexInfoProvider); ok {
- var ret []string
- for _, info := range allApexInfo.ApexInfos {
- ret = append(ret, info.InApexVariants...)
- }
- return ret
- }
- return nil
- }
-
- aApexes := collectApexes(a)
- bApexes := collectApexes(b)
- sort.Strings(bApexes)
- for _, aApex := range aApexes {
- index := sort.SearchStrings(bApexes, aApex)
- if index < len(bApexes) && bApexes[index] == aApex {
- return true
- }
- }
- return false
- }
-
// If any of the dependencies requires unique apex variations, so does this module.
mctx.VisitDirectDeps(func(dep Module) {
if depApexModule, ok := dep.(ApexModule); ok {
- if anyInSameApex(depApexModule, am) &&
+ if IsDepInSameApex(mctx, am, depApexModule) &&
(depApexModule.UniqueApexVariations() ||
depApexModule.apexModuleBase().ApexProperties.UniqueApexVariationsForDeps) {
am.apexModuleBase().ApexProperties.UniqueApexVariationsForDeps = true
@@ -823,30 +726,53 @@
if !IsDepInSameApex(ctx, from, to) {
return false
}
- if m, ok := to.(ModuleWithMinSdkVersionCheck); ok {
- // This dependency performs its own min_sdk_version check, just make sure it sets min_sdk_version
- // to trigger the check.
- if !m.MinSdkVersion(ctx).Specified() {
- ctx.OtherModuleErrorf(m, "must set min_sdk_version")
+ if info, ok := OtherModuleProvider(ctx, to, CommonModuleInfoKey); ok && info.ModuleWithMinSdkVersionCheck {
+ if info.MinSdkVersion.ApiLevel == nil || !info.MinSdkVersion.ApiLevel.Specified() {
+ // This dependency performs its own min_sdk_version check, just make sure it sets min_sdk_version
+ // to trigger the check.
+ ctx.OtherModuleErrorf(to, "must set min_sdk_version")
}
return false
}
- if err := to.ShouldSupportSdkVersion(ctx, minSdkVersion); err != nil {
- toName := ctx.OtherModuleName(to)
+ if err := ShouldSupportSdkVersion(ctx, to, minSdkVersion); err != nil {
ctx.OtherModuleErrorf(to, "should support min_sdk_version(%v) for %q: %v."+
"\n\nDependency path: %s\n\n"+
"Consider adding 'min_sdk_version: %q' to %q",
minSdkVersion, ctx.ModuleName(), err.Error(),
ctx.GetPathString(false),
- minSdkVersion, toName)
+ minSdkVersion, ctx.OtherModuleName(to))
return false
}
return true
})
}
+type MinSdkVersionFromValueContext interface {
+ Config() Config
+ DeviceConfig() DeviceConfig
+ ModuleErrorContext
+}
+
+// Returns nil (success) if this module should support the given sdk version. Returns an
+// error if not. No default implementation is provided for this method. A module type
+// implementing this interface should provide an implementation. A module supports an sdk
+// version when the module's min_sdk_version is equal to or less than the given sdk version.
+func ShouldSupportSdkVersion(ctx BaseModuleContext, module Module, sdkVersion ApiLevel) error {
+ info, ok := OtherModuleProvider(ctx, module, CommonModuleInfoKey)
+ if !ok || info.MinSdkVersionSupported.IsNone() {
+ return fmt.Errorf("min_sdk_version is not specified")
+ }
+ minVer := info.MinSdkVersionSupported
+
+ if minVer.GreaterThan(sdkVersion) {
+ return fmt.Errorf("newer SDK(%v)", minVer)
+ }
+
+ return nil
+}
+
// Construct ApiLevel object from min_sdk_version string value
-func MinSdkVersionFromValue(ctx EarlyModuleContext, value string) ApiLevel {
+func MinSdkVersionFromValue(ctx MinSdkVersionFromValueContext, value string) ApiLevel {
if value == "" {
return NoneApiLevel
}
@@ -887,3 +813,21 @@
// to generate the mainline module prebuilt.
Prebuilt_info_file_path string `json:",omitempty"`
}
+
+// FragmentInApexTag is embedded into a dependency tag to allow apex modules to annotate
+// their fragments in a way that allows the java bootclasspath modules to traverse from
+// the apex to the fragment.
+type FragmentInApexTag struct{}
+
+func (FragmentInApexTag) isFragmentInApexTag() {}
+
+type isFragmentInApexTagIntf interface {
+ isFragmentInApexTag()
+}
+
+// IsFragmentInApexTag returns true if the dependency tag embeds FragmentInApexTag,
+// signifying that it is a dependency from an apex module to its fragment.
+func IsFragmentInApexTag(tag blueprint.DependencyTag) bool {
+ _, ok := tag.(isFragmentInApexTagIntf)
+ return ok
+}
diff --git a/android/apex_contributions.go b/android/apex_contributions.go
index ce34278..fe7a835 100644
--- a/android/apex_contributions.go
+++ b/android/apex_contributions.go
@@ -104,19 +104,8 @@
AcDepTag = apexContributionsDepTag{}
)
-// Creates a dep to each selected apex_contributions
-func (a *allApexContributions) DepsMutator(ctx BottomUpMutatorContext) {
- // Skip apex_contributions if BuildApexContributionContents is true
- // This product config var allows some products in the same family to use mainline modules from source
- // (e.g. shiba and shiba_fullmte)
- // Eventually these product variants will have their own release config maps.
- if !proptools.Bool(ctx.Config().BuildIgnoreApexContributionContents()) {
- ctx.AddDependency(ctx.Module(), AcDepTag, ctx.Config().AllApexContributions()...)
- }
-}
-
// Set PrebuiltSelectionInfoProvider in post deps phase
-func (a *allApexContributions) SetPrebuiltSelectionInfoProvider(ctx BaseModuleContext) {
+func (a *allApexContributions) SetPrebuiltSelectionInfoProvider(ctx BottomUpMutatorContext) {
addContentsToProvider := func(p *PrebuiltSelectionInfoMap, m *apexContributions) {
for _, content := range m.Contents() {
// Verify that the module listed in contents exists in the tree
@@ -135,13 +124,23 @@
}
p := PrebuiltSelectionInfoMap{}
- ctx.VisitDirectDepsWithTag(AcDepTag, func(child Module) {
- if m, ok := child.(*apexContributions); ok {
- addContentsToProvider(&p, m)
- } else {
- ctx.ModuleErrorf("%s is not an apex_contributions module\n", child.Name())
+ // Skip apex_contributions if BuildApexContributionContents is true
+ // This product config var allows some products in the same family to use mainline modules from source
+ // (e.g. shiba and shiba_fullmte)
+ // Eventually these product variants will have their own release config maps.
+ if !proptools.Bool(ctx.Config().BuildIgnoreApexContributionContents()) {
+ deps := ctx.AddDependency(ctx.Module(), AcDepTag, ctx.Config().AllApexContributions()...)
+ for _, child := range deps {
+ if child == nil {
+ continue
+ }
+ if m, ok := child.(*apexContributions); ok {
+ addContentsToProvider(&p, m)
+ } else {
+ ctx.ModuleErrorf("%s is not an apex_contributions module\n", child.Name())
+ }
}
- })
+ }
SetProvider(ctx, PrebuiltSelectionInfoProvider, p)
}
diff --git a/android/apex_test.go b/android/apex_test.go
deleted file mode 100644
index 78597b2..0000000
--- a/android/apex_test.go
+++ /dev/null
@@ -1,270 +0,0 @@
-// Copyright 2020 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 android
-
-import (
- "reflect"
- "testing"
-)
-
-func Test_mergeApexVariations(t *testing.T) {
- const (
- ForPrebuiltApex = true
- NotForPrebuiltApex = false
- )
- tests := []struct {
- name string
- in []ApexInfo
- wantMerged []ApexInfo
- wantAliases [][2]string
- }{
- {
- name: "single",
- in: []ApexInfo{
- {
- ApexVariationName: "foo",
- MinSdkVersion: FutureApiLevel,
- InApexVariants: []string{"foo"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- },
- wantMerged: []ApexInfo{
- {
- ApexVariationName: "apex10000",
- MinSdkVersion: FutureApiLevel,
- InApexVariants: []string{"foo"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- },
- wantAliases: [][2]string{
- {"foo", "apex10000"},
- },
- },
- {
- name: "merge",
- in: []ApexInfo{
- {
- ApexVariationName: "foo",
- MinSdkVersion: FutureApiLevel,
- InApexVariants: []string{"foo"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- {
- ApexVariationName: "bar",
- MinSdkVersion: FutureApiLevel,
- InApexVariants: []string{"bar"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- },
- wantMerged: []ApexInfo{
- {
- ApexVariationName: "apex10000",
- MinSdkVersion: FutureApiLevel,
- InApexVariants: []string{"foo", "bar"},
- }},
- wantAliases: [][2]string{
- {"foo", "apex10000"},
- {"bar", "apex10000"},
- },
- },
- {
- name: "don't merge version",
- in: []ApexInfo{
- {
- ApexVariationName: "foo",
- MinSdkVersion: FutureApiLevel,
- InApexVariants: []string{"foo"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- {
- ApexVariationName: "bar",
- MinSdkVersion: uncheckedFinalApiLevel(30),
- InApexVariants: []string{"bar"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- },
- wantMerged: []ApexInfo{
- {
- ApexVariationName: "apex10000",
- MinSdkVersion: FutureApiLevel,
- InApexVariants: []string{"foo"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- {
- ApexVariationName: "apex30",
- MinSdkVersion: uncheckedFinalApiLevel(30),
- InApexVariants: []string{"bar"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- },
- wantAliases: [][2]string{
- {"foo", "apex10000"},
- {"bar", "apex30"},
- },
- },
- {
- name: "merge updatable",
- in: []ApexInfo{
- {
- ApexVariationName: "foo",
- MinSdkVersion: FutureApiLevel,
- InApexVariants: []string{"foo"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- {
- ApexVariationName: "bar",
- MinSdkVersion: FutureApiLevel,
- Updatable: true,
- InApexVariants: []string{"bar"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- },
- wantMerged: []ApexInfo{
- {
- ApexVariationName: "apex10000",
- MinSdkVersion: FutureApiLevel,
- Updatable: true,
- InApexVariants: []string{"foo", "bar"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- },
- wantAliases: [][2]string{
- {"foo", "apex10000"},
- {"bar", "apex10000"},
- },
- },
- {
- name: "don't merge when for prebuilt_apex",
- in: []ApexInfo{
- {
- ApexVariationName: "foo",
- MinSdkVersion: FutureApiLevel,
- InApexVariants: []string{"foo"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- {
- ApexVariationName: "bar",
- MinSdkVersion: FutureApiLevel,
- Updatable: true,
- InApexVariants: []string{"bar"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- // This one should not be merged in with the others because it is for
- // a prebuilt_apex.
- {
- ApexVariationName: "baz",
- MinSdkVersion: FutureApiLevel,
- Updatable: true,
- InApexVariants: []string{"baz"},
- ForPrebuiltApex: ForPrebuiltApex,
- },
- },
- wantMerged: []ApexInfo{
- {
- ApexVariationName: "apex10000",
- MinSdkVersion: FutureApiLevel,
- Updatable: true,
- InApexVariants: []string{"foo", "bar"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- {
- ApexVariationName: "baz",
- MinSdkVersion: FutureApiLevel,
- Updatable: true,
- InApexVariants: []string{"baz"},
- ForPrebuiltApex: ForPrebuiltApex,
- },
- },
- wantAliases: [][2]string{
- {"foo", "apex10000"},
- {"bar", "apex10000"},
- },
- },
- {
- name: "merge different UsePlatformApis but don't allow using platform api",
- in: []ApexInfo{
- {
- ApexVariationName: "foo",
- MinSdkVersion: FutureApiLevel,
- InApexVariants: []string{"foo"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- {
- ApexVariationName: "bar",
- MinSdkVersion: FutureApiLevel,
- UsePlatformApis: true,
- InApexVariants: []string{"bar"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- },
- wantMerged: []ApexInfo{
- {
- ApexVariationName: "apex10000",
- MinSdkVersion: FutureApiLevel,
- InApexVariants: []string{"foo", "bar"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- },
- wantAliases: [][2]string{
- {"foo", "apex10000"},
- {"bar", "apex10000"},
- },
- },
- {
- name: "merge same UsePlatformApis and allow using platform api",
- in: []ApexInfo{
- {
- ApexVariationName: "foo",
- MinSdkVersion: FutureApiLevel,
- UsePlatformApis: true,
- InApexVariants: []string{"foo"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- {
- ApexVariationName: "bar",
- MinSdkVersion: FutureApiLevel,
- UsePlatformApis: true,
- InApexVariants: []string{"bar"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- },
- wantMerged: []ApexInfo{
- {
- ApexVariationName: "apex10000",
- MinSdkVersion: FutureApiLevel,
- UsePlatformApis: true,
- InApexVariants: []string{"foo", "bar"},
- ForPrebuiltApex: NotForPrebuiltApex,
- },
- },
- wantAliases: [][2]string{
- {"foo", "apex10000"},
- {"bar", "apex10000"},
- },
- },
- }
-
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- gotMerged, gotAliases := mergeApexVariations(tt.in)
- if !reflect.DeepEqual(gotMerged, tt.wantMerged) {
- t.Errorf("mergeApexVariations() gotMerged = %v, want %v", gotMerged, tt.wantMerged)
- }
- if !reflect.DeepEqual(gotAliases, tt.wantAliases) {
- t.Errorf("mergeApexVariations() gotAliases = %v, want %v", gotAliases, tt.wantAliases)
- }
- })
- }
-}
diff --git a/android/api_levels.go b/android/api_levels.go
index 2b1d01d..c042eeb 100644
--- a/android/api_levels.go
+++ b/android/api_levels.go
@@ -252,6 +252,9 @@
isPreview: true,
}
+// A special ApiLevel that all modules should at least support.
+var MinApiLevel = ApiLevel{number: 1}
+
// Sentinel ApiLevel to validate that an apiLevel is either an int or a recognized codename.
var InvalidApiLevel = NewInvalidApiLevel("invalid")
@@ -311,7 +314,7 @@
// ApiLevelFrom converts the given string `raw` to an ApiLevel.
// If `raw` is invalid (empty string, unrecognized codename etc.) it returns an invalid ApiLevel
-func ApiLevelFrom(ctx PathContext, raw string) ApiLevel {
+func ApiLevelFrom(ctx ConfigContext, raw string) ApiLevel {
ret, err := ApiLevelFromUser(ctx, raw)
if err != nil {
return NewInvalidApiLevel(raw)
@@ -333,7 +336,7 @@
//
// Inputs that are not "current", known previews, or convertible to an integer
// will return an error.
-func ApiLevelFromUser(ctx PathContext, raw string) (ApiLevel, error) {
+func ApiLevelFromUser(ctx ConfigContext, raw string) (ApiLevel, error) {
return ApiLevelFromUserWithConfig(ctx.Config(), raw)
}
@@ -413,7 +416,7 @@
// Converts an API level string `raw` into an ApiLevel in the same method as
// `ApiLevelFromUser`, but the input is assumed to have no errors and any errors
// will panic instead of returning an error.
-func ApiLevelOrPanic(ctx PathContext, raw string) ApiLevel {
+func ApiLevelOrPanic(ctx ConfigContext, raw string) ApiLevel {
value, err := ApiLevelFromUser(ctx, raw)
if err != nil {
panic(err.Error())
@@ -465,6 +468,7 @@
"Tiramisu": 33,
"UpsideDownCake": 34,
"VanillaIceCream": 35,
+ "Baklava": 36,
}, nil
}
diff --git a/android/arch_test.go b/android/arch_test.go
index 7914884..adb655f 100644
--- a/android/arch_test.go
+++ b/android/arch_test.go
@@ -432,7 +432,7 @@
var ret []string
variants := ctx.ModuleVariantsForTests(name)
for _, variant := range variants {
- m := ctx.ModuleForTests(name, variant)
+ m := ctx.ModuleForTests(t, name, variant)
if m.Module().Enabled(PanickingConfigAndErrorContext(ctx)) {
ret = append(ret, variant)
}
@@ -442,7 +442,7 @@
moduleMultiTargets := func(ctx *TestContext, name string, variant string) []string {
var ret []string
- targets := ctx.ModuleForTests(name, variant).Module().MultiTargets()
+ targets := ctx.ModuleForTests(t, name, variant).Module().MultiTargets()
for _, t := range targets {
ret = append(ret, t.String())
}
@@ -546,7 +546,7 @@
var ret []string
variants := ctx.ModuleVariantsForTests(name)
for _, variant := range variants {
- m := ctx.ModuleForTests(name, variant)
+ m := ctx.ModuleForTests(t, name, variant)
if m.Module().Enabled(PanickingConfigAndErrorContext(ctx)) {
ret = append(ret, variant)
}
@@ -758,7 +758,7 @@
for _, want := range tt.results {
t.Run(want.module+"_"+want.variant, func(t *testing.T) {
- got := result.ModuleForTests(want.module, want.variant).Module().(*testArchPropertiesModule).properties.A
+ got := result.ModuleForTests(t, want.module, want.variant).Module().(*testArchPropertiesModule).properties.A
AssertArrayString(t, "arch mutator property", want.property, got)
})
}
diff --git a/android/base_module_context.go b/android/base_module_context.go
index d8558d0..5e05f54 100644
--- a/android/base_module_context.go
+++ b/android/base_module_context.go
@@ -53,6 +53,9 @@
// dependencies on the module being visited, it returns the dependency tag used for the current dependency.
OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
+ // OtherModuleSubDir returns the string representing the variations of a module.
+ OtherModuleSubDir(m blueprint.Module) string
+
// OtherModuleExists returns true if a module with the specified name exists, as determined by the NameInterface
// passed to Context.SetNameInterface, or SimpleNameInterface if it was not called.
OtherModuleExists(name string) bool
@@ -88,6 +91,11 @@
// This method shouldn't be used directly, prefer the type-safe android.OtherModuleProvider instead.
otherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) (any, bool)
+ // OtherModuleHasProvider returns true if the module has the given provider set. This
+ // can avoid copying the provider if the caller only cares about the existence of
+ // the provider.
+ OtherModuleHasProvider(m blueprint.Module, provider blueprint.AnyProviderKey) bool
+
// OtherModuleIsAutoGenerated returns true if the module is auto generated by another module
// instead of being defined in Android.bp file.
OtherModuleIsAutoGenerated(m blueprint.Module) bool
@@ -254,6 +262,9 @@
}
func getWrappedModule(module blueprint.Module) blueprint.Module {
+ if mp, isProxy := module.(*ModuleProxy); isProxy {
+ return mp.module
+ }
if mp, isProxy := module.(ModuleProxy); isProxy {
return mp.module
}
@@ -276,6 +287,9 @@
func (b *baseModuleContext) OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag {
return b.bp.OtherModuleDependencyTag(getWrappedModule(m))
}
+func (b *baseModuleContext) OtherModuleSubDir(m blueprint.Module) string {
+ return b.bp.OtherModuleSubDir(getWrappedModule(m))
+}
func (b *baseModuleContext) OtherModuleExists(name string) bool { return b.bp.OtherModuleExists(name) }
func (b *baseModuleContext) OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool {
return b.bp.OtherModuleDependencyVariantExists(variations, name)
@@ -291,7 +305,11 @@
}
func (b *baseModuleContext) otherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) {
- return b.bp.OtherModuleProvider(m, provider)
+ return b.bp.OtherModuleProvider(getWrappedModule(m), provider)
+}
+
+func (b *baseModuleContext) OtherModuleHasProvider(m blueprint.Module, provider blueprint.AnyProviderKey) bool {
+ return b.bp.OtherModuleHasProvider(getWrappedModule(m), provider)
}
func (b *baseModuleContext) OtherModuleIsAutoGenerated(m blueprint.Module) bool {
diff --git a/android/build_prop_test.go b/android/build_prop_test.go
index e75975a..e136a1a 100644
--- a/android/build_prop_test.go
+++ b/android/build_prop_test.go
@@ -36,6 +36,6 @@
res := GroupFixturePreparers(
FixtureRegisterWithContext(registerBuildPropComponents),
).RunTestWithBp(t, bp)
- buildPropCmd := res.ModuleForTests("vendor-build.prop", "").Rule("vendor-build.prop_.vendor-build.prop").RuleParams.Command
+ buildPropCmd := res.ModuleForTests(t, "vendor-build.prop", "").Rule("vendor-build.prop_.vendor-build.prop").RuleParams.Command
AssertStringDoesContain(t, "Could not find android-info in prop files of vendor build.prop", buildPropCmd, "--prop-files=out/soong/.intermediates/board-info/android-info.prop")
}
diff --git a/android/compliance_metadata.go b/android/compliance_metadata.go
index 2f11df6..a6dbb8d 100644
--- a/android/compliance_metadata.go
+++ b/android/compliance_metadata.go
@@ -43,6 +43,7 @@
STATIC_DEP_FILES string
WHOLE_STATIC_DEPS string
WHOLE_STATIC_DEP_FILES string
+ HEADER_LIBS string
LICENSES string
// module_type=package
@@ -71,6 +72,7 @@
"static_dep_files",
"whole_static_deps",
"whole_static_dep_files",
+ "header_libs",
"licenses",
"pkg_default_applicable_licenses",
@@ -106,6 +108,8 @@
ComplianceMetadataProp.WHOLE_STATIC_DEPS,
// Space separated file paths of whole static dependencies
ComplianceMetadataProp.WHOLE_STATIC_DEP_FILES,
+ // Space separated modules name of header libs
+ ComplianceMetadataProp.HEADER_LIBS,
ComplianceMetadataProp.LICENSES,
// module_type=package
ComplianceMetadataProp.PKG_DEFAULT_APPLICABLE_LICENSES,
@@ -236,8 +240,8 @@
blueprint.RuleParams{
Command: `rm -rf $out && ` +
`${sqlite3} $out ".import --csv $in modules" && ` +
- `([ -z "${make_metadata}" ] || ${sqlite3} $out ".import --csv ${make_metadata} make_metadata") && ` +
- `([ -z "${make_modules}" ] || ${sqlite3} $out ".import --csv ${make_modules} make_modules")`,
+ `${sqlite3} $out ".import --csv ${make_metadata} make_metadata" && ` +
+ `${sqlite3} $out ".import --csv ${make_modules} make_modules"`,
CommandDeps: []string{"${sqlite3}"},
}, "make_metadata", "make_modules")
)
@@ -271,16 +275,18 @@
writerToCsv(csvWriter, columnNames)
rowId := -1
- ctx.VisitAllModules(func(module Module) {
- if !module.Enabled(ctx) {
+ ctx.VisitAllModuleProxies(func(module ModuleProxy) {
+ commonInfo, _ := OtherModuleProvider(ctx, module, CommonModuleInfoKey)
+ if !commonInfo.Enabled {
return
}
+
moduleType := ctx.ModuleType(module)
if moduleType == "package" {
metadataMap := map[string]string{
ComplianceMetadataProp.NAME: ctx.ModuleName(module),
ComplianceMetadataProp.MODULE_TYPE: ctx.ModuleType(module),
- ComplianceMetadataProp.PKG_DEFAULT_APPLICABLE_LICENSES: strings.Join(module.base().primaryLicensesProperty.getStrings(), " "),
+ ComplianceMetadataProp.PKG_DEFAULT_APPLICABLE_LICENSES: strings.Join(commonInfo.PrimaryLicensesProperty.getStrings(), " "),
}
rowId = rowId + 1
metadata := []string{strconv.Itoa(rowId)}
@@ -290,8 +296,7 @@
writerToCsv(csvWriter, metadata)
return
}
- if provider, ok := ctx.otherModuleProvider(module, ComplianceMetadataProvider); ok {
- metadataInfo := provider.(*ComplianceMetadataInfo)
+ if metadataInfo, ok := OtherModuleProvider(ctx, module, ComplianceMetadataProvider); ok {
rowId = rowId + 1
metadata := []string{strconv.Itoa(rowId)}
for _, propertyName := range COMPLIANCE_METADATA_PROPS {
@@ -307,29 +312,29 @@
modulesCsv := PathForOutput(ctx, "compliance-metadata", deviceProduct, "soong-modules.csv")
WriteFileRuleVerbatim(ctx, modulesCsv, buffer.String())
- var implicits []Path
- args := make(map[string]string)
+ // Metadata generated in Make
+ makeMetadataCsv := PathForOutput(ctx, "compliance-metadata", deviceProduct, "make-metadata.csv")
+ makeModulesCsv := PathForOutput(ctx, "compliance-metadata", deviceProduct, "make-modules.csv")
- if ctx.Config().KatiEnabled() {
- // Metadata generated in Make
- makeMetadataCsv := PathForOutput(ctx, "compliance-metadata", deviceProduct, "make-metadata.csv")
- makeModulesCsv := PathForOutput(ctx, "compliance-metadata", deviceProduct, "make-modules.csv")
- implicits = append(implicits, makeMetadataCsv, makeModulesCsv)
- args["make_metadata"] = makeMetadataCsv.String()
- args["make_modules"] = makeModulesCsv.String()
- } else {
- args["make_metadata"] = ""
- args["make_modules"] = ""
+ if !ctx.Config().KatiEnabled() {
+ WriteFileRule(ctx, makeMetadataCsv, "installed_file,module_path,is_soong_module,is_prebuilt_make_module,product_copy_files,kernel_module_copy_files,is_platform_generated,static_libs,whole_static_libs,license_text")
+ WriteFileRule(ctx, makeModulesCsv, "name,module_path,module_class,module_type,static_libs,whole_static_libs,built_files,installed_files")
}
// Import metadata from Make and Soong to sqlite3 database
complianceMetadataDb := PathForOutput(ctx, "compliance-metadata", deviceProduct, "compliance-metadata.db")
ctx.Build(pctx, BuildParams{
- Rule: importCsv,
- Input: modulesCsv,
- Implicits: implicits,
- Output: complianceMetadataDb,
- Args: args,
+ Rule: importCsv,
+ Input: modulesCsv,
+ Implicits: []Path{
+ makeMetadataCsv,
+ makeModulesCsv,
+ },
+ Output: complianceMetadataDb,
+ Args: map[string]string{
+ "make_metadata": makeMetadataCsv.String(),
+ "make_modules": makeModulesCsv.String(),
+ },
})
// Phony rule "compliance-metadata.db". "m compliance-metadata.db" to create the compliance metadata database.
diff --git a/android/config.go b/android/config.go
index 87aacd5..f6d08b8 100644
--- a/android/config.go
+++ b/android/config.go
@@ -294,6 +294,10 @@
return c.config.productVariables.GetBuildFlagBool("RELEASE_FINGERPRINT_ACONFIG_PACKAGES")
}
+func (c Config) ReleaseAconfigCheckApiLevel() bool {
+ return c.config.productVariables.GetBuildFlagBool("RELEASE_ACONFIG_CHECK_API_LEVEL")
+}
+
// A DeviceConfig object represents the configuration for a particular device
// being built. For now there will only be one of these, but in the future there
// may be multiple devices being built.
@@ -382,14 +386,25 @@
type partialCompileFlags struct {
// Is partial compilation enabled at all?
- enabled bool
+ Enabled bool
// Whether to use d8 instead of r8
- use_d8 bool
+ Use_d8 bool
// Add others as needed.
}
+// These are the flags when `SOONG_PARTIAL_COMPILE` is empty or not set.
+var defaultPartialCompileFlags = partialCompileFlags{
+ Enabled: false,
+}
+
+// These are the flags when `SOONG_PARTIAL_COMPILE=true`.
+var enabledPartialCompileFlags = partialCompileFlags{
+ Enabled: true,
+ Use_d8: true,
+}
+
type deviceConfig struct {
config *config
OncePer
@@ -423,11 +438,6 @@
// To add a new feature to the list, add the field in the struct
// `partialCompileFlags` above, and then add the name of the field in the
// switch statement below.
-var defaultPartialCompileFlags = partialCompileFlags{
- // Set any opt-out flags here. Opt-in flags are off by default.
- enabled: false,
-}
-
func (c *config) parsePartialCompileFlags(isEngBuild bool) (partialCompileFlags, error) {
if !isEngBuild {
return partialCompileFlags{}, nil
@@ -468,15 +478,14 @@
}
switch tok {
case "true":
- ret = defaultPartialCompileFlags
- ret.enabled = true
+ ret = enabledPartialCompileFlags
case "false":
// Set everything to false.
ret = partialCompileFlags{}
case "enabled":
- ret.enabled = makeVal(state, defaultPartialCompileFlags.enabled)
+ ret.Enabled = makeVal(state, defaultPartialCompileFlags.Enabled)
case "use_d8":
- ret.use_d8 = makeVal(state, defaultPartialCompileFlags.use_d8)
+ ret.Use_d8 = makeVal(state, defaultPartialCompileFlags.Use_d8)
default:
return partialCompileFlags{}, fmt.Errorf("Unknown SOONG_PARTIAL_COMPILE value: %v", tok)
}
@@ -2167,18 +2176,22 @@
return c.productVariables.GetBuildFlagBool("RELEASE_USE_OPTIMIZED_RESOURCE_SHRINKING_BY_DEFAULT")
}
-func (c *config) UseResourceProcessorByDefault() bool {
- return c.productVariables.GetBuildFlagBool("RELEASE_USE_RESOURCE_PROCESSOR_BY_DEFAULT")
+func (c *config) UseR8FullModeByDefault() bool {
+ return c.productVariables.GetBuildFlagBool("RELEASE_R8_FULL_MODE_BY_DEFAULT")
}
-func (c *config) UseTransitiveJarsInClasspath() bool {
- return c.productVariables.GetBuildFlagBool("RELEASE_USE_TRANSITIVE_JARS_IN_CLASSPATH")
+func (c *config) UseR8OnlyRuntimeVisibleAnnotations() bool {
+ return c.productVariables.GetBuildFlagBool("RELEASE_R8_ONLY_RUNTIME_VISIBLE_ANNOTATIONS")
}
func (c *config) UseR8StoreStoreFenceConstructorInlining() bool {
return c.productVariables.GetBuildFlagBool("RELEASE_R8_STORE_STORE_FENCE_CONSTRUCTOR_INLINING")
}
+func (c *config) UseR8GlobalCheckNotNullFlags() bool {
+ return c.productVariables.GetBuildFlagBool("RELEASE_R8_GLOBAL_CHECK_NOT_NULL_FLAGS")
+}
+
func (c *config) UseDexV41() bool {
return c.productVariables.GetBuildFlagBool("RELEASE_USE_DEX_V41")
}
@@ -2195,7 +2208,7 @@
"RELEASE_APEX_CONTRIBUTIONS_CONFIGINFRASTRUCTURE": "com.android.configinfrastructure",
"RELEASE_APEX_CONTRIBUTIONS_CONNECTIVITY": "com.android.tethering",
"RELEASE_APEX_CONTRIBUTIONS_CONSCRYPT": "com.android.conscrypt",
- "RELEASE_APEX_CONTRIBUTIONS_CRASHRECOVERY": "",
+ "RELEASE_APEX_CONTRIBUTIONS_CRASHRECOVERY": "com.android.crashrecovery",
"RELEASE_APEX_CONTRIBUTIONS_DEVICELOCK": "com.android.devicelock",
"RELEASE_APEX_CONTRIBUTIONS_DOCUMENTSUIGOOGLE": "",
"RELEASE_APEX_CONTRIBUTIONS_EXTSERVICES": "com.android.extservices",
@@ -2206,9 +2219,11 @@
"RELEASE_APEX_CONTRIBUTIONS_MODULE_METADATA": "",
"RELEASE_APEX_CONTRIBUTIONS_NETWORKSTACKGOOGLE": "",
"RELEASE_APEX_CONTRIBUTIONS_NEURALNETWORKS": "com.android.neuralnetworks",
+ "RELEASE_APEX_CONTRIBUTIONS_NFC": "com.android.nfcservices",
"RELEASE_APEX_CONTRIBUTIONS_ONDEVICEPERSONALIZATION": "com.android.ondevicepersonalization",
"RELEASE_APEX_CONTRIBUTIONS_PERMISSION": "com.android.permission",
"RELEASE_APEX_CONTRIBUTIONS_PRIMARY_LIBS": "",
+ "RELEASE_APEX_CONTRIBUTIONS_PROFILING": "com.android.profiling",
"RELEASE_APEX_CONTRIBUTIONS_REMOTEKEYPROVISIONING": "com.android.rkpd",
"RELEASE_APEX_CONTRIBUTIONS_RESOLV": "com.android.resolv",
"RELEASE_APEX_CONTRIBUTIONS_SCHEDULING": "com.android.scheduling",
@@ -2217,6 +2232,7 @@
"RELEASE_APEX_CONTRIBUTIONS_STATSD": "com.android.os.statsd",
"RELEASE_APEX_CONTRIBUTIONS_TELEMETRY_TVP": "",
"RELEASE_APEX_CONTRIBUTIONS_TZDATA": "com.android.tzdata",
+ "RELEASE_APEX_CONTRIBUTIONS_UPROBESTATS": "com.android.uprobestats",
"RELEASE_APEX_CONTRIBUTIONS_UWB": "com.android.uwb",
"RELEASE_APEX_CONTRIBUTIONS_WIFI": "com.android.wifi",
}
@@ -2286,10 +2302,6 @@
return PathsForSource(ctx, c.productVariables.VendorPropFiles)
}
-func (c *config) ExtraAllowedDepsTxt() string {
- return String(c.productVariables.ExtraAllowedDepsTxt)
-}
-
func (c *config) EnableUffdGc() string {
return String(c.productVariables.EnableUffdGc)
}
diff --git a/android/config_test.go b/android/config_test.go
index 4fdcc9c..3d86860 100644
--- a/android/config_test.go
+++ b/android/config_test.go
@@ -214,12 +214,12 @@
}
func (p partialCompileFlags) updateEnabled(value bool) partialCompileFlags {
- p.enabled = value
+ p.Enabled = value
return p
}
func (p partialCompileFlags) updateUseD8(value bool) partialCompileFlags {
- p.use_d8 = value
+ p.Use_d8 = value
return p
}
@@ -239,10 +239,10 @@
}{
{"", true, defaultPartialCompileFlags},
{"false", true, partialCompileFlags{}},
- {"true", true, defaultPartialCompileFlags.updateEnabled(true)},
+ {"true", true, enabledPartialCompileFlags},
{"true", false, partialCompileFlags{}},
- {"true,use_d8", true, defaultPartialCompileFlags.updateEnabled(true).updateUseD8(true)},
- {"true,-use_d8", true, defaultPartialCompileFlags.updateEnabled(true).updateUseD8(false)},
+ {"true,use_d8", true, enabledPartialCompileFlags.updateUseD8(true)},
+ {"true,-use_d8", true, enabledPartialCompileFlags.updateUseD8(false)},
{"use_d8,false", true, partialCompileFlags{}},
{"false,+use_d8", true, partialCompileFlags{}.updateUseD8(true)},
}
diff --git a/android/container.go b/android/container.go
index 882535e..5dc97d3 100644
--- a/android/container.go
+++ b/android/container.go
@@ -167,8 +167,8 @@
}
var apexContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bool {
- _, ok := ModuleProvider(mctx, AllApexInfoProvider)
- return ok
+ // TODO(b/394955484): a module can't determine the apexes it belongs to any more
+ return false
}
var ctsContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bool {
@@ -198,7 +198,7 @@
unstableModule := module.Name() == "framework-minus-apex"
if installable, ok := module.(InstallableModule); ok {
for _, staticDepTag := range installable.StaticDependencyTags() {
- mctx.VisitDirectDepsWithTag(staticDepTag, func(dep Module) {
+ mctx.VisitDirectDepsProxyWithTag(staticDepTag, func(dep ModuleProxy) {
if unstableInfo, ok := OtherModuleProvider(mctx, dep, unstableInfoProvider); ok {
unstableModule = unstableModule || unstableInfo.ContainsPlatformPrivateApis
}
@@ -380,7 +380,7 @@
func (c *ContainersInfo) ApexNames() (ret []string) {
for _, apex := range c.belongingApexes {
- ret = append(ret, apex.InApexVariants...)
+ ret = append(ret, apex.BaseApexName)
}
slices.Sort(ret)
return ret
@@ -441,14 +441,10 @@
}
}
- var belongingApexes []ApexInfo
- if apexInfo, ok := ModuleProvider(ctx, AllApexInfoProvider); ok {
- belongingApexes = apexInfo.ApexInfos
- }
-
return ContainersInfo{
belongingContainers: containers,
- belongingApexes: belongingApexes,
+ // TODO(b/394955484): a module can't determine the apexes it belongs to any more
+ belongingApexes: nil,
}
}
diff --git a/android/container_violations.go b/android/container_violations.go
index e1583c5..4c6386d 100644
--- a/android/container_violations.go
+++ b/android/container_violations.go
@@ -997,7 +997,7 @@
"android.nfc.flags-aconfig-java", // apex [com.android.nfcservices] -> system
"android.permission.flags-aconfig-java", // apex [com.android.nfcservices] -> apex [com.android.permission, test_com.android.permission]
// TODO(b/383782511): Remove the violations once the infra is fixed.
- "framework-nfc.impl", // apex [com.android.nfcservices] -> system
+ "framework-nfc.impl", // apex [com.android.nfcservices] -> system
},
"okhttp-norepackage": {
diff --git a/android/csuite_config_test.go b/android/csuite_config_test.go
index b8a176e..7e25aac 100644
--- a/android/csuite_config_test.go
+++ b/android/csuite_config_test.go
@@ -32,7 +32,6 @@
if len(variants) > 1 {
t.Errorf("expected 1, got %d", len(variants))
}
- outputFilename := result.ModuleForTests(
- "plain", variants[0]).Module().(*CSuiteConfig).OutputFilePath.Base()
+ outputFilename := result.ModuleForTests(t, "plain", variants[0]).Module().(*CSuiteConfig).OutputFilePath.Base()
AssertStringEquals(t, "output file name", "plain", outputFilename)
}
diff --git a/android/deapexer.go b/android/deapexer.go
index 4049d2b..6d00dcd 100644
--- a/android/deapexer.go
+++ b/android/deapexer.go
@@ -75,8 +75,6 @@
// map from the name of an exported file from a prebuilt_apex to the path to that file. The
// exported file name is the apex relative path, e.g. javalib/core-libart.jar.
- //
- // See Prebuilt.ApexInfoMutator for more information.
exports map[string]WritablePath
// name of the java libraries exported from the apex
diff --git a/android/defaults.go b/android/defaults.go
index 510ebe0..0fc1768 100644
--- a/android/defaults.go
+++ b/android/defaults.go
@@ -178,6 +178,7 @@
module.AddProperties(
&hostAndDeviceProperties{},
commonProperties,
+ &baseProperties{},
&ApexProperties{},
&distProperties{})
diff --git a/android/defaults_test.go b/android/defaults_test.go
index 0ad0fb8..24f1461 100644
--- a/android/defaults_test.go
+++ b/android/defaults_test.go
@@ -123,8 +123,8 @@
FixtureWithRootAndroidBp(bp),
).RunTest(t)
- missingDefaults := result.ModuleForTests("missing_defaults", "").Output("out")
- missingTransitiveDefaults := result.ModuleForTests("missing_transitive_defaults", "").Output("out")
+ missingDefaults := result.ModuleForTests(t, "missing_defaults", "").Output("out")
+ missingTransitiveDefaults := result.ModuleForTests(t, "missing_transitive_defaults", "").Output("out")
AssertSame(t, "missing_defaults rule", ErrorRule, missingDefaults.Rule)
diff --git a/android/defs.go b/android/defs.go
index 9f3fb1e..57fcc9b 100644
--- a/android/defs.go
+++ b/android/defs.go
@@ -51,6 +51,14 @@
},
"cpFlags", "extraCmds")
+ // A copy rule wrapped with bash.
+ CpWithBash = pctx.AndroidStaticRule("CpWithBash",
+ blueprint.RuleParams{
+ Command: "/bin/bash -c \"rm -f $out && cp $cpFlags $cpPreserveSymlinks $in $out$extraCmds\"",
+ Description: "cp $out",
+ },
+ "cpFlags", "extraCmds")
+
// A copy rule that doesn't preserve symlinks.
CpNoPreserveSymlink = pctx.AndroidStaticRule("CpNoPreserveSymlink",
blueprint.RuleParams{
@@ -74,6 +82,14 @@
},
"cpFlags", "extraCmds")
+ // A copy executable rule wrapped with bash
+ CpExecutableWithBash = pctx.AndroidStaticRule("CpExecutableWithBash",
+ blueprint.RuleParams{
+ Command: "/bin/bash -c \"(rm -f $out && cp $cpFlags $cpPreserveSymlinks $in $out ) && (chmod +x $out$extraCmds )\"",
+ Description: "cp $out",
+ },
+ "cpFlags", "extraCmds")
+
// A timestamp touch rule.
Touch = pctx.AndroidStaticRule("Touch",
blueprint.RuleParams{
@@ -89,6 +105,14 @@
},
"fromPath")
+ // A symlink rule wrapped with bash
+ SymlinkWithBash = pctx.AndroidStaticRule("SymlinkWithBash",
+ blueprint.RuleParams{
+ Command: "/bin/bash -c \"rm -f $out && ln -sfn $fromPath $out\"",
+ Description: "symlink $out",
+ },
+ "fromPath")
+
ErrorRule = pctx.AndroidStaticRule("Error",
blueprint.RuleParams{
Command: `echo "$error" && false`,
@@ -119,3 +143,13 @@
return ctx.Config().RBEWrapper()
})
}
+
+// CopyFileRule creates a ninja rule to copy path to outPath.
+func CopyFileRule(ctx ModuleContext, path Path, outPath OutputPath) {
+ ctx.Build(pctx, BuildParams{
+ Rule: Cp,
+ Input: path,
+ Output: outPath,
+ Description: "copy " + outPath.Base(),
+ })
+}
diff --git a/android/deptag_test.go b/android/deptag_test.go
index eb4fa89..9037871 100644
--- a/android/deptag_test.go
+++ b/android/deptag_test.go
@@ -90,10 +90,10 @@
config := result.Config
- hostFoo := result.ModuleForTests("foo", config.BuildOSCommonTarget.String()).Description("install")
- hostInstallDep := result.ModuleForTests("install_dep", config.BuildOSCommonTarget.String()).Description("install")
- hostTransitive := result.ModuleForTests("transitive", config.BuildOSCommonTarget.String()).Description("install")
- hostDep := result.ModuleForTests("dep", config.BuildOSCommonTarget.String()).Description("install")
+ hostFoo := result.ModuleForTests(t, "foo", config.BuildOSCommonTarget.String()).Description("install")
+ hostInstallDep := result.ModuleForTests(t, "install_dep", config.BuildOSCommonTarget.String()).Description("install")
+ hostTransitive := result.ModuleForTests(t, "transitive", config.BuildOSCommonTarget.String()).Description("install")
+ hostDep := result.ModuleForTests(t, "dep", config.BuildOSCommonTarget.String()).Description("install")
if g, w := hostFoo.Implicits.Strings(), hostInstallDep.Output.String(); !InList(w, g) {
t.Errorf("expected host dependency %q, got %q", w, g)
@@ -111,10 +111,10 @@
t.Errorf("expected no host dependency %q, got %q", w, g)
}
- deviceFoo := result.ModuleForTests("foo", "android_common").Description("install")
- deviceInstallDep := result.ModuleForTests("install_dep", "android_common").Description("install")
- deviceTransitive := result.ModuleForTests("transitive", "android_common").Description("install")
- deviceDep := result.ModuleForTests("dep", "android_common").Description("install")
+ deviceFoo := result.ModuleForTests(t, "foo", "android_common").Description("install")
+ deviceInstallDep := result.ModuleForTests(t, "install_dep", "android_common").Description("install")
+ deviceTransitive := result.ModuleForTests(t, "transitive", "android_common").Description("install")
+ deviceDep := result.ModuleForTests(t, "dep", "android_common").Description("install")
if g, w := deviceFoo.OrderOnly.Strings(), deviceInstallDep.Output.String(); !InList(w, g) {
t.Errorf("expected device dependency %q, got %q", w, g)
diff --git a/android/filegroup.go b/android/filegroup.go
index 4daff8f..47102b9 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -41,11 +41,11 @@
Exclude_srcs proptools.Configurable[[]string] `android:"path"`
- // Sources the will be included in the filegroup, but any module dependencies will be added
+ // Sources that will be included in the filegroup, but any module dependencies will be added
// using the device os and the device's first architecture's variant.
Device_first_srcs proptools.Configurable[[]string] `android:"path_device_first"`
- // Sources the will be included in the filegroup, but any module dependencies will be added
+ // Sources that will be included in the filegroup, but any module dependencies will be added
// using the device os and the common architecture's variant.
Device_common_srcs proptools.Configurable[[]string] `android:"path_device_common"`
diff --git a/android/fixture.go b/android/fixture.go
index 5ad47e8..ea52b95 100644
--- a/android/fixture.go
+++ b/android/fixture.go
@@ -1048,7 +1048,7 @@
// Module returns the module with the specific name and of the specified variant.
func (r *TestResult) Module(name string, variant string) Module {
- return r.ModuleForTests(name, variant).Module()
+ return r.ModuleForTests(r.fixture.t, name, variant).Module()
}
// CollateErrs adds additional errors to the result and returns true if there is more than one
diff --git a/android/hooks.go b/android/hooks.go
index f8022d0..5d509a4 100644
--- a/android/hooks.go
+++ b/android/hooks.go
@@ -100,12 +100,12 @@
l.appendPrependHelper(props, proptools.PrependMatchingProperties)
}
-func (l *loadHookContext) createModule(factory blueprint.ModuleFactory, name string, props ...interface{}) blueprint.Module {
- return l.bp.CreateModule(factory, name, props...)
+func (l *loadHookContext) createModule(factory blueprint.ModuleFactory, name string, props ...interface{}) Module {
+ return bpModuleToModule(l.bp.CreateModule(factory, name, props...))
}
-func (l *loadHookContext) createModuleInDirectory(factory blueprint.ModuleFactory, name, moduleDir string, props ...interface{}) blueprint.Module {
- return l.bp.CreateModuleInDirectory(factory, name, moduleDir, props...)
+func (l *loadHookContext) createModuleInDirectory(factory blueprint.ModuleFactory, name, moduleDir string, props ...interface{}) Module {
+ return bpModuleToModule(l.bp.CreateModuleInDirectory(factory, name, moduleDir, props...))
}
type specifyDirectory struct {
@@ -130,8 +130,8 @@
type createModuleContext interface {
Module() Module
HasMutatorFinished(mutatorName string) bool
- createModule(blueprint.ModuleFactory, string, ...interface{}) blueprint.Module
- createModuleInDirectory(blueprint.ModuleFactory, string, string, ...interface{}) blueprint.Module
+ createModule(blueprint.ModuleFactory, string, ...interface{}) Module
+ createModuleInDirectory(blueprint.ModuleFactory, string, string, ...interface{}) Module
}
func createModule(ctx createModuleContext, factory ModuleFactory, ext string, specifyDirectory specifyDirectory, props ...interface{}) Module {
diff --git a/android/license.go b/android/license.go
index 5bffc25..7b4aeeb 100644
--- a/android/license.go
+++ b/android/license.go
@@ -18,6 +18,15 @@
"github.com/google/blueprint"
)
+type LicenseInfo struct {
+ PackageName *string
+ EffectiveLicenseText NamedPaths
+ EffectiveLicenseKinds []string
+ EffectiveLicenseConditions []string
+}
+
+var LicenseInfoProvider = blueprint.NewProvider[LicenseInfo]()
+
type licenseKindDependencyTag struct {
blueprint.BaseDependencyTag
}
@@ -69,16 +78,24 @@
func (m *licenseModule) GenerateAndroidBuildActions(ctx ModuleContext) {
// license modules have no licenses, but license_kinds must refer to license_kind modules
- mergeStringProps(&m.base().commonProperties.Effective_licenses, ctx.ModuleName())
namePathProps(&m.base().commonProperties.Effective_license_text, m.properties.Package_name, PathsForModuleSrc(ctx, m.properties.License_text)...)
- for _, module := range ctx.GetDirectDepsWithTag(licenseKindTag) {
- if lk, ok := module.(*licenseKindModule); ok {
- mergeStringProps(&m.base().commonProperties.Effective_license_conditions, lk.properties.Conditions...)
- mergeStringProps(&m.base().commonProperties.Effective_license_kinds, ctx.OtherModuleName(module))
+ var conditions []string
+ var kinds []string
+ for _, module := range ctx.GetDirectDepsProxyWithTag(licenseKindTag) {
+ if lk, ok := OtherModuleProvider(ctx, module, LicenseKindInfoProvider); ok {
+ conditions = append(conditions, lk.Conditions...)
+ kinds = append(kinds, ctx.OtherModuleName(module))
} else {
ctx.ModuleErrorf("license_kinds property %q is not a license_kind module", ctx.OtherModuleName(module))
}
}
+
+ SetProvider(ctx, LicenseInfoProvider, LicenseInfo{
+ PackageName: m.properties.Package_name,
+ EffectiveLicenseText: m.base().commonProperties.Effective_license_text,
+ EffectiveLicenseKinds: SortedUniqueStrings(kinds),
+ EffectiveLicenseConditions: SortedUniqueStrings(conditions),
+ })
}
func LicenseFactory() Module {
diff --git a/android/license_kind.go b/android/license_kind.go
index 838dedd..1ca6954 100644
--- a/android/license_kind.go
+++ b/android/license_kind.go
@@ -14,6 +14,14 @@
package android
+import "github.com/google/blueprint"
+
+type LicenseKindInfo struct {
+ Conditions []string
+}
+
+var LicenseKindInfoProvider = blueprint.NewProvider[LicenseKindInfo]()
+
func init() {
RegisterLicenseKindBuildComponents(InitRegistrationContext)
}
@@ -43,8 +51,10 @@
// Nothing to do.
}
-func (m *licenseKindModule) GenerateAndroidBuildActions(ModuleContext) {
- // Nothing to do.
+func (m *licenseKindModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+ SetProvider(ctx, LicenseKindInfoProvider, LicenseKindInfo{
+ Conditions: m.properties.Conditions,
+ })
}
func LicenseKindFactory() Module {
diff --git a/android/licenses.go b/android/licenses.go
index 53d0555..32d12c8 100644
--- a/android/licenses.go
+++ b/android/licenses.go
@@ -227,16 +227,18 @@
}
var licenses []string
- for _, module := range ctx.GetDirectDepsWithTag(licensesTag) {
- if l, ok := module.(*licenseModule); ok {
+ var texts NamedPaths
+ var conditions []string
+ var kinds []string
+ for _, module := range ctx.GetDirectDepsProxyWithTag(licensesTag) {
+ if l, ok := OtherModuleProvider(ctx, module, LicenseInfoProvider); ok {
licenses = append(licenses, ctx.OtherModuleName(module))
- if m.base().commonProperties.Effective_package_name == nil && l.properties.Package_name != nil {
- m.base().commonProperties.Effective_package_name = l.properties.Package_name
+ if m.base().commonProperties.Effective_package_name == nil && l.PackageName != nil {
+ m.base().commonProperties.Effective_package_name = l.PackageName
}
- mergeStringProps(&m.base().commonProperties.Effective_licenses, module.base().commonProperties.Effective_licenses...)
- mergeNamedPathProps(&m.base().commonProperties.Effective_license_text, module.base().commonProperties.Effective_license_text...)
- mergeStringProps(&m.base().commonProperties.Effective_license_kinds, module.base().commonProperties.Effective_license_kinds...)
- mergeStringProps(&m.base().commonProperties.Effective_license_conditions, module.base().commonProperties.Effective_license_conditions...)
+ texts = append(texts, l.EffectiveLicenseText...)
+ kinds = append(kinds, l.EffectiveLicenseKinds...)
+ conditions = append(conditions, l.EffectiveLicenseConditions...)
} else {
propertyName := "licenses"
primaryProperty := m.base().primaryLicensesProperty
@@ -247,17 +249,15 @@
}
}
+ m.base().commonProperties.Effective_license_text = SortedUniqueNamedPaths(texts)
+ m.base().commonProperties.Effective_license_kinds = SortedUniqueStrings(kinds)
+ m.base().commonProperties.Effective_license_conditions = SortedUniqueStrings(conditions)
+
// Make the license information available for other modules.
- licenseInfo := LicenseInfo{
+ licenseInfo := LicensesInfo{
Licenses: licenses,
}
- SetProvider(ctx, LicenseInfoProvider, licenseInfo)
-}
-
-// Update a property string array with a distinct union of its values and a list of new values.
-func mergeStringProps(prop *[]string, values ...string) {
- *prop = append(*prop, values...)
- *prop = SortedUniqueStrings(*prop)
+ SetProvider(ctx, LicensesInfoProvider, licenseInfo)
}
// Update a property NamedPath array with a distinct union of its values and a list of new values.
@@ -274,12 +274,6 @@
*prop = SortedUniqueNamedPaths(*prop)
}
-// Update a property NamedPath array with a distinct union of its values and a list of new values.
-func mergeNamedPathProps(prop *NamedPaths, values ...NamedPath) {
- *prop = append(*prop, values...)
- *prop = SortedUniqueNamedPaths(*prop)
-}
-
// Get the licenses property falling back to the package default.
func getLicenses(ctx BaseModuleContext, module Module) []string {
if exemptFromRequiredApplicableLicensesProperty(module) {
@@ -336,14 +330,14 @@
return true
}
-// LicenseInfo contains information about licenses for a specific module.
-type LicenseInfo struct {
+// LicensesInfo contains information about licenses for a specific module.
+type LicensesInfo struct {
// The list of license modules this depends upon, either explicitly or through default package
// configuration.
Licenses []string
}
-var LicenseInfoProvider = blueprint.NewProvider[LicenseInfo]()
+var LicensesInfoProvider = blueprint.NewProvider[LicensesInfo]()
func init() {
RegisterMakeVarsProvider(pctx, licensesMakeVarsProvider)
diff --git a/android/licenses_test.go b/android/licenses_test.go
index 8a81e12..0c371e8 100644
--- a/android/licenses_test.go
+++ b/android/licenses_test.go
@@ -7,15 +7,13 @@
)
var licensesTests = []struct {
- name string
- fs MockFS
- expectedErrors []string
- effectiveLicenses map[string][]string
- effectiveInheritedLicenses map[string][]string
- effectivePackage map[string]string
- effectiveNotices map[string][]string
- effectiveKinds map[string][]string
- effectiveConditions map[string][]string
+ name string
+ fs MockFS
+ expectedErrors []string
+ effectivePackage map[string]string
+ effectiveNotices map[string][]string
+ effectiveKinds map[string][]string
+ effectiveConditions map[string][]string
}{
{
name: "invalid module type without licenses property",
@@ -69,11 +67,6 @@
licenses: ["top_Apache2"],
}`),
},
- effectiveLicenses: map[string][]string{
- "libexample1": []string{"top_Apache2"},
- "libnested": []string{"top_Apache2"},
- "libother": []string{"top_Apache2"},
- },
effectiveKinds: map[string][]string{
"libexample1": []string{"notice"},
"libnested": []string{"notice"},
@@ -146,18 +139,6 @@
deps: ["libexample"],
}`),
},
- effectiveLicenses: map[string][]string{
- "libexample": []string{"nested_other", "top_other"},
- "libsamepackage": []string{},
- "libnested": []string{},
- "libother": []string{},
- },
- effectiveInheritedLicenses: map[string][]string{
- "libexample": []string{"nested_other", "top_other"},
- "libsamepackage": []string{"nested_other", "top_other"},
- "libnested": []string{"nested_other", "top_other"},
- "libother": []string{"nested_other", "top_other"},
- },
effectiveKinds: map[string][]string{
"libexample": []string{"nested_notice", "top_notice"},
"libsamepackage": []string{},
@@ -217,20 +198,6 @@
deps: ["libexample"],
}`),
},
- effectiveLicenses: map[string][]string{
- "libexample": []string{"other", "top_nested"},
- "libsamepackage": []string{},
- "libnested": []string{},
- "libother": []string{},
- "liboutsider": []string{},
- },
- effectiveInheritedLicenses: map[string][]string{
- "libexample": []string{"other", "top_nested"},
- "libsamepackage": []string{"other", "top_nested"},
- "libnested": []string{"other", "top_nested"},
- "libother": []string{"other", "top_nested"},
- "liboutsider": []string{"other", "top_nested"},
- },
effectiveKinds: map[string][]string{
"libexample": []string{},
"libsamepackage": []string{},
@@ -284,14 +251,6 @@
defaults: ["top_defaults"],
}`),
},
- effectiveLicenses: map[string][]string{
- "libexample": []string{"by_exception_only"},
- "libdefaults": []string{"notice"},
- },
- effectiveInheritedLicenses: map[string][]string{
- "libexample": []string{"by_exception_only"},
- "libdefaults": []string{"notice"},
- },
},
// Package default_applicable_licenses tests
@@ -326,14 +285,6 @@
deps: ["libexample"],
}`),
},
- effectiveLicenses: map[string][]string{
- "libexample": []string{"top_notice"},
- "liboutsider": []string{},
- },
- effectiveInheritedLicenses: map[string][]string{
- "libexample": []string{"top_notice"},
- "liboutsider": []string{"top_notice"},
- },
},
{
name: "package default_applicable_licenses not inherited to subpackages",
@@ -369,18 +320,6 @@
deps: ["libexample", "libother", "libnested"],
}`),
},
- effectiveLicenses: map[string][]string{
- "libexample": []string{"top_notice"},
- "libnested": []string{"outsider"},
- "libother": []string{},
- "liboutsider": []string{},
- },
- effectiveInheritedLicenses: map[string][]string{
- "libexample": []string{"top_notice"},
- "libnested": []string{"outsider"},
- "libother": []string{},
- "liboutsider": []string{"top_notice", "outsider"},
- },
},
{
name: "verify that prebuilt dependencies are included",
@@ -409,12 +348,6 @@
deps: [":module"],
}`),
},
- effectiveLicenses: map[string][]string{
- "other": []string{},
- },
- effectiveInheritedLicenses: map[string][]string{
- "other": []string{"prebuilt", "top_sources"},
- },
},
{
name: "verify that prebuilt dependencies are ignored for licenses reasons (preferred)",
@@ -444,13 +377,6 @@
deps: [":module"],
}`),
},
- effectiveLicenses: map[string][]string{
- "other": []string{},
- },
- effectiveInheritedLicenses: map[string][]string{
- "module": []string{"prebuilt", "top_sources"},
- "other": []string{"prebuilt", "top_sources"},
- },
},
}
@@ -470,10 +396,6 @@
ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)).
RunTest(t)
- if test.effectiveLicenses != nil {
- checkEffectiveLicenses(t, result, test.effectiveLicenses)
- }
-
if test.effectivePackage != nil {
checkEffectivePackage(t, result, test.effectivePackage)
}
@@ -489,114 +411,10 @@
if test.effectiveConditions != nil {
checkEffectiveConditions(t, result, test.effectiveConditions)
}
-
- if test.effectiveInheritedLicenses != nil {
- checkEffectiveInheritedLicenses(t, result, test.effectiveInheritedLicenses)
- }
})
}
}
-func checkEffectiveLicenses(t *testing.T, result *TestResult, effectiveLicenses map[string][]string) {
- actualLicenses := make(map[string][]string)
- result.Context.Context.VisitAllModules(func(m blueprint.Module) {
- if _, ok := m.(*licenseModule); ok {
- return
- }
- if _, ok := m.(*licenseKindModule); ok {
- return
- }
- if _, ok := m.(*packageModule); ok {
- return
- }
- module, ok := m.(Module)
- if !ok {
- t.Errorf("%q not a module", m.Name())
- return
- }
- base := module.base()
- if base == nil {
- return
- }
- actualLicenses[m.Name()] = base.commonProperties.Effective_licenses
- })
-
- for moduleName, expectedLicenses := range effectiveLicenses {
- licenses, ok := actualLicenses[moduleName]
- if !ok {
- licenses = []string{}
- }
- if !compareUnorderedStringArrays(expectedLicenses, licenses) {
- t.Errorf("effective licenses mismatch for module %q: expected %q, found %q", moduleName, expectedLicenses, licenses)
- }
- }
-}
-
-func checkEffectiveInheritedLicenses(t *testing.T, result *TestResult, effectiveInheritedLicenses map[string][]string) {
- actualLicenses := make(map[string][]string)
- result.Context.Context.VisitAllModules(func(m blueprint.Module) {
- if _, ok := m.(*licenseModule); ok {
- return
- }
- if _, ok := m.(*licenseKindModule); ok {
- return
- }
- if _, ok := m.(*packageModule); ok {
- return
- }
- module, ok := m.(Module)
- if !ok {
- t.Errorf("%q not a module", m.Name())
- return
- }
- base := module.base()
- if base == nil {
- return
- }
- inherited := make(map[string]bool)
- for _, l := range base.commonProperties.Effective_licenses {
- inherited[l] = true
- }
- result.Context.Context.VisitDepsDepthFirst(m, func(c blueprint.Module) {
- if _, ok := c.(*licenseModule); ok {
- return
- }
- if _, ok := c.(*licenseKindModule); ok {
- return
- }
- if _, ok := c.(*packageModule); ok {
- return
- }
- cmodule, ok := c.(Module)
- if !ok {
- t.Errorf("%q not a module", c.Name())
- return
- }
- cbase := cmodule.base()
- if cbase == nil {
- return
- }
- for _, l := range cbase.commonProperties.Effective_licenses {
- inherited[l] = true
- }
- })
- actualLicenses[m.Name()] = []string{}
- for l := range inherited {
- actualLicenses[m.Name()] = append(actualLicenses[m.Name()], l)
- }
- })
-
- for moduleName, expectedInheritedLicenses := range effectiveInheritedLicenses {
- licenses, ok := actualLicenses[moduleName]
- if !ok {
- licenses = []string{}
- }
- if !compareUnorderedStringArrays(expectedInheritedLicenses, licenses) {
- t.Errorf("effective inherited licenses mismatch for module %q: expected %q, found %q", moduleName, expectedInheritedLicenses, licenses)
- }
- }
-}
-
func checkEffectivePackage(t *testing.T, result *TestResult, effectivePackage map[string]string) {
actualPackage := make(map[string]string)
result.Context.Context.VisitAllModules(func(m blueprint.Module) {
diff --git a/android/makevars.go b/android/makevars.go
index 8305d8e..2931d0b 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -65,24 +65,6 @@
// dependencies to be added to it. Phony can be called on the same name multiple
// times to add additional dependencies.
Phony(names string, deps ...Path)
-
- // DistForGoal creates a rule to copy one or more Paths to the artifacts
- // directory on the build server when the specified goal is built.
- DistForGoal(goal string, paths ...Path)
-
- // DistForGoalWithFilename creates a rule to copy a Path to the artifacts
- // directory on the build server with the given filename when the specified
- // goal is built.
- DistForGoalWithFilename(goal string, path Path, filename string)
-
- // DistForGoals creates a rule to copy one or more Paths to the artifacts
- // directory on the build server when any of the specified goals are built.
- DistForGoals(goals []string, paths ...Path)
-
- // DistForGoalsWithFilename creates a rule to copy a Path to the artifacts
- // directory on the build server with the given filename when any of the
- // specified goals are built.
- DistForGoalsWithFilename(goals []string, path Path, filename string)
}
// MakeVarsContext contains the set of functions available for MakeVarsProvider
@@ -185,6 +167,7 @@
type makeVarsSingleton struct {
varsForTesting []makeVarsVariable
installsForTesting []byte
+ lateForTesting []byte
}
type makeVarsProvider struct {
@@ -197,11 +180,9 @@
type makeVarsContext struct {
SingletonContext
- config Config
pctx PackageContext
vars []makeVarsVariable
phonies []phony
- dists []dist
}
var _ MakeVarsContext = &makeVarsContext{}
@@ -220,7 +201,7 @@
type dist struct {
goals []string
- paths []string
+ paths distCopies
}
func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
@@ -262,9 +243,13 @@
vars = append(vars, mctx.vars...)
phonies = append(phonies, mctx.phonies...)
- dists = append(dists, mctx.dists...)
}
+ singletonDists := getSingletonDists(ctx.Config())
+ singletonDists.lock.Lock()
+ dists = append(dists, singletonDists.dists...)
+ singletonDists.lock.Unlock()
+
ctx.VisitAllModules(func(m Module) {
if provider, ok := m.(ModuleMakeVarsProvider); ok && m.Enabled(ctx) {
mctx := &makeVarsContext{
@@ -275,7 +260,6 @@
vars = append(vars, mctx.vars...)
phonies = append(phonies, mctx.phonies...)
- dists = append(dists, mctx.dists...)
}
if m.ExportedToMake() {
@@ -285,6 +269,10 @@
katiVintfManifestInstalls = append(katiVintfManifestInstalls, info.KatiVintfInstalls...)
katiSymlinks = append(katiSymlinks, info.KatiSymlinks...)
}
+
+ if distInfo, ok := OtherModuleProvider(ctx, m, DistProvider); ok {
+ dists = append(dists, distInfo.Dists...)
+ }
})
compareKatiInstalls := func(a, b katiInstall) int {
@@ -318,19 +306,12 @@
sort.Slice(phonies, func(i, j int) bool {
return phonies[i].name < phonies[j].name
})
- lessArr := func(a, b []string) bool {
- if len(a) == len(b) {
- for i := range a {
- if a[i] < b[i] {
- return true
- }
- }
- return false
- }
- return len(a) < len(b)
- }
sort.Slice(dists, func(i, j int) bool {
- return lessArr(dists[i].goals, dists[j].goals) || lessArr(dists[i].paths, dists[j].paths)
+ goals := slices.Compare(dists[i].goals, dists[j].goals)
+ if goals != 0 {
+ return goals < 0
+ }
+ return slices.Compare(dists[i].paths.Strings(), dists[j].paths.Strings()) < 0
})
outBytes := s.writeVars(vars)
@@ -354,6 +335,7 @@
if ctx.Config().RunningInsideUnitTest() {
s.varsForTesting = vars
s.installsForTesting = installsBytes
+ s.lateForTesting = lateOutBytes
}
}
@@ -458,7 +440,7 @@
for _, dist := range dists {
fmt.Fprintf(buf, ".PHONY: %s\n", strings.Join(dist.goals, " "))
fmt.Fprintf(buf, "$(call dist-for-goals,%s,%s)\n",
- strings.Join(dist.goals, " "), strings.Join(dist.paths, " "))
+ strings.Join(dist.goals, " "), strings.Join(dist.paths.Strings(), " "))
}
return buf.Bytes()
@@ -607,13 +589,6 @@
c.phonies = append(c.phonies, phony{name, deps})
}
-func (c *makeVarsContext) addDist(goals []string, paths []string) {
- c.dists = append(c.dists, dist{
- goals: goals,
- paths: paths,
- })
-}
-
func (c *makeVarsContext) Strict(name, ninjaStr string) {
c.addVariable(name, ninjaStr, true, false)
}
@@ -637,19 +612,3 @@
func (c *makeVarsContext) Phony(name string, deps ...Path) {
c.addPhony(name, Paths(deps).Strings())
}
-
-func (c *makeVarsContext) DistForGoal(goal string, paths ...Path) {
- c.DistForGoals([]string{goal}, paths...)
-}
-
-func (c *makeVarsContext) DistForGoalWithFilename(goal string, path Path, filename string) {
- c.DistForGoalsWithFilename([]string{goal}, path, filename)
-}
-
-func (c *makeVarsContext) DistForGoals(goals []string, paths ...Path) {
- c.addDist(goals, Paths(paths).Strings())
-}
-
-func (c *makeVarsContext) DistForGoalsWithFilename(goals []string, path Path, filename string) {
- c.addDist(goals, []string{path.String() + ":" + filename})
-}
diff --git a/android/makevars_test.go b/android/makevars_test.go
new file mode 100644
index 0000000..387d457
--- /dev/null
+++ b/android/makevars_test.go
@@ -0,0 +1,96 @@
+package android
+
+import (
+ "regexp"
+ "testing"
+)
+
+func TestDistFilesInGenerateAndroidBuildActions(t *testing.T) {
+ result := GroupFixturePreparers(
+ FixtureRegisterWithContext(func(ctx RegistrationContext) {
+ ctx.RegisterModuleType("my_module_type", newDistFileModule)
+ ctx.RegisterParallelSingletonType("my_singleton", newDistFileSingleton)
+ ctx.RegisterParallelSingletonModuleType("my_singleton_module", newDistFileSingletonModule)
+ }),
+ FixtureModifyConfig(SetKatiEnabledForTests),
+ PrepareForTestWithMakevars,
+ ).RunTestWithBp(t, `
+ my_module_type {
+ name: "foo",
+ }
+ my_singleton_module {
+ name: "bar"
+ }
+ `)
+
+ lateContents := string(result.SingletonForTests(t, "makevars").Singleton().(*makeVarsSingleton).lateForTesting)
+ matched, err := regexp.MatchString(`call dist-for-goals,my_goal,.*/my_file.txt:my_file.txt\)`, lateContents)
+ if err != nil || !matched {
+ t.Fatalf("Expected a dist of my_file.txt, but got: %s", lateContents)
+ }
+ matched, err = regexp.MatchString(`call dist-for-goals,my_singleton_goal,.*/my_singleton_file.txt:my_singleton_file.txt\)`, lateContents)
+ if err != nil || !matched {
+ t.Fatalf("Expected a dist of my_singleton_file.txt, but got: %s", lateContents)
+ }
+ matched, err = regexp.MatchString(`call dist-for-goals,my_singleton_module_module_goal,.*/my_singleton_module_module_file.txt:my_singleton_module_module_file.txt\)`, lateContents)
+ if err != nil || !matched {
+ t.Fatalf("Expected a dist of my_singleton_module_module_file.txt, but got: %s", lateContents)
+ }
+ matched, err = regexp.MatchString(`call dist-for-goals,my_singleton_module_singleton_goal,.*/my_singleton_module_singleton_file.txt:my_singleton_module_singleton_file.txt\)`, lateContents)
+ if err != nil || !matched {
+ t.Fatalf("Expected a dist of my_singleton_module_singleton_file.txt, but got: %s", lateContents)
+ }
+}
+
+type distFileModule struct {
+ ModuleBase
+}
+
+func newDistFileModule() Module {
+ m := &distFileModule{}
+ InitAndroidModule(m)
+ return m
+}
+
+func (m *distFileModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+ out := PathForModuleOut(ctx, "my_file.txt")
+ WriteFileRule(ctx, out, "Hello, world!")
+ ctx.DistForGoal("my_goal", out)
+}
+
+type distFileSingleton struct {
+}
+
+func newDistFileSingleton() Singleton {
+ return &distFileSingleton{}
+}
+
+func (d *distFileSingleton) GenerateBuildActions(ctx SingletonContext) {
+ out := PathForOutput(ctx, "my_singleton_file.txt")
+ WriteFileRule(ctx, out, "Hello, world!")
+ ctx.DistForGoal("my_singleton_goal", out)
+}
+
+type distFileSingletonModule struct {
+ SingletonModuleBase
+}
+
+func newDistFileSingletonModule() SingletonModule {
+ sm := &distFileSingletonModule{}
+ InitAndroidSingletonModule(sm)
+ return sm
+}
+
+// GenerateAndroidBuildActions implements SingletonModule.
+func (d *distFileSingletonModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+ out := PathForModuleOut(ctx, "my_singleton_module_module_file.txt")
+ WriteFileRule(ctx, out, "Hello, world!")
+ ctx.DistForGoal("my_singleton_module_module_goal", out)
+}
+
+// GenerateSingletonBuildActions implements SingletonModule.
+func (d *distFileSingletonModule) GenerateSingletonBuildActions(ctx SingletonContext) {
+ out := PathForOutput(ctx, "my_singleton_module_singleton_file.txt")
+ WriteFileRule(ctx, out, "Hello, world!")
+ ctx.DistForGoal("my_singleton_module_singleton_goal", out)
+}
diff --git a/android/metrics.go b/android/metrics.go
index 6834b1b..dc51703 100644
--- a/android/metrics.go
+++ b/android/metrics.go
@@ -57,8 +57,8 @@
func (soongMetricsSingleton) GenerateBuildActions(ctx SingletonContext) {
metrics := getSoongMetrics(ctx.Config())
- ctx.VisitAllModules(func(m Module) {
- if ctx.PrimaryModule(m) == m {
+ ctx.VisitAllModuleProxies(func(m ModuleProxy) {
+ if ctx.PrimaryModuleProxy(m) == m {
metrics.modules++
}
metrics.variants++
diff --git a/android/module.go b/android/module.go
index 9e620fb..996c64e 100644
--- a/android/module.go
+++ b/android/module.go
@@ -94,7 +94,6 @@
ReplacedByPrebuilt()
IsReplacedByPrebuilt() bool
ExportedToMake() bool
- EffectiveLicenseKinds() []string
EffectiveLicenseFiles() Paths
AddProperties(props ...interface{})
@@ -257,6 +256,8 @@
Name *string
}
+// Properties common to all modules inheriting from ModuleBase. These properties are automatically
+// inherited by sub-modules created with ctx.CreateModule()
type commonProperties struct {
// emit build rules for this module
//
@@ -315,8 +316,6 @@
// Describes the licenses applicable to this module. Must reference license modules.
Licenses []string
- // Flattened from direct license dependencies. Equal to Licenses unless particular module adds more.
- Effective_licenses []string `blueprint:"mutated"`
// Override of module name when reporting licenses
Effective_package_name *string `blueprint:"mutated"`
// Notice files
@@ -409,15 +408,6 @@
// VINTF manifest fragments to be installed if this module is installed
Vintf_fragments proptools.Configurable[[]string] `android:"path"`
- // names of other modules to install if this module is installed
- Required proptools.Configurable[[]string] `android:"arch_variant"`
-
- // names of other modules to install on host if this module is installed
- Host_required []string `android:"arch_variant"`
-
- // names of other modules to install on target if this module is installed
- Target_required []string `android:"arch_variant"`
-
// The OsType of artifacts that this module variant is responsible for creating.
//
// Set by osMutator
@@ -518,6 +508,19 @@
Overrides []string
}
+// Properties common to all modules inheriting from ModuleBase. Unlike commonProperties, these
+// properties are NOT automatically inherited by sub-modules created with ctx.CreateModule()
+type baseProperties struct {
+ // names of other modules to install if this module is installed
+ Required proptools.Configurable[[]string] `android:"arch_variant"`
+
+ // names of other modules to install on host if this module is installed
+ Host_required []string `android:"arch_variant"`
+
+ // names of other modules to install on target if this module is installed
+ Target_required []string `android:"arch_variant"`
+}
+
type distProperties struct {
// configuration to distribute output files from this module to the distribution
// directory (default: $OUT/dist, configurable with $DIST_DIR)
@@ -716,6 +719,7 @@
m.AddProperties(
&base.nameProperties,
&base.commonProperties,
+ &base.baseProperties,
&base.distProperties)
initProductVariableModule(m)
@@ -834,6 +838,7 @@
nameProperties nameProperties
commonProperties commonProperties
+ baseProperties baseProperties
distProperties distProperties
variableProperties interface{}
hostAndDeviceProperties hostAndDeviceProperties
@@ -990,8 +995,9 @@
// 2. `boot_signer` is `required` by modules like `build_image` which is explicitly list as
// the top-level build goal (in the shell file that invokes Soong).
// 3. `boot_signer` depends on `bouncycastle-unbundled` which is in the missing git project.
- // 4. aosp_kernel-build-tools invokes soong with `--skip-make`. Therefore, the absence of
- // ALLOW_MISSING_DEPENDENCIES didn't cause a problem.
+ // 4. aosp_kernel-build-tools invokes soong with `--soong-only`. Therefore, the absence of
+ // ALLOW_MISSING_DEPENDENCIES didn't cause a problem, as previously only make processed required
+ // dependencies.
// 5. Now, since Soong understands `required` deps, it tries to build `boot_signer` and the
// absence of external/bouncycastle fails the build.
//
@@ -1085,6 +1091,10 @@
InstallAlwaysNeededDependencyTag
}{}
+func IsVintfDepTag(depTag blueprint.DependencyTag) bool {
+ return depTag == vintfDepTag
+}
+
func addVintfFragmentDeps(ctx BottomUpMutatorContext) {
// Vintf manifests in the recovery partition will be ignored.
if !ctx.Device() || ctx.Module().InstallInRecovery() {
@@ -1103,7 +1113,7 @@
// of nil pointer dereference errors, but we should resolve the missing dependencies.
continue
}
- if vintfModule, ok := vintf.(*vintfFragmentModule); ok {
+ if vintfModule, ok := vintf.(*VintfFragmentModule); ok {
vintfPartition := vintfModule.PartitionTag(deviceConfig)
if modPartition != vintfPartition {
ctx.ModuleErrorf("Module %q(%q) and Vintf_fragment %q(%q) are installed to different partitions.",
@@ -1458,10 +1468,6 @@
return m.commonProperties.NamespaceExportedToMake
}
-func (m *ModuleBase) EffectiveLicenseKinds() []string {
- return m.commonProperties.Effective_license_kinds
-}
-
func (m *ModuleBase) EffectiveLicenseFiles() Paths {
result := make(Paths, 0, len(m.commonProperties.Effective_license_text))
for _, p := range m.commonProperties.Effective_license_text {
@@ -1618,15 +1624,15 @@
}
func (m *ModuleBase) RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string {
- return m.base().commonProperties.Required.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
+ return m.base().baseProperties.Required.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
}
func (m *ModuleBase) HostRequiredModuleNames() []string {
- return m.base().commonProperties.Host_required
+ return m.base().baseProperties.Host_required
}
func (m *ModuleBase) TargetRequiredModuleNames() []string {
- return m.base().commonProperties.Target_required
+ return m.base().baseProperties.Target_required
}
func (m *ModuleBase) VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string {
@@ -1654,6 +1660,7 @@
func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) {
var allInstalledFiles InstallPaths
var allCheckbuildTargets Paths
+ var alloutputFiles Paths
ctx.VisitAllModuleVariantProxies(func(module ModuleProxy) {
var checkbuildTarget Path
var uncheckedModule bool
@@ -1670,6 +1677,9 @@
uncheckedModule = info.UncheckedModule
skipAndroidMkProcessing = OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoKey).SkipAndroidMkProcessing
}
+ if outputFiles, err := outputFilesForModule(ctx, module, ""); err == nil {
+ alloutputFiles = append(alloutputFiles, outputFiles...)
+ }
// A module's -checkbuild phony targets should
// not be created if the module is not exported to make.
// Those could depend on the build target and fail to compile
@@ -1701,6 +1711,12 @@
deps = append(deps, PathForPhony(ctx, name))
}
+ if len(alloutputFiles) > 0 {
+ name := namespacePrefix + ctx.ModuleName() + "-outputs"
+ ctx.Phony(name, alloutputFiles...)
+ deps = append(deps, PathForPhony(ctx, name))
+ }
+
if len(deps) > 0 {
suffix := ""
if ctx.Config().KatiEnabled() {
@@ -1708,6 +1724,17 @@
}
ctx.Phony(namespacePrefix+ctx.ModuleName()+suffix, deps...)
+ if ctx.Device() {
+ // Generate a target suffix for use in atest etc.
+ ctx.Phony(namespacePrefix+ctx.ModuleName()+"-target"+suffix, deps...)
+ } else {
+ // Generate a host suffix for use in atest etc.
+ ctx.Phony(namespacePrefix+ctx.ModuleName()+"-host"+suffix, deps...)
+ if ctx.Target().HostCross {
+ // Generate a host-cross suffix for use in atest etc.
+ ctx.Phony(namespacePrefix+ctx.ModuleName()+"-host-cross"+suffix, deps...)
+ }
+ }
info.BlueprintDir = ctx.ModuleDir()
SetProvider(ctx, FinalModuleBuildTargetsProvider, info)
@@ -1850,7 +1877,7 @@
Srcs Paths
}
-var SourceFilesInfoKey = blueprint.NewProvider[SourceFilesInfo]()
+var SourceFilesInfoProvider = blueprint.NewProvider[SourceFilesInfo]()
// FinalModuleBuildTargetsInfo is used by buildTargetSingleton to create checkbuild and
// per-directory build targets. Only set on the final variant of each module
@@ -1871,7 +1898,8 @@
SkipAndroidMkProcessing bool
BaseModuleName string
CanHaveApexVariants bool
- MinSdkVersion string
+ MinSdkVersion ApiLevelOrPlatform
+ SdkVersion string
NotAvailableForPlatform bool
// There some subtle differences between this one and the one above.
NotInPlatform bool
@@ -1880,25 +1908,64 @@
// is used to avoid adding install or packaging dependencies into libraries provided
// by apexes.
UninstallableApexPlatformVariant bool
- HideFromMake bool
- SkipInstall bool
- IsStubsModule bool
- Host bool
+ MinSdkVersionSupported ApiLevel
+ ModuleWithMinSdkVersionCheck bool
+ // Tests if this module can be installed to APEX as a file. For example, this would return
+ // true for shared libs while return false for static libs because static libs are not
+ // installable module (but it can still be mutated for APEX)
+ IsInstallableToApex bool
+ HideFromMake bool
+ SkipInstall bool
+ IsStubsModule bool
+ Host bool
+ IsApexModule bool
+ // The primary licenses property, may be nil, records license metadata for the module.
+ PrimaryLicensesProperty applicableLicensesProperty
+ Owner string
+ Vendor bool
+ Proprietary bool
+ SocSpecific bool
+ ProductSpecific bool
+ SystemExtSpecific bool
+ DeviceSpecific bool
+ // When set to true, this module is not installed to the full install path (ex: under
+ // out/target/product/<name>/<partition>). It can be installed only to the packaging
+ // modules like android_filesystem.
+ NoFullInstall bool
+ InVendorRamdisk bool
+ ExemptFromRequiredApplicableLicensesProperty bool
+ RequiredModuleNames []string
+ HostRequiredModuleNames []string
+ TargetRequiredModuleNames []string
+ VintfFragmentModuleNames []string
+ Dists []Dist
+}
+
+type ApiLevelOrPlatform struct {
+ ApiLevel *ApiLevel
+ IsPlatform bool
}
var CommonModuleInfoKey = blueprint.NewProvider[CommonModuleInfo]()
type PrebuiltModuleInfo struct {
SourceExists bool
+ UsePrebuilt bool
}
var PrebuiltModuleInfoProvider = blueprint.NewProvider[PrebuiltModuleInfo]()
-type HostToolProviderData struct {
+type HostToolProviderInfo struct {
HostToolPath OptionalPath
}
-var HostToolProviderKey = blueprint.NewProvider[HostToolProviderData]()
+var HostToolProviderInfoProvider = blueprint.NewProvider[HostToolProviderInfo]()
+
+type DistInfo struct {
+ Dists []dist
+}
+
+var DistProvider = blueprint.NewProvider[DistInfo]()
type SourceFileGenerator interface {
GeneratedSourceFiles() Paths
@@ -2085,7 +2152,7 @@
}
if sourceFileProducer, ok := m.module.(SourceFileProducer); ok {
- SetProvider(ctx, SourceFilesInfoKey, SourceFilesInfo{Srcs: sourceFileProducer.Srcs()})
+ SetProvider(ctx, SourceFilesInfoProvider, SourceFilesInfo{Srcs: sourceFileProducer.Srcs()})
}
if ctx.IsFinalModule(m.module) {
@@ -2102,47 +2169,84 @@
SetProvider(ctx, InstallFilesProvider, installFiles)
buildLicenseMetadata(ctx, ctx.licenseMetadataFile)
- if ctx.moduleInfoJSON != nil {
- var installed InstallPaths
- installed = append(installed, ctx.katiInstalls.InstallPaths()...)
- installed = append(installed, ctx.katiSymlinks.InstallPaths()...)
- installed = append(installed, ctx.katiInitRcInstalls.InstallPaths()...)
- installed = append(installed, ctx.katiVintfInstalls.InstallPaths()...)
- installedStrings := installed.Strings()
+ if len(ctx.moduleInfoJSON) > 0 {
+ for _, moduleInfoJSON := range ctx.moduleInfoJSON {
+ if moduleInfoJSON.Disabled {
+ continue
+ }
+ var installed InstallPaths
+ installed = append(installed, ctx.katiInstalls.InstallPaths()...)
+ installed = append(installed, ctx.katiSymlinks.InstallPaths()...)
+ installed = append(installed, ctx.katiInitRcInstalls.InstallPaths()...)
+ installed = append(installed, ctx.katiVintfInstalls.InstallPaths()...)
+ installedStrings := installed.Strings()
- var targetRequired, hostRequired []string
- if ctx.Host() {
- targetRequired = m.commonProperties.Target_required
- } else {
- hostRequired = m.commonProperties.Host_required
- }
+ var targetRequired, hostRequired []string
+ if ctx.Host() {
+ targetRequired = m.baseProperties.Target_required
+ } else {
+ hostRequired = m.baseProperties.Host_required
+ }
- var data []string
- for _, d := range ctx.testData {
- data = append(data, d.ToRelativeInstallPath())
- }
+ var data []string
+ for _, d := range ctx.testData {
+ data = append(data, d.ToRelativeInstallPath())
+ }
- if ctx.moduleInfoJSON.Uninstallable {
- installedStrings = nil
- if len(ctx.moduleInfoJSON.CompatibilitySuites) == 1 && ctx.moduleInfoJSON.CompatibilitySuites[0] == "null-suite" {
- ctx.moduleInfoJSON.CompatibilitySuites = nil
- ctx.moduleInfoJSON.TestConfig = nil
- ctx.moduleInfoJSON.AutoTestConfig = nil
- data = nil
+ if moduleInfoJSON.Uninstallable {
+ installedStrings = nil
+ if len(moduleInfoJSON.CompatibilitySuites) == 1 && moduleInfoJSON.CompatibilitySuites[0] == "null-suite" {
+ moduleInfoJSON.CompatibilitySuites = nil
+ moduleInfoJSON.TestConfig = nil
+ moduleInfoJSON.AutoTestConfig = nil
+ data = nil
+ }
+ }
+
+ // M(C)TS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}.
+ // To reduce repetition, if we find a partial M(C)TS test suite without an full M(C)TS test suite,
+ // we add the full test suite to our list. This was inherited from
+ // AndroidMkEntries.AddCompatibilityTestSuites.
+ suites := moduleInfoJSON.CompatibilitySuites
+ if PrefixInList(suites, "mts-") && !InList("mts", suites) {
+ suites = append(suites, "mts")
+ }
+ if PrefixInList(suites, "mcts-") && !InList("mcts", suites) {
+ suites = append(suites, "mcts")
+ }
+ moduleInfoJSON.CompatibilitySuites = suites
+
+ required := append(m.RequiredModuleNames(ctx), m.VintfFragmentModuleNames(ctx)...)
+ required = append(required, moduleInfoJSON.ExtraRequired...)
+
+ registerName := moduleInfoJSON.RegisterNameOverride
+ if len(registerName) == 0 {
+ registerName = m.moduleInfoRegisterName(ctx, moduleInfoJSON.SubName)
+ }
+
+ moduleName := moduleInfoJSON.ModuleNameOverride
+ if len(moduleName) == 0 {
+ moduleName = m.BaseModuleName() + moduleInfoJSON.SubName
+ }
+
+ supportedVariants := moduleInfoJSON.SupportedVariantsOverride
+ if moduleInfoJSON.SupportedVariantsOverride == nil {
+ supportedVariants = []string{m.moduleInfoVariant(ctx)}
+ }
+
+ moduleInfoJSON.core = CoreModuleInfoJSON{
+ RegisterName: registerName,
+ Path: []string{ctx.ModuleDir()},
+ Installed: installedStrings,
+ ModuleName: moduleName,
+ SupportedVariants: supportedVariants,
+ TargetDependencies: targetRequired,
+ HostDependencies: hostRequired,
+ Data: data,
+ Required: required,
}
}
- ctx.moduleInfoJSON.core = CoreModuleInfoJSON{
- RegisterName: m.moduleInfoRegisterName(ctx, ctx.moduleInfoJSON.SubName),
- Path: []string{ctx.ModuleDir()},
- Installed: installedStrings,
- ModuleName: m.BaseModuleName() + ctx.moduleInfoJSON.SubName,
- SupportedVariants: []string{m.moduleInfoVariant(ctx)},
- TargetDependencies: targetRequired,
- HostDependencies: hostRequired,
- Data: data,
- Required: append(m.RequiredModuleNames(ctx), m.VintfFragmentModuleNames(ctx)...),
- }
SetProvider(ctx, ModuleInfoJSONProvider, ctx.moduleInfoJSON)
}
@@ -2160,50 +2264,96 @@
Phonies: ctx.phonies,
})
}
+
+ if len(ctx.dists) > 0 {
+ SetProvider(ctx, DistProvider, DistInfo{
+ Dists: ctx.dists,
+ })
+ }
+
buildComplianceMetadataProvider(ctx, m)
commonData := CommonModuleInfo{
+ Enabled: m.Enabled(ctx),
ReplacedByPrebuilt: m.commonProperties.ReplacedByPrebuilt,
Target: m.commonProperties.CompileTarget,
SkipAndroidMkProcessing: shouldSkipAndroidMkProcessing(ctx, m),
- BaseModuleName: m.BaseModuleName(),
UninstallableApexPlatformVariant: m.commonProperties.UninstallableApexPlatformVariant,
HideFromMake: m.commonProperties.HideFromMake,
SkipInstall: m.commonProperties.SkipInstall,
Host: m.Host(),
+ PrimaryLicensesProperty: m.primaryLicensesProperty,
+ Owner: m.module.Owner(),
+ SocSpecific: Bool(m.commonProperties.Soc_specific),
+ Vendor: Bool(m.commonProperties.Vendor),
+ Proprietary: Bool(m.commonProperties.Proprietary),
+ ProductSpecific: Bool(m.commonProperties.Product_specific),
+ SystemExtSpecific: Bool(m.commonProperties.System_ext_specific),
+ DeviceSpecific: Bool(m.commonProperties.Device_specific),
+ NoFullInstall: proptools.Bool(m.commonProperties.No_full_install),
+ InVendorRamdisk: m.InVendorRamdisk(),
+ ExemptFromRequiredApplicableLicensesProperty: exemptFromRequiredApplicableLicensesProperty(m.module),
+ RequiredModuleNames: m.module.RequiredModuleNames(ctx),
+ HostRequiredModuleNames: m.module.HostRequiredModuleNames(),
+ TargetRequiredModuleNames: m.module.TargetRequiredModuleNames(),
+ VintfFragmentModuleNames: m.module.VintfFragmentModuleNames(ctx),
+ Dists: m.Dists(),
}
if mm, ok := m.module.(interface {
MinSdkVersion(ctx EarlyModuleContext) ApiLevel
}); ok {
ver := mm.MinSdkVersion(ctx)
- if !ver.IsNone() {
- commonData.MinSdkVersion = ver.String()
- }
+ commonData.MinSdkVersion.ApiLevel = &ver
} else if mm, ok := m.module.(interface{ MinSdkVersion() string }); ok {
- commonData.MinSdkVersion = mm.MinSdkVersion()
+ ver := mm.MinSdkVersion()
+ // Compile against the current platform
+ if ver == "" {
+ commonData.MinSdkVersion.IsPlatform = true
+ } else {
+ api := ApiLevelFrom(ctx, ver)
+ commonData.MinSdkVersion.ApiLevel = &api
+ }
}
- if m.commonProperties.ForcedDisabled {
- commonData.Enabled = false
- } else {
- commonData.Enabled = m.commonProperties.Enabled.GetOrDefault(m.ConfigurableEvaluator(ctx), !m.Os().DefaultDisabled)
+ if mm, ok := m.module.(interface {
+ SdkVersion(ctx EarlyModuleContext) ApiLevel
+ }); ok {
+ ver := mm.SdkVersion(ctx)
+ if !ver.IsNone() {
+ commonData.SdkVersion = ver.String()
+ }
+ } else if mm, ok := m.module.(interface{ SdkVersion() string }); ok {
+ commonData.SdkVersion = mm.SdkVersion()
}
+
if am, ok := m.module.(ApexModule); ok {
commonData.CanHaveApexVariants = am.CanHaveApexVariants()
commonData.NotAvailableForPlatform = am.NotAvailableForPlatform()
commonData.NotInPlatform = am.NotInPlatform()
+ commonData.MinSdkVersionSupported = am.MinSdkVersionSupported(ctx)
+ commonData.IsInstallableToApex = am.IsInstallableToApex()
+ commonData.IsApexModule = true
}
+
+ if _, ok := m.module.(ModuleWithMinSdkVersionCheck); ok {
+ commonData.ModuleWithMinSdkVersionCheck = true
+ }
+
if st, ok := m.module.(StubsAvailableModule); ok {
commonData.IsStubsModule = st.IsStubsModule()
}
+ if mm, ok := m.module.(interface{ BaseModuleName() string }); ok {
+ commonData.BaseModuleName = mm.BaseModuleName()
+ }
SetProvider(ctx, CommonModuleInfoKey, commonData)
if p, ok := m.module.(PrebuiltInterface); ok && p.Prebuilt() != nil {
SetProvider(ctx, PrebuiltModuleInfoProvider, PrebuiltModuleInfo{
SourceExists: p.Prebuilt().SourceExists(),
+ UsePrebuilt: p.Prebuilt().UsePrebuilt(),
})
}
if h, ok := m.module.(HostToolProvider); ok {
- SetProvider(ctx, HostToolProviderKey, HostToolProviderData{
+ SetProvider(ctx, HostToolProviderInfoProvider, HostToolProviderInfo{
HostToolPath: h.HostToolPath()})
}
@@ -2241,7 +2391,7 @@
arches = slices.DeleteFunc(arches, func(target Target) bool {
return target.NativeBridge != ctx.Target().NativeBridge
})
- if len(arches) > 0 && ctx.Arch().ArchType != arches[0].Arch.ArchType {
+ if len(arches) > 0 && ctx.Arch().ArchType != arches[0].Arch.ArchType && ctx.Arch().ArchType != Common {
if ctx.Arch().ArchType.Multilib == "lib32" {
suffix = "_32"
} else {
@@ -2494,6 +2644,8 @@
return proptools.ConfigurableValueBool(ctx.Config().BuildFromTextStub())
case "debuggable":
return proptools.ConfigurableValueBool(ctx.Config().Debuggable())
+ case "eng":
+ return proptools.ConfigurableValueBool(ctx.Config().Eng())
case "use_debug_art":
// TODO(b/234351700): Remove once ART does not have separated debug APEX
return proptools.ConfigurableValueBool(ctx.Config().UseDebugArt())
@@ -2784,7 +2936,7 @@
if sourceFileProducer, ok := module.(SourceFileProducer); ok {
return sourceFileProducer.Srcs(), nil
}
- } else if sourceFiles, ok := OtherModuleProvider(octx, module, SourceFilesInfoKey); ok {
+ } else if sourceFiles, ok := OtherModuleProvider(octx, module, SourceFilesInfoProvider); ok {
if tag != "" {
return nil, fmt.Errorf("module %q is a SourceFileProducer, which does not support tag %q", pathContextName(ctx, module), tag)
}
@@ -2908,6 +3060,9 @@
func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
var checkbuildDeps Paths
+ // Create a top level partialcompileclean target for modules to add dependencies to.
+ ctx.Phony("partialcompileclean")
+
mmTarget := func(dir string) string {
return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1)
}
diff --git a/android/module_context.go b/android/module_context.go
index f6a676d..fb62e67 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -24,6 +24,7 @@
"github.com/google/blueprint"
"github.com/google/blueprint/depset"
"github.com/google/blueprint/proptools"
+ "github.com/google/blueprint/uniquelist"
)
// BuildParameters describes the set of potential parameters to build a Ninja rule.
@@ -80,6 +81,8 @@
Default bool
// Args is a key value mapping for replacements of variables within the Rule
Args map[string]string
+ // PhonyOutput marks this build as `phony_output = true`
+ PhonyOutput bool
}
type ModuleBuildParams BuildParams
@@ -230,6 +233,10 @@
// the module-info.json generated by Make, and Make will not generate its own data for this module.
ModuleInfoJSON() *ModuleInfoJSON
+ // Simiar to ModuleInfoJSON, ExtraModuleInfoJSON also returns a pointer to the ModuleInfoJSON struct.
+ // This should only be called by a module that generates multiple AndroidMkEntries struct.
+ ExtraModuleInfoJSON() *ModuleInfoJSON
+
// SetOutputFiles stores the outputFiles to outputFiles property, which is used
// to set the OutputFilesProvider later.
SetOutputFiles(outputFiles Paths, tag string)
@@ -250,6 +257,24 @@
setContainersInfo(info ContainersInfo)
setAconfigPaths(paths Paths)
+
+ // DistForGoals creates a rule to copy one or more Paths to the artifacts
+ // directory on the build server when any of the specified goals are built.
+ DistForGoal(goal string, paths ...Path)
+
+ // DistForGoalWithFilename creates a rule to copy a Path to the artifacts
+ // directory on the build server with the given filename when the specified
+ // goal is built.
+ DistForGoalWithFilename(goal string, path Path, filename string)
+
+ // DistForGoals creates a rule to copy one or more Paths to the artifacts
+ // directory on the build server when any of the specified goals are built.
+ DistForGoals(goals []string, paths ...Path)
+
+ // DistForGoalsWithFilename creates a rule to copy a Path to the artifacts
+ // directory on the build server with the given filename when any of the
+ // specified goals are built.
+ DistForGoalsWithFilename(goals []string, path Path, filename string)
}
type moduleContext struct {
@@ -295,7 +320,7 @@
// moduleInfoJSON can be filled out by GenerateAndroidBuildActions to write a JSON file that will
// be included in the final module-info.json produced by Make.
- moduleInfoJSON *ModuleInfoJSON
+ moduleInfoJSON []*ModuleInfoJSON
// containersInfo stores the information about the containers and the information of the
// apexes the module belongs to.
@@ -307,6 +332,8 @@
// complianceMetadataInfo is for different module types to dump metadata.
// See android.ModuleContext interface.
complianceMetadataInfo *ComplianceMetadataInfo
+
+ dists []dist
}
var _ ModuleContext = &moduleContext{}
@@ -344,6 +371,7 @@
Validations: params.Validations.Strings(),
Args: params.Args,
Default: params.Default,
+ PhonyOutput: params.PhonyOutput,
}
if params.Depfile != nil {
@@ -586,11 +614,11 @@
func (m *moduleContext) PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec {
fullInstallPath := installPath.Join(m, name)
- return m.packageFile(fullInstallPath, srcPath, false)
+ return m.packageFile(fullInstallPath, srcPath, false, false)
}
-func (m *moduleContext) getAconfigPaths() *Paths {
- return &m.aconfigFilePaths
+func (m *moduleContext) getAconfigPaths() Paths {
+ return m.aconfigFilePaths
}
func (m *moduleContext) setAconfigPaths(paths Paths) {
@@ -610,7 +638,7 @@
return owner, overrides
}
-func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, executable bool) PackagingSpec {
+func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, executable bool, requiresFullInstall bool) PackagingSpec {
licenseFiles := m.Module().EffectiveLicenseFiles()
owner, overrides := m.getOwnerAndOverrides()
spec := PackagingSpec{
@@ -618,13 +646,16 @@
srcPath: srcPath,
symlinkTarget: "",
executable: executable,
- effectiveLicenseFiles: &licenseFiles,
+ effectiveLicenseFiles: uniquelist.Make(licenseFiles),
partition: fullInstallPath.partition,
skipInstall: m.skipInstall(),
- aconfigPaths: m.getAconfigPaths(),
+ aconfigPaths: uniquelist.Make(m.getAconfigPaths()),
archType: m.target.Arch.ArchType,
- overrides: &overrides,
+ overrides: uniquelist.Make(overrides),
owner: owner,
+ requiresFullInstall: requiresFullInstall,
+ fullInstallPath: fullInstallPath,
+ variation: m.ModuleSubDir(),
}
m.packagingSpecs = append(m.packagingSpecs, spec)
return spec
@@ -632,6 +663,9 @@
func (m *moduleContext) installFile(installPath InstallPath, name string, srcPath Path, deps []InstallPath,
executable bool, hooks bool, checkbuild bool, extraZip *extraFilesZip) InstallPath {
+ if _, ok := srcPath.(InstallPath); ok {
+ m.ModuleErrorf("Src path cannot be another installed file. Please use a path from source or intermediates instead.")
+ }
fullInstallPath := installPath.Join(m, name)
if hooks {
@@ -655,22 +689,24 @@
orderOnlyDeps = InstallPaths(deps).Paths()
}
- if m.Config().KatiEnabled() {
- // When creating the install rule in Soong but embedding in Make, write the rule to a
- // makefile instead of directly to the ninja file so that main.mk can add the
- // dependencies from the `required` property that are hard to resolve in Soong.
- m.katiInstalls = append(m.katiInstalls, katiInstall{
- from: srcPath,
- to: fullInstallPath,
- implicitDeps: implicitDeps,
- orderOnlyDeps: orderOnlyDeps,
- executable: executable,
- extraFiles: extraZip,
- })
- } else {
- rule := Cp
+ // When creating the install rule in Soong but embedding in Make, write the rule to a
+ // makefile instead of directly to the ninja file so that main.mk can add the
+ // dependencies from the `required` property that are hard to resolve in Soong.
+ // In soong-only builds, the katiInstall will still be created for semi-legacy code paths
+ // such as module-info.json or compliance, but it will not be used for actually installing
+ // the file.
+ m.katiInstalls = append(m.katiInstalls, katiInstall{
+ from: srcPath,
+ to: fullInstallPath,
+ implicitDeps: implicitDeps,
+ orderOnlyDeps: orderOnlyDeps,
+ executable: executable,
+ extraFiles: extraZip,
+ })
+ if !m.Config().KatiEnabled() {
+ rule := CpWithBash
if executable {
- rule = CpExecutable
+ rule = CpExecutableWithBash
}
extraCmds := ""
@@ -681,6 +717,17 @@
implicitDeps = append(implicitDeps, extraZip.zip)
}
+ var cpFlags = "-f"
+
+ // If this is a device file, copy while preserving timestamps. This is to support
+ // adb sync in soong-only builds. Because soong-only builds have 2 different staging
+ // directories, the out/target/product one and the out/soong/.intermediates one,
+ // we need to ensure the files in them have the same timestamps so that adb sync doesn't
+ // update the files on device.
+ if strings.Contains(fullInstallPath.String(), "target/product") {
+ cpFlags += " -p"
+ }
+
m.Build(pctx, BuildParams{
Rule: rule,
Description: "install " + fullInstallPath.Base(),
@@ -690,6 +737,7 @@
OrderOnly: orderOnlyDeps,
Args: map[string]string{
"extraCmds": extraCmds,
+ "cpFlags": cpFlags,
},
})
}
@@ -697,7 +745,7 @@
m.installFiles = append(m.installFiles, fullInstallPath)
}
- m.packageFile(fullInstallPath, srcPath, executable)
+ m.packageFile(fullInstallPath, srcPath, executable, m.requiresFullInstall())
if checkbuild {
m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
@@ -716,21 +764,23 @@
}
if m.requiresFullInstall() {
- if m.Config().KatiEnabled() {
- // When creating the symlink rule in Soong but embedding in Make, write the rule to a
- // makefile instead of directly to the ninja file so that main.mk can add the
- // dependencies from the `required` property that are hard to resolve in Soong.
- m.katiSymlinks = append(m.katiSymlinks, katiInstall{
- from: srcPath,
- to: fullInstallPath,
- })
- } else {
+ // When creating the symlink rule in Soong but embedding in Make, write the rule to a
+ // makefile instead of directly to the ninja file so that main.mk can add the
+ // dependencies from the `required` property that are hard to resolve in Soong.
+ // In soong-only builds, the katiInstall will still be created for semi-legacy code paths
+ // such as module-info.json or compliance, but it will not be used for actually installing
+ // the file.
+ m.katiSymlinks = append(m.katiSymlinks, katiInstall{
+ from: srcPath,
+ to: fullInstallPath,
+ })
+ if !m.Config().KatiEnabled() {
// The symlink doesn't need updating when the target is modified, but we sometimes
// have a dependency on a symlink to a binary instead of to the binary directly, and
// the mtime of the symlink must be updated when the binary is modified, so use a
// normal dependency here instead of an order-only dependency.
m.Build(pctx, BuildParams{
- Rule: Symlink,
+ Rule: SymlinkWithBash,
Description: "install symlink " + fullInstallPath.Base(),
Output: fullInstallPath,
Input: srcPath,
@@ -745,16 +795,19 @@
owner, overrides := m.getOwnerAndOverrides()
m.packagingSpecs = append(m.packagingSpecs, PackagingSpec{
- relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
- srcPath: nil,
- symlinkTarget: relPath,
- executable: false,
- partition: fullInstallPath.partition,
- skipInstall: m.skipInstall(),
- aconfigPaths: m.getAconfigPaths(),
- archType: m.target.Arch.ArchType,
- overrides: &overrides,
- owner: owner,
+ relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
+ srcPath: nil,
+ symlinkTarget: relPath,
+ executable: false,
+ partition: fullInstallPath.partition,
+ skipInstall: m.skipInstall(),
+ aconfigPaths: uniquelist.Make(m.getAconfigPaths()),
+ archType: m.target.Arch.ArchType,
+ overrides: uniquelist.Make(overrides),
+ owner: owner,
+ requiresFullInstall: m.requiresFullInstall(),
+ fullInstallPath: fullInstallPath,
+ variation: m.ModuleSubDir(),
})
return fullInstallPath
@@ -767,17 +820,19 @@
m.module.base().hooks.runInstallHooks(m, nil, fullInstallPath, true)
if m.requiresFullInstall() {
- if m.Config().KatiEnabled() {
- // When creating the symlink rule in Soong but embedding in Make, write the rule to a
- // makefile instead of directly to the ninja file so that main.mk can add the
- // dependencies from the `required` property that are hard to resolve in Soong.
- m.katiSymlinks = append(m.katiSymlinks, katiInstall{
- absFrom: absPath,
- to: fullInstallPath,
- })
- } else {
+ // When creating the symlink rule in Soong but embedding in Make, write the rule to a
+ // makefile instead of directly to the ninja file so that main.mk can add the
+ // dependencies from the `required` property that are hard to resolve in Soong.
+ // In soong-only builds, the katiInstall will still be created for semi-legacy code paths
+ // such as module-info.json or compliance, but it will not be used for actually installing
+ // the file.
+ m.katiSymlinks = append(m.katiSymlinks, katiInstall{
+ absFrom: absPath,
+ to: fullInstallPath,
+ })
+ if !m.Config().KatiEnabled() {
m.Build(pctx, BuildParams{
- Rule: Symlink,
+ Rule: SymlinkWithBash,
Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath,
Output: fullInstallPath,
Args: map[string]string{
@@ -791,16 +846,19 @@
owner, overrides := m.getOwnerAndOverrides()
m.packagingSpecs = append(m.packagingSpecs, PackagingSpec{
- relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
- srcPath: nil,
- symlinkTarget: absPath,
- executable: false,
- partition: fullInstallPath.partition,
- skipInstall: m.skipInstall(),
- aconfigPaths: m.getAconfigPaths(),
- archType: m.target.Arch.ArchType,
- overrides: &overrides,
- owner: owner,
+ relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
+ srcPath: nil,
+ symlinkTarget: absPath,
+ executable: false,
+ partition: fullInstallPath.partition,
+ skipInstall: m.skipInstall(),
+ aconfigPaths: uniquelist.Make(m.getAconfigPaths()),
+ archType: m.target.Arch.ArchType,
+ overrides: uniquelist.Make(overrides),
+ owner: owner,
+ requiresFullInstall: m.requiresFullInstall(),
+ fullInstallPath: fullInstallPath,
+ variation: m.ModuleSubDir(),
})
return fullInstallPath
@@ -838,11 +896,20 @@
}
func (m *moduleContext) ModuleInfoJSON() *ModuleInfoJSON {
- if moduleInfoJSON := m.moduleInfoJSON; moduleInfoJSON != nil {
- return moduleInfoJSON
+ if len(m.moduleInfoJSON) == 0 {
+ moduleInfoJSON := &ModuleInfoJSON{}
+ m.moduleInfoJSON = append(m.moduleInfoJSON, moduleInfoJSON)
}
+ return m.moduleInfoJSON[0]
+}
+
+func (m *moduleContext) ExtraModuleInfoJSON() *ModuleInfoJSON {
+ if len(m.moduleInfoJSON) == 0 {
+ panic("call ModuleInfoJSON() instead")
+ }
+
moduleInfoJSON := &ModuleInfoJSON{}
- m.moduleInfoJSON = moduleInfoJSON
+ m.moduleInfoJSON = append(m.moduleInfoJSON, moduleInfoJSON)
return moduleInfoJSON
}
@@ -929,3 +996,32 @@
func (m *moduleContext) setContainersInfo(info ContainersInfo) {
m.containersInfo = info
}
+
+func (c *moduleContext) DistForGoal(goal string, paths ...Path) {
+ c.DistForGoals([]string{goal}, paths...)
+}
+
+func (c *moduleContext) DistForGoalWithFilename(goal string, path Path, filename string) {
+ c.DistForGoalsWithFilename([]string{goal}, path, filename)
+}
+
+func (c *moduleContext) DistForGoals(goals []string, paths ...Path) {
+ var copies distCopies
+ for _, path := range paths {
+ copies = append(copies, distCopy{
+ from: path,
+ dest: path.Base(),
+ })
+ }
+ c.dists = append(c.dists, dist{
+ goals: slices.Clone(goals),
+ paths: copies,
+ })
+}
+
+func (c *moduleContext) DistForGoalsWithFilename(goals []string, path Path, filename string) {
+ c.dists = append(c.dists, dist{
+ goals: slices.Clone(goals),
+ paths: distCopies{{from: path, dest: filename}},
+ })
+}
diff --git a/android/module_info_json.go b/android/module_info_json.go
index d102dd2..bb309ff 100644
--- a/android/module_info_json.go
+++ b/android/module_info_json.go
@@ -34,7 +34,7 @@
SrcJars []string `json:"srcjars,omitempty"` // $(sort $(ALL_MODULES.$(m).SRCJARS))
ClassesJar []string `json:"classes_jar,omitempty"` // $(sort $(ALL_MODULES.$(m).CLASSES_JAR))
TestMainlineModules []string `json:"test_mainline_modules,omitempty"` // $(sort $(ALL_MODULES.$(m).TEST_MAINLINE_MODULES))
- IsUnitTest bool `json:"is_unit_test,omitempty"` // $(ALL_MODULES.$(m).IS_UNIT_TEST)
+ IsUnitTest string `json:"is_unit_test,omitempty"` // $(ALL_MODULES.$(m).IS_UNIT_TEST)
TestOptionsTags []string `json:"test_options_tags,omitempty"` // $(sort $(ALL_MODULES.$(m).TEST_OPTIONS_TAGS))
RuntimeDependencies []string `json:"runtime_dependencies,omitempty"` // $(sort $(ALL_MODULES.$(m).LOCAL_RUNTIME_LIBRARIES))
StaticDependencies []string `json:"static_dependencies,omitempty"` // $(sort $(ALL_MODULES.$(m).LOCAL_STATIC_LIBRARIES))
@@ -43,6 +43,12 @@
CompatibilitySuites []string `json:"compatibility_suites,omitempty"` // $(sort $(ALL_MODULES.$(m).COMPATIBILITY_SUITES))
AutoTestConfig []string `json:"auto_test_config,omitempty"` // $(ALL_MODULES.$(m).auto_test_config)
TestConfig []string `json:"test_config,omitempty"` // $(strip $(ALL_MODULES.$(m).TEST_CONFIG) $(ALL_MODULES.$(m).EXTRA_TEST_CONFIGS)
+ ExtraRequired []string `json:"-"`
+
+ SupportedVariantsOverride []string `json:"-"`
+ Disabled bool `json:"-"`
+ RegisterNameOverride string `json:"-"`
+ ModuleNameOverride string `json:"-"`
}
type ModuleInfoJSON struct {
@@ -127,4 +133,12 @@
return gobtools.CustomGobDecode[combinedModuleInfoJSON](data, m)
}
-var ModuleInfoJSONProvider = blueprint.NewProvider[*ModuleInfoJSON]()
+func (m *ModuleInfoJSON) GetInstalled() []string {
+ return m.core.Installed
+}
+
+func (m *ModuleInfoJSON) GetClass() []string {
+ return m.Class
+}
+
+var ModuleInfoJSONProvider = blueprint.NewProvider[[]*ModuleInfoJSON]()
diff --git a/android/module_proxy.go b/android/module_proxy.go
index 8cc8fa1..77abc11 100644
--- a/android/module_proxy.go
+++ b/android/module_proxy.go
@@ -11,6 +11,10 @@
var _ Module = (*ModuleProxy)(nil)
+func (m ModuleProxy) IsNil() bool {
+ return m.module.IsNil()
+}
+
func (m ModuleProxy) Name() string {
return m.module.Name()
}
@@ -160,10 +164,6 @@
panic("method is not implemented on ModuleProxy")
}
-func (m ModuleProxy) EffectiveLicenseKinds() []string {
- panic("method is not implemented on ModuleProxy")
-}
-
func (m ModuleProxy) EffectiveLicenseFiles() Paths {
panic("method is not implemented on ModuleProxy")
}
diff --git a/android/module_test.go b/android/module_test.go
index 6e6d449..5331e49 100644
--- a/android/module_test.go
+++ b/android/module_test.go
@@ -321,7 +321,7 @@
if host {
variant = result.Config.BuildOSCommonTarget.String()
}
- return result.ModuleForTests(name, variant)
+ return result.ModuleForTests(t, name, variant)
}
outputRule := func(name string) TestingBuildParams { return module(name, false).Output(name) }
@@ -434,11 +434,12 @@
rules := result.InstallMakeRulesForTesting(t)
module := func(name string, host bool) TestingModule {
+ t.Helper()
variant := "android_common"
if host {
variant = result.Config.BuildOSCommonTarget.String()
}
- return result.ModuleForTests(name, variant)
+ return result.ModuleForTests(t, name, variant)
}
outputRule := func(name string) TestingBuildParams { return module(name, false).Output(name) }
@@ -743,7 +744,7 @@
FixtureWithRootAndroidBp(tc.bp),
).RunTest(t)
- foo := result.ModuleForTests("foo", "").Module().base()
+ foo := result.ModuleForTests(t, "foo", "").Module().base()
AssertDeepEquals(t, "foo ", tc.expectedProps, foo.propertiesWithValues())
})
@@ -1078,7 +1079,7 @@
PathContext: PathContextForTesting(config),
OtherModuleProviderContext: result.TestContext.OtherModuleProviderAdaptor(),
}
- got := OutputFileForModule(ctx, result.ModuleForTests("test_module", "").Module(), tt.tag)
+ got := OutputFileForModule(ctx, result.ModuleForTests(t, "test_module", "").Module(), tt.tag)
AssertPathRelativeToTopEquals(t, "expected output path", tt.expected, got)
AssertArrayString(t, "expected missing deps", tt.missingDeps, ctx.missingDeps)
})
@@ -1110,3 +1111,14 @@
"Module .+ and Vintf_fragment .+ are installed to different partitions.")).
RunTestWithBp(t, bp)
}
+
+func TestInvalidModuleName(t *testing.T) {
+ bp := `
+ deps {
+ name: "fo o",
+ }
+ `
+ prepareForModuleTests.
+ ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`should use a valid name`)).
+ RunTestWithBp(t, bp)
+}
diff --git a/android/mutator.go b/android/mutator.go
index 1523794..12861c0 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -15,9 +15,8 @@
package android
import (
- "sync"
-
"github.com/google/blueprint"
+ "github.com/google/blueprint/pool"
)
// Phases:
@@ -67,10 +66,10 @@
}
type RegisterMutatorsContext interface {
- TopDown(name string, m TopDownMutator) MutatorHandle
BottomUp(name string, m BottomUpMutator) MutatorHandle
BottomUpBlueprint(name string, m blueprint.BottomUpMutator) MutatorHandle
- Transition(name string, m TransitionMutator) TransitionMutatorHandle
+ Transition(name string, m VariationTransitionMutator) TransitionMutatorHandle
+ InfoBasedTransition(name string, m androidTransitionMutator) TransitionMutatorHandle
}
type RegisterMutatorFunc func(RegisterMutatorsContext)
@@ -158,6 +157,7 @@
var preDeps = []RegisterMutatorFunc{
registerArchMutator,
+ RegisterPrebuiltsPreDepsMutators,
}
var postDeps = []RegisterMutatorFunc{
@@ -193,17 +193,6 @@
finalDeps = append(finalDeps, f)
}
-type TopDownMutator func(TopDownMutatorContext)
-
-type TopDownMutatorContext interface {
- BaseModuleContext
-}
-
-type topDownMutatorContext struct {
- bp blueprint.TopDownMutatorContext
- baseModuleContext
-}
-
type BottomUpMutator func(BottomUpMutatorContext)
type BottomUpMutatorContext interface {
@@ -213,7 +202,7 @@
// dependency (some entries may be nil).
//
// This method will pause until the new dependencies have had the current mutator called on them.
- AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module
+ AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []Module
// AddReverseDependency adds a dependency from the destination to the given module.
// Does not affect the ordering of the current mutator pass, but will be ordered
@@ -229,7 +218,7 @@
// all the non-local variations of the current module, plus the variations argument.
//
// This method will pause until the new dependencies have had the current mutator called on them.
- AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag, names ...string) []blueprint.Module
+ AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag, names ...string) []Module
// AddReverseVariationDependency adds a dependency from the named module to the current
// module. The given variations will be added to the current module's varations, and then the
@@ -252,7 +241,7 @@
// dependency only needs to match the supplied variations.
//
// This method will pause until the new dependencies have had the current mutator called on them.
- AddFarVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string) []blueprint.Module
+ AddFarVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string) []Module
// ReplaceDependencies finds all the variants of the module with the specified name, then
// replaces all dependencies onto those variants with the current variant of this module.
@@ -279,22 +268,12 @@
}
// An outgoingTransitionContextImpl and incomingTransitionContextImpl is created for every dependency of every module
-// for each transition mutator. bottomUpMutatorContext and topDownMutatorContext are created once for every module
-// for every BottomUp or TopDown mutator. Use a global pool for each to avoid reallocating every time.
+// for each transition mutator. bottomUpMutatorContext is created once for every module for every BottomUp mutator.
+// Use a global pool for each to avoid reallocating every time.
var (
- outgoingTransitionContextPool = sync.Pool{
- New: func() any { return &outgoingTransitionContextImpl{} },
- }
- incomingTransitionContextPool = sync.Pool{
- New: func() any { return &incomingTransitionContextImpl{} },
- }
- bottomUpMutatorContextPool = sync.Pool{
- New: func() any { return &bottomUpMutatorContext{} },
- }
-
- topDownMutatorContextPool = sync.Pool{
- New: func() any { return &topDownMutatorContext{} },
- }
+ outgoingTransitionContextPool = pool.New[outgoingTransitionContextImpl]()
+ incomingTransitionContextPool = pool.New[incomingTransitionContextImpl]()
+ bottomUpMutatorContextPool = pool.New[bottomUpMutatorContext]()
)
type bottomUpMutatorContext struct {
@@ -305,10 +284,10 @@
// callers must immediately follow the call to this function with defer bottomUpMutatorContextPool.Put(mctx).
func bottomUpMutatorContextFactory(ctx blueprint.BottomUpMutatorContext, a Module,
- finalPhase bool) BottomUpMutatorContext {
+ finalPhase bool) *bottomUpMutatorContext {
moduleContext := a.base().baseModuleContextFactory(ctx)
- mctx := bottomUpMutatorContextPool.Get().(*bottomUpMutatorContext)
+ mctx := bottomUpMutatorContextPool.Get()
*mctx = bottomUpMutatorContext{
bp: ctx,
baseModuleContext: moduleContext,
@@ -337,8 +316,22 @@
return mutator
}
-func (x *registerMutatorsContext) Transition(name string, m TransitionMutator) TransitionMutatorHandle {
- atm := &androidTransitionMutator{
+func (x *registerMutatorsContext) Transition(name string, m VariationTransitionMutator) TransitionMutatorHandle {
+ atm := &androidTransitionMutatorAdapter{
+ finalPhase: x.finalPhase,
+ mutator: variationTransitionMutatorAdapter{m},
+ name: name,
+ }
+ mutator := &mutator{
+ name: name,
+ transitionMutator: atm,
+ }
+ x.mutators = append(x.mutators, mutator)
+ return mutator
+}
+
+func (x *registerMutatorsContext) InfoBasedTransition(name string, m androidTransitionMutator) TransitionMutatorHandle {
+ atm := &androidTransitionMutatorAdapter{
finalPhase: x.finalPhase,
mutator: m,
name: name,
@@ -355,24 +348,6 @@
return name
}
-func (x *registerMutatorsContext) TopDown(name string, m TopDownMutator) MutatorHandle {
- f := func(ctx blueprint.TopDownMutatorContext) {
- if a, ok := ctx.Module().(Module); ok {
- moduleContext := a.base().baseModuleContextFactory(ctx)
- actx := topDownMutatorContextPool.Get().(*topDownMutatorContext)
- defer topDownMutatorContextPool.Put(actx)
- *actx = topDownMutatorContext{
- bp: ctx,
- baseModuleContext: moduleContext,
- }
- m(actx)
- }
- }
- mutator := &mutator{name: x.mutatorName(name), topDownMutator: f}
- x.mutators = append(x.mutators, mutator)
- return mutator
-}
-
func (mutator *mutator) componentName() string {
return mutator.name
}
@@ -382,8 +357,6 @@
var handle blueprint.MutatorHandle
if mutator.bottomUpMutator != nil {
handle = blueprintCtx.RegisterBottomUpMutator(mutator.name, mutator.bottomUpMutator)
- } else if mutator.topDownMutator != nil {
- handle = blueprintCtx.RegisterTopDownMutator(mutator.name, mutator.topDownMutator)
} else if mutator.transitionMutator != nil {
handle := blueprintCtx.RegisterTransitionMutator(mutator.name, mutator.transitionMutator)
if mutator.neverFar {
@@ -513,22 +486,22 @@
ctx.BottomUp("deps", depsMutator).UsesReverseDependencies()
}
-// android.topDownMutatorContext either has to embed blueprint.TopDownMutatorContext, in which case every method that
+// android.bottomUpMutatorContext either has to embed blueprint.BottomUpMutatorContext, in which case every method that
// has an overridden version in android.BaseModuleContext has to be manually forwarded to BaseModuleContext to avoid
-// ambiguous method errors, or it has to store a blueprint.TopDownMutatorContext non-embedded, in which case every
+// ambiguous method errors, or it has to store a blueprint.BottomUpMutatorContext non-embedded, in which case every
// non-overridden method has to be forwarded. There are fewer non-overridden methods, so use the latter. The following
-// methods forward to the identical blueprint versions for topDownMutatorContext and bottomUpMutatorContext.
+// methods forward to the identical blueprint versions for bottomUpMutatorContext.
func (b *bottomUpMutatorContext) Rename(name string) {
b.bp.Rename(name)
b.Module().base().commonProperties.DebugName = name
}
-func (b *bottomUpMutatorContext) createModule(factory blueprint.ModuleFactory, name string, props ...interface{}) blueprint.Module {
- return b.bp.CreateModule(factory, name, props...)
+func (b *bottomUpMutatorContext) createModule(factory blueprint.ModuleFactory, name string, props ...interface{}) Module {
+ return bpModuleToModule(b.bp.CreateModule(factory, name, props...))
}
-func (b *bottomUpMutatorContext) createModuleInDirectory(factory blueprint.ModuleFactory, name string, _ string, props ...interface{}) blueprint.Module {
+func (b *bottomUpMutatorContext) createModuleInDirectory(factory blueprint.ModuleFactory, name string, _ string, props ...interface{}) Module {
panic("createModuleInDirectory is not implemented for bottomUpMutatorContext")
}
@@ -536,11 +509,11 @@
return createModule(b, factory, "_bottomUpMutatorModule", doesNotSpecifyDirectory(), props...)
}
-func (b *bottomUpMutatorContext) AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module {
+func (b *bottomUpMutatorContext) AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []Module {
if b.baseModuleContext.checkedMissingDeps() {
panic("Adding deps not allowed after checking for missing deps")
}
- return b.bp.AddDependency(module, tag, name...)
+ return bpModulesToModules(b.bp.AddDependency(module, tag, name...))
}
func (b *bottomUpMutatorContext) AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) {
@@ -558,20 +531,20 @@
}
func (b *bottomUpMutatorContext) AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag,
- names ...string) []blueprint.Module {
+ names ...string) []Module {
if b.baseModuleContext.checkedMissingDeps() {
panic("Adding deps not allowed after checking for missing deps")
}
- return b.bp.AddVariationDependencies(variations, tag, names...)
+ return bpModulesToModules(b.bp.AddVariationDependencies(variations, tag, names...))
}
func (b *bottomUpMutatorContext) AddFarVariationDependencies(variations []blueprint.Variation,
- tag blueprint.DependencyTag, names ...string) []blueprint.Module {
+ tag blueprint.DependencyTag, names ...string) []Module {
if b.baseModuleContext.checkedMissingDeps() {
panic("Adding deps not allowed after checking for missing deps")
}
- return b.bp.AddFarVariationDependencies(variations, tag, names...)
+ return bpModulesToModules(b.bp.AddFarVariationDependencies(variations, tag, names...))
}
func (b *bottomUpMutatorContext) ReplaceDependencies(name string) {
@@ -587,3 +560,18 @@
}
b.bp.ReplaceDependenciesIf(name, predicate)
}
+
+func bpModulesToModules(bpModules []blueprint.Module) []Module {
+ modules := make([]Module, len(bpModules))
+ for i, bpModule := range bpModules {
+ modules[i] = bpModuleToModule(bpModule)
+ }
+ return modules
+}
+
+func bpModuleToModule(bpModule blueprint.Module) Module {
+ if bpModule != nil {
+ return bpModule.(Module)
+ }
+ return nil
+}
diff --git a/android/mutator_test.go b/android/mutator_test.go
index 60a6119..f7ee7d8 100644
--- a/android/mutator_test.go
+++ b/android/mutator_test.go
@@ -54,7 +54,7 @@
ctx.AddDependency(ctx.Module(), nil, m.props.Deps_missing_deps...)
}
-func addMissingDependenciesMutator(ctx TopDownMutatorContext) {
+func addMissingDependenciesMutator(ctx BottomUpMutatorContext) {
ctx.AddMissingDependencies(ctx.Module().(*mutatorTestModule).props.Mutator_missing_deps)
}
@@ -72,13 +72,13 @@
FixtureRegisterWithContext(func(ctx RegistrationContext) {
ctx.RegisterModuleType("test", mutatorTestModuleFactory)
ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
- ctx.TopDown("add_missing_dependencies", addMissingDependenciesMutator)
+ ctx.BottomUp("add_missing_dependencies", addMissingDependenciesMutator)
})
}),
FixtureWithRootAndroidBp(bp),
).RunTest(t)
- foo := result.ModuleForTests("foo", "").Module().(*mutatorTestModule)
+ foo := result.ModuleForTests(t, "foo", "").Module().(*mutatorTestModule)
AssertDeepEquals(t, "foo missing deps", []string{"added_missing_dep", "regular_missing_dep"}, foo.missingDeps)
}
diff --git a/android/namespace_test.go b/android/namespace_test.go
index 0327e78..a183bbf 100644
--- a/android/namespace_test.go
+++ b/android/namespace_test.go
@@ -683,7 +683,7 @@
}
func getModule(result *TestResult, moduleName string) TestingModule {
- return result.ModuleForTests(moduleName, "")
+ return result.ModuleForTests(result.fixture.t, moduleName, "")
}
func findModuleById(result *TestResult, id string) (module TestingModule) {
@@ -691,7 +691,7 @@
testModule, ok := candidate.(*testModule)
if ok {
if testModule.properties.Id == id {
- module = newTestingModule(result.config, testModule)
+ module = newTestingModule(result.fixture.t, result.config, testModule)
}
}
}
diff --git a/android/neverallow.go b/android/neverallow.go
index e12e8b7..70af2ac 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -65,6 +65,7 @@
AddNeverAllowRules(createKotlinPluginRule()...)
AddNeverAllowRules(createPrebuiltEtcBpDefineRule())
AddNeverAllowRules(createAutogenRroBpDefineRule())
+ AddNeverAllowRules(createNoSha1HashRule())
}
// Add a NeverAllow rule to the set of rules to apply.
@@ -291,23 +292,39 @@
return []Rule{
NeverAllow().
ModuleType("dirgroup").
- WithMatcher("visibility", NotInList([]string{"//trusty/vendor/google/aosp/scripts"})).Because(reason),
+ WithMatcher("visibility", NotInList([]string{"//trusty/vendor/google/aosp/scripts", "//trusty/vendor/google/proprietary/scripts"})).Because(reason),
NeverAllow().
ModuleType("dirgroup").
- Without("visibility", "//trusty/vendor/google/aosp/scripts").Because(reason),
+ WithoutMatcher("visibility", InAllowedList([]string{"//trusty/vendor/google/aosp/scripts", "//trusty/vendor/google/proprietary/scripts"})).Because(reason),
NeverAllow().
ModuleType("genrule").
+ // TODO: remove the 4 below targets once new targets are submitted
Without("name", "trusty-arm64.lk.elf.gen").
Without("name", "trusty-arm64-virt-test-debug.lk.elf.gen").
Without("name", "trusty-x86_64.lk.elf.gen").
Without("name", "trusty-x86_64-test.lk.elf.gen").
+ // trusty vm target names moving forward
+ Without("name", "trusty-test_vm-arm64.elf.gen").
+ Without("name", "trusty-test_vm-x86.elf.gen").
+ Without("name", "trusty-security_vm-arm64.elf.gen").
+ Without("name", "trusty-security_vm-x86.elf.gen").
+ Without("name", "trusty-widevine_vm-arm64.elf.gen").
+ Without("name", "trusty-widevine_vm-x86.elf.gen").
WithMatcher("dir_srcs", isSetMatcherInstance).Because(reason),
NeverAllow().
ModuleType("genrule").
+ // TODO: remove the 4 below targets once new targets are submitted
Without("name", "trusty-arm64.lk.elf.gen").
Without("name", "trusty-arm64-virt-test-debug.lk.elf.gen").
Without("name", "trusty-x86_64.lk.elf.gen").
Without("name", "trusty-x86_64-test.lk.elf.gen").
+ // trusty vm target names moving forward
+ Without("name", "trusty-test_vm-arm64.elf.gen").
+ Without("name", "trusty-test_vm-x86.elf.gen").
+ Without("name", "trusty-security_vm-arm64.elf.gen").
+ Without("name", "trusty-security_vm-x86.elf.gen").
+ Without("name", "trusty-widevine_vm-arm64.elf.gen").
+ Without("name", "trusty-widevine_vm-x86.elf.gen").
With("keep_gendir", "true").Because(reason),
}
}
@@ -320,6 +337,14 @@
Because("is_auto_generated property is only allowed for filesystem modules in build/soong/fsgen directory")
}
+func createNoSha1HashRule() Rule {
+ return NeverAllow().
+ ModuleType("filesystem", "android_filesystem").
+ ModuleType("filesystem", "android_system_image").
+ With("avb_hash_algorithm", "sha1").
+ Because("sha1 is discouraged")
+}
+
func createKotlinPluginRule() []Rule {
kotlinPluginProjectsAllowedList := []string{
"external/kotlinc",
@@ -474,6 +499,18 @@
return ".not-in-list(" + strings.Join(m.allowed, ",") + ")"
}
+type InListMatcher struct {
+ allowed []string
+}
+
+func (m *InListMatcher) Test(value string) bool {
+ return InList(value, m.allowed)
+}
+
+func (m *InListMatcher) String() string {
+ return ".in-list(" + strings.Join(m.allowed, ",") + ")"
+}
+
type isSetMatcher struct{}
func (m *isSetMatcher) Test(value string) bool {
@@ -752,6 +789,10 @@
return ¬InListMatcher{allowed}
}
+func InAllowedList(allowed []string) ValueMatcher {
+ return &InListMatcher{allowed}
+}
+
// assorted utils
func cleanPaths(paths []string) []string {
diff --git a/android/package.go b/android/package.go
index eb76751..385326e 100644
--- a/android/package.go
+++ b/android/package.go
@@ -56,7 +56,10 @@
}
func (p *packageModule) GenerateBuildActions(ctx blueprint.ModuleContext) {
- // Nothing to do.
+ ctx.SetProvider(CommonModuleInfoKey, CommonModuleInfo{
+ Enabled: true,
+ PrimaryLicensesProperty: p.primaryLicensesProperty,
+ })
}
func (p *packageModule) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName {
diff --git a/android/packaging.go b/android/packaging.go
index d96cccd..6146f02 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -22,6 +22,7 @@
"github.com/google/blueprint"
"github.com/google/blueprint/gobtools"
"github.com/google/blueprint/proptools"
+ "github.com/google/blueprint/uniquelist"
)
// PackagingSpec abstracts a request to place a built artifact at a certain path in a package. A
@@ -42,7 +43,7 @@
// Whether relPathInPackage should be marked as executable or not
executable bool
- effectiveLicenseFiles *Paths
+ effectiveLicenseFiles uniquelist.UniqueList[Path]
partition string
@@ -52,16 +53,28 @@
skipInstall bool
// Paths of aconfig files for the built artifact
- aconfigPaths *Paths
+ aconfigPaths uniquelist.UniqueList[Path]
// ArchType of the module which produced this packaging spec
archType ArchType
// List of module names that this packaging spec overrides
- overrides *[]string
+ overrides uniquelist.UniqueList[string]
// Name of the module where this packaging spec is output of
owner string
+
+ // If the ninja rule creating the FullInstallPath has already been emitted or not. Do not use,
+ // for the soong-only migration.
+ requiresFullInstall bool
+
+ // The path to the installed file in out/target/product. This is for legacy purposes, with
+ // tools that want to interact with these files outside of the build. You should not use it
+ // inside of the build. Will be nil if this module doesn't require a "full install".
+ fullInstallPath InstallPath
+
+ // String representation of the variation of the module where this packaging spec is output of
+ variation string
}
type packagingSpecGob struct {
@@ -69,13 +82,22 @@
SrcPath Path
SymlinkTarget string
Executable bool
- EffectiveLicenseFiles *Paths
+ EffectiveLicenseFiles Paths
Partition string
SkipInstall bool
- AconfigPaths *Paths
+ AconfigPaths Paths
ArchType ArchType
- Overrides *[]string
+ Overrides []string
Owner string
+ Variation string
+}
+
+func (p *PackagingSpec) Owner() string {
+ return p.owner
+}
+
+func (p *PackagingSpec) Variation() string {
+ return p.variation
}
func (p *PackagingSpec) ToGob() *packagingSpecGob {
@@ -84,13 +106,14 @@
SrcPath: p.srcPath,
SymlinkTarget: p.symlinkTarget,
Executable: p.executable,
- EffectiveLicenseFiles: p.effectiveLicenseFiles,
+ EffectiveLicenseFiles: p.effectiveLicenseFiles.ToSlice(),
Partition: p.partition,
SkipInstall: p.skipInstall,
- AconfigPaths: p.aconfigPaths,
+ AconfigPaths: p.aconfigPaths.ToSlice(),
ArchType: p.archType,
- Overrides: p.overrides,
+ Overrides: p.overrides.ToSlice(),
Owner: p.owner,
+ Variation: p.variation,
}
}
@@ -99,13 +122,14 @@
p.srcPath = data.SrcPath
p.symlinkTarget = data.SymlinkTarget
p.executable = data.Executable
- p.effectiveLicenseFiles = data.EffectiveLicenseFiles
+ p.effectiveLicenseFiles = uniquelist.Make(data.EffectiveLicenseFiles)
p.partition = data.Partition
p.skipInstall = data.SkipInstall
- p.aconfigPaths = data.AconfigPaths
+ p.aconfigPaths = uniquelist.Make(data.AconfigPaths)
p.archType = data.ArchType
- p.overrides = data.Overrides
+ p.overrides = uniquelist.Make(data.Overrides)
p.owner = data.Owner
+ p.variation = data.Variation
}
func (p *PackagingSpec) GobEncode() ([]byte, error) {
@@ -154,10 +178,7 @@
}
func (p *PackagingSpec) EffectiveLicenseFiles() Paths {
- if p.effectiveLicenseFiles == nil {
- return Paths{}
- }
- return *p.effectiveLicenseFiles
+ return p.effectiveLicenseFiles.ToSlice()
}
func (p *PackagingSpec) Partition() string {
@@ -174,7 +195,30 @@
// Paths of aconfig files for the built artifact
func (p *PackagingSpec) GetAconfigPaths() Paths {
- return *p.aconfigPaths
+ return p.aconfigPaths.ToSlice()
+}
+
+// The path to the installed file in out/target/product. This is for legacy purposes, with
+// tools that want to interact with these files outside of the build. You should not use it
+// inside of the build. Will be nil if this module doesn't require a "full install".
+func (p *PackagingSpec) FullInstallPath() InstallPath {
+ return p.fullInstallPath
+}
+
+// If the ninja rule creating the FullInstallPath has already been emitted or not. Do not use,
+// for the soong-only migration.
+func (p *PackagingSpec) RequiresFullInstall() bool {
+ return p.requiresFullInstall
+}
+
+// The source file to be copied to the FullInstallPath. Do not use, for the soong-only migration.
+func (p *PackagingSpec) SrcPath() Path {
+ return p.srcPath
+}
+
+// The symlink target of the PackagingSpec. Do not use, for the soong-only migration.
+func (p *PackagingSpec) SymlinkTarget() string {
+ return p.symlinkTarget
}
type PackageModule interface {
@@ -507,9 +551,7 @@
}
depNames = append(depNames, child.Name())
- if ps.overrides != nil {
- overridden = append(overridden, *ps.overrides...)
- }
+ overridden = append(overridden, ps.overrides.ToSlice()...)
}
})
@@ -575,12 +617,12 @@
func (p *PackagingBase) CopySpecsToDir(ctx ModuleContext, builder *RuleBuilder, specs map[string]PackagingSpec, dir WritablePath) (entries []string) {
dirsToSpecs := make(map[WritablePath]map[string]PackagingSpec)
dirsToSpecs[dir] = specs
- return p.CopySpecsToDirs(ctx, builder, dirsToSpecs)
+ return p.CopySpecsToDirs(ctx, builder, dirsToSpecs, false)
}
// CopySpecsToDirs is a helper that will add commands to the rule builder to copy the PackagingSpec
// entries into corresponding directories.
-func (p *PackagingBase) CopySpecsToDirs(ctx ModuleContext, builder *RuleBuilder, dirsToSpecs map[WritablePath]map[string]PackagingSpec) (entries []string) {
+func (p *PackagingBase) CopySpecsToDirs(ctx ModuleContext, builder *RuleBuilder, dirsToSpecs map[WritablePath]map[string]PackagingSpec, preserveTimestamps bool) (entries []string) {
empty := true
for _, specs := range dirsToSpecs {
if len(specs) > 0 {
@@ -614,7 +656,11 @@
builder.Command().Textf("mkdir -p %s", destDir)
}
if ps.symlinkTarget == "" {
- builder.Command().Text("cp").Input(ps.srcPath).Text(destPath)
+ cmd := builder.Command().Text("cp")
+ if preserveTimestamps {
+ cmd.Flag("-p")
+ }
+ cmd.Input(ps.srcPath).Text(destPath)
} else {
builder.Command().Textf("ln -sf %s %s", ps.symlinkTarget, destPath)
}
diff --git a/android/path_properties.go b/android/path_properties.go
index 55a4dc0..d769d58 100644
--- a/android/path_properties.go
+++ b/android/path_properties.go
@@ -54,12 +54,14 @@
var pathDeviceFirstPrefer32Properties []string
var pathDeviceCommonProperties []string
var pathCommonOsProperties []string
+ var pathHostCommonProperties []string
for _, ps := range props {
pathProperties = append(pathProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path")...)
pathDeviceFirstProperties = append(pathDeviceFirstProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_device_first")...)
pathDeviceFirstPrefer32Properties = append(pathDeviceFirstPrefer32Properties, taggedPropertiesForPropertyStruct(ctx, ps, "path_device_first_prefer32")...)
pathDeviceCommonProperties = append(pathDeviceCommonProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_device_common")...)
pathCommonOsProperties = append(pathCommonOsProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_common_os")...)
+ pathHostCommonProperties = append(pathHostCommonProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_host_common")...)
}
// Remove duplicates to avoid multiple dependencies.
@@ -68,6 +70,7 @@
pathDeviceFirstPrefer32Properties = FirstUniqueStrings(pathDeviceFirstPrefer32Properties)
pathDeviceCommonProperties = FirstUniqueStrings(pathDeviceCommonProperties)
pathCommonOsProperties = FirstUniqueStrings(pathCommonOsProperties)
+ pathHostCommonProperties = FirstUniqueStrings(pathHostCommonProperties)
// Add dependencies to anything that is a module reference.
for _, s := range pathProperties {
@@ -108,6 +111,12 @@
ctx.AddVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), sourceOrOutputDepTag(m, t), m)
}
}
+ // properties tagged "path_host_common" get the host common variant
+ for _, s := range pathHostCommonProperties {
+ if m, t := SrcIsModuleWithTag(s); m != "" {
+ ctx.AddVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), sourceOrOutputDepTag(m, t), m)
+ }
+ }
// properties tagged "path_common_os" get the CommonOs variant
for _, s := range pathCommonOsProperties {
if m, t := SrcIsModuleWithTag(s); m != "" {
diff --git a/android/paths_test.go b/android/paths_test.go
index 20beecc..b125c4e 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -1269,7 +1269,7 @@
ExtendWithErrorHandler(errorHandler).
RunTest(t)
- m := result.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
+ m := result.ModuleForTests(t, "foo", "").Module().(*pathForModuleSrcTestModule)
AssertStringPathsRelativeToTopEquals(t, "srcs", result.Config, test.srcs, m.srcs)
AssertStringPathsRelativeToTopEquals(t, "rels", result.Config, test.rels, m.rels)
@@ -1533,13 +1533,13 @@
FixtureWithRootAndroidBp(bp),
).RunTest(t)
- foo := result.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
+ foo := result.ModuleForTests(t, "foo", "").Module().(*pathForModuleSrcTestModule)
AssertArrayString(t, "foo missing deps", []string{"a", "b", "c"}, foo.missingDeps)
AssertArrayString(t, "foo srcs", []string{}, foo.srcs)
AssertStringEquals(t, "foo src", "", foo.src)
- bar := result.ModuleForTests("bar", "").Module().(*pathForModuleSrcTestModule)
+ bar := result.ModuleForTests(t, "bar", "").Module().(*pathForModuleSrcTestModule)
AssertArrayString(t, "bar missing deps", []string{"d", "e"}, bar.missingDeps)
AssertArrayString(t, "bar srcs", []string{}, bar.srcs)
diff --git a/android/plugin.go b/android/plugin.go
index d62fc94..4348f14 100644
--- a/android/plugin.go
+++ b/android/plugin.go
@@ -135,6 +135,6 @@
disallowedPlugins[name] = true
})
if len(disallowedPlugins) > 0 {
- ctx.Errorf("New plugins are not supported; however %q were found. Please reach out to the build team or use BUILD_BROKEN_PLUGIN_VALIDATION (see Changes.md for more info).", SortedStringKeys(disallowedPlugins))
+ ctx.Errorf("New plugins are not supported; however %q were found. Please reach out to the build team or use BUILD_BROKEN_PLUGIN_VALIDATION (see Changes.md for more info).", SortedKeys(disallowedPlugins))
}
}
diff --git a/android/prebuilt.go b/android/prebuilt.go
index bf27178..7273599 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -28,6 +28,7 @@
func RegisterPrebuiltMutators(ctx RegistrationContext) {
ctx.PreArchMutators(RegisterPrebuiltsPreArchMutators)
+ ctx.PreDepsMutators(RegisterPrebuiltsPreDepsMutators)
ctx.PostDepsMutators(RegisterPrebuiltsPostDepsMutators)
}
@@ -195,6 +196,10 @@
return p.properties.UsePrebuilt
}
+func (p *Prebuilt) SetUsePrebuilt(use bool) {
+ p.properties.UsePrebuilt = use
+}
+
// Called to provide the srcs value for the prebuilt module.
//
// This can be called with a context for any module not just the prebuilt one itself. It can also be
@@ -352,6 +357,17 @@
return true
}
+func IsModulePreferredProxy(ctx OtherModuleProviderContext, module ModuleProxy) bool {
+ if OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoKey).ReplacedByPrebuilt {
+ // A source module that has been replaced by a prebuilt counterpart.
+ return false
+ }
+ if p, ok := OtherModuleProvider(ctx, module, PrebuiltModuleInfoProvider); ok {
+ return p.UsePrebuilt
+ }
+ return true
+}
+
// IsModulePrebuilt returns true if the module implements PrebuiltInterface and
// has been initialized as a prebuilt and so returns a non-nil value from the
// PrebuiltInterface.Prebuilt() method.
@@ -422,9 +438,12 @@
ctx.BottomUp("prebuilt_rename", PrebuiltRenameMutator).UsesRename()
}
-func RegisterPrebuiltsPostDepsMutators(ctx RegisterMutatorsContext) {
+func RegisterPrebuiltsPreDepsMutators(ctx RegisterMutatorsContext) {
ctx.BottomUp("prebuilt_source", PrebuiltSourceDepsMutator).UsesReverseDependencies()
ctx.BottomUp("prebuilt_select", PrebuiltSelectModuleMutator)
+}
+
+func RegisterPrebuiltsPostDepsMutators(ctx RegisterMutatorsContext) {
ctx.BottomUp("prebuilt_postdeps", PrebuiltPostDepsMutator).UsesReplaceDependencies()
}
@@ -468,7 +487,7 @@
bmn, _ := m.(baseModuleName)
name := bmn.BaseModuleName()
if ctx.OtherModuleReverseDependencyVariantExists(name) {
- ctx.AddReverseDependency(ctx.Module(), PrebuiltDepTag, name)
+ ctx.AddReverseVariationDependency(nil, PrebuiltDepTag, name)
p.properties.SourceExists = true
}
}
@@ -604,6 +623,13 @@
}
}
+func IsDontReplaceSourceWithPrebuiltTag(tag blueprint.DependencyTag) bool {
+ if t, ok := tag.(ReplaceSourceWithPrebuilt); ok {
+ return !t.ReplaceSourceWithPrebuilt()
+ }
+ return false
+}
+
// PrebuiltPostDepsMutator replaces dependencies on the source module with dependencies on the
// prebuilt when both modules exist and the prebuilt should be used. When the prebuilt should not
// be used, disable installing it.
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index b90ef3b..27a68fb 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -335,7 +335,7 @@
).RunTestWithBp(t, bp)
for _, variant := range result.ModuleVariantsForTests("foo") {
- foo := result.ModuleForTests("foo", variant)
+ foo := result.ModuleForTests(t, "foo", variant)
t.Run(foo.Module().Target().Os.String(), func(t *testing.T) {
var dependsOnSourceModule, dependsOnPrebuiltModule bool
result.VisitDirectDeps(foo.Module(), func(m blueprint.Module) {
diff --git a/android/proto.go b/android/proto.go
index 66faa20..91d6732 100644
--- a/android/proto.go
+++ b/android/proto.go
@@ -75,7 +75,7 @@
}
ctx.VisitDirectDepsProxyWithTag(ProtoPluginDepTag, func(dep ModuleProxy) {
- if h, ok := OtherModuleProvider(ctx, dep, HostToolProviderKey); !ok || !h.HostToolPath.Valid() {
+ if h, ok := OtherModuleProvider(ctx, dep, HostToolProviderInfoProvider); !ok || !h.HostToolPath.Valid() {
ctx.PropertyErrorf("proto.plugin", "module %q is not a host tool provider",
ctx.OtherModuleName(dep))
} else {
diff --git a/android/provider.go b/android/provider.go
index 81d17a1..b48fd91 100644
--- a/android/provider.go
+++ b/android/provider.go
@@ -4,8 +4,8 @@
"github.com/google/blueprint"
)
-// OtherModuleProviderContext is a helper interface that is a subset of ModuleContext, BottomUpMutatorContext, or
-// TopDownMutatorContext for use in OtherModuleProvider.
+// OtherModuleProviderContext is a helper interface that is a subset of ModuleContext or BottomUpMutatorContext
+// for use in OtherModuleProvider.
type OtherModuleProviderContext interface {
otherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) (any, bool)
}
@@ -13,7 +13,6 @@
var _ OtherModuleProviderContext = BaseModuleContext(nil)
var _ OtherModuleProviderContext = ModuleContext(nil)
var _ OtherModuleProviderContext = BottomUpMutatorContext(nil)
-var _ OtherModuleProviderContext = TopDownMutatorContext(nil)
var _ OtherModuleProviderContext = SingletonContext(nil)
var _ OtherModuleProviderContext = (*TestContext)(nil)
@@ -21,8 +20,7 @@
// returned and the boolean is true. If it has not been set the zero value of the provider's type is returned
// and the boolean is false. The value returned may be a deep copy of the value originally passed to SetProvider.
//
-// OtherModuleProviderContext is a helper interface that accepts ModuleContext, BottomUpMutatorContext, or
-// TopDownMutatorContext.
+// OtherModuleProviderContext is a helper interface that accepts ModuleContext or BottomUpMutatorContext.
func OtherModuleProvider[K any](ctx OtherModuleProviderContext, module blueprint.Module, provider blueprint.ProviderKey[K]) (K, bool) {
value, ok := ctx.otherModuleProvider(getWrappedModule(module), provider)
if !ok {
@@ -37,8 +35,8 @@
return value
}
-// ModuleProviderContext is a helper interface that is a subset of ModuleContext, BottomUpMutatorContext, or
-// TopDownMutatorContext for use in ModuleProvider.
+// ModuleProviderContext is a helper interface that is a subset of ModuleContext or BottomUpMutatorContext
+// for use in ModuleProvider.
type ModuleProviderContext interface {
provider(provider blueprint.AnyProviderKey) (any, bool)
}
@@ -46,14 +44,12 @@
var _ ModuleProviderContext = BaseModuleContext(nil)
var _ ModuleProviderContext = ModuleContext(nil)
var _ ModuleProviderContext = BottomUpMutatorContext(nil)
-var _ ModuleProviderContext = TopDownMutatorContext(nil)
// ModuleProvider reads the provider for the current module. If the provider has been set the value is
// returned and the boolean is true. If it has not been set the zero value of the provider's type is returned
// and the boolean is false. The value returned may be a deep copy of the value originally passed to SetProvider.
//
-// ModuleProviderContext is a helper interface that accepts ModuleContext, BottomUpMutatorContext, or
-// TopDownMutatorContext.
+// ModuleProviderContext is a helper interface that accepts ModuleContext or BottomUpMutatorContext.
func ModuleProvider[K any](ctx ModuleProviderContext, provider blueprint.ProviderKey[K]) (K, bool) {
value, ok := ctx.provider(provider)
if !ok {
@@ -63,8 +59,8 @@
return value.(K), ok
}
-// SetProviderContext is a helper interface that is a subset of ModuleContext, BottomUpMutatorContext, or
-// TopDownMutatorContext for use in SetProvider.
+// SetProviderContext is a helper interface that is a subset of ModuleContext or BottomUpMutatorContext
+// for use in SetProvider.
type SetProviderContext interface {
setProvider(provider blueprint.AnyProviderKey, value any)
}
@@ -72,15 +68,13 @@
var _ SetProviderContext = BaseModuleContext(nil)
var _ SetProviderContext = ModuleContext(nil)
var _ SetProviderContext = BottomUpMutatorContext(nil)
-var _ SetProviderContext = TopDownMutatorContext(nil)
// SetProvider sets the value for a provider for the current module. It panics if not called
// during the appropriate mutator or GenerateBuildActions pass for the provider, if the value
// is not of the appropriate type, or if the value has already been set. The value should not
// be modified after being passed to SetProvider.
//
-// SetProviderContext is a helper interface that accepts ModuleContext, BottomUpMutatorContext, or
-// TopDownMutatorContext.
+// SetProviderContext is a helper interface that accepts ModuleContext or BottomUpMutatorContext.
func SetProvider[K any](ctx SetProviderContext, provider blueprint.ProviderKey[K], value K) {
ctx.setProvider(provider, value)
}
diff --git a/android/register.go b/android/register.go
index 8d2f19e..10c9114 100644
--- a/android/register.go
+++ b/android/register.go
@@ -89,7 +89,6 @@
type mutator struct {
name string
bottomUpMutator blueprint.BottomUpMutator
- topDownMutator blueprint.TopDownMutator
transitionMutator blueprint.TransitionMutator
usesRename bool
@@ -192,6 +191,11 @@
func collateGloballyRegisteredSingletons() sortableComponents {
allSingletons := append(sortableComponents(nil), singletons...)
allSingletons = append(allSingletons,
+ // Soong only androidmk is registered later than other singletons in order to collect
+ // dist contributions from other singletons. This singleton is registered just before
+ // phony so that its phony rules can be collected by the phony singleton.
+ singleton{parallel: false, name: "soongonlyandroidmk", factory: soongOnlyAndroidMkSingletonFactory},
+
// Register phony just before makevars so it can write out its phony rules as Make rules
singleton{parallel: false, name: "phony", factory: phonySingletonFactory},
diff --git a/android/rule_builder_test.go b/android/rule_builder_test.go
index 566bafa..5f3b9be 100644
--- a/android/rule_builder_test.go
+++ b/android/rule_builder_test.go
@@ -651,7 +651,7 @@
outFile := "out/soong/.intermediates/foo/gen/foo"
rspFile := "out/soong/.intermediates/foo/rsp"
rspFile2 := "out/soong/.intermediates/foo/rsp2"
- module := result.ModuleForTests("foo", "")
+ module := result.ModuleForTests(t, "foo", "")
check(t, module.Rule("rule"), module.Output(rspFile2),
"cp in "+outFile+" @"+rspFile+" @"+rspFile2,
outFile, outFile+".d", rspFile, rspFile2, true, nil, nil)
@@ -668,7 +668,7 @@
sandboxPath := shared.TempDirForOutDir("out/soong")
cmd := sbox + ` --sandbox-path ` + sandboxPath + ` --output-dir ` + sboxOutDir + ` --manifest ` + manifest
- module := result.ModuleForTests("foo_sbox", "")
+ module := result.ModuleForTests(t, "foo_sbox", "")
check(t, module.Output("gen/foo_sbox"), module.Output(rspFile2),
cmd, outFile, depFile, rspFile, rspFile2, false, []string{manifest}, []string{sbox})
})
@@ -685,7 +685,7 @@
cmd := sbox + ` --sandbox-path ` + sandboxPath + ` --output-dir ` + sboxOutDir + ` --manifest ` + manifest
- module := result.ModuleForTests("foo_sbox_inputs", "")
+ module := result.ModuleForTests(t, "foo_sbox_inputs", "")
check(t, module.Output("gen/foo_sbox_inputs"), module.Output(rspFile2),
cmd, outFile, depFile, rspFile, rspFile2, false, []string{manifest}, []string{sbox})
})
@@ -693,7 +693,7 @@
outFile := filepath.Join("out/soong/singleton/gen/baz")
rspFile := filepath.Join("out/soong/singleton/rsp")
rspFile2 := filepath.Join("out/soong/singleton/rsp2")
- singleton := result.SingletonForTests("rule_builder_test")
+ singleton := result.SingletonForTests(t, "rule_builder_test")
check(t, singleton.Rule("rule"), singleton.Output(rspFile2),
"cp in "+outFile+" @"+rspFile+" @"+rspFile2,
outFile, outFile+".d", rspFile, rspFile2, true, nil, nil)
@@ -756,14 +756,14 @@
for _, test := range testcases {
t.Run(test.name, func(t *testing.T) {
t.Run("sbox", func(t *testing.T) {
- gen := result.ModuleForTests(test.name+"_sbox", "")
+ gen := result.ModuleForTests(t, test.name+"_sbox", "")
manifest := RuleBuilderSboxProtoForTests(t, result.TestContext, gen.Output("sbox.textproto"))
hash := manifest.Commands[0].GetInputHash()
AssertStringEquals(t, "hash", test.expectedHash, hash)
})
t.Run("", func(t *testing.T) {
- gen := result.ModuleForTests(test.name+"", "")
+ gen := result.ModuleForTests(t, test.name+"", "")
command := gen.Output("gen/" + test.name).RuleParams.Command
if g, w := command, " # hash of input list: "+test.expectedHash; !strings.HasSuffix(g, w) {
t.Errorf("Expected command line to end with %q, got %q", w, g)
diff --git a/android/sbom.go b/android/sbom.go
index f2b9c0f..fc61c41 100644
--- a/android/sbom.go
+++ b/android/sbom.go
@@ -84,12 +84,6 @@
Inputs: []Path{this.sbomFile},
Output: PathForPhony(ctx, "sbom"),
})
- }
-}
-
-func (this *sbomSingleton) MakeVars(ctx MakeVarsContext) {
- // When building SBOM of products
- if !ctx.Config().UnbundledBuildApps() {
ctx.DistForGoalWithFilename("droid", this.sbomFile, "sbom/sbom.spdx.json")
}
}
diff --git a/android/sdk_version.go b/android/sdk_version.go
index a9b88fb..fa3abaa 100644
--- a/android/sdk_version.go
+++ b/android/sdk_version.go
@@ -123,6 +123,31 @@
}
}
+func JavaLibraryNameToSdkKind(name string) (SdkKind, bool) {
+ if name == SdkPublic.DefaultJavaLibraryName() {
+ return SdkPublic, true
+ }
+ if name == SdkSystem.DefaultJavaLibraryName() {
+ return SdkSystem, true
+ }
+ if name == SdkTest.DefaultJavaLibraryName() {
+ return SdkTest, true
+ }
+ if name == SdkTestFrameworksCore.DefaultJavaLibraryName() {
+ return SdkTestFrameworksCore, true
+ }
+ if name == SdkCore.DefaultJavaLibraryName() {
+ return SdkCore, true
+ }
+ if name == SdkModule.DefaultJavaLibraryName() {
+ return SdkModule, true
+ }
+ if name == SdkSystemServer.DefaultJavaLibraryName() {
+ return SdkSystemServer, true
+ }
+ return SdkInvalid, false
+}
+
func (k SdkKind) DefaultExportableJavaLibraryName() string {
switch k {
case SdkPublic, SdkSystem, SdkTest, SdkModule, SdkSystemServer:
diff --git a/android/selects_test.go b/android/selects_test.go
index 1397ed8..7f20a3d 100644
--- a/android/selects_test.go
+++ b/android/selects_test.go
@@ -1118,7 +1118,7 @@
for moduleName := range tc.providers {
expected := tc.providers[moduleName]
- m := result.ModuleForTests(moduleName, "android_arm64_armv8-a")
+ m := result.ModuleForTests(t, moduleName, "android_arm64_armv8-a")
p, _ := OtherModuleProvider(result.testContext.OtherModuleProviderAdaptor(), m.Module(), selectsTestProviderKey)
if !reflect.DeepEqual(p, expected) {
t.Errorf("Expected:\n %q\ngot:\n %q", expected.String(), p.String())
diff --git a/android/singleton.go b/android/singleton.go
index 0754b0c..a03ea74 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -15,6 +15,9 @@
package android
import (
+ "slices"
+ "sync"
+
"github.com/google/blueprint"
)
@@ -81,6 +84,9 @@
VisitAllModuleVariantProxies(module Module, visit func(proxy ModuleProxy))
PrimaryModule(module Module) Module
+
+ PrimaryModuleProxy(module ModuleProxy) ModuleProxy
+
IsFinalModule(module Module) bool
AddNinjaFileDeps(deps ...string)
@@ -97,6 +103,24 @@
// HasMutatorFinished returns true if the given mutator has finished running.
// It will panic if given an invalid mutator name.
HasMutatorFinished(mutatorName string) bool
+
+ // DistForGoals creates a rule to copy one or more Paths to the artifacts
+ // directory on the build server when any of the specified goals are built.
+ DistForGoal(goal string, paths ...Path)
+
+ // DistForGoalWithFilename creates a rule to copy a Path to the artifacts
+ // directory on the build server with the given filename when the specified
+ // goal is built.
+ DistForGoalWithFilename(goal string, path Path, filename string)
+
+ // DistForGoals creates a rule to copy one or more Paths to the artifacts
+ // directory on the build server when any of the specified goals are built.
+ DistForGoals(goals []string, paths ...Path)
+
+ // DistForGoalsWithFilename creates a rule to copy a Path to the artifacts
+ // directory on the build server with the given filename when any of the
+ // specified goals are built.
+ DistForGoalsWithFilename(goals []string, path Path, filename string)
}
type singletonAdaptor struct {
@@ -118,6 +142,13 @@
s.buildParams = sctx.buildParams
s.ruleParams = sctx.ruleParams
+
+ if len(sctx.dists) > 0 {
+ dists := getSingletonDists(sctx.Config())
+ dists.lock.Lock()
+ defer dists.lock.Unlock()
+ dists.dists = append(dists.dists, sctx.dists...)
+ }
}
func (s *singletonAdaptor) BuildParamsForTests() []BuildParams {
@@ -128,6 +159,19 @@
return s.ruleParams
}
+var singletonDistsKey = NewOnceKey("singletonDistsKey")
+
+type singletonDistsAndLock struct {
+ dists []dist
+ lock sync.Mutex
+}
+
+func getSingletonDists(config Config) *singletonDistsAndLock {
+ return config.Once(singletonDistsKey, func() interface{} {
+ return &singletonDistsAndLock{}
+ }).(*singletonDistsAndLock)
+}
+
type Singleton interface {
GenerateBuildActions(SingletonContext)
}
@@ -137,6 +181,7 @@
buildParams []BuildParams
ruleParams map[blueprint.Rule]blueprint.RuleParams
+ dists []dist
}
func (s *singletonContextAdaptor) blueprintSingletonContext() blueprint.SingletonContext {
@@ -229,6 +274,22 @@
}
}
+func (s *singletonContextAdaptor) ModuleName(module blueprint.Module) string {
+ return s.SingletonContext.ModuleName(getWrappedModule(module))
+}
+
+func (s *singletonContextAdaptor) ModuleDir(module blueprint.Module) string {
+ return s.SingletonContext.ModuleDir(getWrappedModule(module))
+}
+
+func (s *singletonContextAdaptor) ModuleSubDir(module blueprint.Module) string {
+ return s.SingletonContext.ModuleSubDir(getWrappedModule(module))
+}
+
+func (s *singletonContextAdaptor) ModuleType(module blueprint.Module) string {
+ return s.SingletonContext.ModuleType(getWrappedModule(module))
+}
+
func (s *singletonContextAdaptor) VisitAllModulesBlueprint(visit func(blueprint.Module)) {
s.SingletonContext.VisitAllModules(visit)
}
@@ -273,6 +334,10 @@
return s.SingletonContext.PrimaryModule(module).(Module)
}
+func (s *singletonContextAdaptor) PrimaryModuleProxy(module ModuleProxy) ModuleProxy {
+ return ModuleProxy{s.SingletonContext.PrimaryModuleProxy(module.module)}
+}
+
func (s *singletonContextAdaptor) IsFinalModule(module Module) bool {
return s.SingletonContext.IsFinalModule(module)
}
@@ -315,3 +380,31 @@
func (s *singletonContextAdaptor) HasMutatorFinished(mutatorName string) bool {
return s.blueprintSingletonContext().HasMutatorFinished(mutatorName)
}
+func (s *singletonContextAdaptor) DistForGoal(goal string, paths ...Path) {
+ s.DistForGoals([]string{goal}, paths...)
+}
+
+func (s *singletonContextAdaptor) DistForGoalWithFilename(goal string, path Path, filename string) {
+ s.DistForGoalsWithFilename([]string{goal}, path, filename)
+}
+
+func (s *singletonContextAdaptor) DistForGoals(goals []string, paths ...Path) {
+ var copies distCopies
+ for _, path := range paths {
+ copies = append(copies, distCopy{
+ from: path,
+ dest: path.Base(),
+ })
+ }
+ s.dists = append(s.dists, dist{
+ goals: slices.Clone(goals),
+ paths: copies,
+ })
+}
+
+func (s *singletonContextAdaptor) DistForGoalsWithFilename(goals []string, path Path, filename string) {
+ s.dists = append(s.dists, dist{
+ goals: slices.Clone(goals),
+ paths: distCopies{{from: path, dest: filename}},
+ })
+}
diff --git a/android/singleton_module_test.go b/android/singleton_module_test.go
index 3b8c6b2..6f61a3b 100644
--- a/android/singleton_module_test.go
+++ b/android/singleton_module_test.go
@@ -61,7 +61,7 @@
FixtureWithRootAndroidBp(bp),
).RunTest(t)
- ops := result.ModuleForTests("test_singleton_module", "").Module().(*testSingletonModule).ops
+ ops := result.ModuleForTests(t, "test_singleton_module", "").Module().(*testSingletonModule).ops
wantOps := []string{"GenerateAndroidBuildActions", "GenerateSingletonBuildActions", "MakeVars"}
AssertDeepEquals(t, "operations", wantOps, ops)
}
@@ -88,7 +88,7 @@
prepareForSingletonModuleTest,
).RunTest(t)
- singleton := result.SingletonForTests("test_singleton_module").Singleton()
+ singleton := result.SingletonForTests(t, "test_singleton_module").Singleton()
sm := singleton.(*singletonModuleSingletonAdaptor).sm
ops := sm.(*testSingletonModule).ops
if ops != nil {
diff --git a/android/soong_config_modules_test.go b/android/soong_config_modules_test.go
index 04aafde..f98e02b 100644
--- a/android/soong_config_modules_test.go
+++ b/android/soong_config_modules_test.go
@@ -321,10 +321,10 @@
FixtureWithRootAndroidBp(bp),
).RunTest(t)
- foo := result.ModuleForTests("foo", "").Module().(*soongConfigTestModule)
+ foo := result.ModuleForTests(t, "foo", "").Module().(*soongConfigTestModule)
AssertDeepEquals(t, "foo cflags", tc.fooExpectedFlags, foo.props.Cflags)
- fooDefaults := result.ModuleForTests("foo_with_defaults", "").Module().(*soongConfigTestModule)
+ fooDefaults := result.ModuleForTests(t, "foo_with_defaults", "").Module().(*soongConfigTestModule)
AssertDeepEquals(t, "foo_with_defaults cflags", tc.fooDefaultsExpectedFlags, fooDefaults.props.Cflags)
})
}
@@ -499,8 +499,8 @@
).RunTest(t)
// Make sure that the singleton was created.
- result.SingletonForTests("test_singleton")
- m := result.ModuleForTests("wiley", "").module.(*soongConfigTestSingletonModule)
+ result.SingletonForTests(t, "test_singleton")
+ m := result.ModuleForTests(t, "wiley", "").module.(*soongConfigTestSingletonModule)
AssertStringEquals(t, "fragments", test.expectedFragments, fmt.Sprintf("%+v", m.props.Fragments))
})
}
diff --git a/android/team_proto/OWNERS b/android/team_proto/OWNERS
index 2beb4f4..1eb820b 100644
--- a/android/team_proto/OWNERS
+++ b/android/team_proto/OWNERS
@@ -1,5 +1,4 @@
dariofreni@google.com
joeo@google.com
ronish@google.com
-caditya@google.com
rbraunstein@google.com
diff --git a/android/team_test.go b/android/team_test.go
index ccfcaaa..dcc1c99 100644
--- a/android/team_test.go
+++ b/android/team_test.go
@@ -61,9 +61,9 @@
`)
// Assert the rule from GenerateAndroidBuildActions exists.
- m := ctx.ModuleForTests("main_test", "")
+ m := ctx.ModuleForTests(t, "main_test", "")
AssertStringEquals(t, "msg", m.Module().base().Team(), "someteam")
- m = ctx.ModuleForTests("tool", "")
+ m = ctx.ModuleForTests(t, "tool", "")
AssertStringEquals(t, "msg", m.Module().base().Team(), "team2")
}
diff --git a/android/test_mapping_zip.go b/android/test_mapping_zip.go
new file mode 100644
index 0000000..8dc70d7
--- /dev/null
+++ b/android/test_mapping_zip.go
@@ -0,0 +1,49 @@
+// Copyright 2025 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 android
+
+func init() {
+ InitRegistrationContext.RegisterSingletonType("test_mapping_zip_singleton", testMappingZipSingletonFactory)
+}
+
+func testMappingZipSingletonFactory() Singleton {
+ return &testMappingZipSingleton{}
+}
+
+type testMappingZipSingleton struct{}
+
+func (s *testMappingZipSingleton) GenerateBuildActions(ctx SingletonContext) {
+ fileListFile := PathForArbitraryOutput(ctx, ".module_paths", "TEST_MAPPING.list")
+ out := PathForOutput(ctx, "test_mappings.zip")
+ dep := PathForOutput(ctx, "test_mappings.zip.d")
+
+ // disabled-presubmit-tests used to be filled out based on modules that set
+ // LOCAL_PRESUBMIT_DISABLED. But that's no longer used and there was never a soong equivalent
+ // anyways, so just always create an empty file.
+ disabledPresubmitTestsFile := PathForOutput(ctx, "disabled-presubmit-tests")
+ WriteFileRule(ctx, disabledPresubmitTestsFile, "")
+
+ builder := NewRuleBuilder(pctx, ctx)
+ builder.Command().BuiltTool("soong_zip").
+ FlagWithOutput("-o ", out).
+ FlagWithInput("-l ", fileListFile).
+ FlagWithArg("-e ", "disabled-presubmit-tests").
+ FlagWithInput("-f ", disabledPresubmitTestsFile)
+ builder.Command().Textf("echo '%s : ' $(cat %s) > ", out, fileListFile).DepFile(dep)
+ builder.Build("test_mappings_zip", "build TEST_MAPPING zip")
+
+ ctx.Phony("test_mapping", out)
+ ctx.DistForGoals([]string{"dist_files", "test_mapping"}, out)
+}
diff --git a/android/test_suites.go b/android/test_suites.go
index 936d2b6..39317ec 100644
--- a/android/test_suites.go
+++ b/android/test_suites.go
@@ -17,6 +17,8 @@
import (
"path/filepath"
"strings"
+
+ "github.com/google/blueprint"
)
func init() {
@@ -37,18 +39,24 @@
TestSuites() []string
}
+type TestSuiteInfo struct {
+ TestSuites []string
+}
+
+var TestSuiteInfoProvider = blueprint.NewProvider[TestSuiteInfo]()
+
func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) {
files := make(map[string]map[string]InstallPaths)
- ctx.VisitAllModules(func(m Module) {
- if tsm, ok := m.(TestSuiteModule); ok {
- for _, testSuite := range tsm.TestSuites() {
+ ctx.VisitAllModuleProxies(func(m ModuleProxy) {
+ if tsm, ok := OtherModuleProvider(ctx, m, TestSuiteInfoProvider); ok {
+ for _, testSuite := range tsm.TestSuites {
if files[testSuite] == nil {
files[testSuite] = make(map[string]InstallPaths)
}
name := ctx.ModuleName(m)
files[testSuite][name] = append(files[testSuite][name],
- OtherModuleProviderOrDefault(ctx, tsm, InstallFilesProvider).InstallFiles...)
+ OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider).InstallFiles...)
}
}
})
@@ -58,9 +66,6 @@
t.ravenwood = ravenwoodTestSuite(ctx, files["ravenwood-tests"])
ctx.Phony("ravenwood-tests", t.ravenwood...)
-}
-
-func (t *testSuiteFiles) MakeVars(ctx MakeVarsContext) {
ctx.DistForGoal("robolectric-tests", t.robolectric...)
ctx.DistForGoal("ravenwood-tests", t.ravenwood...)
}
diff --git a/android/test_suites_test.go b/android/test_suites_test.go
index db9a34d..dda9329 100644
--- a/android/test_suites_test.go
+++ b/android/test_suites_test.go
@@ -52,7 +52,7 @@
}
`)
- config := ctx.SingletonForTests("testsuites")
+ config := ctx.SingletonForTests(t, "testsuites")
allOutputs := config.AllOutputs()
wantContents := map[string]string{
@@ -110,6 +110,10 @@
for _, output := range f.props.Outputs {
ctx.InstallFile(pathForTestCases(ctx), output, nil)
}
+
+ SetProvider(ctx, TestSuiteInfoProvider, TestSuiteInfo{
+ TestSuites: f.TestSuites(),
+ })
}
func (f *fake_module) TestSuites() []string {
diff --git a/android/testing.go b/android/testing.go
index 6c4f4f8..1962fde 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -530,7 +530,8 @@
// both have the same value. Both the module and the map are allowed to have
// extra variations that the other doesn't have. Panics if not exactly one
// module variant matches.
-func (ctx *TestContext) ModuleVariantForTests(name string, matchVariations map[string]string) TestingModule {
+func (ctx *TestContext) ModuleVariantForTests(t *testing.T, name string, matchVariations map[string]string) TestingModule {
+ t.Helper()
modules := []Module{}
ctx.VisitAllModules(func(m blueprint.Module) {
if ctx.ModuleName(m) == name {
@@ -562,12 +563,12 @@
})
if len(allVariants) == 0 {
- panic(fmt.Errorf("failed to find module %q. All modules:\n %s",
- name, strings.Join(SortedUniqueStrings(allModuleNames), "\n ")))
+ t.Fatalf("failed to find module %q. All modules:\n %s",
+ name, strings.Join(SortedUniqueStrings(allModuleNames), "\n "))
} else {
sort.Strings(allVariants)
- panic(fmt.Errorf("failed to find module %q matching %v. All variants:\n %s",
- name, matchVariations, strings.Join(allVariants, "\n ")))
+ t.Fatalf("failed to find module %q matching %v. All variants:\n %s",
+ name, matchVariations, strings.Join(allVariants, "\n "))
}
}
@@ -577,14 +578,15 @@
moduleStrings = append(moduleStrings, m.String())
}
sort.Strings(moduleStrings)
- panic(fmt.Errorf("module %q has more than one variant that match %v:\n %s",
- name, matchVariations, strings.Join(moduleStrings, "\n ")))
+ t.Fatalf("module %q has more than one variant that match %v:\n %s",
+ name, matchVariations, strings.Join(moduleStrings, "\n "))
}
- return newTestingModule(ctx.config, modules[0])
+ return newTestingModule(t, ctx.config, modules[0])
}
-func (ctx *TestContext) ModuleForTests(name, variant string) TestingModule {
+func (ctx *TestContext) ModuleForTests(t *testing.T, name, variant string) TestingModule {
+ t.Helper()
var module Module
ctx.VisitAllModules(func(m blueprint.Module) {
if ctx.ModuleName(m) == name && ctx.ModuleSubDir(m) == variant {
@@ -605,15 +607,15 @@
sort.Strings(allVariants)
if len(allVariants) == 0 {
- panic(fmt.Errorf("failed to find module %q. All modules:\n %s",
- name, strings.Join(SortedUniqueStrings(allModuleNames), "\n ")))
+ t.Fatalf("failed to find module %q. All modules:\n %s",
+ name, strings.Join(SortedUniqueStrings(allModuleNames), "\n "))
} else {
- panic(fmt.Errorf("failed to find module %q variant %q. All variants:\n %s",
- name, variant, strings.Join(allVariants, "\n ")))
+ t.Fatalf("failed to find module %q variant %q. All variants:\n %s",
+ name, variant, strings.Join(allVariants, "\n "))
}
}
- return newTestingModule(ctx.config, module)
+ return newTestingModule(t, ctx.config, module)
}
func (ctx *TestContext) ModuleVariantsForTests(name string) []string {
@@ -627,21 +629,24 @@
}
// SingletonForTests returns a TestingSingleton for the singleton registered with the given name.
-func (ctx *TestContext) SingletonForTests(name string) TestingSingleton {
+func (ctx *TestContext) SingletonForTests(t *testing.T, name string) TestingSingleton {
+ t.Helper()
allSingletonNames := []string{}
for _, s := range ctx.Singletons() {
n := ctx.SingletonName(s)
if n == name {
return TestingSingleton{
- baseTestingComponent: newBaseTestingComponent(ctx.config, s.(testBuildProvider)),
+ baseTestingComponent: newBaseTestingComponent(t, ctx.config, s.(testBuildProvider)),
singleton: s.(*singletonAdaptor).Singleton,
}
}
allSingletonNames = append(allSingletonNames, n)
}
- panic(fmt.Errorf("failed to find singleton %q."+
- "\nall singletons: %v", name, allSingletonNames))
+ t.Fatalf("failed to find singleton %q."+
+ "\nall singletons: %v", name, allSingletonNames)
+
+ return TestingSingleton{}
}
type InstallMakeRule struct {
@@ -651,6 +656,7 @@
}
func parseMkRules(t *testing.T, config Config, nodes []mkparser.Node) []InstallMakeRule {
+ t.Helper()
var rules []InstallMakeRule
for _, node := range nodes {
if mkParserRule, ok := node.(*mkparser.Rule); ok {
@@ -688,7 +694,8 @@
}
func (ctx *TestContext) InstallMakeRulesForTesting(t *testing.T) []InstallMakeRule {
- installs := ctx.SingletonForTests("makevars").Singleton().(*makeVarsSingleton).installsForTesting
+ t.Helper()
+ installs := ctx.SingletonForTests(t, "makevars").Singleton().(*makeVarsSingleton).installsForTesting
buf := bytes.NewBuffer(append([]byte(nil), installs...))
parser := mkparser.NewParser("makevars", buf)
@@ -728,8 +735,9 @@
//
// It is necessary to use PrepareForTestAccessingMakeVars in tests that want to call this function.
// Along with any other preparers needed to add the make vars.
-func (ctx *TestContext) MakeVarsForTesting(filter func(variable MakeVarVariable) bool) []MakeVarVariable {
- vars := ctx.SingletonForTests("makevars").Singleton().(*makeVarsSingleton).varsForTesting
+func (ctx *TestContext) MakeVarsForTesting(t *testing.T, filter func(variable MakeVarVariable) bool) []MakeVarVariable {
+ t.Helper()
+ vars := ctx.SingletonForTests(t, "makevars").Singleton().(*makeVarsSingleton).varsForTesting
result := make([]MakeVarVariable, 0, len(vars))
for _, v := range vars {
if filter(v) {
@@ -846,12 +854,13 @@
// baseTestingComponent provides functionality common to both TestingModule and TestingSingleton.
type baseTestingComponent struct {
+ t *testing.T
config Config
provider testBuildProvider
}
-func newBaseTestingComponent(config Config, provider testBuildProvider) baseTestingComponent {
- return baseTestingComponent{config, provider}
+func newBaseTestingComponent(t *testing.T, config Config, provider testBuildProvider) baseTestingComponent {
+ return baseTestingComponent{t, config, provider}
}
// A function that will normalize a string containing paths, e.g. ninja command, by replacing
@@ -922,9 +931,10 @@
}
func (b baseTestingComponent) buildParamsFromRule(rule string) TestingBuildParams {
+ b.t.Helper()
p, searchRules := b.maybeBuildParamsFromRule(rule)
if p.Rule == nil {
- panic(fmt.Errorf("couldn't find rule %q.\nall rules:\n%s", rule, strings.Join(searchRules, "\n")))
+ b.t.Fatalf("couldn't find rule %q.\nall rules:\n%s", rule, strings.Join(searchRules, "\n"))
}
return p
}
@@ -941,9 +951,10 @@
}
func (b baseTestingComponent) buildParamsFromDescription(desc string) TestingBuildParams {
+ b.t.Helper()
p, searchedDescriptions := b.maybeBuildParamsFromDescription(desc)
if p.Rule == nil {
- panic(fmt.Errorf("couldn't find description %q\nall descriptions:\n%s", desc, strings.Join(searchedDescriptions, "\n")))
+ b.t.Fatalf("couldn't find description %q\nall descriptions:\n%s", desc, strings.Join(searchedDescriptions, "\n"))
}
return p
}
@@ -974,10 +985,11 @@
}
func (b baseTestingComponent) buildParamsFromOutput(file string) TestingBuildParams {
+ b.t.Helper()
p, searchedOutputs := b.maybeBuildParamsFromOutput(file)
if p.Rule == nil {
- panic(fmt.Errorf("couldn't find output %q.\nall outputs:\n %s\n",
- file, strings.Join(searchedOutputs, "\n ")))
+ b.t.Fatalf("couldn't find output %q.\nall outputs:\n %s\n",
+ file, strings.Join(searchedOutputs, "\n "))
}
return p
}
@@ -999,6 +1011,7 @@
// Rule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name. Panics if no rule is found.
func (b baseTestingComponent) Rule(rule string) TestingBuildParams {
+ b.t.Helper()
return b.buildParamsFromRule(rule)
}
@@ -1012,6 +1025,7 @@
// Description finds a call to ctx.Build with BuildParams.Description set to a the given string. Panics if no rule is
// found.
func (b baseTestingComponent) Description(desc string) TestingBuildParams {
+ b.t.Helper()
return b.buildParamsFromDescription(desc)
}
@@ -1025,6 +1039,7 @@
// Output finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel()
// value matches the provided string. Panics if no rule is found.
func (b baseTestingComponent) Output(file string) TestingBuildParams {
+ b.t.Helper()
return b.buildParamsFromOutput(file)
}
@@ -1040,9 +1055,9 @@
module Module
}
-func newTestingModule(config Config, module Module) TestingModule {
+func newTestingModule(t *testing.T, config Config, module Module) TestingModule {
return TestingModule{
- newBaseTestingComponent(config, module),
+ newBaseTestingComponent(t, config, module),
module,
}
}
@@ -1152,7 +1167,7 @@
config.katiEnabled = true
}
-func AndroidMkEntriesForTest(t *testing.T, ctx *TestContext, mod blueprint.Module) []AndroidMkEntries {
+func AndroidMkEntriesForTest(t *testing.T, ctx *TestContext, mod Module) []AndroidMkEntries {
t.Helper()
var p AndroidMkEntriesProvider
var ok bool
@@ -1161,15 +1176,15 @@
}
entriesList := p.AndroidMkEntries()
- aconfigUpdateAndroidMkEntries(ctx, mod.(Module), &entriesList)
+ aconfigUpdateAndroidMkEntries(ctx, mod, &entriesList)
for i := range entriesList {
entriesList[i].fillInEntries(ctx, mod)
}
return entriesList
}
-func AndroidMkInfoForTest(t *testing.T, ctx *TestContext, mod blueprint.Module) *AndroidMkProviderInfo {
- if runtime.GOOS == "darwin" && mod.(Module).base().Os() != Darwin {
+func AndroidMkInfoForTest(t *testing.T, ctx *TestContext, mod Module) *AndroidMkProviderInfo {
+ if runtime.GOOS == "darwin" && mod.base().Os() != Darwin {
// The AndroidMkInfo provider is not set in this case.
t.Skip("AndroidMkInfo provider is not set on darwin")
}
@@ -1181,18 +1196,19 @@
}
info := OtherModuleProviderOrDefault(ctx, mod, AndroidMkInfoProvider)
- aconfigUpdateAndroidMkInfos(ctx, mod.(Module), info)
- info.PrimaryInfo.fillInEntries(ctx, mod)
+ aconfigUpdateAndroidMkInfos(ctx, mod, info)
+ commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoKey)
+ info.PrimaryInfo.fillInEntries(ctx, mod, &commonInfo)
if len(info.ExtraInfo) > 0 {
for _, ei := range info.ExtraInfo {
- ei.fillInEntries(ctx, mod)
+ ei.fillInEntries(ctx, mod, &commonInfo)
}
}
return info
}
-func AndroidMkDataForTest(t *testing.T, ctx *TestContext, mod blueprint.Module) AndroidMkData {
+func AndroidMkDataForTest(t *testing.T, ctx *TestContext, mod Module) AndroidMkData {
t.Helper()
var p AndroidMkDataProvider
var ok bool
@@ -1201,7 +1217,7 @@
}
data := p.AndroidMk()
data.fillInData(ctx, mod)
- aconfigUpdateAndroidMkData(ctx, mod.(Module), &data)
+ aconfigUpdateAndroidMkData(ctx, mod, &data)
return data
}
diff --git a/android/transition.go b/android/transition.go
index 7c04eff..0677ca1 100644
--- a/android/transition.go
+++ b/android/transition.go
@@ -73,29 +73,56 @@
// two systems: when creating new variations, Soong clones the old module and
// thus some way is needed to change it state whereas Bazel creates each
// configuration of a given configured target anew.
-type TransitionMutator interface {
+type TransitionMutator[T blueprint.TransitionInfo] interface {
// Split returns the set of variations that should be created for a module no
// matter who depends on it. Used when Make depends on a particular variation
// or when the module knows its variations just based on information given to
// it in the Blueprint file. This method should not mutate the module it is
// called on.
- Split(ctx BaseModuleContext) []string
+ Split(ctx BaseModuleContext) []T
// OutgoingTransition is called on a module to determine which variation it wants
// from its direct dependencies. The dependency itself can override this decision.
// This method should not mutate the module itself.
- OutgoingTransition(ctx OutgoingTransitionContext, sourceVariation string) string
+ OutgoingTransition(ctx OutgoingTransitionContext, sourceTransitionInfo T) T
// IncomingTransition is called on a module to determine which variation it should
// be in based on the variation modules that depend on it want. This gives the module
// a final say about its own variations. This method should not mutate the module
// itself.
- IncomingTransition(ctx IncomingTransitionContext, incomingVariation string) string
+ IncomingTransition(ctx IncomingTransitionContext, incomingTransitionInfo T) T
// Mutate is called after a module was split into multiple variations on each variation.
// It should not split the module any further but adding new dependencies is
// fine. Unlike all the other methods on TransitionMutator, this method is
// allowed to mutate the module.
+ Mutate(ctx BottomUpMutatorContext, transitionInfo T)
+
+ // TransitionInfoFromVariation is called when adding dependencies with an explicit variation after the
+ // TransitionMutator has already run. It takes a variation name and returns a TransitionInfo for that
+ // variation. It may not be possible for some TransitionMutators to generate an appropriate TransitionInfo
+ // if the variation does not contain all the information from the TransitionInfo, in which case the
+ // TransitionMutator can panic in TransitionInfoFromVariation, and adding dependencies with explicit variations
+ // for this TransitionMutator is not supported.
+ TransitionInfoFromVariation(variation string) T
+}
+
+// androidTransitionMutator is a copy of blueprint.TransitionMutator with the context argument types changed
+// from blueprint.BaseModuleContext to BaseModuleContext, etc.
+type androidTransitionMutator interface {
+ Split(ctx BaseModuleContext) []blueprint.TransitionInfo
+ OutgoingTransition(ctx OutgoingTransitionContext, sourceTransitionInfo blueprint.TransitionInfo) blueprint.TransitionInfo
+ IncomingTransition(ctx IncomingTransitionContext, incomingTransitionInfo blueprint.TransitionInfo) blueprint.TransitionInfo
+ Mutate(ctx BottomUpMutatorContext, transitionInfo blueprint.TransitionInfo)
+ TransitionInfoFromVariation(variation string) blueprint.TransitionInfo
+}
+
+// VariationTransitionMutator is a simpler version of androidTransitionMutator that passes variation strings instead
+// of a blueprint.TransitionInfo object.
+type VariationTransitionMutator interface {
+ Split(ctx BaseModuleContext) []string
+ OutgoingTransition(ctx OutgoingTransitionContext, sourceVariation string) string
+ IncomingTransition(ctx IncomingTransitionContext, incomingVariation string) string
Mutate(ctx BottomUpMutatorContext, variation string)
}
@@ -108,6 +135,14 @@
// is being computed
Module() Module
+ // ModuleName returns the name of the module. This is generally the value that was returned by Module.Name() when
+ // the module was created, but may have been modified by calls to BottomUpMutatorContext.Rename.
+ ModuleName() string
+
+ // DepTag() Returns the dependency tag through which this dependency is
+ // reached
+ DepTag() blueprint.DependencyTag
+
// Config returns the configuration for the build.
Config() Config
@@ -128,6 +163,10 @@
// is being computed
Module() Module
+ // ModuleName returns the name of the module. This is generally the value that was returned by Module.Name() when
+ // the module was created, but may have been modified by calls to BottomUpMutatorContext.Rename.
+ ModuleName() string
+
// DepTag() Returns the dependency tag through which this dependency is
// reached
DepTag() blueprint.DependencyTag
@@ -138,68 +177,166 @@
DeviceConfig() DeviceConfig
}
-type androidTransitionMutator struct {
+// androidTransitionMutatorAdapter wraps an androidTransitionMutator to convert it to a blueprint.TransitionInfo
+// by converting the blueprint.*Context objects into android.*Context objects.
+type androidTransitionMutatorAdapter struct {
finalPhase bool
- mutator TransitionMutator
+ mutator androidTransitionMutator
name string
}
-func (a *androidTransitionMutator) Split(ctx blueprint.BaseModuleContext) []string {
+func (a *androidTransitionMutatorAdapter) Split(ctx blueprint.BaseModuleContext) []blueprint.TransitionInfo {
if a.finalPhase {
panic("TransitionMutator not allowed in FinalDepsMutators")
}
- if m, ok := ctx.Module().(Module); ok {
- moduleContext := m.base().baseModuleContextFactory(ctx)
- return a.mutator.Split(&moduleContext)
- } else {
- return []string{""}
- }
+ m := ctx.Module().(Module)
+ moduleContext := m.base().baseModuleContextFactory(ctx)
+ return a.mutator.Split(&moduleContext)
}
-func (a *androidTransitionMutator) OutgoingTransition(bpctx blueprint.OutgoingTransitionContext, sourceVariation string) string {
- if m, ok := bpctx.Module().(Module); ok {
- ctx := outgoingTransitionContextPool.Get().(*outgoingTransitionContextImpl)
- defer outgoingTransitionContextPool.Put(ctx)
- *ctx = outgoingTransitionContextImpl{
- archModuleContext: m.base().archModuleContextFactory(bpctx),
- bp: bpctx,
- }
- return a.mutator.OutgoingTransition(ctx, sourceVariation)
- } else {
- return ""
+func (a *androidTransitionMutatorAdapter) OutgoingTransition(bpctx blueprint.OutgoingTransitionContext,
+ sourceTransitionInfo blueprint.TransitionInfo) blueprint.TransitionInfo {
+ m := bpctx.Module().(Module)
+ ctx := outgoingTransitionContextPool.Get()
+ defer outgoingTransitionContextPool.Put(ctx)
+ *ctx = outgoingTransitionContextImpl{
+ archModuleContext: m.base().archModuleContextFactory(bpctx),
+ bp: bpctx,
}
+ return a.mutator.OutgoingTransition(ctx, sourceTransitionInfo)
}
-func (a *androidTransitionMutator) IncomingTransition(bpctx blueprint.IncomingTransitionContext, incomingVariation string) string {
- if m, ok := bpctx.Module().(Module); ok {
- ctx := incomingTransitionContextPool.Get().(*incomingTransitionContextImpl)
- defer incomingTransitionContextPool.Put(ctx)
- *ctx = incomingTransitionContextImpl{
- archModuleContext: m.base().archModuleContextFactory(bpctx),
- bp: bpctx,
- }
- return a.mutator.IncomingTransition(ctx, incomingVariation)
- } else {
- return ""
+func (a *androidTransitionMutatorAdapter) IncomingTransition(bpctx blueprint.IncomingTransitionContext,
+ incomingTransitionInfo blueprint.TransitionInfo) blueprint.TransitionInfo {
+ m := bpctx.Module().(Module)
+ ctx := incomingTransitionContextPool.Get()
+ defer incomingTransitionContextPool.Put(ctx)
+ *ctx = incomingTransitionContextImpl{
+ archModuleContext: m.base().archModuleContextFactory(bpctx),
+ bp: bpctx,
}
+ return a.mutator.IncomingTransition(ctx, incomingTransitionInfo)
}
-func (a *androidTransitionMutator) Mutate(ctx blueprint.BottomUpMutatorContext, variation string) {
- if am, ok := ctx.Module().(Module); ok {
- if variation != "" {
- // TODO: this should really be checking whether the TransitionMutator affected this module, not
- // the empty variant, but TransitionMutator has no concept of skipping a module.
- base := am.base()
- base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, a.name)
- base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variation)
- }
-
- mctx := bottomUpMutatorContextFactory(ctx, am, a.finalPhase)
- defer bottomUpMutatorContextPool.Put(mctx)
- a.mutator.Mutate(mctx, variation)
+func (a *androidTransitionMutatorAdapter) Mutate(ctx blueprint.BottomUpMutatorContext, transitionInfo blueprint.TransitionInfo) {
+ am := ctx.Module().(Module)
+ variation := transitionInfo.Variation()
+ if variation != "" {
+ // TODO: this should really be checking whether the TransitionMutator affected this module, not
+ // the empty variant, but TransitionMutator has no concept of skipping a module.
+ base := am.base()
+ base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, a.name)
+ base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variation)
}
+
+ mctx := bottomUpMutatorContextFactory(ctx, am, a.finalPhase)
+ defer bottomUpMutatorContextPool.Put(mctx)
+ a.mutator.Mutate(mctx, transitionInfo)
}
+func (a *androidTransitionMutatorAdapter) TransitionInfoFromVariation(variation string) blueprint.TransitionInfo {
+ return a.mutator.TransitionInfoFromVariation(variation)
+}
+
+// variationTransitionMutatorAdapter wraps a VariationTransitionMutator to convert it to an androidTransitionMutator
+// by wrapping the string info object used by VariationTransitionMutator with variationTransitionInfo to convert it into
+// blueprint.TransitionInfo.
+type variationTransitionMutatorAdapter struct {
+ m VariationTransitionMutator
+}
+
+func (v variationTransitionMutatorAdapter) Split(ctx BaseModuleContext) []blueprint.TransitionInfo {
+ variations := v.m.Split(ctx)
+ transitionInfos := make([]blueprint.TransitionInfo, 0, len(variations))
+ for _, variation := range variations {
+ transitionInfos = append(transitionInfos, variationTransitionInfo{variation})
+ }
+ return transitionInfos
+}
+
+func (v variationTransitionMutatorAdapter) OutgoingTransition(ctx OutgoingTransitionContext,
+ sourceTransitionInfo blueprint.TransitionInfo) blueprint.TransitionInfo {
+
+ sourceVariationTransitionInfo, _ := sourceTransitionInfo.(variationTransitionInfo)
+ outgoingVariation := v.m.OutgoingTransition(ctx, sourceVariationTransitionInfo.variation)
+ return variationTransitionInfo{outgoingVariation}
+}
+
+func (v variationTransitionMutatorAdapter) IncomingTransition(ctx IncomingTransitionContext,
+ incomingTransitionInfo blueprint.TransitionInfo) blueprint.TransitionInfo {
+
+ incomingVariationTransitionInfo, _ := incomingTransitionInfo.(variationTransitionInfo)
+ variation := v.m.IncomingTransition(ctx, incomingVariationTransitionInfo.variation)
+ return variationTransitionInfo{variation}
+}
+
+func (v variationTransitionMutatorAdapter) Mutate(ctx BottomUpMutatorContext, transitionInfo blueprint.TransitionInfo) {
+ variationTransitionInfo, _ := transitionInfo.(variationTransitionInfo)
+ v.m.Mutate(ctx, variationTransitionInfo.variation)
+}
+
+func (v variationTransitionMutatorAdapter) TransitionInfoFromVariation(variation string) blueprint.TransitionInfo {
+ return variationTransitionInfo{variation}
+}
+
+// variationTransitionInfo is a blueprint.TransitionInfo that contains a single variation string.
+type variationTransitionInfo struct {
+ variation string
+}
+
+func (v variationTransitionInfo) Variation() string {
+ return v.variation
+}
+
+// genericTransitionMutatorAdapter wraps a TransitionMutator to convert it to an androidTransitionMutator
+type genericTransitionMutatorAdapter[T blueprint.TransitionInfo] struct {
+ m TransitionMutator[T]
+}
+
+// NewGenericTransitionMutatorAdapter is used to convert a generic TransitionMutator[T] into an androidTransitionMutator
+// that can be passed to RegisterMutatorsContext.InfoBasedTransition.
+func NewGenericTransitionMutatorAdapter[T blueprint.TransitionInfo](m TransitionMutator[T]) androidTransitionMutator {
+ return &genericTransitionMutatorAdapter[T]{m}
+}
+
+func (g *genericTransitionMutatorAdapter[T]) convertTransitionInfoToT(transitionInfo blueprint.TransitionInfo) T {
+ if transitionInfo == nil {
+ var zero T
+ return zero
+ }
+ return transitionInfo.(T)
+}
+
+func (g *genericTransitionMutatorAdapter[T]) Split(ctx BaseModuleContext) []blueprint.TransitionInfo {
+ transitionInfos := g.m.Split(ctx)
+ bpTransitionInfos := make([]blueprint.TransitionInfo, 0, len(transitionInfos))
+ for _, transitionInfo := range transitionInfos {
+ bpTransitionInfos = append(bpTransitionInfos, transitionInfo)
+ }
+ return bpTransitionInfos
+}
+
+func (g *genericTransitionMutatorAdapter[T]) OutgoingTransition(ctx OutgoingTransitionContext, sourceTransitionInfo blueprint.TransitionInfo) blueprint.TransitionInfo {
+ sourceTransitionInfoT := g.convertTransitionInfoToT(sourceTransitionInfo)
+ return g.m.OutgoingTransition(ctx, sourceTransitionInfoT)
+}
+
+func (g *genericTransitionMutatorAdapter[T]) IncomingTransition(ctx IncomingTransitionContext, incomingTransitionInfo blueprint.TransitionInfo) blueprint.TransitionInfo {
+ incomingTransitionInfoT := g.convertTransitionInfoToT(incomingTransitionInfo)
+ return g.m.IncomingTransition(ctx, incomingTransitionInfoT)
+}
+
+func (g *genericTransitionMutatorAdapter[T]) Mutate(ctx BottomUpMutatorContext, transitionInfo blueprint.TransitionInfo) {
+ transitionInfoT := g.convertTransitionInfoToT(transitionInfo)
+ g.m.Mutate(ctx, transitionInfoT)
+}
+
+func (g *genericTransitionMutatorAdapter[T]) TransitionInfoFromVariation(variation string) blueprint.TransitionInfo {
+ return g.m.TransitionInfoFromVariation(variation)
+}
+
+// incomingTransitionContextImpl wraps a blueprint.IncomingTransitionContext to convert it to an
+// IncomingTransitionContext.
type incomingTransitionContextImpl struct {
archModuleContext
bp blueprint.IncomingTransitionContext
@@ -209,6 +346,14 @@
return c.bp.Module().(Module)
}
+func (c *incomingTransitionContextImpl) ModuleName() string {
+ return c.bp.ModuleName()
+}
+
+func (c *incomingTransitionContextImpl) DepTag() blueprint.DependencyTag {
+ return c.bp.DepTag()
+}
+
func (c *incomingTransitionContextImpl) Config() Config {
return c.bp.Config().(Config)
}
@@ -233,6 +378,8 @@
c.bp.PropertyErrorf(property, fmt, args)
}
+// outgoingTransitionContextImpl wraps a blueprint.OutgoingTransitionContext to convert it to an
+// OutgoingTransitionContext.
type outgoingTransitionContextImpl struct {
archModuleContext
bp blueprint.OutgoingTransitionContext
@@ -242,6 +389,10 @@
return c.bp.Module().(Module)
}
+func (c *outgoingTransitionContextImpl) ModuleName() string {
+ return c.bp.ModuleName()
+}
+
func (c *outgoingTransitionContextImpl) DepTag() blueprint.DependencyTag {
return c.bp.DepTag()
}
diff --git a/android/util.go b/android/util.go
index 30d8ec6..7b305b5 100644
--- a/android/util.go
+++ b/android/util.go
@@ -102,13 +102,6 @@
return buf.String()
}
-// SortedStringKeys returns the keys of the given map in the ascending order.
-//
-// Deprecated: Use SortedKeys instead.
-func SortedStringKeys[V any](m map[string]V) []string {
- return SortedKeys(m)
-}
-
// SortedKeys returns the keys of the given map in the ascending order.
func SortedKeys[T cmp.Ordered, V any](m map[T]V) []T {
if len(m) == 0 {
@@ -213,21 +206,23 @@
}
// ListSetDifference checks if the two lists contain the same elements. It returns
-// a boolean which is true if there is a difference, and then returns lists of elements
+// a boolean which is true if there is a difference, and then returns lists of unique elements
// that are in l1 but not l2, and l2 but not l1.
func ListSetDifference[T comparable](l1, l2 []T) (bool, []T, []T) {
listsDiffer := false
+ l1 = firstUnique(l1)
+ l2 = firstUnique(l2)
diff1 := []T{}
diff2 := []T{}
m1 := setFromList(l1)
m2 := setFromList(l2)
- for t := range m1 {
+ for _, t := range l1 {
if _, ok := m2[t]; !ok {
diff1 = append(diff1, t)
listsDiffer = true
}
}
- for t := range m2 {
+ for _, t := range l2 {
if _, ok := m1[t]; !ok {
diff2 = append(diff2, t)
listsDiffer = true
@@ -238,8 +233,13 @@
// Returns true if the two lists have common elements.
func HasIntersection[T comparable](l1, l2 []T) bool {
- _, a, b := ListSetDifference(l1, l2)
- return len(a)+len(b) < len(setFromList(l1))+len(setFromList(l2))
+ m1 := setFromList(l1)
+ for _, x := range l2 {
+ if _, ok := m1[x]; ok {
+ return true
+ }
+ }
+ return false
}
// Returns true if the given string s is prefixed with any string in the given prefix list.
diff --git a/android/variable.go b/android/variable.go
index 4b61827..81999f3 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -543,8 +543,6 @@
PartitionVarsForSoongMigrationOnlyDoNotUse PartitionVariables
- ExtraAllowedDepsTxt *string `json:",omitempty"`
-
AdbKeys *string `json:",omitempty"`
DeviceMatrixFile []string `json:",omitempty"`
@@ -553,10 +551,13 @@
SystemExtManifestFiles []string `json:",omitempty"`
DeviceManifestFiles []string `json:",omitempty"`
OdmManifestFiles []string `json:",omitempty"`
+
+ UseSoongNoticeXML *bool `json:",omitempty"`
}
type PartitionQualifiedVariablesType struct {
BuildingImage bool `json:",omitempty"`
+ PrebuiltImage bool `json:",omitempty"`
BoardErofsCompressor string `json:",omitempty"`
BoardErofsCompressHints string `json:",omitempty"`
BoardErofsPclusterSize string `json:",omitempty"`
@@ -625,6 +626,8 @@
VendorDlkmSecurityPatch string `json:",omitempty"`
OdmDlkmSecurityPatch string `json:",omitempty"`
+ BuildingSystemOtherImage bool `json:",omitempty"`
+
// Boot image stuff
BuildingRamdiskImage bool `json:",omitempty"`
ProductBuildBootImage bool `json:",omitempty"`
@@ -656,7 +659,14 @@
BoardSuperPartitionGroups map[string]BoardSuperPartitionGroupProps `json:",omitempty"`
ProductVirtualAbOta bool `json:",omitempty"`
ProductVirtualAbOtaRetrofit bool `json:",omitempty"`
+ ProductVirtualAbCompression bool `json:",omitempty"`
+ ProductVirtualAbCompressionMethod string `json:",omitempty"`
+ ProductVirtualAbCompressionFactor string `json:",omitempty"`
+ ProductVirtualAbCowVersion string `json:",omitempty"`
AbOtaUpdater bool `json:",omitempty"`
+ AbOtaPartitions []string `json:",omitempty"`
+ AbOtaKeys []string `json:",omitempty"`
+ AbOtaPostInstallConfig []string `json:",omitempty"`
// Avb (android verified boot) stuff
BoardAvbEnable bool `json:",omitempty"`
@@ -699,6 +709,12 @@
PrivateRecoveryUiProperties map[string]string `json:",omitempty"`
PrebuiltBootloader string `json:",omitempty"`
+
+ ProductFsCasefold string `json:",omitempty"`
+ ProductQuotaProjid string `json:",omitempty"`
+ ProductFsCompression string `json:",omitempty"`
+
+ ReleaseToolsExtensionDir string `json:",omitempty"`
}
func boolPtr(v bool) *bool {
diff --git a/android/variable_test.go b/android/variable_test.go
index 73dc052..1d928f2 100644
--- a/android/variable_test.go
+++ b/android/variable_test.go
@@ -299,7 +299,7 @@
FixtureWithRootAndroidBp(bp),
).RunTest(t)
- foo := result.ModuleForTests("foo", "").Module().(*productVariablesDefaultsTestModule)
+ foo := result.ModuleForTests(t, "foo", "").Module().(*productVariablesDefaultsTestModule)
want := []string{"defaults", "module", "product_variable_defaults", "product_variable_module"}
AssertDeepEquals(t, "foo", want, foo.properties.Foo)
@@ -360,7 +360,7 @@
FixtureWithRootAndroidBp(bp),
).RunTest(t)
- foo := result.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*productVariablesDefaultsTestModule)
+ foo := result.ModuleForTests(t, "foo", "android_arm64_armv8-a").Module().(*productVariablesDefaultsTestModule)
want := []string{"module", "arm64"}
AssertDeepEquals(t, "foo", want, foo.properties.Foo)
diff --git a/android/vendor_api_levels.go b/android/vendor_api_levels.go
index 4d364fd..d32bc56 100644
--- a/android/vendor_api_levels.go
+++ b/android/vendor_api_levels.go
@@ -27,6 +27,8 @@
sdkVersion = 35
case 202504:
sdkVersion = 36
+ case 202604:
+ sdkVersion = 37
default:
ok = false
}
diff --git a/android/vintf_data.go b/android/vintf_data.go
index 401f4d2..2909817 100644
--- a/android/vintf_data.go
+++ b/android/vintf_data.go
@@ -140,6 +140,7 @@
// Process vintf fragment source file with assemble_vintf tool
builder.Command().
+ Implicits(inputPaths).
Flags(assembleVintfEnvs).
BuiltTool("assemble_vintf").
FlagWithArg("-i ", strings.Join(inputPaths.Strings(), ":")).
diff --git a/android/vintf_fragment.go b/android/vintf_fragment.go
index a3343fd..4a29fee 100644
--- a/android/vintf_fragment.go
+++ b/android/vintf_fragment.go
@@ -14,13 +14,16 @@
package android
+import "github.com/google/blueprint"
+
type vintfFragmentProperties struct {
// Vintf fragment XML file.
Src string `android:"path"`
}
-type vintfFragmentModule struct {
+type VintfFragmentModule struct {
ModuleBase
+ ApexModuleBase
properties vintfFragmentProperties
@@ -36,11 +39,17 @@
ctx.RegisterModuleType("vintf_fragment", vintfLibraryFactory)
}
+type VintfFragmentInfo struct {
+ OutputFile Path
+}
+
+var VintfFragmentInfoProvider = blueprint.NewProvider[VintfFragmentInfo]()
+
// vintf_fragment module processes vintf fragment file and installs under etc/vintf/manifest.
// Vintf fragment files formerly listed in vintf_fragment property would be transformed into
// this module type.
func vintfLibraryFactory() Module {
- m := &vintfFragmentModule{}
+ m := &VintfFragmentModule{}
m.AddProperties(
&m.properties,
)
@@ -49,7 +58,7 @@
return m
}
-func (m *vintfFragmentModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+func (m *VintfFragmentModule) GenerateAndroidBuildActions(ctx ModuleContext) {
builder := NewRuleBuilder(pctx, ctx)
srcVintfFragment := PathForModuleSrc(ctx, m.properties.Src)
processedVintfFragment := PathForModuleOut(ctx, srcVintfFragment.Base())
@@ -67,10 +76,18 @@
m.outputFilePath = processedVintfFragment
ctx.InstallFile(m.installDirPath, processedVintfFragment.Base(), processedVintfFragment)
+
+ SetProvider(ctx, VintfFragmentInfoProvider, VintfFragmentInfo{
+ OutputFile: m.OutputFile(),
+ })
+}
+
+func (m *VintfFragmentModule) OutputFile() Path {
+ return m.outputFilePath
}
// Make this module visible to AndroidMK so it can be referenced from modules defined from Android.mk files
-func (m *vintfFragmentModule) AndroidMkEntries() []AndroidMkEntries {
+func (m *VintfFragmentModule) AndroidMkEntries() []AndroidMkEntries {
return []AndroidMkEntries{{
Class: "ETC",
OutputFile: OptionalPathForPath(m.outputFilePath),
@@ -82,3 +99,10 @@
},
}}
}
+
+var _ ApexModule = (*VintfFragmentModule)(nil)
+
+// Implements android.ApexModule
+func (m *VintfFragmentModule) MinSdkVersionSupported(ctx BaseModuleContext) ApiLevel {
+ return MinApiLevel
+}
diff --git a/android/vintf_fragment_test.go b/android/vintf_fragment_test.go
index cb038f5..7f0078c 100644
--- a/android/vintf_fragment_test.go
+++ b/android/vintf_fragment_test.go
@@ -29,7 +29,7 @@
testResult := PrepareForTestWithAndroidBuildComponents.RunTestWithBp(t, bp)
- vintfFragmentBuild := testResult.TestContext.ModuleForTests("test_vintf_fragment", "android_common").Rule("assemble_vintf")
+ vintfFragmentBuild := testResult.TestContext.ModuleForTests(t, "test_vintf_fragment", "android_common").Rule("assemble_vintf")
if !strings.Contains(vintfFragmentBuild.RuleParams.Command, "assemble_vintf") {
t.Error("Vintf_manifest build command does not process with assemble_vintf : " + vintfFragmentBuild.RuleParams.Command)
}
diff --git a/android/visibility.go b/android/visibility.go
index cee465e..4837c7d 100644
--- a/android/visibility.go
+++ b/android/visibility.go
@@ -529,7 +529,7 @@
rule := effectiveVisibilityRules(ctx.Config(), depQualified)
if !rule.matches(qualified) {
- ctx.ModuleErrorf("depends on %s which is not visible to this module\nYou may need to add %q to its visibility", depQualified, "//"+ctx.ModuleDir())
+ ctx.ModuleErrorf("depends on %s which is not visible to this module\nYou may need to add %q to its visibility, %#v", depQualified, "//"+ctx.ModuleDir(), ctx.OtherModuleDependencyTag(dep))
}
})
}
diff --git a/android_sdk/sdk_repo_host_test.go b/android_sdk/sdk_repo_host_test.go
index 0688921..ce84204 100644
--- a/android_sdk/sdk_repo_host_test.go
+++ b/android_sdk/sdk_repo_host_test.go
@@ -44,7 +44,7 @@
`)
// produces "sdk-repo-{OS}-platform-tools.zip"
- result.ModuleForTests("platform-tools", "linux_glibc_common").Output("sdk-repo-linux-platform-tools.zip")
+ result.ModuleForTests(t, "platform-tools", "linux_glibc_common").Output("sdk-repo-linux-platform-tools.zip")
}
func TestRemapPackageSpecs(t *testing.T) {
diff --git a/androidmk/androidmk/android.go b/androidmk/androidmk/android.go
index 570f36c..6485cc5 100644
--- a/androidmk/androidmk/android.go
+++ b/androidmk/androidmk/android.go
@@ -103,25 +103,26 @@
func init() {
addStandardProperties(bpparser.StringType,
map[string]string{
- "LOCAL_MODULE": "name",
- "LOCAL_CXX_STL": "stl",
- "LOCAL_MULTILIB": "compile_multilib",
- "LOCAL_ARM_MODE_HACK": "instruction_set",
- "LOCAL_SDK_VERSION": "sdk_version",
- "LOCAL_MIN_SDK_VERSION": "min_sdk_version",
- "LOCAL_TARGET_SDK_VERSION": "target_sdk_version",
- "LOCAL_NDK_STL_VARIANT": "stl",
- "LOCAL_JAR_MANIFEST": "manifest",
- "LOCAL_CERTIFICATE": "certificate",
- "LOCAL_CERTIFICATE_LINEAGE": "lineage",
- "LOCAL_PACKAGE_NAME": "name",
- "LOCAL_MODULE_RELATIVE_PATH": "relative_install_path",
- "LOCAL_PROTOC_OPTIMIZE_TYPE": "proto.type",
- "LOCAL_MODULE_OWNER": "owner",
- "LOCAL_RENDERSCRIPT_TARGET_API": "renderscript.target_api",
- "LOCAL_JAVA_LANGUAGE_VERSION": "java_version",
- "LOCAL_INSTRUMENTATION_FOR": "instrumentation_for",
- "LOCAL_MANIFEST_FILE": "manifest",
+ "LOCAL_MODULE": "name",
+ "LOCAL_CXX_STL": "stl",
+ "LOCAL_MULTILIB": "compile_multilib",
+ "LOCAL_ARM_MODE_HACK": "instruction_set",
+ "LOCAL_SDK_VERSION": "sdk_version",
+ "LOCAL_MIN_SDK_VERSION": "min_sdk_version",
+ "LOCAL_ROTATION_MIN_SDK_VERSION": "rotationMinSdkVersion",
+ "LOCAL_TARGET_SDK_VERSION": "target_sdk_version",
+ "LOCAL_NDK_STL_VARIANT": "stl",
+ "LOCAL_JAR_MANIFEST": "manifest",
+ "LOCAL_CERTIFICATE": "certificate",
+ "LOCAL_CERTIFICATE_LINEAGE": "lineage",
+ "LOCAL_PACKAGE_NAME": "name",
+ "LOCAL_MODULE_RELATIVE_PATH": "relative_install_path",
+ "LOCAL_PROTOC_OPTIMIZE_TYPE": "proto.type",
+ "LOCAL_MODULE_OWNER": "owner",
+ "LOCAL_RENDERSCRIPT_TARGET_API": "renderscript.target_api",
+ "LOCAL_JAVA_LANGUAGE_VERSION": "java_version",
+ "LOCAL_INSTRUMENTATION_FOR": "instrumentation_for",
+ "LOCAL_MANIFEST_FILE": "manifest",
"LOCAL_DEX_PREOPT_PROFILE_CLASS_LISTING": "dex_preopt.profile",
"LOCAL_TEST_CONFIG": "test_config",
diff --git a/apex/androidmk.go b/apex/androidmk.go
index ec5ca15..3a81ee4 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -226,11 +226,6 @@
required = append(required, a.required...)
targetRequired = append(targetRequired, a.TargetRequiredModuleNames()...)
hostRequired = append(hostRequired, a.HostRequiredModuleNames()...)
- for _, fi := range a.filesInfo {
- required = append(required, fi.requiredModuleNames...)
- targetRequired = append(targetRequired, fi.targetRequiredModuleNames...)
- hostRequired = append(hostRequired, fi.hostRequiredModuleNames...)
- }
android.AndroidMkEmitAssignList(w, "LOCAL_REQUIRED_MODULES", moduleNames, a.makeModulesToInstall, required)
android.AndroidMkEmitAssignList(w, "LOCAL_TARGET_REQUIRED_MODULES", targetRequired)
android.AndroidMkEmitAssignList(w, "LOCAL_HOST_REQUIRED_MODULES", hostRequired)
@@ -261,6 +256,7 @@
fmt.Fprintln(w, "LOCAL_SOONG_INSTALLED_MODULE :=", a.installedFile.String())
fmt.Fprintln(w, "LOCAL_SOONG_INSTALL_PAIRS :=", a.outputFile.String()+":"+a.installedFile.String())
fmt.Fprintln(w, "LOCAL_SOONG_INSTALL_SYMLINKS := ", strings.Join(a.compatSymlinks.Strings(), " "))
+ fmt.Fprintln(w, "LOCAL_SOONG_INSTALL_PAIRS +=", a.extraInstalledPairs.String())
}
fmt.Fprintln(w, "LOCAL_APEX_KEY_PATH := ", a.apexKeysPath.String())
diff --git a/apex/apex.go b/apex/apex.go
index 3d8baa6..6e4685b 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -61,12 +61,11 @@
}
func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
- ctx.TopDown("apex_info", apexInfoMutator)
ctx.BottomUp("apex_unique", apexUniqueVariationsMutator)
// Run mark_platform_availability before the apexMutator as the apexMutator needs to know whether
// it should create a platform variant.
ctx.BottomUp("mark_platform_availability", markPlatformAvailability)
- ctx.Transition("apex", &apexTransitionMutator{})
+ ctx.InfoBasedTransition("apex", android.NewGenericTransitionMutatorAdapter(&apexTransitionMutator{}))
}
type apexBundleProperties struct {
@@ -411,6 +410,30 @@
Min_sdk_version *string
}
+// installPair stores a path to a built object and its install location. It is used for holding
+// the installation location of the dexpreopt artifacts for system server jars in apexes that need
+// to be installed when the apex is installed.
+type installPair struct {
+ from android.Path
+ to android.InstallPath
+}
+
+type installPairs []installPair
+
+// String converts a list of installPair structs to the form accepted by LOCAL_SOONG_INSTALL_PAIRS.
+func (p installPairs) String() string {
+ sb := &strings.Builder{}
+ for i, pair := range p {
+ if i != 0 {
+ sb.WriteByte(' ')
+ }
+ sb.WriteString(pair.from.String())
+ sb.WriteByte(':')
+ sb.WriteString(pair.to.String())
+ }
+ return sb.String()
+}
+
type apexBundle struct {
// Inherited structs
android.ModuleBase
@@ -492,6 +515,12 @@
// Path where this APEX was installed.
installedFile android.InstallPath
+ // Extra files that are installed alongside this APEX.
+ extraInstalledFiles android.InstallPaths
+
+ // The source and install locations for extraInstalledFiles for use in LOCAL_SOONG_INSTALL_PAIRS.
+ extraInstalledPairs installPairs
+
// fragment for this apex for apexkeys.txt
apexKeysPath android.WritablePath
@@ -566,13 +595,15 @@
// Info for Android.mk Module name of `module` in AndroidMk. Note the generated AndroidMk
// module for apexFile is named something like <AndroidMk module name>.<apex name>[<apex
// suffix>]
- androidMkModuleName string // becomes LOCAL_MODULE
- class apexFileClass // becomes LOCAL_MODULE_CLASS
- moduleDir string // becomes LOCAL_PATH
- requiredModuleNames []string // becomes LOCAL_REQUIRED_MODULES
- targetRequiredModuleNames []string // becomes LOCAL_TARGET_REQUIRED_MODULES
- hostRequiredModuleNames []string // becomes LOCAL_HOST_REQUIRED_MODULES
- dataPaths []android.DataPath // becomes LOCAL_TEST_DATA
+ androidMkModuleName string // becomes LOCAL_MODULE
+ class apexFileClass // becomes LOCAL_MODULE_CLASS
+ moduleDir string // becomes LOCAL_PATH
+ dataPaths []android.DataPath // becomes LOCAL_TEST_DATA
+
+ // systemServerDexpreoptInstalls stores the list of dexpreopt artifacts for a system server jar.
+ systemServerDexpreoptInstalls []java.DexpreopterInstall
+ // systemServerDexJars stores the list of dexjars for a system server jar.
+ systemServerDexJars android.Paths
jacocoReportClassesFile android.Path // only for javalibs and apps
lintInfo *java.LintInfo // only for javalibs and apps
@@ -589,7 +620,8 @@
}
// TODO(jiyong): shorten the arglist using an option struct
-func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile {
+func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string,
+ installDir string, class apexFileClass, module android.Module) apexFile {
ret := apexFile{
builtFile: builtFile,
installDir: installDir,
@@ -732,6 +764,17 @@
shBinaryTag = &dependencyTag{name: "shBinary", payload: true}
)
+type fragmentInApexDepTag struct {
+ blueprint.BaseDependencyTag
+ android.FragmentInApexTag
+}
+
+func (fragmentInApexDepTag) ExcludeFromVisibilityEnforcement() {}
+
+// fragmentInApexTag is used by apex modules to depend on their fragments. Java bootclasspath
+// modules can traverse from the apex to the fragment using android.IsFragmentInApexTag.
+var fragmentInApexTag = fragmentInApexDepTag{}
+
// TODO(jiyong): shorten this function signature
func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ResolvedApexNativeDependencies, target android.Target, imageVariation string) {
binVariations := target.Variations()
@@ -880,6 +923,7 @@
commonVariation := ctx.Config().AndroidCommonTarget.Variations()
ctx.AddFarVariationDependencies(commonVariation, rroTag, a.properties.Rros...)
ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.properties.Bootclasspath_fragments.GetOrDefault(ctx, nil)...)
+ ctx.AddFarVariationDependencies(commonVariation, fragmentInApexTag, a.properties.Bootclasspath_fragments.GetOrDefault(ctx, nil)...)
ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.properties.Systemserverclasspath_fragments.GetOrDefault(ctx, nil)...)
ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.properties.Java_libs...)
ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
@@ -888,6 +932,12 @@
// Add a reverse dependency to all_apex_certs singleton module.
// all_apex_certs will use this dependency to collect the certificate of this apex.
ctx.AddReverseDependency(ctx.Module(), allApexCertsDepTag, "all_apex_certs")
+
+ // TODO: When all branches contain this singleton module, make this strict
+ // TODO: Add this dependency only for mainline prebuilts and not every prebuilt module
+ if ctx.OtherModuleExists("all_apex_contributions") {
+ ctx.AddDependency(ctx.Module(), android.AcDepTag, "all_apex_contributions")
+ }
}
type allApexCertsDependencyTag struct {
@@ -942,45 +992,29 @@
}
}
-var _ ApexInfoMutator = (*apexBundle)(nil)
+var _ ApexTransitionMutator = (*apexBundle)(nil)
func (a *apexBundle) ApexVariationName() string {
return a.properties.ApexVariationName
}
-// ApexInfoMutator is responsible for collecting modules that need to have apex variants. They are
-// identified by doing a graph walk starting from an apexBundle. Basically, all the (direct and
-// indirect) dependencies are collected. But a few types of modules that shouldn't be included in
-// the apexBundle (e.g. stub libraries) are not collected. Note that a single module can be depended
-// on by multiple apexBundles. In that case, the module is collected for all of the apexBundles.
-//
-// For each dependency between an apex and an ApexModule an ApexInfo object describing the apex
-// is passed to that module's BuildForApex(ApexInfo) method which collates them all in a list.
-// The apexMutator uses that list to create module variants for the apexes to which it belongs.
-// The relationship between module variants and apexes is not one-to-one as variants will be
-// shared between compatible apexes.
-func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
+type generateApexInfoContext interface {
+ android.MinSdkVersionFromValueContext
+ Module() android.Module
+ ModuleName() string
+}
+// generateApexInfo returns an android.ApexInfo configuration that should be used for dependencies of this apex.
+func (a *apexBundle) generateApexInfo(ctx generateApexInfoContext) android.ApexInfo {
// The VNDK APEX is special. For the APEX, the membership is described in a very different
// way. There is no dependency from the VNDK APEX to the VNDK libraries. Instead, VNDK
// libraries are self-identified by their vndk.enabled properties. There is no need to run
- // this mutator for the APEX as nothing will be collected. So, let's return fast.
+ // this mutator for the APEX as nothing will be collected so return an empty ApexInfo.
if a.vndkApex {
- return
+ return android.ApexInfo{}
}
- continueApexDepsWalk := func(child, parent android.Module) bool {
- am, ok := child.(android.ApexModule)
- if !ok || !am.CanHaveApexVariants() {
- return false
- }
-
- return android.IsDepInSameApex(mctx, parent, child)
- }
-
- android.SetProvider(mctx, android.ApexBundleInfoProvider, android.ApexBundleInfo{})
-
- minSdkVersion := a.minSdkVersion(mctx)
+ minSdkVersion := a.minSdkVersion(ctx)
// When min_sdk_version is not set, the apex is built against FutureApiLevel.
if minSdkVersion.IsNone() {
minSdkVersion = android.FutureApiLevel
@@ -989,56 +1023,45 @@
// This is the main part of this mutator. Mark the collected dependencies that they need to
// be built for this apexBundle.
- apexVariationName := mctx.ModuleName() // could be com.android.foo
- if overridable, ok := mctx.Module().(android.OverridableModule); ok && overridable.GetOverriddenBy() != "" {
+ apexVariationName := ctx.ModuleName() // could be com.android.foo
+ if a.GetOverriddenBy() != "" {
// use the overridden name com.mycompany.android.foo
- apexVariationName = overridable.GetOverriddenBy()
+ apexVariationName = a.GetOverriddenBy()
}
- a.properties.ApexVariationName = apexVariationName
apexInfo := android.ApexInfo{
ApexVariationName: apexVariationName,
MinSdkVersion: minSdkVersion,
Updatable: a.Updatable(),
UsePlatformApis: a.UsePlatformApis(),
- InApexVariants: []string{apexVariationName},
- BaseApexName: mctx.ModuleName(),
+ BaseApexName: ctx.ModuleName(),
ApexAvailableName: proptools.String(a.properties.Apex_available_name),
}
- mctx.WalkDeps(func(child, parent android.Module) bool {
- if !continueApexDepsWalk(child, parent) {
- return false
- }
- child.(android.ApexModule).BuildForApex(apexInfo) // leave a mark!
- return true
- })
+ return apexInfo
}
-type ApexInfoMutator interface {
- // ApexVariationName returns the name of the APEX variation to use in the apex
- // mutator etc. It is the same name as ApexInfo.ApexVariationName.
- ApexVariationName() string
-
- // ApexInfoMutator implementations must call BuildForApex(ApexInfo) on any modules that are
- // depended upon by an apex and which require an apex specific variant.
- ApexInfoMutator(android.TopDownMutatorContext)
+func (a *apexBundle) ApexTransitionMutatorSplit(ctx android.BaseModuleContext) []android.ApexInfo {
+ return []android.ApexInfo{a.generateApexInfo(ctx)}
}
-// apexInfoMutator delegates the work of identifying which modules need an ApexInfo and apex
-// specific variant to modules that support the ApexInfoMutator.
-// It also propagates updatable=true to apps of updatable apexes
-func apexInfoMutator(mctx android.TopDownMutatorContext) {
- if !mctx.Module().Enabled(mctx) {
- return
- }
+func (a *apexBundle) ApexTransitionMutatorOutgoing(ctx android.OutgoingTransitionContext, sourceInfo android.ApexInfo) android.ApexInfo {
+ return sourceInfo
+}
- if a, ok := mctx.Module().(ApexInfoMutator); ok {
- a.ApexInfoMutator(mctx)
- }
+func (a *apexBundle) ApexTransitionMutatorIncoming(ctx android.IncomingTransitionContext, outgoingInfo android.ApexInfo) android.ApexInfo {
+ return a.generateApexInfo(ctx)
+}
- if am, ok := mctx.Module().(android.ApexModule); ok {
- android.ApexInfoMutator(mctx, am)
- }
+func (a *apexBundle) ApexTransitionMutatorMutate(ctx android.BottomUpMutatorContext, info android.ApexInfo) {
+ android.SetProvider(ctx, android.ApexBundleInfoProvider, android.ApexBundleInfo{})
+ a.properties.ApexVariationName = info.ApexVariationName
+}
+
+type ApexTransitionMutator interface {
+ ApexTransitionMutatorSplit(ctx android.BaseModuleContext) []android.ApexInfo
+ ApexTransitionMutatorOutgoing(ctx android.OutgoingTransitionContext, sourceInfo android.ApexInfo) android.ApexInfo
+ ApexTransitionMutatorIncoming(ctx android.IncomingTransitionContext, outgoingInfo android.ApexInfo) android.ApexInfo
+ ApexTransitionMutatorMutate(ctx android.BottomUpMutatorContext, info android.ApexInfo)
}
// TODO: b/215736885 Whittle the denylist
@@ -1101,6 +1124,9 @@
}
if am, ok := mctx.Module().(android.ApexModule); ok {
android.UpdateUniqueApexVariationsForDeps(mctx, am)
+ android.SetProvider(mctx, android.DepInSameApexInfoProvider, android.DepInSameApexInfo{
+ Checker: am.GetDepInSameApexChecker(),
+ })
}
}
@@ -1153,53 +1179,35 @@
type apexTransitionMutator struct{}
-func (a *apexTransitionMutator) Split(ctx android.BaseModuleContext) []string {
- // apexBundle itself is mutated so that it and its dependencies have the same apex variant.
- if ai, ok := ctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) {
- if overridable, ok := ctx.Module().(android.OverridableModule); ok && overridable.GetOverriddenBy() != "" {
- return []string{overridable.GetOverriddenBy()}
- }
- return []string{ai.ApexVariationName()}
- } else if _, ok := ctx.Module().(*OverrideApex); ok {
- return []string{ctx.ModuleName()}
+func (a *apexTransitionMutator) Split(ctx android.BaseModuleContext) []android.ApexInfo {
+ if ai, ok := ctx.Module().(ApexTransitionMutator); ok {
+ return ai.ApexTransitionMutatorSplit(ctx)
}
- return []string{""}
+ return []android.ApexInfo{{}}
}
-func (a *apexTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
- return sourceVariation
-}
-
-func (a *apexTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
- if am, ok := ctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
- return android.IncomingApexTransition(ctx, incomingVariation)
- } else if ai, ok := ctx.Module().(ApexInfoMutator); ok {
- if overridable, ok := ctx.Module().(android.OverridableModule); ok && overridable.GetOverriddenBy() != "" {
- return overridable.GetOverriddenBy()
- }
- return ai.ApexVariationName()
- } else if _, ok := ctx.Module().(*OverrideApex); ok {
- return ctx.Module().Name()
+func (a *apexTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceInfo android.ApexInfo) android.ApexInfo {
+ if ai, ok := ctx.Module().(ApexTransitionMutator); ok {
+ return ai.ApexTransitionMutatorOutgoing(ctx, sourceInfo)
}
-
- return ""
+ return android.ApexInfo{}
}
-func (a *apexTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
- if am, ok := ctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
- android.MutateApexTransition(ctx, variation)
+func (a *apexTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, outgoingInfo android.ApexInfo) android.ApexInfo {
+ if ai, ok := ctx.Module().(ApexTransitionMutator); ok {
+ return ai.ApexTransitionMutatorIncoming(ctx, outgoingInfo)
+ }
+ return android.ApexInfo{}
+}
+
+func (a *apexTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, info android.ApexInfo) {
+ if ai, ok := ctx.Module().(ApexTransitionMutator); ok {
+ ai.ApexTransitionMutatorMutate(ctx, info)
}
}
-// apexModuleTypeRequiresVariant determines whether the module supplied requires an apex specific
-// variant.
-func apexModuleTypeRequiresVariant(module ApexInfoMutator) bool {
- if a, ok := module.(*apexBundle); ok {
- // TODO(jiyong): document the reason why the VNDK APEX is an exception here.
- return !a.vndkApex
- }
-
- return true
+func (a *apexTransitionMutator) TransitionInfoFromVariation(variation string) android.ApexInfo {
+ panic(fmt.Errorf("adding dependencies on explicit apex variations is not supported"))
}
const (
@@ -1215,21 +1223,6 @@
erofsFsType = "erofs"
)
-var _ android.DepIsInSameApex = (*apexBundle)(nil)
-
-// Implements android.DepInInSameApex
-func (a *apexBundle) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
- // direct deps of an APEX bundle are all part of the APEX bundle
- // TODO(jiyong): shouldn't we look into the payload field of the dependencyTag?
- return true
-}
-
-func (a *apexBundle) IncomingDepIsInSameApex(tag blueprint.DependencyTag) bool {
- // direct deps of an APEX bundle are all part of the APEX bundle
- // TODO(jiyong): shouldn't we look into the payload field of the dependencyTag?
- return true
-}
-
func (a *apexBundle) Exportable() bool {
return true
}
@@ -1379,24 +1372,29 @@
}
}
+func setDirInApexForNativeBridge(commonInfo *android.CommonModuleInfo, dir *string) {
+ if commonInfo.Target.NativeBridge == android.NativeBridgeEnabled {
+ *dir = filepath.Join(*dir, commonInfo.Target.NativeBridgeRelativePath)
+ }
+}
+
// apexFileFor<Type> functions below create an apexFile struct for a given Soong module. The
// returned apexFile saves information about the Soong module that will be used for creating the
// build rules.
-func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile {
+func apexFileForNativeLibrary(ctx android.BaseModuleContext, module android.Module,
+ commonInfo *android.CommonModuleInfo, ccMod *cc.LinkableInfo, handleSpecialLibs bool) apexFile {
// Decide the APEX-local directory by the multilib of the library In the future, we may
// query this to the module.
// TODO(jiyong): use the new PackagingSpec
var dirInApex string
- switch ccMod.Arch().ArchType.Multilib {
+ switch ccMod.Multilib {
case "lib32":
dirInApex = "lib"
case "lib64":
dirInApex = "lib64"
}
- if ccMod.Target().NativeBridge == android.NativeBridgeEnabled {
- dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath)
- }
- if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) {
+ setDirInApexForNativeBridge(commonInfo, &dirInApex)
+ if handleSpecialLibs && cc.InstallToBootstrap(commonInfo.BaseModuleName, ctx.Config()) {
// Special case for Bionic libs and other libs installed with them. This is to
// prevent those libs from being included in the search path
// /apex/com.android.runtime/${LIB}. This exclusion is required because those libs
@@ -1411,79 +1409,68 @@
// This needs to go after the runtime APEX handling because otherwise we would get
// weird paths like lib64/rel_install_path/bionic rather than
// lib64/bionic/rel_install_path.
- dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath())
+ dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath)
- fileToCopy := android.OutputFileForModule(ctx, ccMod, "")
- androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
- return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
+ fileToCopy := android.OutputFileForModule(ctx, module, "")
+ androidMkModuleName := commonInfo.BaseModuleName + ccMod.SubName
+ return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, module)
}
-func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile {
+func apexFileForExecutable(ctx android.BaseModuleContext, module android.Module,
+ commonInfo *android.CommonModuleInfo, ccInfo *cc.CcInfo) apexFile {
+ linkableInfo := android.OtherModuleProviderOrDefault(ctx, module, cc.LinkableInfoProvider)
dirInApex := "bin"
- if cc.Target().NativeBridge == android.NativeBridgeEnabled {
- dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
- }
- dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
- fileToCopy := android.OutputFileForModule(ctx, cc, "")
- androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
- af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
- af.symlinks = cc.Symlinks()
- af.dataPaths = cc.DataPaths()
+ setDirInApexForNativeBridge(commonInfo, &dirInApex)
+ dirInApex = filepath.Join(dirInApex, linkableInfo.RelativeInstallPath)
+ fileToCopy := android.OutputFileForModule(ctx, module, "")
+ androidMkModuleName := commonInfo.BaseModuleName + linkableInfo.SubName
+ af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, module)
+ af.symlinks = linkableInfo.Symlinks
+ af.dataPaths = ccInfo.DataPaths
return af
}
-func apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
+func apexFileForRustExecutable(ctx android.BaseModuleContext, module android.Module,
+ commonInfo *android.CommonModuleInfo) apexFile {
+ linkableInfo := android.OtherModuleProviderOrDefault(ctx, module, cc.LinkableInfoProvider)
dirInApex := "bin"
- if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
- dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
- }
- dirInApex = filepath.Join(dirInApex, rustm.RelativeInstallPath())
- fileToCopy := android.OutputFileForModule(ctx, rustm, "")
- androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
- af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
+ setDirInApexForNativeBridge(commonInfo, &dirInApex)
+ dirInApex = filepath.Join(dirInApex, linkableInfo.RelativeInstallPath)
+ fileToCopy := android.OutputFileForModule(ctx, module, "")
+ androidMkModuleName := commonInfo.BaseModuleName + linkableInfo.SubName
+ af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, module)
return af
}
-func apexFileForRustLibrary(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
- // Decide the APEX-local directory by the multilib of the library
- // In the future, we may query this to the module.
- var dirInApex string
- switch rustm.Arch().ArchType.Multilib {
- case "lib32":
- dirInApex = "lib"
- case "lib64":
- dirInApex = "lib64"
- }
- if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
- dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
- }
- dirInApex = filepath.Join(dirInApex, rustm.RelativeInstallPath())
- fileToCopy := android.OutputFileForModule(ctx, rustm, "")
- androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
- return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
-}
-
-func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
- dirInApex := filepath.Join("bin", sh.SubDir())
- if sh.Target().NativeBridge == android.NativeBridgeEnabled {
- dirInApex = filepath.Join(dirInApex, sh.Target().NativeBridgeRelativePath)
- }
- fileToCopy := sh.OutputFile()
- af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh)
- af.symlinks = sh.Symlinks()
+func apexFileForShBinary(ctx android.BaseModuleContext, module android.Module,
+ commonInfo *android.CommonModuleInfo, sh *sh.ShBinaryInfo) apexFile {
+ dirInApex := filepath.Join("bin", sh.SubDir)
+ setDirInApexForNativeBridge(commonInfo, &dirInApex)
+ fileToCopy := sh.OutputFile
+ af := newApexFile(ctx, fileToCopy, commonInfo.BaseModuleName, dirInApex, shBinary, module)
+ af.symlinks = sh.Symlinks
return af
}
-func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, outputFile android.Path) apexFile {
- dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir())
+func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, module android.Module,
+ prebuilt *prebuilt_etc.PrebuiltEtcInfo, outputFile android.Path) apexFile {
+ dirInApex := filepath.Join(prebuilt.BaseDir, prebuilt.SubDir)
makeModuleName := strings.ReplaceAll(filepath.Join(dirInApex, outputFile.Base()), "/", "_")
- return newApexFile(ctx, outputFile, makeModuleName, dirInApex, etc, prebuilt)
+ return newApexFile(ctx, outputFile, makeModuleName, dirInApex, etc, module)
}
-func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile {
- dirInApex := filepath.Join("etc", config.SubDir())
- fileToCopy := config.CompatConfig()
- return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config)
+func apexFileForCompatConfig(ctx android.BaseModuleContext, module android.Module,
+ config *java.PlatformCompatConfigInfo, depName string) apexFile {
+ dirInApex := filepath.Join("etc", config.SubDir)
+ fileToCopy := config.CompatConfig
+ return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, module)
+}
+
+func apexFileForVintfFragment(ctx android.BaseModuleContext, module android.Module,
+ commonInfo *android.CommonModuleInfo, vf *android.VintfFragmentInfo) apexFile {
+ dirInApex := filepath.Join("etc", "vintf")
+
+ return newApexFile(ctx, vf.OutputFile, commonInfo.BaseModuleName, dirInApex, etc, module)
}
// javaModule is an interface to handle all Java modules (java_library, dex_import, etc) in the same
@@ -1503,61 +1490,42 @@
var _ javaModule = (*java.SdkLibraryImport)(nil)
// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
-func apexFileForJavaModule(ctx android.ModuleContext, module javaModule) apexFile {
- return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath(ctx).PathOrNil())
+func apexFileForJavaModule(ctx android.ModuleContext, module android.Module, javaInfo *java.JavaInfo) apexFile {
+ return apexFileForJavaModuleWithFile(ctx, module, javaInfo, javaInfo.DexJarBuildPath.PathOrNil())
}
// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
-func apexFileForJavaModuleWithFile(ctx android.ModuleContext, module javaModule, dexImplementationJar android.Path) apexFile {
+func apexFileForJavaModuleWithFile(ctx android.ModuleContext, module android.Module,
+ javaInfo *java.JavaInfo, dexImplementationJar android.Path) apexFile {
dirInApex := "javalib"
- af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module)
- af.jacocoReportClassesFile = module.JacocoReportClassesFile()
+ commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey)
+ af := newApexFile(ctx, dexImplementationJar, commonInfo.BaseModuleName, dirInApex, javaSharedLib, module)
+ af.jacocoReportClassesFile = javaInfo.JacocoReportClassesFile
if lintInfo, ok := android.OtherModuleProvider(ctx, module, java.LintProvider); ok {
af.lintInfo = lintInfo
}
- af.customStem = module.Stem() + ".jar"
+ af.customStem = javaInfo.Stem + ".jar"
+ // Collect any system server dex jars and dexpreopt artifacts for installation alongside the apex.
// TODO: b/338641779 - Remove special casing of sdkLibrary once bcpf and sscpf depends
// on the implementation library
- if sdkLib, ok := module.(*java.SdkLibrary); ok {
- for _, install := range sdkLib.BuiltInstalledForApex() {
- af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
- }
- } else if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
- for _, install := range dexpreopter.DexpreoptBuiltInstalledForApex() {
- af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
- }
+ if javaInfo.DexpreopterInfo != nil {
+ af.systemServerDexpreoptInstalls = append(af.systemServerDexpreoptInstalls, javaInfo.DexpreopterInfo.ApexSystemServerDexpreoptInstalls...)
+ af.systemServerDexJars = append(af.systemServerDexJars, javaInfo.DexpreopterInfo.ApexSystemServerDexJars...)
}
return af
}
-func apexFileForJavaModuleProfile(ctx android.BaseModuleContext, module javaModule) *apexFile {
- if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
- if profilePathOnHost := dexpreopter.OutputProfilePathOnHost(); profilePathOnHost != nil {
- dirInApex := "javalib"
- af := newApexFile(ctx, profilePathOnHost, module.BaseModuleName()+"-profile", dirInApex, etc, nil)
- af.customStem = module.Stem() + ".jar.prof"
- return &af
- }
+func apexFileForJavaModuleProfile(ctx android.BaseModuleContext, commonInfo *android.CommonModuleInfo,
+ javaInfo *java.JavaInfo) *apexFile {
+ if profilePathOnHost := javaInfo.DexpreopterInfo.OutputProfilePathOnHost; profilePathOnHost != nil {
+ dirInApex := "javalib"
+ af := newApexFile(ctx, profilePathOnHost, commonInfo.BaseModuleName+"-profile", dirInApex, etc, nil)
+ af.customStem = javaInfo.Stem + ".jar.prof"
+ return &af
}
return nil
}
-// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
-// the same way.
-type androidApp interface {
- android.Module
- Privileged() bool
- InstallApkName() string
- OutputFile() android.Path
- JacocoReportClassesFile() android.Path
- Certificate() java.Certificate
- BaseModuleName() string
- PrivAppAllowlist() android.OptionalPath
-}
-
-var _ androidApp = (*java.AndroidApp)(nil)
-var _ androidApp = (*java.AndroidAppImport)(nil)
-
func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string {
buildId := ctx.Config().BuildId()
@@ -1573,36 +1541,35 @@
return buildId
}
-func apexFilesForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) []apexFile {
+func apexFilesForAndroidApp(ctx android.BaseModuleContext, module android.Module,
+ commonInfo *android.CommonModuleInfo, aapp *java.AppInfo) []apexFile {
appDir := "app"
- if aapp.Privileged() {
+ if aapp.Privileged {
appDir = "priv-app"
}
// TODO(b/224589412, b/226559955): Ensure that the subdirname is suffixed
// so that PackageManager correctly invalidates the existing installed apk
// in favour of the new APK-in-APEX. See bugs for more information.
- dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+sanitizedBuildIdForPath(ctx))
- fileToCopy := aapp.OutputFile()
+ dirInApex := filepath.Join(appDir, aapp.InstallApkName+"@"+sanitizedBuildIdForPath(ctx))
+ fileToCopy := aapp.OutputFile
- af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
- af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
- if lintInfo, ok := android.OtherModuleProvider(ctx, aapp, java.LintProvider); ok {
+ af := newApexFile(ctx, fileToCopy, commonInfo.BaseModuleName, dirInApex, app, module)
+ af.jacocoReportClassesFile = aapp.JacocoReportClassesFile
+ if lintInfo, ok := android.OtherModuleProvider(ctx, module, java.LintProvider); ok {
af.lintInfo = lintInfo
}
- af.certificate = aapp.Certificate()
+ af.certificate = aapp.Certificate
- if app, ok := aapp.(interface {
- OverriddenManifestPackageName() string
- }); ok {
- af.overriddenPackageName = app.OverriddenManifestPackageName()
+ if aapp.OverriddenManifestPackageName != nil {
+ af.overriddenPackageName = *aapp.OverriddenManifestPackageName
}
apexFiles := []apexFile{}
- if allowlist := aapp.PrivAppAllowlist(); allowlist.Valid() {
+ if allowlist := aapp.PrivAppAllowlist; allowlist.Valid() {
dirInApex := filepath.Join("etc", "permissions")
- privAppAllowlist := newApexFile(ctx, allowlist.Path(), aapp.BaseModuleName()+"_privapp", dirInApex, etc, aapp)
+ privAppAllowlist := newApexFile(ctx, allowlist.Path(), commonInfo.BaseModuleName+"_privapp", dirInApex, etc, module)
apexFiles = append(apexFiles, privAppAllowlist)
}
@@ -1611,29 +1578,24 @@
return apexFiles
}
-func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile {
+func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, module android.Module, rro java.RuntimeResourceOverlayInfo) apexFile {
rroDir := "overlay"
- dirInApex := filepath.Join(rroDir, rro.Theme())
- fileToCopy := rro.OutputFile()
- af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro)
- af.certificate = rro.Certificate()
+ dirInApex := filepath.Join(rroDir, rro.Theme)
+ fileToCopy := rro.OutputFile
+ af := newApexFile(ctx, fileToCopy, module.Name(), dirInApex, app, module)
+ af.certificate = rro.Certificate
- if a, ok := rro.(interface {
- OverriddenManifestPackageName() string
- }); ok {
- af.overriddenPackageName = a.OverriddenManifestPackageName()
- }
return af
}
-func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram bpf.BpfModule) apexFile {
+func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram android.Module) apexFile {
dirInApex := filepath.Join("etc", "bpf", apex_sub_dir)
return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram)
}
-func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, fs filesystem.Filesystem) apexFile {
+func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, module android.Module) apexFile {
dirInApex := filepath.Join("etc", "fs")
- return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, fs)
+ return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, module)
}
// WalkPayloadDeps visits dependencies that contributes to the payload of this APEX. For each of the
@@ -1659,8 +1621,7 @@
return false
}
- ai, _ := android.OtherModuleProvider(ctx, child, android.ApexInfoProvider)
- externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)
+ externalDep := !android.IsDepInSameApex(ctx, parent, child)
// Visit actually
return do(ctx, parent, am, externalDep)
@@ -1685,8 +1646,7 @@
return false
}
- ai, _ := android.OtherModuleProvider(ctx, child, android.ApexInfoProvider)
- externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)
+ externalDep := !android.IsDepInSameApex(ctx, parent, child)
// Visit actually
return do(ctx, parent, child, externalDep)
@@ -1884,11 +1844,12 @@
if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
return false
}
- if !child.Enabled(ctx) {
+ commonInfo := android.OtherModuleProviderOrDefault(ctx, child, android.CommonModuleInfoKey)
+ if !commonInfo.Enabled {
return false
}
depName := ctx.OtherModuleName(child)
- if _, isDirectDep := parent.(*apexBundle); isDirectDep {
+ if ctx.EqualModules(parent, ctx.Module()) {
switch depTag {
case sharedLibTag, jniLibTag:
isJniLib := depTag == jniLibTag
@@ -1896,58 +1857,54 @@
if isJniLib {
propertyName = "jni_libs"
}
- switch ch := child.(type) {
- case *cc.Module:
- if ch.IsStubs() {
+
+ if ch, ok := android.OtherModuleProvider(ctx, child, cc.LinkableInfoProvider); ok {
+ if ch.IsStubs {
ctx.PropertyErrorf(propertyName, "%q is a stub. Remove it from the list.", depName)
}
- fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
+ fi := apexFileForNativeLibrary(ctx, child, &commonInfo, ch, vctx.handleSpecialLibs)
fi.isJniLib = isJniLib
vctx.filesInfo = append(vctx.filesInfo, fi)
// Collect the list of stub-providing libs except:
// - VNDK libs are only for vendors
// - bootstrap bionic libs are treated as provided by system
- if ch.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(ch.BaseModuleName(), ctx.Config()) {
+ if ch.HasStubsVariants && !a.vndkApex && !cc.InstallToBootstrap(commonInfo.BaseModuleName, ctx.Config()) {
vctx.provideNativeLibs = append(vctx.provideNativeLibs, fi.stem())
}
return true // track transitive dependencies
- case *rust.Module:
- fi := apexFileForRustLibrary(ctx, ch)
- fi.isJniLib = isJniLib
- vctx.filesInfo = append(vctx.filesInfo, fi)
- return true // track transitive dependencies
- default:
- ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
+ } else {
+ ctx.PropertyErrorf(propertyName,
+ "%q is not a VersionLinkableInterface (e.g. cc_library or rust_ffi module)", depName)
}
+
case executableTag:
- switch ch := child.(type) {
- case *cc.Module:
- vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
+ if ccInfo, ok := android.OtherModuleProvider(ctx, child, cc.CcInfoProvider); ok {
+ vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, child, &commonInfo, ccInfo))
return true // track transitive dependencies
- case *rust.Module:
- vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
+ }
+ if _, ok := android.OtherModuleProvider(ctx, child, rust.RustInfoProvider); ok {
+ vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, child, &commonInfo))
return true // track transitive dependencies
- default:
+ } else {
ctx.PropertyErrorf("binaries",
"%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName)
}
case shBinaryTag:
- if csh, ok := child.(*sh.ShBinary); ok {
- vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, csh))
+ if csh, ok := android.OtherModuleProvider(ctx, child, sh.ShBinaryInfoProvider); ok {
+ vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, child, &commonInfo, &csh))
} else {
ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName)
}
case bcpfTag:
- _, ok := child.(*java.BootclasspathFragmentModule)
+ _, ok := android.OtherModuleProvider(ctx, child, java.BootclasspathFragmentInfoProvider)
if !ok {
ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName)
return false
}
-
vctx.filesInfo = append(vctx.filesInfo, apexBootclasspathFragmentFiles(ctx, child)...)
return true
case sscpfTag:
- if _, ok := child.(*java.SystemServerClasspathModule); !ok {
+ if _, ok := android.OtherModuleProvider(ctx, child, java.LibraryNameToPartitionInfoProvider); !ok {
ctx.PropertyErrorf("systemserverclasspath_fragments",
"%q is not a systemserverclasspath_fragment module", depName)
return false
@@ -1957,83 +1914,84 @@
}
return true
case javaLibTag:
- switch child.(type) {
- case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
- af := apexFileForJavaModule(ctx, child.(javaModule))
+ if ctx.OtherModuleHasProvider(child, java.JavaLibraryInfoProvider) ||
+ ctx.OtherModuleHasProvider(child, java.JavaDexImportInfoProvider) ||
+ ctx.OtherModuleHasProvider(child, java.SdkLibraryInfoProvider) {
+ javaInfo := android.OtherModuleProviderOrDefault(ctx, child, java.JavaInfoProvider)
+ af := apexFileForJavaModule(ctx, child, javaInfo)
if !af.ok() {
ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
return false
}
vctx.filesInfo = append(vctx.filesInfo, af)
return true // track transitive dependencies
- default:
+ } else {
ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
}
case androidAppTag:
- switch ap := child.(type) {
- case *java.AndroidApp:
- vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
- return true // track transitive dependencies
- case *java.AndroidAppImport:
- vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
- case *java.AndroidTestHelperApp:
- vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
- case *java.AndroidAppSet:
- appDir := "app"
- if ap.Privileged() {
- appDir = "priv-app"
+ if appInfo, ok := android.OtherModuleProvider(ctx, child, java.AppInfoProvider); ok {
+ if appInfo.AppSet {
+ appDir := "app"
+ if appInfo.Privileged {
+ appDir = "priv-app"
+ }
+ // TODO(b/224589412, b/226559955): Ensure that the dirname is
+ // suffixed so that PackageManager correctly invalidates the
+ // existing installed apk in favour of the new APK-in-APEX.
+ // See bugs for more information.
+ appDirName := filepath.Join(appDir, commonInfo.BaseModuleName+"@"+sanitizedBuildIdForPath(ctx))
+ af := newApexFile(ctx, appInfo.OutputFile, commonInfo.BaseModuleName, appDirName, appSet, child)
+ af.certificate = java.PresignedCertificate
+ vctx.filesInfo = append(vctx.filesInfo, af)
+ } else {
+ vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, child, &commonInfo, appInfo)...)
+ if !appInfo.Prebuilt && !appInfo.TestHelperApp {
+ return true // track transitive dependencies
+ }
}
- // TODO(b/224589412, b/226559955): Ensure that the dirname is
- // suffixed so that PackageManager correctly invalidates the
- // existing installed apk in favour of the new APK-in-APEX.
- // See bugs for more information.
- appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx))
- af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
- af.certificate = java.PresignedCertificate
- vctx.filesInfo = append(vctx.filesInfo, af)
- default:
+ } else {
ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
}
case rroTag:
- if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
- vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
+ if rro, ok := android.OtherModuleProvider(ctx, child, java.RuntimeResourceOverlayInfoProvider); ok {
+ vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, child, rro))
} else {
ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
}
case bpfTag:
- if bpfProgram, ok := child.(bpf.BpfModule); ok {
- filesToCopy := android.OutputFilesForModule(ctx, bpfProgram, "")
- apex_sub_dir := bpfProgram.SubDir()
+ if bpfProgram, ok := android.OtherModuleProvider(ctx, child, bpf.BpfInfoProvider); ok {
+ filesToCopy := android.OutputFilesForModule(ctx, child, "")
+ apex_sub_dir := bpfProgram.SubDir
for _, bpfFile := range filesToCopy {
- vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram))
+ vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, child))
}
} else {
ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName)
}
case fsTag:
- if fs, ok := child.(filesystem.Filesystem); ok {
- vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs))
+ if fs, ok := android.OtherModuleProvider(ctx, child, filesystem.FilesystemProvider); ok {
+ vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.Output, child))
} else {
ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName)
}
case prebuiltTag:
- if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
- filesToCopy := android.OutputFilesForModule(ctx, prebuilt, "")
+ if prebuilt, ok := android.OtherModuleProvider(ctx, child, prebuilt_etc.PrebuiltEtcInfoProvider); ok {
+ filesToCopy := android.OutputFilesForModule(ctx, child, "")
for _, etcFile := range filesToCopy {
- vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, etcFile))
+ vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, child, &prebuilt, etcFile))
}
} else {
ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
}
case compatConfigTag:
- if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok {
- vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName))
+ if compatConfig, ok := android.OtherModuleProvider(ctx, child, java.PlatformCompatConfigInfoProvider); ok {
+ vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, child, &compatConfig, depName))
} else {
ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName)
}
case testTag:
- if ccTest, ok := child.(*cc.Module); ok {
- af := apexFileForExecutable(ctx, ccTest)
+ if ccInfo, ok := android.OtherModuleProvider(ctx, child, cc.CcInfoProvider); ok {
+ af := apexFileForExecutable(ctx, child, &commonInfo, ccInfo)
af.class = nativeTest
vctx.filesInfo = append(vctx.filesInfo, af)
return true // track transitive dependencies
@@ -2041,14 +1999,14 @@
ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
}
case keyTag:
- if key, ok := child.(*apexKey); ok {
- a.privateKeyFile = key.privateKeyFile
- a.publicKeyFile = key.publicKeyFile
+ if key, ok := android.OtherModuleProvider(ctx, child, ApexKeyInfoProvider); ok {
+ a.privateKeyFile = key.PrivateKeyFile
+ a.publicKeyFile = key.PublicKeyFile
} else {
ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
}
case certificateTag:
- if dep, ok := child.(*java.AndroidAppCertificate); ok {
+ if dep, ok := android.OtherModuleProvider(ctx, child, java.AndroidAppCertificateInfoProvider); ok {
a.containerCertificateFile = dep.Certificate.Pem
a.containerPrivateKeyFile = dep.Certificate.Key
} else {
@@ -2063,18 +2021,17 @@
}
// indirect dependencies
- am, ok := child.(android.ApexModule)
- if !ok {
+ if !commonInfo.IsApexModule {
return false
}
// We cannot use a switch statement on `depTag` here as the checked
// tags used below are private (e.g. `cc.sharedDepTag`).
if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
- if ch, ok := child.(*cc.Module); ok {
- af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
+ if ch, ok := android.OtherModuleProvider(ctx, child, cc.LinkableInfoProvider); ok {
+ af := apexFileForNativeLibrary(ctx, child, &commonInfo, ch, vctx.handleSpecialLibs)
af.transitiveDep = true
- if ch.IsStubs() || ch.HasStubsVariants() {
+ if ch.IsStubs || ch.HasStubsVariants {
// If the dependency is a stubs lib, don't include it in this APEX,
// but make sure that the lib is installed on the device.
// In case no APEX is having the lib, the lib is installed to the system
@@ -2085,9 +2042,10 @@
//
// Skip the dependency in unbundled builds where the device image is not
// being built.
- if ch.IsStubsImplementationRequired() && !am.NotInPlatform() && !ctx.Config().UnbundledBuild() {
+ if ch.IsStubsImplementationRequired &&
+ !commonInfo.NotInPlatform && !ctx.Config().UnbundledBuild() {
// we need a module name for Make
- name := ch.ImplementationModuleNameForMake(ctx) + ch.Properties.SubName
+ name := ch.ImplementationModuleNameForMake + ch.SubName
if !android.InList(name, a.makeModulesToInstall) {
a.makeModulesToInstall = append(a.makeModulesToInstall, name)
}
@@ -2106,40 +2064,33 @@
// like to record requiredNativeLibs even when
// DepIsInSameAPex is false. We also shouldn't do
// this for host.
- if !android.IsDepInSameApex(ctx, parent, am) {
+ if !android.IsDepInSameApex(ctx, parent, child) {
return false
}
vctx.filesInfo = append(vctx.filesInfo, af)
return true // track transitive dependencies
- } else if rm, ok := child.(*rust.Module); ok {
- if !android.IsDepInSameApex(ctx, parent, am) {
- return false
- }
-
- af := apexFileForRustLibrary(ctx, rm)
- af.transitiveDep = true
- vctx.filesInfo = append(vctx.filesInfo, af)
- return true // track transitive dependencies
}
} else if cc.IsHeaderDepTag(depTag) {
// nothing
} else if java.IsJniDepTag(depTag) {
// Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
} else if java.IsXmlPermissionsFileDepTag(depTag) {
- if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
- filesToCopy := android.OutputFilesForModule(ctx, prebuilt, "")
+ if prebuilt, ok := android.OtherModuleProvider(ctx, child, prebuilt_etc.PrebuiltEtcInfoProvider); ok {
+ filesToCopy := android.OutputFilesForModule(ctx, child, "")
for _, etcFile := range filesToCopy {
- vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, etcFile))
+ vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, child, &prebuilt, etcFile))
}
}
} else if rust.IsDylibDepTag(depTag) {
- if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
- if !android.IsDepInSameApex(ctx, am, am) {
+ if _, ok := android.OtherModuleProvider(ctx, child, rust.RustInfoProvider); ok &&
+ commonInfo.IsInstallableToApex {
+ if !android.IsDepInSameApex(ctx, parent, child) {
return false
}
- af := apexFileForRustLibrary(ctx, rustm)
+ linkableInfo := android.OtherModuleProviderOrDefault(ctx, child, cc.LinkableInfoProvider)
+ af := apexFileForNativeLibrary(ctx, child, &commonInfo, linkableInfo, vctx.handleSpecialLibs)
af.transitiveDep = true
vctx.filesInfo = append(vctx.filesInfo, af)
return true // track transitive dependencies
@@ -2150,10 +2101,9 @@
return true
} else if java.IsBootclasspathFragmentContentDepTag(depTag) {
// Add the contents of the bootclasspath fragment to the apex.
- switch child.(type) {
- case *java.Library, *java.SdkLibrary:
- javaModule := child.(javaModule)
- af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule)
+ if ctx.OtherModuleHasProvider(child, java.JavaLibraryInfoProvider) ||
+ ctx.OtherModuleHasProvider(child, java.SdkLibraryInfoProvider) {
+ af := apexFileForBootclasspathFragmentContentModule(ctx, parent, child)
if !af.ok() {
ctx.PropertyErrorf("bootclasspath_fragments",
"bootclasspath_fragment content %q is not configured to be compiled into dex", depName)
@@ -2161,21 +2111,22 @@
}
vctx.filesInfo = append(vctx.filesInfo, af)
return true // track transitive dependencies
- default:
+ } else {
ctx.PropertyErrorf("bootclasspath_fragments",
"bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
}
} else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) {
// Add the contents of the systemserverclasspath fragment to the apex.
- switch child.(type) {
- case *java.Library, *java.SdkLibrary:
- af := apexFileForJavaModule(ctx, child.(javaModule))
+ if ctx.OtherModuleHasProvider(child, java.JavaLibraryInfoProvider) ||
+ ctx.OtherModuleHasProvider(child, java.SdkLibraryInfoProvider) {
+ javaInfo := android.OtherModuleProviderOrDefault(ctx, child, java.JavaInfoProvider)
+ af := apexFileForJavaModule(ctx, child, javaInfo)
vctx.filesInfo = append(vctx.filesInfo, af)
- if profileAf := apexFileForJavaModuleProfile(ctx, child.(javaModule)); profileAf != nil {
+ if profileAf := apexFileForJavaModuleProfile(ctx, &commonInfo, javaInfo); profileAf != nil {
vctx.filesInfo = append(vctx.filesInfo, *profileAf)
}
return true // track transitive dependencies
- default:
+ } else {
ctx.PropertyErrorf("systemserverclasspath_fragments",
"systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
}
@@ -2183,9 +2134,15 @@
// nothing
} else if depTag == android.RequiredDepTag {
// nothing
- } else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
+ } else if commonInfo.IsInstallableToApex {
ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
+ } else if android.IsVintfDepTag(depTag) {
+ if vf, ok := android.OtherModuleProvider(ctx, child, android.VintfFragmentInfoProvider); ok {
+ apexFile := apexFileForVintfFragment(ctx, child, &commonInfo, &vf)
+ vctx.filesInfo = append(vctx.filesInfo, apexFile)
+ }
}
+
return false
}
@@ -2284,6 +2241,7 @@
////////////////////////////////////////////////////////////////////////////////////////////
// 4) generate the build rules to create the APEX. This is done in builder.go.
a.buildManifest(ctx, vctx.provideNativeLibs, vctx.requireNativeLibs)
+ a.installApexSystemServerFiles(ctx)
a.buildApex(ctx)
a.buildApexDependencyInfo(ctx)
a.buildLintReports(ctx)
@@ -2349,8 +2307,8 @@
// checking direct deps is sufficient since apex->apk is a direct edge, even when inherited via apex_defaults
mctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
if appInfo, ok := android.OtherModuleProvider(mctx, module, java.AppInfoProvider); ok {
- // ignore android_test_app
- if !appInfo.TestHelperApp && !appInfo.Updatable {
+ // ignore android_test_app and android_app_import
+ if !appInfo.TestHelperApp && !appInfo.Prebuilt && !appInfo.Updatable {
mctx.ModuleErrorf("app dependency %s must have updatable: true", mctx.OtherModuleName(module))
}
}
@@ -2360,7 +2318,7 @@
// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
// the bootclasspath_fragment contributes to the apex.
-func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile {
+func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module android.Module) []apexFile {
bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, module, java.BootclasspathFragmentApexContentInfoProvider)
var filesToAdd []apexFile
@@ -2409,7 +2367,7 @@
// apexClasspathFragmentProtoFile returns *apexFile structure defining the classpath.proto config that
// the module contributes to the apex; or nil if the proto config was not generated.
-func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) *apexFile {
+func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module android.Module) *apexFile {
info, _ := android.OtherModuleProvider(ctx, module, java.ClasspathFragmentProtoContentInfoProvider)
if !info.ClasspathFragmentProtoGenerated {
return nil
@@ -2421,7 +2379,7 @@
// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
// content module, i.e. a library that is part of the bootclasspath.
-func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile {
+func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule, javaModule android.Module) apexFile {
bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, fragmentModule, java.BootclasspathFragmentApexContentInfoProvider)
// Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the
@@ -2433,7 +2391,8 @@
// Create an apexFile as for a normal java module but with the dex boot jar provided by the
// bootclasspath_fragment.
- af := apexFileForJavaModuleWithFile(ctx, javaModule, dexBootJar)
+ javaInfo := android.OtherModuleProviderOrDefault(ctx, javaModule, java.JavaInfoProvider)
+ af := apexFileForJavaModuleWithFile(ctx, javaModule, javaInfo, dexBootJar)
return af
}
@@ -2543,7 +2502,7 @@
}
// Returns apex's min_sdk_version string value, honoring overrides
-func (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string {
+func (a *apexBundle) minSdkVersionValue(ctx android.MinSdkVersionFromValueContext) string {
// Only override the minSdkVersion value on Apexes which already specify
// a min_sdk_version (it's optional for non-updatable apexes), and that its
// min_sdk_version value is lower than the one to override with.
@@ -2567,7 +2526,7 @@
}
// Returns apex's min_sdk_version ApiLevel, honoring overrides
-func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
+func (a *apexBundle) minSdkVersion(ctx android.MinSdkVersionFromValueContext) android.ApiLevel {
return android.MinSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx))
}
@@ -2583,7 +2542,7 @@
librariesDirectlyInApex[ctx.OtherModuleName(dep)] = true
})
- a.WalkPayloadDepsProxy(ctx, func(ctx android.BaseModuleContext, from, to android.ModuleProxy, externalDep bool) bool {
+ a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from android.Module, to android.ApexModule, externalDep bool) bool {
if info, ok := android.OtherModuleProvider(ctx, to, cc.LinkableInfoProvider); ok {
// If `to` is not actually in the same APEX as `from` then it does not need
// apex_available and neither do any of its dependencies.
@@ -2596,7 +2555,7 @@
fromName := ctx.OtherModuleName(from)
toName := ctx.OtherModuleName(to)
- // The dynamic linker and crash_dump tool in the runtime APEX is the only
+ // The dynamic linker and crash_dump tool in the runtime APEX is an
// exception to this rule. It can't make the static dependencies dynamic
// because it can't do the dynamic linking for itself.
// Same rule should be applied to linkerconfig, because it should be executed
@@ -2605,6 +2564,15 @@
return false
}
+ // b/389067742 adds libz as an exception to this check. Although libz is
+ // a part of NDK and thus provides a stable interface, it never was the
+ // intention because the upstream zlib provides neither ABI- nor behavior-
+ // stability. Therefore, we want to allow portable components like APEXes to
+ // bundle libz by statically linking to it.
+ if toName == "libz" {
+ return false
+ }
+
isStubLibraryFromOtherApex := info.HasStubsVariants && !librariesDirectlyInApex[toName]
if isStubLibraryFromOtherApex && !externalDep {
ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
@@ -2688,7 +2656,7 @@
return
}
- a.WalkPayloadDepsProxy(ctx, func(ctx android.BaseModuleContext, from, to android.ModuleProxy, externalDep bool) bool {
+ a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from android.Module, to android.ApexModule, externalDep bool) bool {
// As soon as the dependency graph crosses the APEX boundary, don't go further.
if externalDep {
return false
@@ -2706,7 +2674,7 @@
toName := ctx.OtherModuleName(to)
if android.CheckAvailableForApex(apexName,
- android.OtherModuleProviderOrDefault(ctx, to, android.ApexInfoProvider).ApexAvailableFor) {
+ android.OtherModuleProviderOrDefault(ctx, to, android.ApexAvailableInfoProvider).ApexAvailableFor) {
return true
}
@@ -2911,14 +2879,14 @@
if !inApex && !inApkInApex {
ctx.ModuleErrorf("library in apex transitively linked against implementation library %q not in apex", lib)
var depPath []android.Module
- ctx.WalkDeps(func(child, parent android.Module) bool {
+ ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
if depPath != nil {
return false
}
tag := ctx.OtherModuleDependencyTag(child)
- if parent == ctx.Module() {
+ if ctx.EqualModules(parent, ctx.Module()) {
if !checkApexTag(tag) {
return false
}
diff --git a/apex/apex_singleton.go b/apex/apex_singleton.go
index d46104e..a8bd984 100644
--- a/apex/apex_singleton.go
+++ b/apex/apex_singleton.go
@@ -59,9 +59,9 @@
// Diff two given lists while ignoring comments in the allowed deps file.
diffAllowedApexDepsInfoRule = pctx.AndroidStaticRule("diffAllowedApexDepsInfoRule", blueprint.RuleParams{
- Description: "Diff ${allowed_deps_list} and ${new_allowed_deps}",
+ Description: "Diff ${allowed_deps} and ${new_allowed_deps}",
Command: `
- if grep -v -h '^#' ${allowed_deps_list} | sort -u -f| diff -B -u - ${new_allowed_deps}; then
+ if grep -v '^#' ${allowed_deps} | diff -B - ${new_allowed_deps}; then
touch ${out};
else
echo;
@@ -85,62 +85,54 @@
exit 1;
fi;
`,
- }, "allowed_deps_list", "new_allowed_deps")
+ }, "allowed_deps", "new_allowed_deps")
)
func (s *apexDepsInfoSingleton) GenerateBuildActions(ctx android.SingletonContext) {
- allowedDepsSources := []android.OptionalPath{android.ExistentPathForSource(ctx, "packages/modules/common/build/allowed_deps.txt")}
- extraAllowedDepsPath := ctx.Config().ExtraAllowedDepsTxt()
- if extraAllowedDepsPath != "" {
- allowedDepsSources = append(allowedDepsSources, android.ExistentPathForSource(ctx, extraAllowedDepsPath))
- }
updatableFlatLists := android.Paths{}
ctx.VisitAllModules(func(module android.Module) {
if binaryInfo, ok := module.(android.ApexBundleDepsInfoIntf); ok {
apexInfo, _ := android.OtherModuleProvider(ctx, module, android.ApexInfoProvider)
if path := binaryInfo.FlatListPath(); path != nil {
if binaryInfo.Updatable() || apexInfo.Updatable {
- updatableFlatLists = append(updatableFlatLists, path)
+ if strings.HasPrefix(module.String(), "com.android.") {
+ updatableFlatLists = append(updatableFlatLists, path)
+ }
}
}
}
})
+
+ allowedDepsSource := android.ExistentPathForSource(ctx, "packages/modules/common/build/allowed_deps.txt")
newAllowedDeps := android.PathForOutput(ctx, "apex", "depsinfo", "new-allowed-deps.txt")
s.allowedApexDepsInfoCheckResult = android.PathForOutput(ctx, newAllowedDeps.Rel()+".check")
- hasOneValidDepsPath := false
- for _, allowedDepsSource := range allowedDepsSources {
- if allowedDepsSource.Valid() {
- hasOneValidDepsPath = true
- updatableFlatLists = append(updatableFlatLists, allowedDepsSource.Path())
- }
- }
- allowedDepsStrList := make([]string, len(allowedDepsSources))
- for _, value := range allowedDepsSources {
- allowedDepsStrList = append(allowedDepsStrList, value.String())
- }
- allowedDepsListString := strings.Join(allowedDepsStrList, " ")
- if !hasOneValidDepsPath {
+
+ if !allowedDepsSource.Valid() {
// Unbundled projects may not have packages/modules/common/ checked out; ignore those.
ctx.Build(pctx, android.BuildParams{
Rule: android.Touch,
Output: s.allowedApexDepsInfoCheckResult,
})
} else {
+ allowedDeps := allowedDepsSource.Path()
+
ctx.Build(pctx, android.BuildParams{
Rule: generateApexDepsInfoFilesRule,
- Inputs: updatableFlatLists,
+ Inputs: append(updatableFlatLists, allowedDeps),
Output: newAllowedDeps,
})
+
ctx.Build(pctx, android.BuildParams{
Rule: diffAllowedApexDepsInfoRule,
Input: newAllowedDeps,
Output: s.allowedApexDepsInfoCheckResult,
Args: map[string]string{
- "allowed_deps_list": allowedDepsListString,
- "new_allowed_deps": newAllowedDeps.String(),
+ "allowed_deps": allowedDeps.String(),
+ "new_allowed_deps": newAllowedDeps.String(),
},
})
}
+
ctx.Phony("apex-allowed-deps-check", s.allowedApexDepsInfoCheckResult)
}
@@ -183,8 +175,5 @@
}
a.out = android.PathForOutput(ctx, "prebuilt_info.json")
android.WriteFileRule(ctx, a.out, string(j))
-}
-
-func (a *apexPrebuiltInfo) MakeVars(ctx android.MakeVarsContext) {
ctx.DistForGoal("droidcore", a.out)
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index e1a9582..9eaf814 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -20,7 +20,6 @@
"path/filepath"
"reflect"
"regexp"
- "slices"
"sort"
"strconv"
"strings"
@@ -29,7 +28,6 @@
"android/soong/aconfig/codegen"
"github.com/google/blueprint"
- "github.com/google/blueprint/bpmodify"
"github.com/google/blueprint/proptools"
"android/soong/android"
@@ -507,10 +505,10 @@
}
`)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+ apexRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("apexRule")
// Make sure that Android.mk is created
- ab := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle)
+ ab := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Module().(*apexBundle)
data := android.AndroidMkDataForTest(t, ctx, ab)
var builder strings.Builder
data.Custom(&builder, ab.BaseModuleName(), "TARGET_", "", data)
@@ -587,14 +585,14 @@
}
fullDepsInfo := strings.Split(android.ContentFromFileRuleForTests(t, ctx,
- ctx.ModuleForTests("myapex", "android_common_myapex").Output("depsinfo/fulllist.txt")), "\n")
+ ctx.ModuleForTests(t, "myapex", "android_common_myapex").Output("depsinfo/fulllist.txt")), "\n")
ensureListContains(t, fullDepsInfo, " myjar(minSdkVersion:(no version)) <- myapex")
ensureListContains(t, fullDepsInfo, " mylib2(minSdkVersion:(no version)) <- mylib")
ensureListContains(t, fullDepsInfo, " myotherjar(minSdkVersion:(no version)) <- myjar")
ensureListContains(t, fullDepsInfo, " mysharedjar(minSdkVersion:(no version)) (external) <- myjar")
flatDepsInfo := strings.Split(android.ContentFromFileRuleForTests(t, ctx,
- ctx.ModuleForTests("myapex", "android_common_myapex").Output("depsinfo/flatlist.txt")), "\n")
+ ctx.ModuleForTests(t, "myapex", "android_common_myapex").Output("depsinfo/flatlist.txt")), "\n")
ensureListContains(t, flatDepsInfo, "myjar(minSdkVersion:(no version))")
ensureListContains(t, flatDepsInfo, "mylib2(minSdkVersion:(no version))")
ensureListContains(t, flatDepsInfo, "myotherjar(minSdkVersion:(no version))")
@@ -701,7 +699,7 @@
}
`)
- module := ctx.ModuleForTests("myapex", "android_common_myapex")
+ module := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
args := module.Rule("apexRule").Args
if manifest := args["manifest"]; manifest != module.Output("apex_manifest.pb").Output.String() {
t.Error("manifest should be apex_manifest.pb, but " + manifest)
@@ -773,7 +771,7 @@
},
}
for _, tc := range testCases {
- module := ctx.ModuleForTests(tc.module, "android_common_"+tc.module)
+ module := ctx.ModuleForTests(t, tc.module, "android_common_"+tc.module)
args := module.Rule("apexRule").Args
optFlags := args["opt_flags"]
if !strings.Contains(optFlags, "--min_sdk_version "+tc.minSdkVersion) {
@@ -847,7 +845,7 @@
},
}
for _, tc := range testCases {
- module := ctx.ModuleForTests(tc.module, "android_common_"+tc.module)
+ module := ctx.ModuleForTests(t, tc.module, "android_common_"+tc.module)
args := module.Rule("apexRule").Args
optFlags := args["opt_flags"]
if !strings.Contains(optFlags, "--min_sdk_version "+tc.minSdkVersion) {
@@ -878,7 +876,7 @@
}
`)
- rule := ctx.ModuleForTests("myapex", "android_common_myapex").Output("file_contexts")
+ rule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Output("file_contexts")
if vendor {
android.AssertStringDoesContain(t, "should force-label as vendor_apex_metadata_file",
rule.RuleParams.Command,
@@ -897,7 +895,11 @@
apex {
name: "myapex",
key: "myapex.key",
- native_shared_libs: ["mylib", "mylib3"],
+ native_shared_libs: [
+ "mylib",
+ "mylib3",
+ "libmylib3_rs",
+ ],
binaries: ["foo.rust"],
updatable: false,
}
@@ -911,7 +913,14 @@
cc_library {
name: "mylib",
srcs: ["mylib.cpp"],
- shared_libs: ["mylib2", "mylib3#impl", "my_prebuilt_platform_lib", "my_prebuilt_platform_stub_only_lib"],
+ shared_libs: [
+ "mylib2",
+ "mylib3#impl",
+ "libmylib2_rs",
+ "libmylib3_rs#impl",
+ "my_prebuilt_platform_lib",
+ "my_prebuilt_platform_stub_only_lib",
+ ],
system_shared_libs: [],
stl: "none",
apex_available: [ "myapex" ],
@@ -929,6 +938,16 @@
},
}
+ rust_ffi {
+ name: "libmylib2_rs",
+ crate_name: "mylib2",
+ srcs: ["mylib.rs"],
+ stubs: {
+ symbol_file: "mylib2.map.txt",
+ versions: ["1", "2", "3"],
+ },
+ }
+
cc_library {
name: "mylib3",
srcs: ["mylib.cpp"],
@@ -942,6 +961,18 @@
apex_available: [ "myapex" ],
}
+ rust_ffi {
+ name: "libmylib3_rs",
+ crate_name: "mylib3",
+ srcs: ["mylib.rs"],
+ shared_libs: ["mylib4.from_rust"],
+ stubs: {
+ symbol_file: "mylib3.map.txt",
+ versions: ["10", "11", "12"],
+ },
+ apex_available: [ "myapex" ],
+ }
+
cc_library {
name: "mylib4",
srcs: ["mylib.cpp"],
@@ -950,6 +981,14 @@
apex_available: [ "myapex" ],
}
+ cc_library {
+ name: "mylib4.from_rust",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [ "myapex" ],
+ }
+
cc_prebuilt_library_shared {
name: "my_prebuilt_platform_lib",
stubs: {
@@ -971,7 +1010,10 @@
rust_binary {
name: "foo.rust",
srcs: ["foo.rs"],
- shared_libs: ["libfoo.shared_from_rust"],
+ shared_libs: [
+ "libfoo.shared_from_rust",
+ "libfoo_rs.shared_from_rust",
+ ],
prefer_rlib: true,
apex_available: ["myapex"],
}
@@ -986,9 +1028,18 @@
},
}
+ rust_ffi {
+ name: "libfoo_rs.shared_from_rust",
+ crate_name: "foo_rs",
+ srcs: ["mylib.rs"],
+ stubs: {
+ versions: ["10", "11", "12"],
+ },
+ }
+
`)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+ apexRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
// Ensure that direct non-stubs dep is always included
@@ -996,21 +1047,27 @@
// Ensure that indirect stubs dep is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libmylib2_rs.so")
// Ensure that direct stubs dep is included
ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so")
+ ensureContains(t, copyCmds, "image.apex/lib64/libmylib3_rs.so")
- mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
+ mylibLdFlags := ctx.ModuleForTests(t, "mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
// Ensure that mylib is linking with the latest version of stubs for mylib2
ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so")
+ ensureContains(t, mylibLdFlags, "libmylib2_rs/android_arm64_armv8-a_shared_current/unstripped/libmylib2_rs.so")
// ... and not linking to the non-stub (impl) variant of mylib2
ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
+ ensureNotContains(t, mylibLdFlags, "libmylib2_rs/android_arm64_armv8-a_shared/unstripped/libmylib2_rs.so")
// Ensure that mylib is linking with the non-stub (impl) of mylib3 (because the dependency is added with mylib3#impl)
ensureContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_apex10000/mylib3.so")
+ ensureContains(t, mylibLdFlags, "libmylib3_rs/android_arm64_armv8-a_shared_apex10000/unstripped/libmylib3_rs.so")
// .. and not linking to the stubs variant of mylib3
ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_12/mylib3.so")
+ ensureNotContains(t, mylibLdFlags, "libmylib3_rs/android_arm64_armv8-a_shared_12/unstripped/mylib3.so")
// Comment out this test. Now it fails after the optimization of sharing "cflags" in cc/cc.go
// is replaced by sharing of "cFlags" in cc/builder.go.
@@ -1021,46 +1078,54 @@
// including the original cflags's "-include mylib.h".
//
// Ensure that stubs libs are built without -include flags
- // mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
+ // mylib2Cflags := ctx.ModuleForTests(t, "mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
// ensureNotContains(t, mylib2Cflags, "-include ")
// Ensure that genstub for platform-provided lib is invoked with --systemapi
- ensureContains(t, ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi")
+ ensureContains(t, ctx.ModuleForTests(t, "mylib2", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi")
+ ensureContains(t, ctx.ModuleForTests(t, "libmylib2_rs", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi")
// Ensure that genstub for apex-provided lib is invoked with --apex
- ensureContains(t, ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_shared_12").Rule("genStubSrc").Args["flags"], "--apex")
+ ensureContains(t, ctx.ModuleForTests(t, "mylib3", "android_arm64_armv8-a_shared_12").Rule("genStubSrc").Args["flags"], "--apex")
+ ensureContains(t, ctx.ModuleForTests(t, "libmylib3_rs", "android_arm64_armv8-a_shared_12").Rule("genStubSrc").Args["flags"], "--apex")
ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{
"lib64/mylib.so",
"lib64/mylib3.so",
+ "lib64/libmylib3_rs.so",
"lib64/mylib4.so",
+ "lib64/mylib4.from_rust.so",
"bin/foo.rust",
- "lib64/libc++.so", // by the implicit dependency from foo.rust
- "lib64/liblog.so", // by the implicit dependency from foo.rust
+
+ "lib64/libstd.dylib.so", // implicit rust ffi dep
})
// Ensure that stub dependency from a rust module is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo_rs.shared_from_rust.so")
// The rust module is linked to the stub cc library
- rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").Args["linkFlags"]
+ rustDeps := ctx.ModuleForTests(t, "foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").Args["linkFlags"]
ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so")
+ ensureContains(t, rustDeps, "libfoo_rs.shared_from_rust/android_arm64_armv8-a_shared_current/unstripped/libfoo_rs.shared_from_rust.so")
ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so")
+ ensureNotContains(t, rustDeps, "libfoo_rs.shared_from_rust/android_arm64_armv8-a_shared/unstripped/libfoo_rs.shared_from_rust.so")
- apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexManifestRule")
+ apexManifestRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("apexManifestRule")
ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libfoo.shared_from_rust.so")
+ ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libfoo_rs.shared_from_rust.so")
// Ensure that mylib is linking with the latest version of stubs for my_prebuilt_platform_lib
ensureContains(t, mylibLdFlags, "my_prebuilt_platform_lib/android_arm64_armv8-a_shared_current/my_prebuilt_platform_lib.so")
// ... and not linking to the non-stub (impl) variant of my_prebuilt_platform_lib
ensureNotContains(t, mylibLdFlags, "my_prebuilt_platform_lib/android_arm64_armv8-a_shared/my_prebuilt_platform_lib.so")
// Ensure that genstub for platform-provided lib is invoked with --systemapi
- ensureContains(t, ctx.ModuleForTests("my_prebuilt_platform_lib", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi")
+ ensureContains(t, ctx.ModuleForTests(t, "my_prebuilt_platform_lib", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi")
// Ensure that mylib is linking with the latest version of stubs for my_prebuilt_platform_lib
ensureContains(t, mylibLdFlags, "my_prebuilt_platform_stub_only_lib/android_arm64_armv8-a_shared_current/my_prebuilt_platform_stub_only_lib.so")
// ... and not linking to the non-stub (impl) variant of my_prebuilt_platform_lib
ensureNotContains(t, mylibLdFlags, "my_prebuilt_platform_stub_only_lib/android_arm64_armv8-a_shared/my_prebuilt_platform_stub_only_lib.so")
// Ensure that genstub for platform-provided lib is invoked with --systemapi
- ensureContains(t, ctx.ModuleForTests("my_prebuilt_platform_stub_only_lib", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi")
+ ensureContains(t, ctx.ModuleForTests(t, "my_prebuilt_platform_stub_only_lib", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi")
}
func TestApexShouldNotEmbedStubVariant(t *testing.T) {
@@ -1111,7 +1176,10 @@
cc_library {
name: "mylib",
srcs: ["mylib.cpp"],
- shared_libs: ["mylib2"],
+ shared_libs: [
+ "mylib2",
+ "libmylib2_rust"
+ ],
system_shared_libs: [],
stl: "none",
apex_available: [ "myapex" ],
@@ -1128,10 +1196,22 @@
},
}
+ rust_ffi {
+ name: "libmylib2_rust",
+ crate_name: "mylib2_rust",
+ srcs: ["mylib.rs"],
+ stubs: {
+ versions: ["1", "2", "3"],
+ },
+ }
+
rust_binary {
name: "foo.rust",
srcs: ["foo.rs"],
- shared_libs: ["libfoo.shared_from_rust"],
+ shared_libs: [
+ "libfoo.shared_from_rust",
+ "libmylib_rust.shared_from_rust"
+ ],
prefer_rlib: true,
apex_available: ["myapex"],
}
@@ -1145,23 +1225,38 @@
versions: ["10", "11", "12"],
},
}
+ rust_ffi {
+ name: "libmylib_rust.shared_from_rust",
+ crate_name: "mylib_rust",
+ srcs: ["mylib.rs"],
+ stubs: {
+ versions: ["1", "2", "3"],
+ },
+ }
+
`)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+ apexRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
// Ensure that indirect stubs dep is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libmylib_rust.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libmylib_rust.shared_from_rust.so")
ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so")
// Ensure that we are using non-stub variants of mylib2 and libfoo.shared_from_rust (because
// of the platform_apis: true)
- mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
+ mylibLdFlags := ctx.ModuleForTests(t, "mylib", "android_arm64_armv8-a_shared_apex10000_p").Rule("ld").Args["libFlags"]
ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so")
ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
- rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").Args["linkFlags"]
+ ensureNotContains(t, mylibLdFlags, "libmylib2_rust/android_arm64_armv8-a_shared_current/unstripped/libmylib2_rust.so")
+ ensureContains(t, mylibLdFlags, "libmylib2_rust/android_arm64_armv8-a_shared/unstripped/libmylib2_rust.so")
+ rustDeps := ctx.ModuleForTests(t, "foo.rust", "android_arm64_armv8-a_apex10000_p").Rule("rustc").Args["linkFlags"]
ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so")
ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so")
+ ensureNotContains(t, rustDeps, "libmylib_rust.shared_from_rust/android_arm64_armv8-a_shared_current/unstripped/libmylib_rust.shared_from_rust.so")
+ ensureContains(t, rustDeps, "libmylib_rust.shared_from_rust/android_arm64_armv8-a_shared/unstripped/libmylib_rust.shared_from_rust.so")
}
func TestApexWithStubsWithMinSdkVersion(t *testing.T) {
@@ -1170,7 +1265,11 @@
apex {
name: "myapex",
key: "myapex.key",
- native_shared_libs: ["mylib", "mylib3"],
+ native_shared_libs: [
+ "mylib",
+ "mylib3",
+ "libmylib3_rust",
+ ],
min_sdk_version: "29",
}
@@ -1183,7 +1282,12 @@
cc_library {
name: "mylib",
srcs: ["mylib.cpp"],
- shared_libs: ["mylib2", "mylib3#impl"],
+ shared_libs: [
+ "mylib2",
+ "mylib3#impl",
+ "libmylib2_rust",
+ "libmylib3_rust#impl",
+ ],
system_shared_libs: [],
stl: "none",
apex_available: [ "myapex" ],
@@ -1203,6 +1307,17 @@
min_sdk_version: "28",
}
+ rust_ffi {
+ name: "libmylib2_rust",
+ crate_name: "mylib2_rust",
+ srcs: ["mylib.rs"],
+ stubs: {
+ symbol_file: "mylib2.map.txt",
+ versions: ["28", "29", "30", "current"],
+ },
+ min_sdk_version: "28",
+ }
+
cc_library {
name: "mylib3",
srcs: ["mylib.cpp"],
@@ -1217,6 +1332,19 @@
min_sdk_version: "28",
}
+ rust_ffi {
+ name: "libmylib3_rust",
+ crate_name: "mylib3_rust",
+ srcs: ["mylib.rs"],
+ shared_libs: ["libmylib4.from_rust"],
+ stubs: {
+ symbol_file: "mylib3.map.txt",
+ versions: ["28", "29", "30", "current"],
+ },
+ apex_available: [ "myapex" ],
+ min_sdk_version: "28",
+ }
+
cc_library {
name: "mylib4",
srcs: ["mylib.cpp"],
@@ -1225,43 +1353,63 @@
apex_available: [ "myapex" ],
min_sdk_version: "28",
}
+
+ rust_ffi {
+ name: "libmylib4.from_rust",
+ crate_name: "mylib4",
+ srcs: ["mylib.rs"],
+ apex_available: [ "myapex" ],
+ min_sdk_version: "28",
+ }
`)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+ apexRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
// Ensure that direct non-stubs dep is always included
ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
+ ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so")
+ ensureContains(t, copyCmds, "image.apex/lib64/libmylib3_rust.so")
// Ensure that indirect stubs dep is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libmylib2_rust.so")
// Ensure that direct stubs dep is included
ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so")
- mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex29").Rule("ld").Args["libFlags"]
+ mylibLdFlags := ctx.ModuleForTests(t, "mylib", "android_arm64_armv8-a_shared_apex29").Rule("ld").Args["libFlags"]
// Ensure that mylib is linking with the latest version of stub for mylib2
ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so")
+ ensureContains(t, mylibLdFlags, "libmylib2_rust/android_arm64_armv8-a_shared_current/unstripped/libmylib2_rust.so")
// ... and not linking to the non-stub (impl) variant of mylib2
ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
+ ensureNotContains(t, mylibLdFlags, "libmylib2_rust/android_arm64_armv8-a_shared/unstripped/libmylib2_rust.so")
// Ensure that mylib is linking with the non-stub (impl) of mylib3 (because the dependency is added with mylib3#impl)
ensureContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_apex29/mylib3.so")
+ ensureContains(t, mylibLdFlags, "libmylib3_rust/android_arm64_armv8-a_shared_apex29/unstripped/libmylib3_rust.so")
// .. and not linking to the stubs variant of mylib3
ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_29/mylib3.so")
+ ensureNotContains(t, mylibLdFlags, "libmylib3_rust/android_arm64_armv8-a_shared_29/unstripped/libmylib3_rust.so")
// Ensure that stubs libs are built without -include flags
- mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("cc").Args["cFlags"]
+ mylib2Cflags := ctx.ModuleForTests(t, "mylib2", "android_arm64_armv8-a_shared_29").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylib2Cflags, "-include ")
// Ensure that genstub is invoked with --systemapi
- ensureContains(t, ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("genStubSrc").Args["flags"], "--systemapi")
+ ensureContains(t, ctx.ModuleForTests(t, "mylib2", "android_arm64_armv8-a_shared_29").Rule("genStubSrc").Args["flags"], "--systemapi")
+ ensureContains(t, ctx.ModuleForTests(t, "libmylib2_rust", "android_arm64_armv8-a_shared_29").Rule("cc.genStubSrc").Args["flags"], "--systemapi")
ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{
"lib64/mylib.so",
"lib64/mylib3.so",
+ "lib64/libmylib3_rust.so",
"lib64/mylib4.so",
+ "lib64/libmylib4.from_rust.so",
+
+ "lib64/libstd.dylib.so", // by the implicit dependency from foo.rust
})
}
@@ -1286,7 +1434,10 @@
cc_library {
name: "mylib",
srcs: ["mylib.cpp"],
- shared_libs: ["libstub"],
+ shared_libs: [
+ "libstub",
+ "libstub_rust",
+ ],
apex_available: ["myapex"],
min_sdk_version: "Z",
}
@@ -1300,7 +1451,10 @@
apex {
name: "otherapex",
key: "myapex.key",
- native_shared_libs: ["libstub"],
+ native_shared_libs: [
+ "libstub",
+ "libstub_rust",
+ ],
min_sdk_version: "29",
}
@@ -1314,11 +1468,25 @@
min_sdk_version: "29",
}
+ rust_ffi {
+ name: "libstub_rust",
+ crate_name: "stub_rust",
+ srcs: ["mylib.rs"],
+ stubs: {
+ versions: ["29", "Z", "current"],
+ },
+ apex_available: ["otherapex"],
+ min_sdk_version: "29",
+ }
+
// platform module depending on libstub from otherapex should use the latest stub("current")
cc_library {
name: "libplatform",
srcs: ["mylib.cpp"],
- shared_libs: ["libstub"],
+ shared_libs: [
+ "libstub",
+ "libstub_rust",
+ ],
}
`,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
@@ -1329,16 +1497,22 @@
)
// Ensure that mylib from myapex is built against the latest stub (current)
- mylibCflags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"]
+ mylibCflags := ctx.ModuleForTests(t, "mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"]
ensureContains(t, mylibCflags, "-D__LIBSTUB_API__=10000 ")
- mylibLdflags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
+ // rust stubs do not emit -D__LIBFOO_API__ flags as this is deprecated behavior for cc stubs
+
+ mylibLdflags := ctx.ModuleForTests(t, "mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
ensureContains(t, mylibLdflags, "libstub/android_arm64_armv8-a_shared_current/libstub.so ")
+ ensureContains(t, mylibLdflags, "libstub_rust/android_arm64_armv8-a_shared_current/unstripped/libstub_rust.so ")
// Ensure that libplatform is built against latest stub ("current") of mylib3 from the apex
- libplatformCflags := ctx.ModuleForTests("libplatform", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
+ libplatformCflags := ctx.ModuleForTests(t, "libplatform", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
ensureContains(t, libplatformCflags, "-D__LIBSTUB_API__=10000 ") // "current" maps to 10000
- libplatformLdflags := ctx.ModuleForTests("libplatform", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"]
+ // rust stubs do not emit -D__LIBFOO_API__ flags as this is deprecated behavior for cc stubs
+
+ libplatformLdflags := ctx.ModuleForTests(t, "libplatform", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"]
ensureContains(t, libplatformLdflags, "libstub/android_arm64_armv8-a_shared_current/libstub.so ")
+ ensureContains(t, libplatformLdflags, "libstub_rust/android_arm64_armv8-a_shared_current/unstripped/libstub_rust.so ")
}
func TestApexWithExplicitStubsDependency(t *testing.T) {
@@ -1360,7 +1534,10 @@
cc_library {
name: "mylib",
srcs: ["mylib.cpp"],
- shared_libs: ["libfoo#10"],
+ shared_libs: [
+ "libfoo#10",
+ "libfoo_rust#10"
+ ],
static_libs: ["libbaz"],
system_shared_libs: [],
stl: "none",
@@ -1378,6 +1555,16 @@
},
}
+ rust_ffi {
+ name: "libfoo_rust",
+ crate_name: "foo_rust",
+ srcs: ["mylib.cpp"],
+ shared_libs: ["libbar.from_rust"],
+ stubs: {
+ versions: ["10", "20", "30"],
+ },
+ }
+
cc_library {
name: "libbar",
srcs: ["mylib.cpp"],
@@ -1385,6 +1572,13 @@
stl: "none",
}
+ cc_library {
+ name: "libbar.from_rust",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ }
+
cc_library_static {
name: "libbaz",
srcs: ["mylib.cpp"],
@@ -1395,7 +1589,7 @@
`)
- apexRule := ctx.ModuleForTests("myapex2", "android_common_myapex2").Rule("apexRule")
+ apexRule := ctx.ModuleForTests(t, "myapex2", "android_common_myapex2").Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
// Ensure that direct non-stubs dep is always included
@@ -1403,28 +1597,34 @@
// Ensure that indirect stubs dep is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo_rust.so")
// Ensure that dependency of stubs is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.from_rust.so")
- mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
+ mylibLdFlags := ctx.ModuleForTests(t, "mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
// Ensure that mylib is linking with version 10 of libfoo
ensureContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared_10/libfoo.so")
+ ensureContains(t, mylibLdFlags, "libfoo_rust/android_arm64_armv8-a_shared_10/unstripped/libfoo_rust.so")
// ... and not linking to the non-stub (impl) variant of libfoo
ensureNotContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared/libfoo.so")
+ ensureNotContains(t, mylibLdFlags, "libfoo_rust/android_arm64_armv8-a_shared/unstripped/libfoo_rust.so")
- libFooStubsLdFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_10").Rule("ld").Args["libFlags"]
+ libFooStubsLdFlags := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared_10").Rule("ld").Args["libFlags"]
+ libFooRustStubsLdFlags := ctx.ModuleForTests(t, "libfoo_rust", "android_arm64_armv8-a_shared_10").Rule("ld").Args["libFlags"]
// Ensure that libfoo stubs is not linking to libbar (since it is a stubs)
ensureNotContains(t, libFooStubsLdFlags, "libbar.so")
+ ensureNotContains(t, libFooRustStubsLdFlags, "libbar.from_rust.so")
fullDepsInfo := strings.Split(android.ContentFromFileRuleForTests(t, ctx,
- ctx.ModuleForTests("myapex2", "android_common_myapex2").Output("depsinfo/fulllist.txt")), "\n")
+ ctx.ModuleForTests(t, "myapex2", "android_common_myapex2").Output("depsinfo/fulllist.txt")), "\n")
ensureListContains(t, fullDepsInfo, " libfoo(minSdkVersion:(no version)) (external) <- mylib")
flatDepsInfo := strings.Split(android.ContentFromFileRuleForTests(t, ctx,
- ctx.ModuleForTests("myapex2", "android_common_myapex2").Output("depsinfo/flatlist.txt")), "\n")
+ ctx.ModuleForTests(t, "myapex2", "android_common_myapex2").Output("depsinfo/flatlist.txt")), "\n")
ensureListContains(t, flatDepsInfo, "libfoo(minSdkVersion:(no version)) (external)")
}
@@ -1457,7 +1657,11 @@
srcs: ["mylib.cpp"],
static_libs: ["libstatic"],
shared_libs: ["libshared"],
- runtime_libs: ["libfoo", "libbar"],
+ runtime_libs: [
+ "libfoo",
+ "libbar",
+ "libfoo_rs",
+ ],
system_shared_libs: [],
stl: "none",
apex_available: [ "myapex" ],
@@ -1473,6 +1677,15 @@
},
}
+ rust_ffi {
+ name: "libfoo_rs",
+ crate_name: "foo_rs",
+ srcs: ["mylib.rs"],
+ stubs: {
+ versions: ["10", "20", "30"],
+ },
+ }
+
cc_library {
name: "libbar",
srcs: ["mylib.cpp"],
@@ -1516,7 +1729,7 @@
}
`)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+ apexRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
// Ensure that direct non-stubs dep is always included
@@ -1524,6 +1737,7 @@
// Ensure that indirect stubs dep is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo_rs.so")
// Ensure that runtime_libs dep in included
ensureContains(t, copyCmds, "image.apex/lib64/libbar.so")
@@ -1532,9 +1746,10 @@
ensureNotContains(t, copyCmds, "image.apex/lib64/libstatic_to_runtime.so")
- apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexManifestRule")
+ apexManifestRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("apexManifestRule")
ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"]))
ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libfoo.so")
+ ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libfoo_rs.so")
}
var prepareForTestOfRuntimeApexWithHwasan = android.GroupFixturePreparers(
@@ -1601,7 +1816,7 @@
"lib64/bionic/libclang_rt.hwasan-aarch64-android.so",
})
- hwasan := ctx.ModuleForTests("libclang_rt.hwasan", "android_arm64_armv8-a_shared")
+ hwasan := ctx.ModuleForTests(t, "libclang_rt.hwasan", "android_arm64_armv8-a_shared")
installed := hwasan.Description("install libclang_rt.hwasan")
ensureContains(t, installed.Output.String(), "/system/lib64/bootstrap/libclang_rt.hwasan-aarch64-android.so")
@@ -1657,7 +1872,7 @@
"lib64/bionic/libclang_rt.hwasan-aarch64-android.so",
})
- hwasan := ctx.ModuleForTests("libclang_rt.hwasan", "android_arm64_armv8-a_shared")
+ hwasan := ctx.ModuleForTests(t, "libclang_rt.hwasan", "android_arm64_armv8-a_shared")
installed := hwasan.Description("install libclang_rt.hwasan")
ensureContains(t, installed.Output.String(), "/system/lib64/bootstrap/libclang_rt.hwasan-aarch64-android.so")
@@ -1740,17 +1955,17 @@
})
// Ensure that LLNDK dep is required
- apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexManifestRule")
+ apexManifestRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("apexManifestRule")
ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"]))
ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libbar.so")
- mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_"+tc.apexVariant).Rule("ld").Args["libFlags"]
+ mylibLdFlags := ctx.ModuleForTests(t, "mylib", "android_arm64_armv8-a_shared_"+tc.apexVariant).Rule("ld").Args["libFlags"]
ensureContains(t, mylibLdFlags, "libbar/android_arm64_armv8-a_shared_"+tc.shouldLink+"/libbar.so")
for _, ver := range tc.shouldNotLink {
ensureNotContains(t, mylibLdFlags, "libbar/android_arm64_armv8-a_shared_"+ver+"/libbar.so")
}
- mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_"+tc.apexVariant).Rule("cc").Args["cFlags"]
+ mylibCFlags := ctx.ModuleForTests(t, "mylib", "android_arm64_armv8-a_static_"+tc.apexVariant).Rule("cc").Args["cFlags"]
ver := tc.shouldLink
if tc.shouldLink == "current" {
ver = strconv.Itoa(android.FutureApiLevelInt)
@@ -1766,7 +1981,7 @@
apex {
name: "myapex",
key: "myapex.key",
- native_shared_libs: ["mylib", "mylib_shared", "libdl", "libm"],
+ native_shared_libs: ["mylib", "mylib_shared", "libdl", "libm", "libmylib_rs"],
updatable: false,
}
@@ -1785,6 +2000,14 @@
apex_available: [ "myapex" ],
}
+ rust_ffi {
+ name: "libmylib_rs",
+ crate_name: "mylib_rs",
+ shared_libs: ["libvers#27", "libm#impl"],
+ srcs: ["mylib.rs"],
+ apex_available: [ "myapex" ],
+ }
+
cc_library_shared {
name: "mylib_shared",
srcs: ["mylib.cpp"],
@@ -1799,22 +2022,40 @@
stl: "none",
bootstrap: true,
}
+
+ rust_ffi {
+ name: "libbootstrap_rs",
+ srcs: ["mylib.cpp"],
+ crate_name: "bootstrap_rs",
+ bootstrap: true,
+ }
+
+ cc_library {
+ name: "libvers",
+ srcs: ["mylib.cpp"],
+ stl: "none",
+ stubs: { versions: ["27","30"] },
+ }
`)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+ apexRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
- // Ensure that mylib, libm, libdl are included.
+ // Ensure that mylib, libmylib_rs, libm, libdl, libstd.dylib.so (from Rust) are included.
ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
+ ensureContains(t, copyCmds, "image.apex/lib64/libmylib_rs.so")
ensureContains(t, copyCmds, "image.apex/lib64/bionic/libm.so")
ensureContains(t, copyCmds, "image.apex/lib64/bionic/libdl.so")
+ ensureContains(t, copyCmds, "image.apex/lib64/libstd.dylib.so")
- // Ensure that libc is not included (since it has stubs and not listed in native_shared_libs)
+ // Ensure that libc and liblog (from Rust) is not included (since it has stubs and not listed in native_shared_libs)
ensureNotContains(t, copyCmds, "image.apex/lib64/bionic/libc.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/liblog.so")
- mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
- mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"]
- mylibSharedCFlags := ctx.ModuleForTests("mylib_shared", "android_arm64_armv8-a_shared_apex10000").Rule("cc").Args["cFlags"]
+ mylibLdFlags := ctx.ModuleForTests(t, "mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
+ mylibRsFlags := ctx.ModuleForTests(t, "libmylib_rs", "android_arm64_armv8-a_shared_apex10000").Rule("rustc").Args["linkFlags"]
+ mylibCFlags := ctx.ModuleForTests(t, "mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"]
+ mylibSharedCFlags := ctx.ModuleForTests(t, "mylib_shared", "android_arm64_armv8-a_shared_apex10000").Rule("cc").Args["cFlags"]
// For dependency to libc
// Ensure that mylib is linking with the latest version of stubs
@@ -1846,11 +2087,42 @@
ensureContains(t, mylibCFlags, "__LIBDL_API__=27")
ensureContains(t, mylibSharedCFlags, "__LIBDL_API__=27")
+ // Rust checks
+ // For dependency to libc, liblog
+ // Ensure that libmylib_rs is linking with the latest versions of stubs
+ ensureContains(t, mylibRsFlags, "libc/android_arm64_armv8-a_shared_current/libc.so")
+ ensureContains(t, mylibRsFlags, "liblog/android_arm64_armv8-a_shared_current/liblog.so")
+ // ... and not linking to the non-stub (impl) variants
+ ensureNotContains(t, mylibRsFlags, "libc/android_arm64_armv8-a_shared/libc.so")
+ ensureNotContains(t, mylibRsFlags, "liblog/android_arm64_armv8-a_shared/liblog.so")
+
+ // For libm dependency (explicit)
+ // Ensure that mylib is linking with the non-stub (impl) variant
+ ensureContains(t, mylibRsFlags, "libm/android_arm64_armv8-a_shared_apex10000/libm.so")
+ // ... and not linking to the stub variant
+ ensureNotContains(t, mylibRsFlags, "libm/android_arm64_armv8-a_shared_29/libm.so")
+
+ // For dependency to libvers
+ // (We do not use libdl#27 as Rust links the system libs implicitly and does
+ // not currently have a system_shared_libs equivalent to prevent this)
+ // Ensure that mylib is linking with the specified version of stubs
+ ensureContains(t, mylibRsFlags, "libvers/android_arm64_armv8-a_shared_27/libvers.so")
+ // ... and not linking to the other versions of stubs
+ ensureNotContains(t, mylibRsFlags, "libvers/android_arm64_armv8-a_shared_30/libvers.so")
+ // ... and not linking to the non-stub (impl) variant
+ ensureNotContains(t, mylibRsFlags, "libvers/android_arm64_armv8-a_shared_apex10000/libvers.so")
+
// Ensure that libBootstrap is depending on the platform variant of bionic libs
- libFlags := ctx.ModuleForTests("libBootstrap", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"]
+ libFlags := ctx.ModuleForTests(t, "libBootstrap", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"]
ensureContains(t, libFlags, "libc/android_arm64_armv8-a_shared/libc.so")
ensureContains(t, libFlags, "libm/android_arm64_armv8-a_shared/libm.so")
ensureContains(t, libFlags, "libdl/android_arm64_armv8-a_shared/libdl.so")
+
+ // Ensure that libbootstrap_rs is depending on the platform variant of bionic libs
+ libRsFlags := ctx.ModuleForTests(t, "libbootstrap_rs", "android_arm64_armv8-a_shared").Rule("rustc").Args["linkFlags"]
+ ensureContains(t, libRsFlags, "libc/android_arm64_armv8-a_shared/libc.so")
+ ensureContains(t, libRsFlags, "libm/android_arm64_armv8-a_shared/libm.so")
+ ensureContains(t, libRsFlags, "libdl/android_arm64_armv8-a_shared/libdl.so")
}
func TestApexMinSdkVersion_NativeModulesShouldBeBuiltAgainstStubs(t *testing.T) {
@@ -1900,7 +2172,7 @@
cc_library {
name: "liba",
- shared_libs: ["libz"],
+ shared_libs: ["libz", "libz_rs"],
system_shared_libs: [],
stl: "none",
apex_available: [
@@ -1918,28 +2190,46 @@
versions: ["28", "30"],
},
}
+
+ rust_ffi {
+ name: "libz_rs",
+ crate_name: "z_rs",
+ srcs: ["foo.rs"],
+ stubs: {
+ versions: ["28", "30"],
+ },
+ }
`)
expectLink := func(from, from_variant, to, to_variant string) {
- ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
+ ldArgs := ctx.ModuleForTests(t, from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
expectNoLink := func(from, from_variant, to, to_variant string) {
- ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
+ ldArgs := ctx.ModuleForTests(t, from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
// platform liba is linked to non-stub version
expectLink("liba", "shared", "libz", "shared")
+ expectLink("liba", "shared", "unstripped/libz_rs", "shared")
// liba in myapex is linked to current
expectLink("liba", "shared_apex29", "libz", "shared_current")
expectNoLink("liba", "shared_apex29", "libz", "shared_30")
expectNoLink("liba", "shared_apex29", "libz", "shared_28")
expectNoLink("liba", "shared_apex29", "libz", "shared")
+ expectLink("liba", "shared_apex29", "unstripped/libz_rs", "shared_current")
+ expectNoLink("liba", "shared_apex29", "unstripped/libz_rs", "shared_30")
+ expectNoLink("liba", "shared_apex29", "unstripped/libz_rs", "shared_28")
+ expectNoLink("liba", "shared_apex29", "unstripped/libz_rs", "shared")
// liba in otherapex is linked to current
expectLink("liba", "shared_apex30", "libz", "shared_current")
expectNoLink("liba", "shared_apex30", "libz", "shared_30")
expectNoLink("liba", "shared_apex30", "libz", "shared_28")
expectNoLink("liba", "shared_apex30", "libz", "shared")
+ expectLink("liba", "shared_apex30", "unstripped/libz_rs", "shared_current")
+ expectNoLink("liba", "shared_apex30", "unstripped/libz_rs", "shared_30")
+ expectNoLink("liba", "shared_apex30", "unstripped/libz_rs", "shared_28")
+ expectNoLink("liba", "shared_apex30", "unstripped/libz_rs", "shared")
}
func TestApexMinSdkVersion_SupportsCodeNames(t *testing.T) {
@@ -1982,11 +2272,11 @@
)
expectLink := func(from, from_variant, to, to_variant string) {
- ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
+ ldArgs := ctx.ModuleForTests(t, from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
expectNoLink := func(from, from_variant, to, to_variant string) {
- ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
+ ldArgs := ctx.ModuleForTests(t, from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
expectLink("libx", "shared_apex10000", "libz", "shared_current")
@@ -2062,11 +2352,11 @@
`)
expectLink := func(from, from_variant, to, to_variant string) {
- ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
+ ldArgs := ctx.ModuleForTests(t, from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
expectNoLink := func(from, from_variant, to, to_variant string) {
- ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
+ ldArgs := ctx.ModuleForTests(t, from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
expectLink("libx", "shared_apex10000", "libz", "shared_current")
@@ -2110,14 +2400,14 @@
vendorVariant := "android_vendor_arm64_armv8-a"
- mylib := ctx.ModuleForTests("mylib", vendorVariant+"_shared_apex29")
+ mylib := ctx.ModuleForTests(t, "mylib", vendorVariant+"_shared_apex29")
// Ensure that mylib links with "current" LLNDK
libFlags := names(mylib.Rule("ld").Args["libFlags"])
ensureListContains(t, libFlags, "out/soong/.intermediates/libbar/"+vendorVariant+"_shared/libbar.so")
// Ensure that mylib is targeting 29
- ccRule := ctx.ModuleForTests("mylib", vendorVariant+"_static_apex29").Output("obj/mylib.o")
+ ccRule := ctx.ModuleForTests(t, "mylib", vendorVariant+"_static_apex29").Output("obj/mylib.o")
ensureContains(t, ccRule.Args["cFlags"], "-target aarch64-linux-android29")
// Ensure that the correct variant of crtbegin_so is used.
@@ -2125,11 +2415,91 @@
ensureContains(t, crtBegin, "out/soong/.intermediates/"+cc.DefaultCcCommonTestModulesDir+"crtbegin_so/"+vendorVariant+"_apex29/crtbegin_so.o")
// Ensure that the crtbegin_so used by the APEX is targeting 29
- cflags := ctx.ModuleForTests("crtbegin_so", vendorVariant+"_apex29").Rule("cc").Args["cFlags"]
+ cflags := ctx.ModuleForTests(t, "crtbegin_so", vendorVariant+"_apex29").Rule("cc").Args["cFlags"]
android.AssertStringDoesContain(t, "cflags", cflags, "-target aarch64-linux-android29")
}
-func TestTrackAllowedDeps(t *testing.T) {
+func TestTrackAllowedDepsForAndroidApex(t *testing.T) {
+ t.Parallel()
+ ctx := testApex(t, `
+ apex {
+ name: "com.android.myapex",
+ key: "myapex.key",
+ updatable: true,
+ native_shared_libs: [
+ "mylib",
+ "yourlib",
+ ],
+ min_sdk_version: "29",
+ }
+
+ apex {
+ name: "myapex2",
+ key: "myapex.key",
+ updatable: false,
+ native_shared_libs: ["yourlib"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "mylib",
+ srcs: ["mylib.cpp"],
+ shared_libs: ["libbar", "libbar_rs"],
+ min_sdk_version: "29",
+ apex_available: ["com.android.myapex"],
+ }
+
+ cc_library {
+ name: "libbar",
+ stubs: { versions: ["29", "30"] },
+ }
+
+ rust_ffi {
+ name: "libbar_rs",
+ crate_name: "bar_rs",
+ srcs: ["bar.rs"],
+ stubs: { versions: ["29", "30"] },
+ }
+
+ cc_library {
+ name: "yourlib",
+ srcs: ["mylib.cpp"],
+ min_sdk_version: "29",
+ apex_available: ["com.android.myapex", "myapex2", "//apex_available:platform"],
+ }
+ `, withFiles(android.MockFS{
+ "packages/modules/common/build/allowed_deps.txt": nil,
+ }),
+ android.FixtureMergeMockFs(android.MockFS{
+ "system/sepolicy/apex/com.android.myapex-file_contexts": nil,
+ }))
+
+ depsinfo := ctx.SingletonForTests(t, "apex_depsinfo_singleton")
+ inputs := depsinfo.Rule("generateApexDepsInfoFilesRule").BuildParams.Inputs.Strings()
+ android.AssertStringListContains(t, "updatable com.android.myapex should generate depsinfo file", inputs,
+ "out/soong/.intermediates/com.android.myapex/android_common_com.android.myapex/depsinfo/flatlist.txt")
+ android.AssertStringListDoesNotContain(t, "non-updatable myapex2 should not generate depsinfo file", inputs,
+ "out/soong/.intermediates/myapex2/android_common_myapex2/depsinfo/flatlist.txt")
+
+ myapex := ctx.ModuleForTests(t, "com.android.myapex", "android_common_com.android.myapex")
+ flatlist := strings.Split(android.ContentFromFileRuleForTests(t, ctx,
+ myapex.Output("depsinfo/flatlist.txt")), "\n")
+ android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep",
+ flatlist, "libbar(minSdkVersion:(no version)) (external)")
+ android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep",
+ flatlist, "libbar_rs(minSdkVersion:(no version)) (external)")
+ android.AssertStringListDoesNotContain(t, "do not track if not available for platform",
+ flatlist, "mylib:(minSdkVersion:29)")
+ android.AssertStringListContains(t, "track platform-available lib",
+ flatlist, "yourlib(minSdkVersion:29)")
+}
+
+func TestNotTrackAllowedDepsForNonAndroidApex(t *testing.T) {
t.Parallel()
ctx := testApex(t, `
apex {
@@ -2179,176 +2549,19 @@
"packages/modules/common/build/allowed_deps.txt": nil,
}))
- depsinfo := ctx.SingletonForTests("apex_depsinfo_singleton")
+ depsinfo := ctx.SingletonForTests(t, "apex_depsinfo_singleton")
inputs := depsinfo.Rule("generateApexDepsInfoFilesRule").BuildParams.Inputs.Strings()
- android.AssertStringListContains(t, "updatable myapex should generate depsinfo file", inputs,
+ android.AssertStringListDoesNotContain(t, "updatable myapex should generate depsinfo file", inputs,
"out/soong/.intermediates/myapex/android_common_myapex/depsinfo/flatlist.txt")
android.AssertStringListDoesNotContain(t, "non-updatable myapex2 should not generate depsinfo file", inputs,
"out/soong/.intermediates/myapex2/android_common_myapex2/depsinfo/flatlist.txt")
-
- myapex := ctx.ModuleForTests("myapex", "android_common_myapex")
- flatlist := strings.Split(android.ContentFromFileRuleForTests(t, ctx,
- myapex.Output("depsinfo/flatlist.txt")), "\n")
- android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep",
- flatlist, "libbar(minSdkVersion:(no version)) (external)")
- android.AssertStringListDoesNotContain(t, "do not track if not available for platform",
- flatlist, "mylib:(minSdkVersion:29)")
- android.AssertStringListContains(t, "track platform-available lib",
- flatlist, "yourlib(minSdkVersion:29)")
-}
-
-func TestTrackCustomAllowedDepsInvalidDefaultTxt(t *testing.T) {
- t.Parallel()
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: true,
- native_shared_libs: [
- "mylib",
- "yourlib",
- ],
- min_sdk_version: "29",
- }
-
- apex {
- name: "myapex2",
- key: "myapex.key",
- updatable: false,
- native_shared_libs: ["yourlib"],
- }
-
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
-
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- shared_libs: ["libbar"],
- min_sdk_version: "29",
- apex_available: ["myapex"],
- }
-
- cc_library {
- name: "libbar",
- stubs: { versions: ["29", "30"] },
- }
-
- cc_library {
- name: "yourlib",
- srcs: ["mylib.cpp"],
- min_sdk_version: "29",
- apex_available: ["myapex", "myapex2", "//apex_available:platform"],
- }
- `, withFiles(android.MockFS{
- "packages/modules/common/build/custom_allowed_deps.txt": nil,
- }),
- android.FixtureModifyProductVariables(
- func(variables android.FixtureProductVariables) {
- variables.ExtraAllowedDepsTxt = proptools.StringPtr("packages/modules/common/build/custom_allowed_deps.txt")
- },
- ))
-
- depsinfo := ctx.SingletonForTests("apex_depsinfo_singleton")
- inputs := depsinfo.Rule("generateApexDepsInfoFilesRule").BuildParams.Inputs.Strings()
- android.AssertStringListContains(t, "updatable myapex should generate depsinfo file", inputs,
- "out/soong/.intermediates/myapex/android_common_myapex/depsinfo/flatlist.txt")
- android.AssertStringListDoesNotContain(t, "non-updatable myapex2 should not generate depsinfo file", inputs,
- "out/soong/.intermediates/myapex2/android_common_myapex2/depsinfo/flatlist.txt")
-
- myapex := ctx.ModuleForTests("myapex", "android_common_myapex")
- flatlist := strings.Split(android.ContentFromFileRuleForTests(t, ctx,
- myapex.Output("depsinfo/flatlist.txt")), "\n")
- android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep",
- flatlist, "libbar(minSdkVersion:(no version)) (external)")
- android.AssertStringListDoesNotContain(t, "do not track if not available for platform",
- flatlist, "mylib:(minSdkVersion:29)")
- android.AssertStringListContains(t, "track platform-available lib",
- flatlist, "yourlib(minSdkVersion:29)")
-}
-
-func TestTrackCustomAllowedDepsWithDefaultTxt(t *testing.T) {
- t.Parallel()
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: true,
- native_shared_libs: [
- "mylib",
- "yourlib",
- ],
- min_sdk_version: "29",
- }
-
- apex {
- name: "myapex2",
- key: "myapex.key",
- updatable: false,
- native_shared_libs: ["yourlib"],
- }
-
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
-
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- shared_libs: ["libbar"],
- min_sdk_version: "29",
- apex_available: ["myapex"],
- }
-
- cc_library {
- name: "libbar",
- stubs: { versions: ["29", "30"] },
- }
-
- cc_library {
- name: "yourlib",
- srcs: ["mylib.cpp"],
- min_sdk_version: "29",
- apex_available: ["myapex", "myapex2", "//apex_available:platform"],
- }
- `, withFiles(android.MockFS{
- "packages/modules/common/build/custom_allowed_deps.txt": nil,
- "packages/modules/common/build/allowed_deps.txt": nil,
- }),
- android.FixtureModifyProductVariables(
- func(variables android.FixtureProductVariables) {
- variables.ExtraAllowedDepsTxt = proptools.StringPtr("packages/modules/common/build/custom_allowed_deps.txt")
- },
- ))
-
- depsinfo := ctx.SingletonForTests("apex_depsinfo_singleton")
- inputs := depsinfo.Rule("generateApexDepsInfoFilesRule").BuildParams.Inputs.Strings()
- android.AssertStringListContains(t, "updatable myapex should generate depsinfo file", inputs,
- "out/soong/.intermediates/myapex/android_common_myapex/depsinfo/flatlist.txt")
- android.AssertStringListDoesNotContain(t, "non-updatable myapex2 should not generate depsinfo file", inputs,
- "out/soong/.intermediates/myapex2/android_common_myapex2/depsinfo/flatlist.txt")
-
- myapex := ctx.ModuleForTests("myapex", "android_common_myapex")
- flatlist := strings.Split(android.ContentFromFileRuleForTests(t, ctx,
- myapex.Output("depsinfo/flatlist.txt")), "\n")
- android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep",
- flatlist, "libbar(minSdkVersion:(no version)) (external)")
- android.AssertStringListDoesNotContain(t, "do not track if not available for platform",
- flatlist, "mylib:(minSdkVersion:29)")
- android.AssertStringListContains(t, "track platform-available lib",
- flatlist, "yourlib(minSdkVersion:29)")
}
func TestTrackAllowedDeps_SkipWithoutAllowedDepsTxt(t *testing.T) {
t.Parallel()
ctx := testApex(t, `
apex {
- name: "myapex",
+ name: "com.android.myapex",
key: "myapex.key",
updatable: true,
min_sdk_version: "29",
@@ -2359,8 +2572,11 @@
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
- `)
- depsinfo := ctx.SingletonForTests("apex_depsinfo_singleton")
+ `,
+ android.FixtureMergeMockFs(android.MockFS{
+ "system/sepolicy/apex/com.android.myapex-file_contexts": nil,
+ }))
+ depsinfo := ctx.SingletonForTests(t, "apex_depsinfo_singleton")
if nil != depsinfo.MaybeRule("generateApexDepsInfoFilesRule").Output {
t.Error("apex_depsinfo_singleton shouldn't run when allowed_deps.txt doesn't exist")
}
@@ -2372,7 +2588,7 @@
apex {
name: "myapex",
key: "myapex.key",
- native_shared_libs: ["libx"],
+ native_shared_libs: ["libx", "libx_rs"],
updatable: false,
}
@@ -2392,9 +2608,19 @@
},
}
+ rust_ffi {
+ name: "libx_rs",
+ crate_name: "x_rs",
+ srcs: ["x.rs"],
+ apex_available: [ "myapex" ],
+ stubs: {
+ versions: ["1", "2"],
+ },
+ }
+
cc_library {
name: "libz",
- shared_libs: ["libx"],
+ shared_libs: ["libx", "libx_rs",],
system_shared_libs: [],
stl: "none",
}
@@ -2402,16 +2628,18 @@
expectLink := func(from, from_variant, to, to_variant string) {
t.Helper()
- ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
+ ldArgs := ctx.ModuleForTests(t, from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
expectNoLink := func(from, from_variant, to, to_variant string) {
t.Helper()
- ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
+ ldArgs := ctx.ModuleForTests(t, from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
expectLink("libz", "shared", "libx", "shared_current")
expectNoLink("libz", "shared", "libx", "shared_2")
+ expectLink("libz", "shared", "unstripped/libx_rs", "shared_current")
+ expectNoLink("libz", "shared", "unstripped/libx_rs", "shared_2")
expectNoLink("libz", "shared", "libz", "shared_1")
expectNoLink("libz", "shared", "libz", "shared")
}
@@ -2440,11 +2668,18 @@
cc_library {
name: "libx",
- shared_libs: ["libbar"],
+ shared_libs: ["libbar", "libbar_rs"],
apex_available: [ "myapex" ],
min_sdk_version: "29",
}
+ rust_ffi {
+ name: "libbar_rs",
+ crate_name: "bar_rs",
+ srcs: ["bar.rs"],
+ stubs: { versions: ["29", "30"] },
+ }
+
cc_library {
name: "libbar",
stubs: {
@@ -2455,11 +2690,12 @@
prepareForTestWithSantitizeHwaddress,
)
expectLink := func(from, from_variant, to, to_variant string) {
- ld := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld")
+ ld := ctx.ModuleForTests(t, from, "android_arm64_armv8-a_"+from_variant).Rule("ld")
libFlags := ld.Args["libFlags"]
ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
expectLink("libx", "shared_hwasan_apex29", "libbar", "shared_current")
+ expectLink("libx", "shared_hwasan_apex29", "unstripped/libbar_rs", "shared_current")
}
func TestQTargetApexUsesStaticUnwinder(t *testing.T) {
@@ -2486,10 +2722,10 @@
`)
// ensure apex variant of c++ is linked with static unwinder
- cm := ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared_apex29").Module().(*cc.Module)
+ cm := ctx.ModuleForTests(t, "libc++", "android_arm64_armv8-a_shared_apex29").Module().(*cc.Module)
ensureListContains(t, cm.Properties.AndroidMkStaticLibs, "libunwind")
// note that platform variant is not.
- cm = ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared").Module().(*cc.Module)
+ cm = ctx.ModuleForTests(t, "libc++", "android_arm64_armv8-a_shared").Module().(*cc.Module)
ensureListNotContains(t, cm.Properties.AndroidMkStaticLibs, "libunwind")
}
@@ -2982,7 +3218,7 @@
}
`)
expectLink := func(from, from_variant, to, to_variant string) {
- ld := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld")
+ ld := ctx.ModuleForTests(t, from, "android_arm64_armv8-a_"+from_variant).Rule("ld")
libFlags := ld.Args["libFlags"]
ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
@@ -3057,7 +3293,7 @@
`, withSAsActiveCodeNames)
// ensure libfoo is linked with current version of libbar stub
- libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_apex10000")
+ libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared_apex10000")
libFlags := libfoo.Rule("ld").Args["libFlags"]
ensureContains(t, libFlags, "android_arm64_armv8-a_shared_current/libbar.so")
}
@@ -3113,7 +3349,7 @@
}
`)
- generateFsRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("generateFsConfig")
+ generateFsRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("generateFsConfig")
cmd := generateFsRule.RuleParams.Command
// Ensure that the subdirectories are all listed
@@ -3227,7 +3463,7 @@
"lib64/libc++.so",
})
- apexBundle := result.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle)
+ apexBundle := result.ModuleForTests(t, "myapex", "android_common_myapex").Module().(*apexBundle)
data := android.AndroidMkDataForTest(t, result.TestContext, apexBundle)
name := apexBundle.BaseModuleName()
prefix := "TARGET_"
@@ -3237,7 +3473,7 @@
installPath := "out/target/product/test_device/vendor/apex"
ensureContains(t, androidMk, "LOCAL_MODULE_PATH := "+installPath)
- apexManifestRule := result.ModuleForTests("myapex", "android_common_myapex").Rule("apexManifestRule")
+ apexManifestRule := result.ModuleForTests(t, "myapex", "android_common_myapex").Rule("apexManifestRule")
requireNativeLibs := names(apexManifestRule.Args["requireNativeLibs"])
ensureListNotContains(t, requireNativeLibs, ":vndk")
}
@@ -3268,7 +3504,7 @@
`)
cflags := strings.Fields(
- ctx.ModuleForTests("foo", "android_product_arm64_armv8-a_apex10000").Rule("cc").Args["cFlags"])
+ ctx.ModuleForTests(t, "foo", "android_product_arm64_armv8-a_apex10000").Rule("cc").Args["cFlags"])
ensureListContains(t, cflags, "-D__ANDROID_VNDK__")
ensureListContains(t, cflags, "-D__ANDROID_APEX__")
ensureListContains(t, cflags, "-D__ANDROID_PRODUCT__")
@@ -3337,7 +3573,7 @@
}
`)
- apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle)
+ apexBundle := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Module().(*apexBundle)
data := android.AndroidMkDataForTest(t, ctx, apexBundle)
name := apexBundle.BaseModuleName()
prefix := "TARGET_"
@@ -3366,7 +3602,7 @@
}
`)
- apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle)
+ apexBundle := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Module().(*apexBundle)
data := android.AndroidMkDataForTest(t, ctx, apexBundle)
name := apexBundle.BaseModuleName()
prefix := "TARGET_"
@@ -3404,20 +3640,31 @@
apex_available: ["myapex"],
}
+ rust_ffi {
+ name: "libmylib_rs",
+ crate_name: "mylib_rs",
+ srcs: ["mylib.rs"],
+ stubs: {
+ versions: ["1", "2", "3"],
+ },
+ apex_available: ["myapex"],
+ }
+
cc_binary {
name: "not_in_apex",
srcs: ["mylib.cpp"],
- static_libs: ["mylib"],
+ static_libs: ["mylib", "libmylib_rs"],
static_executable: true,
system_shared_libs: [],
stl: "none",
}
`)
- ldFlags := ctx.ModuleForTests("not_in_apex", "android_arm64_armv8-a").Rule("ld").Args["libFlags"]
+ ldFlags := ctx.ModuleForTests(t, "not_in_apex", "android_arm64_armv8-a").Rule("ld").Args["libFlags"]
// Ensure that not_in_apex is linking with the static variant of mylib
ensureContains(t, ldFlags, "mylib/android_arm64_armv8-a_static/mylib.a")
+ ensureContains(t, ldFlags, "generated_rust_staticlib/librustlibs.a")
}
func TestKeys(t *testing.T) {
@@ -3459,7 +3706,7 @@
`)
// check the APEX keys
- keys := ctx.ModuleForTests("myapex.key", "android_common").Module().(*apexKey)
+ keys := ctx.ModuleForTests(t, "myapex.key", "android_common").Module().(*apexKey)
if keys.publicKeyFile.String() != "vendor/foo/devkeys/testkey.avbpubkey" {
t.Errorf("public key %q is not %q", keys.publicKeyFile.String(),
@@ -3471,7 +3718,7 @@
}
// check the APK certs. It should be overridden to myapex.certificate.override
- certs := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest").Rule("signapk").Args["certificates"]
+ certs := ctx.ModuleForTests(t, "myapex_keytest", "android_common_myapex_keytest").Rule("signapk").Args["certificates"]
if certs != "testkey.override.x509.pem testkey.override.pk8" {
t.Errorf("cert and private key %q are not %q", certs,
"testkey.override.509.pem testkey.override.pk8")
@@ -3493,7 +3740,7 @@
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}`)
- rule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("signapk")
+ rule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("signapk")
expected := "vendor/foo/devkeys/test.x509.pem vendor/foo/devkeys/test.pk8"
if actual := rule.Args["certificates"]; actual != expected {
t.Errorf("certificates should be %q, not %q", expected, actual)
@@ -3517,7 +3764,7 @@
name: "myapex.certificate.override",
certificate: "testkey.override",
}`)
- rule := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest").Rule("signapk")
+ rule := ctx.ModuleForTests(t, "myapex_keytest", "android_common_myapex_keytest").Rule("signapk")
expected := "testkey.override.x509.pem testkey.override.pk8"
if actual := rule.Args["certificates"]; actual != expected {
t.Errorf("certificates should be %q, not %q", expected, actual)
@@ -3541,7 +3788,7 @@
name: "myapex.certificate",
certificate: "testkey",
}`)
- rule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("signapk")
+ rule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("signapk")
expected := "testkey.x509.pem testkey.pk8"
if actual := rule.Args["certificates"]; actual != expected {
t.Errorf("certificates should be %q, not %q", expected, actual)
@@ -3566,7 +3813,7 @@
name: "myapex.certificate.override",
certificate: "testkey.override",
}`)
- rule := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest").Rule("signapk")
+ rule := ctx.ModuleForTests(t, "myapex_keytest", "android_common_myapex_keytest").Rule("signapk")
expected := "testkey.override.x509.pem testkey.override.pk8"
if actual := rule.Args["certificates"]; actual != expected {
t.Errorf("certificates should be %q, not %q", expected, actual)
@@ -3590,7 +3837,7 @@
"vendor/foo/devkeys/testkey.x509.pem": nil,
}.AddToFixture(),
)
- rule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("signapk")
+ rule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("signapk")
expected := "vendor/foo/devkeys/testkey.x509.pem vendor/foo/devkeys/testkey.pk8"
if actual := rule.Args["certificates"]; actual != expected {
t.Errorf("certificates should be %q, not %q", expected, actual)
@@ -3615,7 +3862,7 @@
name: "myapex.certificate.override",
certificate: "testkey.override",
}`)
- rule := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest").Rule("signapk")
+ rule := ctx.ModuleForTests(t, "myapex_keytest", "android_common_myapex_keytest").Rule("signapk")
expected := "testkey.override.x509.pem testkey.override.pk8"
if actual := rule.Args["certificates"]; actual != expected {
t.Errorf("certificates should be %q, not %q", expected, actual)
@@ -3686,34 +3933,34 @@
`)
// non-APEX variant does not have __ANDROID_APEX__ defined
- mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
+ mylibCFlags := ctx.ModuleForTests(t, "mylib", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
// APEX variant has __ANDROID_APEX__ and __ANDROID_APEX__ defined
- mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"]
+ mylibCFlags = ctx.ModuleForTests(t, "mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"]
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
// APEX variant has __ANDROID_APEX__ and __ANDROID_APEX__ defined
- mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex29").Rule("cc").Args["cFlags"]
+ mylibCFlags = ctx.ModuleForTests(t, "mylib", "android_arm64_armv8-a_static_apex29").Rule("cc").Args["cFlags"]
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
// When a cc_library sets use_apex_name_macro: true each apex gets a unique variant and
// each variant defines additional macros to distinguish which apex variant it is built for
// non-APEX variant does not have __ANDROID_APEX__ defined
- mylibCFlags = ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
+ mylibCFlags = ctx.ModuleForTests(t, "mylib3", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
// recovery variant does not set __ANDROID_APEX__
- mylibCFlags = ctx.ModuleForTests("mylib3", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
+ mylibCFlags = ctx.ModuleForTests(t, "mylib3", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
// non-APEX variant does not have __ANDROID_APEX__ defined
- mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
+ mylibCFlags = ctx.ModuleForTests(t, "mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
// recovery variant does not set __ANDROID_APEX__
- mylibCFlags = ctx.ModuleForTests("mylib2", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
+ mylibCFlags = ctx.ModuleForTests(t, "mylib2", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
}
@@ -3763,7 +4010,7 @@
}
`)
- cFlags := ctx.ModuleForTests("otherlib", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
+ cFlags := ctx.ModuleForTests(t, "otherlib", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
// Ensure that the include path of the header lib is exported to 'otherlib'
ensureContains(t, cFlags, "-Imy_include")
@@ -3795,7 +4042,7 @@
func getFiles(t *testing.T, ctx *android.TestContext, moduleName, variant string) []fileInApex {
t.Helper()
- module := ctx.ModuleForTests(moduleName, variant)
+ module := ctx.ModuleForTests(t, moduleName, variant)
apexRule := module.MaybeRule("apexRule")
apexDir := "/image.apex/"
copyCmds := apexRule.Args["copy_commands"]
@@ -3886,7 +4133,7 @@
}
func ensureExactDeapexedContents(t *testing.T, ctx *android.TestContext, moduleName string, variant string, files []string) {
- deapexer := ctx.ModuleForTests(moduleName, variant).Description("deapex")
+ deapexer := ctx.ModuleForTests(t, moduleName, variant).Description("deapex")
outputs := make([]string, 0, len(deapexer.ImplicitOutputs)+1)
if deapexer.Output != nil {
outputs = append(outputs, deapexer.Output.String())
@@ -4015,7 +4262,7 @@
}`+vndkLibrariesTxtFiles("28", "29"))
assertApexName := func(expected, moduleName string) {
- module := ctx.ModuleForTests(moduleName, "android_common")
+ module := ctx.ModuleForTests(t, moduleName, "android_common")
apexManifestRule := module.Rule("apexManifestRule")
ensureContains(t, apexManifestRule.Args["opt"], "-v name "+expected)
}
@@ -4243,25 +4490,25 @@
var apexManifestRule android.TestingBuildParams
var provideNativeLibs, requireNativeLibs []string
- apexManifestRule = ctx.ModuleForTests("myapex_nodep", "android_common_myapex_nodep").Rule("apexManifestRule")
+ apexManifestRule = ctx.ModuleForTests(t, "myapex_nodep", "android_common_myapex_nodep").Rule("apexManifestRule")
provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"])
requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"])
ensureListEmpty(t, provideNativeLibs)
ensureListEmpty(t, requireNativeLibs)
- apexManifestRule = ctx.ModuleForTests("myapex_dep", "android_common_myapex_dep").Rule("apexManifestRule")
+ apexManifestRule = ctx.ModuleForTests(t, "myapex_dep", "android_common_myapex_dep").Rule("apexManifestRule")
provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"])
requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"])
ensureListEmpty(t, provideNativeLibs)
ensureListContains(t, requireNativeLibs, "libfoo.so")
- apexManifestRule = ctx.ModuleForTests("myapex_provider", "android_common_myapex_provider").Rule("apexManifestRule")
+ apexManifestRule = ctx.ModuleForTests(t, "myapex_provider", "android_common_myapex_provider").Rule("apexManifestRule")
provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"])
requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"])
ensureListContains(t, provideNativeLibs, "libfoo.so")
ensureListEmpty(t, requireNativeLibs)
- apexManifestRule = ctx.ModuleForTests("myapex_selfcontained", "android_common_myapex_selfcontained").Rule("apexManifestRule")
+ apexManifestRule = ctx.ModuleForTests(t, "myapex_selfcontained", "android_common_myapex_selfcontained").Rule("apexManifestRule")
provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"])
requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"])
ensureListContains(t, provideNativeLibs, "libbar.so")
@@ -4298,7 +4545,7 @@
"OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION": "1234",
}))
- module := ctx.ModuleForTests("myapex", "android_common_myapex")
+ module := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
apexManifestRule := module.Rule("apexManifestRule")
ensureContains(t, apexManifestRule.Args["default_version"], "1234")
}
@@ -4362,7 +4609,7 @@
}
`, testCase.compileMultiLibProp),
)
- module := ctx.ModuleForTests("myapex", "android_common_myapex")
+ module := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
apexRule := module.Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
for _, containedLib := range testCase.containedLibs {
@@ -4402,7 +4649,7 @@
}
`)
- module := ctx.ModuleForTests("myapex", "android_common_myapex")
+ module := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
apexRule := module.Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
@@ -4422,7 +4669,7 @@
// Ensure that the platform variant ends with _shared
ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared")
- if !ctx.ModuleForTests("mylib_common", "android_arm64_armv8-a_shared_apex10000").Module().(*cc.Module).InAnyApex() {
+ if !ctx.ModuleForTests(t, "mylib_common", "android_arm64_armv8-a_shared_apex10000").Module().(*cc.Module).InAnyApex() {
t.Log("Found mylib_common not in any apex!")
t.Fail()
}
@@ -4457,7 +4704,7 @@
}
`)
- module := ctx.ModuleForTests("myapex", "android_common_myapex")
+ module := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
apexRule := module.Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
@@ -4531,7 +4778,7 @@
ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{
"bin/mybin",
})
- apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexManifestRule")
+ apexManifestRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("apexManifestRule")
android.AssertStringEquals(t, "should require libz", apexManifestRule.Args["requireNativeLibs"], "libz.so")
}
// libz doesn't provide stubs for vendor variant.
@@ -4540,7 +4787,7 @@
"bin/mybin",
"lib64/libz.so",
})
- apexManifestRule := ctx.ModuleForTests("myvendorapex", "android_common_myvendorapex").Rule("apexManifestRule")
+ apexManifestRule := ctx.ModuleForTests(t, "myvendorapex", "android_common_myvendorapex").Rule("apexManifestRule")
android.AssertStringEquals(t, "should not require libz", apexManifestRule.Args["requireNativeLibs"], "")
}
}
@@ -4615,7 +4862,7 @@
}
`)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+ apexRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
// Ensure that main rule creates an output
@@ -4700,7 +4947,7 @@
}
`)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+ apexRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
// Ensure that apex variant is created for the direct dep
@@ -4738,7 +4985,7 @@
}
`)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+ apexRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
ensureContains(t, copyCmds, "image.apex/bin/script/myscript.sh")
@@ -4774,7 +5021,7 @@
}
`)
- apex := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle)
+ apex := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Module().(*apexBundle)
expected := "out/target/product/test_device/" + tc.partition + "/apex"
actual := apex.installDir.RelativeToTop().String()
if actual != expected {
@@ -4799,7 +5046,7 @@
private_key: "testkey.pem",
}
`)
- module := ctx.ModuleForTests("myapex", "android_common_myapex")
+ module := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
rule := module.Output("file_contexts")
ensureContains(t, rule.RuleParams.Command, "cat system/sepolicy/apex/myapex-file_contexts")
}
@@ -4859,7 +5106,7 @@
`, withFiles(map[string][]byte{
"product_specific_file_contexts": nil,
}))
- module := ctx.ModuleForTests("myapex", "android_common_myapex")
+ module := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
rule := module.Output("file_contexts")
ensureContains(t, rule.RuleParams.Command, "cat product_specific_file_contexts")
}
@@ -4888,7 +5135,7 @@
`, withFiles(map[string][]byte{
"product_specific_file_contexts": nil,
}))
- module := ctx.ModuleForTests("myapex", "android_common_myapex")
+ module := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
rule := module.Output("file_contexts")
ensureContains(t, rule.RuleParams.Command, "cat product_specific_file_contexts")
}
@@ -4914,7 +5161,7 @@
}
`)
- apex_key := ctx.ModuleForTests("myapex.key", "android_common").Module().(*apexKey)
+ apex_key := ctx.ModuleForTests(t, "myapex.key", "android_common").Module().(*apexKey)
expected_pubkey := "testkey2.avbpubkey"
actual_pubkey := apex_key.publicKeyFile.String()
if actual_pubkey != expected_pubkey {
@@ -4943,7 +5190,7 @@
}
`)
- testingModule := ctx.ModuleForTests("myapex", "android_common_myapex")
+ testingModule := ctx.ModuleForTests(t, "myapex", "android_common_prebuilt_myapex")
prebuilt := testingModule.Module().(*Prebuilt)
expectedInput := "myapex-arm64.apex"
@@ -4964,7 +5211,7 @@
func TestPrebuiltMissingSrc(t *testing.T) {
t.Parallel()
- testApexError(t, `module "myapex" variant "android_common_myapex".*: prebuilt_apex does not support "arm64_armv8-a"`, `
+ testApexError(t, `module "myapex" variant "android_common_prebuilt_myapex".*: prebuilt_apex does not support "arm64_armv8-a"`, `
prebuilt_apex {
name: "myapex",
}
@@ -4981,7 +5228,7 @@
}
`)
- testingModule := ctx.ModuleForTests("myapex", "android_common_myapex")
+ testingModule := ctx.ModuleForTests(t, "myapex", "android_common_prebuilt_myapex")
p := testingModule.Module().(*Prebuilt)
expected := "notmyapex.apex"
@@ -5004,7 +5251,7 @@
set: "company-myapex.apks",
filename: "com.company.android.myapex.apex"
}
- `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex")
+ `).ModuleForTests(t, "com.company.android.myapex", "android_common_prebuilt_com.android.myapex")
testApex(t, `
apex_set {
@@ -5013,7 +5260,7 @@
set: "company-myapex.apks",
filename: "com.company.android.myapex.capex"
}
- `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex")
+ `).ModuleForTests(t, "com.company.android.myapex", "android_common_prebuilt_com.android.myapex")
testApexError(t, `filename should end in .apex or .capex for apex_set`, `
apex_set {
@@ -5037,7 +5284,7 @@
}
`)
- testingModule := ctx.ModuleForTests("myapex.prebuilt", "android_common_myapex.prebuilt")
+ testingModule := ctx.ModuleForTests(t, "myapex.prebuilt", "android_common_prebuilt_myapex.prebuilt")
p := testingModule.Module().(*Prebuilt)
expected := []string{"myapex"}
@@ -5060,7 +5307,7 @@
apex_name: "com.android.myapex",
src: "company-myapex-arm.apex",
}
- `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex")
+ `).ModuleForTests(t, "com.company.android.myapex", "android_common_prebuilt_com.android.myapex")
testApex(t, `
apex_set {
@@ -5068,7 +5315,7 @@
apex_name: "com.android.myapex",
set: "company-myapex.apks",
}
- `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex")
+ `).ModuleForTests(t, "com.company.android.myapex", "android_common_prebuilt_com.android.myapex")
}
func TestPrebuiltApexNameWithPlatformBootclasspath(t *testing.T) {
@@ -5094,6 +5341,12 @@
exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
}
+ prebuilt_apex {
+ name: "com.android.art",
+ src: "com.android.art-arm.apex",
+ exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
+ }
+
prebuilt_bootclasspath_fragment {
name: "art-bootclasspath-fragment",
image_name: "art",
@@ -5147,7 +5400,7 @@
checkHiddenAPIIndexFromClassesInputs := func(t *testing.T, ctx *android.TestContext, expectedIntermediateInputs string) {
t.Helper()
- platformBootclasspath := ctx.ModuleForTests("platform-bootclasspath", "android_common")
+ platformBootclasspath := ctx.ModuleForTests(t, "platform-bootclasspath", "android_common")
var rule android.TestingBuildParams
rule = platformBootclasspath.Output("hiddenapi-monolithic/index-from-classes.csv")
@@ -5156,7 +5409,7 @@
checkHiddenAPIIndexFromFlagsInputs := func(t *testing.T, ctx *android.TestContext, expectedIntermediateInputs string) {
t.Helper()
- platformBootclasspath := ctx.ModuleForTests("platform-bootclasspath", "android_common")
+ platformBootclasspath := ctx.ModuleForTests(t, "platform-bootclasspath", "android_common")
var rule android.TestingBuildParams
rule = platformBootclasspath.Output("hiddenapi-index.csv")
@@ -5226,7 +5479,7 @@
checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
my-bootclasspath-fragment/index.csv
out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
- out/soong/.intermediates/packages/modules/com.android.art/art-bootclasspath-fragment/android_common_apex10000/modular-hiddenapi/index.csv
+ out/soong/.intermediates/packages/modules/com.android.art/art-bootclasspath-fragment/android_common_com.android.art/modular-hiddenapi/index.csv
`)
})
@@ -5299,10 +5552,10 @@
checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
my-bootclasspath-fragment/index.csv
out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
- out/soong/.intermediates/packages/modules/com.android.art/art-bootclasspath-fragment/android_common_apex10000/modular-hiddenapi/index.csv
+ out/soong/.intermediates/packages/modules/com.android.art/art-bootclasspath-fragment/android_common_com.android.art/modular-hiddenapi/index.csv
`)
- myApex := ctx.ModuleForTests("myapex", "android_common_myapex").Module()
+ myApex := ctx.ModuleForTests(t, "myapex", "android_common_prebuilt_myapex").Module()
overrideNames := []string{
"",
@@ -5386,7 +5639,7 @@
// prebuilt_apex module always depends on the prebuilt, and so it doesn't
// find the dex boot jar in it. We either need to disable the source libfoo
// or make the prebuilt libfoo preferred.
- testDexpreoptWithApexes(t, bp, "module libfoo does not provide a dex boot jar", preparer, fragment)
+ testDexpreoptWithApexes(t, bp, `module "platform-bootclasspath" variant ".*": module libfoo{.*} does not provide a dex jar`, preparer, fragment)
// dexbootjar check is skipped if AllowMissingDependencies is true
preparerAllowMissingDeps := android.GroupFixturePreparers(
preparer,
@@ -5422,6 +5675,7 @@
prebuilt_apex {
name: "myapex",
+ prefer: true,
arch: {
arm64: {
src: "myapex-arm64.apex",
@@ -5494,7 +5748,7 @@
checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
my-bootclasspath-fragment/index.csv
out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
- out/soong/.intermediates/packages/modules/com.android.art/art-bootclasspath-fragment/android_common_apex10000/modular-hiddenapi/index.csv
+ out/soong/.intermediates/packages/modules/com.android.art/art-bootclasspath-fragment/android_common_com.android.art/modular-hiddenapi/index.csv
`)
})
@@ -5593,7 +5847,7 @@
checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
out/soong/.intermediates/my-bootclasspath-fragment/android_common_myapex/modular-hiddenapi/index.csv
- out/soong/.intermediates/packages/modules/com.android.art/art-bootclasspath-fragment/android_common_apex10000/modular-hiddenapi/index.csv
+ out/soong/.intermediates/packages/modules/com.android.art/art-bootclasspath-fragment/android_common_com.android.art/modular-hiddenapi/index.csv
`)
})
@@ -5705,7 +5959,7 @@
checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
my-bootclasspath-fragment/index.csv
out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
- out/soong/.intermediates/packages/modules/com.android.art/art-bootclasspath-fragment/android_common_apex10000/modular-hiddenapi/index.csv
+ out/soong/.intermediates/packages/modules/com.android.art/art-bootclasspath-fragment/android_common_com.android.art/modular-hiddenapi/index.csv
`)
})
@@ -5841,7 +6095,7 @@
}
`)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+ apexRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
// Ensure that test dep (and their transitive dependencies) are copied into apex.
@@ -5853,7 +6107,7 @@
ensureContains(t, copyCmds, "image.apex/bin/test/bar/baz")
// Ensure the module is correctly translated.
- bundle := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle)
+ bundle := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Module().(*apexBundle)
data := android.AndroidMkDataForTest(t, ctx, bundle)
name := bundle.BaseModuleName()
prefix := "TARGET_"
@@ -5935,7 +6189,7 @@
}
`)
- module := ctx.ModuleForTests("myapex", "android_common_myapex")
+ module := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
apexRule := module.Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
ensureContains(t, copyCmds, "image.apex/javalib/myjavaimport.jar")
@@ -6001,7 +6255,7 @@
}
`)
- module := ctx.ModuleForTests("myapex", "android_common_myapex")
+ module := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
apexRule := module.Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
@@ -6009,14 +6263,14 @@
ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPriv@TEST.BUILD_ID/AppFooPriv.apk")
ensureContains(t, copyCmds, "image.apex/etc/permissions/privapp_allowlist_com.android.AppFooPriv.xml")
- appZipRule := ctx.ModuleForTests("AppFoo", "android_common_apex10000").Description("zip jni libs")
+ appZipRule := ctx.ModuleForTests(t, "AppFoo", "android_common_apex10000").Description("zip jni libs")
// JNI libraries are uncompressed
if args := appZipRule.Args["jarArgs"]; !strings.Contains(args, "-L 0") {
t.Errorf("jni libs are not uncompressed for AppFoo")
}
// JNI libraries including transitive deps are
for _, jni := range []string{"libjni", "libfoo"} {
- jniOutput := ctx.ModuleForTests(jni, "android_arm64_armv8-a_sdk_shared_apex10000").Module().(*cc.Module).OutputFile().RelativeToTop()
+ jniOutput := ctx.ModuleForTests(t, jni, "android_arm64_armv8-a_sdk_shared_apex10000").Module().(*cc.Module).OutputFile().RelativeToTop()
// ... embedded inside APK (jnilibs.zip)
ensureListContains(t, appZipRule.Implicits.Strings(), jniOutput.String())
// ... and not directly inside the APEX
@@ -6109,7 +6363,7 @@
}
`)
- module := ctx.ModuleForTests("myapex", "android_common_myapex")
+ module := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
apexRule := module.Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
@@ -6187,7 +6441,7 @@
`)
- module := ctx.ModuleForTests("myapex", "android_common_myapex")
+ module := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
apexRule := module.Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
@@ -6356,16 +6610,10 @@
testApexError(t, `requires "libbaz" that doesn't list the APEX under 'apex_available'.\n\nDependency path:
.*via tag apex\.dependencyTag\{"sharedLib"\}
.*-> libfoo.*link:shared.*
-.*via tag cc\.dependencyTag.*
-.*-> libfoo.*link:static.*
.*via tag cc\.libraryDependencyTag.*Kind:sharedLibraryDependency.*
.*-> libbar.*link:shared.*
-.*via tag cc\.dependencyTag.*
-.*-> libbar.*link:static.*
.*via tag cc\.libraryDependencyTag.*Kind:sharedLibraryDependency.*
-.*-> libbaz.*link:shared.*
-.*via tag cc\.dependencyTag.*
-.*-> libbaz.*link:static.*`, `
+.*-> libbaz.*link:shared.*`, `
apex {
name: "myapex",
key: "myapex.key",
@@ -6691,14 +6939,14 @@
}
`)
- fooManifestRule := result.ModuleForTests("foo", "android_common_foo").Rule("apexManifestRule")
+ fooManifestRule := result.ModuleForTests(t, "foo", "android_common_foo").Rule("apexManifestRule")
fooExpectedDefaultVersion := testDefaultUpdatableModuleVersion
fooActualDefaultVersion := fooManifestRule.Args["default_version"]
if fooActualDefaultVersion != fooExpectedDefaultVersion {
t.Errorf("expected to find defaultVersion %q; got %q", fooExpectedDefaultVersion, fooActualDefaultVersion)
}
- barManifestRule := result.ModuleForTests("bar", "android_common_bar").Rule("apexManifestRule")
+ barManifestRule := result.ModuleForTests(t, "bar", "android_common_bar").Rule("apexManifestRule")
defaultVersionInt, _ := strconv.Atoi(testDefaultUpdatableModuleVersion)
barExpectedDefaultVersion := fmt.Sprint(defaultVersionInt + 3)
barActualDefaultVersion := barManifestRule.Args["default_version"]
@@ -6706,7 +6954,7 @@
t.Errorf("expected to find defaultVersion %q; got %q", barExpectedDefaultVersion, barActualDefaultVersion)
}
- overrideBarManifestRule := result.ModuleForTests("bar", "android_common_myoverrideapex_myoverrideapex").Rule("apexManifestRule")
+ overrideBarManifestRule := result.ModuleForTests(t, "bar", "android_common_myoverrideapex_myoverrideapex").Rule("apexManifestRule")
overrideBarActualDefaultVersion := overrideBarManifestRule.Args["default_version"]
if overrideBarActualDefaultVersion != barExpectedDefaultVersion {
t.Errorf("expected to find defaultVersion %q; got %q", barExpectedDefaultVersion, barActualDefaultVersion)
@@ -6946,14 +7194,14 @@
// libfoo shouldn't be available to platform even though it has "//apex_available:platform",
// because it depends on libbar which isn't available to platform
- libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*cc.Module)
+ libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module().(*cc.Module)
if libfoo.NotAvailableForPlatform() != true {
t.Errorf("%q shouldn't be available to platform", libfoo.String())
}
// libfoo2 however can be available to platform because it depends on libbaz which provides
// stubs
- libfoo2 := ctx.ModuleForTests("libfoo2", "android_arm64_armv8-a_shared").Module().(*cc.Module)
+ libfoo2 := ctx.ModuleForTests(t, "libfoo2", "android_arm64_armv8-a_shared").Module().(*cc.Module)
if libfoo2.NotAvailableForPlatform() == true {
t.Errorf("%q should be available to platform", libfoo2.String())
}
@@ -6985,11 +7233,11 @@
},
}`)
- libfooShared := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*cc.Module)
+ libfooShared := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module().(*cc.Module)
if libfooShared.NotAvailableForPlatform() != true {
t.Errorf("%q shouldn't be available to platform", libfooShared.String())
}
- libfooStatic := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Module().(*cc.Module)
+ libfooStatic := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_static").Module().(*cc.Module)
if libfooStatic.NotAvailableForPlatform() != false {
t.Errorf("%q should be available to platform", libfooStatic.String())
}
@@ -7090,6 +7338,34 @@
`)
}
+func TestApexValidation_UsesProperPartitionTag(t *testing.T) {
+ t.Parallel()
+ ctx := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ updatable: false,
+ vendor: true,
+ }
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+ `, android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ // vendor path should not affect "partition tag"
+ variables.VendorPath = proptools.StringPtr("system/vendor")
+ }))
+
+ module := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
+ android.AssertStringEquals(t, "partition tag for host_apex_verifier",
+ "vendor",
+ module.Output("host_apex_verifier.timestamp").Args["partition_tag"])
+ android.AssertStringEquals(t, "partition tag for apex_sepolicy_tests",
+ "vendor",
+ module.Output("apex_sepolicy_tests.timestamp").Args["partition_tag"])
+}
+
func TestApexValidation_TestApexCanSkipInitRcCheck(t *testing.T) {
t.Parallel()
ctx := testApex(t, `
@@ -7108,7 +7384,7 @@
}
`)
- validations := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("signapk").Validations.Strings()
+ validations := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("signapk").Validations.Strings()
if android.SuffixInList(validations, "host_apex_verifier.timestamp") {
t.Error("should not run host_apex_verifier")
}
@@ -7129,7 +7405,7 @@
}
`)
- validations := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("signapk").Validations.Strings()
+ validations := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("signapk").Validations.Strings()
if !android.SuffixInList(validations, "host_apex_verifier.timestamp") {
t.Error("should run host_apex_verifier")
}
@@ -7233,8 +7509,8 @@
}
`, withManifestPackageNameOverrides([]string{"myapex:com.android.myapex"}))
- originalVariant := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(android.OverridableModule)
- overriddenVariant := ctx.ModuleForTests("myapex", "android_common_override_myapex_override_myapex").Module().(android.OverridableModule)
+ originalVariant := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Module().(android.OverridableModule)
+ overriddenVariant := ctx.ModuleForTests(t, "myapex", "android_common_override_myapex_override_myapex").Module().(android.OverridableModule)
if originalVariant.GetOverriddenBy() != "" {
t.Errorf("GetOverriddenBy should be empty, but was %q", originalVariant.GetOverriddenBy())
}
@@ -7242,7 +7518,7 @@
t.Errorf("GetOverriddenBy should be \"override_myapex\", but was %q", overriddenVariant.GetOverriddenBy())
}
- module := ctx.ModuleForTests("myapex", "android_common_override_myapex_override_myapex")
+ module := ctx.ModuleForTests(t, "myapex", "android_common_override_myapex_override_myapex")
apexRule := module.Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
@@ -7333,7 +7609,7 @@
`, withApexGlobalMinSdkVersionOverride(&minSdkOverride31))
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+ apexRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
// Ensure that direct non-stubs dep is always included
@@ -7393,7 +7669,7 @@
`, withApexGlobalMinSdkVersionOverride(&minSdkOverride29))
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+ apexRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
// Ensure that direct non-stubs dep is always included
@@ -7432,7 +7708,7 @@
}
`, withUnbundledBuild)
- module := ctx.ModuleForTests("myapex", "android_common_myapex")
+ module := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
args := module.Rule("apexRule").Args
ensureContains(t, args["opt_flags"], "--manifest_json "+module.Output("apex_manifest.json").Output.String())
@@ -7441,8 +7717,8 @@
// the dependency names directly here but for some reason the names are blank in
// this test.
for _, lib := range []string{"libc++", "mylib"} {
- apexImplicits := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared_apex29").Rule("ld").Implicits
- nonApexImplicits := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld").Implicits
+ apexImplicits := ctx.ModuleForTests(t, lib, "android_arm64_armv8-a_shared_apex29").Rule("ld").Implicits
+ nonApexImplicits := ctx.ModuleForTests(t, lib, "android_arm64_armv8-a_shared").Rule("ld").Implicits
if len(apexImplicits) != len(nonApexImplicits)+1 {
t.Errorf("%q missing unwinder dep", lib)
}
@@ -7501,7 +7777,7 @@
"etc/permissions/foo.xml",
})
// Permission XML should point to the activated path of impl jar of java_sdk_library
- sdkLibrary := ctx.ModuleForTests("foo.xml", "android_common_myapex").Output("foo.xml")
+ sdkLibrary := ctx.ModuleForTests(t, "foo.xml", "android_common_myapex").Output("foo.xml")
contents := android.ContentFromFileRuleForTests(t, ctx, sdkLibrary)
ensureMatches(t, contents, "<library\\n\\s+name=\\\"foo\\\"\\n\\s+file=\\\"/apex/myapex/javalib/foo.jar\\\"")
}
@@ -7542,7 +7818,7 @@
// Permission XML should point to the activated path of impl jar of java_sdk_library.
// Since override variants (com.mycompany.android.foo) are installed in the same package as the overridden variant
// (com.android.foo), the filepath should not contain override apex name.
- sdkLibrary := ctx.ModuleForTests("foo.xml", "android_common_mycompanyapex").Output("foo.xml")
+ sdkLibrary := ctx.ModuleForTests(t, "foo.xml", "android_common_mycompanyapex").Output("foo.xml")
contents := android.ContentFromFileRuleForTests(t, ctx, sdkLibrary)
ensureMatches(t, contents, "<library\\n\\s+name=\\\"foo\\\"\\n\\s+file=\\\"/apex/myapex/javalib/foo.jar\\\"")
}
@@ -7597,8 +7873,8 @@
})
// The bar library should depend on the implementation jar.
- barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac")
- if expected, actual := `^-classpath [^:]*/turbine-combined/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
+ barLibrary := ctx.ModuleForTests(t, "bar", "android_common_apex10000").Rule("javac")
+ if expected, actual := `^-classpath [^:]*/turbine/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
t.Errorf("expected %q, found %#q", expected, actual)
}
}
@@ -7649,8 +7925,8 @@
})
// The bar library should depend on the stubs jar.
- barLibrary := ctx.ModuleForTests("bar", "android_common").Rule("javac")
- if expected, actual := `^-classpath [^:]*/turbine-combined/foo\.stubs\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
+ barLibrary := ctx.ModuleForTests(t, "bar", "android_common").Rule("javac")
+ if expected, actual := `^-classpath [^:]*/foo\.stubs\.from-text/foo\.stubs\.from-text\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
t.Errorf("expected %q, found %#q", expected, actual)
}
}
@@ -7743,8 +8019,8 @@
})
// The bar library should depend on the implementation jar.
- barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac")
- if expected, actual := `^-classpath [^:]*/turbine-combined/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
+ barLibrary := ctx.ModuleForTests(t, "bar", "android_common_apex10000").Rule("javac")
+ if expected, actual := `^-classpath [^:]*/turbine/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
t.Errorf("expected %q, found %#q", expected, actual)
}
}
@@ -8122,7 +8398,7 @@
}
`)
- apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle)
+ apexBundle := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Module().(*apexBundle)
data := android.AndroidMkDataForTest(t, ctx, apexBundle)
var builder strings.Builder
data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data)
@@ -8208,7 +8484,7 @@
`)
- rule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexManifestRule")
+ rule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("apexManifestRule")
// Notice mylib2.so (transitive dep) is not added as a jni_lib
ensureEquals(t, rule.Args["opt"], "-a jniLibs libfoo.rust.so mylib.so mylib3.so")
ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{
@@ -8217,39 +8493,12 @@
"lib64/mylib2.so",
"lib64/mylib3.so",
"lib64/libfoo.rust.so",
- "lib64/libc++.so", // auto-added to libfoo.rust by Soong
- "lib64/liblog.so", // auto-added to libfoo.rust by Soong
})
// b/220397949
ensureListContains(t, names(rule.Args["requireNativeLibs"]), "libfoo.shared_from_rust.so")
}
-func TestApexMutatorsDontRunIfDisabled(t *testing.T) {
- t.Parallel()
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- `,
- android.FixtureModifyConfig(func(config android.Config) {
- delete(config.Targets, android.Android)
- config.AndroidCommonTarget = android.Target{}
- }),
- )
-
- if expected, got := []string{""}, ctx.ModuleVariantsForTests("myapex"); !reflect.DeepEqual(expected, got) {
- t.Errorf("Expected variants: %v, but got: %v", expected, got)
- }
-}
-
func TestAppBundle(t *testing.T) {
t.Parallel()
ctx := testApex(t, `
@@ -8275,7 +8524,7 @@
}
`, withManifestPackageNameOverrides([]string{"AppFoo:com.android.foo"}))
- bundleConfigRule := ctx.ModuleForTests("myapex", "android_common_myapex").Output("bundle_config.json")
+ bundleConfigRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Output("bundle_config.json")
content := android.ContentFromFileRuleForTests(t, ctx, bundleConfigRule)
ensureContains(t, content, `"compression":{"uncompressed_glob":["apex_payload.img","apex_manifest.*"]}`)
@@ -8302,7 +8551,7 @@
name: "AppSet",
set: "AppSet.apks",
}`)
- mod := ctx.ModuleForTests("myapex", "android_common_myapex")
+ mod := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
bundleConfigRule := mod.Output("bundle_config.json")
content := android.ContentFromFileRuleForTests(t, ctx, bundleConfigRule)
ensureContains(t, content, `"compression":{"uncompressed_glob":["apex_payload.img","apex_manifest.*"]}`)
@@ -8336,16 +8585,16 @@
ctx := testApex(t, bp, prepareForTestWithSantitizeHwaddress)
// Check that the extractor produces the correct output file from the correct input file.
- extractorOutput := "out/soong/.intermediates/myapex/android_common_myapex/extracted/myapex.hwasan.apks"
+ extractorOutput := "out/soong/.intermediates/myapex/android_common_prebuilt_myapex/extracted/myapex.hwasan.apks"
- m := ctx.ModuleForTests("myapex", "android_common_myapex")
+ m := ctx.ModuleForTests(t, "myapex", "android_common_prebuilt_myapex")
extractedApex := m.Output(extractorOutput)
android.AssertArrayString(t, "extractor input", []string{"myapex.hwasan.apks"}, extractedApex.Inputs.Strings())
// Ditto for the apex.
- m = ctx.ModuleForTests("myapex", "android_common_myapex")
- copiedApex := m.Output("out/soong/.intermediates/myapex/android_common_myapex/foo_v2.apex")
+ m = ctx.ModuleForTests(t, "myapex", "android_common_prebuilt_myapex")
+ copiedApex := m.Output("out/soong/.intermediates/myapex/android_common_prebuilt_myapex/foo_v2.apex")
android.AssertStringEquals(t, "myapex input", extractorOutput, copiedApex.Input.String())
}
@@ -8364,10 +8613,10 @@
}
`)
- m := ctx.ModuleForTests("myapex", "android_common_myapex")
+ m := ctx.ModuleForTests(t, "myapex", "android_common_prebuilt_myapex")
// Check that the extractor produces the correct apks file from the input module
- extractorOutput := "out/soong/.intermediates/myapex/android_common_myapex/extracted/myapex.apks"
+ extractorOutput := "out/soong/.intermediates/myapex/android_common_prebuilt_myapex/extracted/myapex.apks"
extractedApex := m.Output(extractorOutput)
android.AssertArrayString(t, "extractor input", []string{"myapex.apks"}, extractedApex.Inputs.Strings())
@@ -8756,7 +9005,7 @@
}),
)
- m := ctx.ModuleForTests("myapex", "android_common_myapex")
+ m := ctx.ModuleForTests(t, "myapex", "android_common_prebuilt_myapex")
// Check extract_apks tool parameters.
extractedApex := m.Output("extracted/myapex.apks")
@@ -8771,7 +9020,7 @@
t.Errorf("Unexpected abis parameter - expected %q vs actual %q", expected, actual)
}
- m = ctx.ModuleForTests("myapex", "android_common_myapex")
+ m = ctx.ModuleForTests(t, "myapex", "android_common_prebuilt_myapex")
a := m.Module().(*ApexSet)
expectedOverrides := []string{"foo"}
actualOverrides := android.AndroidMkEntriesForTest(t, ctx, a)[0].EntryMap["LOCAL_OVERRIDES_MODULES"]
@@ -8798,7 +9047,7 @@
}),
)
- m := ctx.ModuleForTests("myapex", "android_common_myapex")
+ m := ctx.ModuleForTests(t, "myapex", "android_common_prebuilt_myapex")
// Check extract_apks tool parameters. No native bridge arch expected
extractedApex := m.Output("extracted/myapex.apks")
@@ -8860,7 +9109,7 @@
}
`)
- myapex := ctx.ModuleForTests("myapex", "android_common_myapex")
+ myapex := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
content := android.ContentFromFileRuleForTests(t, ctx, myapex.Output("apexkeys.txt"))
ensureContains(t, content, `name="myapex.apex" public_key="vendor/foo/devkeys/testkey.avbpubkey" private_key="vendor/foo/devkeys/testkey.pem" container_certificate="vendor/foo/devkeys/test.x509.pem" container_private_key="vendor/foo/devkeys/test.pk8" partition="system" sign_tool="sign_myapex"`)
}
@@ -8903,10 +9152,10 @@
`)
content := android.ContentFromFileRuleForTests(t, ctx,
- ctx.ModuleForTests("myapex", "android_common_myapex").Output("apexkeys.txt"))
+ ctx.ModuleForTests(t, "myapex", "android_common_myapex").Output("apexkeys.txt"))
ensureContains(t, content, `name="myapex.apex" public_key="vendor/foo/devkeys/testkey.avbpubkey" private_key="vendor/foo/devkeys/testkey.pem" container_certificate="vendor/foo/devkeys/test.x509.pem" container_private_key="vendor/foo/devkeys/test.pk8" partition="system" sign_tool="sign_myapex"`)
content = android.ContentFromFileRuleForTests(t, ctx,
- ctx.ModuleForTests("myapex_set", "android_common_myapex_set").Output("apexkeys.txt"))
+ ctx.ModuleForTests(t, "myapex_set", "android_common_prebuilt_myapex_set").Output("apexkeys.txt"))
ensureContains(t, content, `name="myapex_set.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" partition="system"`)
}
@@ -8956,12 +9205,12 @@
`),
}))
- rule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("diffApexContentRule")
+ rule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("diffApexContentRule")
if expected, actual := "allowed.txt", rule.Args["allowed_files_file"]; expected != actual {
t.Errorf("allowed_files_file: expected %q but got %q", expected, actual)
}
- rule2 := ctx.ModuleForTests("myapex", "android_common_override_myapex_override_myapex").Rule("diffApexContentRule")
+ rule2 := ctx.ModuleForTests(t, "myapex", "android_common_override_myapex_override_myapex").Rule("diffApexContentRule")
if expected, actual := "sub/allowed.txt", rule2.Args["allowed_files_file"]; expected != actual {
t.Errorf("allowed_files_file: expected %q but got %q", expected, actual)
}
@@ -9024,14 +9273,14 @@
}),
)
- compressRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("compressRule")
+ compressRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("compressRule")
ensureContains(t, compressRule.Output.String(), "myapex.capex.unsigned")
- signApkRule := ctx.ModuleForTests("myapex", "android_common_myapex").Description("sign compressedApex")
+ signApkRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Description("sign compressedApex")
ensureEquals(t, signApkRule.Input.String(), compressRule.Output.String())
// Make sure output of bundle is .capex
- ab := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle)
+ ab := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Module().(*apexBundle)
ensureContains(t, ab.outputFile.String(), "myapex.capex")
// Verify android.mk rules
@@ -9063,7 +9312,7 @@
}),
)
- compressRule := ctx.ModuleForTests("myapex", "android_common_myapex").MaybeRule("compressRule")
+ compressRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").MaybeRule("compressRule")
if compressRule.Rule != nil {
t.Error("erofs apex should not be compressed")
}
@@ -9085,7 +9334,7 @@
}),
)
- build := ctx.ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex").Output("com.company.android.myapex.apex")
+ build := ctx.ModuleForTests(t, "com.company.android.myapex", "android_common_prebuilt_com.android.myapex").Output("com.company.android.myapex.apex")
if compressionEnabled {
ensureEquals(t, build.Rule.String(), "android/soong/android.Cp")
} else {
@@ -9137,7 +9386,7 @@
}
`)
- ab := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle)
+ ab := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Module().(*apexBundle)
data := android.AndroidMkDataForTest(t, ctx, ab)
var builder strings.Builder
data.Custom(&builder, ab.BaseModuleName(), "TARGET_", "", data)
@@ -9187,15 +9436,15 @@
`)
// Check if mylib is linked to mylib2 for the non-apex target
- ldFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"]
+ ldFlags := ctx.ModuleForTests(t, "mylib", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"]
ensureContains(t, ldFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
// Make sure that the link doesn't occur for the apex target
- ldFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
+ ldFlags = ctx.ModuleForTests(t, "mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
ensureNotContains(t, ldFlags, "mylib2/android_arm64_armv8-a_shared_apex10000/mylib2.so")
// It shouldn't appear in the copy cmd as well.
- copyCmds := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule").Args["copy_commands"]
+ copyCmds := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("apexRule").Args["copy_commands"]
ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
}
@@ -9311,7 +9560,7 @@
if !strings.HasPrefix(variant, "android_arm64_armv8-a_shared") {
continue
}
- mod := ctx.ModuleForTests(modName, variant).Module().(*cc.Module)
+ mod := ctx.ModuleForTests(t, modName, variant).Module().(*cc.Module)
if !mod.Enabled(android.PanickingConfigAndErrorContext(ctx)) || mod.IsHideFromMake() {
continue
}
@@ -9434,13 +9683,13 @@
).RunTest(t)
// Make sure jacoco ran on both mylib and mybootclasspathlib
- if result.ModuleForTests("mylib", "android_common_apex10000").MaybeRule("jacoco").Rule == nil {
+ if result.ModuleForTests(t, "mylib", "android_common_apex10000").MaybeRule("jacoco").Rule == nil {
t.Errorf("Failed to find jacoco rule for mylib")
}
- if result.ModuleForTests("mybootclasspathlib", "android_common_apex10000").MaybeRule("jacoco").Rule == nil {
+ if result.ModuleForTests(t, "mybootclasspathlib", "android_common_apex10000").MaybeRule("jacoco").Rule == nil {
t.Errorf("Failed to find jacoco rule for mybootclasspathlib")
}
- if result.ModuleForTests("mysystemserverclasspathlib", "android_common_apex10000").MaybeRule("jacoco").Rule == nil {
+ if result.ModuleForTests(t, "mysystemserverclasspathlib", "android_common_apex10000").MaybeRule("jacoco").Rule == nil {
t.Errorf("Failed to find jacoco rule for mysystemserverclasspathlib")
}
}
@@ -9523,12 +9772,21 @@
dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"),
)
- apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle)
+ apexBundle := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Module().(*apexBundle)
data := android.AndroidMkDataForTest(t, ctx, apexBundle)
var builder strings.Builder
data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data)
androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := foo.myapex foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.odex foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.vdex\n")
+ out := ctx.Config().OutDir()
+ ensureContains(t, androidMk, "LOCAL_SOONG_INSTALL_PAIRS += "+
+ filepath.Join(out, "soong/.intermediates/foo/android_common_apex10000/dexpreopt/foo/oat/arm64/javalib.odex")+
+ ":"+
+ filepath.Join(out, "target/product/test_device/system/framework/oat/arm64/apex@myapex@javalib@foo.jar@classes.odex")+
+ " "+
+ filepath.Join(out, "soong/.intermediates/foo/android_common_apex10000/dexpreopt/foo/oat/arm64/javalib.vdex")+
+ ":"+
+ filepath.Join(out, "target/product/test_device/system/framework/oat/arm64/apex@myapex@javalib@foo.jar@classes.vdex")+
+ "\n")
}
func TestAndroidMk_RequiredModules(t *testing.T) {
@@ -9563,7 +9821,7 @@
}
`)
- apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle)
+ apexBundle := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Module().(*apexBundle)
data := android.AndroidMkDataForTest(t, ctx, apexBundle)
var builder strings.Builder
data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data)
@@ -9587,7 +9845,7 @@
}
`)
- bundle := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle)
+ bundle := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Module().(*apexBundle)
bundle.makeModulesToInstall = append(bundle.makeModulesToInstall, "foo")
data := android.AndroidMkDataForTest(t, ctx, bundle)
var builder strings.Builder
@@ -9639,7 +9897,7 @@
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.CompressedApex = proptools.BoolPtr(true)
}))
- javaTest := ctx.ModuleForTests(tc.name, "android_common").Module().(*java.Test)
+ javaTest := ctx.ModuleForTests(t, tc.name, "android_common").Module().(*java.Test)
data := android.AndroidMkEntriesForTest(t, ctx, javaTest)[0].EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
android.AssertStringPathsRelativeToTopEquals(t, "data", ctx.Config(), tc.expected_data, data)
})
@@ -9842,7 +10100,7 @@
// Verifies that the APEX depends on all the Make modules in the list.
func ensureContainsRequiredDeps(t *testing.T, ctx *android.TestContext, moduleName, variant string, deps []string) {
- a := ctx.ModuleForTests(moduleName, variant).Module().(*apexBundle)
+ a := ctx.ModuleForTests(t, moduleName, variant).Module().(*apexBundle)
for _, dep := range deps {
android.AssertStringListContains(t, "", a.makeModulesToInstall, dep)
}
@@ -9850,7 +10108,7 @@
// Verifies that the APEX does not depend on any of the Make modules in the list.
func ensureDoesNotContainRequiredDeps(t *testing.T, ctx *android.TestContext, moduleName, variant string, deps []string) {
- a := ctx.ModuleForTests(moduleName, variant).Module().(*apexBundle)
+ a := ctx.ModuleForTests(t, moduleName, variant).Module().(*apexBundle)
for _, dep := range deps {
android.AssertStringListDoesNotContain(t, "", a.makeModulesToInstall, dep)
}
@@ -9958,8 +10216,8 @@
}
}
- myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29")
- apex := result.ModuleForTests("myapex", "android_common_myapex")
+ myjavalib := result.ModuleForTests(t, "myjavalib", "android_common_apex29")
+ apex := result.ModuleForTests(t, "myapex", "android_common_myapex")
apexStrictUpdatabilityCheck := apex.MaybeOutput("lint_strict_updatability_check.stamp")
javalibStrictUpdatabilityCheck := myjavalib.MaybeOutput("lint_strict_updatability_check.stamp")
@@ -10008,7 +10266,7 @@
}
result := testApex(t, bp, dexpreopt.FixtureSetApexBootJars("myapex:myjavalib"), fs.AddToFixture())
- apex := result.ModuleForTests("myapex", "android_common_myapex")
+ apex := result.ModuleForTests(t, "myapex", "android_common_myapex")
apexStrictUpdatabilityCheck := apex.Output("lint_strict_updatability_check.stamp")
android.AssertStringDoesContain(t, "strict updatability check rule for myapex",
apexStrictUpdatabilityCheck.RuleParams.Command, "--disallowed_issues NewApi")
@@ -10060,7 +10318,7 @@
android.FixtureMergeMockFs(fs),
).RunTestWithBp(t, bp)
- myapex := result.ModuleForTests("myapex", "android_common_myapex")
+ myapex := result.ModuleForTests(t, "myapex", "android_common_myapex")
lintReportInputs := strings.Join(myapex.Output("lint-report-xml.zip").Inputs.Strings(), " ")
android.AssertStringDoesContain(t,
"myapex lint report expected to contain that of the sdk library impl lib as an input",
@@ -10112,7 +10370,7 @@
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}`)
- mod := ctx.ModuleForTests("myapex", "android_common_myapex")
+ mod := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
generateFsRule := mod.Rule("generateFsConfig")
cmd := generateFsRule.RuleParams.Command
@@ -10134,7 +10392,7 @@
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}`)
- mod := ctx.ModuleForTests("myapex", "android_common_myapex")
+ mod := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
generateFsRule := mod.Rule("generateFsConfig")
cmd := generateFsRule.RuleParams.Command
@@ -10269,7 +10527,7 @@
}
`)
- inputs := result.ModuleForTests("myfilesystem", "android_common").Output("myfilesystem.img").Implicits
+ inputs := result.ModuleForTests(t, "myfilesystem", "android_common").Output("myfilesystem.img").Implicits
android.AssertStringListDoesNotContain(t, "filesystem should not have libbar",
inputs.Strings(),
"out/soong/.intermediates/libbar/android_arm64_armv8-a_shared/libbar.so")
@@ -10363,7 +10621,7 @@
}
`)
- mod := ctx.ModuleForTests("myapex", "android_common_myapex")
+ mod := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
s := mod.Rule("apexRule").Args["copy_commands"]
copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
if len(copyCmds) != 14 {
@@ -10502,7 +10760,7 @@
}
`)
- mod := ctx.ModuleForTests("myapex", "android_common_myapex")
+ mod := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
s := mod.Rule("apexRule").Args["copy_commands"]
copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
if len(copyCmds) != 18 {
@@ -10548,15 +10806,6 @@
}
rust_library {
- name: "libflags_rust", // test mock
- crate_name: "flags_rust",
- srcs: ["lib.rs"],
- apex_available: [
- "myapex",
- ],
- }
-
- rust_library {
name: "liblazy_static", // test mock
crate_name: "lazy_static",
srcs: ["src/lib.rs"],
@@ -10673,11 +10922,11 @@
}
`)
- mod := ctx.ModuleForTests("myapex", "android_common_myapex")
+ mod := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
s := mod.Rule("apexRule").Args["copy_commands"]
copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
- if len(copyCmds) != 38 {
- t.Fatalf("Expected 38 commands, got %d in:\n%s", len(copyCmds), s)
+ if len(copyCmds) != 32 {
+ t.Fatalf("Expected 32 commands, got %d in:\n%s", len(copyCmds), s)
}
ensureListContainsMatch(t, copyCmds, "^cp -f .*/aconfig_flags.pb .*/image.apex/etc/aconfig_flags.pb")
@@ -10789,7 +11038,7 @@
}
`)
- mod := ctx.ModuleForTests("myapex", "android_common_myapex")
+ mod := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
combineAconfigRule := mod.Rule("All_aconfig_declarations_dump")
s := " " + combineAconfigRule.Args["cache_files"]
aconfigArgs := regexp.MustCompile(" --cache ").Split(s, -1)[1:]
@@ -10869,7 +11118,7 @@
}
`)
- mod := ctx.ModuleForTests("myapex", "android_common_myapex")
+ mod := ctx.ModuleForTests(t, "myapex", "android_common_myapex")
combineAconfigRule := mod.Rule("All_aconfig_declarations_dump")
s := " " + combineAconfigRule.Args["cache_files"]
aconfigArgs := regexp.MustCompile(" --cache ").Split(s, -1)[1:]
@@ -10892,7 +11141,7 @@
t.Parallel()
checkBootDexJarPath := func(t *testing.T, ctx *android.TestContext, stem string, bootDexJarPath string) {
t.Helper()
- s := ctx.ModuleForTests("dex_bootjars", "android_common")
+ s := ctx.ModuleForTests(t, "dex_bootjars", "android_common")
foundLibfooJar := false
base := stem + ".jar"
for _, output := range s.AllOutputs() {
@@ -10910,14 +11159,14 @@
// Check that the boot jars of the selected apex are run through boot_jars_package_check
// This validates that the jars on the bootclasspath do not contain packages outside an allowlist
checkBootJarsPackageCheck := func(t *testing.T, ctx *android.TestContext, expectedBootJar string) {
- platformBcp := ctx.ModuleForTests("platform-bootclasspath", "android_common")
+ platformBcp := ctx.ModuleForTests(t, "platform-bootclasspath", "android_common")
bootJarsCheckRule := platformBcp.Rule("boot_jars_package_check")
android.AssertStringMatches(t, "Could not find the correct boot dex jar in package check rule", bootJarsCheckRule.RuleParams.Command, "build/soong/scripts/check_boot_jars/package_allowed_list.txt.*"+expectedBootJar)
}
// Check that the boot jars used to generate the monolithic hiddenapi flags come from the selected apex
checkBootJarsForMonolithicHiddenapi := func(t *testing.T, ctx *android.TestContext, expectedBootJar string) {
- monolithicHiddenapiFlagsCmd := ctx.ModuleForTests("platform-bootclasspath", "android_common").Output("out/soong/hiddenapi/hiddenapi-stub-flags.txt").RuleParams.Command
+ monolithicHiddenapiFlagsCmd := ctx.ModuleForTests(t, "platform-bootclasspath", "android_common").Output("out/soong/hiddenapi/hiddenapi-stub-flags.txt").RuleParams.Command
android.AssertStringMatches(t, "Could not find the correct boot dex jar in monolithic hiddenapi flags generation command", monolithicHiddenapiFlagsCmd, "--boot-dex="+expectedBootJar)
}
@@ -11027,17 +11276,17 @@
{
desc: "Source apex com.android.foo is selected, bootjar should come from source java library",
selectedApexContributions: "foo.source.contributions",
- expectedBootJar: "out/soong/.intermediates/foo-bootclasspath-fragment/android_common_apex10000/hiddenapi-modular/encoded/framework-foo.jar",
+ expectedBootJar: "out/soong/.intermediates/foo-bootclasspath-fragment/android_common_com.android.foo/hiddenapi-modular/encoded/framework-foo.jar",
},
{
desc: "Prebuilt apex prebuilt_com.android.foo is selected, profile should come from .prof deapexed from the prebuilt",
selectedApexContributions: "foo.prebuilt.contributions",
- expectedBootJar: "out/soong/.intermediates/prebuilt_com.android.foo/android_common_com.android.foo/deapexer/javalib/framework-foo.jar",
+ expectedBootJar: "out/soong/.intermediates/prebuilt_com.android.foo/android_common_prebuilt_com.android.foo/deapexer/javalib/framework-foo.jar",
},
{
desc: "Prebuilt apex prebuilt_com.android.foo.v2 is selected, profile should come from .prof deapexed from the prebuilt",
selectedApexContributions: "foo.prebuilt.v2.contributions",
- expectedBootJar: "out/soong/.intermediates/com.android.foo.v2/android_common_com.android.foo/deapexer/javalib/framework-foo.jar",
+ expectedBootJar: "out/soong/.intermediates/com.android.foo.v2/android_common_prebuilt_com.android.foo/deapexer/javalib/framework-foo.jar",
},
}
@@ -11082,18 +11331,18 @@
// for a mainline module family, check that only the flagged soong module is visible to make
checkHideFromMake := func(t *testing.T, ctx *android.TestContext, visibleModuleName string, hiddenModuleNames []string) {
variation := func(moduleName string) string {
- ret := "android_common_com.android.foo"
+ ret := "android_common_prebuilt_com.android.foo"
if moduleName == "com.google.android.foo" {
- ret = "android_common_com.google.android.foo_com.google.android.foo"
+ ret = "android_common_com.google.android.foo"
}
return ret
}
- visibleModule := ctx.ModuleForTests(visibleModuleName, variation(visibleModuleName)).Module()
+ visibleModule := ctx.ModuleForTests(t, visibleModuleName, variation(visibleModuleName)).Module()
android.AssertBoolEquals(t, "Apex "+visibleModuleName+" selected using apex_contributions should be visible to make", false, visibleModule.IsHideFromMake())
for _, hiddenModuleName := range hiddenModuleNames {
- hiddenModule := ctx.ModuleForTests(hiddenModuleName, variation(hiddenModuleName)).Module()
+ hiddenModule := ctx.ModuleForTests(t, hiddenModuleName, variation(hiddenModuleName)).Module()
android.AssertBoolEquals(t, "Apex "+hiddenModuleName+" not selected using apex_contributions should be hidden from make", true, hiddenModule.IsHideFromMake())
}
@@ -11229,19 +11478,19 @@
checkHideFromMake := func(t *testing.T, ctx *android.TestContext, visibleModuleNames []string, hiddenModuleNames []string) {
variation := func(moduleName string) string {
ret := "android_common_com.android.adservices"
- if moduleName == "com.google.android.foo" {
- ret = "android_common_com.google.android.foo_com.google.android.foo"
+ if moduleName == "com.google.android.adservices" || moduleName == "com.google.android.adservices.v2" {
+ ret = "android_common_prebuilt_com.android.adservices"
}
return ret
}
for _, visibleModuleName := range visibleModuleNames {
- visibleModule := ctx.ModuleForTests(visibleModuleName, variation(visibleModuleName)).Module()
+ visibleModule := ctx.ModuleForTests(t, visibleModuleName, variation(visibleModuleName)).Module()
android.AssertBoolEquals(t, "Apex "+visibleModuleName+" selected using apex_contributions should be visible to make", false, visibleModule.IsHideFromMake())
}
for _, hiddenModuleName := range hiddenModuleNames {
- hiddenModule := ctx.ModuleForTests(hiddenModuleName, variation(hiddenModuleName)).Module()
+ hiddenModule := ctx.ModuleForTests(t, hiddenModuleName, variation(hiddenModuleName)).Module()
android.AssertBoolEquals(t, "Apex "+hiddenModuleName+" not selected using apex_contributions should be hidden from make", true, hiddenModule.IsHideFromMake())
}
@@ -11305,13 +11554,13 @@
expectedHiddenModuleNames: []string{"com.google.android.adservices", "com.google.android.adservices.v2"},
},
{
- desc: "Prebuilt apex prebuilt_com.android.foo is selected",
+ desc: "Prebuilt apex prebuilt_com.android.adservices is selected",
selectedApexContributions: "adservices.prebuilt.contributions",
expectedVisibleModuleNames: []string{"com.android.adservices", "com.google.android.adservices"},
expectedHiddenModuleNames: []string{"com.google.android.adservices.v2"},
},
{
- desc: "Prebuilt apex prebuilt_com.android.foo.v2 is selected",
+ desc: "Prebuilt apex prebuilt_com.android.adservices.v2 is selected",
selectedApexContributions: "adservices.prebuilt.v2.contributions",
expectedVisibleModuleNames: []string{"com.android.adservices", "com.google.android.adservices.v2"},
expectedHiddenModuleNames: []string{"com.google.android.adservices"},
@@ -11413,7 +11662,7 @@
}
`+aconfigDeclarationLibraryString([]string{"bar", "baz", "qux", "quux"}))
- m := result.ModuleForTests("foo.stubs.source", "android_common")
+ m := result.ModuleForTests(t, "foo.stubs.source", "android_common")
outDir := "out/soong/.intermediates"
// Arguments passed to aconfig to retrieve the state of the flags defined in the
@@ -11478,7 +11727,7 @@
"packages/modules/common/build/allowed_deps.txt": nil,
}))
- ab := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle)
+ ab := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Module().(*apexBundle)
data := android.AndroidMkDataForTest(t, ctx, ab)
var builder strings.Builder
data.Custom(&builder, ab.BaseModuleName(), "TARGET_", "", data)
@@ -11550,18 +11799,18 @@
}),
)
- baseModule := ctx.ModuleForTests("com.android.apex30", "android_common_com.android.apex30")
+ baseModule := ctx.ModuleForTests(t, "com.android.apex30", "android_common_com.android.apex30")
checkMinSdkVersion(t, baseModule, "30")
// Override module, but uses same min_sdk_version
- overridingModuleSameMinSdkVersion := ctx.ModuleForTests("com.android.apex30", "android_common_com.mycompany.android.apex30_com.mycompany.android.apex30")
- javalibApex30Variant := ctx.ModuleForTests("javalib", "android_common_apex30")
+ overridingModuleSameMinSdkVersion := ctx.ModuleForTests(t, "com.android.apex30", "android_common_com.mycompany.android.apex30_com.mycompany.android.apex30")
+ javalibApex30Variant := ctx.ModuleForTests(t, "javalib", "android_common_apex30")
checkMinSdkVersion(t, overridingModuleSameMinSdkVersion, "30")
checkHasDep(t, ctx, overridingModuleSameMinSdkVersion.Module(), javalibApex30Variant.Module())
// Override module, uses different min_sdk_version
- overridingModuleDifferentMinSdkVersion := ctx.ModuleForTests("com.android.apex30", "android_common_com.mycompany.android.apex31_com.mycompany.android.apex31")
- javalibApex31Variant := ctx.ModuleForTests("javalib", "android_common_apex31")
+ overridingModuleDifferentMinSdkVersion := ctx.ModuleForTests(t, "com.android.apex30", "android_common_com.mycompany.android.apex31_com.mycompany.android.apex31")
+ javalibApex31Variant := ctx.ModuleForTests(t, "javalib", "android_common_apex31")
checkMinSdkVersion(t, overridingModuleDifferentMinSdkVersion, "31")
checkHasDep(t, ctx, overridingModuleDifferentMinSdkVersion.Module(), javalibApex31Variant.Module())
}
@@ -11599,7 +11848,7 @@
}
`)
- java.CheckModuleHasDependency(t, res.TestContext, "myoverrideapex", "android_common_myoverrideapex_myoverrideapex", "foo")
+ java.CheckModuleHasDependency(t, res.TestContext, "myoverrideapex", "android_common_myoverrideapex", "foo")
}
func TestUpdatableApexMinSdkVersionCurrent(t *testing.T) {
@@ -11630,7 +11879,7 @@
android.FixtureMergeMockFs(fs),
).RunTest(t)
- ldRule := result.ModuleForTests("installedlib", "android_arm64_armv8-a_shared").Rule("ld")
+ ldRule := result.ModuleForTests(t, "installedlib", "android_arm64_armv8-a_shared").Rule("ld")
android.AssertStringDoesContain(t, "", ldRule.Args["libFlags"], "android_arm64_armv8-a_shared_current/libfoo.so")
installRules := result.InstallMakeRulesForTesting(t)
@@ -11931,400 +12180,39 @@
}
`, filesystem.PrepareForTestWithFilesystemBuildComponents)
- partition := result.ModuleForTests("myfilesystem", "android_common")
+ partition := result.ModuleForTests(t, "myfilesystem", "android_common")
fileList := android.ContentFromFileRuleForTests(t, result, partition.Output("fileList"))
android.AssertDeepEquals(t, "filesystem with apex", "apex/myapex.apex\n", fileList)
}
-func TestApexVerifyNativeImplementationLibs(t *testing.T) {
+func TestVintfFragmentInApex(t *testing.T) {
t.Parallel()
-
- extractDepenencyPathFromErrors := func(errs []error) []string {
- i := slices.IndexFunc(errs, func(err error) bool {
- return strings.Contains(err.Error(), "dependency path:")
- })
- if i < 0 {
- return nil
+ ctx := testApex(t, apex_default_bp+`
+ apex {
+ name: "myapex",
+ manifest: ":myapex.manifest",
+ androidManifest: ":myapex.androidmanifest",
+ key: "myapex.key",
+ binaries: [ "mybin" ],
+ updatable: false,
}
- var dependencyPath []string
- for _, err := range errs[i+1:] {
- s := err.Error()
- lastSpace := strings.LastIndexByte(s, ' ')
- if lastSpace >= 0 {
- dependencyPath = append(dependencyPath, s[lastSpace+1:])
- }
+
+ cc_binary {
+ name: "mybin",
+ srcs: ["mybin.cpp"],
+ vintf_fragment_modules: ["my_vintf_fragment.xml"],
+ apex_available: [ "myapex" ],
}
- return dependencyPath
- }
- checkErrors := func(wantDependencyPath []string) func(t *testing.T, result *android.TestResult) {
- return func(t *testing.T, result *android.TestResult) {
- t.Helper()
- if len(result.Errs) == 0 {
- t.Fatalf("expected errors")
- }
- t.Log("found errors:")
- for _, err := range result.Errs {
- t.Log(err)
- }
- if g, w := result.Errs[0].Error(), "library in apex transitively linked against implementation library"; !strings.Contains(g, w) {
- t.Fatalf("expected error %q, got %q", w, g)
- }
- dependencyPath := extractDepenencyPathFromErrors(result.Errs)
- if g, w := dependencyPath, wantDependencyPath; !slices.Equal(g, w) {
- t.Errorf("expected dependency path %q, got %q", w, g)
- }
+ vintf_fragment {
+ name: "my_vintf_fragment.xml",
+ src: "my_vintf_fragment.xml",
}
- }
+ `)
- addToSharedLibs := func(module, lib string) func(bp *bpmodify.Blueprint) {
- return func(bp *bpmodify.Blueprint) {
- m := bp.ModulesByName(module)
- props, err := m.GetOrCreateProperty(bpmodify.List, "shared_libs")
- if err != nil {
- panic(err)
- }
- props.AddStringToList(lib)
- }
- }
+ generateFsRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").Rule("generateFsConfig")
+ cmd := generateFsRule.RuleParams.Command
- bpTemplate := `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- rust_dyn_libs: ["libmyrust"],
- binaries: ["mybin", "myrustbin"],
- jni_libs: ["libjni"],
- apps: ["myapp"],
- updatable: false,
- }
-
- apex {
- name: "otherapex",
- key: "myapex.key",
- native_shared_libs: ["libotherapex"],
- updatable: false,
- }
-
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
-
- cc_library {
- name: "mylib",
- srcs: ["foo.cpp"],
- apex_available: ["myapex"],
- }
-
- cc_binary {
- name: "mybin",
- srcs: ["foo.cpp"],
- apex_available: ["myapex"],
- }
-
- rust_library {
- name: "libmyrust",
- crate_name: "myrust",
- srcs: ["src/lib.rs"],
- rustlibs: ["libmyrust_transitive_dylib"],
- rlibs: ["libmyrust_transitive_rlib"],
- apex_available: ["myapex"],
- }
-
- rust_library{
- name: "libmyrust_transitive_dylib",
- crate_name: "myrust_transitive_dylib",
- srcs: ["src/lib.rs"],
- apex_available: ["myapex"],
- }
-
- rust_library {
- name: "libmyrust_transitive_rlib",
- crate_name: "myrust_transitive_rlib",
- srcs: ["src/lib.rs"],
- apex_available: ["myapex"],
- }
-
- rust_binary {
- name: "myrustbin",
- srcs: ["src/main.rs"],
- apex_available: ["myapex"],
- }
-
- cc_library {
- name: "libbar",
- sdk_version: "current",
- srcs: ["bar.cpp"],
- apex_available: ["myapex"],
- stl: "none",
- }
-
- android_app {
- name: "myapp",
- jni_libs: ["libembeddedjni"],
- use_embedded_native_libs: true,
- sdk_version: "current",
- apex_available: ["myapex"],
- }
-
- cc_library {
- name: "libembeddedjni",
- sdk_version: "current",
- srcs: ["bar.cpp"],
- apex_available: ["myapex"],
- stl: "none",
- }
-
- cc_library {
- name: "libjni",
- sdk_version: "current",
- srcs: ["bar.cpp"],
- apex_available: ["myapex"],
- stl: "none",
- }
-
- cc_library {
- name: "libotherapex",
- sdk_version: "current",
- srcs: ["otherapex.cpp"],
- apex_available: ["otherapex"],
- stubs: {
- symbol_file: "libotherapex.map.txt",
- versions: ["1", "2", "3"],
- },
- stl: "none",
- }
-
- cc_library {
- name: "libplatform",
- sdk_version: "current",
- srcs: ["libplatform.cpp"],
- stubs: {
- symbol_file: "libplatform.map.txt",
- versions: ["1", "2", "3"],
- },
- stl: "none",
- system_shared_libs: [],
- }
- `
-
- testCases := []struct {
- name string
- bpModifier func(bp *bpmodify.Blueprint)
- dependencyPath []string
- }{
- {
- name: "library dependency in other apex",
- bpModifier: addToSharedLibs("mylib", "libotherapex#impl"),
- dependencyPath: []string{"myapex", "mylib", "libotherapex"},
- },
- {
- name: "transitive library dependency in other apex",
- bpModifier: func(bp *bpmodify.Blueprint) {
- addToSharedLibs("mylib", "libbar")(bp)
- addToSharedLibs("libbar", "libotherapex#impl")(bp)
- },
- dependencyPath: []string{"myapex", "mylib", "libbar", "libotherapex"},
- },
- {
- name: "library dependency in platform",
- bpModifier: addToSharedLibs("mylib", "libplatform#impl"),
- dependencyPath: []string{"myapex", "mylib", "libplatform"},
- },
- {
- name: "jni library dependency in other apex",
- bpModifier: addToSharedLibs("libjni", "libotherapex#impl"),
- dependencyPath: []string{"myapex", "libjni", "libotherapex"},
- },
- {
- name: "transitive jni library dependency in other apex",
- bpModifier: func(bp *bpmodify.Blueprint) {
- addToSharedLibs("libjni", "libbar")(bp)
- addToSharedLibs("libbar", "libotherapex#impl")(bp)
- },
- dependencyPath: []string{"myapex", "libjni", "libbar", "libotherapex"},
- },
- {
- name: "jni library dependency in platform",
- bpModifier: addToSharedLibs("libjni", "libplatform#impl"),
- dependencyPath: []string{"myapex", "libjni", "libplatform"},
- },
- {
- name: "transitive jni library dependency in platform",
- bpModifier: func(bp *bpmodify.Blueprint) {
- addToSharedLibs("libjni", "libbar")(bp)
- addToSharedLibs("libbar", "libplatform#impl")(bp)
- },
- dependencyPath: []string{"myapex", "libjni", "libbar", "libplatform"},
- },
- {
- name: "app jni library dependency in other apex",
- bpModifier: addToSharedLibs("libembeddedjni", "libotherapex#impl"),
- dependencyPath: []string{"myapex", "myapp", "libembeddedjni", "libotherapex"},
- },
- {
- name: "transitive app jni library dependency in other apex",
- bpModifier: func(bp *bpmodify.Blueprint) {
- addToSharedLibs("libembeddedjni", "libbar")(bp)
- addToSharedLibs("libbar", "libotherapex#impl")(bp)
- },
- dependencyPath: []string{"myapex", "myapp", "libembeddedjni", "libbar", "libotherapex"},
- },
- {
- name: "app jni library dependency in platform",
- bpModifier: addToSharedLibs("libembeddedjni", "libplatform#impl"),
- dependencyPath: []string{"myapex", "myapp", "libembeddedjni", "libplatform"},
- },
- {
- name: "transitive app jni library dependency in platform",
- bpModifier: func(bp *bpmodify.Blueprint) {
- addToSharedLibs("libembeddedjni", "libbar")(bp)
- addToSharedLibs("libbar", "libplatform#impl")(bp)
- },
- dependencyPath: []string{"myapex", "myapp", "libembeddedjni", "libbar", "libplatform"},
- },
- {
- name: "binary dependency in other apex",
- bpModifier: addToSharedLibs("mybin", "libotherapex#impl"),
- dependencyPath: []string{"myapex", "mybin", "libotherapex"},
- },
- {
- name: "transitive binary dependency in other apex",
- bpModifier: func(bp *bpmodify.Blueprint) {
- addToSharedLibs("mybin", "libbar")(bp)
- addToSharedLibs("libbar", "libotherapex#impl")(bp)
- },
- dependencyPath: []string{"myapex", "mybin", "libbar", "libotherapex"},
- },
- {
- name: "binary dependency in platform",
- bpModifier: addToSharedLibs("mybin", "libplatform#impl"),
- dependencyPath: []string{"myapex", "mybin", "libplatform"},
- },
- {
- name: "transitive binary dependency in platform",
- bpModifier: func(bp *bpmodify.Blueprint) {
- addToSharedLibs("mybin", "libbar")(bp)
- addToSharedLibs("libbar", "libplatform#impl")(bp)
- },
- dependencyPath: []string{"myapex", "mybin", "libbar", "libplatform"},
- },
-
- {
- name: "rust library dependency in other apex",
- bpModifier: addToSharedLibs("libmyrust", "libotherapex#impl"),
- dependencyPath: []string{"myapex", "libmyrust", "libotherapex"},
- },
- {
- name: "transitive rust library dependency in other apex",
- bpModifier: func(bp *bpmodify.Blueprint) {
- addToSharedLibs("libmyrust", "libbar")(bp)
- addToSharedLibs("libbar", "libotherapex#impl")(bp)
- },
- dependencyPath: []string{"myapex", "libmyrust", "libbar", "libotherapex"},
- },
- {
- name: "rust library dependency in platform",
- bpModifier: addToSharedLibs("libmyrust", "libplatform#impl"),
- dependencyPath: []string{"myapex", "libmyrust", "libplatform"},
- },
- {
- name: "transitive rust library dependency in platform",
- bpModifier: func(bp *bpmodify.Blueprint) {
- addToSharedLibs("libmyrust", "libbar")(bp)
- addToSharedLibs("libbar", "libplatform#impl")(bp)
- },
- dependencyPath: []string{"myapex", "libmyrust", "libbar", "libplatform"},
- },
- {
- name: "transitive rust library dylib dependency in other apex",
- bpModifier: func(bp *bpmodify.Blueprint) {
- addToSharedLibs("libmyrust_transitive_dylib", "libotherapex#impl")(bp)
- },
- dependencyPath: []string{"myapex", "libmyrust", "libmyrust_transitive_dylib", "libotherapex"},
- },
- {
- name: "transitive rust library dylib dependency in platform",
- bpModifier: func(bp *bpmodify.Blueprint) {
- addToSharedLibs("libmyrust_transitive_dylib", "libplatform#impl")(bp)
- },
- dependencyPath: []string{"myapex", "libmyrust", "libmyrust_transitive_dylib", "libplatform"},
- },
- {
- name: "transitive rust library rlib dependency in other apex",
- bpModifier: func(bp *bpmodify.Blueprint) {
- addToSharedLibs("libmyrust_transitive_rlib", "libotherapex#impl")(bp)
- },
- dependencyPath: []string{"myapex", "libmyrust", "libmyrust_transitive_rlib", "libotherapex"},
- },
- {
- name: "transitive rust library rlib dependency in platform",
- bpModifier: func(bp *bpmodify.Blueprint) {
- addToSharedLibs("libmyrust_transitive_rlib", "libplatform#impl")(bp)
- },
- dependencyPath: []string{"myapex", "libmyrust", "libmyrust_transitive_rlib", "libplatform"},
- },
- {
- name: "rust binary dependency in other apex",
- bpModifier: addToSharedLibs("myrustbin", "libotherapex#impl"),
- dependencyPath: []string{"myapex", "myrustbin", "libotherapex"},
- },
- {
- name: "transitive rust binary dependency in other apex",
- bpModifier: func(bp *bpmodify.Blueprint) {
- addToSharedLibs("myrustbin", "libbar")(bp)
- addToSharedLibs("libbar", "libotherapex#impl")(bp)
- },
- dependencyPath: []string{"myapex", "myrustbin", "libbar", "libotherapex"},
- },
- {
- name: "rust binary dependency in platform",
- bpModifier: addToSharedLibs("myrustbin", "libplatform#impl"),
- dependencyPath: []string{"myapex", "myrustbin", "libplatform"},
- },
- {
- name: "transitive rust binary dependency in platform",
- bpModifier: func(bp *bpmodify.Blueprint) {
- addToSharedLibs("myrustbin", "libbar")(bp)
- addToSharedLibs("libbar", "libplatform#impl")(bp)
- },
- dependencyPath: []string{"myapex", "myrustbin", "libbar", "libplatform"},
- },
- }
-
- for _, testCase := range testCases {
- t.Run(testCase.name, func(t *testing.T) {
- t.Parallel()
- bp, err := bpmodify.NewBlueprint("", []byte(bpTemplate))
- if err != nil {
- t.Fatal(err)
- }
- if testCase.bpModifier != nil {
- func() {
- defer func() {
- if r := recover(); r != nil {
- t.Fatalf("panic in bpModifier: %v", r)
- }
- }()
- testCase.bpModifier(bp)
- }()
- }
- android.GroupFixturePreparers(
- android.PrepareForTestWithAndroidBuildComponents,
- cc.PrepareForTestWithCcBuildComponents,
- java.PrepareForTestWithDexpreopt,
- rust.PrepareForTestWithRustDefaultModules,
- PrepareForTestWithApexBuildComponents,
- prepareForTestWithMyapex,
- prepareForTestWithOtherapex,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.BuildId = proptools.StringPtr("TEST.BUILD_ID")
- }),
- ).ExtendWithErrorHandler(android.FixtureCustomErrorHandler(checkErrors(testCase.dependencyPath))).
- RunTestWithBp(t, bp.String())
- })
- }
+ // Ensure that vintf fragment file is being installed
+ ensureContains(t, cmd, "/etc/vintf/my_vintf_fragment.xml ")
}
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index 71a8246..97644e6 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -242,6 +242,7 @@
apex_available: [
"com.android.art",
],
+ min_sdk_version: "33",
}
`, content)
}
@@ -291,6 +292,7 @@
apex_available: [
"com.android.art",
],
+ min_sdk_version: "33",
compile_dex: true,
}
`, content, prefer)
@@ -320,6 +322,7 @@
})
java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
+ `all_apex_contributions`,
`art-bootclasspath-fragment`,
`com.android.art.key`,
`dex2oatd`,
@@ -327,7 +330,7 @@
// Make sure that the source bootclasspath_fragment copies its dex files to the predefined
// locations for the art image.
- module := result.ModuleForTests("dex_bootjars", "android_common")
+ module := result.ModuleForTests(t, "dex_bootjars", "android_common")
checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
})
@@ -418,22 +421,24 @@
java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
).RunTest(t)
- ensureExactDeapexedContents(t, result.TestContext, "prebuilt_com.android.art", "android_common_com.android.art", []string{
+ ensureExactDeapexedContents(t, result.TestContext, "prebuilt_com.android.art", "android_common_prebuilt_com.android.art", []string{
"etc/boot-image.prof",
"javalib/bar.jar",
"javalib/foo.jar",
})
java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
+ `all_apex_contributions`,
`art-bootclasspath-fragment`,
`com.android.art.key`,
`dex2oatd`,
+ `prebuilt_art-bootclasspath-fragment`,
`prebuilt_com.android.art`,
})
// Make sure that the prebuilt bootclasspath_fragment copies its dex files to the predefined
// locations for the art image.
- module := result.ModuleForTests("dex_bootjars", "android_common")
+ module := result.ModuleForTests(t, "dex_bootjars", "android_common")
checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
})
@@ -586,20 +591,20 @@
t.Parallel()
result := preparers.RunTestWithBp(t, fmt.Sprintf(bp, "enabled: false,"))
- java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
+ java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_prebuilt_com.android.art", []string{
`all_apex_contributions`,
`dex2oatd`,
`prebuilt_art-bootclasspath-fragment`,
})
- java.CheckModuleDependencies(t, result.TestContext, "art-bootclasspath-fragment", "android_common_com.android.art", []string{
+ java.CheckModuleDependencies(t, result.TestContext, "art-bootclasspath-fragment", "android_common_prebuilt_com.android.art", []string{
`all_apex_contributions`,
`dex2oatd`,
`prebuilt_bar`,
`prebuilt_foo`,
})
- module := result.ModuleForTests("dex_bootjars", "android_common")
+ module := result.ModuleForTests(t, "dex_bootjars", "android_common")
checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
})
}
@@ -698,17 +703,18 @@
})
java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex", []string{
+ `all_apex_contributions`,
`dex2oatd`,
`myapex.key`,
`mybootclasspathfragment`,
})
- apex := result.ModuleForTests("myapex", "android_common_myapex")
+ apex := result.ModuleForTests(t, "myapex", "android_common_myapex")
apexRule := apex.Rule("apexRule")
copyCommands := apexRule.Args["copy_commands"]
// Make sure that the fragment provides the hidden API encoded dex jars to the APEX.
- fragment := result.Module("mybootclasspathfragment", "android_common_apex10000")
+ fragment := result.Module("mybootclasspathfragment", "android_common_myapex")
info, _ := android.OtherModuleProvider(result, fragment, java.BootclasspathFragmentApexContentInfoProvider)
@@ -724,8 +730,8 @@
android.AssertStringDoesContain(t, name+" apex copy command", copyCommands, expectedCopyCommand)
}
- checkFragmentExportedDexJar("foo", "out/soong/.intermediates/mybootclasspathfragment/android_common_apex10000/hiddenapi-modular/encoded/foo.jar")
- checkFragmentExportedDexJar("bar", "out/soong/.intermediates/mybootclasspathfragment/android_common_apex10000/hiddenapi-modular/encoded/bar.jar")
+ checkFragmentExportedDexJar("foo", "out/soong/.intermediates/mybootclasspathfragment/android_common_myapex/hiddenapi-modular/encoded/foo.jar")
+ checkFragmentExportedDexJar("bar", "out/soong/.intermediates/mybootclasspathfragment/android_common_myapex/hiddenapi-modular/encoded/bar.jar")
}
func getDexJarPath(result *android.TestResult, name string) string {
@@ -856,10 +862,10 @@
}
`)
- java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{
+ java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_myapex", []string{
"all_apex_contributions",
- "art-bootclasspath-fragment",
"bar",
+ "com.android.art",
"dex2oatd",
"foo",
})
@@ -871,7 +877,7 @@
quuzModuleLibStubs := getDexJarPath(result, "quuz.stubs.exportable.module_lib")
// Make sure that the fragment uses the quuz stub dex jars when generating the hidden API flags.
- fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
+ fragment := result.ModuleForTests(t, "mybootclasspathfragment", "android_common_myapex")
rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
command := rule.RuleParams.Command
@@ -1029,14 +1035,14 @@
}
`)
- java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{
+ java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_myapex", []string{
"all_apex_contributions",
"android-non-updatable.stubs",
"android-non-updatable.stubs.module_lib",
"android-non-updatable.stubs.system",
"android-non-updatable.stubs.test",
- "art-bootclasspath-fragment",
"bar",
+ "com.android.art",
"dex2oatd",
"foo",
})
@@ -1048,7 +1054,7 @@
// Make sure that the fragment uses the android-non-updatable modules when generating the hidden
// API flags.
- fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
+ fragment := result.ModuleForTests(t, "mybootclasspathfragment", "android_common_myapex")
rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
command := rule.RuleParams.Command
@@ -1203,14 +1209,14 @@
}
`)
- java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{
+ java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_myapex", []string{
"all_apex_contributions",
"android-non-updatable.stubs",
"android-non-updatable.stubs.system",
"android-non-updatable.stubs.test",
"android-non-updatable.stubs.test_module_lib",
- "art-bootclasspath-fragment",
"bar",
+ "com.android.art",
"dex2oatd",
"foo",
})
@@ -1219,7 +1225,7 @@
// Make sure that the fragment uses the android-non-updatable modules when generating the hidden
// API flags.
- fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
+ fragment := result.ModuleForTests(t, "mybootclasspathfragment", "android_common_myapex")
rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
command := rule.RuleParams.Command
@@ -1358,10 +1364,10 @@
}
`)
- java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{
+ java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_myapex", []string{
"all_apex_contributions",
- "art-bootclasspath-fragment",
"bar",
+ "com.android.art",
"dex2oatd",
"foo",
"prebuilt_sdk_module-lib_current_android-non-updatable",
@@ -1377,7 +1383,7 @@
// Make sure that the fragment uses the android-non-updatable modules when generating the hidden
// API flags.
- fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
+ fragment := result.ModuleForTests(t, "mybootclasspathfragment", "android_common_myapex")
rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
command := rule.RuleParams.Command
@@ -1460,7 +1466,7 @@
}
`)
- fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
+ fragment := result.ModuleForTests(t, "mybootclasspathfragment", "android_common_myapex")
classPathProtoContent := android.ContentFromFileRuleForTests(t, result.TestContext, fragment.Output("bootclasspath.pb.textproto"))
// foo
ensureContains(t, classPathProtoContent, `jars {
diff --git a/apex/builder.go b/apex/builder.go
index 641aa27..15737f8 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -20,12 +20,14 @@
"path"
"path/filepath"
"runtime"
+ "slices"
"sort"
"strconv"
"strings"
"android/soong/aconfig"
"android/soong/android"
+ "android/soong/dexpreopt"
"android/soong/java"
"github.com/google/blueprint"
@@ -522,9 +524,10 @@
})
}
-func isVintfFragment(fi apexFile) bool {
+func shouldApplyAssembleVintf(fi apexFile) bool {
isVintfFragment, _ := path.Match("etc/vintf/*", fi.path())
- return isVintfFragment
+ _, fromVintfFragmentModule := fi.module.(*android.VintfFragmentModule)
+ return isVintfFragment && !fromVintfFragmentModule
}
func runAssembleVintf(ctx android.ModuleContext, vintfFragment android.Path) android.Path {
@@ -538,6 +541,64 @@
return processed
}
+// installApexSystemServerFiles installs dexpreopt and dexjar files for system server classpath entries
+// provided by the apex. They are installed here instead of in library module because there may be multiple
+// variants of the library, generally one for the "main" apex and another with a different min_sdk_version
+// for the Android Go version of the apex. Both variants would attempt to install to the same locations,
+// and the library variants cannot determine which one should. The apex module is better equipped to determine
+// if it is "selected".
+// This assumes that the jars produced by different min_sdk_version values are identical, which is currently
+// true but may not be true if the min_sdk_version difference between the variants spans version that changed
+// the dex format.
+func (a *apexBundle) installApexSystemServerFiles(ctx android.ModuleContext) {
+ // If performInstalls is set this module is responsible for creating the install rules.
+ performInstalls := a.GetOverriddenBy() == "" && !a.testApex && a.installable()
+ // TODO(b/234351700): Remove once ART does not have separated debug APEX, or make the selection
+ // explicit in the ART Android.bp files.
+ if ctx.Config().UseDebugArt() {
+ if ctx.ModuleName() == "com.android.art" {
+ performInstalls = false
+ }
+ } else {
+ if ctx.ModuleName() == "com.android.art.debug" {
+ performInstalls = false
+ }
+ }
+
+ psi := android.PrebuiltSelectionInfoMap{}
+ ctx.VisitDirectDeps(func(am android.Module) {
+ if info, exists := android.OtherModuleProvider(ctx, am, android.PrebuiltSelectionInfoProvider); exists {
+ psi = info
+ }
+ })
+
+ if len(psi.GetSelectedModulesForApiDomain(ctx.ModuleName())) > 0 {
+ performInstalls = false
+ }
+
+ for _, fi := range a.filesInfo {
+ for _, install := range fi.systemServerDexpreoptInstalls {
+ var installedFile android.InstallPath
+ if performInstalls {
+ installedFile = ctx.InstallFile(install.InstallDirOnDevice, install.InstallFileOnDevice, install.OutputPathOnHost)
+ } else {
+ // Another module created the install rules, but this module should still depend on
+ // the installed locations.
+ installedFile = install.InstallDirOnDevice.Join(ctx, install.InstallFileOnDevice)
+ }
+ a.extraInstalledFiles = append(a.extraInstalledFiles, installedFile)
+ a.extraInstalledPairs = append(a.extraInstalledPairs, installPair{install.OutputPathOnHost, installedFile})
+ }
+ if performInstalls {
+ for _, dexJar := range fi.systemServerDexJars {
+ // Copy the system server dex jar to a predefined location where dex2oat will find it.
+ android.CopyFileRule(ctx, dexJar,
+ android.PathForOutput(ctx, dexpreopt.SystemServerDexjarsDir, dexJar.Base()))
+ }
+ }
+ }
+}
+
// buildApex creates build rules to build an APEX using apexer.
func (a *apexBundle) buildApex(ctx android.ModuleContext) {
suffix := imageApexSuffix
@@ -548,7 +609,7 @@
imageDir := android.PathForModuleOut(ctx, "image"+suffix)
- installSymbolFiles := (ctx.Config().KatiEnabled() && a.ExportedToMake()) && a.installable()
+ installSymbolFiles := a.ExportedToMake() && a.installable()
// set of dependency module:location mappings
installMapSet := make(map[string]bool)
@@ -575,7 +636,7 @@
copyCommands = append(copyCommands, "ln -sfn "+pathOnDevice+" "+destPath)
} else {
// Copy the file into APEX
- if !a.testApex && isVintfFragment(fi) {
+ if !a.testApex && shouldApplyAssembleVintf(fi) {
// copy the output of assemble_vintf instead of the original
vintfFragment := runAssembleVintf(ctx, fi.builtFile)
copyCommands = append(copyCommands, "cp -f "+vintfFragment.String()+" "+destPath)
@@ -599,7 +660,7 @@
} else {
if installSymbolFiles {
// store installedPath. symlinks might be created if required.
- installedPath = apexDir.Join(ctx, fi.installDir, fi.stem())
+ installedPath = ctx.InstallFile(apexDir.Join(ctx, fi.installDir), fi.stem(), fi.builtFile)
}
}
@@ -981,9 +1042,9 @@
a.SkipInstall()
}
+ installDeps := slices.Concat(a.compatSymlinks, a.extraInstalledFiles)
// Install to $OUT/soong/{target,host}/.../apex.
- a.installedFile = ctx.InstallFile(a.installDir, a.Name()+installSuffix, a.outputFile,
- a.compatSymlinks...)
+ a.installedFile = ctx.InstallFile(a.installDir, a.Name()+installSuffix, a.outputFile, installDeps...)
// installed-files.txt is dist'ed
a.installedFilesFile = a.buildInstalledFilesFile(ctx, a.outputFile, imageDir)
@@ -1040,7 +1101,7 @@
}
depInfos := android.DepNameToDepInfoMap{}
- a.WalkPayloadDepsProxy(ctx, func(ctx android.BaseModuleContext, from, to android.ModuleProxy, externalDep bool) bool {
+ a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from android.Module, to android.ApexModule, externalDep bool) bool {
if from.Name() == to.Name() {
// This can happen for cc.reuseObjTag. We are not interested in tracking this.
// As soon as the dependency graph crosses the APEX boundary, don't go further.
@@ -1067,10 +1128,9 @@
depInfos[to.Name()] = info
} else {
toMinSdkVersion := "(no version)"
- if info, ok := android.OtherModuleProvider(ctx, to, android.CommonModuleInfoKey); ok {
- if v := info.MinSdkVersion; v != "" {
- toMinSdkVersion = v
- }
+ if info, ok := android.OtherModuleProvider(ctx, to, android.CommonModuleInfoKey); ok &&
+ !info.MinSdkVersion.IsPlatform && info.MinSdkVersion.ApiLevel != nil {
+ toMinSdkVersion = info.MinSdkVersion.ApiLevel.String()
}
depInfos[to.Name()] = android.ApexModuleDepInfo{
To: to.Name(),
@@ -1198,6 +1258,22 @@
return timestamp
}
+// Can't use PartitionTag() because PartitionTag() returns the partition this module is actually
+// installed (e.g. PartitionTag() may return "system" for vendor apex when vendor is linked to /system/vendor)
+func (a *apexBundle) partition() string {
+ if a.SocSpecific() {
+ return "vendor"
+ } else if a.DeviceSpecific() {
+ return "odm"
+ } else if a.ProductSpecific() {
+ return "product"
+ } else if a.SystemExtSpecific() {
+ return "system_ext"
+ } else {
+ return "system"
+ }
+}
+
// Runs apex_sepolicy_tests
//
// $ apex-ls -Z {apex_file} > {file_contexts}
@@ -1209,7 +1285,7 @@
Input: apexFile,
Output: timestamp,
Args: map[string]string{
- "partition_tag": a.PartitionTag(ctx.DeviceConfig()),
+ "partition_tag": a.partition(),
},
})
return timestamp
@@ -1236,7 +1312,7 @@
Input: apexFile,
Output: timestamp,
Args: map[string]string{
- "partition_tag": a.PartitionTag(ctx.DeviceConfig()),
+ "partition_tag": a.partition(),
},
})
return timestamp
diff --git a/apex/classpath_element_test.go b/apex/classpath_element_test.go
index f367174..c2f2fc5 100644
--- a/apex/classpath_element_test.go
+++ b/apex/classpath_element_test.go
@@ -198,15 +198,13 @@
result := preparer.RunTest(t)
- artFragment := result.Module("art-bootclasspath-fragment", "android_common_apex10000")
+ artFragment := result.Module("art-bootclasspath-fragment", "android_common_com.android.art")
artBaz := result.Module("baz", "android_common_apex10000")
artQuuz := result.Module("quuz", "android_common_apex10000")
- myFragment := result.Module("mybootclasspath-fragment", "android_common_apex10000")
+ myFragment := result.Module("mybootclasspath-fragment", "android_common_myapex")
myBar := result.Module("bar", "android_common_apex10000")
- other := result.Module("othersdklibrary", "android_common_apex10000")
-
otherApexLibrary := result.Module("otherapexlibrary", "android_common_apex10000")
platformFoo := result.Module("quuz", "android_common")
@@ -240,7 +238,11 @@
t.Run("art:baz, art:quuz, my:bar, foo", func(t *testing.T) {
t.Parallel()
ctx := newCtx()
- elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, artQuuz, myBar, platformFoo}, []android.Module{artFragment, myFragment})
+ elements := java.CreateClasspathElements(ctx,
+ []android.Module{artBaz, artQuuz, myBar, platformFoo},
+ []android.Module{artFragment, myFragment},
+ map[android.Module]string{artBaz: "com.android.art", artQuuz: "com.android.art", myBar: "myapex"},
+ map[string]android.Module{"com.android.art": artFragment, "myapex": myFragment})
expectedElements := java.ClasspathElements{
expectFragmentElement(artFragment, artBaz, artQuuz),
expectFragmentElement(myFragment, myBar),
@@ -249,32 +251,16 @@
assertElementsEquals(t, "elements", expectedElements, elements)
})
- // Verify that CreateClasspathElements detects when an apex has multiple fragments.
- t.Run("multiple fragments for same apex", func(t *testing.T) {
- t.Parallel()
- ctx := newCtx()
- elements := java.CreateClasspathElements(ctx, []android.Module{}, []android.Module{artFragment, artFragment})
- android.FailIfNoMatchingErrors(t, "apex com.android.art has multiple fragments, art-bootclasspath-fragment{.*} and art-bootclasspath-fragment{.*}", ctx.errs)
- expectedElements := java.ClasspathElements{}
- assertElementsEquals(t, "elements", expectedElements, elements)
- })
-
- // Verify that CreateClasspathElements detects when a library is in multiple fragments.
- t.Run("library from multiple fragments", func(t *testing.T) {
- t.Parallel()
- ctx := newCtx()
- elements := java.CreateClasspathElements(ctx, []android.Module{other}, []android.Module{artFragment, myFragment})
- android.FailIfNoMatchingErrors(t, "library othersdklibrary{.*} is in two separate fragments, art-bootclasspath-fragment{.*} and mybootclasspath-fragment{.*}", ctx.errs)
- expectedElements := java.ClasspathElements{}
- assertElementsEquals(t, "elements", expectedElements, elements)
- })
-
// Verify that CreateClasspathElements detects when a fragment's contents are not contiguous and
// are separated by a library from another fragment.
t.Run("discontiguous separated by fragment", func(t *testing.T) {
t.Parallel()
ctx := newCtx()
- elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, myBar, artQuuz, platformFoo}, []android.Module{artFragment, myFragment})
+ elements := java.CreateClasspathElements(ctx,
+ []android.Module{artBaz, myBar, artQuuz, platformFoo},
+ []android.Module{artFragment, myFragment},
+ map[android.Module]string{artBaz: "com.android.art", artQuuz: "com.android.art", myBar: "myapex"},
+ map[string]android.Module{"com.android.art": artFragment, "myapex": myFragment})
expectedElements := java.ClasspathElements{
expectFragmentElement(artFragment, artBaz, artQuuz),
expectFragmentElement(myFragment, myBar),
@@ -289,7 +275,11 @@
t.Run("discontiguous separated by library", func(t *testing.T) {
t.Parallel()
ctx := newCtx()
- elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, platformFoo, artQuuz, myBar}, []android.Module{artFragment, myFragment})
+ elements := java.CreateClasspathElements(ctx,
+ []android.Module{artBaz, platformFoo, artQuuz, myBar},
+ []android.Module{artFragment, myFragment},
+ map[android.Module]string{artBaz: "com.android.art", artQuuz: "com.android.art", myBar: "myapex"},
+ map[string]android.Module{"com.android.art": artFragment, "myapex": myFragment})
expectedElements := java.ClasspathElements{
expectFragmentElement(artFragment, artBaz, artQuuz),
expectLibraryElement(platformFoo),
@@ -305,7 +295,11 @@
t.Run("no fragment for apex", func(t *testing.T) {
t.Parallel()
ctx := newCtx()
- elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, otherApexLibrary}, []android.Module{artFragment})
+ elements := java.CreateClasspathElements(ctx,
+ []android.Module{artBaz, otherApexLibrary},
+ []android.Module{artFragment},
+ map[android.Module]string{artBaz: "com.android.art", otherApexLibrary: "otherapex"},
+ map[string]android.Module{"com.android.art": artFragment})
expectedElements := java.ClasspathElements{
expectFragmentElement(artFragment, artBaz),
}
diff --git a/apex/container_test.go b/apex/container_test.go
index 395793f..b19e050 100644
--- a/apex/container_test.go
+++ b/apex/container_test.go
@@ -29,6 +29,7 @@
func TestApexDepsContainers(t *testing.T) {
t.Parallel()
+ t.Skip("TODO(b/394955484): this probably has to be moved to a check by the apex")
result := android.GroupFixturePreparers(
prepareForApexTest,
java.PrepareForTestWithJavaSdkLibraryFiles,
@@ -156,7 +157,7 @@
}
for _, c := range testcases {
- m := result.ModuleForTests(c.moduleName, c.variant)
+ m := result.ModuleForTests(t, c.moduleName, c.variant)
containers, _ := android.OtherModuleProvider(result.TestContext.OtherModuleProviderAdaptor(), m.Module(), android.ContainersInfoProvider)
belongingContainers := containers.BelongingContainers()
checkContainerMatch(t, c.moduleName, "system", c.isSystemContainer, android.InList(android.SystemContainer, belongingContainers))
@@ -166,6 +167,7 @@
func TestNonUpdatableApexDepsContainers(t *testing.T) {
t.Parallel()
+ t.Skip("TODO(b/394955484): this probably has to be moved to a check by the apex")
result := android.GroupFixturePreparers(
prepareForApexTest,
java.PrepareForTestWithJavaSdkLibraryFiles,
@@ -271,7 +273,7 @@
}
for _, c := range testcases {
- m := result.ModuleForTests(c.moduleName, c.variant)
+ m := result.ModuleForTests(t, c.moduleName, c.variant)
containers, _ := android.OtherModuleProvider(result.TestContext.OtherModuleProviderAdaptor(), m.Module(), android.ContainersInfoProvider)
belongingContainers := containers.BelongingContainers()
checkContainerMatch(t, c.moduleName, "system", c.isSystemContainer, android.InList(android.SystemContainer, belongingContainers))
@@ -281,6 +283,7 @@
func TestUpdatableAndNonUpdatableApexesIdenticalMinSdkVersion(t *testing.T) {
t.Parallel()
+ t.Skip("TODO(b/394955484): this probably has to be moved to a check by the apex")
result := android.GroupFixturePreparers(
prepareForApexTest,
java.PrepareForTestWithJavaSdkLibraryFiles,
@@ -334,7 +337,7 @@
}
`)
- fooApexVariant := result.ModuleForTests("foo", "android_common_apex30")
+ fooApexVariant := result.ModuleForTests(t, "foo", "android_common_apex30")
containers, _ := android.OtherModuleProvider(result.TestContext.OtherModuleProviderAdaptor(), fooApexVariant.Module(), android.ContainersInfoProvider)
belongingContainers := containers.BelongingContainers()
checkContainerMatch(t, "foo", "system", true, android.InList(android.SystemContainer, belongingContainers))
diff --git a/apex/dexpreopt_bootjars_test.go b/apex/dexpreopt_bootjars_test.go
index b51bb36..2c7c459 100644
--- a/apex/dexpreopt_bootjars_test.go
+++ b/apex/dexpreopt_bootjars_test.go
@@ -151,7 +151,7 @@
}
result := fixture.RunTestWithBp(t, fmt.Sprintf(bp, preferPrebuilt))
- dexBootJars := result.ModuleForTests("dex_bootjars", "android_common")
+ dexBootJars := result.ModuleForTests(t, "dex_bootjars", "android_common")
rule := dexBootJars.Output(ruleFile)
inputs := rule.Implicits.Strings()
@@ -176,7 +176,7 @@
"out/soong/dexpreopt_arm64/dex_bootjars_input/foo.jar",
"out/soong/dexpreopt_arm64/dex_bootjars_input/bar.jar",
"out/soong/dexpreopt_arm64/dex_bootjars_input/baz.jar",
- "out/soong/.intermediates/art-bootclasspath-fragment/android_common_apex10000/art-bootclasspath-fragment/boot.prof",
+ "out/soong/.intermediates/art-bootclasspath-fragment/android_common_com.android.art/art-bootclasspath-fragment/boot.prof",
"out/soong/.intermediates/default/java/dex_bootjars/android_common/boot/boot.prof",
"out/soong/dexpreopt/uffd_gc_flag.txt",
}
@@ -215,7 +215,7 @@
"out/soong/dexpreopt_arm64/dex_bootjars_input/foo.jar",
"out/soong/dexpreopt_arm64/dex_bootjars_input/bar.jar",
"out/soong/dexpreopt_arm64/dex_bootjars_input/baz.jar",
- "out/soong/.intermediates/prebuilt_com.android.art/android_common_com.android.art/deapexer/etc/boot-image.prof",
+ "out/soong/.intermediates/prebuilt_com.android.art/android_common_prebuilt_com.android.art/deapexer/etc/boot-image.prof",
"out/soong/.intermediates/default/java/dex_bootjars/android_common/boot/boot.prof",
"out/soong/dexpreopt/uffd_gc_flag.txt",
}
@@ -396,17 +396,17 @@
{
desc: "Source apex com.android.art is selected, profile should come from source java library",
selectedArtApexContributions: "art.source.contributions",
- expectedProfile: "out/soong/.intermediates/art-bootclasspath-fragment/android_common_apex10000/art-bootclasspath-fragment/boot.prof",
+ expectedProfile: "out/soong/.intermediates/art-bootclasspath-fragment/android_common_com.android.art/art-bootclasspath-fragment/boot.prof",
},
{
desc: "Prebuilt apex prebuilt_com.android.art is selected, profile should come from .prof deapexed from the prebuilt",
selectedArtApexContributions: "art.prebuilt.contributions",
- expectedProfile: "out/soong/.intermediates/prebuilt_com.android.art/android_common_com.android.art/deapexer/etc/boot-image.prof",
+ expectedProfile: "out/soong/.intermediates/prebuilt_com.android.art/android_common_prebuilt_com.android.art/deapexer/etc/boot-image.prof",
},
{
desc: "Prebuilt apex prebuilt_com.android.art.v2 is selected, profile should come from .prof deapexed from the prebuilt",
selectedArtApexContributions: "art.prebuilt.v2.contributions",
- expectedProfile: "out/soong/.intermediates/com.android.art.v2/android_common_com.android.art/deapexer/etc/boot-image.prof",
+ expectedProfile: "out/soong/.intermediates/com.android.art.v2/android_common_prebuilt_com.android.art/deapexer/etc/boot-image.prof",
},
}
for _, tc := range testCases {
@@ -419,7 +419,7 @@
android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART", tc.selectedArtApexContributions),
).RunTestWithBp(t, bp)
- dexBootJars := result.ModuleForTests("dex_bootjars", "android_common")
+ dexBootJars := result.ModuleForTests(t, "dex_bootjars", "android_common")
rule := dexBootJars.Output(ruleFile)
inputs := rule.Implicits.Strings()
diff --git a/apex/key.go b/apex/key.go
index 1622c65..cc66a13 100644
--- a/apex/key.go
+++ b/apex/key.go
@@ -33,6 +33,13 @@
ctx.RegisterParallelSingletonModuleType("all_apex_certs", allApexCertsFactory)
}
+type ApexKeyInfo struct {
+ PublicKeyFile android.Path
+ PrivateKeyFile android.Path
+}
+
+var ApexKeyInfoProvider = blueprint.NewProvider[ApexKeyInfo]()
+
type apexKey struct {
android.ModuleBase
@@ -95,6 +102,11 @@
m.publicKeyFile.String(), pubKeyName, m.privateKeyFile, privKeyName)
return
}
+
+ android.SetProvider(ctx, ApexKeyInfoProvider, ApexKeyInfo{
+ PublicKeyFile: m.publicKeyFile,
+ PrivateKeyFile: m.privateKeyFile,
+ })
}
type apexKeyEntry struct {
diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go
index c13d599..d79af86 100644
--- a/apex/platform_bootclasspath_test.go
+++ b/apex/platform_bootclasspath_test.go
@@ -23,7 +23,6 @@
"android/soong/dexpreopt"
"android/soong/java"
- "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -165,12 +164,12 @@
android.AssertPathsRelativeToTopEquals(t, message, expected, info.FlagsFilesByCategory[category])
}
- android.AssertPathsRelativeToTopEquals(t, "annotation flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/annotation-flags.csv"}, info.AnnotationFlagsPaths)
- android.AssertPathsRelativeToTopEquals(t, "metadata flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/metadata.csv"}, info.MetadataPaths)
- android.AssertPathsRelativeToTopEquals(t, "index flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/index.csv"}, info.IndexPaths)
+ android.AssertPathsRelativeToTopEquals(t, "annotation flags", []string{"out/soong/.intermediates/bar-fragment/android_common_myapex/modular-hiddenapi/annotation-flags.csv"}, info.AnnotationFlagsPaths)
+ android.AssertPathsRelativeToTopEquals(t, "metadata flags", []string{"out/soong/.intermediates/bar-fragment/android_common_myapex/modular-hiddenapi/metadata.csv"}, info.MetadataPaths)
+ android.AssertPathsRelativeToTopEquals(t, "index flags", []string{"out/soong/.intermediates/bar-fragment/android_common_myapex/modular-hiddenapi/index.csv"}, info.IndexPaths)
- android.AssertArrayString(t, "stub flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/filtered-stub-flags.csv:out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/signature-patterns.csv"}, info.StubFlagSubsets.RelativeToTop())
- android.AssertArrayString(t, "all flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/filtered-flags.csv:out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop())
+ android.AssertArrayString(t, "stub flags", []string{"out/soong/.intermediates/bar-fragment/android_common_myapex/modular-hiddenapi/filtered-stub-flags.csv:out/soong/.intermediates/bar-fragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv"}, info.StubFlagSubsets.RelativeToTop())
+ android.AssertArrayString(t, "all flags", []string{"out/soong/.intermediates/bar-fragment/android_common_myapex/modular-hiddenapi/filtered-flags.csv:out/soong/.intermediates/bar-fragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop())
}
// TestPlatformBootclasspath_LegacyPrebuiltFragment verifies that the
@@ -240,8 +239,8 @@
pbcp := result.Module("myplatform-bootclasspath", "android_common")
info, _ := android.OtherModuleProvider(result, pbcp, java.MonolithicHiddenAPIInfoProvider)
- android.AssertArrayString(t, "stub flags", []string{"prebuilt-stub-flags.csv:out/soong/.intermediates/mybootclasspath-fragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv"}, info.StubFlagSubsets.RelativeToTop())
- android.AssertArrayString(t, "all flags", []string{"prebuilt-all-flags.csv:out/soong/.intermediates/mybootclasspath-fragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop())
+ android.AssertArrayString(t, "stub flags", []string{"prebuilt-stub-flags.csv:out/soong/.intermediates/mybootclasspath-fragment/android_common_prebuilt_myapex/modular-hiddenapi/signature-patterns.csv"}, info.StubFlagSubsets.RelativeToTop())
+ android.AssertArrayString(t, "all flags", []string{"prebuilt-all-flags.csv:out/soong/.intermediates/mybootclasspath-fragment/android_common_prebuilt_myapex/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop())
}
func TestPlatformBootclasspathDependencies(t *testing.T) {
@@ -388,7 +387,7 @@
})
// Make sure that the myplatform-bootclasspath has the correct dependencies.
- CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{
+ java.CheckPlatformBootclasspathDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{
// source vs prebuilt selection metadata module
`platform:all_apex_contributions`,
@@ -401,17 +400,17 @@
// Needed for generating the boot image.
`platform:dex2oatd`,
- // The configured contents of BootJars.
- `com.android.art:baz`,
- `com.android.art:quuz`,
+ // The configured contents of BootJars, via their apexes if necessary.
+ `platform:com.android.art`,
+ `platform:com.android.art`,
`platform:foo`,
- // The configured contents of ApexBootJars.
- `myapex:bar`,
+ // The configured contents of ApexBootJars, via their apex.
+ `platform:myapex`,
- // The fragments.
- `com.android.art:art-bootclasspath-fragment`,
- `myapex:my-bootclasspath-fragment`,
+ // The fragments via their apexes.
+ `platform:com.android.art`,
+ `platform:myapex`,
// Impl lib of sdk_library for transitive srcjar generation
`platform:foo.impl`,
@@ -429,7 +428,7 @@
// of AlwaysUsePrebuiltsSdk(). The second is a normal library that is unaffected. The order
// matters, so that the dependencies resolved by the platform_bootclasspath matches the
// configured list.
- java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
+ java.FixtureConfigureApexBootJars("myapex:foo"),
java.PrepareForTestWithJavaSdkLibraryFiles,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
@@ -479,6 +478,7 @@
name: "myapex",
src: "myapex.apex",
exported_bootclasspath_fragments: ["mybootclasspath-fragment"],
+ prefer: true,
}
// A prebuilt java_sdk_library_import that is not preferred by default but will be preferred
@@ -544,12 +544,11 @@
java.CheckPlatformBootclasspathModules(t, result, "myplatform-bootclasspath", []string{
// The configured contents of BootJars.
- "myapex:prebuilt_foo",
- "myapex:bar",
+ "prebuilt_myapex:prebuilt_foo",
})
// Make sure that the myplatform-bootclasspath has the correct dependencies.
- CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{
+ java.CheckPlatformBootclasspathDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{
// source vs prebuilt selection metadata module
`platform:all_apex_contributions`,
@@ -561,39 +560,17 @@
// Not a prebuilt as no prebuilt existed when it was added.
"platform:legacy.core.platform.api.stubs.exportable",
- // The platform_bootclasspath intentionally adds dependencies on both source and prebuilt
- // modules when available as it does not know which one will be preferred.
- "myapex:foo",
- "myapex:prebuilt_foo",
+ // The prebuilt library via the apex.
+ "platform:prebuilt_myapex",
- // Only a source module exists.
- "myapex:bar",
-
- // The fragments.
- "myapex:mybootclasspath-fragment",
- "myapex:prebuilt_mybootclasspath-fragment",
+ // The fragments via the apex.
+ "platform:prebuilt_myapex",
// Impl lib of sdk_library for transitive srcjar generation
"platform:foo.impl",
})
}
-// CheckModuleDependencies checks the dependencies of the selected module against the expected list.
-//
-// The expected list must be a list of strings of the form "<apex>:<module>", where <apex> is the
-// name of the apex, or platform is it is not part of an apex and <module> is the module name.
-func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) {
- t.Helper()
- module := ctx.ModuleForTests(name, variant).Module()
- modules := []android.Module{}
- ctx.VisitDirectDeps(module, func(m blueprint.Module) {
- modules = append(modules, m.(android.Module))
- })
-
- pairs := java.ApexNamePairsFromModules(ctx, modules)
- android.AssertDeepEquals(t, "module dependencies", expected, pairs)
-}
-
// TestPlatformBootclasspath_IncludesRemainingApexJars verifies that any apex boot jar is present in
// platform_bootclasspath's classpaths.proto config, if the apex does not generate its own config
// by setting generate_classpaths_proto property to false.
@@ -665,7 +642,7 @@
prepareForTestWithMyapex,
java.FixtureConfigureApexBootJars("myapex:foo"),
).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
- `dependency "foo" of "myplatform-bootclasspath" missing variant`)).
+ `module "myplatform-bootclasspath" variant ".*": failed to find module "foo" in apex "myapex"`)).
RunTestWithBp(t, `
apex {
name: "myapex",
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index aaf2cb7..3daa4f8 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -15,6 +15,7 @@
package apex
import (
+ "slices"
"strconv"
"strings"
@@ -59,10 +60,12 @@
// Properties common to both prebuilt_apex and apex_set.
prebuiltCommonProperties *PrebuiltCommonProperties
- installDir android.InstallPath
- installFilename string
- installedFile android.InstallPath
- outputApex android.WritablePath
+ installDir android.InstallPath
+ installFilename string
+ installedFile android.InstallPath
+ extraInstalledFiles android.InstallPaths
+ extraInstalledPairs installPairs
+ outputApex android.WritablePath
// fragment for this apex for apexkeys.txt
apexKeysPath android.WritablePath
@@ -70,8 +73,12 @@
// Installed locations of symlinks for backward compatibility.
compatSymlinks android.InstallPaths
- hostRequired []string
- requiredModuleNames []string
+ // systemServerDexpreoptInstalls stores the list of dexpreopt artifacts for a system server jar.
+ systemServerDexpreoptInstalls []java.DexpreopterInstall
+
+ // systemServerDexJars stores the list of dexjars for system server jars in the prebuilt for use when
+ // dexpreopting system server jars that are later in the system server classpath.
+ systemServerDexJars android.Paths
}
type sanitizedPrebuilt interface {
@@ -188,9 +195,8 @@
// initApexFilesForAndroidMk initializes the prebuiltCommon.requiredModuleNames field with the install only deps of the prebuilt apex
func (p *prebuiltCommon) initApexFilesForAndroidMk(ctx android.ModuleContext) {
// If this apex contains a system server jar, then the dexpreopt artifacts should be added as required
- for _, install := range p.Dexpreopter.DexpreoptBuiltInstalledForApex() {
- p.requiredModuleNames = append(p.requiredModuleNames, install.FullModuleName())
- }
+ p.systemServerDexpreoptInstalls = append(p.systemServerDexpreoptInstalls, p.Dexpreopter.ApexSystemServerDexpreoptInstalls()...)
+ p.systemServerDexJars = append(p.systemServerDexJars, p.Dexpreopter.ApexSystemServerDexJars()...)
}
// If this prebuilt has system server jar, create the rules to dexpreopt it and install it alongside the prebuilt apex
@@ -218,38 +224,58 @@
}
}
-func (p *prebuiltCommon) addRequiredModules(entries *android.AndroidMkEntries) {
- entries.AddStrings("LOCAL_REQUIRED_MODULES", p.requiredModuleNames...)
+// installApexSystemServerFiles installs dexpreopt files for system server classpath entries
+// provided by the apex. They are installed here instead of in library module because there may be multiple
+// variants of the library, generally one for the "main" apex and another with a different min_sdk_version
+// for the Android Go version of the apex. Both variants would attempt to install to the same locations,
+// and the library variants cannot determine which one should. The apex module is better equipped to determine
+// if it is "selected".
+// This assumes that the jars produced by different min_sdk_version values are identical, which is currently
+// true but may not be true if the min_sdk_version difference between the variants spans version that changed
+// the dex format.
+func (p *prebuiltCommon) installApexSystemServerFiles(ctx android.ModuleContext) {
+ performInstalls := android.IsModulePreferred(ctx.Module())
+
+ for _, install := range p.systemServerDexpreoptInstalls {
+ var installedFile android.InstallPath
+ if performInstalls {
+ installedFile = ctx.InstallFile(install.InstallDirOnDevice, install.InstallFileOnDevice, install.OutputPathOnHost)
+ } else {
+ installedFile = install.InstallDirOnDevice.Join(ctx, install.InstallFileOnDevice)
+ }
+ p.extraInstalledFiles = append(p.extraInstalledFiles, installedFile)
+ p.extraInstalledPairs = append(p.extraInstalledPairs, installPair{install.OutputPathOnHost, installedFile})
+ }
+
+ for _, dexJar := range p.systemServerDexJars {
+ // Copy the system server dex jar to a predefined location where dex2oat will find it.
+ android.CopyFileRule(ctx, dexJar,
+ android.PathForOutput(ctx, dexpreopt.SystemServerDexjarsDir, dexJar.Base()))
+ }
}
func (p *prebuiltCommon) AndroidMkEntries() []android.AndroidMkEntries {
entriesList := []android.AndroidMkEntries{
{
- Class: "ETC",
- OutputFile: android.OptionalPathForPath(p.outputApex),
- Include: "$(BUILD_PREBUILT)",
- Host_required: p.hostRequired,
+ Class: "ETC",
+ OutputFile: android.OptionalPathForPath(p.outputApex),
+ Include: "$(BUILD_PREBUILT)",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
entries.SetString("LOCAL_MODULE_PATH", p.installDir.String())
entries.SetString("LOCAL_MODULE_STEM", p.installFilename)
entries.SetPath("LOCAL_SOONG_INSTALLED_MODULE", p.installedFile)
- entries.SetString("LOCAL_SOONG_INSTALL_PAIRS", p.outputApex.String()+":"+p.installedFile.String())
+ installPairs := append(installPairs{{p.outputApex, p.installedFile}}, p.extraInstalledPairs...)
+ entries.SetString("LOCAL_SOONG_INSTALL_PAIRS", installPairs.String())
entries.AddStrings("LOCAL_SOONG_INSTALL_SYMLINKS", p.compatSymlinks.Strings()...)
entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.installable())
entries.AddStrings("LOCAL_OVERRIDES_MODULES", p.prebuiltCommonProperties.Overrides...)
entries.SetString("LOCAL_APEX_KEY_PATH", p.apexKeysPath.String())
- p.addRequiredModules(entries)
},
},
},
}
- // Add the dexpreopt artifacts to androidmk
- for _, install := range p.Dexpreopter.DexpreoptBuiltInstalledForApex() {
- entriesList = append(entriesList, install.ToMakeEntries())
- }
-
return entriesList
}
@@ -265,6 +291,7 @@
for _, dep := range p.prebuiltCommonProperties.Exported_bootclasspath_fragments {
prebuiltDep := android.PrebuiltNameFromSource(dep)
ctx.AddDependency(module, exportedBootclasspathFragmentTag, prebuiltDep)
+ ctx.AddDependency(module, fragmentInApexTag, prebuiltDep)
}
for _, dep := range p.prebuiltCommonProperties.Exported_systemserverclasspath_fragments {
@@ -274,98 +301,47 @@
}
// Implements android.DepInInSameApex
-func (p *prebuiltCommon) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
+func (m *prebuiltCommon) GetDepInSameApexChecker() android.DepInSameApexChecker {
+ return ApexPrebuiltDepInSameApexChecker{}
+}
+
+type ApexPrebuiltDepInSameApexChecker struct {
+ android.BaseDepInSameApexChecker
+}
+
+func (m ApexPrebuiltDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
_, ok := tag.(exportedDependencyTag)
return ok
}
-func (p *prebuiltCommon) IncomingDepIsInSameApex(tag blueprint.DependencyTag) bool {
- return true
-}
-
-// apexInfoMutator marks any modules for which this apex exports a file as requiring an apex
-// specific variant and checks that they are supported.
-//
-// The apexMutator will ensure that the ApexInfo objects passed to BuildForApex(ApexInfo) are
-// associated with the apex specific variant using the ApexInfoProvider for later retrieval.
-//
-// Unlike the source apex module type the prebuilt_apex module type cannot share compatible variants
-// across prebuilt_apex modules. That is because there is no way to determine whether two
-// prebuilt_apex modules that export files for the same module are compatible. e.g. they could have
-// been built from different source at different times or they could have been built with different
-// build options that affect the libraries.
-//
-// While it may be possible to provide sufficient information to determine whether two prebuilt_apex
-// modules were compatible it would be a lot of work and would not provide much benefit for a couple
-// of reasons:
-// - The number of prebuilt_apex modules that will be exporting files for the same module will be
-// low as the prebuilt_apex only exports files for the direct dependencies that require it and
-// very few modules are direct dependencies of multiple prebuilt_apex modules, e.g. there are a
-// few com.android.art* apex files that contain the same contents and could export files for the
-// same modules but only one of them needs to do so. Contrast that with source apex modules which
-// need apex specific variants for every module that contributes code to the apex, whether direct
-// or indirect.
-// - The build cost of a prebuilt_apex variant is generally low as at worst it will involve some
-// extra copying of files. Contrast that with source apex modules that has to build each variant
-// from source.
-func (p *prebuiltCommon) apexInfoMutator(mctx android.TopDownMutatorContext) {
- // Collect the list of dependencies.
- var dependencies []android.ApexModule
- mctx.WalkDeps(func(child, parent android.Module) bool {
- // If the child is not in the same apex as the parent then exit immediately and do not visit
- // any of the child's dependencies.
- if !android.IsDepInSameApex(mctx, parent, child) {
- return false
- }
-
- tag := mctx.OtherModuleDependencyTag(child)
- depName := mctx.OtherModuleName(child)
+func (p *prebuiltCommon) checkExportedDependenciesArePrebuilts(ctx android.ModuleContext) {
+ ctx.VisitDirectDeps(func(dep android.Module) {
+ tag := ctx.OtherModuleDependencyTag(dep)
+ depName := ctx.OtherModuleName(dep)
if exportedTag, ok := tag.(exportedDependencyTag); ok {
propertyName := exportedTag.name
// It is an error if the other module is not a prebuilt.
- if !android.IsModulePrebuilt(child) {
- mctx.PropertyErrorf(propertyName, "%q is not a prebuilt module", depName)
- return false
+ if !android.IsModulePrebuilt(dep) {
+ ctx.PropertyErrorf(propertyName, "%q is not a prebuilt module", depName)
}
// It is an error if the other module is not an ApexModule.
- if _, ok := child.(android.ApexModule); !ok {
- mctx.PropertyErrorf(propertyName, "%q is not usable within an apex", depName)
- return false
+ if _, ok := dep.(android.ApexModule); !ok {
+ ctx.PropertyErrorf(propertyName, "%q is not usable within an apex", depName)
}
}
- // Ignore any modules that do not implement ApexModule as they cannot have an APEX specific
- // variant.
- if _, ok := child.(android.ApexModule); !ok {
- return false
- }
-
- // Strip off the prebuilt_ prefix if present before storing content to ensure consistent
- // behavior whether there is a corresponding source module present or not.
- depName = android.RemoveOptionalPrebuiltPrefix(depName)
-
- // Add the module to the list of dependencies that need to have an APEX variant.
- dependencies = append(dependencies, child.(android.ApexModule))
-
- return true
})
+}
- android.SetProvider(mctx, android.ApexBundleInfoProvider, android.ApexBundleInfo{})
-
- // Create an ApexInfo for the prebuilt_apex.
- apexVariationName := p.ApexVariationName()
- apexInfo := android.ApexInfo{
- ApexVariationName: apexVariationName,
- InApexVariants: []string{apexVariationName},
+// generateApexInfo returns an android.ApexInfo configuration suitable for dependencies of this apex.
+func (p *prebuiltCommon) generateApexInfo(ctx generateApexInfoContext) android.ApexInfo {
+ return android.ApexInfo{
+ ApexVariationName: "prebuilt_" + p.ApexVariationName(),
+ BaseApexName: p.ApexVariationName(),
ForPrebuiltApex: true,
}
-
- // Mark the dependencies of this module as requiring a variant for this module.
- for _, am := range dependencies {
- am.BuildForApex(apexInfo)
- }
}
type Prebuilt struct {
@@ -569,10 +545,22 @@
p.prebuiltApexContentsDeps(ctx)
}
-var _ ApexInfoMutator = (*Prebuilt)(nil)
+var _ ApexTransitionMutator = (*Prebuilt)(nil)
-func (p *Prebuilt) ApexInfoMutator(mctx android.TopDownMutatorContext) {
- p.apexInfoMutator(mctx)
+func (p *Prebuilt) ApexTransitionMutatorSplit(ctx android.BaseModuleContext) []android.ApexInfo {
+ return []android.ApexInfo{p.generateApexInfo(ctx)}
+}
+
+func (p *Prebuilt) ApexTransitionMutatorOutgoing(ctx android.OutgoingTransitionContext, sourceInfo android.ApexInfo) android.ApexInfo {
+ return sourceInfo
+}
+
+func (p *Prebuilt) ApexTransitionMutatorIncoming(ctx android.IncomingTransitionContext, outgoingInfo android.ApexInfo) android.ApexInfo {
+ return p.generateApexInfo(ctx)
+}
+
+func (p *Prebuilt) ApexTransitionMutatorMutate(ctx android.BottomUpMutatorContext, info android.ApexInfo) {
+ android.SetProvider(ctx, android.ApexBundleInfoProvider, android.ApexBundleInfo{})
}
// creates the build rules to deapex the prebuilt, and returns a deapexerInfo
@@ -638,6 +626,8 @@
validateApexClasspathFragments(ctx)
}
+ p.checkExportedDependenciesArePrebuilts(ctx)
+
p.apexKeysPath = writeApexKeys(ctx, p)
// TODO(jungjw): Check the key validity.
p.inputApex = android.PathForModuleSrc(ctx, p.properties.prebuiltApexSelector(ctx, ctx.Module()))
@@ -679,7 +669,9 @@
}
if p.installable() {
- p.installedFile = ctx.InstallFile(p.installDir, p.installFilename, p.inputApex, p.compatSymlinks...)
+ p.installApexSystemServerFiles(ctx)
+ installDeps := slices.Concat(p.compatSymlinks, p.extraInstalledFiles)
+ p.installedFile = ctx.InstallFile(p.installDir, p.installFilename, p.inputApex, installDeps...)
p.provenanceMetaDataFile = provenance.GenerateArtifactProvenanceMetaData(ctx, p.inputApex, p.installedFile)
}
@@ -690,16 +682,6 @@
return p.provenanceMetaDataFile
}
-// prebuiltApexExtractorModule is a private module type that is only created by the prebuilt_apex
-// module. It extracts the correct apex to use and makes it available for use by apex_set.
-type prebuiltApexExtractorModule struct {
- android.ModuleBase
-
- properties ApexExtractorProperties
-
- extractedApex android.WritablePath
-}
-
// extract registers the build actions to extract an apex from .apks file
// returns the path of the extracted apex
func extract(ctx android.ModuleContext, apexSet android.Path, prerelease *bool) android.Path {
@@ -806,10 +788,22 @@
a.prebuiltApexContentsDeps(ctx)
}
-var _ ApexInfoMutator = (*ApexSet)(nil)
+var _ ApexTransitionMutator = (*ApexSet)(nil)
-func (a *ApexSet) ApexInfoMutator(mctx android.TopDownMutatorContext) {
- a.apexInfoMutator(mctx)
+func (a *ApexSet) ApexTransitionMutatorSplit(ctx android.BaseModuleContext) []android.ApexInfo {
+ return []android.ApexInfo{a.generateApexInfo(ctx)}
+}
+
+func (a *ApexSet) ApexTransitionMutatorOutgoing(ctx android.OutgoingTransitionContext, sourceInfo android.ApexInfo) android.ApexInfo {
+ return sourceInfo
+}
+
+func (a *ApexSet) ApexTransitionMutatorIncoming(ctx android.IncomingTransitionContext, outgoingInfo android.ApexInfo) android.ApexInfo {
+ return a.generateApexInfo(ctx)
+}
+
+func (a *ApexSet) ApexTransitionMutatorMutate(ctx android.BottomUpMutatorContext, info android.ApexInfo) {
+ android.SetProvider(ctx, android.ApexBundleInfoProvider, android.ApexBundleInfo{})
}
func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -866,7 +860,8 @@
a.installDir = android.PathForModuleInstall(ctx, "apex")
if a.installable() {
- a.installedFile = ctx.InstallFile(a.installDir, a.installFilename, a.outputApex)
+ a.installApexSystemServerFiles(ctx)
+ a.installedFile = ctx.InstallFile(a.installDir, a.installFilename, a.outputApex, a.extraInstalledFiles...)
}
// in case that apex_set replaces source apex (using prefer: prop)
@@ -878,11 +873,3 @@
ctx.SetOutputFiles(android.Paths{a.outputApex}, "")
}
-
-type systemExtContext struct {
- android.ModuleContext
-}
-
-func (*systemExtContext) SystemExtSpecific() bool {
- return true
-}
diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go
index 7dbac5f..61f79d6 100644
--- a/apex/systemserver_classpath_fragment_test.go
+++ b/apex/systemserver_classpath_fragment_test.go
@@ -108,6 +108,7 @@
})
java.CheckModuleDependencies(t, ctx, "myapex", "android_common_myapex", []string{
+ `all_apex_contributions`,
`dex2oatd`,
`myapex.key`,
`mysystemserverclasspathfragment`,
@@ -166,6 +167,7 @@
})
java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex", []string{
+ `all_apex_contributions`,
`dex2oatd`,
`myapex.key`,
`mysystemserverclasspathfragment`,
@@ -278,19 +280,19 @@
ctx := result.TestContext
- java.CheckModuleDependencies(t, ctx, "myapex", "android_common_myapex", []string{
+ java.CheckModuleDependencies(t, ctx, "myapex", "android_common_prebuilt_myapex", []string{
`all_apex_contributions`,
`dex2oatd`,
`prebuilt_mysystemserverclasspathfragment`,
})
- java.CheckModuleDependencies(t, ctx, "mysystemserverclasspathfragment", "android_common_myapex", []string{
+ java.CheckModuleDependencies(t, ctx, "mysystemserverclasspathfragment", "android_common_prebuilt_myapex", []string{
`all_apex_contributions`,
`prebuilt_bar`,
`prebuilt_foo`,
})
- ensureExactDeapexedContents(t, ctx, "myapex", "android_common_myapex", []string{
+ ensureExactDeapexedContents(t, ctx, "myapex", "android_common_prebuilt_myapex", []string{
"javalib/foo.jar",
"javalib/bar.jar",
"javalib/bar.jar.prof",
@@ -438,13 +440,13 @@
ctx := result.TestContext
- java.CheckModuleDependencies(t, ctx, "mysystemserverclasspathfragment", "android_common_myapex", []string{
+ java.CheckModuleDependencies(t, ctx, "mysystemserverclasspathfragment", "android_common_prebuilt_myapex", []string{
`all_apex_contributions`,
`prebuilt_bar`,
`prebuilt_foo`,
})
- ensureExactDeapexedContents(t, ctx, "myapex", "android_common_myapex", []string{
+ ensureExactDeapexedContents(t, ctx, "myapex", "android_common_prebuilt_myapex", []string{
"javalib/foo.jar",
"javalib/bar.jar",
"javalib/bar.jar.prof",
@@ -455,7 +457,7 @@
}
func assertProfileGuided(t *testing.T, ctx *android.TestContext, moduleName string, variant string, expected bool) {
- dexpreopt := ctx.ModuleForTests(moduleName, variant).Rule("dexpreopt")
+ dexpreopt := ctx.ModuleForTests(t, moduleName, variant).Rule("dexpreopt")
actual := strings.Contains(dexpreopt.RuleParams.Command, "--profile-file=")
if expected != actual {
t.Fatalf("Expected profile-guided to be %v, got %v", expected, actual)
@@ -463,9 +465,126 @@
}
func assertProfileGuidedPrebuilt(t *testing.T, ctx *android.TestContext, apexName string, moduleName string, expected bool) {
- dexpreopt := ctx.ModuleForTests(apexName, "android_common_"+apexName).Rule("dexpreopt." + moduleName)
+ dexpreopt := ctx.ModuleForTests(t, apexName, "android_common_prebuilt_"+apexName).Rule("dexpreopt." + moduleName)
actual := strings.Contains(dexpreopt.RuleParams.Command, "--profile-file=")
if expected != actual {
t.Fatalf("Expected profile-guided to be %v, got %v", expected, actual)
}
}
+
+func TestCheckSystemServerOrderWithArtApex(t *testing.T) {
+ preparers := android.GroupFixturePreparers(
+ java.PrepareForTestWithDexpreopt,
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ PrepareForTestWithApexBuildComponents,
+ prepareForTestWithArtApex,
+ java.FixtureConfigureBootJars("com.android.art:framework-art"),
+ dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-apex1", "com.android.art:service-art"),
+ java.FixtureWithLastReleaseApis("baz"),
+ )
+
+ // Creates a com.android.art apex with a bootclasspath fragment and a systemserverclasspath fragment, and a
+ // com.android.apex1 prebuilt whose bootclasspath fragment depends on the com.android.art bootclasspath fragment.
+ // Verifies that the checkSystemServerOrder doesn't get confused by the bootclasspath dependencies and report
+ // that service-apex1 depends on service-art.
+ result := preparers.RunTestWithBp(t, `
+ apex {
+ name: "com.android.art",
+ key: "com.android.art.key",
+ bootclasspath_fragments: ["art-bootclasspath-fragment"],
+ systemserverclasspath_fragments: ["art-systemserverclasspath-fragment"],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "com.android.art.key",
+ public_key: "com.android.art.avbpubkey",
+ private_key: "com.android.art.pem",
+ }
+
+ bootclasspath_fragment {
+ name: "art-bootclasspath-fragment",
+ image_name: "art",
+ contents: ["framework-art"],
+ apex_available: [
+ "com.android.art",
+ ],
+ hidden_api: {
+ split_packages: ["*"],
+ },
+ }
+
+ java_library {
+ name: "framework-art",
+ apex_available: ["com.android.art"],
+ srcs: ["a.java"],
+ compile_dex: true,
+ }
+
+ systemserverclasspath_fragment {
+ name: "art-systemserverclasspath-fragment",
+ apex_available: ["com.android.art"],
+ contents: ["service-art"],
+ }
+
+ java_library {
+ name: "service-art",
+ srcs: ["a.java"],
+ apex_available: ["com.android.art"],
+ compile_dex: true,
+ }
+
+ prebuilt_apex {
+ name: "com.android.apex1",
+ arch: {
+ arm64: {
+ src: "myapex-arm64.apex",
+ },
+ arm: {
+ src: "myapex-arm.apex",
+ },
+ },
+ exported_bootclasspath_fragments: ["com.android.apex1-bootclasspath-fragment"],
+ exported_systemserverclasspath_fragments: ["com.android.apex1-systemserverclasspath-fragment"],
+ }
+
+ prebuilt_bootclasspath_fragment {
+ name: "com.android.apex1-bootclasspath-fragment",
+ visibility: ["//visibility:public"],
+ apex_available: ["com.android.apex1"],
+ contents: ["framework-apex1"],
+ fragments: [
+ {
+ apex: "com.android.art",
+ module: "art-bootclasspath-fragment",
+ },
+ ],
+ hidden_api: {
+ annotation_flags: "hiddenapi/annotation-flags.csv",
+ metadata: "hiddenapi/metadata.csv",
+ index: "hiddenapi/index.csv",
+ stub_flags: "hiddenapi/stub-flags.csv",
+ all_flags: "hiddenapi/all-flags.csv",
+ },
+ }
+
+ java_import {
+ name: "framework-apex1",
+ apex_available: ["com.android.apex1"],
+ }
+
+ prebuilt_systemserverclasspath_fragment {
+ name: "com.android.apex1-systemserverclasspath-fragment",
+ apex_available: ["com.android.apex1"],
+ contents: ["service-apex1"],
+ }
+
+ java_import {
+ name: "service-apex1",
+ installable: true,
+ apex_available: ["com.android.apex1"],
+ sdk_version: "current",
+ }`)
+
+ _ = result
+}
diff --git a/bin/mm b/bin/mm
index 6461b1e..6f1c934 100755
--- a/bin/mm
+++ b/bin/mm
@@ -19,6 +19,6 @@
require_top
-_wrap_build "$TOP/build/soong/soong_ui.bash" --build-mode --modules-in-a-dir-no-deps --dir="$(pwd)" "$@"
+_wrap_build "$TOP/build/soong/soong_ui.bash" --build-mode --modules-in-a-dir --dir="$(pwd)" "$@"
exit $?
diff --git a/bin/mmm b/bin/mmm
index ab3a632..d9190e5 100755
--- a/bin/mmm
+++ b/bin/mmm
@@ -19,6 +19,6 @@
require_top
-_wrap_build "$TOP/build/soong/soong_ui.bash" --build-mode --modules-in-dirs-no-deps --dir="$(pwd)" "$@"
+_wrap_build "$TOP/build/soong/soong_ui.bash" --build-mode --modules-in-dirs --dir="$(pwd)" "$@"
exit $?
diff --git a/bin/soongdbg b/bin/soongdbg
index 0807291..dad5137 100755
--- a/bin/soongdbg
+++ b/bin/soongdbg
@@ -450,13 +450,17 @@
def main():
+ global SOONG_DEBUG_DATA_FILENAME
parser = argparse.ArgumentParser()
+ parser.add_argument("-f", "--debug-file", nargs=1, help="location of the debug info file",
+ default=[SOONG_DEBUG_DATA_FILENAME])
subparsers = parser.add_subparsers(required=True, dest="command")
for name in sorted(COMMANDS.keys()):
command = COMMANDS[name]
subparser = subparsers.add_parser(name, help=command.help)
command.args(subparser)
args = parser.parse_args()
+ SOONG_DEBUG_DATA_FILENAME = args.debug_file[0]
COMMANDS[args.command].run(args)
sys.exit(0)
diff --git a/bloaty/bloaty.go b/bloaty/bloaty.go
index 8ecea98..26f2aa8 100644
--- a/bloaty/bloaty.go
+++ b/bloaty/bloaty.go
@@ -105,13 +105,11 @@
}
})
+ protoFilenamePath := android.PathForOutput(ctx, protoFilename)
ctx.Build(pctx, android.BuildParams{
Rule: bloatyMerger,
Inputs: android.SortedUniquePaths(deps),
- Output: android.PathForOutput(ctx, protoFilename),
+ Output: protoFilenamePath,
})
-}
-
-func (singleton *sizesSingleton) MakeVars(ctx android.MakeVarsContext) {
- ctx.DistForGoalWithFilename("checkbuild", android.PathForOutput(ctx, protoFilename), protoFilename)
+ ctx.DistForGoalWithFilename("checkbuild", protoFilenamePath, protoFilename)
}
diff --git a/bpf/bpf.go b/bpf/bpf.go
index 3f34382..deb465d 100644
--- a/bpf/bpf.go
+++ b/bpf/bpf.go
@@ -60,6 +60,12 @@
ctx.RegisterModuleType("bpf", BpfFactory)
}
+type BpfInfo struct {
+ SubDir string
+}
+
+var BpfInfoProvider = blueprint.NewProvider[BpfInfo]()
+
var PrepareForTestWithBpf = android.FixtureRegisterWithContext(registerBpfBuildComponents)
// BpfModule interface is used by the apex package to gather information from a bpf module.
@@ -230,6 +236,10 @@
ctx.PackageFile(installDir, obj.Base(), obj)
}
+ android.SetProvider(ctx, BpfInfoProvider, BpfInfo{
+ SubDir: bpf.SubDir(),
+ })
+
ctx.SetOutputFiles(bpf.objs, "")
}
diff --git a/cc/Android.bp b/cc/Android.bp
index 3b29ae8..1ac5a4a 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -36,6 +36,7 @@
"linkable.go",
"lto.go",
"makevars.go",
+ "misc_disted_files.go",
"orderfile.go",
"prebuilt.go",
"proto.go",
diff --git a/cc/afdo.go b/cc/afdo.go
index 828e494..8d8341e 100644
--- a/cc/afdo.go
+++ b/cc/afdo.go
@@ -96,8 +96,10 @@
flags.Local.CFlags = append([]string{"-funique-internal-linkage-names"}, flags.Local.CFlags...)
// Flags for Flow Sensitive AutoFDO
flags.Local.CFlags = append([]string{"-mllvm", "-enable-fs-discriminator=true"}, flags.Local.CFlags...)
+ flags.Local.LdFlags = append([]string{"-Wl,-mllvm,-enable-fs-discriminator=true"}, flags.Local.LdFlags...)
// TODO(b/266595187): Remove the following feature once it is enabled in LLVM by default.
flags.Local.CFlags = append([]string{"-mllvm", "-improved-fs-discriminator=true"}, flags.Local.CFlags...)
+ flags.Local.LdFlags = append([]string{"-Wl,-mllvm,-improved-fs-discriminator=true"}, flags.Local.LdFlags...)
}
if fdoProfilePath := getFdoProfilePathFromDep(ctx); fdoProfilePath != "" {
// The flags are prepended to allow overriding.
diff --git a/cc/afdo_test.go b/cc/afdo_test.go
index 0679d13..d2d5584 100644
--- a/cc/afdo_test.go
+++ b/cc/afdo_test.go
@@ -94,9 +94,9 @@
afdoLtoLdFlag := "-Wl,-plugin-opt,-import-instr-limit=40"
noAfdoLtoLdFlag := "-Wl,-plugin-opt,-import-instr-limit=5"
- libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
- libFooAfdoVariant := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest")
- libBarAfdoVariant := result.ModuleForTests("libBar", "android_arm64_armv8-a_static_afdo-libTest")
+ libTest := result.ModuleForTests(t, "libTest", "android_arm64_armv8-a_shared")
+ libFooAfdoVariant := result.ModuleForTests(t, "libFoo", "android_arm64_armv8-a_static_afdo-libTest")
+ libBarAfdoVariant := result.ModuleForTests(t, "libBar", "android_arm64_armv8-a_static_afdo-libTest")
// Check cFlags of afdo-enabled module and the afdo-variant of its static deps
cFlags := libTest.Rule("cc").Args["cFlags"]
@@ -138,8 +138,8 @@
}
// Verify non-afdo variant exists and doesn't contain afdo
- libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
- libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
+ libFoo := result.ModuleForTests(t, "libFoo", "android_arm64_armv8-a_static")
+ libBar := result.ModuleForTests(t, "libBar", "android_arm64_armv8-a_static")
cFlags = libFoo.Rule("cc").Args["cFlags"]
if strings.Contains(cFlags, profileSampleCFlag) {
@@ -166,9 +166,9 @@
}
// Verify that the arm variant does not have FDO since the fdo_profile module only has a profile for arm64
- libTest32 := result.ModuleForTests("libTest", "android_arm_armv7-a-neon_shared")
- libFooAfdoVariant32 := result.ModuleForTests("libFoo", "android_arm_armv7-a-neon_static_afdo-libTest_lto-thin")
- libBarAfdoVariant32 := result.ModuleForTests("libBar", "android_arm_armv7-a-neon_static_afdo-libTest_lto-thin")
+ libTest32 := result.ModuleForTests(t, "libTest", "android_arm_armv7-a-neon_shared")
+ libFooAfdoVariant32 := result.ModuleForTests(t, "libFoo", "android_arm_armv7-a-neon_static_afdo-libTest_lto-thin")
+ libBarAfdoVariant32 := result.ModuleForTests(t, "libBar", "android_arm_armv7-a-neon_static_afdo-libTest_lto-thin")
cFlags = libTest32.Rule("cc").Args["cFlags"]
if strings.Contains(cFlags, profileSampleCFlag) {
@@ -215,9 +215,9 @@
}
// Verify that the host variants don't enable afdo
- libTestHost := result.ModuleForTests("libTest", result.Config.BuildOSTarget.String()+"_shared")
- libFooHost := result.ModuleForTests("libFoo", result.Config.BuildOSTarget.String()+"_static_lto-thin")
- libBarHost := result.ModuleForTests("libBar", result.Config.BuildOSTarget.String()+"_static_lto-thin")
+ libTestHost := result.ModuleForTests(t, "libTest", result.Config.BuildOSTarget.String()+"_shared")
+ libFooHost := result.ModuleForTests(t, "libFoo", result.Config.BuildOSTarget.String()+"_static_lto-thin")
+ libBarHost := result.ModuleForTests(t, "libBar", result.Config.BuildOSTarget.String()+"_static_lto-thin")
cFlags = libTestHost.Rule("cc").Args["cFlags"]
if strings.Contains(cFlags, profileSampleCFlag) {
@@ -301,9 +301,9 @@
}.AddToFixture(),
).RunTestWithBp(t, bp)
- libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared").Module()
- libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
- libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static").Module()
+ libTest := result.ModuleForTests(t, "libTest", "android_arm64_armv8-a_shared").Module()
+ libFoo := result.ModuleForTests(t, "libFoo", "android_arm64_armv8-a_static")
+ libBar := result.ModuleForTests(t, "libBar", "android_arm64_armv8-a_static").Module()
if !hasDirectDep(result, libTest, libFoo.Module()) {
t.Errorf("libTest missing dependency on non-afdo variant of libFoo")
@@ -412,13 +412,13 @@
}.AddToFixture(),
).RunTestWithBp(t, bp)
- fooArm := result.ModuleForTests("foo", "android_arm_armv7-a-neon_shared")
+ fooArm := result.ModuleForTests(t, "foo", "android_arm_armv7-a-neon_shared")
fooArmCFlags := fooArm.Rule("cc").Args["cFlags"]
if w := "-fprofile-sample-use=afdo_profiles_package/foo_arm.afdo"; !strings.Contains(fooArmCFlags, w) {
t.Errorf("Expected 'foo' to enable afdo, but did not find %q in cflags %q", w, fooArmCFlags)
}
- fooArm64 := result.ModuleForTests("foo", "android_arm64_armv8-a_shared")
+ fooArm64 := result.ModuleForTests(t, "foo", "android_arm64_armv8-a_shared")
fooArm64CFlags := fooArm64.Rule("cc").Args["cFlags"]
if w := "-fprofile-sample-use=afdo_profiles_package/foo_arm64.afdo"; !strings.Contains(fooArm64CFlags, w) {
t.Errorf("Expected 'foo' to enable afdo, but did not find %q in cflags %q", w, fooArm64CFlags)
@@ -476,11 +476,11 @@
expectedCFlagLibTest := "-fprofile-sample-use=afdo_profiles_package/libTest.afdo"
expectedCFlagLibBar := "-fprofile-sample-use=afdo_profiles_package/libBar.afdo"
- libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
- libFooAfdoVariantWithLibTest := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest")
+ libTest := result.ModuleForTests(t, "libTest", "android_arm64_armv8-a_shared")
+ libFooAfdoVariantWithLibTest := result.ModuleForTests(t, "libFoo", "android_arm64_armv8-a_static_afdo-libTest")
- libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_shared")
- libFooAfdoVariantWithLibBar := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libBar")
+ libBar := result.ModuleForTests(t, "libBar", "android_arm64_armv8-a_shared")
+ libFooAfdoVariantWithLibBar := result.ModuleForTests(t, "libFoo", "android_arm64_armv8-a_static_afdo-libBar")
// Check cFlags of afdo-enabled module and the afdo-variant of its static deps
cFlags := libTest.Rule("cc").Args["cFlags"]
@@ -543,9 +543,9 @@
// -funique-internal-linkage-names.
expectedCFlag := "-funique-internal-linkage-names"
- libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
- libFooAfdoVariant := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest")
- libBarAfdoVariant := result.ModuleForTests("libBar", "android_arm64_armv8-a_static_afdo-libTest")
+ libTest := result.ModuleForTests(t, "libTest", "android_arm64_armv8-a_shared")
+ libFooAfdoVariant := result.ModuleForTests(t, "libFoo", "android_arm64_armv8-a_static_afdo-libTest")
+ libBarAfdoVariant := result.ModuleForTests(t, "libBar", "android_arm64_armv8-a_static_afdo-libTest")
// Check cFlags of afdo-enabled module and the afdo-variant of its static deps
cFlags := libTest.Rule("cc").Args["cFlags"]
@@ -572,8 +572,8 @@
}
// Verify non-afdo variant exists and doesn't contain afdo
- libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
- libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
+ libFoo := result.ModuleForTests(t, "libFoo", "android_arm64_armv8-a_static")
+ libBar := result.ModuleForTests(t, "libBar", "android_arm64_armv8-a_static")
cFlags = libFoo.Rule("cc").Args["cFlags"]
if strings.Contains(cFlags, expectedCFlag) {
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 8037272..03f229e 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -231,7 +231,7 @@
} else if library.shared() {
entries.Class = "SHARED_LIBRARIES"
entries.SetString("LOCAL_SOONG_TOC", library.toc().String())
- if !library.buildStubs() && library.unstrippedOutputFile != nil {
+ if !library.BuildStubs() && library.unstrippedOutputFile != nil {
entries.SetString("LOCAL_SOONG_UNSTRIPPED_BINARY", library.unstrippedOutputFile.String())
}
if len(library.Properties.Overrides) > 0 {
@@ -260,16 +260,16 @@
entries.SetString("LOCAL_PREBUILT_COVERAGE_ARCHIVE", library.coverageOutputFile.String())
}
- if library.shared() && !library.buildStubs() {
+ if library.shared() && !library.BuildStubs() {
ctx.subAndroidMk(config, entries, library.baseInstaller)
} else {
- if library.buildStubs() && library.stubsVersion() != "" {
- entries.SubName = "." + library.stubsVersion()
+ if library.BuildStubs() && library.StubsVersion() != "" {
+ entries.SubName = "." + library.StubsVersion()
}
// library.makeUninstallable() depends on this to bypass HideFromMake() for
// static libraries.
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
- if library.buildStubs() {
+ if library.BuildStubs() {
entries.SetBool("LOCAL_NO_NOTICE_FILE", true)
}
}
@@ -281,10 +281,10 @@
// very early stage in the boot process).
if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.NotInPlatform() &&
!ctx.InRamdisk() && !ctx.InVendorRamdisk() && !ctx.InRecovery() && !ctx.InVendorOrProduct() && !ctx.static() {
- if library.buildStubs() && library.isLatestStubVersion() {
+ if library.BuildStubs() && library.isLatestStubVersion() {
entries.SubName = ""
}
- if !library.buildStubs() {
+ if !library.BuildStubs() {
entries.SubName = ".bootstrap"
}
}
@@ -423,7 +423,7 @@
entries.SubName = ndkLibrarySuffix + "." + c.apiLevel.String()
entries.Class = "SHARED_LIBRARIES"
- if !c.buildStubs() {
+ if !c.BuildStubs() {
entries.Disabled = true
return
}
diff --git a/cc/api_level.go b/cc/api_level.go
index 3dac571..deca723 100644
--- a/cc/api_level.go
+++ b/cc/api_level.go
@@ -55,7 +55,7 @@
return apiLevel
}
-func nativeApiLevelFromUser(ctx android.BaseModuleContext,
+func NativeApiLevelFromUser(ctx android.BaseModuleContext,
raw string) (android.ApiLevel, error) {
if raw == "minimum" {
@@ -73,7 +73,7 @@
func nativeApiLevelOrPanic(ctx android.BaseModuleContext,
raw string) android.ApiLevel {
- value, err := nativeApiLevelFromUser(ctx, raw)
+ value, err := NativeApiLevelFromUser(ctx, raw)
if err != nil {
panic(err.Error())
}
diff --git a/cc/binary.go b/cc/binary.go
index 4b77bea..c4791c5 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -426,7 +426,7 @@
validations = append(validations, objs.tidyDepFiles...)
linkerDeps = append(linkerDeps, flags.LdFlagsDeps...)
- if generatedLib := generateRustStaticlib(ctx, deps.RustRlibDeps); generatedLib != nil {
+ if generatedLib := GenerateRustStaticlib(ctx, deps.RustRlibDeps); generatedLib != nil {
deps.StaticLibs = append(deps.StaticLibs, generatedLib)
}
diff --git a/cc/binary_test.go b/cc/binary_test.go
index 3e18940..4f001d7 100644
--- a/cc/binary_test.go
+++ b/cc/binary_test.go
@@ -29,7 +29,7 @@
linker_scripts: ["foo.ld", "bar.ld"],
}`)
- binFoo := result.ModuleForTests("foo", "android_arm64_armv8-a").Rule("ld")
+ binFoo := result.ModuleForTests(t, "foo", "android_arm64_armv8-a").Rule("ld")
android.AssertStringListContains(t, "missing dependency on linker_scripts",
binFoo.Implicits.Strings(), "foo.ld")
diff --git a/cc/builder.go b/cc/builder.go
index b98bef9..f4f8596 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -472,15 +472,25 @@
}
// Generate rules for compiling multiple .c, .cpp, or .S files to individual .o files
-func transformSourceToObj(ctx ModuleContext, subdir string, srcFiles, noTidySrcs, timeoutTidySrcs android.Paths,
- flags builderFlags, pathDeps android.Paths, cFlagsDeps android.Paths) Objects {
+func transformSourceToObj(ctx android.ModuleContext, subdir string, srcFiles, noTidySrcs, timeoutTidySrcs android.Paths,
+ flags builderFlags, pathDeps android.Paths, cFlagsDeps android.Paths, sharedFlags *SharedFlags) Objects {
+
+ // Not all source files produce a .o; a Rust source provider
+ // may provide both a .c and a .rs file (e.g. rust_bindgen).
+ srcObjFiles := android.Paths{}
+ for _, src := range srcFiles {
+ if src.Ext() != ".rs" {
+ srcObjFiles = append(srcObjFiles, src)
+ }
+ }
+
// Source files are one-to-one with tidy, coverage, or kythe files, if enabled.
- objFiles := make(android.Paths, len(srcFiles))
+ objFiles := make(android.Paths, len(srcObjFiles))
var tidyFiles android.Paths
noTidySrcsMap := make(map[string]bool)
var tidyVars string
if flags.tidy {
- tidyFiles = make(android.Paths, 0, len(srcFiles))
+ tidyFiles = make(android.Paths, 0, len(srcObjFiles))
for _, path := range noTidySrcs {
noTidySrcsMap[path.String()] = true
}
@@ -495,11 +505,11 @@
}
var coverageFiles android.Paths
if flags.gcovCoverage {
- coverageFiles = make(android.Paths, 0, len(srcFiles))
+ coverageFiles = make(android.Paths, 0, len(srcObjFiles))
}
var kytheFiles android.Paths
if flags.emitXrefs && ctx.Module() == ctx.PrimaryModule() {
- kytheFiles = make(android.Paths, 0, len(srcFiles))
+ kytheFiles = make(android.Paths, 0, len(srcObjFiles))
}
// Produce fully expanded flags for use by C tools, C compiles, C++ tools, C++ compiles, and asm compiles
@@ -548,16 +558,14 @@
var sAbiDumpFiles android.Paths
if flags.sAbiDump {
- sAbiDumpFiles = make(android.Paths, 0, len(srcFiles))
+ sAbiDumpFiles = make(android.Paths, 0, len(srcObjFiles))
}
// Multiple source files have build rules usually share the same cFlags or tidyFlags.
- // Define only one version in this module and share it in multiple build rules.
- // To simplify the code, the shared variables are all named as $flags<nnn>.
- shared := ctx.getSharedFlags()
-
+ // SharedFlags provides one version for this module and shares it in multiple build rules.
+ // To simplify the code, the SharedFlags variables are all named as $flags<nnn>.
// Share flags only when there are multiple files or tidy rules.
- var hasMultipleRules = len(srcFiles) > 1 || flags.tidy
+ var hasMultipleRules = len(srcObjFiles) > 1 || flags.tidy
var shareFlags = func(kind string, flags string) string {
if !hasMultipleRules || len(flags) < 60 {
@@ -566,17 +574,17 @@
return flags
}
mapKey := kind + flags
- n, ok := shared.flagsMap[mapKey]
+ n, ok := sharedFlags.FlagsMap[mapKey]
if !ok {
- shared.numSharedFlags += 1
- n = strconv.Itoa(shared.numSharedFlags)
- shared.flagsMap[mapKey] = n
+ sharedFlags.NumSharedFlags += 1
+ n = strconv.Itoa(sharedFlags.NumSharedFlags)
+ sharedFlags.FlagsMap[mapKey] = n
ctx.Variable(pctx, kind+n, flags)
}
return "$" + kind + n
}
- for i, srcFile := range srcFiles {
+ for i, srcFile := range srcObjFiles {
objFile := android.ObjPathWithExt(ctx, subdir, srcFile, "o")
objFiles[i] = objFile
@@ -809,7 +817,7 @@
}
// Generate a Rust staticlib from a list of rlibDeps. Returns nil if TransformRlibstoStaticlib is nil or rlibDeps is empty.
-func generateRustStaticlib(ctx android.ModuleContext, rlibDeps []RustRlibDep) android.Path {
+func GenerateRustStaticlib(ctx android.ModuleContext, rlibDeps []RustRlibDep) android.Path {
if TransformRlibstoStaticlib == nil && len(rlibDeps) > 0 {
// This should only be reachable if a module defines Rust deps in static_libs and
// soong-rust hasn't been loaded alongside soong-cc (e.g. in soong-cc tests).
@@ -853,6 +861,27 @@
return strings.Join(lines, "\n")
}
+func BuildRustStubs(ctx android.ModuleContext, outputFile android.ModuleOutPath,
+ stubObjs Objects, ccFlags Flags) {
+
+ // Instantiate paths
+ sharedLibs := android.Paths{}
+ staticLibs := android.Paths{}
+ lateStaticLibs := android.Paths{}
+ wholeStaticLibs := android.Paths{}
+ deps := android.Paths{}
+ implicitOutputs := android.WritablePaths{}
+ validations := android.Paths{}
+ crtBegin := android.Paths{}
+ crtEnd := android.Paths{}
+ groupLate := false
+
+ builderFlags := flagsToBuilderFlags(ccFlags)
+ transformObjToDynamicBinary(ctx, stubObjs.objFiles, sharedLibs, staticLibs,
+ lateStaticLibs, wholeStaticLibs, deps, crtBegin, crtEnd,
+ groupLate, builderFlags, outputFile, implicitOutputs, validations)
+}
+
// Generate a rule for compiling multiple .o files, plus static libraries, whole static libraries,
// and shared libraries, to a shared library (.so) or dynamic executable
func transformObjToDynamicBinary(ctx android.ModuleContext,
@@ -945,13 +974,18 @@
func transformDumpToLinkedDump(ctx android.ModuleContext, sAbiDumps android.Paths, soFile android.Path,
baseName string, exportedIncludeDirs []string, symbolFile android.OptionalPath,
excludedSymbolVersions, excludedSymbolTags, includedSymbolTags []string,
- api string) android.Path {
+ api string, commonGlobalIncludes bool) android.Path {
outputFile := android.PathForModuleOut(ctx, baseName+".lsdump")
implicits := android.Paths{soFile}
symbolFilterStr := "-so " + soFile.String()
exportedHeaderFlags := android.JoinWithPrefix(exportedIncludeDirs, "-I")
+ // If this library does not export any include directory, do not append the flags
+ // so that the ABI tool dumps everything without filtering by the include directories.
+ if commonGlobalIncludes && len(exportedIncludeDirs) > 0 {
+ exportedHeaderFlags += " ${config.CommonGlobalIncludes}"
+ }
if symbolFile.Valid() {
implicits = append(implicits, symbolFile.Path())
diff --git a/cc/cc.go b/cc/cc.go
index af1b259..0e70d48 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -66,19 +66,19 @@
type CompilerInfo struct {
Srcs android.Paths
// list of module-specific flags that will be used for C and C++ compiles.
- Cflags proptools.Configurable[[]string]
+ Cflags []string
AidlInterfaceInfo AidlInterfaceInfo
LibraryDecoratorInfo *LibraryDecoratorInfo
}
type LinkerInfo struct {
- WholeStaticLibs proptools.Configurable[[]string]
+ WholeStaticLibs []string
// list of modules that should be statically linked into this module.
- StaticLibs proptools.Configurable[[]string]
+ StaticLibs []string
// list of modules that should be dynamically linked into this module.
- SharedLibs proptools.Configurable[[]string]
+ SharedLibs []string
// list of modules that should only provide headers for this module.
- HeaderLibs proptools.Configurable[[]string]
+ HeaderLibs []string
ImplementationModuleName *string
BinaryDecoratorInfo *BinaryDecoratorInfo
@@ -91,7 +91,7 @@
type BinaryDecoratorInfo struct{}
type LibraryDecoratorInfo struct {
- ExportIncludeDirs proptools.Configurable[[]string]
+ ExportIncludeDirs []string
InjectBsslHash bool
}
@@ -117,6 +117,7 @@
IsPrebuilt bool
CmakeSnapshotSupported bool
HasLlndkStubs bool
+ DataPaths []android.DataPath
CompilerInfo *CompilerInfo
LinkerInfo *LinkerInfo
SnapshotInfo *SnapshotInfo
@@ -136,7 +137,11 @@
UnstrippedOutputFile android.Path
OutputFile android.OptionalPath
CoverageFiles android.Paths
- SAbiDumpFiles android.Paths
+ // CoverageOutputFile returns the output archive of gcno coverage information files.
+ CoverageOutputFile android.OptionalPath
+ SAbiDumpFiles android.Paths
+ // Partition returns the partition string for this module.
+ Partition string
CcLibrary bool
CcLibraryInterface bool
RustLibraryInterface bool
@@ -144,11 +149,11 @@
CrateName string
// DepFlags returns a slice of Rustc string flags
ExportedCrateLinkDirs []string
- // This can be different from the one on CommonModuleInfo
- BaseModuleName string
- HasNonSystemVariants bool
- IsLlndk bool
- InVendorOrProduct bool
+ HasNonSystemVariants bool
+ IsLlndk bool
+ // True if the library is in the configs known NDK list.
+ IsNdk bool
+ InVendorOrProduct bool
// SubName returns the modules SubName, used for image and NDK/SDK variations.
SubName string
InRamdisk bool
@@ -157,9 +162,20 @@
OnlyInVendorRamdisk bool
InRecovery bool
OnlyInRecovery bool
+ InVendor bool
Installable *bool
// RelativeInstallPath returns the relative install path for this module.
RelativeInstallPath string
+ // TODO(b/362509506): remove this once all apex_exclude uses are switched to stubs.
+ RustApexExclude bool
+ // Bootstrap tests if this module is allowed to use non-APEX version of libraries.
+ Bootstrap bool
+ Multilib string
+ ImplementationModuleNameForMake string
+ IsStubsImplementationRequired bool
+ // Symlinks returns a list of symlinks that should be created for this module.
+ Symlinks []string
+ APIListCoverageXMLPath android.ModuleOutPath
}
var LinkableInfoProvider = blueprint.NewProvider[*LinkableInfo]()
@@ -623,7 +639,6 @@
binary() bool
object() bool
toolchain() config.Toolchain
- canUseSdk() bool
useSdk() bool
sdkVersion() string
minSdkVersion() string
@@ -647,9 +662,7 @@
isFuzzer() bool
isNDKStubLibrary() bool
useClangLld(actx ModuleContext) bool
- isForPlatform() bool
apexVariationName() string
- apexSdkVersion() android.ApiLevel
bootstrap() bool
nativeCoverage() bool
isPreventInstall() bool
@@ -661,8 +674,8 @@
}
type SharedFlags struct {
- numSharedFlags int
- flagsMap map[string]string
+ NumSharedFlags int
+ FlagsMap map[string]string
}
type ModuleContext interface {
@@ -832,6 +845,7 @@
reexportFlags bool
explicitlyVersioned bool
+ explicitlyImpl bool
dataLib bool
ndk bool
@@ -920,13 +934,18 @@
dataLibDepTag = dependencyTag{name: "data lib"}
dataBinDepTag = dependencyTag{name: "data bin"}
runtimeDepTag = installDependencyTag{name: "runtime lib"}
- stubImplDepTag = dependencyTag{name: "stub_impl"}
+ StubImplDepTag = dependencyTag{name: "stub_impl"}
JniFuzzLibTag = dependencyTag{name: "jni_fuzz_lib_tag"}
FdoProfileTag = dependencyTag{name: "fdo_profile"}
aidlLibraryTag = dependencyTag{name: "aidl_library"}
llndkHeaderLibTag = dependencyTag{name: "llndk_header_lib"}
)
+func IsExplicitImplSharedDepTag(depTag blueprint.DependencyTag) bool {
+ ccLibDepTag, ok := depTag.(libraryDependencyTag)
+ return ok && ccLibDepTag.shared() && ccLibDepTag.explicitlyImpl
+}
+
func IsSharedDepTag(depTag blueprint.DependencyTag) bool {
ccLibDepTag, ok := depTag.(libraryDependencyTag)
return ok && ccLibDepTag.shared()
@@ -946,6 +965,11 @@
return depTag == runtimeDepTag
}
+func ExcludeInApexDepTag(depTag blueprint.DependencyTag) bool {
+ ccLibDepTag, ok := depTag.(libraryDependencyTag)
+ return ok && ccLibDepTag.excludeInApex
+}
+
// Module contains the properties and members used by all C/C++ module types, and implements
// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces
// to construct the output file. Behavior can be customized with a Customizer, or "decorator",
@@ -1169,7 +1193,21 @@
return String(c.Properties.Min_sdk_version)
}
-func (c *Module) isCrt() bool {
+func (c *Module) SetSdkVersion(s string) {
+ c.Properties.Sdk_version = StringPtr(s)
+}
+
+func (c *Module) SetMinSdkVersion(s string) {
+ c.Properties.Min_sdk_version = StringPtr(s)
+}
+
+func (c *Module) SetStl(s string) {
+ if c.stl != nil {
+ c.stl.Properties.Stl = StringPtr(s)
+ }
+}
+
+func (c *Module) IsCrt() bool {
if linker, ok := c.linker.(*objectLinker); ok {
return linker.isCrt()
}
@@ -1177,7 +1215,7 @@
}
func (c *Module) SplitPerApiLevel() bool {
- return c.canUseSdk() && c.isCrt()
+ return CanUseSdk(c) && c.IsCrt()
}
func (c *Module) AlwaysSdk() bool {
@@ -1197,7 +1235,7 @@
}
func (c *Module) CcLibraryInterface() bool {
- if _, ok := c.linker.(libraryInterface); ok {
+ if c.library != nil {
return true
}
return false
@@ -1310,6 +1348,13 @@
var _ LinkableInterface = (*Module)(nil)
+func (c *Module) VersionedInterface() VersionedInterface {
+ if c.library != nil {
+ return c.library
+ }
+ return nil
+}
+
func (c *Module) UnstrippedOutputFile() android.Path {
if c.linker != nil {
return c.linker.unstrippedOutputFilePath()
@@ -1394,13 +1439,13 @@
return c.Properties.VndkVersion != ""
}
-func (c *Module) canUseSdk() bool {
- return c.Os() == android.Android && c.Target().NativeBridge == android.NativeBridgeDisabled &&
+func CanUseSdk(c LinkableInterface) bool {
+ return c.Module().Target().Os == android.Android && c.Target().NativeBridge == android.NativeBridgeDisabled &&
!c.InVendorOrProduct() && !c.InRamdisk() && !c.InRecovery() && !c.InVendorRamdisk()
}
func (c *Module) UseSdk() bool {
- if c.canUseSdk() {
+ if CanUseSdk(c) {
return String(c.Properties.Sdk_version) != ""
}
return false
@@ -1419,13 +1464,13 @@
}
func (m *Module) NeedsLlndkVariants() bool {
- lib := moduleLibraryInterface(m)
- return lib != nil && (lib.hasLLNDKStubs() || lib.hasLLNDKHeaders())
+ lib := moduleVersionedInterface(m)
+ return lib != nil && (lib.HasLLNDKStubs() || lib.HasLLNDKHeaders())
}
func (m *Module) NeedsVendorPublicLibraryVariants() bool {
- lib := moduleLibraryInterface(m)
- return lib != nil && (lib.hasVendorPublicLibrary())
+ lib := moduleVersionedInterface(m)
+ return lib != nil && (lib.HasVendorPublicLibrary())
}
// IsVendorPublicLibrary returns true for vendor public libraries.
@@ -1445,13 +1490,13 @@
}
func (c *Module) HasLlndkStubs() bool {
- lib := moduleLibraryInterface(c)
- return lib != nil && lib.hasLLNDKStubs()
+ lib := moduleVersionedInterface(c)
+ return lib != nil && lib.HasLLNDKStubs()
}
func (c *Module) StubsVersion() string {
- if lib, ok := c.linker.(versionedInterface); ok {
- return lib.stubsVersion()
+ if lib, ok := c.linker.(VersionedInterface); ok {
+ return lib.StubsVersion()
}
panic(fmt.Errorf("StubsVersion called on non-versioned module: %q", c.BaseModuleName()))
}
@@ -1460,7 +1505,7 @@
// and does not set llndk.vendor_available: false.
func (c *Module) isImplementationForLLNDKPublic() bool {
library, _ := c.library.(*libraryDecorator)
- return library != nil && library.hasLLNDKStubs() &&
+ return library != nil && library.HasLLNDKStubs() &&
!Bool(library.Properties.Llndk.Private)
}
@@ -1499,21 +1544,25 @@
func (c *Module) IsStubs() bool {
if lib := c.library; lib != nil {
- return lib.buildStubs()
+ return lib.BuildStubs()
}
return false
}
func (c *Module) HasStubsVariants() bool {
if lib := c.library; lib != nil {
- return lib.hasStubsVariants()
+ return lib.HasStubsVariants()
}
return false
}
+func (c *Module) RustApexExclude() bool {
+ return false
+}
+
func (c *Module) IsStubsImplementationRequired() bool {
if lib := c.library; lib != nil {
- return lib.isStubsImplementationRequired()
+ return lib.IsStubsImplementationRequired()
}
return false
}
@@ -1522,21 +1571,21 @@
// the implementation. If it is an implementation library it returns its own name.
func (c *Module) ImplementationModuleName(ctx android.BaseModuleContext) string {
name := ctx.OtherModuleName(c)
- if versioned, ok := c.linker.(versionedInterface); ok {
- name = versioned.implementationModuleName(name)
+ if versioned, ok := c.linker.(VersionedInterface); ok {
+ name = versioned.ImplementationModuleName(name)
}
return name
}
-// Similar to ImplementationModuleName, but uses the Make variant of the module
+// Similar to ImplementationModuleNameByCtx, but uses the Make variant of the module
// name as base name, for use in AndroidMk output. E.g. for a prebuilt module
// where the Soong name is prebuilt_foo, this returns foo (which works in Make
// under the premise that the prebuilt module overrides its source counterpart
// if it is exposed to Make).
-func (c *Module) ImplementationModuleNameForMake(ctx android.BaseModuleContext) string {
+func (c *Module) ImplementationModuleNameForMake() string {
name := c.BaseModuleName()
- if versioned, ok := c.linker.(versionedInterface); ok {
- name = versioned.implementationModuleName(name)
+ if versioned, ok := c.linker.(VersionedInterface); ok {
+ name = versioned.ImplementationModuleName(name)
}
return name
}
@@ -1644,10 +1693,6 @@
return ctx.mod.OptimizeForSize()
}
-func (ctx *moduleContextImpl) canUseSdk() bool {
- return ctx.mod.canUseSdk()
-}
-
func (ctx *moduleContextImpl) useSdk() bool {
return ctx.mod.UseSdk()
}
@@ -1659,21 +1704,23 @@
return ""
}
-func (ctx *moduleContextImpl) minSdkVersion() string {
- ver := ctx.mod.MinSdkVersion()
- if ver == "apex_inherit" && !ctx.isForPlatform() {
- ver = ctx.apexSdkVersion().String()
+func MinSdkVersion(mod VersionedLinkableInterface, ctxIsForPlatform bool, device bool,
+ platformSdkVersion string) string {
+
+ ver := mod.MinSdkVersion()
+ if ver == "apex_inherit" && !ctxIsForPlatform {
+ ver = mod.ApexSdkVersion().String()
}
if ver == "apex_inherit" || ver == "" {
- ver = ctx.sdkVersion()
+ ver = mod.SdkVersion()
}
- if ctx.ctx.Device() {
+ if device {
// When building for vendor/product, use the latest _stable_ API as "current".
// This is passed to clang/aidl compilers so that compiled/generated code works
// with the system.
- if (ctx.inVendor() || ctx.inProduct()) && (ver == "" || ver == "current") {
- ver = ctx.ctx.Config().PlatformSdkVersion().String()
+ if (mod.InVendor() || mod.InProduct()) && (ver == "" || ver == "current") {
+ ver = platformSdkVersion
}
}
@@ -1687,19 +1734,19 @@
// support such an old version. The version is set to the later version in case when the
// non-sdk variant is for the platform, or the min_sdk_version of the containing APEX if
// it's for an APEX.
- if ctx.mod.isCrt() && !ctx.isSdkVariant() {
- if ctx.isForPlatform() {
+ if mod.IsCrt() && !mod.IsSdkVariant() {
+ if ctxIsForPlatform {
ver = strconv.Itoa(android.FutureApiLevelInt)
} else { // for apex
- ver = ctx.apexSdkVersion().String()
+ ver = mod.ApexSdkVersion().String()
if ver == "" { // in case when min_sdk_version was not set by the APEX
- ver = ctx.sdkVersion()
+ ver = mod.SdkVersion()
}
}
}
// Also make sure that minSdkVersion is not greater than sdkVersion, if they are both numbers
- sdkVersionInt, err := strconv.Atoi(ctx.sdkVersion())
+ sdkVersionInt, err := strconv.Atoi(mod.SdkVersion())
minSdkVersionInt, err2 := strconv.Atoi(ver)
if err == nil && err2 == nil {
if sdkVersionInt < minSdkVersionInt {
@@ -1709,6 +1756,14 @@
return ver
}
+func (ctx *moduleContextImpl) minSdkVersion() string {
+ platformSdkVersion := ""
+ if ctx.ctx.Device() {
+ platformSdkVersion = ctx.ctx.Config().PlatformSdkVersion().String()
+ }
+ return MinSdkVersion(ctx.mod, CtxIsForPlatform(ctx.ctx), ctx.ctx.Device(), platformSdkVersion)
+}
+
func (ctx *moduleContextImpl) isSdkVariant() bool {
return ctx.mod.IsSdkVariant()
}
@@ -1772,8 +1827,8 @@
return ctx.mod.BaseModuleName()
}
-func (ctx *moduleContextImpl) isForPlatform() bool {
- apexInfo, _ := android.ModuleProvider(ctx.ctx, android.ApexInfoProvider)
+func CtxIsForPlatform(ctx android.BaseModuleContext) bool {
+ apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
return apexInfo.IsForPlatform()
}
@@ -1782,10 +1837,6 @@
return apexInfo.ApexVariationName
}
-func (ctx *moduleContextImpl) apexSdkVersion() android.ApiLevel {
- return ctx.mod.apexSdkVersion
-}
-
func (ctx *moduleContextImpl) bootstrap() bool {
return ctx.mod.Bootstrap()
}
@@ -1800,9 +1851,9 @@
func (ctx *moduleContextImpl) getSharedFlags() *SharedFlags {
shared := &ctx.mod.sharedFlags
- if shared.flagsMap == nil {
- shared.numSharedFlags = 0
- shared.flagsMap = make(map[string]string)
+ if shared.FlagsMap == nil {
+ shared.NumSharedFlags = 0
+ shared.FlagsMap = make(map[string]string)
}
return shared
}
@@ -1866,6 +1917,14 @@
return name
}
+func (c *Module) Multilib() string {
+ return c.Arch().ArchType.Multilib
+}
+
+func (c *Module) ApexSdkVersion() android.ApiLevel {
+ return c.apexSdkVersion
+}
+
func (c *Module) Symlinks() []string {
if p, ok := c.installer.(interface {
symlinkList() []string
@@ -2222,9 +2281,9 @@
android.SetProvider(ctx, CcObjectInfoProvider, ccObjectInfo)
}
- linkableInfo := CreateCommonLinkableInfo(c)
- if lib, ok := c.linker.(versionedInterface); ok {
- linkableInfo.StubsVersion = lib.stubsVersion()
+ linkableInfo := CreateCommonLinkableInfo(ctx, c)
+ if lib, ok := c.linker.(VersionedInterface); ok {
+ linkableInfo.StubsVersion = lib.StubsVersion()
}
if c.linker != nil {
if library, ok := c.linker.(libraryInterface); ok {
@@ -2240,11 +2299,13 @@
IsPrebuilt: c.IsPrebuilt(),
CmakeSnapshotSupported: proptools.Bool(c.Properties.Cmake_snapshot_supported),
HasLlndkStubs: c.HasLlndkStubs(),
+ DataPaths: c.DataPaths(),
}
if c.compiler != nil {
+ cflags := c.compiler.baseCompilerProps().Cflags
ccInfo.CompilerInfo = &CompilerInfo{
Srcs: c.compiler.(CompiledInterface).Srcs(),
- Cflags: c.compiler.baseCompilerProps().Cflags,
+ Cflags: cflags.GetOrDefault(ctx, nil),
AidlInterfaceInfo: AidlInterfaceInfo{
Sources: c.compiler.baseCompilerProps().AidlInterface.Sources,
AidlRoot: c.compiler.baseCompilerProps().AidlInterface.AidlRoot,
@@ -2255,16 +2316,17 @@
switch decorator := c.compiler.(type) {
case *libraryDecorator:
ccInfo.CompilerInfo.LibraryDecoratorInfo = &LibraryDecoratorInfo{
- ExportIncludeDirs: decorator.flagExporter.Properties.Export_include_dirs,
+ ExportIncludeDirs: decorator.flagExporter.Properties.Export_include_dirs.GetOrDefault(ctx, nil),
}
}
}
if c.linker != nil {
+ baseLinkerProps := c.linker.baseLinkerProps()
ccInfo.LinkerInfo = &LinkerInfo{
- WholeStaticLibs: c.linker.baseLinkerProps().Whole_static_libs,
- StaticLibs: c.linker.baseLinkerProps().Static_libs,
- SharedLibs: c.linker.baseLinkerProps().Shared_libs,
- HeaderLibs: c.linker.baseLinkerProps().Header_libs,
+ WholeStaticLibs: baseLinkerProps.Whole_static_libs.GetOrDefault(ctx, nil),
+ StaticLibs: baseLinkerProps.Static_libs.GetOrDefault(ctx, nil),
+ SharedLibs: baseLinkerProps.Shared_libs.GetOrDefault(ctx, nil),
+ HeaderLibs: baseLinkerProps.Header_libs.GetOrDefault(ctx, nil),
}
switch decorator := c.linker.(type) {
case *binaryDecorator:
@@ -2290,14 +2352,14 @@
SnapshotAndroidMkSuffix: s.SnapshotAndroidMkSuffix(),
}
}
- if v, ok := c.linker.(versionedInterface); ok {
- name := v.implementationModuleName(ctx.OtherModuleName(c))
+ if v, ok := c.linker.(VersionedInterface); ok {
+ name := v.ImplementationModuleName(ctx.OtherModuleName(c))
ccInfo.LinkerInfo.ImplementationModuleName = &name
}
}
if c.library != nil {
ccInfo.LibraryInfo = &LibraryInfo{
- BuildStubs: c.library.buildStubs(),
+ BuildStubs: c.library.BuildStubs(),
}
}
android.SetProvider(ctx, CcInfoProvider, &ccInfo)
@@ -2309,18 +2371,20 @@
}
}
-func CreateCommonLinkableInfo(mod LinkableInterface) *LinkableInfo {
- return &LinkableInfo{
+func CreateCommonLinkableInfo(ctx android.ModuleContext, mod VersionedLinkableInterface) *LinkableInfo {
+ info := &LinkableInfo{
StaticExecutable: mod.StaticExecutable(),
HasStubsVariants: mod.HasStubsVariants(),
OutputFile: mod.OutputFile(),
UnstrippedOutputFile: mod.UnstrippedOutputFile(),
+ CoverageOutputFile: mod.CoverageOutputFile(),
+ Partition: mod.Partition(),
IsStubs: mod.IsStubs(),
CcLibrary: mod.CcLibrary(),
CcLibraryInterface: mod.CcLibraryInterface(),
RustLibraryInterface: mod.RustLibraryInterface(),
- BaseModuleName: mod.BaseModuleName(),
IsLlndk: mod.IsLlndk(),
+ IsNdk: mod.IsNdk(ctx.Config()),
HasNonSystemVariants: mod.HasNonSystemVariants(),
SubName: mod.SubName(),
InVendorOrProduct: mod.InVendorOrProduct(),
@@ -2330,15 +2394,24 @@
OnlyInVendorRamdisk: mod.OnlyInVendorRamdisk(),
InRecovery: mod.InRecovery(),
OnlyInRecovery: mod.OnlyInRecovery(),
+ InVendor: mod.InVendor(),
Installable: mod.Installable(),
RelativeInstallPath: mod.RelativeInstallPath(),
+ // TODO(b/362509506): remove this once all apex_exclude uses are switched to stubs.
+ RustApexExclude: mod.RustApexExclude(),
+ Bootstrap: mod.Bootstrap(),
+ Multilib: mod.Multilib(),
+ ImplementationModuleNameForMake: mod.ImplementationModuleNameForMake(),
+ Symlinks: mod.Symlinks(),
}
-}
-func setOutputFilesIfNotEmpty(ctx ModuleContext, files android.Paths, tag string) {
- if len(files) > 0 {
- ctx.SetOutputFiles(files, tag)
+ vi := mod.VersionedInterface()
+ if vi != nil {
+ info.IsStubsImplementationRequired = vi.IsStubsImplementationRequired()
+ info.APIListCoverageXMLPath = vi.GetAPIListCoverageXMLPath()
}
+
+ return info
}
func (c *Module) setOutputFiles(ctx ModuleContext) {
@@ -2356,7 +2429,7 @@
func buildComplianceMetadataInfo(ctx ModuleContext, c *Module, deps PathDeps) {
// Dump metadata that can not be done in android/compliance-metadata.go
complianceMetadataInfo := ctx.ComplianceMetadataInfo()
- complianceMetadataInfo.SetStringValue(android.ComplianceMetadataProp.IS_STATIC_LIB, strconv.FormatBool(ctx.static()))
+ complianceMetadataInfo.SetStringValue(android.ComplianceMetadataProp.IS_STATIC_LIB, strconv.FormatBool(ctx.static() || ctx.ModuleType() == "cc_object"))
complianceMetadataInfo.SetStringValue(android.ComplianceMetadataProp.BUILT_FILES, c.outputFile.String())
// Static deps
@@ -2365,11 +2438,28 @@
for _, dep := range staticDeps {
staticDepNames = append(staticDepNames, dep.Name())
}
+ // Process CrtBegin and CrtEnd as static libs
+ ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
+ depName := ctx.OtherModuleName(dep)
+ depTag := ctx.OtherModuleDependencyTag(dep)
+ switch depTag {
+ case CrtBeginDepTag:
+ staticDepNames = append(staticDepNames, depName)
+ case CrtEndDepTag:
+ staticDepNames = append(staticDepNames, depName)
+ }
+ })
- staticDepPaths := make([]string, 0, len(deps.StaticLibs))
+ staticDepPaths := make([]string, 0, len(deps.StaticLibs)+len(deps.CrtBegin)+len(deps.CrtEnd))
for _, dep := range deps.StaticLibs {
staticDepPaths = append(staticDepPaths, dep.String())
}
+ for _, dep := range deps.CrtBegin {
+ staticDepPaths = append(staticDepPaths, dep.String())
+ }
+ for _, dep := range deps.CrtEnd {
+ staticDepPaths = append(staticDepPaths, dep.String())
+ }
complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEPS, android.FirstUniqueStrings(staticDepNames))
complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEP_FILES, android.FirstUniqueStrings(staticDepPaths))
@@ -2386,6 +2476,14 @@
}
complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.WHOLE_STATIC_DEPS, android.FirstUniqueStrings(wholeStaticDepNames))
complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.WHOLE_STATIC_DEP_FILES, android.FirstUniqueStrings(wholeStaticDepPaths))
+
+ // Header libs
+ headerLibDeps := ctx.GetDirectDepsProxyWithTag(HeaderDepTag())
+ headerLibDepNames := make([]string, 0, len(headerLibDeps))
+ for _, dep := range headerLibDeps {
+ headerLibDepNames = append(headerLibDepNames, dep.Name())
+ }
+ complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.HEADER_LIBS, android.FirstUniqueStrings(headerLibDepNames))
}
func (c *Module) maybeUnhideFromMake() {
@@ -2465,7 +2563,7 @@
c.orderfile.begin(ctx)
}
if ctx.useSdk() && c.IsSdkVariant() {
- version, err := nativeApiLevelFromUser(ctx, ctx.sdkVersion())
+ version, err := NativeApiLevelFromUser(ctx, ctx.sdkVersion())
if err != nil {
ctx.PropertyErrorf("sdk_version", err.Error())
c.Properties.Sdk_version = nil
@@ -2621,6 +2719,9 @@
variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version})
if tag, ok := depTag.(libraryDependencyTag); ok {
tag.explicitlyVersioned = true
+ if version == "" {
+ tag.explicitlyImpl = true
+ }
// depTag is an interface that contains a concrete non-pointer struct. That makes the local
// tag variable a copy of the contents of depTag, and updating it doesn't change depTag. Reassign
// the modified copy to depTag.
@@ -2979,6 +3080,7 @@
// Recovery code is not NDK
return
}
+ // Change this to LinkableInterface if Rust gets NDK support, which stubDecorators are for
if c, ok := to.(*Module); ok {
if c.StubDecorator() {
// These aren't real libraries, but are the stub shared libraries that are included in
@@ -3085,7 +3187,7 @@
if depTag == staticVariantTag {
return false
}
- if depTag == stubImplDepTag {
+ if depTag == StubImplDepTag {
return false
}
if depTag == android.RequiredDepTag {
@@ -3116,7 +3218,7 @@
}
if module, ok := ctx.Module().(*Module); ok {
if lib, ok := module.linker.(*libraryDecorator); ok && lib.shared() {
- if lib.hasLLNDKStubs() {
+ if lib.HasLLNDKStubs() {
ctx.WalkDeps(check)
}
}
@@ -3254,7 +3356,7 @@
// The reuseObjTag dependency still exists because the LinkageMutator runs before the
// version mutator, so the stubs variant is created from the shared variant that
// already has the reuseObjTag dependency on the static variant.
- if !c.library.buildStubs() {
+ if !c.library.BuildStubs() {
staticAnalogue, _ := android.OtherModuleProvider(ctx, dep, StaticLibraryInfoProvider)
objs := staticAnalogue.ReuseObjects
depPaths.Objs = depPaths.Objs.Append(objs)
@@ -3325,9 +3427,12 @@
depFile = sharedLibraryInfo.TableOfContents
if !sharedLibraryInfo.IsStubs {
- depPaths.directImplementationDeps = append(depPaths.directImplementationDeps, android.OutputFileForModule(ctx, dep, ""))
- if info, ok := android.OtherModuleProvider(ctx, dep, ImplementationDepInfoProvider); ok {
- depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps)
+ // TODO(b/362509506): remove this additional check once all apex_exclude uses are switched to stubs.
+ if !linkableInfo.RustApexExclude {
+ depPaths.directImplementationDeps = append(depPaths.directImplementationDeps, android.OutputFileForModule(ctx, dep, ""))
+ if info, ok := android.OtherModuleProvider(ctx, dep, ImplementationDepInfoProvider); ok {
+ depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps)
+ }
}
}
@@ -3489,7 +3594,7 @@
c.sabi.Properties.ReexportedSystemIncludes, depExporterInfo.SystemIncludeDirs.Strings()...)
}
- makeLibName := MakeLibName(ccInfo, linkableInfo, &commonInfo, linkableInfo.BaseModuleName) + libDepTag.makeSuffix
+ makeLibName := MakeLibName(ccInfo, linkableInfo, &commonInfo, commonInfo.BaseModuleName) + libDepTag.makeSuffix
switch {
case libDepTag.header():
c.Properties.AndroidMkHeaderLibs = append(
@@ -3516,7 +3621,8 @@
switch depTag {
case runtimeDepTag:
c.Properties.AndroidMkRuntimeLibs = append(
- c.Properties.AndroidMkRuntimeLibs, MakeLibName(ccInfo, linkableInfo, &commonInfo, linkableInfo.BaseModuleName)+libDepTag.makeSuffix)
+ c.Properties.AndroidMkRuntimeLibs, MakeLibName(ccInfo, linkableInfo, &commonInfo,
+ commonInfo.BaseModuleName)+libDepTag.makeSuffix)
case objDepTag:
depPaths.Objs.objFiles = append(depPaths.Objs.objFiles, linkFile.Path())
case CrtBeginDepTag:
@@ -3556,14 +3662,23 @@
return depPaths
}
-func ShouldUseStubForApex(ctx android.ModuleContext, parent, dep android.Module) bool {
+func ShouldUseStubForApex(ctx android.ModuleContext, parent android.Module, dep android.ModuleProxy) bool {
inVendorOrProduct := false
bootstrap := false
- if linkable, ok := parent.(LinkableInterface); !ok {
- ctx.ModuleErrorf("Not a Linkable module: %q", ctx.ModuleName())
+ if ctx.EqualModules(ctx.Module(), parent) {
+ if linkable, ok := parent.(LinkableInterface); !ok {
+ ctx.ModuleErrorf("Not a Linkable module: %q", ctx.ModuleName())
+ } else {
+ inVendorOrProduct = linkable.InVendorOrProduct()
+ bootstrap = linkable.Bootstrap()
+ }
} else {
- inVendorOrProduct = linkable.InVendorOrProduct()
- bootstrap = linkable.Bootstrap()
+ if linkable, ok := android.OtherModuleProvider(ctx, parent, LinkableInfoProvider); !ok {
+ ctx.ModuleErrorf("Not a Linkable module: %q", ctx.ModuleName())
+ } else {
+ inVendorOrProduct = linkable.InVendorOrProduct
+ bootstrap = linkable.Bootstrap
+ }
}
apexInfo, _ := android.OtherModuleProvider(ctx, parent, android.ApexInfoProvider)
@@ -3600,7 +3715,7 @@
// library bar which provides stable interface and exists in the platform, foo uses the stub variant
// of bar. If bar doesn't provide a stable interface (i.e. buildStubs() == false) or is in the
// same APEX as foo, the non-stub variant of bar is used.
-func ChooseStubOrImpl(ctx android.ModuleContext, dep android.Module) (SharedLibraryInfo, FlagExporterInfo) {
+func ChooseStubOrImpl(ctx android.ModuleContext, dep android.ModuleProxy) (SharedLibraryInfo, FlagExporterInfo) {
depTag := ctx.OtherModuleDependencyTag(dep)
libDepTag, ok := depTag.(libraryDependencyTag)
if !ok || !libDepTag.shared() {
@@ -3669,7 +3784,7 @@
if ccInfo != nil {
// Use base module name for snapshots when exporting to Makefile.
if ccInfo.SnapshotInfo != nil {
- return linkableInfo.BaseModuleName + ccInfo.SnapshotInfo.SnapshotAndroidMkSuffix
+ return commonInfo.BaseModuleName + ccInfo.SnapshotInfo.SnapshotAndroidMkSuffix
}
}
@@ -3820,6 +3935,10 @@
return false
}
+func (c *Module) ForceDisableSanitizers() {
+ c.sanitize.Properties.ForceDisable = true
+}
+
func (c *Module) StaticExecutable() bool {
if b, ok := c.linker.(*binaryDecorator); ok {
return b.static()
@@ -3875,7 +3994,7 @@
if lib := c.library; lib != nil {
// Stub libs and prebuilt libs in a versioned SDK are not
// installable to APEX even though they are shared libs.
- return lib.shared() && !lib.buildStubs()
+ return lib.shared() && !lib.BuildStubs()
}
return false
}
@@ -3927,15 +4046,6 @@
return ret
}
- // Special case for modules that are configured to be installed to /data, which includes
- // test modules. For these modules, both APEX and non-APEX variants are considered as
- // installable. This is because even the APEX variants won't be included in the APEX, but
- // will anyway be installed to /data/*.
- // See b/146995717
- if c.InstallInData() {
- return ret
- }
-
return false
}
@@ -3950,8 +4060,24 @@
var _ android.ApexModule = (*Module)(nil)
// Implements android.ApexModule
-func (c *Module) OutgoingDepIsInSameApex(depTag blueprint.DependencyTag) bool {
- if depTag == stubImplDepTag {
+func (c *Module) GetDepInSameApexChecker() android.DepInSameApexChecker {
+ return CcDepInSameApexChecker{
+ Static: c.static(),
+ HasStubsVariants: c.HasStubsVariants(),
+ IsLlndk: c.IsLlndk(),
+ Host: c.Host(),
+ }
+}
+
+type CcDepInSameApexChecker struct {
+ Static bool
+ HasStubsVariants bool
+ IsLlndk bool
+ Host bool
+}
+
+func (c CcDepInSameApexChecker) OutgoingDepIsInSameApex(depTag blueprint.DependencyTag) bool {
+ if depTag == StubImplDepTag {
// We don't track from an implementation library to its stubs.
return false
}
@@ -3963,7 +4089,7 @@
}
libDepTag, isLibDepTag := depTag.(libraryDependencyTag)
- if isLibDepTag && c.static() && libDepTag.shared() {
+ if isLibDepTag && c.Static && libDepTag.shared() {
// shared_lib dependency from a static lib is considered as crossing
// the APEX boundary because the dependency doesn't actually is
// linked; the dependency is used only during the compilation phase.
@@ -3977,9 +4103,12 @@
return true
}
-func (c *Module) IncomingDepIsInSameApex(depTag blueprint.DependencyTag) bool {
- if c.HasStubsVariants() {
- if IsSharedDepTag(depTag) {
+func (c CcDepInSameApexChecker) IncomingDepIsInSameApex(depTag blueprint.DependencyTag) bool {
+ if c.Host {
+ return false
+ }
+ if c.HasStubsVariants {
+ if IsSharedDepTag(depTag) && !IsExplicitImplSharedDepTag(depTag) {
// dynamic dep to a stubs lib crosses APEX boundary
return false
}
@@ -3991,7 +4120,7 @@
return false
}
}
- if c.IsLlndk() {
+ if c.IsLlndk {
return false
}
@@ -3999,20 +4128,19 @@
}
// Implements android.ApexModule
-func (c *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
- sdkVersion android.ApiLevel) error {
+func (c *Module) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
// We ignore libclang_rt.* prebuilt libs since they declare sdk_version: 14(b/121358700)
if strings.HasPrefix(ctx.OtherModuleName(c), "libclang_rt") {
- return nil
+ return android.MinApiLevel
}
// We don't check for prebuilt modules
if _, ok := c.linker.(prebuiltLinkerInterface); ok {
- return nil
+ return android.MinApiLevel
}
minSdkVersion := c.MinSdkVersion()
if minSdkVersion == "apex_inherit" {
- return nil
+ return android.MinApiLevel
}
if minSdkVersion == "" {
// JNI libs within APK-in-APEX fall into here
@@ -4021,14 +4149,16 @@
// non-SDK variant resets sdk_version, which works too.
minSdkVersion = c.SdkVersion()
}
+
if minSdkVersion == "" {
- return fmt.Errorf("neither min_sdk_version nor sdk_version specificed")
+ return android.NoneApiLevel
}
+
// Not using nativeApiLevelFromUser because the context here is not
// necessarily a native context.
- ver, err := android.ApiLevelFromUser(ctx, minSdkVersion)
+ ver, err := android.ApiLevelFromUserWithConfig(ctx.Config(), minSdkVersion)
if err != nil {
- return err
+ return android.NoneApiLevel
}
// A dependency only needs to support a min_sdk_version at least
@@ -4036,15 +4166,14 @@
// This allows introducing new architectures in the platform that
// need to be included in apexes that normally require an older
// min_sdk_version.
- minApiForArch := MinApiForArch(ctx, c.Target().Arch.ArchType)
- if sdkVersion.LessThan(minApiForArch) {
- sdkVersion = minApiForArch
+ if c.Enabled(ctx) {
+ minApiForArch := MinApiForArch(ctx, c.Target().Arch.ArchType)
+ if ver.LessThanOrEqualTo(minApiForArch) {
+ ver = android.MinApiLevel
+ }
}
- if ver.GreaterThan(sdkVersion) {
- return fmt.Errorf("newer SDK(%v)", ver)
- }
- return nil
+ return ver
}
// Implements android.ApexModule
@@ -4118,7 +4247,6 @@
type Defaults struct {
android.ModuleBase
android.DefaultsModuleBase
- android.ApexModuleBase
}
// cc_defaults provides a set of properties that can be inherited by other cc
diff --git a/cc/cc_preprocess_no_configuration_test.go b/cc/cc_preprocess_no_configuration_test.go
index c6eae4c..f09c44a 100644
--- a/cc/cc_preprocess_no_configuration_test.go
+++ b/cc/cc_preprocess_no_configuration_test.go
@@ -36,7 +36,7 @@
result := fixture.RunTest(t)
- foo := result.ModuleForTests("foo", "")
+ foo := result.ModuleForTests(t, "foo", "")
actual := foo.Rule("cc").Args["cFlags"]
expected := "-E -DANDROID -Ifoo/bar"
android.AssertStringEquals(t, "cflags should be correct", expected, actual)
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 98af7b6..2c06924 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -160,7 +160,7 @@
}
`)
- ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
+ ld := ctx.ModuleForTests(t, "libTest", vendorVariant).Rule("ld")
var objs []string
for _, o := range ld.Inputs {
objs = append(objs, o.Base())
@@ -171,7 +171,7 @@
}
func checkInstallPartition(t *testing.T, ctx *android.TestContext, name, variant, expected string) {
- mod := ctx.ModuleForTests(name, variant).Module().(*Module)
+ mod := ctx.ModuleForTests(t, name, variant).Module().(*Module)
partitionDefined := false
checkPartition := func(specific bool, partition string) {
if specific {
@@ -311,7 +311,7 @@
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
ctx := testCcWithConfig(t, config)
- testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon")
+ testingModule := ctx.ModuleForTests(t, "main_test", "android_arm_armv7-a-neon")
testBinary := testingModule.Module().(*Module).linker.(*testBinary)
outputFiles := testingModule.OutputFiles(ctx, t, "")
if len(outputFiles) != 1 {
@@ -363,7 +363,7 @@
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
ctx := testCcWithConfig(t, config)
- testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon")
+ testingModule := ctx.ModuleForTests(t, "main_test", "android_arm_armv7-a-neon")
module := testingModule.Module()
testBinary := module.(*Module).linker.(*testBinary)
outputFiles := testingModule.OutputFiles(ctx, t, "")
@@ -405,7 +405,7 @@
`
ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
- module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
+ module := ctx.ModuleForTests(t, "main_test", "android_arm_armv7-a-neon").Module()
entries := android.AndroidMkInfoForTest(t, ctx, module).PrimaryInfo
compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"]
@@ -437,7 +437,7 @@
`
ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
- module := ctx.ModuleForTests("main_test_lib", "android_arm_armv7-a-neon_shared").Module()
+ module := ctx.ModuleForTests(t, "main_test_lib", "android_arm_armv7-a-neon_shared").Module()
entries := android.AndroidMkInfoForTest(t, ctx, module).PrimaryInfo
compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"]
@@ -668,7 +668,7 @@
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
- module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module)
+ module := ctx.ModuleForTests(t, test.name, test.variant).Module().(*Module)
assertString(t, module.makeLinkType, test.expected)
})
}
@@ -861,10 +861,10 @@
`)
variant := "android_arm64_armv8-a_static"
- moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
+ moduleA := ctx.ModuleForTests(t, "a", variant).Module().(*Module)
staticLibInfo, _ := android.OtherModuleProvider(ctx, moduleA, StaticLibraryInfoProvider)
actual := android.Paths(staticLibInfo.TransitiveStaticLibrariesForOrdering.ToList()).RelativeToTop()
- expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b", "d"})
+ expected := GetOutputPaths(t, ctx, variant, []string{"a", "c", "b", "d"})
if !reflect.DeepEqual(actual, expected) {
t.Errorf("staticDeps orderings were not propagated correctly"+
@@ -897,10 +897,10 @@
`)
variant := "android_arm64_armv8-a_static"
- moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
+ moduleA := ctx.ModuleForTests(t, "a", variant).Module().(*Module)
staticLibInfo, _ := android.OtherModuleProvider(ctx, moduleA, StaticLibraryInfoProvider)
actual := android.Paths(staticLibInfo.TransitiveStaticLibrariesForOrdering.ToList()).RelativeToTop()
- expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b"})
+ expected := GetOutputPaths(t, ctx, variant, []string{"a", "c", "b"})
if !reflect.DeepEqual(actual, expected) {
t.Errorf("staticDeps orderings did not account for shared libs"+
@@ -1004,12 +1004,12 @@
}
android.AssertArrayString(t, "variants for llndk stubs", expected, actual)
- params := result.ModuleForTests("libllndk", "android_vendor_arm_armv7-a-neon_shared").Description("generate stub")
+ params := result.ModuleForTests(t, "libllndk", "android_vendor_arm_armv7-a-neon_shared").Description("generate stub")
android.AssertSame(t, "use Vendor API level for default stubs", "35", params.Args["apiLevel"])
checkExportedIncludeDirs := func(module, variant string, expectedSystemDirs []string, expectedDirs ...string) {
t.Helper()
- m := result.ModuleForTests(module, variant).Module()
+ m := result.ModuleForTests(t, module, variant).Module()
f, _ := android.OtherModuleProvider(result, m, FlagExporterInfoProvider)
android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
expectedDirs, f.IncludeDirs)
@@ -1030,14 +1030,14 @@
checkAbiLinkerIncludeDirs := func(module string) {
t.Helper()
- coreModule := result.ModuleForTests(module, coreVariant)
+ coreModule := result.ModuleForTests(t, module, coreVariant)
abiCheckFlags := ""
for _, output := range coreModule.AllOutputs() {
if strings.HasSuffix(output, ".so.llndk.lsdump") {
abiCheckFlags = coreModule.Output(output).Args["exportedHeaderFlags"]
}
}
- vendorModule := result.ModuleForTests(module, vendorVariant).Module()
+ vendorModule := result.ModuleForTests(t, module, vendorVariant).Module()
vendorInfo, _ := android.OtherModuleProvider(result, vendorModule, FlagExporterInfoProvider)
vendorDirs := android.Concat(vendorInfo.IncludeDirs, vendorInfo.SystemIncludeDirs)
android.AssertStringEquals(t, module+" has different exported include dirs for vendor variant and ABI check",
@@ -1078,7 +1078,7 @@
`)
// _static variant is used since _shared reuses *.o from the static variant
- cc := ctx.ModuleForTests("libvendor", "android_vendor_arm_armv7-a-neon_static").Rule("cc")
+ cc := ctx.ModuleForTests(t, "libvendor", "android_vendor_arm_armv7-a-neon_static").Rule("cc")
cflags := cc.Args["cFlags"]
if !strings.Contains(cflags, "-Imy_include") {
t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
@@ -1189,33 +1189,33 @@
// runtime_libs for core variants use the module names without suffixes.
variant := "android_arm64_armv8-a_shared"
- module := ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
+ module := ctx.ModuleForTests(t, "libvendor_available1", variant).Module().(*Module)
checkRuntimeLibs(t, []string{"liball_available"}, module)
- module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
+ module = ctx.ModuleForTests(t, "libproduct_available1", variant).Module().(*Module)
checkRuntimeLibs(t, []string{"liball_available"}, module)
- module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
+ module = ctx.ModuleForTests(t, "libcore", variant).Module().(*Module)
checkRuntimeLibs(t, []string{"liball_available"}, module)
// runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
// and vendor variants.
variant = "android_vendor_arm64_armv8-a_shared"
- module = ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
+ module = ctx.ModuleForTests(t, "libvendor_available1", variant).Module().(*Module)
checkRuntimeLibs(t, []string{"liball_available.vendor"}, module)
- module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
+ module = ctx.ModuleForTests(t, "libvendor2", variant).Module().(*Module)
checkRuntimeLibs(t, []string{"liball_available.vendor", "libvendor1", "libproduct_vendor.vendor"}, module)
// runtime_libs for product variants have '.product' suffixes if the modules have both core
// and product variants.
variant = "android_product_arm64_armv8-a_shared"
- module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
+ module = ctx.ModuleForTests(t, "libproduct_available1", variant).Module().(*Module)
checkRuntimeLibs(t, []string{"liball_available.product"}, module)
- module = ctx.ModuleForTests("libproduct2", variant).Module().(*Module)
+ module = ctx.ModuleForTests(t, "libproduct2", variant).Module().(*Module)
checkRuntimeLibs(t, []string{"liball_available.product", "libproduct1", "libproduct_vendor"}, module)
}
@@ -1224,11 +1224,11 @@
ctx := testCc(t, runtimeLibAndroidBp)
variant := "android_arm64_armv8-a_shared"
- module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
+ module := ctx.ModuleForTests(t, "libvendor_available2", variant).Module().(*Module)
checkRuntimeLibs(t, []string{"liball_available"}, module)
variant = "android_vendor_arm64_armv8-a_shared"
- module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
+ module = ctx.ModuleForTests(t, "libvendor_available2", variant).Module().(*Module)
checkRuntimeLibs(t, nil, module)
}
@@ -1261,12 +1261,12 @@
// Check the shared version of lib2.
variant := "android_arm64_armv8-a_shared"
- module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
+ module := ctx.ModuleForTests(t, "lib2", variant).Module().(*Module)
checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins"}, module)
// Check the static version of lib2.
variant = "android_arm64_armv8-a_static"
- module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
+ module = ctx.ModuleForTests(t, "lib2", variant).Module().(*Module)
// libc++_static is linked additionally.
checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins"}, module)
}
@@ -1387,7 +1387,7 @@
t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
}
- recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
+ recoveryModule := ctx.ModuleForTests(t, "libHalInRecovery", recoveryVariant).Module().(*Module)
if !recoveryModule.Platform() {
t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
}
@@ -1412,7 +1412,7 @@
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
ctx := testCcWithConfig(t, config)
- testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon")
+ testingModule := ctx.ModuleForTests(t, "main_test", "android_arm_armv7-a-neon")
module := testingModule.Module()
testBinary := module.(*Module).linker.(*testBinary)
outputFiles := testingModule.OutputFiles(ctx, t, "")
@@ -1487,14 +1487,14 @@
}
}
- libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("ld")
+ libBarLinkRule := ctx.ModuleForTests(t, "libBar", "android_arm64_armv8-a_shared").Rule("ld")
libFlags := libBarLinkRule.Args["libFlags"]
libFoo1StubPath := "libFoo/android_arm64_armv8-a_shared_1/libFoo.so"
if !strings.Contains(libFlags, libFoo1StubPath) {
t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
}
- libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("cc")
+ libBarCompileRule := ctx.ModuleForTests(t, "libBar", "android_arm64_armv8-a_shared").Rule("cc")
cFlags := libBarCompileRule.Args["cFlags"]
libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
if !strings.Contains(cFlags, libFoo1VersioningMacro) {
@@ -1550,7 +1550,7 @@
}`)
variant := "android_arm64_armv8-a_static"
- arRule := ctx.ModuleForTests("baz", variant).Rule("ar")
+ arRule := ctx.ModuleForTests(t, "baz", variant).Rule("ar")
// For static libraries, the object files of a whole static dep are included in the archive
// directly
@@ -1591,7 +1591,7 @@
}`)
variant := "android_arm64_armv8-a_shared"
- linkRule := ctx.ModuleForTests("baz", variant).Rule("ld")
+ linkRule := ctx.ModuleForTests(t, "baz", variant).Rule("ld")
libFlags := linkRule.Args["libFlags"]
// When dynamically linking, we expect static dependencies to be found on the command line
if expected := "foo.a"; !strings.Contains(libFlags, expected) {
@@ -1623,7 +1623,7 @@
}`)
variant := "android_arm64_armv8-a"
- binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
+ binModuleRule := ctx.ModuleForTests(t, "static_test", variant).Rule("ld")
libFlags := binModuleRule.Args["libFlags"]
systemStaticLibs := []string{"libc.a", "libm.a"}
for _, lib := range systemStaticLibs {
@@ -1666,9 +1666,9 @@
},
}`)
- mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a").Rule("ld")
+ mybin := ctx.ModuleForTests(t, "mybin", "android_arm64_armv8-a").Rule("ld")
actual := mybin.Implicits[:2]
- expected := GetOutputPaths(ctx, "android_arm64_armv8-a_static", []string{"libfooB", "libfooC"})
+ expected := GetOutputPaths(t, ctx, "android_arm64_armv8-a_static", []string{"libfooB", "libfooC"})
if !reflect.DeepEqual(actual, expected) {
t.Errorf("staticDeps orderings were not propagated correctly"+
@@ -1775,7 +1775,7 @@
checkPcGuardFlag := func(
modName string, variantName string, shouldHave bool) {
- cc := ctx.ModuleForTests(modName, variantName).Rule("cc")
+ cc := ctx.ModuleForTests(t, modName, variantName).Rule("cc")
cFlags, ok := cc.Args["cFlags"]
if !ok {
@@ -1802,9 +1802,9 @@
checkPcGuardFlag(moduleName, variant+"_static", false)
checkPcGuardFlag(moduleName, variant+"_static_fuzzer_afl", true)
- ctx.ModuleForTests("afl_fuzz_shared_lib",
+ ctx.ModuleForTests(t, "afl_fuzz_shared_lib",
"android_arm64_armv8-a_shared").Rule("cc")
- ctx.ModuleForTests("afl_fuzz_shared_lib",
+ ctx.ModuleForTests(t, "afl_fuzz_shared_lib",
"android_arm64_armv8-a_shared_fuzzer").Rule("cc")
}
@@ -1833,7 +1833,7 @@
}`)
variant := "android_arm64_armv8-a_fuzzer"
- ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
+ ctx.ModuleForTests(t, "fuzz_smoke_test", variant).Rule("cc")
}
func assertString(t *testing.T, got, expected string) {
@@ -1897,24 +1897,24 @@
defaults: ["defaults"],
}`)
- shared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Rule("ld")
+ shared := ctx.ModuleForTests(t, "libshared", "android_arm64_armv8-a_shared").Rule("ld")
if g, w := pathsToBase(shared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
t.Errorf("libshared ld rule wanted %q, got %q", w, g)
}
- bothShared := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_shared").Rule("ld")
+ bothShared := ctx.ModuleForTests(t, "libboth", "android_arm64_armv8-a_shared").Rule("ld")
if g, w := pathsToBase(bothShared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
t.Errorf("libboth ld rule wanted %q, got %q", w, g)
}
- binary := ctx.ModuleForTests("binary", "android_arm64_armv8-a").Rule("ld")
+ binary := ctx.ModuleForTests(t, "binary", "android_arm64_armv8-a").Rule("ld")
if g, w := pathsToBase(binary.Inputs), []string{"foo.o"}; !reflect.DeepEqual(w, g) {
t.Errorf("binary ld rule wanted %q, got %q", w, g)
}
- static := ctx.ModuleForTests("libstatic", "android_arm64_armv8-a_static").Rule("ar")
+ static := ctx.ModuleForTests(t, "libstatic", "android_arm64_armv8-a_static").Rule("ar")
if g, w := pathsToBase(static.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
t.Errorf("libstatic ar rule wanted %q, got %q", w, g)
}
- bothStatic := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_static").Rule("ar")
+ bothStatic := ctx.ModuleForTests(t, "libboth", "android_arm64_armv8-a_static").Rule("ar")
if g, w := pathsToBase(bothStatic.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
t.Errorf("libboth ar rule wanted %q, got %q", w, g)
}
@@ -1973,12 +1973,12 @@
android.PrepareForTestWithAllowMissingDependencies,
).RunTestWithBp(t, bp)
- libbar := result.ModuleForTests("libbar", "android_arm64_armv8-a_static").Output("libbar.a")
+ libbar := result.ModuleForTests(t, "libbar", "android_arm64_armv8-a_static").Output("libbar.a")
android.AssertDeepEquals(t, "libbar rule", android.ErrorRule, libbar.Rule)
android.AssertStringDoesContain(t, "libbar error", libbar.Args["error"], "missing dependencies: libmissing")
- libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Output("libfoo.a")
+ libfoo := result.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_static").Output("libfoo.a")
android.AssertStringListContains(t, "libfoo.a dependencies", libfoo.Inputs.Strings(), libbar.Output.String())
}
@@ -2025,11 +2025,11 @@
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
ctx := testCcWithConfig(t, config)
- hostBin := ctx.ModuleForTests("bin", config.BuildOSTarget.String()).Description("install")
- hostShared := ctx.ModuleForTests("libshared", config.BuildOSTarget.String()+"_shared").Description("install")
- hostRuntime := ctx.ModuleForTests("libruntime", config.BuildOSTarget.String()+"_shared").Description("install")
- hostTransitive := ctx.ModuleForTests("libtransitive", config.BuildOSTarget.String()+"_shared").Description("install")
- hostTool := ctx.ModuleForTests("tool", config.BuildOSTarget.String()).Description("install")
+ hostBin := ctx.ModuleForTests(t, "bin", config.BuildOSTarget.String()).Description("install")
+ hostShared := ctx.ModuleForTests(t, "libshared", config.BuildOSTarget.String()+"_shared").Description("install")
+ hostRuntime := ctx.ModuleForTests(t, "libruntime", config.BuildOSTarget.String()+"_shared").Description("install")
+ hostTransitive := ctx.ModuleForTests(t, "libtransitive", config.BuildOSTarget.String()+"_shared").Description("install")
+ hostTool := ctx.ModuleForTests(t, "tool", config.BuildOSTarget.String()).Description("install")
if g, w := hostBin.Implicits.Strings(), hostShared.Output.String(); !android.InList(w, g) {
t.Errorf("expected host bin dependency %q, got %q", w, g)
@@ -2051,10 +2051,10 @@
t.Errorf("expected no host bin dependency %q, got %q", w, g)
}
- deviceBin := ctx.ModuleForTests("bin", "android_arm64_armv8-a").Description("install")
- deviceShared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Description("install")
- deviceTransitive := ctx.ModuleForTests("libtransitive", "android_arm64_armv8-a_shared").Description("install")
- deviceRuntime := ctx.ModuleForTests("libruntime", "android_arm64_armv8-a_shared").Description("install")
+ deviceBin := ctx.ModuleForTests(t, "bin", "android_arm64_armv8-a").Description("install")
+ deviceShared := ctx.ModuleForTests(t, "libshared", "android_arm64_armv8-a_shared").Description("install")
+ deviceTransitive := ctx.ModuleForTests(t, "libtransitive", "android_arm64_armv8-a_shared").Description("install")
+ deviceRuntime := ctx.ModuleForTests(t, "libruntime", "android_arm64_armv8-a_shared").Description("install")
if g, w := deviceBin.OrderOnly.Strings(), deviceShared.Output.String(); !android.InList(w, g) {
t.Errorf("expected device bin dependency %q, got %q", w, g)
@@ -2104,7 +2104,7 @@
srcs: ["foo.c"],
}`)
- cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
+ cFlags := ctx.ModuleForTests(t, "libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
if !strings.Contains(cFlags, "-Iinclude/libbar") {
t.Errorf("expected %q in cflags, got %q", "-Iinclude/libbar", cFlags)
@@ -2144,7 +2144,7 @@
}.AddToFixture(),
).RunTest(t).TestContext
- libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
+ libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_static")
android.AssertPathsRelativeToTopEquals(
t,
@@ -2192,7 +2192,7 @@
}
`)
- libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
+ libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_static")
manifest := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, libfoo.Output("aidl.sbox.textproto"))
aidlCommand := manifest.Commands[0].GetCommand()
expectedAidlFlag := "-Werror"
@@ -2243,7 +2243,7 @@
`+tc.sdkVersion+`
}
`)
- libfoo := ctx.ModuleForTests("libfoo", tc.variant)
+ libfoo := ctx.ModuleForTests(t, "libfoo", tc.variant)
manifest := android.RuleBuilderSboxProtoForTests(t, ctx, libfoo.Output("aidl.sbox.textproto"))
aidlCommand := manifest.Commands[0].GetCommand()
expectedAidlFlag := "--min_sdk_version=" + tc.expected
@@ -2312,7 +2312,7 @@
min_sdk_version: "29",
}`)
- cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
+ cFlags := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android29")
}
@@ -2332,7 +2332,7 @@
}),
).RunTestWithBp(t, bp)
ctx := result.TestContext
- cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
+ cFlags := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android31")
}
@@ -2439,7 +2439,7 @@
export_generated_headers: ["genrule_bar"],
}
`)
- foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
+ foo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module()
checkIncludeDirs(t, ctx, foo,
expectedIncludeDirs(`
foo/standard
@@ -2450,7 +2450,7 @@
expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
)
- bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
+ bar := ctx.ModuleForTests(t, "libbar", "android_arm64_armv8-a_shared").Module()
checkIncludeDirs(t, ctx, bar,
expectedIncludeDirs(`
bar/standard
@@ -2483,7 +2483,7 @@
export_generated_headers: ["genrule_bar"],
}
`)
- foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
+ foo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module()
checkIncludeDirs(t, ctx, foo,
expectedIncludeDirs(`
foo/standard
@@ -2494,7 +2494,7 @@
expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
)
- bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
+ bar := ctx.ModuleForTests(t, "libbar", "android_arm64_armv8-a_shared").Module()
checkIncludeDirs(t, ctx, bar,
expectedIncludeDirs(`
bar/standard
@@ -2540,7 +2540,7 @@
}
}
`).TestContext
- foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
+ foo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module()
checkIncludeDirs(t, ctx, foo,
expectedIncludeDirs(`
.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl
@@ -2580,7 +2580,7 @@
}
}
`)
- foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
+ foo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module()
checkIncludeDirs(t, ctx, foo,
expectedIncludeDirs(`
.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto
@@ -2607,7 +2607,7 @@
],
}
`)
- foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
+ foo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module()
checkIncludeDirs(t, ctx, foo,
expectedIncludeDirs(`
.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include
@@ -2877,7 +2877,7 @@
PrepareForIntegrationTestWithCc,
android.FixtureAddTextFile("external/foo/Android.bp", bp),
).RunTest(t)
- cflags := ctx.ModuleForTests("libfoo", variant).Output("obj/external/foo/foo.o").Args["cFlags"]
+ cflags := ctx.ModuleForTests(t, "libfoo", variant).Output("obj/external/foo/foo.o").Args["cFlags"]
var includes []string
flags := strings.Split(cflags, " ")
@@ -2931,7 +2931,7 @@
srcs: ["foo.c"],
}`)
- cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
+ cFlags := ctx.ModuleForTests(t, "libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
if !strings.Contains(cFlags, "${config.NoOverride64GlobalCflags}") {
t.Errorf("expected %q in cflags, got %q", "${config.NoOverride64GlobalCflags}", cFlags)
@@ -3095,7 +3095,7 @@
`
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
ctx := testCcWithConfig(t, config)
- testingModule := ctx.ModuleForTests("test_lib", "android_arm_armv7-a-neon_shared")
+ testingModule := ctx.ModuleForTests(t, "test_lib", "android_arm_armv7-a-neon_shared")
outputFile := testingModule.OutputFiles(ctx, t, "stripped_all")
if !strings.HasSuffix(outputFile.Strings()[0], "/stripped_all/test_lib.so") {
t.Errorf("Unexpected output file: %s", outputFile.Strings()[0])
@@ -3140,8 +3140,8 @@
if imageVariant != "core" {
imageVariantStr = "_" + imageVariant
}
- binFooModule := ctx.ModuleForTests("binfoo", "android"+imageVariantStr+"_arm64_armv8-a").Module()
- libBarModule := ctx.ModuleForTests("libbar", "android"+imageVariantStr+"_arm64_armv8-a_shared").Module()
+ binFooModule := ctx.ModuleForTests(t, "binfoo", "android"+imageVariantStr+"_arm64_armv8-a").Module()
+ libBarModule := ctx.ModuleForTests(t, "libbar", "android"+imageVariantStr+"_arm64_armv8-a_shared").Module()
android.AssertBoolEquals(t, "binfoo should have dependency on libbar with image variant "+imageVariant, true, hasDep(binFooModule, libBarModule))
}
@@ -3172,7 +3172,7 @@
ctx := prepareForCcTest.RunTestWithBp(t, bp)
testSdkVersionFlag := func(module, variant, version string) {
- flags := ctx.ModuleForTests(module, "android_"+variant+"_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
+ flags := ctx.ModuleForTests(t, module, "android_"+variant+"_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
android.AssertStringDoesContain(t, "target SDK version", flags, "-target aarch64-linux-android"+version)
}
@@ -3199,14 +3199,14 @@
}
`)
- module := ctx.ModuleForTests("lib_no_clang_verify", "android_arm64_armv8-a_shared")
+ module := ctx.ModuleForTests(t, "lib_no_clang_verify", "android_arm64_armv8-a_shared")
cFlags_no_cv := module.Rule("cc").Args["cFlags"]
if strings.Contains(cFlags_no_cv, "-Xclang") || strings.Contains(cFlags_no_cv, "-verify") {
t.Errorf("expected %q not in cflags, got %q", "-Xclang -verify", cFlags_no_cv)
}
- cFlags_cv := ctx.ModuleForTests("lib_clang_verify", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
+ cFlags_cv := ctx.ModuleForTests(t, "lib_clang_verify", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
if strings.Contains(cFlags_cv, "-Xclang") && strings.Contains(cFlags_cv, "-verify") {
t.Errorf("expected %q in cflags, got %q", "-Xclang -verify", cFlags_cv)
}
diff --git a/cc/cc_test_only_property_test.go b/cc/cc_test_only_property_test.go
index 972e86b..a178cad 100644
--- a/cc/cc_test_only_property_test.go
+++ b/cc/cc_test_only_property_test.go
@@ -173,7 +173,7 @@
func getTeamProtoOutput(t *testing.T, ctx *android.TestResult) *team_proto.AllTeams {
teams := new(team_proto.AllTeams)
- config := ctx.SingletonForTests("all_teams")
+ config := ctx.SingletonForTests(t, "all_teams")
allOutputs := config.AllOutputs()
protoPath := allOutputs[0]
diff --git a/cc/ccdeps.go b/cc/ccdeps.go
index 469fe31..4247778 100644
--- a/cc/ccdeps.go
+++ b/cc/ccdeps.go
@@ -41,8 +41,6 @@
outputPath android.Path
}
-var _ android.SingletonMakeVarsProvider = (*ccdepsGeneratorSingleton)(nil)
-
const (
ccdepsJsonFileName = "module_bp_cc_deps.json"
cClang = "clang"
@@ -114,13 +112,6 @@
Rule: android.Touch,
Output: ccfpath,
})
-}
-
-func (c *ccdepsGeneratorSingleton) MakeVars(ctx android.MakeVarsContext) {
- if c.outputPath == nil {
- return
- }
-
ctx.DistForGoal("general-tests", c.outputPath)
}
diff --git a/cc/cmake_snapshot.go b/cc/cmake_snapshot.go
index 71fbcce..3f6a01d 100644
--- a/cc/cmake_snapshot.go
+++ b/cc/cmake_snapshot.go
@@ -204,24 +204,19 @@
return info.CompilerInfo.AidlInterfaceInfo
},
"getCflagsProperty": func(ctx android.ModuleContext, info *CcInfo) []string {
- prop := info.CompilerInfo.Cflags
- return prop.GetOrDefault(ctx, nil)
+ return info.CompilerInfo.Cflags
},
"getWholeStaticLibsProperty": func(ctx android.ModuleContext, info *CcInfo) []string {
- prop := info.LinkerInfo.WholeStaticLibs
- return prop.GetOrDefault(ctx, nil)
+ return info.LinkerInfo.WholeStaticLibs
},
"getStaticLibsProperty": func(ctx android.ModuleContext, info *CcInfo) []string {
- prop := info.LinkerInfo.StaticLibs
- return prop.GetOrDefault(ctx, nil)
+ return info.LinkerInfo.StaticLibs
},
"getSharedLibsProperty": func(ctx android.ModuleContext, info *CcInfo) []string {
- prop := info.LinkerInfo.SharedLibs
- return prop.GetOrDefault(ctx, nil)
+ return info.LinkerInfo.SharedLibs
},
"getHeaderLibsProperty": func(ctx android.ModuleContext, info *CcInfo) []string {
- prop := info.LinkerInfo.HeaderLibs
- return prop.GetOrDefault(ctx, nil)
+ return info.LinkerInfo.HeaderLibs
},
"getExtraLibs": getExtraLibs,
"getIncludeDirs": getIncludeDirs,
@@ -552,7 +547,7 @@
func getIncludeDirs(ctx android.ModuleContext, m android.ModuleProxy, info *CcInfo) []string {
moduleDir := ctx.OtherModuleDir(m) + string(filepath.Separator)
if info.CompilerInfo.LibraryDecoratorInfo != nil {
- return sliceWithPrefix(moduleDir, info.CompilerInfo.LibraryDecoratorInfo.ExportIncludeDirs.GetOrDefault(ctx, nil))
+ return sliceWithPrefix(moduleDir, info.CompilerInfo.LibraryDecoratorInfo.ExportIncludeDirs)
}
return nil
}
diff --git a/cc/cmake_snapshot_test.go b/cc/cmake_snapshot_test.go
index b6f4369..d08096a 100644
--- a/cc/cmake_snapshot_test.go
+++ b/cc/cmake_snapshot_test.go
@@ -49,7 +49,7 @@
t.Skip("CMake snapshots are only supported on Linux")
}
- snapshotModule := result.ModuleForTests("foo", "linux_glibc_x86_64")
+ snapshotModule := result.ModuleForTests(t, "foo", "linux_glibc_x86_64")
wasGenerated(t, &snapshotModule, "CMakeLists.txt", "rawFileCopy")
wasGenerated(t, &snapshotModule, "foo.zip", "")
@@ -77,7 +77,7 @@
t.Skip("CMake snapshots are only supported on Linux")
}
- snapshotModule := result.ModuleForTests("foo", "linux_glibc_x86_64")
+ snapshotModule := result.ModuleForTests(t, "foo", "linux_glibc_x86_64")
wasGenerated(t, &snapshotModule, "some/module/CMakeLists.txt", "rawFileCopy")
}
@@ -110,7 +110,7 @@
t.Skip("CMake snapshots are only supported on Linux")
}
- snapshotModule := result.ModuleForTests("foo", "linux_glibc_x86_64")
+ snapshotModule := result.ModuleForTests(t, "foo", "linux_glibc_x86_64")
wasGenerated(t, &snapshotModule, "CMakeLists.txt", "rawFileCopy")
wasGenerated(t, &snapshotModule, "foo.zip", "")
diff --git a/cc/compiler.go b/cc/compiler.go
index f2bced1..949603e 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -324,6 +324,10 @@
getNamedMapForConfig(ctx.Config(), key).Store(module, true)
}
+func requiresGlobalIncludes(ctx ModuleContext) bool {
+ return !(ctx.useSdk() || ctx.InVendorOrProduct()) || ctx.Host()
+}
+
func useGnuExtensions(gnuExtensions *bool) bool {
return proptools.BoolDefault(gnuExtensions, true)
}
@@ -360,6 +364,29 @@
}
}
+func AddTargetFlags(ctx android.ModuleContext, flags Flags, tc config.Toolchain, version string, bpf bool) Flags {
+ target := "-target " + tc.ClangTriple()
+ if ctx.Os().Class == android.Device {
+ if version == "" || version == "current" {
+ target += strconv.Itoa(android.FutureApiLevelInt)
+ } else {
+ apiLevel := nativeApiLevelOrPanic(ctx, version)
+ target += strconv.Itoa(apiLevel.FinalOrFutureInt())
+ }
+ }
+
+ // bpf targets don't need the default target triple. b/308826679
+ if bpf {
+ target = "--target=bpf"
+ }
+
+ flags.Global.CFlags = append(flags.Global.CFlags, target)
+ flags.Global.AsFlags = append(flags.Global.AsFlags, target)
+ flags.Global.LdFlags = append(flags.Global.LdFlags, target)
+
+ return flags
+}
+
// Create a Flags struct that collects the compile flags from global values,
// per-target values, module type values, and per-module Blueprints properties
func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
@@ -429,7 +456,7 @@
flags.Local.YasmFlags = append(flags.Local.YasmFlags, "-I"+modulePath)
}
- if !(ctx.useSdk() || ctx.InVendorOrProduct()) || ctx.Host() {
+ if requiresGlobalIncludes(ctx) {
flags.SystemIncludeFlags = append(flags.SystemIncludeFlags,
"${config.CommonGlobalIncludes}",
tc.IncludeFlags())
@@ -513,25 +540,7 @@
flags.Local.ConlyFlags = config.ClangFilterUnknownCflags(flags.Local.ConlyFlags)
flags.Local.LdFlags = config.ClangFilterUnknownCflags(flags.Local.LdFlags)
- target := "-target " + tc.ClangTriple()
- if ctx.Os().Class == android.Device {
- version := ctx.minSdkVersion()
- if version == "" || version == "current" {
- target += strconv.Itoa(android.FutureApiLevelInt)
- } else {
- apiLevel := nativeApiLevelOrPanic(ctx, version)
- target += strconv.Itoa(apiLevel.FinalOrFutureInt())
- }
- }
-
- // bpf targets don't need the default target triple. b/308826679
- if proptools.Bool(compiler.Properties.Bpf_target) {
- target = "--target=bpf"
- }
-
- flags.Global.CFlags = append(flags.Global.CFlags, target)
- flags.Global.AsFlags = append(flags.Global.AsFlags, target)
- flags.Global.LdFlags = append(flags.Global.LdFlags, target)
+ flags = AddTargetFlags(ctx, flags, tc, ctx.minSdkVersion(), Bool(compiler.Properties.Bpf_target))
hod := "Host"
if ctx.Os().Class == android.Device {
@@ -785,7 +794,7 @@
objs := compileObjs(ctx, buildFlags, "", srcs,
append(android.PathsForModuleSrc(ctx, compiler.Properties.Tidy_disabled_srcs), compiler.generatedSources...),
android.PathsForModuleSrc(ctx, compiler.Properties.Tidy_timeout_srcs),
- pathDeps, compiler.cFlagsDeps)
+ pathDeps, compiler.cFlagsDeps, ctx.getSharedFlags())
if ctx.Failed() {
return Objects{}
@@ -795,10 +804,12 @@
}
// Compile a list of source files into objects a specified subdirectory
-func compileObjs(ctx ModuleContext, flags builderFlags, subdir string,
- srcFiles, noTidySrcs, timeoutTidySrcs, pathDeps android.Paths, cFlagsDeps android.Paths) Objects {
+func compileObjs(ctx android.ModuleContext, flags builderFlags, subdir string,
+ srcFiles, noTidySrcs, timeoutTidySrcs, pathDeps android.Paths, cFlagsDeps android.Paths,
+ sharedFlags *SharedFlags) Objects {
- return transformSourceToObj(ctx, subdir, srcFiles, noTidySrcs, timeoutTidySrcs, flags, pathDeps, cFlagsDeps)
+ return transformSourceToObj(ctx, subdir, srcFiles, noTidySrcs, timeoutTidySrcs, flags, pathDeps, cFlagsDeps,
+ sharedFlags)
}
// Properties for rust_bindgen related to generating rust bindings.
diff --git a/cc/config/OWNERS b/cc/config/OWNERS
index c78b6d5..2668fdd 100644
--- a/cc/config/OWNERS
+++ b/cc/config/OWNERS
@@ -1,3 +1,2 @@
per-file vndk.go = smoreland@google.com, victoryang@google.com
-per-file clang.go,global.go,tidy.go = appujee@google.com, pirama@google.com, srhines@google.com, yabinc@google.com, yikong@google.com, zijunzhao@google.com
-
+per-file clang.go,global.go,tidy.go = appujee@google.com, pirama@google.com, srhines@google.com, yabinc@google.com, yikong@google.com, rprichard@google.com, sharjeelkhan@google.com
\ No newline at end of file
diff --git a/cc/config/global.go b/cc/config/global.go
index d969e97..7bea124 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -290,11 +290,8 @@
// New warnings to be fixed after clang-r468909
"-Wno-error=deprecated-builtins", // http://b/241601211
"-Wno-error=deprecated", // in external/googletest/googletest
- // Disabling until the warning is fixed in libc++abi header files b/366180429
- "-Wno-deprecated-dynamic-exception-spec",
// New warnings to be fixed after clang-r522817
"-Wno-error=invalid-offsetof",
- "-Wno-error=thread-safety-reference-return",
// Allow using VLA CXX extension.
"-Wno-vla-cxx-extension",
@@ -385,8 +382,8 @@
// prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host"
- ClangDefaultVersion = "clang-r536225"
- ClangDefaultShortVersion = "19"
+ ClangDefaultVersion = "clang-r547379"
+ ClangDefaultShortVersion = "20"
// Directories with warnings from Android.bp files.
WarningAllowedProjects = []string{
diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go
index 287967c..c070050 100644
--- a/cc/config/x86_linux_host.go
+++ b/cc/config/x86_linux_host.go
@@ -41,7 +41,6 @@
}
linuxMuslCflags = []string{
- "-D_LIBCPP_HAS_MUSL_LIBC",
"-DANDROID_HOST_MUSL",
"-nostdlibinc",
"--sysroot /dev/null",
diff --git a/cc/coverage.go b/cc/coverage.go
index dbb424f..757641c 100644
--- a/cc/coverage.go
+++ b/cc/coverage.go
@@ -273,8 +273,6 @@
type coverageTransitionMutator struct{}
-var _ android.TransitionMutator = (*coverageTransitionMutator)(nil)
-
func (c coverageTransitionMutator) Split(ctx android.BaseModuleContext) []string {
if c, ok := ctx.Module().(*Module); ok && c.coverage != nil {
if c.coverage.Properties.NeedCoverageVariant {
@@ -354,10 +352,10 @@
}
}
-func parseSymbolFileForAPICoverage(ctx ModuleContext, symbolFile string) android.ModuleOutPath {
+func ParseSymbolFileForAPICoverage(ctx android.ModuleContext, symbolFile string) android.ModuleOutPath {
apiLevelsJson := android.GetApiLevelsJson(ctx)
symbolFilePath := android.PathForModuleSrc(ctx, symbolFile)
- outputFile := ctx.baseModuleName() + ".xml"
+ outputFile := ctx.Module().(LinkableInterface).BaseModuleName() + ".xml"
parsedApiCoveragePath := android.PathForModuleOut(ctx, outputFile)
rule := android.NewRuleBuilder(pctx, ctx)
rule.Command().
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 056b0da..bd3d8e4 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -244,7 +244,7 @@
// libraries must be handled differently - by looking for the stubDecorator.
// Discard LLNDK prebuilts stubs as well.
if hasCcInfo {
- if ccInfo.LinkerInfo.StubDecoratorInfo != nil {
+ if ccInfo.LinkerInfo != nil && ccInfo.LinkerInfo.StubDecoratorInfo != nil {
return false
}
// Discard installable:false libraries because they are expected to be absent
@@ -353,6 +353,7 @@
fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Data)
fuzzPackagedModule.Data = append(fuzzPackagedModule.Data, android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Device_common_data)...)
fuzzPackagedModule.Data = append(fuzzPackagedModule.Data, android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Device_first_data)...)
+ fuzzPackagedModule.Data = append(fuzzPackagedModule.Data, android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Host_common_data)...)
if fuzzPackagedModule.FuzzProperties.Dictionary != nil {
fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzzPackagedModule.FuzzProperties.Dictionary)
diff --git a/cc/gen_test.go b/cc/gen_test.go
index 439f0a9..dde0dcf 100644
--- a/cc/gen_test.go
+++ b/cc/gen_test.go
@@ -33,8 +33,8 @@
],
}`)
- aidl := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("aidl")
- libfoo := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Module().(*Module)
+ aidl := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_shared").Rule("aidl")
+ libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_shared").Module().(*Module)
expected := "-I" + filepath.Dir(aidl.Output.String())
actual := android.StringsRelativeToTop(ctx.Config(), libfoo.flags.Local.CommonFlags)
@@ -59,9 +59,9 @@
],
}`)
- aidl := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("aidl")
- aidlManifest := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Output("aidl.sbox.textproto")
- libfoo := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Module().(*Module)
+ aidl := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_shared").Rule("aidl")
+ aidlManifest := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_shared").Output("aidl.sbox.textproto")
+ libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_shared").Module().(*Module)
if !inList("-I"+filepath.Dir(aidl.Output.String()), android.StringsRelativeToTop(ctx.Config(), libfoo.flags.Local.CommonFlags)) {
t.Errorf("missing aidl includes in global flags")
@@ -84,7 +84,7 @@
}`)
outDir := "out/soong/.intermediates/libsysprop/android_arm64_armv8-a_static/gen"
- syspropBuildParams := ctx.ModuleForTests("libsysprop", "android_arm64_armv8-a_static").Rule("sysprop")
+ syspropBuildParams := ctx.ModuleForTests(t, "libsysprop", "android_arm64_armv8-a_static").Rule("sysprop")
android.AssertStringEquals(t, "header output directory does not match", outDir+"/sysprop/include/path/to", syspropBuildParams.Args["headerOutDir"])
android.AssertStringEquals(t, "public output directory does not match", outDir+"/sysprop/public/include/path/to", syspropBuildParams.Args["publicOutDir"])
diff --git a/cc/genrule_test.go b/cc/genrule_test.go
index 9a8049b..438eb98 100644
--- a/cc/genrule_test.go
+++ b/cc/genrule_test.go
@@ -64,13 +64,13 @@
t.Fatal(errs)
}
- gen := ctx.ModuleForTests("gen", "android_arm_armv7-a-neon").Output("out_arm")
+ gen := ctx.ModuleForTests(t, "gen", "android_arm_armv7-a-neon").Output("out_arm")
expected := []string{"foo"}
if !reflect.DeepEqual(expected, gen.Implicits.Strings()[:len(expected)]) {
t.Errorf(`want arm inputs %v, got %v`, expected, gen.Implicits.Strings())
}
- gen = ctx.ModuleForTests("gen", "android_arm64_armv8-a").Output("out_arm")
+ gen = ctx.ModuleForTests(t, "gen", "android_arm64_armv8-a").Output("out_arm")
expected = []string{"bar"}
if !reflect.DeepEqual(expected, gen.Implicits.Strings()[:len(expected)]) {
t.Errorf(`want arm64 inputs %v, got %v`, expected, gen.Implicits.Strings())
@@ -105,7 +105,7 @@
`
ctx := testCc(t, bp)
- gen := ctx.ModuleForTests("gen", "android_arm_armv7-a-neon").Output("out")
+ gen := ctx.ModuleForTests(t, "gen", "android_arm_armv7-a-neon").Output("out")
expected := []string{"libboth.so", "libshared.so", "libstatic.a"}
var got []string
for _, input := range gen.Implicits {
@@ -178,7 +178,7 @@
PrepareForIntegrationTestWithCc,
android.OptionalFixturePreparer(tt.preparer),
).RunTestWithBp(t, bp)
- gen := result.ModuleForTests("gen", tt.variant)
+ gen := result.ModuleForTests(t, "gen", tt.variant)
sboxProto := android.RuleBuilderSboxProtoForTests(t, result.TestContext, gen.Output("genrule.sbox.textproto"))
cmd := *sboxProto.Commands[0].Command
android.AssertStringDoesContain(t, "incorrect CC_ARCH", cmd, "CC_ARCH="+tt.arch+" ")
@@ -236,7 +236,7 @@
}
`
result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, bp)
- gen_32bit := result.ModuleForTests("gen", "android_arm_armv7-a-neon").OutputFiles(result.TestContext, t, "")
+ gen_32bit := result.ModuleForTests(t, "gen", "android_arm_armv7-a-neon").OutputFiles(result.TestContext, t, "")
android.AssertPathsEndWith(t,
"genrule_out",
[]string{
@@ -245,7 +245,7 @@
gen_32bit,
)
- gen_64bit := result.ModuleForTests("gen", "android_arm64_armv8-a").OutputFiles(result.TestContext, t, "")
+ gen_64bit := result.ModuleForTests(t, "gen", "android_arm64_armv8-a").OutputFiles(result.TestContext, t, "")
android.AssertPathsEndWith(t,
"genrule_out",
[]string{
diff --git a/cc/installer.go b/cc/installer.go
index 30f9612..d7d8c6d 100644
--- a/cc/installer.go
+++ b/cc/installer.go
@@ -107,6 +107,10 @@
installer.installDeps = append(installer.installDeps, installedData...)
}
+func (installer *baseInstaller) installStandaloneTestDep(ctx ModuleContext, standaloneTestDep android.PackagingSpec) {
+ installer.installTestData(ctx, []android.DataPath{{SrcPath: standaloneTestDep.ToGob().SrcPath, RelativeInstallPath: "standalone-libs"}})
+}
+
func (installer *baseInstaller) everInstallable() bool {
// Most cc modules are installable.
return true
diff --git a/cc/library.go b/cc/library.go
index 0566182..532b7e9 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -25,6 +25,7 @@
"sync"
"android/soong/android"
+ "android/soong/cc/config"
"github.com/google/blueprint"
"github.com/google/blueprint/depset"
@@ -64,21 +65,7 @@
Static_ndk_lib *bool
// Generate stubs to make this library accessible to APEXes.
- Stubs struct {
- // Relative path to the symbol map. The symbol map provides the list of
- // symbols that are exported for stubs variant of this library.
- Symbol_file *string `android:"path,arch_variant"`
-
- // List versions to generate stubs libs for. The version name "current" is always
- // implicitly added.
- Versions []string
-
- // Whether to not require the implementation of the library to be installed if a
- // client of the stubs is installed. Defaults to true; set to false if the
- // implementation is made available by some other means, e.g. in a Microdroid
- // virtual machine.
- Implementation_installable *bool
- } `android:"arch_variant"`
+ Stubs StubsProperties `android:"arch_variant"`
// set the name of the output
Stem *string `android:"arch_variant"`
@@ -127,6 +114,22 @@
Vendor_public_library vendorPublicLibraryProperties
}
+type StubsProperties struct {
+ // Relative path to the symbol map. The symbol map provides the list of
+ // symbols that are exported for stubs variant of this library.
+ Symbol_file *string `android:"path,arch_variant"`
+
+ // List versions to generate stubs libs for. The version name "current" is always
+ // implicitly added.
+ Versions []string
+
+ // Whether to not require the implementation of the library to be installed if a
+ // client of the stubs is installed. Defaults to true; set to false if the
+ // implementation is made available by some other means, e.g. in a Microdroid
+ // virtual machine.
+ Implementation_installable *bool
+}
+
// StaticProperties is a properties stanza to affect only attributes of the "static" variants of a
// library module.
type StaticProperties struct {
@@ -457,11 +460,15 @@
return props
}
-// linkerFlags takes a Flags struct and augments it to contain linker flags that are defined by this
-// library, or that are implied by attributes of this library (such as whether this library is a
-// shared library).
-func (library *libraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
- flags = library.baseLinker.linkerFlags(ctx, flags)
+func CommonLibraryLinkerFlags(ctx android.ModuleContext, flags Flags,
+ toolchain config.Toolchain, libName string) Flags {
+
+ mod, ok := ctx.Module().(LinkableInterface)
+
+ if !ok {
+ ctx.ModuleErrorf("trying to add linker flags to a non-LinkableInterface module.")
+ return flags
+ }
// MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
// all code is position independent, and then those warnings get promoted to
@@ -469,27 +476,18 @@
if !ctx.Windows() {
flags.Global.CFlags = append(flags.Global.CFlags, "-fPIC")
}
-
- if library.static() {
- flags.Local.CFlags = append(flags.Local.CFlags, library.StaticProperties.Static.Cflags.GetOrDefault(ctx, nil)...)
- } else if library.shared() {
- flags.Local.CFlags = append(flags.Local.CFlags, library.SharedProperties.Shared.Cflags.GetOrDefault(ctx, nil)...)
- }
-
- if library.shared() {
- libName := library.getLibName(ctx)
+ if mod.Shared() {
var f []string
- if ctx.toolchain().Bionic() {
+ if toolchain.Bionic() {
f = append(f,
"-nostdlib",
"-Wl,--gc-sections",
)
}
-
if ctx.Darwin() {
f = append(f,
"-dynamiclib",
- "-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
+ "-install_name @rpath/"+libName+toolchain.ShlibSuffix(),
)
if ctx.Arch().ArchType == android.X86 {
f = append(f,
@@ -499,16 +497,30 @@
} else {
f = append(f, "-shared")
if !ctx.Windows() {
- f = append(f, "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix())
+ f = append(f, "-Wl,-soname,"+libName+toolchain.ShlibSuffix())
}
}
-
flags.Global.LdFlags = append(flags.Global.LdFlags, f...)
}
return flags
}
+// linkerFlags takes a Flags struct and augments it to contain linker flags that are defined by this
+// library, or that are implied by attributes of this library (such as whether this library is a
+// shared library).
+func (library *libraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
+ flags = library.baseLinker.linkerFlags(ctx, flags)
+ flags = CommonLibraryLinkerFlags(ctx, flags, ctx.toolchain(), library.getLibName(ctx))
+ if library.static() {
+ flags.Local.CFlags = append(flags.Local.CFlags, library.StaticProperties.Static.Cflags.GetOrDefault(ctx, nil)...)
+ } else if library.shared() {
+ flags.Local.CFlags = append(flags.Local.CFlags, library.SharedProperties.Shared.Cflags.GetOrDefault(ctx, nil)...)
+ }
+
+ return flags
+}
+
// compilerFlags takes a Flags and augments it to contain compile flags from global values,
// per-target values, module type values, per-module Blueprints properties, extra flags from
// `flags`, and generated sources from `deps`.
@@ -527,7 +539,7 @@
// Wipe all the module-local properties, leaving only the global properties.
flags.Local = LocalOrGlobalFlags{}
}
- if library.buildStubs() {
+ if library.BuildStubs() {
// Remove -include <file> when compiling stubs. Otherwise, the force included
// headers might cause conflicting types error with the symbols in the
// generated stubs source code. e.g.
@@ -546,7 +558,7 @@
flags.Local.CommonFlags = removeInclude(flags.Local.CommonFlags)
flags.Local.CFlags = removeInclude(flags.Local.CFlags)
- flags = addStubLibraryCompilerFlags(flags)
+ flags = AddStubLibraryCompilerFlags(flags)
}
return flags
}
@@ -567,6 +579,8 @@
}
func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
+ sharedFlags := ctx.getSharedFlags()
+
if ctx.IsLlndk() {
// Get the matching SDK version for the vendor API level.
version, err := android.GetSdkVersionForVendorApiLevel(ctx.Config().VendorApiLevel())
@@ -575,27 +589,27 @@
}
// This is the vendor variant of an LLNDK library, build the LLNDK stubs.
- nativeAbiResult := parseNativeAbiDefinition(ctx,
+ nativeAbiResult := ParseNativeAbiDefinition(ctx,
String(library.Properties.Llndk.Symbol_file),
nativeClampedApiLevel(ctx, version), "--llndk")
- objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
+ objs := CompileStubLibrary(ctx, flags, nativeAbiResult.StubSrc, sharedFlags)
if !Bool(library.Properties.Llndk.Unversioned) {
library.versionScriptPath = android.OptionalPathForPath(
- nativeAbiResult.versionScript)
+ nativeAbiResult.VersionScript)
}
return objs
}
if ctx.IsVendorPublicLibrary() {
- nativeAbiResult := parseNativeAbiDefinition(ctx,
+ nativeAbiResult := ParseNativeAbiDefinition(ctx,
String(library.Properties.Vendor_public_library.Symbol_file),
android.FutureApiLevel, "")
- objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
+ objs := CompileStubLibrary(ctx, flags, nativeAbiResult.StubSrc, sharedFlags)
if !Bool(library.Properties.Vendor_public_library.Unversioned) {
- library.versionScriptPath = android.OptionalPathForPath(nativeAbiResult.versionScript)
+ library.versionScriptPath = android.OptionalPathForPath(nativeAbiResult.VersionScript)
}
return objs
}
- if library.buildStubs() {
+ if library.BuildStubs() {
return library.compileModuleLibApiStubs(ctx, flags, deps)
}
@@ -616,10 +630,17 @@
}
if library.sabi.shouldCreateSourceAbiDump() {
dirs := library.exportedIncludeDirsForAbiCheck(ctx)
- flags.SAbiFlags = make([]string, 0, len(dirs))
+ flags.SAbiFlags = make([]string, 0, len(dirs)+1)
for _, dir := range dirs {
flags.SAbiFlags = append(flags.SAbiFlags, "-I"+dir)
}
+ // If this library does not export any include directory, do not append the flags
+ // so that the ABI tool dumps everything without filtering by the include directories.
+ // requiresGlobalIncludes returns whether this library can include CommonGlobalIncludes.
+ // If the library cannot include them, it cannot export them.
+ if len(dirs) > 0 && requiresGlobalIncludes(ctx) {
+ flags.SAbiFlags = append(flags.SAbiFlags, "${config.CommonGlobalIncludes}")
+ }
totalLength := len(srcs) + len(deps.GeneratedSources) +
len(sharedSrcs) + len(staticSrcs)
if totalLength > 0 {
@@ -635,18 +656,65 @@
objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceStaticLibrary, srcs,
android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Tidy_disabled_srcs),
android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Tidy_timeout_srcs),
- library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps))
+ library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps, sharedFlags))
} else if library.shared() {
srcs := android.PathsForModuleSrc(ctx, sharedSrcs)
objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceSharedLibrary, srcs,
android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Tidy_disabled_srcs),
android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Tidy_timeout_srcs),
- library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps))
+ library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps, sharedFlags))
}
return objs
}
+type ApiStubsParams struct {
+ NotInPlatform bool
+ IsNdk bool
+ BaseModuleName string
+ ModuleName string
+}
+
+// GetApiStubsFlags calculates the genstubFlags string to pass to ParseNativeAbiDefinition
+func GetApiStubsFlags(api ApiStubsParams) string {
+ var flag string
+
+ // b/239274367 --apex and --systemapi filters symbols tagged with # apex and #
+ // systemapi, respectively. The former is for symbols defined in platform libraries
+ // and the latter is for symbols defined in APEXes.
+ // A single library can contain either # apex or # systemapi, but not both.
+ // The stub generator (ndkstubgen) is additive, so passing _both_ of these to it should be a no-op.
+ // However, having this distinction helps guard accidental
+ // promotion or demotion of API and also helps the API review process b/191371676
+ if api.NotInPlatform {
+ flag = "--apex"
+ } else {
+ flag = "--systemapi"
+ }
+
+ // b/184712170, unless the lib is an NDK library, exclude all public symbols from
+ // the stub so that it is mandated that all symbols are explicitly marked with
+ // either apex or systemapi.
+ if !api.IsNdk &&
+ // the symbol files of libclang libs are autogenerated and do not contain systemapi tags
+ // TODO (spandandas): Update mapfile.py to include #systemapi tag on all symbols
+ !strings.Contains(api.ModuleName, "libclang_rt") {
+ flag = flag + " --no-ndk"
+ }
+
+ // TODO(b/361303067): Remove this special case if bionic/ projects are added to ART development branches.
+ if isBionic(api.BaseModuleName) {
+ // set the flags explicitly for bionic libs.
+ // this is necessary for development in minimal branches which does not contain bionic/*.
+ // In such minimal branches, e.g. on the prebuilt libc stubs
+ // 1. IsNdk will return false (since the ndk_library definition for libc does not exist)
+ // 2. NotInPlatform will return true (since the source com.android.runtime does not exist)
+ flag = "--apex"
+ }
+
+ return flag
+}
+
// Compile stubs for the API surface between platform and apex
// This method will be used by source and prebuilt cc module types.
func (library *libraryDecorator) compileModuleLibApiStubs(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
@@ -654,56 +722,34 @@
if library.Properties.Stubs.Symbol_file == nil {
return Objects{}
}
+
symbolFile := String(library.Properties.Stubs.Symbol_file)
library.stubsSymbolFilePath = android.PathForModuleSrc(ctx, symbolFile)
- // b/239274367 --apex and --systemapi filters symbols tagged with # apex and #
- // systemapi, respectively. The former is for symbols defined in platform libraries
- // and the latter is for symbols defined in APEXes.
- // A single library can contain either # apex or # systemapi, but not both.
- // The stub generator (ndkstubgen) is additive, so passing _both_ of these to it should be a no-op.
- // However, having this distinction helps guard accidental
- // promotion or demotion of API and also helps the API review process b/191371676
- var flag string
- if ctx.notInPlatform() {
- flag = "--apex"
- } else {
- flag = "--systemapi"
+
+ apiParams := ApiStubsParams{
+ NotInPlatform: ctx.notInPlatform(),
+ IsNdk: ctx.Module().(*Module).IsNdk(ctx.Config()),
+ BaseModuleName: ctx.baseModuleName(),
+ ModuleName: ctx.ModuleName(),
}
- // b/184712170, unless the lib is an NDK library, exclude all public symbols from
- // the stub so that it is mandated that all symbols are explicitly marked with
- // either apex or systemapi.
- if !ctx.Module().(*Module).IsNdk(ctx.Config()) &&
- // the symbol files of libclang libs are autogenerated and do not contain systemapi tags
- // TODO (spandandas): Update mapfile.py to include #systemapi tag on all symbols
- !strings.Contains(ctx.ModuleName(), "libclang_rt") {
- flag = flag + " --no-ndk"
- }
- // TODO(b/361303067): Remove this special case if bionic/ projects are added to ART development branches.
- if isBionic(ctx.baseModuleName()) {
- // set the flags explicitly for bionic libs.
- // this is necessary for development in minimal branches which does not contain bionic/*.
- // In such minimal branches, e.g. on the prebuilt libc stubs
- // 1. IsNdk will return false (since the ndk_library definition for libc does not exist)
- // 2. NotInPlatform will return true (since the source com.android.runtime does not exist)
- flag = "--apex"
- }
- nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile,
+ flag := GetApiStubsFlags(apiParams)
+
+ nativeAbiResult := ParseNativeAbiDefinition(ctx, symbolFile,
android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), flag)
- objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
+ objs := CompileStubLibrary(ctx, flags, nativeAbiResult.StubSrc, ctx.getSharedFlags())
library.versionScriptPath = android.OptionalPathForPath(
- nativeAbiResult.versionScript)
-
+ nativeAbiResult.VersionScript)
// Parse symbol file to get API list for coverage
- if library.stubsVersion() == "current" && ctx.PrimaryArch() && !ctx.inRecovery() && !ctx.inProduct() && !ctx.inVendor() {
- library.apiListCoverageXmlPath = parseSymbolFileForAPICoverage(ctx, symbolFile)
+ if library.StubsVersion() == "current" && ctx.PrimaryArch() && !ctx.inRecovery() && !ctx.inProduct() && !ctx.inVendor() {
+ library.apiListCoverageXmlPath = ParseSymbolFileForAPICoverage(ctx, symbolFile)
}
return objs
}
type libraryInterface interface {
- versionedInterface
+ VersionedInterface
static() bool
shared() bool
@@ -727,32 +773,49 @@
apexAvailable() []string
- getAPIListCoverageXMLPath() android.ModuleOutPath
+ setAPIListCoverageXMLPath(out android.ModuleOutPath)
+ symbolsFile() *string
+ setSymbolFilePath(path android.Path)
+ setVersionScriptPath(path android.OptionalPath)
installable() *bool
}
-type versionedInterface interface {
- buildStubs() bool
- setBuildStubs(isLatest bool)
- hasStubsVariants() bool
- isStubsImplementationRequired() bool
- setStubsVersion(string)
- stubsVersion() string
+func (library *libraryDecorator) symbolsFile() *string {
+ return library.Properties.Stubs.Symbol_file
+}
- stubsVersions(ctx android.BaseModuleContext) []string
- setAllStubsVersions([]string)
- allStubsVersions() []string
+func (library *libraryDecorator) setSymbolFilePath(path android.Path) {
+ library.stubsSymbolFilePath = path
+}
- implementationModuleName(name string) string
- hasLLNDKStubs() bool
- hasLLNDKHeaders() bool
- hasVendorPublicLibrary() bool
- isLLNDKMovedToApex() bool
+func (library *libraryDecorator) setVersionScriptPath(path android.OptionalPath) {
+ library.versionScriptPath = path
+}
+
+type VersionedInterface interface {
+ BuildStubs() bool
+ SetBuildStubs(isLatest bool)
+ HasStubsVariants() bool
+ IsStubsImplementationRequired() bool
+ SetStubsVersion(string)
+ StubsVersion() string
+
+ StubsVersions(ctx android.BaseModuleContext) []string
+ SetAllStubsVersions([]string)
+ AllStubsVersions() []string
+
+ ImplementationModuleName(name string) string
+ HasLLNDKStubs() bool
+ HasLLNDKHeaders() bool
+ HasVendorPublicLibrary() bool
+ IsLLNDKMovedToApex() bool
+
+ GetAPIListCoverageXMLPath() android.ModuleOutPath
}
var _ libraryInterface = (*libraryDecorator)(nil)
-var _ versionedInterface = (*libraryDecorator)(nil)
+var _ VersionedInterface = (*libraryDecorator)(nil)
func (library *libraryDecorator) getLibNameHelper(baseModuleName string, inVendor bool, inProduct bool) string {
name := library.libName
@@ -801,9 +864,9 @@
library.baseLinker.linkerInit(ctx)
// Let baseLinker know whether this variant is for stubs or not, so that
// it can omit things that are not required for linking stubs.
- library.baseLinker.dynamicProperties.BuildStubs = library.buildStubs()
+ library.baseLinker.dynamicProperties.BuildStubs = library.BuildStubs()
- if library.buildStubs() {
+ if library.BuildStubs() {
macroNames := versioningMacroNamesList(ctx.Config())
myName := versioningMacroName(ctx.ModuleName())
versioningMacroNamesListMutex.Lock()
@@ -962,8 +1025,8 @@
moduleInfoJSON.Uninstallable = true
}
- if library.buildStubs() && library.stubsVersion() != "" {
- moduleInfoJSON.SubName += "." + library.stubsVersion()
+ if library.BuildStubs() && library.StubsVersion() != "" {
+ moduleInfoJSON.SubName += "." + library.StubsVersion()
}
// If a library providing a stub is included in an APEX, the private APIs of the library
@@ -974,10 +1037,10 @@
// very early stage in the boot process).
if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.notInPlatform() &&
!ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() && !ctx.useVndk() && !ctx.static() {
- if library.buildStubs() && library.isLatestStubVersion() {
+ if library.BuildStubs() && library.isLatestStubVersion() {
moduleInfoJSON.SubName = ""
}
- if !library.buildStubs() {
+ if !library.BuildStubs() {
moduleInfoJSON.SubName = ".bootstrap"
}
}
@@ -1120,7 +1183,7 @@
stripFlags := flagsToStripFlags(flags)
needsStrip := library.stripper.NeedsStrip(ctx)
- if library.buildStubs() {
+ if library.BuildStubs() {
// No need to strip stubs libraries
needsStrip = false
}
@@ -1174,7 +1237,7 @@
linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
- if generatedLib := generateRustStaticlib(ctx, deps.RustRlibDeps); generatedLib != nil && !library.buildStubs() {
+ if generatedLib := GenerateRustStaticlib(ctx, deps.RustRlibDeps); generatedLib != nil && !library.BuildStubs() {
if ctx.Module().(*Module).WholeRustStaticlib {
deps.WholeStaticLibs = append(deps.WholeStaticLibs, generatedLib)
} else {
@@ -1205,18 +1268,18 @@
SharedLibrary: unstrippedOutputFile,
TransitiveStaticLibrariesForOrdering: transitiveStaticLibrariesForOrdering,
Target: ctx.Target(),
- IsStubs: library.buildStubs(),
+ IsStubs: library.BuildStubs(),
})
- addStubDependencyProviders(ctx)
+ AddStubDependencyProviders(ctx)
return unstrippedOutputFile
}
// Visits the stub variants of the library and returns a struct containing the stub .so paths
-func addStubDependencyProviders(ctx ModuleContext) []SharedStubLibrary {
+func AddStubDependencyProviders(ctx android.BaseModuleContext) []SharedStubLibrary {
stubsInfo := []SharedStubLibrary{}
- stubs := ctx.GetDirectDepsProxyWithTag(stubImplDepTag)
+ stubs := ctx.GetDirectDepsProxyWithTag(StubImplDepTag)
if len(stubs) > 0 {
for _, stub := range stubs {
stubInfo, ok := android.OtherModuleProvider(ctx, stub, SharedLibraryInfoProvider)
@@ -1237,10 +1300,11 @@
if len(stubsInfo) > 0 {
android.SetProvider(ctx, SharedLibraryStubsProvider, SharedLibraryStubsInfo{
SharedStubLibraries: stubsInfo,
- IsLLNDK: ctx.IsLlndk(),
+ IsLLNDK: ctx.Module().(LinkableInterface).IsLlndk(),
})
}
}
+
return stubsInfo
}
@@ -1257,7 +1321,7 @@
}
func (library *libraryDecorator) nativeCoverage() bool {
- if library.header() || library.buildStubs() {
+ if library.header() || library.BuildStubs() {
return false
}
return true
@@ -1305,13 +1369,15 @@
deps PathDeps, sAbiDumpFiles android.Paths, soFile android.Path, libFileName string,
excludeSymbolVersions, excludeSymbolTags []string,
sdkVersionForVendorApiLevel string) android.Path {
+ // Though LLNDK is implemented in system, the callers in vendor cannot include CommonGlobalIncludes,
+ // so commonGlobalIncludes is false.
return transformDumpToLinkedDump(ctx,
sAbiDumpFiles, soFile, libFileName+".llndk",
library.llndkIncludeDirsForAbiCheck(ctx, deps),
android.OptionalPathForModuleSrc(ctx, library.Properties.Llndk.Symbol_file),
append([]string{"*_PLATFORM", "*_PRIVATE"}, excludeSymbolVersions...),
append([]string{"platform-only"}, excludeSymbolTags...),
- []string{"llndk"}, sdkVersionForVendorApiLevel)
+ []string{"llndk"}, sdkVersionForVendorApiLevel, false /* commonGlobalIncludes */)
}
func (library *libraryDecorator) linkApexSAbiDumpFiles(ctx ModuleContext,
@@ -1324,7 +1390,7 @@
android.OptionalPathForModuleSrc(ctx, library.Properties.Stubs.Symbol_file),
append([]string{"*_PLATFORM", "*_PRIVATE"}, excludeSymbolVersions...),
append([]string{"platform-only"}, excludeSymbolTags...),
- []string{"apex", "systemapi"}, sdkVersion)
+ []string{"apex", "systemapi"}, sdkVersion, requiresGlobalIncludes(ctx))
}
func getRefAbiDumpFile(ctx android.ModuleInstallPathContext,
@@ -1467,7 +1533,7 @@
android.OptionalPathForModuleSrc(ctx, library.symbolFileForAbiCheck(ctx)),
headerAbiChecker.Exclude_symbol_versions,
headerAbiChecker.Exclude_symbol_tags,
- []string{} /* includeSymbolTags */, currSdkVersion)
+ []string{} /* includeSymbolTags */, currSdkVersion, requiresGlobalIncludes(ctx))
var llndkDump, apexVariantDump android.Path
tags := classifySourceAbiDump(ctx.Module().(*Module))
@@ -1726,9 +1792,9 @@
}
func (library *libraryDecorator) exportVersioningMacroIfNeeded(ctx android.BaseModuleContext) {
- if library.buildStubs() && library.stubsVersion() != "" && !library.skipAPIDefine {
+ if library.BuildStubs() && library.StubsVersion() != "" && !library.skipAPIDefine {
name := versioningMacroName(ctx.Module().(*Module).ImplementationModuleName(ctx))
- apiLevel, err := android.ApiLevelFromUser(ctx, library.stubsVersion())
+ apiLevel, err := android.ApiLevelFromUser(ctx, library.StubsVersion())
if err != nil {
ctx.ModuleErrorf("Can't export version macro: %s", err.Error())
}
@@ -1780,8 +1846,8 @@
func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) {
if library.shared() {
translatedArch := ctx.Target().NativeBridge == android.NativeBridgeEnabled
- if library.hasStubsVariants() && !ctx.Host() && !ctx.isSdkVariant() &&
- InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !library.buildStubs() &&
+ if library.HasStubsVariants() && !ctx.Host() && !ctx.isSdkVariant() &&
+ InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !library.BuildStubs() &&
!translatedArch && !ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() {
// Bionic libraries (e.g. libc.so) is installed to the bootstrap subdirectory.
// The original path becomes a symlink to the corresponding file in the
@@ -1798,7 +1864,7 @@
if Bool(library.Properties.Static_ndk_lib) && library.static() &&
!ctx.InVendorOrProduct() && !ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() && ctx.Device() &&
library.baseLinker.sanitize.isUnsanitizedVariant() &&
- ctx.isForPlatform() && !ctx.isPreventInstall() {
+ CtxIsForPlatform(ctx) && !ctx.isPreventInstall() {
installPath := getUnversionedLibraryInstallPath(ctx).Join(ctx, file.Base())
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
@@ -1868,32 +1934,32 @@
library.MutatedProperties.BuildStatic = false
}
-// hasLLNDKStubs returns true if this cc_library module has a variant that will build LLNDK stubs.
-func (library *libraryDecorator) hasLLNDKStubs() bool {
+// HasLLNDKStubs returns true if this cc_library module has a variant that will build LLNDK stubs.
+func (library *libraryDecorator) HasLLNDKStubs() bool {
return String(library.Properties.Llndk.Symbol_file) != ""
}
// hasLLNDKStubs returns true if this cc_library module has a variant that will build LLNDK stubs.
-func (library *libraryDecorator) hasLLNDKHeaders() bool {
+func (library *libraryDecorator) HasLLNDKHeaders() bool {
return Bool(library.Properties.Llndk.Llndk_headers)
}
-// isLLNDKMovedToApex returns true if this cc_library module sets the llndk.moved_to_apex property.
-func (library *libraryDecorator) isLLNDKMovedToApex() bool {
+// IsLLNDKMovedToApex returns true if this cc_library module sets the llndk.moved_to_apex property.
+func (library *libraryDecorator) IsLLNDKMovedToApex() bool {
return Bool(library.Properties.Llndk.Moved_to_apex)
}
-// hasVendorPublicLibrary returns true if this cc_library module has a variant that will build
+// HasVendorPublicLibrary returns true if this cc_library module has a variant that will build
// vendor public library stubs.
-func (library *libraryDecorator) hasVendorPublicLibrary() bool {
+func (library *libraryDecorator) HasVendorPublicLibrary() bool {
return String(library.Properties.Vendor_public_library.Symbol_file) != ""
}
-func (library *libraryDecorator) implementationModuleName(name string) string {
+func (library *libraryDecorator) ImplementationModuleName(name string) string {
return name
}
-func (library *libraryDecorator) buildStubs() bool {
+func (library *libraryDecorator) BuildStubs() bool {
return library.MutatedProperties.BuildStubs
}
@@ -1901,7 +1967,7 @@
if props := library.getHeaderAbiCheckerProperties(ctx.Module().(*Module)); props.Symbol_file != nil {
return props.Symbol_file
}
- if library.hasStubsVariants() && library.Properties.Stubs.Symbol_file != nil {
+ if library.HasStubsVariants() && library.Properties.Stubs.Symbol_file != nil {
return library.Properties.Stubs.Symbol_file
}
// TODO(b/309880485): Distinguish platform, NDK, LLNDK, and APEX version scripts.
@@ -1911,35 +1977,35 @@
return nil
}
-func (library *libraryDecorator) hasStubsVariants() bool {
+func (library *libraryDecorator) HasStubsVariants() bool {
// Just having stubs.symbol_file is enough to create a stub variant. In that case
// the stub for the future API level is created.
return library.Properties.Stubs.Symbol_file != nil ||
len(library.Properties.Stubs.Versions) > 0
}
-func (library *libraryDecorator) isStubsImplementationRequired() bool {
+func (library *libraryDecorator) IsStubsImplementationRequired() bool {
return BoolDefault(library.Properties.Stubs.Implementation_installable, true)
}
-func (library *libraryDecorator) stubsVersions(ctx android.BaseModuleContext) []string {
- if !library.hasStubsVariants() {
+func (library *libraryDecorator) StubsVersions(ctx android.BaseModuleContext) []string {
+ if !library.HasStubsVariants() {
return nil
}
- if library.hasLLNDKStubs() && ctx.Module().(*Module).InVendorOrProduct() {
+ if library.HasLLNDKStubs() && ctx.Module().(*Module).InVendorOrProduct() {
// LLNDK libraries only need a single stubs variant (""), which is
// added automatically in createVersionVariations().
return nil
}
// Future API level is implicitly added if there isn't
- versions := addCurrentVersionIfNotPresent(library.Properties.Stubs.Versions)
- normalizeVersions(ctx, versions)
+ versions := AddCurrentVersionIfNotPresent(library.Properties.Stubs.Versions)
+ NormalizeVersions(ctx, versions)
return versions
}
-func addCurrentVersionIfNotPresent(vers []string) []string {
+func AddCurrentVersionIfNotPresent(vers []string) []string {
if inList(android.FutureApiLevel.String(), vers) {
return vers
}
@@ -1952,24 +2018,24 @@
return append(vers, android.FutureApiLevel.String())
}
-func (library *libraryDecorator) setStubsVersion(version string) {
+func (library *libraryDecorator) SetStubsVersion(version string) {
library.MutatedProperties.StubsVersion = version
}
-func (library *libraryDecorator) stubsVersion() string {
+func (library *libraryDecorator) StubsVersion() string {
return library.MutatedProperties.StubsVersion
}
-func (library *libraryDecorator) setBuildStubs(isLatest bool) {
+func (library *libraryDecorator) SetBuildStubs(isLatest bool) {
library.MutatedProperties.BuildStubs = true
library.MutatedProperties.IsLatestVersion = isLatest
}
-func (library *libraryDecorator) setAllStubsVersions(versions []string) {
+func (library *libraryDecorator) SetAllStubsVersions(versions []string) {
library.MutatedProperties.AllStubsVersions = versions
}
-func (library *libraryDecorator) allStubsVersions() []string {
+func (library *libraryDecorator) AllStubsVersions() []string {
return library.MutatedProperties.AllStubsVersions
}
@@ -1998,7 +2064,7 @@
}
func (library *libraryDecorator) makeUninstallable(mod *Module) {
- if library.static() && library.buildStatic() && !library.buildStubs() {
+ if library.static() && library.buildStatic() && !library.BuildStubs() {
// If we're asked to make a static library uninstallable we don't do
// anything since AndroidMkEntries always sets LOCAL_UNINSTALLABLE_MODULE
// for these entries. This is done to still get the make targets for NOTICE
@@ -2012,10 +2078,14 @@
return library.path.Partition()
}
-func (library *libraryDecorator) getAPIListCoverageXMLPath() android.ModuleOutPath {
+func (library *libraryDecorator) GetAPIListCoverageXMLPath() android.ModuleOutPath {
return library.apiListCoverageXmlPath
}
+func (library *libraryDecorator) setAPIListCoverageXMLPath(xml android.ModuleOutPath) {
+ library.apiListCoverageXmlPath = xml
+}
+
func (library *libraryDecorator) overriddenModules() []string {
return library.Properties.Overrides
}
@@ -2159,6 +2229,9 @@
}
func (linkageTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
+ if ctx.DepTag() == android.PrebuiltDepTag {
+ return sourceVariation
+ }
return ""
}
@@ -2215,11 +2288,13 @@
library.setStatic()
if !library.buildStatic() {
library.disablePrebuilt()
+ ctx.Module().(*Module).Prebuilt().SetUsePrebuilt(false)
}
} else if variation == "shared" {
library.setShared()
if !library.buildShared() {
library.disablePrebuilt()
+ ctx.Module().(*Module).Prebuilt().SetUsePrebuilt(false)
}
}
} else if library, ok := ctx.Module().(LinkableInterface); ok && library.CcLibraryInterface() {
@@ -2242,10 +2317,10 @@
}
}
-// normalizeVersions modifies `versions` in place, so that each raw version
+// NormalizeVersions modifies `versions` in place, so that each raw version
// string becomes its normalized canonical form.
// Validates that the versions in `versions` are specified in least to greatest order.
-func normalizeVersions(ctx android.BaseModuleContext, versions []string) {
+func NormalizeVersions(ctx android.BaseModuleContext, versions []string) {
var previous android.ApiLevel
for i, v := range versions {
ver, err := android.ApiLevelFromUser(ctx, v)
@@ -2262,7 +2337,7 @@
}
func perApiVersionVariations(mctx android.BaseModuleContext, minSdkVersion string) []string {
- from, err := nativeApiLevelFromUser(mctx, minSdkVersion)
+ from, err := NativeApiLevelFromUser(mctx, minSdkVersion)
if err != nil {
mctx.PropertyErrorf("min_sdk_version", err.Error())
return []string{""}
@@ -2290,25 +2365,25 @@
module.CcLibraryInterface() && module.Shared()
}
-func moduleLibraryInterface(module blueprint.Module) libraryInterface {
- if m, ok := module.(*Module); ok {
- return m.library
+func moduleVersionedInterface(module blueprint.Module) VersionedInterface {
+ if m, ok := module.(VersionedLinkableInterface); ok {
+ return m.VersionedInterface()
}
return nil
}
// setStubsVersions normalizes the versions in the Stubs.Versions property into MutatedProperties.AllStubsVersions.
-func setStubsVersions(mctx android.BaseModuleContext, library libraryInterface, module *Module) {
- if !library.buildShared() || !canBeVersionVariant(module) {
+func setStubsVersions(mctx android.BaseModuleContext, module VersionedLinkableInterface) {
+ if !module.BuildSharedVariant() || !canBeVersionVariant(module) {
return
}
- versions := library.stubsVersions(mctx)
+ versions := module.VersionedInterface().StubsVersions(mctx)
if mctx.Failed() {
return
}
// Set the versions on the pre-mutated module so they can be read by any llndk modules that
// depend on the implementation library and haven't been mutated yet.
- library.setAllStubsVersions(versions)
+ module.VersionedInterface().SetAllStubsVersions(versions)
}
// versionTransitionMutator splits a module into the mandatory non-stubs variant
@@ -2319,20 +2394,22 @@
if ctx.Os() != android.Android {
return []string{""}
}
-
- m, ok := ctx.Module().(*Module)
- if library := moduleLibraryInterface(ctx.Module()); library != nil && canBeVersionVariant(m) {
- setStubsVersions(ctx, library, m)
-
- return append(slices.Clone(library.allStubsVersions()), "")
- } else if ok && m.SplitPerApiLevel() && m.IsSdkVariant() {
- return perApiVersionVariations(ctx, m.MinSdkVersion())
+ if m, ok := ctx.Module().(VersionedLinkableInterface); ok {
+ if m.CcLibraryInterface() && canBeVersionVariant(m) {
+ setStubsVersions(ctx, m)
+ return append(slices.Clone(m.VersionedInterface().AllStubsVersions()), "")
+ } else if m.SplitPerApiLevel() && m.IsSdkVariant() {
+ return perApiVersionVariations(ctx, m.MinSdkVersion())
+ }
}
return []string{""}
}
func (versionTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
+ if ctx.DepTag() == android.PrebuiltDepTag {
+ return sourceVariation
+ }
return ""
}
@@ -2340,11 +2417,11 @@
if ctx.Os() != android.Android {
return ""
}
- m, ok := ctx.Module().(*Module)
- if library := moduleLibraryInterface(ctx.Module()); library != nil && canBeVersionVariant(m) {
+ m, ok := ctx.Module().(VersionedLinkableInterface)
+ if library := moduleVersionedInterface(ctx.Module()); library != nil && canBeVersionVariant(m) {
if incomingVariation == "latest" {
latestVersion := ""
- versions := library.allStubsVersions()
+ versions := library.AllStubsVersions()
if len(versions) > 0 {
latestVersion = versions[len(versions)-1]
}
@@ -2369,39 +2446,39 @@
return
}
- m, ok := ctx.Module().(*Module)
- if library := moduleLibraryInterface(ctx.Module()); library != nil && canBeVersionVariant(m) {
+ m, ok := ctx.Module().(VersionedLinkableInterface)
+ if library := moduleVersionedInterface(ctx.Module()); library != nil && canBeVersionVariant(m) {
isLLNDK := m.IsLlndk()
isVendorPublicLibrary := m.IsVendorPublicLibrary()
if variation != "" || isLLNDK || isVendorPublicLibrary {
// A stubs or LLNDK stubs variant.
- if m.sanitize != nil {
- m.sanitize.Properties.ForceDisable = true
+ if sm, ok := ctx.Module().(PlatformSanitizeable); ok && sm.SanitizePropDefined() {
+ sm.ForceDisableSanitizers()
}
- if m.stl != nil {
- m.stl.Properties.Stl = StringPtr("none")
- }
- m.Properties.PreventInstall = true
- lib := moduleLibraryInterface(m)
- allStubsVersions := library.allStubsVersions()
+ m.SetStl("none")
+ m.SetPreventInstall()
+ allStubsVersions := m.VersionedInterface().AllStubsVersions()
isLatest := len(allStubsVersions) > 0 && variation == allStubsVersions[len(allStubsVersions)-1]
- lib.setBuildStubs(isLatest)
+ m.VersionedInterface().SetBuildStubs(isLatest)
}
if variation != "" {
// A non-LLNDK stubs module is hidden from make
- library.setStubsVersion(variation)
- m.Properties.HideFromMake = true
+ m.VersionedInterface().SetStubsVersion(variation)
+ m.SetHideFromMake()
} else {
// A non-LLNDK implementation module has a dependency to all stubs versions
- for _, version := range library.allStubsVersions() {
- ctx.AddVariationDependencies([]blueprint.Variation{{"version", version}},
- stubImplDepTag, ctx.ModuleName())
+ for _, version := range m.VersionedInterface().AllStubsVersions() {
+ ctx.AddVariationDependencies(
+ []blueprint.Variation{
+ {Mutator: "version", Variation: version},
+ {Mutator: "link", Variation: "shared"}},
+ StubImplDepTag, ctx.ModuleName())
}
}
} else if ok && m.SplitPerApiLevel() && m.IsSdkVariant() {
- m.Properties.Sdk_version = StringPtr(variation)
- m.Properties.Min_sdk_version = StringPtr(variation)
+ m.SetSdkVersion(variation)
+ m.SetMinSdkVersion(variation)
}
}
@@ -2415,7 +2492,8 @@
injectBoringSSLHash := Bool(inject)
ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
if tag, ok := ctx.OtherModuleDependencyTag(dep).(libraryDependencyTag); ok && tag.static() {
- if ccInfo, ok := android.OtherModuleProvider(ctx, dep, CcInfoProvider); ok && ccInfo.LinkerInfo.LibraryDecoratorInfo != nil {
+ if ccInfo, ok := android.OtherModuleProvider(ctx, dep, CcInfoProvider); ok &&
+ ccInfo.LinkerInfo != nil && ccInfo.LinkerInfo.LibraryDecoratorInfo != nil {
if ccInfo.LinkerInfo.LibraryDecoratorInfo.InjectBsslHash {
injectBoringSSLHash = true
}
diff --git a/cc/library_headers_test.go b/cc/library_headers_test.go
index 5a45767..88ccd43 100644
--- a/cc/library_headers_test.go
+++ b/cc/library_headers_test.go
@@ -41,11 +41,11 @@
ctx := testCc(t, fmt.Sprintf(bp, headerModule))
// test if header search paths are correctly added
- cc := ctx.ModuleForTests("lib", "android_arm64_armv8-a_static").Rule("cc")
+ cc := ctx.ModuleForTests(t, "lib", "android_arm64_armv8-a_static").Rule("cc")
android.AssertStringDoesContain(t, "cFlags for lib module", cc.Args["cFlags"], " -Imy_include ")
// Test that there's a valid AndroidMk entry.
- headers := ctx.ModuleForTests("headers", "android_arm64_armv8-a").Module()
+ headers := ctx.ModuleForTests(t, "headers", "android_arm64_armv8-a").Module()
e := android.AndroidMkInfoForTest(t, ctx, headers).PrimaryInfo
// This duplicates the tests done in AndroidMkEntries.write. It would be
@@ -80,9 +80,9 @@
for _, prebuiltPreferred := range []bool{false, true} {
t.Run(fmt.Sprintf("prebuilt prefer %t", prebuiltPreferred), func(t *testing.T) {
ctx := testCc(t, fmt.Sprintf(bp, prebuiltPreferred))
- lib := ctx.ModuleForTests("lib", "android_arm64_armv8-a_static")
- sourceDep := ctx.ModuleForTests("headers", "android_arm64_armv8-a")
- prebuiltDep := ctx.ModuleForTests("prebuilt_headers", "android_arm64_armv8-a")
+ lib := ctx.ModuleForTests(t, "lib", "android_arm64_armv8-a_static")
+ sourceDep := ctx.ModuleForTests(t, "headers", "android_arm64_armv8-a")
+ prebuiltDep := ctx.ModuleForTests(t, "prebuilt_headers", "android_arm64_armv8-a")
hasSourceDep := false
hasPrebuiltDep := false
ctx.VisitDirectDeps(lib.Module(), func(dep blueprint.Module) {
diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go
index af3658d..d1440ea 100644
--- a/cc/library_sdk_member.go
+++ b/cc/library_sdk_member.go
@@ -546,7 +546,7 @@
specifiedDeps = ccModule.linker.linkerSpecifiedDeps(ctx.SdkModuleContext(), ccModule, specifiedDeps)
if lib := ccModule.library; lib != nil {
- if !lib.hasStubsVariants() {
+ if !lib.HasStubsVariants() {
// Propagate dynamic dependencies for implementation libs, but not stubs.
p.SharedLibs = specifiedDeps.sharedLibs
} else {
@@ -554,8 +554,8 @@
// ccModule.StubsVersion()) if the module is versioned. 2. Ensure that all
// the versioned stub libs are retained in the prebuilt tree; currently only
// the stub corresponding to ccModule.StubsVersion() is.
- p.StubsVersions = lib.allStubsVersions()
- if lib.buildStubs() && ccModule.stubsSymbolFilePath() == nil {
+ p.StubsVersions = lib.AllStubsVersions()
+ if lib.BuildStubs() && ccModule.stubsSymbolFilePath() == nil {
ctx.ModuleErrorf("Could not determine symbol_file")
} else {
p.StubsSymbolFilePath = ccModule.stubsSymbolFilePath()
diff --git a/cc/library_test.go b/cc/library_test.go
index 2ed2d76..8b7fed2 100644
--- a/cc/library_test.go
+++ b/cc/library_test.go
@@ -30,8 +30,8 @@
srcs: ["foo.c", "baz.o"],
}`)
- libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
- libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a")
+ libfooShared := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
+ libfooStatic := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a")
if len(libfooShared.Inputs) != 2 {
t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings())
@@ -59,8 +59,8 @@
},
}`)
- libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
- libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a")
+ libfooShared := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
+ libfooStatic := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a")
if len(libfooShared.Inputs) != 1 {
t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings())
@@ -85,8 +85,8 @@
},
}`)
- libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
- libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a")
+ libfooShared := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
+ libfooStatic := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a")
if len(libfooShared.Inputs) != 2 {
t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings())
@@ -111,8 +111,8 @@
},
}`)
- libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
- libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a")
+ libfooShared := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
+ libfooStatic := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a")
if len(libfooShared.Inputs) != 1 {
t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings())
@@ -137,8 +137,8 @@
},
}`)
- libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
- libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a")
+ libfooShared := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
+ libfooStatic := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a")
if len(libfooShared.Inputs) != 1 {
t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings())
@@ -168,8 +168,8 @@
},
}`)
- libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
- libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a")
+ libfooShared := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
+ libfooStatic := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a")
if len(libfooShared.Inputs) != 3 {
t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings())
@@ -183,7 +183,7 @@
t.Errorf("static objects not reused for shared library")
}
- libfoo := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Module().(*Module)
+ libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_shared").Module().(*Module)
if !inList("-DGOOGLE_PROTOBUF_NO_RTTI", libfoo.flags.Local.CFlags) {
t.Errorf("missing protobuf cflags")
}
@@ -254,7 +254,7 @@
version_script: "foo.map.txt",
}`)
- libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("ld")
+ libfoo := result.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Rule("ld")
android.AssertStringListContains(t, "missing dependency on version_script",
libfoo.Implicits.Strings(), "foo.map.txt")
@@ -272,7 +272,7 @@
dynamic_list: "foo.dynamic.txt",
}`)
- libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("ld")
+ libfoo := result.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Rule("ld")
android.AssertStringListContains(t, "missing dependency on dynamic_list",
libfoo.Implicits.Strings(), "foo.dynamic.txt")
@@ -312,14 +312,14 @@
}
`)
- libdirect := result.ModuleForTests("libdirect", "android_arm64_armv8-a_static").Rule("arWithLibs")
- libtransitive := result.ModuleForTests("libtransitive", "android_arm64_armv8-a_static").Rule("arWithLibs")
+ libdirect := result.ModuleForTests(t, "libdirect", "android_arm64_armv8-a_static").Rule("arWithLibs")
+ libtransitive := result.ModuleForTests(t, "libtransitive", "android_arm64_armv8-a_static").Rule("arWithLibs")
- libdirectWithSrcs := result.ModuleForTests("libdirect_with_srcs", "android_arm64_armv8-a_static").Rule("arWithLibs")
- libtransitiveWithSrcs := result.ModuleForTests("libtransitive_with_srcs", "android_arm64_armv8-a_static").Rule("arWithLibs")
+ libdirectWithSrcs := result.ModuleForTests(t, "libdirect_with_srcs", "android_arm64_armv8-a_static").Rule("arWithLibs")
+ libtransitiveWithSrcs := result.ModuleForTests(t, "libtransitive_with_srcs", "android_arm64_armv8-a_static").Rule("arWithLibs")
- barObj := result.ModuleForTests("libdirect_with_srcs", "android_arm64_armv8-a_static").Rule("cc")
- bazObj := result.ModuleForTests("libtransitive_with_srcs", "android_arm64_armv8-a_static").Rule("cc")
+ barObj := result.ModuleForTests(t, "libdirect_with_srcs", "android_arm64_armv8-a_static").Rule("cc")
+ bazObj := result.ModuleForTests(t, "libtransitive_with_srcs", "android_arm64_armv8-a_static").Rule("cc")
android.AssertStringListContains(t, "missing dependency on foo.a",
libdirect.Inputs.Strings(), "foo.a")
diff --git a/cc/linkable.go b/cc/linkable.go
index 78ea71c..f3aff15 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -53,6 +53,9 @@
// SanitizableDepTagChecker returns a SantizableDependencyTagChecker function type.
SanitizableDepTagChecker() SantizableDependencyTagChecker
+
+ // ForceDisableSanitizers sets the ForceDisable sanitize property
+ ForceDisableSanitizers()
}
// SantizableDependencyTagChecker functions check whether or not a dependency
@@ -63,6 +66,30 @@
// implementation should handle tags from both.
type SantizableDependencyTagChecker func(tag blueprint.DependencyTag) bool
+type VersionedLinkableInterface interface {
+ LinkableInterface
+ android.ApexModule
+
+ // VersionedInterface returns the VersionedInterface for this module
+ // (e.g. c.library), or nil if this is module is not a VersionedInterface.
+ VersionedInterface() VersionedInterface
+
+ // HasStubsVariants true if this module is a stub or has a sibling variant
+ // that is a stub.
+ HasStubsVariants() bool
+
+ // SetStl sets the stl property for CC modules. Does not panic if for other module types.
+ SetStl(string)
+ SetSdkVersion(string)
+ SetMinSdkVersion(version string)
+ ApexSdkVersion() android.ApiLevel
+ ImplementationModuleNameForMake() string
+
+ // RustApexExclude returns ApexExclude() for Rust modules; always returns false for all non-Rust modules.
+ // TODO(b/362509506): remove this once all apex_exclude uses are switched to stubs.
+ RustApexExclude() bool
+}
+
// LinkableInterface is an interface for a type of module that is linkable in a C++ library.
type LinkableInterface interface {
android.Module
@@ -132,28 +159,18 @@
// IsNdk returns true if the library is in the configs known NDK list.
IsNdk(config android.Config) bool
- // HasStubsVariants true if this module is a stub or has a sibling variant
- // that is a stub.
- HasStubsVariants() bool
-
// IsStubs returns true if the this is a stubs library.
IsStubs() bool
// IsLlndk returns true for both LLNDK (public) and LLNDK-private libs.
IsLlndk() bool
- // HasLlndkStubs returns true if this library has a variant that will build LLNDK stubs.
- HasLlndkStubs() bool
-
// NeedsLlndkVariants returns true if this module has LLNDK stubs or provides LLNDK headers.
NeedsLlndkVariants() bool
// NeedsVendorPublicLibraryVariants returns true if this module has vendor public library stubs.
NeedsVendorPublicLibraryVariants() bool
- //StubsVersion returns the stubs version for this module.
- StubsVersion() string
-
// UseVndk returns true if the module is using VNDK libraries instead of the libraries in /system/lib or /system/lib64.
// "product" and "vendor" variant modules return true for this function.
// When BOARD_VNDK_VERSION is set, vendor variants of "vendor_available: true", "vendor: true",
@@ -182,6 +199,7 @@
MinSdkVersion() string
AlwaysSdk() bool
IsSdkVariant() bool
+ Multilib() string
SplitPerApiLevel() bool
@@ -250,6 +268,7 @@
// FuzzModule returns the fuzz.FuzzModule associated with the module.
FuzzModuleStruct() fuzz.FuzzModule
+ IsCrt() bool
}
var (
diff --git a/cc/linker.go b/cc/linker.go
index b96d139..f854937 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -457,7 +457,7 @@
if ctx.minSdkVersion() == "current" {
return true
}
- parsedSdkVersion, err := nativeApiLevelFromUser(ctx, ctx.minSdkVersion())
+ parsedSdkVersion, err := NativeApiLevelFromUser(ctx, ctx.minSdkVersion())
if err != nil {
ctx.PropertyErrorf("min_sdk_version",
"Invalid min_sdk_version value (must be int or current): %q",
@@ -471,16 +471,77 @@
// ModuleContext extends BaseModuleContext
// BaseModuleContext should know if LLD is used?
-func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
- toolchain := ctx.toolchain()
-
+func CommonLinkerFlags(ctx android.ModuleContext, flags Flags, useClangLld bool,
+ toolchain config.Toolchain, allow_undefined_symbols bool) Flags {
hod := "Host"
if ctx.Os().Class == android.Device {
hod = "Device"
}
- if linker.useClangLld(ctx) {
+ mod, ok := ctx.Module().(LinkableInterface)
+ if !ok {
+ ctx.ModuleErrorf("trying to add CommonLinkerFlags to non-LinkableInterface module.")
+ return flags
+ }
+ if useClangLld {
flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLldflags}", hod))
+ } else {
+ flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLdflags}", hod))
+ }
+
+ if allow_undefined_symbols {
+ if ctx.Darwin() {
+ // darwin defaults to treating undefined symbols as errors
+ flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,-undefined,dynamic_lookup")
+ }
+ } else if !ctx.Darwin() && !ctx.Windows() {
+ flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--no-undefined")
+ }
+
+ if useClangLld {
+ flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.Lldflags())
+ } else {
+ flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.Ldflags())
+ }
+
+ if !toolchain.Bionic() && ctx.Os() != android.LinuxMusl {
+ if !ctx.Windows() {
+ // Add -ldl, -lpthread, -lm and -lrt to host builds to match the default behavior of device
+ // builds
+ flags.Global.LdFlags = append(flags.Global.LdFlags,
+ "-ldl",
+ "-lpthread",
+ "-lm",
+ )
+ if !ctx.Darwin() {
+ flags.Global.LdFlags = append(flags.Global.LdFlags, "-lrt")
+ }
+ }
+ }
+ staticLib := mod.CcLibraryInterface() && mod.Static()
+ if ctx.Host() && !ctx.Windows() && !staticLib {
+ flags.Global.LdFlags = append(flags.Global.LdFlags, RpathFlags(ctx)...)
+ }
+
+ flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ToolchainLdflags())
+ return flags
+}
+
+func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
+ toolchain := ctx.toolchain()
+ allow_undefined_symbols := Bool(linker.Properties.Allow_undefined_symbols)
+
+ flags = CommonLinkerFlags(ctx, flags, linker.useClangLld(ctx), toolchain,
+ allow_undefined_symbols)
+
+ if !toolchain.Bionic() && ctx.Os() != android.LinuxMusl {
+ CheckBadHostLdlibs(ctx, "host_ldlibs", linker.Properties.Host_ldlibs)
+ flags.Local.LdFlags = append(flags.Local.LdFlags, linker.Properties.Host_ldlibs...)
+ }
+
+ CheckBadLinkerFlags(ctx, "ldflags", linker.Properties.Ldflags)
+
+ if linker.useClangLld(ctx) {
if !BoolDefault(linker.Properties.Pack_relocations, packRelocationsDefault) {
flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=none")
} else if ctx.Device() {
@@ -498,53 +559,10 @@
flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=android")
}
}
- } else {
- flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLdflags}", hod))
}
- if Bool(linker.Properties.Allow_undefined_symbols) {
- if ctx.Darwin() {
- // darwin defaults to treating undefined symbols as errors
- flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,-undefined,dynamic_lookup")
- }
- } else if !ctx.Darwin() && !ctx.Windows() {
- flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--no-undefined")
- }
-
- if linker.useClangLld(ctx) {
- flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.Lldflags())
- } else {
- flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.Ldflags())
- }
-
- if !ctx.toolchain().Bionic() && ctx.Os() != android.LinuxMusl {
- CheckBadHostLdlibs(ctx, "host_ldlibs", linker.Properties.Host_ldlibs)
-
- flags.Local.LdFlags = append(flags.Local.LdFlags, linker.Properties.Host_ldlibs...)
-
- if !ctx.Windows() {
- // Add -ldl, -lpthread, -lm and -lrt to host builds to match the default behavior of device
- // builds
- flags.Global.LdFlags = append(flags.Global.LdFlags,
- "-ldl",
- "-lpthread",
- "-lm",
- )
- if !ctx.Darwin() {
- flags.Global.LdFlags = append(flags.Global.LdFlags, "-lrt")
- }
- }
- }
-
- CheckBadLinkerFlags(ctx, "ldflags", linker.Properties.Ldflags)
flags.Local.LdFlags = append(flags.Local.LdFlags, proptools.NinjaAndShellEscapeList(linker.Properties.Ldflags)...)
- if ctx.Host() && !ctx.Windows() && !ctx.static() {
- flags.Global.LdFlags = append(flags.Global.LdFlags, RpathFlags(ctx)...)
- }
-
- flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ToolchainLdflags())
-
// Version_script is not needed when linking stubs lib where the version
// script is created from the symbol map file.
if !linker.dynamicProperties.BuildStubs {
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index 8cc3852..8ca3ca1 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -83,9 +83,9 @@
// Make uses LLNDK_MOVED_TO_APEX_LIBRARIES to generate the linker config.
movedToApexLlndkLibrariesMap := make(map[string]bool)
ctx.VisitAllModules(func(module android.Module) {
- if library := moduleLibraryInterface(module); library != nil && library.hasLLNDKStubs() {
- if library.isLLNDKMovedToApex() {
- name := library.implementationModuleName(module.(*Module).BaseModuleName())
+ if library := moduleVersionedInterface(module); library != nil && library.HasLLNDKStubs() {
+ if library.IsLLNDKMovedToApex() {
+ name := library.ImplementationModuleName(module.(*Module).BaseModuleName())
movedToApexLlndkLibrariesMap[name] = true
}
}
@@ -147,6 +147,8 @@
ctx.InstallFile(installPath, filename, txt.outputFile)
ctx.SetOutputFiles(android.Paths{txt.outputFile}, "")
+
+ etc.SetCommonPrebuiltEtcInfo(ctx, txt)
}
func getVndkFileName(m *Module) (string, error) {
@@ -223,10 +225,10 @@
lib, isLib := m.linker.(*libraryDecorator)
prebuiltLib, isPrebuiltLib := m.linker.(*prebuiltLibraryLinker)
- if m.InVendorOrProduct() && isLib && lib.hasLLNDKStubs() {
+ if m.InVendorOrProduct() && isLib && lib.HasLLNDKStubs() {
m.VendorProperties.IsLLNDK = true
}
- if m.InVendorOrProduct() && isPrebuiltLib && prebuiltLib.hasLLNDKStubs() {
+ if m.InVendorOrProduct() && isPrebuiltLib && prebuiltLib.HasLLNDKStubs() {
m.VendorProperties.IsLLNDK = true
}
diff --git a/cc/lto_test.go b/cc/lto_test.go
index e4b5a3a..3fb1f3c 100644
--- a/cc/lto_test.go
+++ b/cc/lto_test.go
@@ -70,24 +70,24 @@
result := LTOPreparer.RunTestWithBp(t, bp)
- libLto := result.ModuleForTests("lto_enabled", "android_arm64_armv8-a_shared").Module()
+ libLto := result.ModuleForTests(t, "lto_enabled", "android_arm64_armv8-a_shared").Module()
- libFoo := result.ModuleForTests("foo", "android_arm64_armv8-a_static").Module()
+ libFoo := result.ModuleForTests(t, "foo", "android_arm64_armv8-a_static").Module()
if !hasDep(result, libLto, libFoo) {
t.Errorf("'lto_enabled' missing dependency on the default variant of 'foo'")
}
- libBaz := result.ModuleForTests("baz", "android_arm64_armv8-a_static").Module()
+ libBaz := result.ModuleForTests(t, "baz", "android_arm64_armv8-a_static").Module()
if !hasDep(result, libFoo, libBaz) {
t.Errorf("'foo' missing dependency on the default variant of transitive dep 'baz'")
}
- libNeverLto := result.ModuleForTests("lib_never_lto", "android_arm64_armv8-a_static").Module()
+ libNeverLto := result.ModuleForTests(t, "lib_never_lto", "android_arm64_armv8-a_static").Module()
if !hasDep(result, libLto, libNeverLto) {
t.Errorf("'lto_enabled' missing dependency on the default variant of 'lib_never_lto'")
}
- libBar := result.ModuleForTests("bar", "android_arm64_armv8-a_shared").Module()
+ libBar := result.ModuleForTests(t, "bar", "android_arm64_armv8-a_shared").Module()
if !hasDep(result, libLto, libBar) {
t.Errorf("'lto_enabled' missing dependency on the default variant of 'bar'")
}
@@ -138,15 +138,15 @@
result := LTOPreparer.RunTestWithBp(t, bp)
- libRoot := result.ModuleForTests("root", "android_arm64_armv8-a_shared").Module()
- libRootLtoNever := result.ModuleForTests("root_no_lto", "android_arm64_armv8-a_shared").Module()
+ libRoot := result.ModuleForTests(t, "root", "android_arm64_armv8-a_shared").Module()
+ libRootLtoNever := result.ModuleForTests(t, "root_no_lto", "android_arm64_armv8-a_shared").Module()
- libFoo := result.ModuleForTests("foo", "android_arm64_armv8-a_static")
+ libFoo := result.ModuleForTests(t, "foo", "android_arm64_armv8-a_static")
if !hasDep(result, libRoot, libFoo.Module()) {
t.Errorf("'root' missing dependency on the default variant of 'foo'")
}
- libFooNoLto := result.ModuleForTests("foo", "android_arm64_armv8-a_static_lto-none")
+ libFooNoLto := result.ModuleForTests(t, "foo", "android_arm64_armv8-a_static_lto-none")
if !hasDep(result, libRootLtoNever, libFooNoLto.Module()) {
t.Errorf("'root_no_lto' missing dependency on the lto_none variant of 'foo'")
}
@@ -156,7 +156,7 @@
t.Errorf("'foo' expected to have flags %q, but got %q", w, libFooCFlags)
}
- libBaz := result.ModuleForTests("baz", "android_arm64_armv8-a_static")
+ libBaz := result.ModuleForTests(t, "baz", "android_arm64_armv8-a_static")
if !hasDep(result, libFoo.Module(), libBaz.Module()) {
t.Errorf("'foo' missing dependency on the default variant of transitive dep 'baz'")
}
@@ -187,8 +187,8 @@
}`
result := LTOPreparer.RunTestWithBp(t, bp)
- libFooWithLto := result.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
- libFooWithoutLto := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("ld")
+ libFooWithLto := result.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
+ libFooWithoutLto := result.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Rule("ld")
android.AssertStringDoesContain(t, "missing flag for LTO in variant that expects it",
libFooWithLto.Args["ldFlags"], "-flto=thin")
@@ -215,8 +215,8 @@
result := LTOPreparer.RunTestWithBp(t, bp)
- libFoo := result.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
- libBar := result.ModuleForTests("runtime_libbar", "android_arm_armv7-a-neon_shared").Rule("ld")
+ libFoo := result.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
+ libBar := result.ModuleForTests(t, "runtime_libbar", "android_arm_armv7-a-neon_shared").Rule("ld")
android.AssertStringDoesContain(t, "missing flag for LTO in LTO enabled library",
libFoo.Args["ldFlags"], "-flto=thin")
diff --git a/cc/makevars.go b/cc/makevars.go
index ca97b76..9358755 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -100,15 +100,7 @@
// Filter vendor_public_library that are exported to make
var exportedVendorPublicLibraries []string
- var warningsAllowed []string
- var usingWnoErrors []string
- var missingProfiles []string
ctx.VisitAllModules(func(module android.Module) {
- if v, ok := android.OtherModuleProvider(ctx, module, CcMakeVarsInfoProvider); ok {
- warningsAllowed = android.AppendIfNotZero(warningsAllowed, v.WarningsAllowed)
- usingWnoErrors = android.AppendIfNotZero(usingWnoErrors, v.UsingWnoError)
- missingProfiles = android.AppendIfNotZero(missingProfiles, v.MissingProfile)
- }
if ccModule, ok := module.(*Module); ok {
baseName := ccModule.BaseModuleName()
if ccModule.IsVendorPublicLibrary() && module.ExportedToMake() {
@@ -123,9 +115,6 @@
ctx.Strict("LSDUMP_PATHS", strings.Join(lsdumpPaths, " "))
ctx.Strict("ANDROID_WARNING_ALLOWED_PROJECTS", makeStringOfWarningAllowedProjects())
- ctx.Strict("SOONG_MODULES_WARNINGS_ALLOWED", makeVarsString(warningsAllowed))
- ctx.Strict("SOONG_MODULES_USING_WNO_ERROR", makeVarsString(usingWnoErrors))
- ctx.Strict("SOONG_MODULES_MISSING_PGO_PROFILE_FILE", makeVarsString(missingProfiles))
ctx.Strict("CLANG_COVERAGE_CONFIG_CFLAGS", strings.Join(clangCoverageCFlags, " "))
ctx.Strict("CLANG_COVERAGE_CONFIG_COMMFLAGS", strings.Join(clangCoverageCommonFlags, " "))
@@ -175,16 +164,18 @@
sort.Strings(ndkKnownLibs)
ctx.Strict("NDK_KNOWN_LIBS", strings.Join(ndkKnownLibs, " "))
- hostTargets := ctx.Config().Targets[ctx.Config().BuildOS]
- makeVarsToolchain(ctx, "", hostTargets[0])
- if len(hostTargets) > 1 {
- makeVarsToolchain(ctx, "2ND_", hostTargets[1])
+ if hostTargets := ctx.Config().Targets[ctx.Config().BuildOS]; len(hostTargets) > 0 {
+ makeVarsToolchain(ctx, "", hostTargets[0])
+ if len(hostTargets) > 1 {
+ makeVarsToolchain(ctx, "2ND_", hostTargets[1])
+ }
}
- deviceTargets := ctx.Config().Targets[android.Android]
- makeVarsToolchain(ctx, "", deviceTargets[0])
- if len(deviceTargets) > 1 {
- makeVarsToolchain(ctx, "2ND_", deviceTargets[1])
+ if deviceTargets := ctx.Config().Targets[android.Android]; len(deviceTargets) > 0 {
+ makeVarsToolchain(ctx, "", deviceTargets[0])
+ if len(deviceTargets) > 1 {
+ makeVarsToolchain(ctx, "2ND_", deviceTargets[1])
+ }
}
}
diff --git a/cc/misc_disted_files.go b/cc/misc_disted_files.go
new file mode 100644
index 0000000..4bdffaa
--- /dev/null
+++ b/cc/misc_disted_files.go
@@ -0,0 +1,89 @@
+// Copyright 2025 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cc
+
+import (
+ "android/soong/android"
+ "strings"
+)
+
+func init() {
+ android.InitRegistrationContext.RegisterSingletonType("cc_misc_disted_files", ccMiscDistedFilesSingletonFactory)
+}
+
+func ccMiscDistedFilesSingletonFactory() android.Singleton {
+ return &ccMiscDistedFilesSingleton{}
+}
+
+type ccMiscDistedFilesSingleton struct {
+ warningsAllowed []string
+ usingWnoErrors []string
+}
+
+func (s *ccMiscDistedFilesSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ var warningsAllowed []string
+ var usingWnoErrors []string
+ var missingProfiles []string
+ ctx.VisitAllModules(func(module android.Module) {
+ if v, ok := android.OtherModuleProvider(ctx, module, CcMakeVarsInfoProvider); ok {
+ warningsAllowed = android.AppendIfNotZero(warningsAllowed, v.WarningsAllowed)
+ usingWnoErrors = android.AppendIfNotZero(usingWnoErrors, v.UsingWnoError)
+ missingProfiles = android.AppendIfNotZero(missingProfiles, v.MissingProfile)
+ }
+ })
+
+ warningsAllowed = android.SortedUniqueStrings(warningsAllowed)
+ usingWnoErrors = android.SortedUniqueStrings(usingWnoErrors)
+ missingProfiles = android.SortedUniqueStrings(missingProfiles)
+
+ s.warningsAllowed = warningsAllowed
+ s.usingWnoErrors = usingWnoErrors
+
+ var sb strings.Builder
+ sb.WriteString("# Modules using -Wno-error\n")
+ for _, nwe := range usingWnoErrors {
+ sb.WriteString(nwe)
+ sb.WriteString("\n")
+ }
+ sb.WriteString("# Modules that allow warnings\n")
+ for _, wa := range warningsAllowed {
+ sb.WriteString(wa)
+ sb.WriteString("\n")
+ }
+ wallWerrFile := android.PathForOutput(ctx, "wall_werror.txt")
+ android.WriteFileRuleVerbatim(ctx, wallWerrFile, sb.String())
+
+ // Only dist this file in soong-only builds. In soong+make builds, it contains information
+ // from make modules, so we'll still rely on make to build and dist it.
+ if !ctx.Config().KatiEnabled() {
+ ctx.DistForGoal("droidcore-unbundled", wallWerrFile)
+ }
+
+ var sb2 strings.Builder
+ sb2.WriteString("# Modules missing PGO profile files\n")
+ for _, mp := range missingProfiles {
+ sb2.WriteString(mp)
+ sb2.WriteString("\n")
+ }
+ profileMissingFile := android.PathForOutput(ctx, "pgo_profile_file_missing.txt")
+ android.WriteFileRuleVerbatim(ctx, profileMissingFile, sb2.String())
+
+ ctx.DistForGoal("droidcore-unbundled", profileMissingFile)
+}
+
+func (s *ccMiscDistedFilesSingleton) MakeVars(ctx android.MakeVarsContext) {
+ ctx.Strict("SOONG_MODULES_WARNINGS_ALLOWED", strings.Join(s.warningsAllowed, " "))
+ ctx.Strict("SOONG_MODULES_USING_WNO_ERROR", strings.Join(s.usingWnoErrors, " "))
+}
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 27a9f66..1f0fc07 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -133,13 +133,13 @@
unversionedUntil android.ApiLevel
}
-var _ versionedInterface = (*stubDecorator)(nil)
+var _ VersionedInterface = (*stubDecorator)(nil)
func shouldUseVersionScript(ctx BaseModuleContext, stub *stubDecorator) bool {
return stub.apiLevel.GreaterThanOrEqualTo(stub.unversionedUntil)
}
-func (stub *stubDecorator) implementationModuleName(name string) string {
+func (stub *stubDecorator) ImplementationModuleName(name string) string {
return strings.TrimSuffix(name, ndkLibrarySuffix)
}
@@ -155,7 +155,7 @@
return versionStrs
}
-func (this *stubDecorator) stubsVersions(ctx android.BaseModuleContext) []string {
+func (this *stubDecorator) StubsVersions(ctx android.BaseModuleContext) []string {
if !ctx.Module().Enabled(ctx) {
return nil
}
@@ -163,7 +163,7 @@
ctx.Module().Disable()
return nil
}
- firstVersion, err := nativeApiLevelFromUser(ctx,
+ firstVersion, err := NativeApiLevelFromUser(ctx,
String(this.properties.First_version))
if err != nil {
ctx.PropertyErrorf("first_version", err.Error())
@@ -173,10 +173,10 @@
}
func (this *stubDecorator) initializeProperties(ctx BaseModuleContext) bool {
- this.apiLevel = nativeApiLevelOrPanic(ctx, this.stubsVersion())
+ this.apiLevel = nativeApiLevelOrPanic(ctx, this.StubsVersion())
var err error
- this.firstVersion, err = nativeApiLevelFromUser(ctx,
+ this.firstVersion, err = NativeApiLevelFromUser(ctx,
String(this.properties.First_version))
if err != nil {
ctx.PropertyErrorf("first_version", err.Error())
@@ -184,7 +184,7 @@
}
str := proptools.StringDefault(this.properties.Unversioned_until, "minimum")
- this.unversionedUntil, err = nativeApiLevelFromUser(ctx, str)
+ this.unversionedUntil, err = NativeApiLevelFromUser(ctx, str)
if err != nil {
ctx.PropertyErrorf("unversioned_until", err.Error())
return false
@@ -236,7 +236,7 @@
pctx.StaticVariable("StubLibraryCompilerFlags", strings.Join(stubLibraryCompilerFlags, " "))
}
-func addStubLibraryCompilerFlags(flags Flags) Flags {
+func AddStubLibraryCompilerFlags(flags Flags) Flags {
flags.Global.CFlags = append(flags.Global.CFlags, stubLibraryCompilerFlags...)
// All symbols in the stubs library should be visible.
if inList("-fvisibility=hidden", flags.Local.CFlags) {
@@ -247,17 +247,17 @@
func (stub *stubDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
flags = stub.baseCompiler.compilerFlags(ctx, flags, deps)
- return addStubLibraryCompilerFlags(flags)
+ return AddStubLibraryCompilerFlags(flags)
}
-type ndkApiOutputs struct {
- stubSrc android.ModuleGenPath
- versionScript android.ModuleGenPath
+type NdkApiOutputs struct {
+ StubSrc android.ModuleGenPath
+ VersionScript android.ModuleGenPath
symbolList android.ModuleGenPath
}
-func parseNativeAbiDefinition(ctx ModuleContext, symbolFile string,
- apiLevel android.ApiLevel, genstubFlags string) ndkApiOutputs {
+func ParseNativeAbiDefinition(ctx android.ModuleContext, symbolFile string,
+ apiLevel android.ApiLevel, genstubFlags string) NdkApiOutputs {
stubSrcPath := android.PathForModuleGen(ctx, "stub.c")
versionScriptPath := android.PathForModuleGen(ctx, "stub.map")
@@ -279,20 +279,20 @@
},
})
- return ndkApiOutputs{
- stubSrc: stubSrcPath,
- versionScript: versionScriptPath,
+ return NdkApiOutputs{
+ StubSrc: stubSrcPath,
+ VersionScript: versionScriptPath,
symbolList: symbolListPath,
}
}
-func compileStubLibrary(ctx ModuleContext, flags Flags, src android.Path) Objects {
+func CompileStubLibrary(ctx android.ModuleContext, flags Flags, src android.Path, sharedFlags *SharedFlags) Objects {
// libc/libm stubs libraries end up mismatching with clang's internal definition of these
// functions (which have noreturn attributes and other things). Because we just want to create a
// stub with symbol definitions, and types aren't important in C, ignore the mismatch.
flags.Local.ConlyFlags = append(flags.Local.ConlyFlags, "-fno-builtin")
return compileObjs(ctx, flagsToBuilderFlags(flags), "",
- android.Paths{src}, nil, nil, nil, nil)
+ android.Paths{src}, nil, nil, nil, nil, sharedFlags)
}
func (this *stubDecorator) findImplementationLibrary(ctx ModuleContext) android.Path {
@@ -489,7 +489,7 @@
ctx.PropertyErrorf("symbol_file", "must end with .map.txt")
}
- if !c.buildStubs() {
+ if !c.BuildStubs() {
// NDK libraries have no implementation variant, nothing to do
return Objects{}
}
@@ -500,9 +500,9 @@
}
symbolFile := String(c.properties.Symbol_file)
- nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile, c.apiLevel, "")
- objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
- c.versionScriptPath = nativeAbiResult.versionScript
+ nativeAbiResult := ParseNativeAbiDefinition(ctx, symbolFile, c.apiLevel, "")
+ objs := CompileStubLibrary(ctx, flags, nativeAbiResult.StubSrc, ctx.getSharedFlags())
+ c.versionScriptPath = nativeAbiResult.VersionScript
if c.canDumpAbi(ctx) {
c.dumpAbi(ctx, nativeAbiResult.symbolList)
if c.canDiffAbi(ctx.Config()) {
@@ -510,7 +510,7 @@
}
}
if c.apiLevel.IsCurrent() && ctx.PrimaryArch() {
- c.parsedCoverageXmlPath = parseSymbolFileForAPICoverage(ctx, symbolFile)
+ c.parsedCoverageXmlPath = ParseSymbolFileForAPICoverage(ctx, symbolFile)
}
return objs
}
@@ -541,7 +541,7 @@
func (stub *stubDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps,
objs Objects) android.Path {
- if !stub.buildStubs() {
+ if !stub.BuildStubs() {
// NDK libraries have no implementation variant, nothing to do
return nil
}
diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go
index 92da172..a5f014b 100644
--- a/cc/ndk_sysroot.go
+++ b/cc/ndk_sysroot.go
@@ -245,7 +245,7 @@
}
if m, ok := module.(*Module); ok {
- if installer, ok := m.installer.(*stubDecorator); ok && m.library.buildStubs() {
+ if installer, ok := m.installer.(*stubDecorator); ok && m.library.BuildStubs() {
installPaths = append(installPaths, installer.installPath)
}
diff --git a/cc/ndk_test.go b/cc/ndk_test.go
index f20d3c6..8574bf1 100644
--- a/cc/ndk_test.go
+++ b/cc/ndk_test.go
@@ -50,7 +50,7 @@
}
`
ctx := prepareForCcTest.RunTestWithBp(t, bp)
- libfoo := ctx.ModuleForTests("libfoo.ndk", "android_arm64_armv8-a_sdk_shared")
- libfoo_headers := ctx.ModuleForTests("libfoo_headers", "")
+ libfoo := ctx.ModuleForTests(t, "libfoo.ndk", "android_arm64_armv8-a_sdk_shared")
+ libfoo_headers := ctx.ModuleForTests(t, "libfoo_headers", "")
android.AssertBoolEquals(t, "Could not find headers of ndk_library", true, isDep(ctx, libfoo.Module(), libfoo_headers.Module()))
}
diff --git a/cc/object.go b/cc/object.go
index c89520a..bbfca94 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -159,7 +159,7 @@
// isForPlatform is terribly named and actually means isNotApex.
if Bool(object.Properties.Crt) &&
!Bool(object.Properties.Exclude_from_ndk_sysroot) && ctx.useSdk() &&
- ctx.isSdkVariant() && ctx.isForPlatform() {
+ ctx.isSdkVariant() && CtxIsForPlatform(ctx) {
output = getVersionedLibraryInstallPath(ctx,
nativeApiLevelOrPanic(ctx, ctx.sdkVersion())).Join(ctx, outputName)
diff --git a/cc/object_test.go b/cc/object_test.go
index 004dfd3..6d82265 100644
--- a/cc/object_test.go
+++ b/cc/object_test.go
@@ -46,13 +46,13 @@
ctx := prepareForCcTest.RunTestWithBp(t, bp)
for _, v := range variants {
- cflags := ctx.ModuleForTests("crt_foo", v.variant).Rule("cc").Args["cFlags"]
+ cflags := ctx.ModuleForTests(t, "crt_foo", v.variant).Rule("cc").Args["cFlags"]
expected := "-target aarch64-linux-android" + v.num + " "
android.AssertStringDoesContain(t, "cflag", cflags, expected)
}
ctx = prepareForCcTest.RunTestWithBp(t, bp)
android.AssertStringDoesContain(t, "cflag",
- ctx.ModuleForTests("crt_foo", "android_vendor_arm64_armv8-a").Rule("cc").Args["cFlags"],
+ ctx.ModuleForTests(t, "crt_foo", "android_vendor_arm64_armv8-a").Rule("cc").Args["cFlags"],
"-target aarch64-linux-android10000 ")
}
@@ -69,13 +69,13 @@
// Sdk variant uses the crt object of the matching min_sdk_version
variant := "android_arm64_armv8-a_sdk"
- crt := ctx.ModuleForTests("bin", variant).Rule("ld").Args["crtBegin"]
+ crt := ctx.ModuleForTests(t, "bin", variant).Rule("ld").Args["crtBegin"]
android.AssertStringDoesContain(t, "crt dep of sdk variant", crt,
"29/crtbegin_dynamic.o")
// platform variant uses the crt object built for platform
variant = "android_arm64_armv8-a"
- crt = ctx.ModuleForTests("bin", variant).Rule("ld").Args["crtBegin"]
+ crt = ctx.ModuleForTests(t, "bin", variant).Rule("ld").Args["crtBegin"]
android.AssertStringDoesContain(t, "crt dep of platform variant", crt,
variant+"/crtbegin_dynamic.o")
}
@@ -147,7 +147,7 @@
ctx := PrepareForIntegrationTestWithCc.RunTestWithBp(t, bp)
android.AssertPathRelativeToTopEquals(t, "expected output file foo.o",
fmt.Sprintf("out/soong/.intermediates/%s/android_arm64_armv8-a/foo.o", testcase.moduleName),
- ctx.ModuleForTests(testcase.moduleName, "android_arm64_armv8-a").Output("foo.o").Output)
+ ctx.ModuleForTests(t, testcase.moduleName, "android_arm64_armv8-a").Output("foo.o").Output)
})
}
diff --git a/cc/orderfile_test.go b/cc/orderfile_test.go
index 3486f96..41253ad 100644
--- a/cc/orderfile_test.go
+++ b/cc/orderfile_test.go
@@ -41,7 +41,7 @@
expectedCFlag := "-forder-file-instrumentation"
- libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
+ libTest := result.ModuleForTests(t, "libTest", "android_arm64_armv8-a_shared")
// Check cFlags of orderfile-enabled module
cFlags := libTest.Rule("cc").Args["cFlags"]
@@ -77,7 +77,7 @@
expectedCFlag := "-Wl,--symbol-ordering-file=toolchain/pgo-profiles/orderfiles/libTest.orderfile"
- libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
+ libTest := result.ModuleForTests(t, "libTest", "android_arm64_armv8-a_shared")
// Check ldFlags of orderfile-enabled module
ldFlags := libTest.Rule("ld").Args["ldFlags"]
@@ -106,7 +106,7 @@
expectedCFlag := "-forder-file-instrumentation"
- test := result.ModuleForTests("test", "android_arm64_armv8-a")
+ test := result.ModuleForTests(t, "test", "android_arm64_armv8-a")
// Check cFlags of orderfile-enabled module
cFlags := test.Rule("cc").Args["cFlags"]
@@ -142,7 +142,7 @@
expectedCFlag := "-Wl,--symbol-ordering-file=toolchain/pgo-profiles/orderfiles/test.orderfile"
- test := result.ModuleForTests("test", "android_arm64_armv8-a")
+ test := result.ModuleForTests(t, "test", "android_arm64_armv8-a")
// Check ldFlags of orderfile-enabled module
ldFlags := test.Rule("ld").Args["ldFlags"]
@@ -185,7 +185,7 @@
expectedCFlag := "-forder-file-instrumentation"
// Check cFlags of orderfile-enabled module
- libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
+ libTest := result.ModuleForTests(t, "libTest", "android_arm64_armv8-a_shared")
cFlags := libTest.Rule("cc").Args["cFlags"]
if !strings.Contains(cFlags, expectedCFlag) {
@@ -193,8 +193,8 @@
}
// Check cFlags of orderfile variant static libraries
- libFooOfVariant := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_orderfile")
- libBarOfVariant := result.ModuleForTests("libBar", "android_arm64_armv8-a_static_orderfile")
+ libFooOfVariant := result.ModuleForTests(t, "libFoo", "android_arm64_armv8-a_static_orderfile")
+ libBarOfVariant := result.ModuleForTests(t, "libBar", "android_arm64_armv8-a_static_orderfile")
cFlags = libFooOfVariant.Rule("cc").Args["cFlags"]
if !strings.Contains(cFlags, expectedCFlag) {
@@ -216,8 +216,8 @@
}
// Check cFlags of the non-orderfile variant static libraries
- libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
- libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
+ libFoo := result.ModuleForTests(t, "libFoo", "android_arm64_armv8-a_static")
+ libBar := result.ModuleForTests(t, "libBar", "android_arm64_armv8-a_static")
cFlags = libFoo.Rule("cc").Args["cFlags"]
if strings.Contains(cFlags, expectedCFlag) {
@@ -274,15 +274,15 @@
expectedCFlag := "-Wl,--symbol-ordering-file=toolchain/pgo-profiles/orderfiles/test.orderfile"
// Check ldFlags of orderfile-enabled module
- libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
+ libTest := result.ModuleForTests(t, "libTest", "android_arm64_armv8-a_shared")
ldFlags := libTest.Rule("ld").Args["ldFlags"]
if !strings.Contains(ldFlags, expectedCFlag) {
t.Errorf("Expected 'libTest' to load orderfile, but did not find %q in ldFlags %q", expectedCFlag, ldFlags)
}
- libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
- libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
+ libFoo := result.ModuleForTests(t, "libFoo", "android_arm64_armv8-a_static")
+ libBar := result.ModuleForTests(t, "libBar", "android_arm64_armv8-a_static")
// Check dependency edge from orderfile-enabled module to non-orderfile variant static libraries
if !hasDirectDep(result, libTest.Module(), libFoo.Module()) {
@@ -343,7 +343,7 @@
expectedCFlag := "-forder-file-instrumentation"
// Check cFlags of orderfile-enabled module
- libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
+ libTest := result.ModuleForTests(t, "libTest", "android_arm64_armv8-a_shared")
cFlags := libTest.Rule("cc").Args["cFlags"]
if !strings.Contains(cFlags, expectedCFlag) {
@@ -351,8 +351,8 @@
}
// Check cFlags of the static and shared libraries
- libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_shared")
- libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
+ libFoo := result.ModuleForTests(t, "libFoo", "android_arm64_armv8-a_shared")
+ libBar := result.ModuleForTests(t, "libBar", "android_arm64_armv8-a_static")
cFlags = libFoo.Rule("cc").Args["cFlags"]
if strings.Contains(cFlags, expectedCFlag) {
@@ -423,7 +423,7 @@
expectedCFlag := "-forder-file-instrumentation"
// Check cFlags of module
- libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_static")
+ libTest := result.ModuleForTests(t, "libTest", "android_arm64_armv8-a_static")
cFlags := libTest.Rule("cc").Args["cFlags"]
if strings.Contains(cFlags, expectedCFlag) {
@@ -431,8 +431,8 @@
}
// Check cFlags of the static libraries
- libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
- libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
+ libFoo := result.ModuleForTests(t, "libFoo", "android_arm64_armv8-a_static")
+ libBar := result.ModuleForTests(t, "libBar", "android_arm64_armv8-a_static")
cFlags = libFoo.Rule("cc").Args["cFlags"]
if strings.Contains(cFlags, expectedCFlag) {
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index 96a07bc..70ee5e3 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -114,10 +114,10 @@
// TODO(ccross): verify shared library dependencies
srcs := p.prebuiltSrcs(ctx)
- stubInfo := addStubDependencyProviders(ctx)
+ stubInfo := AddStubDependencyProviders(ctx)
// Stub variants will create a stub .so file from stub .c files
- if p.buildStubs() && objs.objFiles != nil {
+ if p.BuildStubs() && objs.objFiles != nil {
// TODO (b/275273834): Make objs.objFiles == nil a hard error when the symbol files have been added to module sdk.
return p.linkShared(ctx, flags, deps, objs)
}
@@ -204,7 +204,7 @@
Target: ctx.Target(),
TableOfContents: p.tocFile,
- IsStubs: p.buildStubs(),
+ IsStubs: p.BuildStubs(),
})
return outputFile
@@ -268,7 +268,7 @@
}
// Implements versionedInterface
-func (p *prebuiltLibraryLinker) implementationModuleName(name string) string {
+func (p *prebuiltLibraryLinker) ImplementationModuleName(name string) string {
return android.RemoveOptionalPrebuiltPrefix(name)
}
@@ -298,7 +298,7 @@
}
func (p *prebuiltLibraryLinker) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
- if p.buildStubs() && p.stubsVersion() != "" {
+ if p.BuildStubs() && p.StubsVersion() != "" {
return p.compileModuleLibApiStubs(ctx, flags, deps)
}
return Objects{}
diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go
index 3214fb4..af68ca6 100644
--- a/cc/prebuilt_test.go
+++ b/cc/prebuilt_test.go
@@ -116,21 +116,21 @@
})
// Verify that all the modules exist and that their dependencies were connected correctly
- liba := ctx.ModuleForTests("liba", "android_arm64_armv8-a_shared").Module()
- libb := ctx.ModuleForTests("libb", "android_arm64_armv8-a_static").Module()
- libd := ctx.ModuleForTests("libd", "android_arm64_armv8-a_shared").Module()
- libe := ctx.ModuleForTests("libe", "android_arm64_armv8-a_static").Module()
- libfStatic := ctx.ModuleForTests("libf", "android_arm64_armv8-a_static").Module()
- libfShared := ctx.ModuleForTests("libf", "android_arm64_armv8-a_shared").Module()
- crtx := ctx.ModuleForTests("crtx", "android_arm64_armv8-a").Module()
+ liba := ctx.ModuleForTests(t, "liba", "android_arm64_armv8-a_shared").Module()
+ libb := ctx.ModuleForTests(t, "libb", "android_arm64_armv8-a_static").Module()
+ libd := ctx.ModuleForTests(t, "libd", "android_arm64_armv8-a_shared").Module()
+ libe := ctx.ModuleForTests(t, "libe", "android_arm64_armv8-a_static").Module()
+ libfStatic := ctx.ModuleForTests(t, "libf", "android_arm64_armv8-a_static").Module()
+ libfShared := ctx.ModuleForTests(t, "libf", "android_arm64_armv8-a_shared").Module()
+ crtx := ctx.ModuleForTests(t, "crtx", "android_arm64_armv8-a").Module()
- prebuiltLiba := ctx.ModuleForTests("prebuilt_liba", "android_arm64_armv8-a_shared").Module()
- prebuiltLibb := ctx.ModuleForTests("prebuilt_libb", "android_arm64_armv8-a_static").Module()
- prebuiltLibd := ctx.ModuleForTests("prebuilt_libd", "android_arm64_armv8-a_shared").Module()
- prebuiltLibe := ctx.ModuleForTests("prebuilt_libe", "android_arm64_armv8-a_static").Module()
- prebuiltLibfStatic := ctx.ModuleForTests("prebuilt_libf", "android_arm64_armv8-a_static").Module()
- prebuiltLibfShared := ctx.ModuleForTests("prebuilt_libf", "android_arm64_armv8-a_shared").Module()
- prebuiltCrtx := ctx.ModuleForTests("prebuilt_crtx", "android_arm64_armv8-a").Module()
+ prebuiltLiba := ctx.ModuleForTests(t, "prebuilt_liba", "android_arm64_armv8-a_shared").Module()
+ prebuiltLibb := ctx.ModuleForTests(t, "prebuilt_libb", "android_arm64_armv8-a_static").Module()
+ prebuiltLibd := ctx.ModuleForTests(t, "prebuilt_libd", "android_arm64_armv8-a_shared").Module()
+ prebuiltLibe := ctx.ModuleForTests(t, "prebuilt_libe", "android_arm64_armv8-a_static").Module()
+ prebuiltLibfStatic := ctx.ModuleForTests(t, "prebuilt_libf", "android_arm64_armv8-a_static").Module()
+ prebuiltLibfShared := ctx.ModuleForTests(t, "prebuilt_libf", "android_arm64_armv8-a_shared").Module()
+ prebuiltCrtx := ctx.ModuleForTests(t, "prebuilt_crtx", "android_arm64_armv8-a").Module()
hasDep := func(m android.Module, wantDep android.Module) bool {
t.Helper()
@@ -190,7 +190,7 @@
"libf.so": nil,
})
- shared := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared").Module().(*Module)
+ shared := ctx.ModuleForTests(t, "libtest", "android_arm64_armv8-a_shared").Module().(*Module)
assertString(t, shared.OutputFile().Path().Base(), "libtest.so")
}
@@ -204,7 +204,7 @@
"libf.a": nil,
})
- static := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static").Module().(*Module)
+ static := ctx.ModuleForTests(t, "libtest", "android_arm64_armv8-a_static").Module().(*Module)
assertString(t, static.OutputFile().Path().Base(), "libf.a")
}
@@ -227,10 +227,10 @@
"libf.so": nil,
})
- shared := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared").Module().(*Module)
+ shared := ctx.ModuleForTests(t, "libtest", "android_arm64_armv8-a_shared").Module().(*Module)
assertString(t, shared.OutputFile().Path().Base(), "libtest.so")
- static := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static").Module().(*Module)
+ static := ctx.ModuleForTests(t, "libtest", "android_arm64_armv8-a_static").Module().(*Module)
assertString(t, static.OutputFile().Path().Base(), "libf.a")
}
@@ -254,10 +254,10 @@
"libfoo.so": nil,
})
- static := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Module().(*Module)
+ static := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_static").Module().(*Module)
assertString(t, static.OutputFile().Path().Base(), "libfoo.a")
- shared := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*Module)
+ shared := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module().(*Module)
assertString(t, shared.OutputFile().Path().Base(), "libbar.so")
}
@@ -275,7 +275,7 @@
"libfoo.so": nil,
})
- shared := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*Module)
+ shared := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module().(*Module)
assertString(t, shared.OutputFile().Path().Base(), "libbar.so")
}
@@ -312,7 +312,7 @@
"foo": nil,
})
- fooRule := ctx.ModuleForTests("foo", "linux_glibc_x86_64").Rule("Symlink")
+ fooRule := ctx.ModuleForTests(t, "foo", "linux_glibc_x86_64").Rule("Symlink")
assertString(t, fooRule.Output.String(), "out/soong/.intermediates/foo/linux_glibc_x86_64/foo")
assertString(t, fooRule.Args["fromPath"], "$$PWD/linux_glibc_x86_64/bin/foo")
@@ -355,16 +355,16 @@
// Without SANITIZE_TARGET.
ctx := testPrebuilt(t, bp, fs)
- shared_rule := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared").Rule("android/soong/cc.strip")
+ shared_rule := ctx.ModuleForTests(t, "libtest", "android_arm64_armv8-a_shared").Rule("android/soong/cc.strip")
assertString(t, shared_rule.Input.String(), "libf.so")
- static := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static").Module().(*Module)
+ static := ctx.ModuleForTests(t, "libtest", "android_arm64_armv8-a_static").Module().(*Module)
assertString(t, static.OutputFile().Path().Base(), "libf.a")
- shared_rule2 := ctx.ModuleForTests("libtest_shared", "android_arm64_armv8-a_shared").Rule("android/soong/cc.strip")
+ shared_rule2 := ctx.ModuleForTests(t, "libtest_shared", "android_arm64_armv8-a_shared").Rule("android/soong/cc.strip")
assertString(t, shared_rule2.Input.String(), "libf.so")
- static2 := ctx.ModuleForTests("libtest_static", "android_arm64_armv8-a_static").Module().(*Module)
+ static2 := ctx.ModuleForTests(t, "libtest_static", "android_arm64_armv8-a_static").Module().(*Module)
assertString(t, static2.OutputFile().Path().Base(), "libf.a")
// With SANITIZE_TARGET=hwaddress
@@ -374,16 +374,16 @@
}),
)
- shared_rule = ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared_hwasan").Rule("android/soong/cc.strip")
+ shared_rule = ctx.ModuleForTests(t, "libtest", "android_arm64_armv8-a_shared_hwasan").Rule("android/soong/cc.strip")
assertString(t, shared_rule.Input.String(), "hwasan/libf.so")
- static = ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static_hwasan").Module().(*Module)
+ static = ctx.ModuleForTests(t, "libtest", "android_arm64_armv8-a_static_hwasan").Module().(*Module)
assertString(t, static.OutputFile().Path().Base(), "libf.hwasan.a")
- shared_rule2 = ctx.ModuleForTests("libtest_shared", "android_arm64_armv8-a_shared_hwasan").Rule("android/soong/cc.strip")
+ shared_rule2 = ctx.ModuleForTests(t, "libtest_shared", "android_arm64_armv8-a_shared_hwasan").Rule("android/soong/cc.strip")
assertString(t, shared_rule2.Input.String(), "hwasan/libf.so")
- static2 = ctx.ModuleForTests("libtest_static", "android_arm64_armv8-a_static_hwasan").Module().(*Module)
+ static2 = ctx.ModuleForTests(t, "libtest_static", "android_arm64_armv8-a_static_hwasan").Module().(*Module)
assertString(t, static2.OutputFile().Path().Base(), "libf.hwasan.a")
}
@@ -394,7 +394,7 @@
srcs: [],
}`
ctx := testPrebuilt(t, bp, map[string][]byte{})
- mod := ctx.ModuleForTests("bintest", "android_arm64_armv8-a").Module().(*Module)
+ mod := ctx.ModuleForTests(t, "bintest", "android_arm64_armv8-a").Module().(*Module)
android.AssertBoolEquals(t, `expected no srcs to yield no output file`, false, mod.OutputFile().Valid())
}
@@ -484,8 +484,8 @@
"libbar.so": nil,
"crtx.o": nil,
}, preparer)
- libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
- expectedDependency := ctx.ModuleForTests(tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module()
+ libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module()
+ expectedDependency := ctx.ModuleForTests(t, tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module()
android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", libfoo.Name(), tc.expectedDependencyName), true, hasDep(ctx, libfoo, expectedDependency))
// check that LOCAL_SHARED_LIBRARIES contains libbar and not libbar.v<N>
entries := android.AndroidMkInfoForTest(t, ctx, libfoo).PrimaryInfo
@@ -493,7 +493,7 @@
// check installation rules
// the selected soong module should be exported to make
- libbar := ctx.ModuleForTests(tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module()
+ libbar := ctx.ModuleForTests(t, tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module()
android.AssertBoolEquals(t, fmt.Sprintf("dependency %s should be exported to make\n", expectedDependency), true, !libbar.IsHideFromMake())
// check LOCAL_MODULE of the selected module name
@@ -585,8 +585,8 @@
if tc.expectedErr != "" {
return // the fixture will assert that the excepted err has been raised
}
- libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
- expectedDependency := ctx.ModuleForTests(tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module()
+ libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module()
+ expectedDependency := ctx.ModuleForTests(t, tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module()
android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", libfoo.Name(), tc.expectedDependencyName), true, hasDep(ctx, libfoo, expectedDependency))
}
}
@@ -638,8 +638,8 @@
"libbar.so": nil,
"crtx.o": nil,
}, preparer)
- libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
- sourceLibBar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_static").Module()
+ libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module()
+ sourceLibBar := ctx.ModuleForTests(t, "libbar", "android_arm64_armv8-a_static").Module()
// Even though the prebuilt is listed in apex_contributions, the prebuilt does not have a static variant.
// Therefore source of libbar should be used.
android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from libfoo to source libbar"), true, hasDep(ctx, libfoo, sourceLibBar))
diff --git a/cc/proto_test.go b/cc/proto_test.go
index a905ea8..47b7e17 100644
--- a/cc/proto_test.go
+++ b/cc/proto_test.go
@@ -29,7 +29,7 @@
srcs: ["a.proto"],
}`)
- proto := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Output("proto/a.pb.cc")
+ proto := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_shared").Output("proto/a.pb.cc")
if cmd := proto.RuleParams.Command; !strings.Contains(cmd, "--cpp_out=") {
t.Errorf("expected '--cpp_out' in %q", cmd)
@@ -53,8 +53,8 @@
buildOS := ctx.Config().BuildOS.String()
- proto := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Output("proto/a.pb.cc")
- foobar := ctx.ModuleForTests("protoc-gen-foobar", buildOS+"_x86_64")
+ proto := ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_shared").Output("proto/a.pb.cc")
+ foobar := ctx.ModuleForTests(t, "protoc-gen-foobar", buildOS+"_x86_64")
cmd := proto.RuleParams.Command
if w := "--foobar_out="; !strings.Contains(cmd, w) {
@@ -85,8 +85,8 @@
buildOS := ctx.Config().BuildOS.String()
- proto := ctx.ModuleForTests("libgrpc", "android_arm_armv7-a-neon_shared").Output("proto/a.grpc.pb.cc")
- grpcCppPlugin := ctx.ModuleForTests("protoc-gen-grpc-cpp-plugin", buildOS+"_x86_64")
+ proto := ctx.ModuleForTests(t, "libgrpc", "android_arm_armv7-a-neon_shared").Output("proto/a.grpc.pb.cc")
+ grpcCppPlugin := ctx.ModuleForTests(t, "protoc-gen-grpc-cpp-plugin", buildOS+"_x86_64")
cmd := proto.RuleParams.Command
if w := "--grpc-cpp-plugin_out="; !strings.Contains(cmd, w) {
diff --git a/cc/sabi.go b/cc/sabi.go
index bc61b6c..06ab6ec 100644
--- a/cc/sabi.go
+++ b/cc/sabi.go
@@ -137,7 +137,7 @@
if m.isImplementationForLLNDKPublic() {
result = append(result, llndkLsdumpTag)
}
- if m.library.hasStubsVariants() {
+ if m.library.HasStubsVariants() {
result = append(result, apexLsdumpTag)
}
if headerAbiChecker.enabled() {
diff --git a/cc/sabi_test.go b/cc/sabi_test.go
index 6b8cc17..3d2a98c 100644
--- a/cc/sabi_test.go
+++ b/cc/sabi_test.go
@@ -48,16 +48,16 @@
PrepareForTestWithCcDefaultModules,
).RunTestWithBp(t, bp)
- libsabiStatic := result.ModuleForTests("libsabi", "android_arm64_armv8-a_static_sabi")
+ libsabiStatic := result.ModuleForTests(t, "libsabi", "android_arm64_armv8-a_static_sabi")
sabiObjSDump := libsabiStatic.Output("obj/sabi.sdump")
- libDirect := result.ModuleForTests("libdirect", "android_arm64_armv8-a_static_sabi")
+ libDirect := result.ModuleForTests(t, "libdirect", "android_arm64_armv8-a_static_sabi")
directObjSDump := libDirect.Output("obj/direct.sdump")
- libTransitive := result.ModuleForTests("libtransitive", "android_arm64_armv8-a_static_sabi")
+ libTransitive := result.ModuleForTests(t, "libtransitive", "android_arm64_armv8-a_static_sabi")
transitiveObjSDump := libTransitive.Output("obj/transitive.sdump")
- libsabiShared := result.ModuleForTests("libsabi", "android_arm64_armv8-a_shared")
+ libsabiShared := result.ModuleForTests(t, "libsabi", "android_arm64_armv8-a_shared")
sabiLink := libsabiShared.Rule("sAbiLink")
android.AssertStringListContains(t, "sabi link inputs", sabiLink.Inputs.Strings(), sabiObjSDump.Output.String())
diff --git a/cc/sanitize.go b/cc/sanitize.go
index d8d8c7a..b704ef4 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -79,7 +79,7 @@
minimalRuntimeFlags = []string{"-fsanitize-minimal-runtime", "-fno-sanitize-trap=integer,undefined",
"-fno-sanitize-recover=integer,undefined"}
- memtagStackCommonFlags = []string{"-march=armv8-a+memtag"}
+ memtagStackCommonFlags = []string{"-Xclang -target-feature -Xclang +mte"}
memtagStackLlvmFlags = []string{"-dom-tree-reachability-max-bbs-to-explore=128"}
hostOnlySanitizeFlags = []string{"-fno-sanitize-recover=all"}
@@ -1901,6 +1901,8 @@
ctx.SetOutputFiles(android.Paths{outputFile}, "")
txt.outputFile = outputFile
+
+ etc.SetCommonPrebuiltEtcInfo(ctx, txt)
}
func (txt *sanitizerLibrariesTxtModule) PrepareAndroidMKProviderInfo(config android.Config) *android.AndroidMkProviderInfo {
diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go
index a1cfb5c..543e808 100644
--- a/cc/sanitize_test.go
+++ b/cc/sanitize_test.go
@@ -222,31 +222,31 @@
staticAsanVariant := staticVariant + "_asan"
// The binaries, one with asan and one without
- binWithAsan := result.ModuleForTests("bin_with_asan", asanVariant)
- binNoAsan := result.ModuleForTests("bin_no_asan", variant)
+ binWithAsan := result.ModuleForTests(t, "bin_with_asan", asanVariant)
+ binNoAsan := result.ModuleForTests(t, "bin_no_asan", variant)
// Shared libraries that don't request asan
- libShared := result.ModuleForTests("libshared", sharedVariant)
- libTransitive := result.ModuleForTests("libtransitive", sharedVariant)
+ libShared := result.ModuleForTests(t, "libshared", sharedVariant)
+ libTransitive := result.ModuleForTests(t, "libtransitive", sharedVariant)
// Shared library that requests asan
- libAsan := result.ModuleForTests("libasan", sharedAsanVariant)
+ libAsan := result.ModuleForTests(t, "libasan", sharedAsanVariant)
// Static library that uses an asan variant for bin_with_asan and a non-asan variant
// for bin_no_asan.
- libStaticAsanVariant := result.ModuleForTests("libstatic", staticAsanVariant)
- libStaticNoAsanVariant := result.ModuleForTests("libstatic", staticVariant)
+ libStaticAsanVariant := result.ModuleForTests(t, "libstatic", staticAsanVariant)
+ libStaticNoAsanVariant := result.ModuleForTests(t, "libstatic", staticVariant)
// Static library that never uses asan.
- libNoAsan := result.ModuleForTests("libnoasan", staticVariant)
+ libNoAsan := result.ModuleForTests(t, "libnoasan", staticVariant)
// Static library that specifies asan
- libStaticAsan := result.ModuleForTests("libstatic_asan", staticAsanVariant)
- libStaticAsanNoAsanVariant := result.ModuleForTests("libstatic_asan", staticVariant)
+ libStaticAsan := result.ModuleForTests(t, "libstatic_asan", staticAsanVariant)
+ libStaticAsanNoAsanVariant := result.ModuleForTests(t, "libstatic_asan", staticVariant)
- libAsanSharedRuntime := result.ModuleForTests("libclang_rt.asan", sharedVariant)
- libAsanStaticRuntime := result.ModuleForTests("libclang_rt.asan.static", staticVariant)
- libAsanStaticCxxRuntime := result.ModuleForTests("libclang_rt.asan_cxx.static", staticVariant)
+ libAsanSharedRuntime := result.ModuleForTests(t, "libclang_rt.asan", sharedVariant)
+ libAsanStaticRuntime := result.ModuleForTests(t, "libclang_rt.asan.static", staticVariant)
+ libAsanStaticCxxRuntime := result.ModuleForTests(t, "libclang_rt.asan_cxx.static", staticVariant)
expectSharedLinkDep(t, ctx, binWithAsan, libShared)
expectSharedLinkDep(t, ctx, binWithAsan, libAsan)
@@ -386,15 +386,15 @@
sharedTsanVariant := sharedVariant + "_tsan"
// The binaries, one with tsan and one without
- binWithTsan := result.ModuleForTests("bin_with_tsan", tsanVariant)
- binNoTsan := result.ModuleForTests("bin_no_tsan", variant)
+ binWithTsan := result.ModuleForTests(t, "bin_with_tsan", tsanVariant)
+ binNoTsan := result.ModuleForTests(t, "bin_no_tsan", variant)
// Shared libraries that don't request tsan
- libShared := result.ModuleForTests("libshared", sharedVariant)
- libTransitive := result.ModuleForTests("libtransitive", sharedVariant)
+ libShared := result.ModuleForTests(t, "libshared", sharedVariant)
+ libTransitive := result.ModuleForTests(t, "libtransitive", sharedVariant)
// Shared library that requests tsan
- libTsan := result.ModuleForTests("libtsan", sharedTsanVariant)
+ libTsan := result.ModuleForTests(t, "libtsan", sharedTsanVariant)
expectSharedLinkDep(t, ctx, binWithTsan, libShared)
expectSharedLinkDep(t, ctx, binWithTsan, libTsan)
@@ -479,16 +479,16 @@
staticVariant := variant + "_static"
// The binaries, one with ubsan and one without
- binWithUbsan := result.ModuleForTests("bin_with_ubsan", variant)
- binNoUbsan := result.ModuleForTests("bin_no_ubsan", variant)
+ binWithUbsan := result.ModuleForTests(t, "bin_with_ubsan", variant)
+ binNoUbsan := result.ModuleForTests(t, "bin_no_ubsan", variant)
// Static libraries that don't request ubsan
- libStatic := result.ModuleForTests("libstatic", staticVariant)
- libTransitive := result.ModuleForTests("libtransitive", staticVariant)
+ libStatic := result.ModuleForTests(t, "libstatic", staticVariant)
+ libTransitive := result.ModuleForTests(t, "libtransitive", staticVariant)
- libUbsan := result.ModuleForTests("libubsan", staticVariant)
+ libUbsan := result.ModuleForTests(t, "libubsan", staticVariant)
- libUbsanMinimal := result.ModuleForTests("libclang_rt.ubsan_minimal", staticVariant)
+ libUbsanMinimal := result.ModuleForTests(t, "libclang_rt.ubsan_minimal", staticVariant)
expectStaticLinkDep(t, ctx, binWithUbsan, libStatic)
expectStaticLinkDep(t, ctx, binWithUbsan, libUbsan)
@@ -610,31 +610,31 @@
staticFuzzerVariant := staticVariant + "_fuzzer"
// The binaries, one with fuzzer and one without
- binWithFuzzer := result.ModuleForTests("bin_with_fuzzer", fuzzerVariant)
- binNoFuzzer := result.ModuleForTests("bin_no_fuzzer", variant)
+ binWithFuzzer := result.ModuleForTests(t, "bin_with_fuzzer", fuzzerVariant)
+ binNoFuzzer := result.ModuleForTests(t, "bin_no_fuzzer", variant)
// Shared libraries that don't request fuzzer
- libShared := result.ModuleForTests("libshared", sharedVariant)
- libTransitive := result.ModuleForTests("libtransitive", sharedVariant)
+ libShared := result.ModuleForTests(t, "libshared", sharedVariant)
+ libTransitive := result.ModuleForTests(t, "libtransitive", sharedVariant)
// Shared libraries that don't request fuzzer
- libSharedFuzzer := result.ModuleForTests("libshared", sharedFuzzerVariant)
- libTransitiveFuzzer := result.ModuleForTests("libtransitive", sharedFuzzerVariant)
+ libSharedFuzzer := result.ModuleForTests(t, "libshared", sharedFuzzerVariant)
+ libTransitiveFuzzer := result.ModuleForTests(t, "libtransitive", sharedFuzzerVariant)
// Shared library that requests fuzzer
- libFuzzer := result.ModuleForTests("libfuzzer", sharedFuzzerVariant)
+ libFuzzer := result.ModuleForTests(t, "libfuzzer", sharedFuzzerVariant)
// Static library that uses an fuzzer variant for bin_with_fuzzer and a non-fuzzer variant
// for bin_no_fuzzer.
- libStaticFuzzerVariant := result.ModuleForTests("libstatic", staticFuzzerVariant)
- libStaticNoFuzzerVariant := result.ModuleForTests("libstatic", staticVariant)
+ libStaticFuzzerVariant := result.ModuleForTests(t, "libstatic", staticFuzzerVariant)
+ libStaticNoFuzzerVariant := result.ModuleForTests(t, "libstatic", staticVariant)
// Static library that never uses fuzzer.
- libNoFuzzer := result.ModuleForTests("libnofuzzer", staticVariant)
+ libNoFuzzer := result.ModuleForTests(t, "libnofuzzer", staticVariant)
// Static library that specifies fuzzer
- libStaticFuzzer := result.ModuleForTests("libstatic_fuzzer", staticFuzzerVariant)
- libStaticFuzzerNoFuzzerVariant := result.ModuleForTests("libstatic_fuzzer", staticVariant)
+ libStaticFuzzer := result.ModuleForTests(t, "libstatic_fuzzer", staticFuzzerVariant)
+ libStaticFuzzerNoFuzzerVariant := result.ModuleForTests(t, "libstatic_fuzzer", staticVariant)
expectSharedLinkDep(t, ctx, binWithFuzzer, libSharedFuzzer)
expectSharedLinkDep(t, ctx, binWithFuzzer, libFuzzer)
@@ -781,16 +781,16 @@
staticVariant := variant + "_static"
sharedVariant := variant + "_shared"
- minimalRuntime := result.ModuleForTests("libclang_rt.ubsan_minimal", staticVariant)
- standaloneRuntime := result.ModuleForTests("libclang_rt.ubsan_standalone.static", staticVariant)
+ minimalRuntime := result.ModuleForTests(t, "libclang_rt.ubsan_minimal", staticVariant)
+ standaloneRuntime := result.ModuleForTests(t, "libclang_rt.ubsan_standalone.static", staticVariant)
// The binaries, one with ubsan and one without
- binWithUbsan := result.ModuleForTests("bin_with_ubsan", variant)
- binDependsUbsan := result.ModuleForTests("bin_depends_ubsan_static", variant)
- libSharedUbsan := result.ModuleForTests("libsharedubsan", sharedVariant)
- binDependsUbsanShared := result.ModuleForTests("bin_depends_ubsan_shared", variant)
- binNoUbsan := result.ModuleForTests("bin_no_ubsan", variant)
- staticBin := result.ModuleForTests("static_bin_with_ubsan_dep", variant)
+ binWithUbsan := result.ModuleForTests(t, "bin_with_ubsan", variant)
+ binDependsUbsan := result.ModuleForTests(t, "bin_depends_ubsan_static", variant)
+ libSharedUbsan := result.ModuleForTests(t, "libsharedubsan", sharedVariant)
+ binDependsUbsanShared := result.ModuleForTests(t, "bin_depends_ubsan_shared", variant)
+ binNoUbsan := result.ModuleForTests(t, "bin_no_ubsan", variant)
+ staticBin := result.ModuleForTests(t, "static_bin_with_ubsan_dep", variant)
android.AssertStringListContains(t, "missing libclang_rt.ubsan_minimal in bin_with_ubsan static libs",
strings.Split(binWithUbsan.Rule("ld").Args["libFlags"], " "),
@@ -979,67 +979,67 @@
).RunTest(t)
ctx := result.TestContext
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_no_override", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_async", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_sync", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_override_default_sync", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_no_override", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_async", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_sync", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_override_default_sync", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_no_override", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_disable", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_no_override", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_disable", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_sync", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_override_default_sync", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_no_override", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_disable", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_sync", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_override_default_sync", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_override_default_sync", variant), Sync)
// should sanitize: { diag: { memtag: true } } result in Sync instead of None here?
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_no_override", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_override_default_async", variant), Sync)
// should sanitize: { diag: { memtag: true } } result in Sync instead of None here?
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_no_override", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_override_default_sync", variant), Sync)
}
func TestSanitizeMemtagHeapWithSanitizeDevice(t *testing.T) {
@@ -1055,66 +1055,66 @@
).RunTest(t)
ctx := result.TestContext
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_no_override", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_async", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_sync", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_override_default_sync", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_no_override", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_async", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_sync", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_override_default_sync", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_no_override", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_disable", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_no_override", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_disable", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_sync", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_override_default_sync", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_no_override", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_disable", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_sync", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_override_default_sync", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_override_default_async", variant), Sync)
// should sanitize: { diag: { memtag: true } } result in Sync instead of None here?
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_no_override", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_override_default_sync", variant), Sync)
}
func TestSanitizeMemtagHeapWithSanitizeDeviceDiag(t *testing.T) {
@@ -1131,66 +1131,66 @@
).RunTest(t)
ctx := result.TestContext
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_no_override", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_async", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_sync", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_override_default_sync", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_no_override", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_async", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_sync", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_override_default_sync", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_no_override", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_disable", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_sync", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_override_default_sync", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_no_override", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_disable", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_sync", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_override_default_sync", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_override_default_async", variant), Sync)
// should sanitize: { diag: { memtag: true } } result in Sync instead of None here?
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_override_default_sync", variant), Sync)
}
func TestCfi(t *testing.T) {
@@ -1250,14 +1250,14 @@
cfi_suffix := "_cfi"
static_suffix := "_static"
- sharedWithCfiLib := result.ModuleForTests("shared_with_cfi", buildOs+shared_suffix+cfi_suffix)
- sharedNoCfiLib := result.ModuleForTests("shared_no_cfi", buildOs+shared_suffix)
- staticWithCfiLib := result.ModuleForTests("static_dep_with_cfi", buildOs+static_suffix)
- staticWithCfiLibCfiVariant := result.ModuleForTests("static_dep_with_cfi", buildOs+static_suffix+cfi_suffix)
- staticNoCfiLib := result.ModuleForTests("static_dep_no_cfi", buildOs+static_suffix)
- staticNoCfiLibCfiVariant := result.ModuleForTests("static_dep_no_cfi", buildOs+static_suffix+cfi_suffix)
- sharedRdepNoCfi := result.ModuleForTests("shared_rdep_no_cfi", buildOs+shared_suffix)
- staticDepWithCfi2Lib := result.ModuleForTests("static_dep_with_cfi_2", buildOs+static_suffix)
+ sharedWithCfiLib := result.ModuleForTests(t, "shared_with_cfi", buildOs+shared_suffix+cfi_suffix)
+ sharedNoCfiLib := result.ModuleForTests(t, "shared_no_cfi", buildOs+shared_suffix)
+ staticWithCfiLib := result.ModuleForTests(t, "static_dep_with_cfi", buildOs+static_suffix)
+ staticWithCfiLibCfiVariant := result.ModuleForTests(t, "static_dep_with_cfi", buildOs+static_suffix+cfi_suffix)
+ staticNoCfiLib := result.ModuleForTests(t, "static_dep_no_cfi", buildOs+static_suffix)
+ staticNoCfiLibCfiVariant := result.ModuleForTests(t, "static_dep_no_cfi", buildOs+static_suffix+cfi_suffix)
+ sharedRdepNoCfi := result.ModuleForTests(t, "shared_rdep_no_cfi", buildOs+shared_suffix)
+ staticDepWithCfi2Lib := result.ModuleForTests(t, "static_dep_with_cfi_2", buildOs+static_suffix)
// Confirm assumptions about propagation of CFI enablement
expectStaticLinkDep(t, ctx, sharedWithCfiLib, staticWithCfiLibCfiVariant)
diff --git a/cc/sdk_test.go b/cc/sdk_test.go
index 61925e3..664a7c6 100644
--- a/cc/sdk_test.go
+++ b/cc/sdk_test.go
@@ -81,16 +81,16 @@
ctx := testCc(t, bp)
- libsdkNDK := ctx.ModuleForTests("libsdk", "android_arm64_armv8-a_sdk_shared")
- libsdkPlatform := ctx.ModuleForTests("libsdk", "android_arm64_armv8-a_shared")
- libsdkdepNDK := ctx.ModuleForTests("libsdkdep", "android_arm64_armv8-a_sdk_shared")
- libsdkdepPlatform := ctx.ModuleForTests("libsdkdep", "android_arm64_armv8-a_shared")
- libplatform := ctx.ModuleForTests("libplatform", "android_arm64_armv8-a_shared")
- platformbinary := ctx.ModuleForTests("platformbinary", "android_arm64_armv8-a")
- sdkbinary := ctx.ModuleForTests("sdkbinary", "android_arm64_armv8-a_sdk")
+ libsdkNDK := ctx.ModuleForTests(t, "libsdk", "android_arm64_armv8-a_sdk_shared")
+ libsdkPlatform := ctx.ModuleForTests(t, "libsdk", "android_arm64_armv8-a_shared")
+ libsdkdepNDK := ctx.ModuleForTests(t, "libsdkdep", "android_arm64_armv8-a_sdk_shared")
+ libsdkdepPlatform := ctx.ModuleForTests(t, "libsdkdep", "android_arm64_armv8-a_shared")
+ libplatform := ctx.ModuleForTests(t, "libplatform", "android_arm64_armv8-a_shared")
+ platformbinary := ctx.ModuleForTests(t, "platformbinary", "android_arm64_armv8-a")
+ sdkbinary := ctx.ModuleForTests(t, "sdkbinary", "android_arm64_armv8-a_sdk")
- libcxxNDK := ctx.ModuleForTests("ndk_libc++_shared", "android_arm64_armv8-a_sdk_shared")
- libcxxPlatform := ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared")
+ libcxxNDK := ctx.ModuleForTests(t, "ndk_libc++_shared", "android_arm64_armv8-a_sdk_shared")
+ libcxxPlatform := ctx.ModuleForTests(t, "libc++", "android_arm64_armv8-a_shared")
assertDep(t, libsdkNDK, libsdkdepNDK)
assertDep(t, libsdkPlatform, libsdkdepPlatform)
diff --git a/cc/strip.go b/cc/strip.go
index b1f34bb..a950df8 100644
--- a/cc/strip.go
+++ b/cc/strip.go
@@ -23,10 +23,8 @@
// StripProperties defines the type of stripping applied to the module.
type StripProperties struct {
Strip struct {
- // none forces all stripping to be disabled.
- // Device modules default to stripping enabled leaving mini debuginfo.
- // Host modules default to stripping disabled, but can be enabled by setting any other
- // strip boolean property.
+ // Device and host modules default to stripping enabled leaving mini debuginfo.
+ // This can be disabled by setting none to true.
None *bool `android:"arch_variant"`
// all forces stripping everything, including the mini debug info.
@@ -52,11 +50,7 @@
// NeedsStrip determines if stripping is required for a module.
func (stripper *Stripper) NeedsStrip(actx android.ModuleContext) bool {
forceDisable := Bool(stripper.StripProperties.Strip.None)
- defaultEnable := (!actx.Config().KatiEnabled() || actx.Device())
- forceEnable := Bool(stripper.StripProperties.Strip.All) ||
- Bool(stripper.StripProperties.Strip.Keep_symbols) ||
- Bool(stripper.StripProperties.Strip.Keep_symbols_and_debug_frame)
- return !forceDisable && (forceEnable || defaultEnable)
+ return !forceDisable
}
func (stripper *Stripper) strip(actx android.ModuleContext, in android.Path, out android.ModuleOutPath,
diff --git a/cc/stub_library.go b/cc/stub_library.go
index 75d649f..21ef139 100644
--- a/cc/stub_library.go
+++ b/cc/stub_library.go
@@ -43,9 +43,9 @@
}
// Get target file name to be installed from this module
-func getInstalledFileName(ctx android.SingletonContext, m *Module) string {
+func getInstalledFileName(ctx android.SingletonContext, m android.ModuleProxy) string {
for _, ps := range android.OtherModuleProviderOrDefault(
- ctx, m.Module(), android.InstallFilesProvider).PackagingSpecs {
+ ctx, m, android.InstallFilesProvider).PackagingSpecs {
if name := ps.FileName(); name != "" {
return name
}
@@ -57,18 +57,18 @@
// Visit all generated soong modules and store stub library file names.
stubLibraryMap := make(map[string]bool)
vendorStubLibraryMap := make(map[string]bool)
- ctx.VisitAllModules(func(module android.Module) {
- if m, ok := module.(*Module); ok {
- if IsStubTarget(android.OtherModuleProviderOrDefault(ctx, m, LinkableInfoProvider)) {
- if name := getInstalledFileName(ctx, m); name != "" {
+ ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
+ if linkableInfo, ok := android.OtherModuleProvider(ctx, module, LinkableInfoProvider); ok {
+ if IsStubTarget(linkableInfo) {
+ if name := getInstalledFileName(ctx, module); name != "" {
stubLibraryMap[name] = true
- if m.InVendor() {
+ if linkableInfo.InVendor {
vendorStubLibraryMap[name] = true
}
}
}
- if m.library != nil && android.IsModulePreferred(m) {
- if p := m.library.getAPIListCoverageXMLPath().String(); p != "" {
+ if linkableInfo.CcLibraryInterface && android.IsModulePreferredProxy(ctx, module) {
+ if p := linkableInfo.APIListCoverageXMLPath.String(); p != "" {
s.apiListCoverageXmlPaths = append(s.apiListCoverageXmlPaths, p)
}
}
diff --git a/cc/test.go b/cc/test.go
index abf9162..d2c4b28 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -18,6 +18,7 @@
"path/filepath"
"strconv"
+ "github.com/google/blueprint/depset"
"github.com/google/blueprint/proptools"
"android/soong/android"
@@ -29,8 +30,8 @@
// if set, build against the gtest library. Defaults to true.
Gtest *bool
- // if set, use the isolated gtest runner. Defaults to true if gtest is also true and the arch is Windows, false
- // otherwise.
+ // if set, use the isolated gtest runner. Defaults to false.
+ // Isolation is not supported on Windows.
Isolated *bool
}
@@ -93,6 +94,11 @@
// of a host test.
Device_first_data []string `android:"path_device_first"`
+ // Same as data, but will add dependencies on modules using the host's os variation and
+ // the common arch variation. Useful for a device test that wants to depend on a host
+ // module, for example to include a custom Tradefed test runner.
+ Host_common_data []string `android:"path_host_common"`
+
// list of shared library modules that should be installed alongside the test
Data_libs []string `android:"arch_variant"`
@@ -128,6 +134,13 @@
// Install the test into a folder named for the module in all test suites.
Per_testcase_directory *bool
+
+ // Install the test's dependencies into a folder named standalone-libs relative to the
+ // test's installation path. ld-library-path will be set to this path in the test's
+ // auto-generated config. This way the dependencies can be used by the test without having
+ // to manually install them to the device. See more details in
+ // go/standalone-native-device-tests.
+ Standalone_test *bool
}
func init() {
@@ -198,8 +211,8 @@
return BoolDefault(test.LinkerProperties.Gtest, true)
}
-func (test *testDecorator) isolated(ctx android.EarlyModuleContext) bool {
- return BoolDefault(test.LinkerProperties.Isolated, false)
+func (test *testDecorator) isolated(ctx android.BaseModuleContext) bool {
+ return BoolDefault(test.LinkerProperties.Isolated, false) && !ctx.Windows()
}
// NOTE: Keep this in sync with cc/cc_test.bzl#gtest_copts
@@ -337,6 +350,7 @@
dataSrcPaths := android.PathsForModuleSrc(ctx, test.Properties.Data)
dataSrcPaths = append(dataSrcPaths, android.PathsForModuleSrc(ctx, test.Properties.Device_common_data)...)
dataSrcPaths = append(dataSrcPaths, android.PathsForModuleSrc(ctx, test.Properties.Device_first_data)...)
+ dataSrcPaths = append(dataSrcPaths, android.PathsForModuleSrc(ctx, test.Properties.Host_common_data)...)
for _, dataSrcPath := range dataSrcPaths {
test.data = append(test.data, android.DataPath{SrcPath: dataSrcPath})
@@ -380,6 +394,7 @@
TestInstallBase: testInstallBase,
DeviceTemplate: "${NativeTestConfigTemplate}",
HostTemplate: "${NativeHostTestConfigTemplate}",
+ StandaloneTest: test.Properties.Standalone_test,
})
test.extraTestConfigs = android.PathsForModuleSrc(ctx, test.Properties.Test_options.Extra_test_configs)
@@ -397,8 +412,52 @@
test.Properties.Test_options.Unit_test = proptools.BoolPtr(true)
}
+ if !ctx.Config().KatiEnabled() { // TODO(spandandas): Remove the special case for kati
+ // Install the test config in testcases/ directory for atest.
+ c, ok := ctx.Module().(*Module)
+ if !ok {
+ ctx.ModuleErrorf("Not a cc_test module")
+ }
+ // Install configs in the root of $PRODUCT_OUT/testcases/$module
+ testCases := android.PathForModuleInPartitionInstall(ctx, "testcases", ctx.ModuleName()+c.SubName())
+ if ctx.PrimaryArch() {
+ if test.testConfig != nil {
+ ctx.InstallFile(testCases, ctx.ModuleName()+".config", test.testConfig)
+ }
+ dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml")
+ if dynamicConfig.Valid() {
+ ctx.InstallFile(testCases, ctx.ModuleName()+".dynamic", dynamicConfig.Path())
+ }
+ for _, extraTestConfig := range test.extraTestConfigs {
+ ctx.InstallFile(testCases, extraTestConfig.Base(), extraTestConfig)
+ }
+ }
+ // Install tests and data in arch specific subdir $PRODUCT_OUT/testcases/$module/$arch
+ testCases = testCases.Join(ctx, ctx.Target().Arch.ArchType.String())
+ ctx.InstallTestData(testCases, test.data)
+ ctx.InstallFile(testCases, file.Base(), file)
+ }
+
test.binaryDecorator.baseInstaller.installTestData(ctx, test.data)
test.binaryDecorator.baseInstaller.install(ctx, file)
+ if Bool(test.Properties.Standalone_test) {
+ packagingSpecsBuilder := depset.NewBuilder[android.PackagingSpec](depset.TOPOLOGICAL)
+
+ ctx.VisitDirectDeps(func(dep android.Module) {
+ deps := android.OtherModuleProviderOrDefault(ctx, dep, android.InstallFilesProvider)
+ packagingSpecsBuilder.Transitive(deps.TransitivePackagingSpecs)
+ })
+
+ for _, standaloneTestDep := range packagingSpecsBuilder.Build().ToList() {
+ if standaloneTestDep.ToGob().SrcPath == nil {
+ continue
+ }
+ if standaloneTestDep.SkipInstall() {
+ continue
+ }
+ test.binaryDecorator.baseInstaller.installStandaloneTestDep(ctx, standaloneTestDep)
+ }
+ }
}
func getTestInstallBase(useVendor bool) string {
diff --git a/cc/test_data_test.go b/cc/test_data_test.go
index a621166..2c03ca4 100644
--- a/cc/test_data_test.go
+++ b/cc/test_data_test.go
@@ -132,7 +132,7 @@
_, errs = ctx.PrepareBuildActions(config)
android.FailIfErrored(t, errs)
- foo := ctx.ModuleForTests("foo", "")
+ foo := ctx.ModuleForTests(t, "foo", "")
got := foo.Module().(*testDataTest).data
if len(got) != len(test.data) {
diff --git a/cc/testing.go b/cc/testing.go
index 14a6b7a..69ae11d 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -193,7 +193,7 @@
},
apex_available: [
"//apex_available:platform",
- "myapex"
+ "//apex_available:anyapex",
],
llndk: {
symbol_file: "libm.map.txt",
@@ -253,7 +253,7 @@
},
apex_available: [
"//apex_available:platform",
- "myapex"
+ "//apex_available:anyapex",
],
llndk: {
symbol_file: "libdl.map.txt",
@@ -708,7 +708,7 @@
func checkSnapshotIncludeExclude(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string, include bool, fake bool) {
t.Helper()
- mod := ctx.ModuleForTests(moduleName, variant)
+ mod := ctx.ModuleForTests(t, moduleName, variant)
outputFiles := mod.OutputFiles(ctx, t, "")
if len(outputFiles) != 1 {
t.Errorf("%q must have single output\n", moduleName)
@@ -750,9 +750,10 @@
checkSnapshotIncludeExclude(t, ctx, singleton, moduleName, snapshotFilename, subDir, variant, true, true)
}
-func GetOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
+func GetOutputPaths(t *testing.T, ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
+ t.Helper()
for _, moduleName := range moduleNames {
- module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
+ module := ctx.ModuleForTests(t, moduleName, variant).Module().(*Module)
output := module.outputFile.Path().RelativeToTop()
paths = append(paths, output)
}
diff --git a/cc/tidy_test.go b/cc/tidy_test.go
index 9481778..afc12b8 100644
--- a/cc/tidy_test.go
+++ b/cc/tidy_test.go
@@ -83,7 +83,7 @@
variant := "android_arm64_armv8-a_shared"
ctx := testCc(t, test.bp)
t.Run("caseTidyFlags", func(t *testing.T) {
- flags := ctx.ModuleForTests(test.libName, variant).Rule("clangTidy").Args["tidyFlags"]
+ flags := ctx.ModuleForTests(t, test.libName, variant).Rule("clangTidy").Args["tidyFlags"]
for _, flag := range test.flags {
if !strings.Contains(flags, flag) {
t.Errorf("tidyFlags %v for %s does not contain %s.", flags, test.libName, flag)
@@ -143,7 +143,7 @@
variant := "android_arm64_armv8-a_shared"
for _, test := range testCases {
libName := fmt.Sprintf("libfoo_%d", test.libNumber)
- flags := ctx.ModuleForTests(libName, variant).Rule("clangTidy").Args["tidyFlags"]
+ flags := ctx.ModuleForTests(t, libName, variant).Rule("clangTidy").Args["tidyFlags"]
splitFlags := strings.Split(flags, " ")
foundCheckFlag := false
for _, flag := range splitFlags {
@@ -231,7 +231,7 @@
checkLibraryRule := func(foo, variant, ruleName string) {
libName := fmt.Sprintf("lib%s_%d", foo, n)
tidyFile := "out/soong/.intermediates/" + libName + "/" + variant + "/obj/" + foo + ".tidy"
- depFiles := ctx.ModuleForTests(libName, variant).Rule(ruleName).Validations.Strings()
+ depFiles := ctx.ModuleForTests(t, libName, variant).Rule(ruleName).Validations.Strings()
if test.needTidyFile[n] {
android.AssertStringListContains(t, libName+" needs .tidy file", depFiles, tidyFile)
} else {
@@ -262,7 +262,7 @@
ctx := android.GroupFixturePreparers(prepareForCcTest, android.FixtureMergeEnv(testEnv)).RunTestWithBp(t, bp)
t.Run("tidy should be only run for source code, not for generated code", func(t *testing.T) {
- depFiles := ctx.ModuleForTests("libfoo", variant).Rule("ld").Validations.Strings()
+ depFiles := ctx.ModuleForTests(t, "libfoo", variant).Rule("ld").Validations.Strings()
tidyFileForCpp := "out/soong/.intermediates/libfoo/" + variant + "/obj/foo_src.tidy"
diff --git a/cc/vendor_public_library_test.go b/cc/vendor_public_library_test.go
index 7385f2b..797bb25 100644
--- a/cc/vendor_public_library_test.go
+++ b/cc/vendor_public_library_test.go
@@ -70,32 +70,32 @@
// test if header search paths are correctly added
// _static variant is used since _shared reuses *.o from the static variant
- cc := ctx.ModuleForTests("libsystem", strings.Replace(coreVariant, "_shared", "_static", 1)).Rule("cc")
+ cc := ctx.ModuleForTests(t, "libsystem", strings.Replace(coreVariant, "_shared", "_static", 1)).Rule("cc")
cflags := cc.Args["cFlags"]
if !strings.Contains(cflags, "-Imy_include") {
t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
}
// test if libsystem is linked to the stub
- ld := ctx.ModuleForTests("libsystem", coreVariant).Rule("ld")
+ ld := ctx.ModuleForTests(t, "libsystem", coreVariant).Rule("ld")
libflags := ld.Args["libFlags"]
- stubPaths := GetOutputPaths(ctx, coreVariant, []string{"libvendorpublic"})
+ stubPaths := GetOutputPaths(t, ctx, coreVariant, []string{"libvendorpublic"})
if !strings.Contains(libflags, stubPaths[0].String()) {
t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
}
// test if libsystem is linked to the stub
- ld = ctx.ModuleForTests("libproduct", productVariant).Rule("ld")
+ ld = ctx.ModuleForTests(t, "libproduct", productVariant).Rule("ld")
libflags = ld.Args["libFlags"]
- stubPaths = GetOutputPaths(ctx, productVariant, []string{"libvendorpublic"})
+ stubPaths = GetOutputPaths(t, ctx, productVariant, []string{"libvendorpublic"})
if !strings.Contains(libflags, stubPaths[0].String()) {
t.Errorf("libflags for libproduct must contain %#v, but was %#v", stubPaths[0], libflags)
}
// test if libvendor is linked to the real shared lib
- ld = ctx.ModuleForTests("libvendor", vendorVariant).Rule("ld")
+ ld = ctx.ModuleForTests(t, "libvendor", vendorVariant).Rule("ld")
libflags = ld.Args["libFlags"]
- stubPaths = GetOutputPaths(ctx, vendorVariant, []string{"libvendorpublic"})
+ stubPaths = GetOutputPaths(t, ctx, vendorVariant, []string{"libvendorpublic"})
if !strings.Contains(libflags, stubPaths[0].String()) {
t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
diff --git a/ci_tests/Android.bp b/ci_tests/Android.bp
new file mode 100644
index 0000000..181ded4
--- /dev/null
+++ b/ci_tests/Android.bp
@@ -0,0 +1,21 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+bootstrap_go_package {
+ name: "soong-ci-tests",
+ pkgPath: "android/soong/ci_tests",
+ deps: [
+ "blueprint",
+ "blueprint-proptools",
+ "soong",
+ "soong-android",
+ ],
+ srcs: [
+ "ci_test_package_zip.go",
+ ],
+ testSrcs: [
+ ],
+ pluginFor: ["soong_build"],
+ visibility: ["//visibility:public"],
+}
diff --git a/ci_tests/ci_test_package_zip.go b/ci_tests/ci_test_package_zip.go
new file mode 100644
index 0000000..acfa8e0
--- /dev/null
+++ b/ci_tests/ci_test_package_zip.go
@@ -0,0 +1,241 @@
+// Copyright (C) 2025 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 ci_tests
+
+import (
+ "fmt"
+ "path/filepath"
+ "strings"
+
+ "android/soong/android"
+ "github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
+)
+
+func init() {
+ pctx.Import("android/soong/android")
+ registerTestPackageZipBuildComponents(android.InitRegistrationContext)
+}
+
+func registerTestPackageZipBuildComponents(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("test_package", TestPackageZipFactory)
+}
+
+type testPackageZip struct {
+ android.ModuleBase
+ android.DefaultableModuleBase
+
+ properties CITestPackageProperties
+
+ output android.Path
+}
+
+type CITestPackageProperties struct {
+ // test modules will be added as dependencies using the device os and the common architecture's variant.
+ Tests proptools.Configurable[[]string] `android:"arch_variant"`
+ // test modules that will be added as dependencies based on the first supported arch variant and the device os variant
+ Device_first_tests proptools.Configurable[[]string] `android:"arch_variant"`
+ // test modules that will be added as dependencies based on both 32bit and 64bit arch variant and the device os variant
+ Device_both_tests proptools.Configurable[[]string] `android:"arch_variant"`
+ // test modules that will be added as dependencies based on host
+ Host_tests proptools.Configurable[[]string] `android:"arch_variant"`
+ // git-main only test modules. Will only be added as dependencies using the device os and the common architecture's variant if exists.
+ Tests_if_exist_common proptools.Configurable[[]string] `android:"arch_variant"`
+ // git-main only test modules. Will only be added as dependencies based on both 32bit and 64bit arch variant and the device os variant if exists.
+ Tests_if_exist_device_both proptools.Configurable[[]string] `android:"arch_variant"`
+}
+
+type testPackageZipDepTagType struct {
+ blueprint.BaseDependencyTag
+}
+
+var testPackageZipDepTag testPackageZipDepTagType
+
+var (
+ pctx = android.NewPackageContext("android/soong/ci_tests")
+ // test_package module type should only be used for the following modules.
+ // TODO: remove "_soong" from the module names inside when eliminating the corresponding make modules
+ moduleNamesAllowed = []string{"continuous_native_tests_soong", "continuous_instrumentation_tests_soong", "platform_tests"}
+)
+
+func (p *testPackageZip) DepsMutator(ctx android.BottomUpMutatorContext) {
+ // adding tests property deps
+ for _, t := range p.properties.Tests.GetOrDefault(ctx, nil) {
+ ctx.AddVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), testPackageZipDepTag, t)
+ }
+
+ // adding device_first_tests property deps
+ for _, t := range p.properties.Device_first_tests.GetOrDefault(ctx, nil) {
+ ctx.AddVariationDependencies(ctx.Config().AndroidFirstDeviceTarget.Variations(), testPackageZipDepTag, t)
+ }
+
+ // adding device_both_tests property deps
+ p.addDeviceBothDeps(ctx, false)
+
+ // adding host_tests property deps
+ for _, t := range p.properties.Host_tests.GetOrDefault(ctx, nil) {
+ ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), testPackageZipDepTag, t)
+ }
+
+ // adding Tests_if_exist_* property deps
+ for _, t := range p.properties.Tests_if_exist_common.GetOrDefault(ctx, nil) {
+ if ctx.OtherModuleExists(t) {
+ ctx.AddVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), testPackageZipDepTag, t)
+ }
+ }
+ p.addDeviceBothDeps(ctx, true)
+}
+
+func (p *testPackageZip) addDeviceBothDeps(ctx android.BottomUpMutatorContext, checkIfExist bool) {
+ android32TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib32")
+ android64TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib64")
+ if len(android32TargetList) > 0 {
+ maybeAndroid32Target := &android32TargetList[0]
+ if checkIfExist {
+ for _, t := range p.properties.Tests_if_exist_device_both.GetOrDefault(ctx, nil) {
+ if ctx.OtherModuleExists(t) {
+ ctx.AddFarVariationDependencies(maybeAndroid32Target.Variations(), testPackageZipDepTag, t)
+ }
+ }
+ } else {
+ ctx.AddFarVariationDependencies(maybeAndroid32Target.Variations(), testPackageZipDepTag, p.properties.Device_both_tests.GetOrDefault(ctx, nil)...)
+ }
+ }
+ if len(android64TargetList) > 0 {
+ maybeAndroid64Target := &android64TargetList[0]
+ if checkIfExist {
+ for _, t := range p.properties.Tests_if_exist_device_both.GetOrDefault(ctx, nil) {
+ if ctx.OtherModuleExists(t) {
+ ctx.AddFarVariationDependencies(maybeAndroid64Target.Variations(), testPackageZipDepTag, t)
+ }
+ }
+ } else {
+ ctx.AddFarVariationDependencies(maybeAndroid64Target.Variations(), testPackageZipDepTag, p.properties.Device_both_tests.GetOrDefault(ctx, nil)...)
+ }
+ }
+}
+
+func TestPackageZipFactory() android.Module {
+ module := &testPackageZip{}
+
+ module.AddProperties(&module.properties)
+
+ android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
+ android.InitDefaultableModule(module)
+
+ return module
+}
+
+func (p *testPackageZip) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ if !android.InList(ctx.ModuleName(), moduleNamesAllowed) {
+ ctx.ModuleErrorf("%s is not allowed to use module type test_package")
+ }
+
+ p.output = createOutput(ctx, pctx)
+
+ ctx.SetOutputFiles(android.Paths{p.output}, "")
+
+ // dist the test output
+ if ctx.ModuleName() == "platform_tests_soong" {
+ distedName := ctx.Config().Getenv("TARGET_PRODUCT") + "-tests-" + ctx.Config().BuildId() + ".zip"
+ ctx.DistForGoalsWithFilename([]string{"droid", "platform_tests"}, p.output, distedName)
+ }
+}
+
+func createOutput(ctx android.ModuleContext, pctx android.PackageContext) android.ModuleOutPath {
+ productOut := filepath.Join(ctx.Config().OutDir(), "target", "product", ctx.Config().DeviceName())
+ stagingDir := android.PathForModuleOut(ctx, "STAGING")
+ productVariables := ctx.Config().ProductVariables()
+ arch := proptools.String(productVariables.DeviceArch)
+ secondArch := proptools.String(productVariables.DeviceSecondaryArch)
+
+ builder := android.NewRuleBuilder(pctx, ctx)
+ builder.Command().Text("rm").Flag("-rf").Text(stagingDir.String())
+ builder.Command().Text("mkdir").Flag("-p").Output(stagingDir)
+ builder.Temporary(stagingDir)
+ ctx.VisitDirectDepsWithTag(testPackageZipDepTag, func(m android.Module) {
+ info, ok := android.OtherModuleProvider(ctx, m, android.ModuleInfoJSONProvider)
+ if !ok {
+ ctx.OtherModuleErrorf(m, "doesn't set ModuleInfoJSON provider")
+ } else if len(info) != 1 {
+ ctx.OtherModuleErrorf(m, "doesn't provide exactly one ModuleInfoJSON")
+ }
+
+ classes := info[0].GetClass()
+ if len(info[0].Class) != 1 {
+ ctx.OtherModuleErrorf(m, "doesn't have exactly one class in its ModuleInfoJSON")
+ }
+ class := strings.ToLower(classes[0])
+ if class == "apps" {
+ class = "app"
+ } else if class == "java_libraries" {
+ class = "framework"
+ }
+
+ installedFilesInfo, ok := android.OtherModuleProvider(ctx, m, android.InstallFilesProvider)
+ if !ok {
+ ctx.ModuleErrorf("Module %s doesn't set InstallFilesProvider", m.Name())
+ }
+
+ for _, installedFile := range installedFilesInfo.InstallFiles {
+ // there are additional installed files for some app-class modules, we only need the .apk files in the test package
+ if class == "app" && installedFile.Ext() != ".apk" {
+ continue
+ }
+ name := removeFileExtension(installedFile.Base())
+ f := strings.TrimPrefix(installedFile.String(), productOut+"/")
+ if strings.HasPrefix(f, "out") {
+ continue
+ }
+ f = strings.ReplaceAll(f, "system/", "DATA/")
+ f = strings.ReplaceAll(f, filepath.Join("testcases", name, arch), filepath.Join("DATA", class, name))
+ f = strings.ReplaceAll(f, filepath.Join("testcases", name, secondArch), filepath.Join("DATA", class, name))
+ f = strings.ReplaceAll(f, "testcases", filepath.Join("DATA", class))
+ f = strings.ReplaceAll(f, "data/", "DATA/")
+ f = strings.ReplaceAll(f, "DATA_other", "system_other")
+ f = strings.ReplaceAll(f, "system_other/DATA", "system_other/system")
+ dir := filepath.Dir(f)
+ tempOut := android.PathForModuleOut(ctx, "STAGING", f)
+ builder.Command().Text("mkdir").Flag("-p").Text(filepath.Join(stagingDir.String(), dir))
+ builder.Command().Text("cp").Flag("-Rf").Input(installedFile).Output(tempOut)
+ builder.Temporary(tempOut)
+ }
+ })
+
+ output := android.PathForModuleOut(ctx, ctx.ModuleName()+".zip")
+ builder.Command().
+ BuiltTool("soong_zip").
+ Flag("-o").Output(output).
+ Flag("-C").Text(stagingDir.String()).
+ Flag("-D").Text(stagingDir.String())
+ builder.Command().Text("rm").Flag("-rf").Text(stagingDir.String())
+ builder.Build("test_package", fmt.Sprintf("build test_package for %s", ctx.ModuleName()))
+ return output
+}
+
+func removeFileExtension(filename string) string {
+ return strings.TrimSuffix(filename, filepath.Ext(filename))
+}
+
+// The only purpose of this method is to make sure we can build the module directly
+// without adding suffix "-soong"
+func (p *testPackageZip) AndroidMkEntries() []android.AndroidMkEntries {
+ return []android.AndroidMkEntries{
+ android.AndroidMkEntries{
+ Class: "ETC",
+ OutputFile: android.OptionalPathForPath(p.output),
+ },
+ }
+}
diff --git a/cmd/javac_wrapper/javac_wrapper.go b/cmd/javac_wrapper/javac_wrapper.go
index 4679906..49bcedf 100644
--- a/cmd/javac_wrapper/javac_wrapper.go
+++ b/cmd/javac_wrapper/javac_wrapper.go
@@ -200,6 +200,9 @@
var warningFilters = []*regexp.Regexp{
regexp.MustCompile(`bootstrap class path not set in conjunction with -source`),
+ regexp.MustCompile(`source value 8 is obsolete and will be removed in a future release`),
+ regexp.MustCompile(`target value 8 is obsolete and will be removed in a future release`),
+ regexp.MustCompile(`To suppress warnings about obsolete options, use -Xlint:-options.`),
}
var filters = []*regexp.Regexp{
diff --git a/cmd/javac_wrapper/javac_wrapper_test.go b/cmd/javac_wrapper/javac_wrapper_test.go
index ad23001..5e26786 100644
--- a/cmd/javac_wrapper/javac_wrapper_test.go
+++ b/cmd/javac_wrapper/javac_wrapper_test.go
@@ -90,6 +90,15 @@
`,
out: "\n\x1b[1m\x1b[35mwarning:\x1b[0m\x1b[1m foo\x1b[0m\n1 warning\n",
},
+ {
+ in: `
+warning: [options] source value 8 is obsolete and will be removed in a future release
+warning: [options] target value 8 is obsolete and will be removed in a future release
+warning: [options] To suppress warnings about obsolete options, use -Xlint:-options.
+3 warnings
+`,
+ out: "\n",
+ },
}
func TestJavacColorize(t *testing.T) {
diff --git a/cmd/kotlinc_incremental/Android.bp b/cmd/kotlinc_incremental/Android.bp
new file mode 100644
index 0000000..7816553
--- /dev/null
+++ b/cmd/kotlinc_incremental/Android.bp
@@ -0,0 +1,65 @@
+//
+// Copyright (C) 2025 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 {
+ default_team: "trendy_team_system_ui_please_use_a_more_specific_subteam_if_possible_",
+ default_applicable_licenses: [
+ "Android-Apache-2.0",
+ "Kotlin_Incremental_license",
+ ],
+}
+
+license {
+ name: "Kotlin_Incremental_license",
+ visibility: [":__subpackages__"],
+ license_kinds: ["legacy_proprietary"],
+}
+
+java_library_host {
+ name: "kotlin-incremental-client-lib",
+ srcs: [
+ "src/com/**/*.kt",
+ ],
+ static_libs: [
+ "kotlin-compiler-embeddable",
+ "kotlin-compiler-runner",
+ "kotlin-daemon-client",
+ ],
+
+ plugins: [],
+
+ kotlincflags: [
+ "-Werror",
+ ],
+}
+
+java_binary_host {
+ name: "kotlin-incremental-client",
+ manifest: "kotlin-incremental-client.mf",
+ static_libs: ["kotlin-incremental-client-lib"],
+}
+
+java_test_host {
+ name: "kotlin-incremental-client-tests",
+ srcs: [
+ "tests/src/com/**/*.kt",
+ ],
+ static_libs: [
+ "kotlin-incremental-client-lib",
+ "junit",
+ "truth",
+ ],
+}
diff --git a/cmd/kotlinc_incremental/kotlin-incremental-client.mf b/cmd/kotlinc_incremental/kotlin-incremental-client.mf
new file mode 100644
index 0000000..b84c86a
--- /dev/null
+++ b/cmd/kotlinc_incremental/kotlin-incremental-client.mf
@@ -0,0 +1 @@
+Main-Class: com.android.kotlin.compiler.client.MainKt
diff --git a/cmd/kotlinc_incremental/src/com/android/kotlin/compiler/client/Main.kt b/cmd/kotlinc_incremental/src/com/android/kotlin/compiler/client/Main.kt
new file mode 100644
index 0000000..4938641
--- /dev/null
+++ b/cmd/kotlinc_incremental/src/com/android/kotlin/compiler/client/Main.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2025 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 com.android.kotlin.compiler.client
+
+fun main(args: Array<String>) {
+ println("compiling")
+}
diff --git a/cmd/kotlinc_incremental/tests/src/com/android/kotlin/compiler/client/MainTest.kt b/cmd/kotlinc_incremental/tests/src/com/android/kotlin/compiler/client/MainTest.kt
new file mode 100644
index 0000000..3354aa4
--- /dev/null
+++ b/cmd/kotlinc_incremental/tests/src/com/android/kotlin/compiler/client/MainTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2025 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 com.android.kotlin.compiler.client
+
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+
+class MainTest {
+ @Test
+ fun testMain() {
+ assertThat(true).isTrue()
+ }
+}
\ No newline at end of file
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 7926292..4f6de82 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -338,7 +338,7 @@
ctx.Fatal(err)
}
- fmt.Println(build.Banner(varData))
+ fmt.Println(build.Banner(config, varData))
} else {
varData, err := build.DumpMakeVars(ctx, config, nil, []string{varName})
if err != nil {
@@ -414,7 +414,7 @@
for _, name := range vars {
if name == "report_config" {
- fmt.Printf("%sreport_config='%s'\n", *varPrefix, build.Banner(varData))
+ fmt.Printf("%sreport_config='%s'\n", *varPrefix, build.Banner(config, varData))
} else {
fmt.Printf("%s%s='%s'\n", *varPrefix, name, varData[name])
}
@@ -471,20 +471,6 @@
description: "Build action: build from the top of the source tree.",
action: build.BUILD_MODULES,
}, {
- // This is redirecting to mma build command behaviour. Once it has soaked for a
- // while, the build command is deleted from here once it has been removed from the
- // envsetup.sh.
- name: "modules-in-a-dir-no-deps",
- description: "Build action: builds all of the modules in the current directory without their dependencies.",
- action: build.BUILD_MODULES_IN_A_DIRECTORY,
- }, {
- // This is redirecting to mmma build command behaviour. Once it has soaked for a
- // while, the build command is deleted from here once it has been removed from the
- // envsetup.sh.
- name: "modules-in-dirs-no-deps",
- description: "Build action: builds all of the modules in the supplied directories without their dependencies.",
- action: build.BUILD_MODULES_IN_DIRECTORIES,
- }, {
name: "modules-in-a-dir",
description: "Build action: builds all of the modules in the current directory and their dependencies.",
action: build.BUILD_MODULES_IN_A_DIRECTORY,
diff --git a/cmd/symbols_map/symbols_map.go b/cmd/symbols_map/symbols_map.go
index c56cf93..3955c8a 100644
--- a/cmd/symbols_map/symbols_map.go
+++ b/cmd/symbols_map/symbols_map.go
@@ -72,6 +72,7 @@
elfFile := flags.String("elf", "", "extract identifier from an elf file")
r8File := flags.String("r8", "", "extract identifier from an r8 dictionary")
+ locationFlag := flags.String("location", "", "an override for the value of the location field in the proto. If not specified, the filename will be used")
merge := flags.String("merge", "", "merge multiple identifier protos")
writeIfChanged := flags.Bool("write_if_changed", false, "only write output file if it is modified")
@@ -134,6 +135,10 @@
panic("shouldn't get here")
}
+ if *locationFlag != "" {
+ location = *locationFlag
+ }
+
mapping := symbols_map_proto.Mapping{
Identifier: proto.String(identifier),
Location: proto.String(location),
diff --git a/compliance/Android.bp b/compliance/Android.bp
index 6662970..25f6f86 100644
--- a/compliance/Android.bp
+++ b/compliance/Android.bp
@@ -34,7 +34,41 @@
name: "notice_xml_system",
partition_name: "system",
visibility: [
- "//build/make/target/product/generic",
- "//build/make/target/product/gsi",
+ "//visibility:any_system_partition",
],
}
+
+notice_xml {
+ name: "notice_xml_system_ext",
+ partition_name: "system_ext",
+}
+
+notice_xml {
+ name: "notice_xml_system_dlkm",
+ partition_name: "system_dlkm",
+}
+
+notice_xml {
+ name: "notice_xml_product",
+ partition_name: "product",
+}
+
+notice_xml {
+ name: "notice_xml_odm",
+ partition_name: "odm",
+}
+
+notice_xml {
+ name: "notice_xml_odm_dlkm",
+ partition_name: "odm_dlkm",
+}
+
+notice_xml {
+ name: "notice_xml_vendor",
+ partition_name: "vendor",
+}
+
+notice_xml {
+ name: "notice_xml_vendor_dlkm",
+ partition_name: "vendor_dlkm",
+}
diff --git a/compliance/notice.go b/compliance/notice.go
index edd1b34..c5b0fbe 100644
--- a/compliance/notice.go
+++ b/compliance/notice.go
@@ -71,12 +71,17 @@
}
func (nx *NoticeXmlModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ prodVars := ctx.Config().ProductVariables()
+ buildFingerprintFile := android.PathForArbitraryOutput(ctx, "target", "product", android.String(prodVars.DeviceName), "build_fingerprint.txt")
+ implicits := []android.Path{buildFingerprintFile}
+
output := android.PathForModuleOut(ctx, "NOTICE.xml.gz")
metadataDb := android.PathForOutput(ctx, "compliance-metadata", ctx.Config().DeviceProduct(), "compliance-metadata.db")
ctx.Build(pctx, android.BuildParams{
- Rule: genNoticeXmlRule,
- Input: metadataDb,
- Output: output,
+ Rule: genNoticeXmlRule,
+ Input: metadataDb,
+ Implicits: implicits,
+ Output: output,
Args: map[string]string{
"productOut": filepath.Join(ctx.Config().OutDir(), "target", "product", ctx.Config().DeviceName()),
"soongOut": ctx.Config().SoongOutDir(),
@@ -86,8 +91,10 @@
nx.outputFile = output.OutputPath
- installPath := android.PathForModuleInPartitionInstall(ctx, nx.props.Partition_name, "etc")
- ctx.PackageFile(installPath, "NOTICE.xml.gz", nx.outputFile)
+ if android.Bool(ctx.Config().ProductVariables().UseSoongNoticeXML) {
+ installPath := android.PathForModuleInPartitionInstall(ctx, nx.props.Partition_name, "etc")
+ ctx.InstallFile(installPath, "NOTICE.xml.gz", nx.outputFile)
+ }
}
func (nx *NoticeXmlModule) AndroidMkEntries() []android.AndroidMkEntries {
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index ee23b51..c5cafb1 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -507,36 +507,37 @@
// final variants, while prebuilt_postdeps needs to run before many of the
// PostDeps mutators, like the APEX mutators). Hence we need to dig out the
// prebuilt explicitly here instead.
- var dex2oatModule android.Module
- ctx.WalkDeps(func(child, parent android.Module) bool {
- if parent == ctx.Module() && ctx.OtherModuleDependencyTag(child) == Dex2oatDepTag {
+ var dex2oatModule android.ModuleProxy
+ ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
+ prebuiltInfo, isPrebuilt := android.OtherModuleProvider(ctx, child, android.PrebuiltModuleInfoProvider)
+ if ctx.EqualModules(parent, ctx.Module()) && ctx.OtherModuleDependencyTag(child) == Dex2oatDepTag {
// Found the source module, or prebuilt module that has replaced the source.
dex2oatModule = child
- if android.IsModulePrebuilt(child) {
+ if isPrebuilt {
return false // If it's the prebuilt we're done.
} else {
return true // Recurse to check if the source has a prebuilt dependency.
}
}
- if parent == dex2oatModule && ctx.OtherModuleDependencyTag(child) == android.PrebuiltDepTag {
- if p := android.GetEmbeddedPrebuilt(child); p != nil && p.UsePrebuilt() {
+ if ctx.EqualModules(parent, dex2oatModule) && ctx.OtherModuleDependencyTag(child) == android.PrebuiltDepTag {
+ if isPrebuilt && prebuiltInfo.UsePrebuilt {
dex2oatModule = child // Found a prebuilt that should be used.
}
}
return false
})
- if dex2oatModule == nil {
+ if dex2oatModule.IsNil() {
// If this happens there's probably a missing call to AddToolDeps in DepsMutator.
panic(fmt.Sprintf("Failed to lookup %s dependency", dex2oatBin))
}
- dex2oatPath := dex2oatModule.(android.HostToolProvider).HostToolPath()
- if !dex2oatPath.Valid() {
+ dex2oatPath, ok := android.OtherModuleProvider(ctx, dex2oatModule, android.HostToolProviderInfoProvider)
+ if !ok || !dex2oatPath.HostToolPath.Valid() {
panic(fmt.Sprintf("Failed to find host tool path in %s", dex2oatModule))
}
- return dex2oatPath.Path()
+ return dex2oatPath.HostToolPath.Path()
}
// createGlobalSoongConfig creates a GlobalSoongConfig from the current context.
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 7a39fa1..699a675 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -46,13 +46,14 @@
const SystemPartition = "/system/"
const SystemOtherPartition = "/system_other/"
+const SystemServerDexjarsDir = "system_server_dexjars"
var DexpreoptRunningInSoong = false
// GenerateDexpreoptRule generates a set of commands that will preopt a module based on a GlobalConfig and a
// ModuleConfig. The produced files and their install locations will be available through rule.Installs().
func GenerateDexpreoptRule(ctx android.BuilderContext, globalSoong *GlobalSoongConfig,
- global *GlobalConfig, module *ModuleConfig, productPackages android.Path, copyApexSystemServerJarDex bool) (
+ global *GlobalConfig, module *ModuleConfig, productPackages android.Path) (
rule *android.RuleBuilder, err error) {
defer func() {
@@ -83,7 +84,7 @@
if !dexpreoptDisabled(ctx, global, module) {
if valid, err := validateClassLoaderContext(module.ClassLoaderContexts); err != nil {
- android.ReportPathErrorf(ctx, err.Error())
+ android.ReportPathErrorf(ctx, "%s", err.Error())
} else if valid {
fixClassLoaderContext(module.ClassLoaderContexts)
@@ -94,7 +95,7 @@
for archIdx, _ := range module.Archs {
dexpreoptCommand(ctx, globalSoong, global, module, rule, archIdx, profile, appImage,
- generateDM, productPackages, copyApexSystemServerJarDex)
+ generateDM, productPackages)
}
}
}
@@ -231,7 +232,7 @@
func dexpreoptCommand(ctx android.BuilderContext, globalSoong *GlobalSoongConfig,
global *GlobalConfig, module *ModuleConfig, rule *android.RuleBuilder, archIdx int,
- profile android.WritablePath, appImage bool, generateDM bool, productPackages android.Path, copyApexSystemServerJarDex bool) {
+ profile android.WritablePath, appImage bool, generateDM bool, productPackages android.Path) {
arch := module.Archs[archIdx]
@@ -279,25 +280,10 @@
clcTarget = append(clcTarget, GetSystemServerDexLocation(ctx, global, lib))
}
- if DexpreoptRunningInSoong && copyApexSystemServerJarDex {
- // Copy the system server jar to a predefined location where dex2oat will find it.
- dexPathHost := SystemServerDexJarHostPath(ctx, module.Name)
- rule.Command().Text("mkdir -p").Flag(filepath.Dir(dexPathHost.String()))
- rule.Command().Text("cp -f").Input(module.DexPath).Output(dexPathHost)
- } else {
- // For Make modules the copy rule is generated in the makefiles, not in dexpreopt.sh.
- // This is necessary to expose the rule to Ninja, otherwise it has rules that depend on
- // the jar (namely, dexpreopt commands for all subsequent system server jars that have
- // this one in their class loader context), but no rule that creates it (because Ninja
- // cannot see the rule in the generated dexpreopt.sh script).
- }
-
clcHostString := "PCL[" + strings.Join(clcHost.Strings(), ":") + "]"
clcTargetString := "PCL[" + strings.Join(clcTarget, ":") + "]"
- if systemServerClasspathJars.ContainsJar(module.Name) {
- checkSystemServerOrder(ctx, jarIndex)
- } else {
+ if !systemServerClasspathJars.ContainsJar(module.Name) {
// Standalone jars are loaded by separate class loaders with SYSTEMSERVERCLASSPATH as the
// parent.
clcHostString = "PCL[];" + clcHostString
@@ -581,34 +567,11 @@
func SystemServerDexJarHostPath(ctx android.PathContext, jar string) android.OutputPath {
if DexpreoptRunningInSoong {
// Soong module, just use the default output directory $OUT/soong.
- return android.PathForOutput(ctx, "system_server_dexjars", jar+".jar")
+ return android.PathForOutput(ctx, SystemServerDexjarsDir, jar+".jar")
} else {
// Make module, default output directory is $OUT (passed via the "null config" created
// by dexpreopt_gen). Append Soong subdirectory to match Soong module paths.
- return android.PathForOutput(ctx, "soong", "system_server_dexjars", jar+".jar")
- }
-}
-
-// Check the order of jars on the system server classpath and give a warning/error if a jar precedes
-// one of its dependencies. This is not an error, but a missed optimization, as dexpreopt won't
-// have the dependency jar in the class loader context, and it won't be able to resolve any
-// references to its classes and methods.
-func checkSystemServerOrder(ctx android.PathContext, jarIndex int) {
- mctx, isModule := ctx.(android.ModuleContext)
- if isModule {
- config := GetGlobalConfig(ctx)
- jars := config.AllSystemServerClasspathJars(ctx)
- mctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
- depIndex := jars.IndexOfJar(dep.Name())
- if jarIndex < depIndex && !config.BrokenSuboptimalOrderOfSystemServerJars {
- jar := jars.Jar(jarIndex)
- dep := jars.Jar(depIndex)
- mctx.ModuleErrorf("non-optimal order of jars on the system server classpath:"+
- " '%s' precedes its dependency '%s', so dexpreopt is unable to resolve any"+
- " references from '%s' to '%s'.\n", jar, dep, jar, dep)
- }
- return true
- })
+ return android.PathForOutput(ctx, "soong", SystemServerDexjarsDir, jar+".jar")
}
}
diff --git a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
index 7512005..8033b48 100644
--- a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
+++ b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
@@ -205,9 +205,8 @@
panic(err)
}
}
- cpApexSscpServerJar := false // dexpreopt_gen operates on make modules, and since sscp libraries are in soong, this should be a noop
dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(
- ctx, globalSoong, global, module, android.PathForTesting(productPackagesPath), cpApexSscpServerJar)
+ ctx, globalSoong, global, module, android.PathForTesting(productPackagesPath))
if err != nil {
panic(err)
}
diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go
index 1f188d5..500b2ff 100644
--- a/dexpreopt/dexpreopt_test.go
+++ b/dexpreopt/dexpreopt_test.go
@@ -104,7 +104,7 @@
module := testSystemModuleConfig(ctx, "test")
productPackages := android.PathForTesting("product_packages.txt")
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
if err != nil {
t.Fatal(err)
}
@@ -164,7 +164,7 @@
for _, test := range tests {
global.PatternsOnSystemOther = test.patterns
for _, mt := range test.moduleTests {
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, mt.module, productPackages, true)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, mt.module, productPackages)
if err != nil {
t.Fatal(err)
}
@@ -199,7 +199,7 @@
global.ApexSystemServerJars = android.CreateTestConfiguredJarList(
[]string{"com.android.apex1:service-A"})
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
if err != nil {
t.Fatal(err)
}
@@ -211,15 +211,6 @@
android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String())
- android.AssertStringListContains(t, "apex sscp jar copy", rule.Outputs().Strings(), "out/soong/system_server_dexjars/service-A.jar")
-
- // rule with apex sscp cp as false
- rule, err = GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, false)
- if err != nil {
- t.Fatal(err)
- }
- android.AssertStringListDoesNotContain(t, "apex sscp jar copy", rule.Outputs().Strings(), "out/soong/system_server_dexjars/service-A.jar")
-
// cleanup the global variable for test
DexpreoptRunningInSoong = oldDexpreoptRunningInSoong
}
@@ -242,7 +233,7 @@
global.ApexSystemServerJars = android.CreateTestConfiguredJarList(
[]string{"com.android.apex1:service-A"})
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
if err != nil {
t.Fatal(err)
}
@@ -254,15 +245,6 @@
android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String())
- android.AssertStringListContains(t, "apex sscp jar copy", rule.Outputs().Strings(), "out/soong/system_server_dexjars/service-A.jar")
-
- // rule with apex sscp cp as false
- rule, err = GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, false)
- if err != nil {
- t.Fatal(err)
- }
- android.AssertStringListDoesNotContain(t, "apex sscp jar copy", rule.Outputs().Strings(), "out/soong/system_server_dexjars/service-A.jar")
-
// cleanup the global variable for test
DexpreoptRunningInSoong = oldDexpreoptRunningInSoong
}
@@ -278,7 +260,7 @@
global.StandaloneSystemServerJars = android.CreateTestConfiguredJarList(
[]string{"platform:service-A"})
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
if err != nil {
t.Fatal(err)
}
@@ -302,7 +284,7 @@
global.StandaloneSystemServerJars = android.CreateTestConfiguredJarList(
[]string{"system_ext:service-A"})
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
if err != nil {
t.Fatal(err)
}
@@ -326,7 +308,7 @@
global.ApexStandaloneSystemServerJars = android.CreateTestConfiguredJarList(
[]string{"com.android.apex1:service-A"})
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
if err != nil {
t.Fatal(err)
}
@@ -349,7 +331,7 @@
module.ProfileClassListing = android.OptionalPathForPath(android.PathForTesting("profile"))
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
if err != nil {
t.Fatal(err)
}
@@ -395,7 +377,7 @@
result := preparers.RunTest(t)
ctx := result.TestContext
- ctx.SingletonForTests("dexpreopt-soong-config").Output("out/soong/dexpreopt/uffd_gc_flag.txt")
+ ctx.SingletonForTests(t, "dexpreopt-soong-config").Output("out/soong/dexpreopt/uffd_gc_flag.txt")
})
}
}
@@ -412,7 +394,7 @@
ctx := result.TestContext
config := ctx.Config()
- rule := ctx.SingletonForTests("dexpreopt-soong-config").Rule("dexpreopt_uffd_gc_flag")
+ rule := ctx.SingletonForTests(t, "dexpreopt-soong-config").Rule("dexpreopt_uffd_gc_flag")
android.AssertStringDoesContain(t, "", rule.RuleParams.Command, "construct_uffd_gc_flag")
android.AssertStringPathsRelativeToTopEquals(t, "", config, []string{
diff --git a/etc/install_symlink_test.go b/etc/install_symlink_test.go
index c97d97c..dce6873 100644
--- a/etc/install_symlink_test.go
+++ b/etc/install_symlink_test.go
@@ -39,7 +39,7 @@
t.Fatalf("expected 1 variant, got %#v", foo_variants)
}
- foo := result.ModuleForTests("foo", "android_common").Module()
+ foo := result.ModuleForTests(t, "foo", "android_common").Module()
androidMkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, foo)
if len(androidMkEntries) != 1 {
t.Fatalf("expected 1 androidmkentry, got %d", len(androidMkEntries))
@@ -70,7 +70,7 @@
t.Fatalf("expected 1 variant, got %#v", foo_variants)
}
- foo := result.ModuleForTests("foo", "android_common").Module()
+ foo := result.ModuleForTests(t, "foo", "android_common").Module()
androidMkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, foo)
if len(androidMkEntries) != 1 {
t.Fatalf("expected 1 androidmkentry, got %d", len(androidMkEntries))
@@ -149,7 +149,7 @@
`)
buildOS := result.Config.BuildOS.String()
- foo := result.ModuleForTests("foo", buildOS+"_common").Module()
+ foo := result.ModuleForTests(t, "foo", buildOS+"_common").Module()
androidMkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, foo)
if len(androidMkEntries) != 1 {
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 2bcbde1..a440c91 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -32,6 +32,7 @@
"path/filepath"
"strings"
+ "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
"android/soong/android"
@@ -90,6 +91,15 @@
}
+type PrebuiltEtcInfo struct {
+ // Returns the base install directory, such as "etc", "usr/share".
+ BaseDir string
+ // Returns the sub install directory relative to BaseDir().
+ SubDir string
+}
+
+var PrebuiltEtcInfoProvider = blueprint.NewProvider[PrebuiltEtcInfo]()
+
var PrepareForTestWithPrebuiltEtc = android.FixtureRegisterWithContext(RegisterPrebuiltEtcBuildComponents)
type PrebuiltEtcProperties struct {
@@ -499,7 +509,28 @@
ip.addInstallRules(ctx)
}
+ p.updateModuleInfoJSON(ctx)
+
ctx.SetOutputFiles(p.outputFilePaths.Paths(), "")
+
+ SetCommonPrebuiltEtcInfo(ctx, p)
+}
+
+func SetCommonPrebuiltEtcInfo(ctx android.ModuleContext, p PrebuiltEtcModule) {
+ android.SetProvider(ctx, PrebuiltEtcInfoProvider, PrebuiltEtcInfo{
+ BaseDir: p.BaseDir(),
+ SubDir: p.SubDir(),
+ })
+}
+
+func (p *PrebuiltEtc) updateModuleInfoJSON(ctx android.ModuleContext) {
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Class = []string{"ETC"}
+ if p.makeClass != "" {
+ moduleInfoJSON.Class = []string{p.makeClass}
+ }
+ moduleInfoJSON.SystemSharedLibs = []string{"none"}
+ moduleInfoJSON.Tags = []string{"optional"}
}
type installProperties struct {
diff --git a/etc/prebuilt_etc_test.go b/etc/prebuilt_etc_test.go
index 70b5462..eb722b4 100644
--- a/etc/prebuilt_etc_test.go
+++ b/etc/prebuilt_etc_test.go
@@ -324,7 +324,7 @@
`)
android.AssertStringEquals(t, "expected error rule", "android/soong/android.Error",
- result.ModuleForTests("foo.conf", "android_arm64_armv8-a").Output("foo.conf").Rule.String())
+ result.ModuleForTests(t, "foo.conf", "android_arm64_armv8-a").Output("foo.conf").Rule.String())
}
func TestPrebuiltRootInstallDirPath(t *testing.T) {
diff --git a/filesystem/Android.bp b/filesystem/Android.bp
index 127faa7..cb76df2 100644
--- a/filesystem/Android.bp
+++ b/filesystem/Android.bp
@@ -17,6 +17,7 @@
srcs: [
"aconfig_files.go",
"android_device.go",
+ "android_device_product_out.go",
"avb_add_hash_footer.go",
"avb_gen_vbmeta_image.go",
"bootimg.go",
@@ -27,6 +28,7 @@
"raw_binary.go",
"super_image.go",
"system_image.go",
+ "system_other.go",
"vbmeta.go",
"testing.go",
],
diff --git a/filesystem/aconfig_files.go b/filesystem/aconfig_files.go
index 9a3ca54..b4173d7 100644
--- a/filesystem/aconfig_files.go
+++ b/filesystem/aconfig_files.go
@@ -22,6 +22,17 @@
"github.com/google/blueprint/proptools"
)
+func init() {
+ pctx.HostBinToolVariable("aconfig", "aconfig")
+}
+
+var (
+ aconfigCreateStorage = pctx.AndroidStaticRule("aconfig_create_storage", blueprint.RuleParams{
+ Command: `$aconfig create-storage --container $container --file $fileType --out $out --cache $in --version $version`,
+ CommandDeps: []string{"$aconfig"},
+ }, "container", "fileType", "version")
+)
+
type installedAconfigFlagsInfo struct {
aconfigFiles android.Paths
}
@@ -34,7 +45,13 @@
var importAconfigDependencyTag = interPartitionDepTag{}
-func (f *filesystem) buildAconfigFlagsFiles(ctx android.ModuleContext, builder *android.RuleBuilder, specs map[string]android.PackagingSpec, dir android.OutputPath) {
+func (f *filesystem) buildAconfigFlagsFiles(
+ ctx android.ModuleContext,
+ builder *android.RuleBuilder,
+ specs map[string]android.PackagingSpec,
+ dir android.OutputPath,
+ fullInstallPaths *[]FullInstallPathInfo,
+) {
var caches []android.Path
for _, ps := range specs {
caches = append(caches, ps.GetAconfigPaths()...)
@@ -60,20 +77,27 @@
container := f.PartitionType()
- installAconfigFlagsPath := dir.Join(ctx, "etc", "aconfig_flags.pb")
- cmd := builder.Command().
+ aconfigFlagsPb := android.PathForModuleOut(ctx, "aconfig", "aconfig_flags.pb")
+ aconfigFlagsPbBuilder := android.NewRuleBuilder(pctx, ctx)
+ cmd := aconfigFlagsPbBuilder.Command().
BuiltTool("aconfig").
Text(" dump-cache --dedup --format protobuf --out").
- Output(installAconfigFlagsPath).
+ Output(aconfigFlagsPb).
Textf("--filter container:%s+state:ENABLED", container).
Textf("--filter container:%s+permission:READ_WRITE", container)
for _, cache := range caches {
cmd.FlagWithInput("--cache ", cache)
}
- f.appendToEntry(ctx, installAconfigFlagsPath)
+ aconfigFlagsPbBuilder.Build("aconfig_flags_pb", "build aconfig_flags.pb")
- installAconfigStorageDir := dir.Join(ctx, "etc", "aconfig")
- builder.Command().Text("mkdir -p").Text(installAconfigStorageDir.String())
+ installAconfigFlagsPath := dir.Join(ctx, "etc", "aconfig_flags.pb")
+ builder.Command().Text("mkdir -p ").Text(dir.Join(ctx, "etc").String())
+ builder.Command().Text("cp").Input(aconfigFlagsPb).Text(installAconfigFlagsPath.String())
+ *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{
+ FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), "etc/aconfig_flags.pb"),
+ SourcePath: aconfigFlagsPb,
+ })
+ f.appendToEntry(ctx, installAconfigFlagsPath)
// To enable fingerprint, we need to have v2 storage files. The default version is 1.
storageFilesVersion := 1
@@ -81,16 +105,29 @@
storageFilesVersion = 2
}
+ installAconfigStorageDir := dir.Join(ctx, "etc", "aconfig")
+ builder.Command().Text("mkdir -p").Text(installAconfigStorageDir.String())
+
generatePartitionAconfigStorageFile := func(fileType, fileName string) {
- outputPath := installAconfigStorageDir.Join(ctx, fileName)
+ outPath := android.PathForModuleOut(ctx, "aconfig", fileName)
+ installPath := installAconfigStorageDir.Join(ctx, fileName)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: aconfigCreateStorage,
+ Input: aconfigFlagsPb,
+ Output: outPath,
+ Args: map[string]string{
+ "container": container,
+ "fileType": fileType,
+ "version": strconv.Itoa(storageFilesVersion),
+ },
+ })
builder.Command().
- BuiltTool("aconfig").
- FlagWithArg("create-storage --container ", container).
- FlagWithArg("--file ", fileType).
- FlagWithOutput("--out ", outputPath).
- FlagWithArg("--cache ", installAconfigFlagsPath.String()).
- FlagWithArg("--version ", strconv.Itoa(storageFilesVersion))
- f.appendToEntry(ctx, outputPath)
+ Text("cp").Input(outPath).Text(installPath.String())
+ *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{
+ SourcePath: outPath,
+ FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), "etc/aconfig", fileName),
+ })
+ f.appendToEntry(ctx, installPath)
}
if ctx.Config().ReleaseCreateAconfigStorageFile() {
diff --git a/filesystem/android_device.go b/filesystem/android_device.go
index 6a939e8..fef4aeb 100644
--- a/filesystem/android_device.go
+++ b/filesystem/android_device.go
@@ -15,16 +15,29 @@
package filesystem
import (
+ "cmp"
+ "fmt"
+ "path/filepath"
+ "slices"
"strings"
"sync/atomic"
"android/soong/android"
+ "android/soong/java"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
+var proguardDictToProto = pctx.AndroidStaticRule("proguard_dict_to_proto", blueprint.RuleParams{
+ Command: `${symbols_map} -r8 $in -location $location -write_if_changed $out`,
+ Restat: true,
+ CommandDeps: []string{"${symbols_map}"},
+}, "location")
+
type PartitionNameProperties struct {
+ // Name of the super partition filesystem module
+ Super_partition_name *string
// Name of the boot partition filesystem module
Boot_partition_name *string
// Name of the vendor boot partition filesystem module
@@ -60,6 +73,20 @@
Bootloader *string `android:"path"`
// Path to android-info.txt file containing board specific info.
Android_info *string `android:"path"`
+ // If this is the "main" android_device target for the build, i.e. the one that gets built
+ // when running a plain `m` command. Currently, this is the autogenerated android_device module
+ // in soong-only builds, but in the future when we check in android_device modules, the main
+ // one will be determined based on the lunch product. TODO: Figure out how to make this
+ // blueprint:"mutated" and still set it from filesystem_creator
+ Main_device *bool
+
+ Ab_ota_updater *bool
+ Ab_ota_partitions []string
+ Ab_ota_keys []string
+ Ab_ota_postinstall_config []string
+
+ Ramdisk_node_list *string `android:"path"`
+ Releasetools_extension *string `android:"path"`
}
type androidDevice struct {
@@ -69,8 +96,11 @@
deviceProps DeviceProperties
- // copyToProductOutTimestamp for copying necessary files to PRODUCT_OUT
- copyToProductOutTimestamp android.WritablePath
+ allImagesZip android.Path
+
+ proguardDictZip android.Path
+ proguardDictMapping android.Path
+ proguardUsageZip android.Path
}
func AndroidDeviceFactory() android.Module {
@@ -80,13 +110,22 @@
return module
}
-var numAutogeneratedAndroidDevicesOnceKey android.OnceKey = android.NewOnceKey("num_auto_generated_anroid_devices")
+var numMainAndroidDevicesOnceKey android.OnceKey = android.NewOnceKey("num_auto_generated_anroid_devices")
type partitionDepTagType struct {
blueprint.BaseDependencyTag
}
+type superPartitionDepTagType struct {
+ blueprint.BaseDependencyTag
+}
+type targetFilesMetadataDepTagType struct {
+ blueprint.BaseDependencyTag
+}
+
+var superPartitionDepTag superPartitionDepTagType
var filesystemDepTag partitionDepTagType
+var targetFilesMetadataDepTag targetFilesMetadataDepTagType
func (a *androidDevice) DepsMutator(ctx android.BottomUpMutatorContext) {
addDependencyIfDefined := func(dep *string) {
@@ -95,6 +134,9 @@
}
}
+ if a.partitionProps.Super_partition_name != nil {
+ ctx.AddDependency(ctx.Module(), superPartitionDepTag, *a.partitionProps.Super_partition_name)
+ }
addDependencyIfDefined(a.partitionProps.Boot_partition_name)
addDependencyIfDefined(a.partitionProps.Init_boot_partition_name)
addDependencyIfDefined(a.partitionProps.Vendor_boot_partition_name)
@@ -111,30 +153,71 @@
for _, vbmetaPartition := range a.partitionProps.Vbmeta_partitions {
ctx.AddDependency(ctx.Module(), filesystemDepTag, vbmetaPartition)
}
+ a.addDepsForTargetFilesMetadata(ctx)
}
-func (a *androidDevice) copyToProductOut(ctx android.ModuleContext, builder *android.RuleBuilder, src android.Path, dest string) {
- destPath := android.PathForModuleInPartitionInstall(ctx, "").Join(ctx, dest)
- builder.Command().Text("rsync").Flag("-a").Flag("--checksum").Input(src).Text(destPath.String())
-}
-
-func (a *androidDevice) copyFilesToProductOut(ctx android.ModuleContext) {
- a.copyToProductOutTimestamp = android.PathForModuleOut(ctx, "timestamp")
- builder := android.NewRuleBuilder(pctx, ctx)
- builder.Command().Text("touch").Output(a.copyToProductOutTimestamp)
-
- // List all individual files to be copied to PRODUCT_OUT here
- if a.deviceProps.Bootloader != nil {
- a.copyToProductOut(ctx, builder, android.PathForModuleSrc(ctx, proptools.String(a.deviceProps.Bootloader)), "bootloader")
- }
-
- builder.Build("copy_to_product_out", "Copy files to PRODUCT_OUT")
+func (a *androidDevice) addDepsForTargetFilesMetadata(ctx android.BottomUpMutatorContext) {
+ ctx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), targetFilesMetadataDepTag, "liblz4") // host variant
}
func (a *androidDevice) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ if proptools.Bool(a.deviceProps.Main_device) {
+ numMainAndroidDevices := ctx.Config().Once(numMainAndroidDevicesOnceKey, func() interface{} {
+ return &atomic.Int32{}
+ }).(*atomic.Int32)
+ total := numMainAndroidDevices.Add(1)
+ if total > 1 {
+ // There should only be 1 main android_device module. That one will be
+ // made the default thing to build in soong-only builds.
+ ctx.ModuleErrorf("There cannot be more than 1 main android_device module")
+ }
+ }
+
+ allInstalledModules := a.allInstalledModules(ctx)
+
a.buildTargetFilesZip(ctx)
+ a.buildProguardZips(ctx, allInstalledModules)
+
var deps []android.Path
- ctx.VisitDirectDepsWithTag(filesystemDepTag, func(m android.Module) {
+ if proptools.String(a.partitionProps.Super_partition_name) != "" {
+ superImage := ctx.GetDirectDepProxyWithTag(*a.partitionProps.Super_partition_name, superPartitionDepTag)
+ if info, ok := android.OtherModuleProvider(ctx, superImage, SuperImageProvider); ok {
+ assertUnset := func(prop *string, propName string) {
+ if prop != nil && *prop != "" {
+ ctx.PropertyErrorf(propName, "Cannot be set because it's already part of the super image")
+ }
+ }
+ for _, subPartitionType := range android.SortedKeys(info.SubImageInfo) {
+ switch subPartitionType {
+ case "system":
+ assertUnset(a.partitionProps.System_partition_name, "system_partition_name")
+ case "system_ext":
+ assertUnset(a.partitionProps.System_ext_partition_name, "system_ext_partition_name")
+ case "system_dlkm":
+ assertUnset(a.partitionProps.System_dlkm_partition_name, "system_dlkm_partition_name")
+ case "system_other":
+ // TODO
+ case "product":
+ assertUnset(a.partitionProps.Product_partition_name, "product_partition_name")
+ case "vendor":
+ assertUnset(a.partitionProps.Vendor_partition_name, "vendor_partition_name")
+ case "vendor_dlkm":
+ assertUnset(a.partitionProps.Vendor_dlkm_partition_name, "vendor_dlkm_partition_name")
+ case "odm":
+ assertUnset(a.partitionProps.Odm_partition_name, "odm_partition_name")
+ case "odm_dlkm":
+ assertUnset(a.partitionProps.Odm_dlkm_partition_name, "odm_dlkm_partition_name")
+ default:
+ ctx.ModuleErrorf("Unsupported sub-partition of super partition: %q", subPartitionType)
+ }
+ }
+
+ deps = append(deps, info.SuperImage)
+ } else {
+ ctx.ModuleErrorf("Expected super image dep to provide SuperImageProvider")
+ }
+ }
+ ctx.VisitDirectDepsProxyWithTag(filesystemDepTag, func(m android.ModuleProxy) {
imageOutput, ok := android.OtherModuleProvider(ctx, m, android.OutputFilesProvider)
if !ok {
ctx.ModuleErrorf("Partition module %s doesn't set OutputfilesProvider", m.Name())
@@ -145,43 +228,170 @@
deps = append(deps, imageOutput.DefaultOutputFiles[0])
})
- a.copyFilesToProductOut(ctx)
+ allImagesZip := android.PathForModuleOut(ctx, "all_images.zip")
+ allImagesZipBuilder := android.NewRuleBuilder(pctx, ctx)
+ cmd := allImagesZipBuilder.Command().BuiltTool("soong_zip")
+ for _, dep := range deps {
+ cmd.FlagWithArg("-e ", dep.Base())
+ cmd.FlagWithInput("-f ", dep)
+ }
+ cmd.FlagWithOutput("-o ", allImagesZip)
+ allImagesZipBuilder.Build("soong_all_images_zip", "all_images.zip")
+ a.allImagesZip = allImagesZip
allImagesStamp := android.PathForModuleOut(ctx, "all_images_stamp")
- ctx.Build(pctx, android.BuildParams{
- Rule: android.Touch,
- Output: allImagesStamp,
- Implicits: deps,
- Validation: a.copyToProductOutTimestamp,
- })
- ctx.SetOutputFiles(android.Paths{allImagesStamp}, "")
- ctx.CheckbuildFile(allImagesStamp)
-
- if ctx.OtherModuleIsAutoGenerated(ctx.Module()) {
- numAutogeneratedAndroidDevices := ctx.Config().Once(numAutogeneratedAndroidDevicesOnceKey, func() interface{} {
- return &atomic.Int32{}
- }).(*atomic.Int32)
- total := numAutogeneratedAndroidDevices.Add(1)
- if total > 1 {
- // There should only be 1 autogenerated android_device module. That one will be
- // made the default thing to build in soong-only builds.
- ctx.ModuleErrorf("There cannot be more than 1 autogenerated android_device module")
- }
- }
-
- if !ctx.Config().KatiEnabled() && ctx.OtherModuleIsAutoGenerated(ctx.Module()) {
+ var validations android.Paths
+ if !ctx.Config().KatiEnabled() && proptools.Bool(a.deviceProps.Main_device) {
// In soong-only builds, build this module by default.
// This is the analogue to this make code:
// https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/main.mk;l=1396;drc=6595459cdd8164a6008335f6372c9f97b9094060
ctx.Phony("droidcore-unbundled", allImagesStamp)
+
+ deps = append(deps, a.copyFilesToProductOutForSoongOnly(ctx))
+ }
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Touch,
+ Output: allImagesStamp,
+ Implicits: deps,
+ Validations: validations,
+ })
+
+ // Checkbuilding it causes soong to make a phony, so you can say `m <module name>`
+ ctx.CheckbuildFile(allImagesStamp)
+
+ a.setVbmetaPhonyTargets(ctx)
+
+ a.distFiles(ctx)
+}
+
+// Returns a list of modules that are installed, which are collected from the dependency
+// filesystem and super_image modules.
+func (a *androidDevice) allInstalledModules(ctx android.ModuleContext) []android.Module {
+ fsInfoMap := a.getFsInfos(ctx)
+ allOwners := make(map[string][]string)
+ for _, partition := range android.SortedKeys(fsInfoMap) {
+ fsInfo := fsInfoMap[partition]
+ for _, owner := range fsInfo.Owners {
+ allOwners[owner.Name] = append(allOwners[owner.Name], owner.Variation)
+ }
+ }
+
+ ret := []android.Module{}
+ ctx.WalkDepsProxy(func(mod, _ android.ModuleProxy) bool {
+ if variations, ok := allOwners[mod.Name()]; ok && android.InList(ctx.OtherModuleSubDir(mod), variations) {
+ ret = append(ret, mod)
+ }
+ return true
+ })
+
+ // Remove duplicates
+ ret = android.FirstUniqueFunc(ret, func(a, b android.Module) bool {
+ return a.String() == b.String()
+ })
+
+ // Sort the modules by their names and variants
+ slices.SortFunc(ret, func(a, b android.Module) int {
+ return cmp.Compare(a.String(), b.String())
+ })
+ return ret
+}
+
+func insertBeforeExtension(file, insertion string) string {
+ ext := filepath.Ext(file)
+ return strings.TrimSuffix(file, ext) + insertion + ext
+}
+
+func (a *androidDevice) distFiles(ctx android.ModuleContext) {
+ if !ctx.Config().KatiEnabled() && proptools.Bool(a.deviceProps.Main_device) {
+ fsInfoMap := a.getFsInfos(ctx)
+ for _, partition := range android.SortedKeys(fsInfoMap) {
+ fsInfo := fsInfoMap[partition]
+ if fsInfo.InstalledFiles.Json != nil {
+ ctx.DistForGoal("droidcore-unbundled", fsInfo.InstalledFiles.Json)
+ }
+ if fsInfo.InstalledFiles.Txt != nil {
+ ctx.DistForGoal("droidcore-unbundled", fsInfo.InstalledFiles.Txt)
+ }
+ }
+
+ namePrefix := ""
+ if ctx.Config().HasDeviceProduct() {
+ namePrefix = ctx.Config().DeviceProduct() + "-"
+ }
+ ctx.DistForGoalWithFilename("droidcore-unbundled", a.proguardDictZip, namePrefix+insertBeforeExtension(a.proguardDictZip.Base(), "-FILE_NAME_TAG_PLACEHOLDER"))
+ ctx.DistForGoalWithFilename("droidcore-unbundled", a.proguardDictMapping, namePrefix+insertBeforeExtension(a.proguardDictMapping.Base(), "-FILE_NAME_TAG_PLACEHOLDER"))
+ ctx.DistForGoalWithFilename("droidcore-unbundled", a.proguardUsageZip, namePrefix+insertBeforeExtension(a.proguardUsageZip.Base(), "-FILE_NAME_TAG_PLACEHOLDER"))
}
}
+func (a *androidDevice) MakeVars(ctx android.MakeVarsModuleContext) {
+ if proptools.Bool(a.deviceProps.Main_device) {
+ ctx.StrictRaw("SOONG_ONLY_ALL_IMAGES_ZIP", a.allImagesZip.String())
+ }
+}
+
+func (a *androidDevice) buildProguardZips(ctx android.ModuleContext, allInstalledModules []android.Module) {
+ dictZip := android.PathForModuleOut(ctx, "proguard-dict.zip")
+ dictZipBuilder := android.NewRuleBuilder(pctx, ctx)
+ dictZipCmd := dictZipBuilder.Command().BuiltTool("soong_zip").Flag("-d").FlagWithOutput("-o ", dictZip)
+
+ dictMapping := android.PathForModuleOut(ctx, "proguard-dict-mapping.textproto")
+ dictMappingBuilder := android.NewRuleBuilder(pctx, ctx)
+ dictMappingCmd := dictMappingBuilder.Command().BuiltTool("symbols_map").Flag("-merge").Output(dictMapping)
+
+ protosDir := android.PathForModuleOut(ctx, "proguard_mapping_protos")
+
+ usageZip := android.PathForModuleOut(ctx, "proguard-usage.zip")
+ usageZipBuilder := android.NewRuleBuilder(pctx, ctx)
+ usageZipCmd := usageZipBuilder.Command().BuiltTool("merge_zips").Output(usageZip)
+
+ for _, mod := range allInstalledModules {
+ if proguardInfo, ok := android.OtherModuleProvider(ctx, mod, java.ProguardProvider); ok {
+ // Maintain these out/target/common paths for backwards compatibility. They may be able
+ // to be changed if tools look up file locations from the protobuf, but I'm not
+ // exactly sure how that works.
+ dictionaryFakePath := fmt.Sprintf("out/target/common/obj/%s/%s_intermediates/proguard_dictionary", proguardInfo.Class, proguardInfo.ModuleName)
+ dictZipCmd.FlagWithArg("-e ", dictionaryFakePath)
+ dictZipCmd.FlagWithInput("-f ", proguardInfo.ProguardDictionary)
+ dictZipCmd.Textf("-e out/target/common/obj/%s/%s_intermediates/classes.jar", proguardInfo.Class, proguardInfo.ModuleName)
+ dictZipCmd.FlagWithInput("-f ", proguardInfo.ClassesJar)
+
+ protoFile := protosDir.Join(ctx, filepath.Dir(dictionaryFakePath), "proguard_dictionary.textproto")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: proguardDictToProto,
+ Input: proguardInfo.ProguardDictionary,
+ Output: protoFile,
+ Args: map[string]string{
+ "location": dictionaryFakePath,
+ },
+ })
+ dictMappingCmd.Input(protoFile)
+
+ usageZipCmd.Input(proguardInfo.ProguardUsageZip)
+ }
+ }
+
+ dictZipBuilder.Build("proguard_dict_zip", "Building proguard dictionary zip")
+ dictMappingBuilder.Build("proguard_dict_mapping_proto", "Building proguard mapping proto")
+ usageZipBuilder.Build("proguard_usage_zip", "Building proguard usage zip")
+
+ a.proguardDictZip = dictZip
+ a.proguardDictMapping = dictMapping
+ a.proguardUsageZip = usageZip
+}
+
+// Helper structs for target_files.zip creation
type targetFilesZipCopy struct {
srcModule *string
destSubdir string
}
+type targetFilesystemZipCopy struct {
+ fsInfo FilesystemInfo
+ destSubdir string
+}
+
func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext) {
targetFilesDir := android.PathForModuleOut(ctx, "target_files_dir")
targetFilesZip := android.PathForModuleOut(ctx, "target_files.zip")
@@ -202,75 +412,92 @@
targetFilesZipCopy{a.partitionProps.Init_boot_partition_name, "INIT_BOOT/RAMDISK"},
targetFilesZipCopy{a.partitionProps.Vendor_boot_partition_name, "VENDOR_BOOT/RAMDISK"},
}
- // TODO: Handle cases where recovery files are copied to BOOT/ or RECOVERY/
- // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=6211-6219?q=core%2FMakefile&ss=android%2Fplatform%2Fsuperproject%2Fmain
- if ctx.DeviceConfig().BoardMoveRecoveryResourcesToVendorBoot() {
- toCopy = append(toCopy, targetFilesZipCopy{a.partitionProps.Recovery_partition_name, "VENDOR_BOOT/RAMDISK"})
- }
- // Create an IMAGES/ subdirectory
- builder.Command().Textf("mkdir -p %s/IMAGES/", targetFilesDir.String())
- if a.deviceProps.Bootloader != nil {
- builder.Command().Textf("cp ").Input(android.PathForModuleSrc(ctx, proptools.String(a.deviceProps.Bootloader))).Textf(" %s/IMAGES/bootloader", targetFilesDir.String())
- }
-
+ filesystemsToCopy := []targetFilesystemZipCopy{}
for _, zipCopy := range toCopy {
if zipCopy.srcModule == nil {
continue
}
- fsInfo := a.getFilesystemInfo(ctx, *zipCopy.srcModule)
- subdir := zipCopy.destSubdir
- rootDirString := fsInfo.RootDir.String()
- if subdir == "SYSTEM" {
+ filesystemsToCopy = append(
+ filesystemsToCopy,
+ targetFilesystemZipCopy{a.getFilesystemInfo(ctx, *zipCopy.srcModule), zipCopy.destSubdir},
+ )
+ }
+ // Get additional filesystems from super_partition dependency
+ if a.partitionProps.Super_partition_name != nil {
+ superPartition := ctx.GetDirectDepProxyWithTag(*a.partitionProps.Super_partition_name, superPartitionDepTag)
+ if info, ok := android.OtherModuleProvider(ctx, superPartition, SuperImageProvider); ok {
+ for _, partition := range android.SortedKeys(info.SubImageInfo) {
+ filesystemsToCopy = append(
+ filesystemsToCopy,
+ targetFilesystemZipCopy{info.SubImageInfo[partition], strings.ToUpper(partition)},
+ )
+ }
+ } else {
+ ctx.ModuleErrorf("Super partition %s does set SuperImageProvider\n", superPartition.Name())
+ }
+ }
+
+ for _, toCopy := range filesystemsToCopy {
+ rootDirString := toCopy.fsInfo.RootDir.String()
+ if toCopy.destSubdir == "SYSTEM" {
rootDirString = rootDirString + "/system"
}
- builder.Command().Textf("mkdir -p %s/%s", targetFilesDir.String(), subdir)
+ builder.Command().Textf("mkdir -p %s/%s", targetFilesDir.String(), toCopy.destSubdir)
builder.Command().
BuiltTool("acp").
- Textf("-rd %s/. %s/%s", rootDirString, targetFilesDir, subdir).
- Implicit(fsInfo.Output) // so that the staging dir is built
-
- if subdir == "SYSTEM" {
- // Create the ROOT partition in target_files.zip
- builder.Command().Textf("rsync --links --exclude=system/* %s/ -r %s/ROOT", fsInfo.RootDir, targetFilesDir.String())
+ Textf("-rd %s/. %s/%s", rootDirString, targetFilesDir, toCopy.destSubdir).
+ Implicit(toCopy.fsInfo.Output) // so that the staging dir is built
+ for _, extraRootDir := range toCopy.fsInfo.ExtraRootDirs {
+ builder.Command().
+ BuiltTool("acp").
+ Textf("-rd %s/. %s/%s", extraRootDir, targetFilesDir, toCopy.destSubdir).
+ Implicit(toCopy.fsInfo.Output) // so that the staging dir is built
}
- builder.Command().Textf("cp %s %s/IMAGES/", fsInfo.Output, targetFilesDir.String())
+
+ if toCopy.destSubdir == "SYSTEM" {
+ // Create the ROOT partition in target_files.zip
+ builder.Command().Textf("rsync --links --exclude=system/* %s/ -r %s/ROOT", toCopy.fsInfo.RootDir, targetFilesDir.String())
+ }
}
// Copy cmdline, kernel etc. files of boot images
if a.partitionProps.Vendor_boot_partition_name != nil {
- bootImg := ctx.GetDirectDepWithTag(proptools.String(a.partitionProps.Vendor_boot_partition_name), filesystemDepTag)
+ bootImg := ctx.GetDirectDepProxyWithTag(proptools.String(a.partitionProps.Vendor_boot_partition_name), filesystemDepTag)
bootImgInfo, _ := android.OtherModuleProvider(ctx, bootImg, BootimgInfoProvider)
builder.Command().Textf("echo %s > %s/VENDOR_BOOT/cmdline", proptools.ShellEscape(strings.Join(bootImgInfo.Cmdline, " ")), targetFilesDir)
builder.Command().Textf("echo %s > %s/VENDOR_BOOT/vendor_cmdline", proptools.ShellEscape(strings.Join(bootImgInfo.Cmdline, " ")), targetFilesDir)
if bootImgInfo.Dtb != nil {
- builder.Command().Textf("cp %s %s/VENDOR_BOOT/dtb", bootImgInfo.Dtb, targetFilesDir)
+ builder.Command().Textf("cp ").Input(bootImgInfo.Dtb).Textf(" %s/VENDOR_BOOT/dtb", targetFilesDir)
}
if bootImgInfo.Bootconfig != nil {
- builder.Command().Textf("cp %s %s/VENDOR_BOOT/vendor_bootconfig", bootImgInfo.Bootconfig, targetFilesDir)
+ builder.Command().Textf("cp ").Input(bootImgInfo.Bootconfig).Textf(" %s/VENDOR_BOOT/vendor_bootconfig", targetFilesDir)
}
}
if a.partitionProps.Boot_partition_name != nil {
- bootImg := ctx.GetDirectDepWithTag(proptools.String(a.partitionProps.Boot_partition_name), filesystemDepTag)
+ bootImg := ctx.GetDirectDepProxyWithTag(proptools.String(a.partitionProps.Boot_partition_name), filesystemDepTag)
bootImgInfo, _ := android.OtherModuleProvider(ctx, bootImg, BootimgInfoProvider)
builder.Command().Textf("echo %s > %s/BOOT/cmdline", proptools.ShellEscape(strings.Join(bootImgInfo.Cmdline, " ")), targetFilesDir)
if bootImgInfo.Dtb != nil {
- builder.Command().Textf("cp %s %s/BOOT/dtb", bootImgInfo.Dtb, targetFilesDir)
+ builder.Command().Textf("cp ").Input(bootImgInfo.Dtb).Textf(" %s/BOOT/dtb", targetFilesDir)
}
if bootImgInfo.Kernel != nil {
- builder.Command().Textf("cp %s %s/BOOT/kernel", bootImgInfo.Kernel, targetFilesDir)
+ builder.Command().Textf("cp ").Input(bootImgInfo.Kernel).Textf(" %s/BOOT/kernel", targetFilesDir)
// Even though kernel is not used to build vendor_boot, copy the kernel to VENDOR_BOOT to match the behavior of make packaging.
- builder.Command().Textf("cp %s %s/VENDOR_BOOT/kernel", bootImgInfo.Kernel, targetFilesDir)
+ builder.Command().Textf("cp ").Input(bootImgInfo.Kernel).Textf(" %s/VENDOR_BOOT/kernel", targetFilesDir)
}
if bootImgInfo.Bootconfig != nil {
- builder.Command().Textf("cp %s %s/BOOT/bootconfig", bootImgInfo.Bootconfig, targetFilesDir)
+ builder.Command().Textf("cp ").Input(bootImgInfo.Bootconfig).Textf(" %s/BOOT/bootconfig", targetFilesDir)
}
}
if a.deviceProps.Android_info != nil {
builder.Command().Textf("mkdir -p %s/OTA", targetFilesDir)
- builder.Command().Textf("cp %s %s/OTA/android-info.txt", android.PathForModuleSrc(ctx, proptools.String(a.deviceProps.Android_info)), targetFilesDir)
+ builder.Command().Textf("cp ").Input(android.PathForModuleSrc(ctx, *a.deviceProps.Android_info)).Textf(" %s/OTA/android-info.txt", targetFilesDir)
}
+ a.copyImagesToTargetZip(ctx, builder, targetFilesDir)
+ a.copyMetadataToTargetZip(ctx, builder, targetFilesDir)
+
builder.Command().
BuiltTool("soong_zip").
Text("-d").
@@ -281,11 +508,130 @@
builder.Build("target_files_"+ctx.ModuleName(), "Build target_files.zip")
}
+func (a *androidDevice) copyImagesToTargetZip(ctx android.ModuleContext, builder *android.RuleBuilder, targetFilesDir android.WritablePath) {
+ // Create an IMAGES/ subdirectory
+ builder.Command().Textf("mkdir -p %s/IMAGES", targetFilesDir.String())
+ if a.deviceProps.Bootloader != nil {
+ builder.Command().Textf("cp ").Input(android.PathForModuleSrc(ctx, proptools.String(a.deviceProps.Bootloader))).Textf(" %s/IMAGES/bootloader", targetFilesDir.String())
+ }
+ // Copy the filesystem ,boot and vbmeta img files to IMAGES/
+ ctx.VisitDirectDepsProxyWithTag(filesystemDepTag, func(child android.ModuleProxy) {
+ if strings.Contains(child.Name(), "recovery") {
+ return // skip recovery.img to match the make packaging behavior
+ }
+ if info, ok := android.OtherModuleProvider(ctx, child, BootimgInfoProvider); ok {
+ // Check Boot img first so that the boot.img is copied and not its dep ramdisk.img
+ builder.Command().Textf("cp ").Input(info.Output).Textf(" %s/IMAGES/", targetFilesDir.String())
+ } else if info, ok := android.OtherModuleProvider(ctx, child, FilesystemProvider); ok {
+ builder.Command().Textf("cp ").Input(info.Output).Textf(" %s/IMAGES/", targetFilesDir.String())
+ } else if info, ok := android.OtherModuleProvider(ctx, child, vbmetaPartitionProvider); ok {
+ builder.Command().Textf("cp ").Input(info.Output).Textf(" %s/IMAGES/", targetFilesDir.String())
+ } else {
+ ctx.ModuleErrorf("Module %s does not provide an .img file output for target_files.zip", child.Name())
+ }
+ })
+
+ if a.partitionProps.Super_partition_name != nil {
+ superPartition := ctx.GetDirectDepProxyWithTag(*a.partitionProps.Super_partition_name, superPartitionDepTag)
+ if info, ok := android.OtherModuleProvider(ctx, superPartition, SuperImageProvider); ok {
+ for _, partition := range android.SortedKeys(info.SubImageInfo) {
+ if info.SubImageInfo[partition].OutputHermetic != nil {
+ builder.Command().Textf("cp ").Input(info.SubImageInfo[partition].OutputHermetic).Textf(" %s/IMAGES/", targetFilesDir.String())
+ }
+ if info.SubImageInfo[partition].MapFile != nil {
+ builder.Command().Textf("cp ").Input(info.SubImageInfo[partition].MapFile).Textf(" %s/IMAGES/", targetFilesDir.String())
+ }
+ }
+ } else {
+ ctx.ModuleErrorf("Super partition %s does set SuperImageProvider\n", superPartition.Name())
+ }
+ }
+}
+
+func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, builder *android.RuleBuilder, targetFilesDir android.WritablePath) {
+ // Create a META/ subdirectory
+ builder.Command().Textf("mkdir -p %s/META", targetFilesDir.String())
+ if proptools.Bool(a.deviceProps.Ab_ota_updater) {
+ ctx.VisitDirectDepsProxyWithTag(targetFilesMetadataDepTag, func(child android.ModuleProxy) {
+ info, _ := android.OtherModuleProvider(ctx, child, android.OutputFilesProvider)
+ builder.Command().Textf("cp").Inputs(info.DefaultOutputFiles).Textf(" %s/META/", targetFilesDir.String())
+ })
+ builder.Command().Textf("cp").Input(android.PathForSource(ctx, "external/zucchini/version_info.h")).Textf(" %s/META/zucchini_config.txt", targetFilesDir.String())
+ builder.Command().Textf("cp").Input(android.PathForSource(ctx, "system/update_engine/update_engine.conf")).Textf(" %s/META/update_engine_config.txt", targetFilesDir.String())
+ if a.getFsInfos(ctx)["system"].ErofsCompressHints != nil {
+ builder.Command().Textf("cp").Input(a.getFsInfos(ctx)["system"].ErofsCompressHints).Textf(" %s/META/erofs_default_compress_hints.txt", targetFilesDir.String())
+ }
+ // ab_partitions.txt
+ abPartitionsSorted := android.SortedUniqueStrings(a.deviceProps.Ab_ota_partitions)
+ abPartitionsSortedString := proptools.ShellEscape(strings.Join(abPartitionsSorted, "\\n"))
+ builder.Command().Textf("echo -e").Flag(abPartitionsSortedString).Textf(" > %s/META/ab_partitions.txt", targetFilesDir.String())
+ // otakeys.txt
+ abOtaKeysSorted := android.SortedUniqueStrings(a.deviceProps.Ab_ota_keys)
+ abOtaKeysSortedString := proptools.ShellEscape(strings.Join(abOtaKeysSorted, "\\n"))
+ builder.Command().Textf("echo -e").Flag(abOtaKeysSortedString).Textf(" > %s/META/otakeys.txt", targetFilesDir.String())
+ // postinstall_config.txt
+ abOtaPostInstallConfigString := proptools.ShellEscape(strings.Join(a.deviceProps.Ab_ota_postinstall_config, "\\n"))
+ builder.Command().Textf("echo -e").Flag(abOtaPostInstallConfigString).Textf(" > %s/META/postinstall_config.txt", targetFilesDir.String())
+ // selinuxfc
+ if a.getFsInfos(ctx)["system"].SelinuxFc != nil {
+ builder.Command().Textf("cp").Input(a.getFsInfos(ctx)["system"].SelinuxFc).Textf(" %s/META/file_contexts.bin", targetFilesDir.String())
+ }
+ }
+ // Copy $partition_filesystem_config.txt
+ fsInfos := a.getFsInfos(ctx)
+ for _, partition := range android.SortedKeys(fsInfos) {
+ if fsInfos[partition].FilesystemConfig == nil {
+ continue
+ }
+ if android.InList(partition, []string{"userdata"}) {
+ continue
+ }
+ builder.Command().Textf("cp").Input(fsInfos[partition].FilesystemConfig).Textf(" %s/META/%s", targetFilesDir.String(), a.filesystemConfigNameForTargetFiles(partition))
+ }
+ // Copy ramdisk_node_list
+ if ramdiskNodeList := android.PathForModuleSrc(ctx, proptools.String(a.deviceProps.Ramdisk_node_list)); ramdiskNodeList != nil {
+ builder.Command().Textf("cp").Input(ramdiskNodeList).Textf(" %s/META/", targetFilesDir.String())
+ }
+ // Copy releasetools.py
+ if releaseTools := android.PathForModuleSrc(ctx, proptools.String(a.deviceProps.Releasetools_extension)); releaseTools != nil {
+ builder.Command().Textf("cp").Input(releaseTools).Textf(" %s/META/", targetFilesDir.String())
+ }
+}
+
+// Filenames for the partition specific fs_config files.
+// Hardcode the ramdisk files to their boot image prefix
+func (a *androidDevice) filesystemConfigNameForTargetFiles(partition string) string {
+ name := partition + "_filesystem_config.txt"
+ if partition == "system" {
+ name = "filesystem_config.txt"
+ } else if partition == "ramdisk" {
+ name = "init_boot_filesystem_config.txt"
+ }
+ return name
+}
+
func (a *androidDevice) getFilesystemInfo(ctx android.ModuleContext, depName string) FilesystemInfo {
- fsMod := ctx.GetDirectDepWithTag(depName, filesystemDepTag)
+ fsMod := ctx.GetDirectDepProxyWithTag(depName, filesystemDepTag)
fsInfo, ok := android.OtherModuleProvider(ctx, fsMod, FilesystemProvider)
if !ok {
ctx.ModuleErrorf("Expected dependency %s to be a filesystem", depName)
}
return fsInfo
}
+
+func (a *androidDevice) setVbmetaPhonyTargets(ctx android.ModuleContext) {
+ if !proptools.Bool(a.deviceProps.Main_device) {
+ return
+ }
+
+ if !ctx.Config().KatiEnabled() {
+ for _, vbmetaPartitionName := range a.partitionProps.Vbmeta_partitions {
+ img := ctx.GetDirectDepProxyWithTag(vbmetaPartitionName, filesystemDepTag)
+ if provider, ok := android.OtherModuleProvider(ctx, img, vbmetaPartitionProvider); ok {
+ // make generates `vbmetasystemimage` phony target instead of `vbmeta_systemimage` phony target.
+ partitionName := strings.ReplaceAll(provider.Name, "_", "")
+ ctx.Phony(fmt.Sprintf("%simage", partitionName), provider.Output)
+ }
+ }
+ }
+}
diff --git a/filesystem/android_device_product_out.go b/filesystem/android_device_product_out.go
new file mode 100644
index 0000000..7d37f1e
--- /dev/null
+++ b/filesystem/android_device_product_out.go
@@ -0,0 +1,260 @@
+// Copyright (C) 2025 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 filesystem
+
+import (
+ "android/soong/android"
+
+ "github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
+)
+
+var (
+ copyStagingDirRule = pctx.AndroidStaticRule("copy_staging_dir", blueprint.RuleParams{
+ Command: "rsync -a --checksum $dir/ $dest && touch $out",
+ }, "dir", "dest")
+)
+
+func (a *androidDevice) copyToProductOut(ctx android.ModuleContext, builder *android.RuleBuilder, src android.Path, dest string) {
+ destPath := android.PathForModuleInPartitionInstall(ctx, "").Join(ctx, dest)
+ builder.Command().Text("rsync").Flag("-a").Flag("--checksum").Input(src).Text(destPath.String())
+}
+
+func (a *androidDevice) copyFilesToProductOutForSoongOnly(ctx android.ModuleContext) android.Path {
+ filesystemInfos := a.getFsInfos(ctx)
+
+ var deps android.Paths
+ var depsNoImg android.Paths // subset of deps without any img files. used for sbom creation.
+
+ for _, partition := range android.SortedKeys(filesystemInfos) {
+ info := filesystemInfos[partition]
+ imgInstallPath := android.PathForModuleInPartitionInstall(ctx, "", partition+".img")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: info.Output,
+ Output: imgInstallPath,
+ })
+
+ // Make it so doing `m <moduleName>` or `m <partitionType>image` will copy the files to
+ // PRODUCT_OUT
+ if partition == "system_ext" {
+ partition = "systemext"
+ }
+ partition = partition + "image"
+ ctx.Phony(info.ModuleName, imgInstallPath)
+ ctx.Phony(partition, imgInstallPath)
+ for _, fip := range info.FullInstallPaths {
+ // TODO: Directories. But maybe they're not necessary? Adevice doesn't care
+ // about empty directories, still need to check if adb sync does.
+ if !fip.IsDir {
+ if !fip.RequiresFullInstall {
+ // Some modules set requires_full_install: false, which causes their staging
+ // directory file to not be installed. This is usually because the file appears
+ // in both PRODUCT_COPY_FILES and a soong module for the handwritten soong system
+ // image. In this case, that module's installed files would conflict with the
+ // PRODUCT_COPY_FILES. However, in soong-only builds, we don't automatically
+ // create rules for PRODUCT_COPY_FILES unless they're needed in the partition.
+ // So in that case, nothing is creating the installed path. Create them now
+ // if that's the case.
+ if fip.SymlinkTarget == "" {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.CpWithBash,
+ Input: fip.SourcePath,
+ Output: fip.FullInstallPath,
+ Args: map[string]string{
+ // Preserve timestamps for adb sync, so that this installed file's
+ // timestamp matches the timestamp in the filesystem's intermediate
+ // staging dir
+ "cpFlags": "-p",
+ },
+ })
+ } else {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.SymlinkWithBash,
+ Output: fip.FullInstallPath,
+ Args: map[string]string{
+ "fromPath": fip.SymlinkTarget,
+ },
+ })
+ }
+ }
+ ctx.Phony(info.ModuleName, fip.FullInstallPath)
+ ctx.Phony(partition, fip.FullInstallPath)
+ deps = append(deps, fip.FullInstallPath)
+ depsNoImg = append(depsNoImg, fip.FullInstallPath)
+ ctx.Phony("sync_"+partition, fip.FullInstallPath)
+ ctx.Phony("sync", fip.FullInstallPath)
+ }
+ }
+
+ deps = append(deps, imgInstallPath)
+ }
+
+ a.createComplianceMetadataTimestamp(ctx, depsNoImg)
+
+ // List all individual files to be copied to PRODUCT_OUT here
+ if a.deviceProps.Bootloader != nil {
+ bootloaderInstallPath := android.PathForModuleInPartitionInstall(ctx, "", "bootloader")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: android.PathForModuleSrc(ctx, *a.deviceProps.Bootloader),
+ Output: bootloaderInstallPath,
+ })
+ deps = append(deps, bootloaderInstallPath)
+ }
+
+ copyBootImg := func(prop *string, type_ string) {
+ if proptools.String(prop) != "" {
+ partition := ctx.GetDirectDepWithTag(*prop, filesystemDepTag)
+ if info, ok := android.OtherModuleProvider(ctx, partition, BootimgInfoProvider); ok {
+ installPath := android.PathForModuleInPartitionInstall(ctx, "", type_+".img")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: info.Output,
+ Output: installPath,
+ })
+ deps = append(deps, installPath)
+ } else {
+ ctx.ModuleErrorf("%s does not set BootimgInfo\n", *prop)
+ }
+ }
+ }
+
+ copyBootImg(a.partitionProps.Init_boot_partition_name, "init_boot")
+ copyBootImg(a.partitionProps.Boot_partition_name, "boot")
+ copyBootImg(a.partitionProps.Vendor_boot_partition_name, "vendor_boot")
+
+ for _, vbmetaModName := range a.partitionProps.Vbmeta_partitions {
+ partition := ctx.GetDirectDepWithTag(vbmetaModName, filesystemDepTag)
+ if info, ok := android.OtherModuleProvider(ctx, partition, vbmetaPartitionProvider); ok {
+ installPath := android.PathForModuleInPartitionInstall(ctx, "", info.Name+".img")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: info.Output,
+ Output: installPath,
+ })
+ deps = append(deps, installPath)
+ } else {
+ ctx.ModuleErrorf("%s does not set vbmetaPartitionProvider\n", vbmetaModName)
+ }
+ }
+
+ if proptools.String(a.partitionProps.Super_partition_name) != "" {
+ partition := ctx.GetDirectDepWithTag(*a.partitionProps.Super_partition_name, superPartitionDepTag)
+ if info, ok := android.OtherModuleProvider(ctx, partition, SuperImageProvider); ok {
+ installPath := android.PathForModuleInPartitionInstall(ctx, "", "super.img")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: info.SuperImage,
+ Output: installPath,
+ })
+ deps = append(deps, installPath)
+ } else {
+ ctx.ModuleErrorf("%s does not set SuperImageProvider\n", *a.partitionProps.Super_partition_name)
+ }
+ }
+
+ if proptools.String(a.deviceProps.Android_info) != "" {
+ installPath := android.PathForModuleInPartitionInstall(ctx, "", "android_info.txt")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: android.PathForModuleSrc(ctx, *a.deviceProps.Android_info),
+ Output: installPath,
+ })
+ deps = append(deps, installPath)
+ }
+
+ copyToProductOutTimestamp := android.PathForModuleOut(ctx, "product_out_copy_timestamp")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Touch,
+ Output: copyToProductOutTimestamp,
+ Implicits: deps,
+ })
+
+ emptyFile := android.PathForModuleOut(ctx, "empty_file")
+ android.WriteFileRule(ctx, emptyFile, "")
+
+ // TODO: We don't have these tests building in soong yet. Add phonies for them so that CI builds
+ // that try to build them don't error out.
+ ctx.Phony("continuous_instrumentation_tests", emptyFile)
+ ctx.Phony("continuous_native_tests", emptyFile)
+ ctx.Phony("device-tests", emptyFile)
+ ctx.Phony("device-platinum-tests", emptyFile)
+ ctx.Phony("platform_tests", emptyFile)
+
+ return copyToProductOutTimestamp
+}
+
+// createComplianceMetadataTimestampForSoongOnly creates a timestamp file in m --soong-only
+// this timestamp file depends on installed files of the main `android_device`.
+// Any changes to installed files of the main `android_device` will retrigger SBOM generation
+func (a *androidDevice) createComplianceMetadataTimestamp(ctx android.ModuleContext, installedFiles android.Paths) {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Touch,
+ Implicits: installedFiles,
+ Output: android.PathForOutput(ctx, "compliance-metadata", ctx.Config().DeviceProduct(), "installed_files.stamp"),
+ })
+}
+
+// Returns a mapping from partition type -> FilesystemInfo. This includes filesystems that are
+// nested inside of other partitions, such as the partitions inside super.img, or ramdisk inside
+// of boot.
+func (a *androidDevice) getFsInfos(ctx android.ModuleContext) map[string]FilesystemInfo {
+ type propToType struct {
+ prop *string
+ ty string
+ }
+
+ filesystemInfos := make(map[string]FilesystemInfo)
+
+ partitionDefinitions := []propToType{
+ propToType{a.partitionProps.System_partition_name, "system"},
+ propToType{a.partitionProps.System_ext_partition_name, "system_ext"},
+ propToType{a.partitionProps.Product_partition_name, "product"},
+ propToType{a.partitionProps.Vendor_partition_name, "vendor"},
+ propToType{a.partitionProps.Odm_partition_name, "odm"},
+ propToType{a.partitionProps.Recovery_partition_name, "recovery"},
+ propToType{a.partitionProps.System_dlkm_partition_name, "system_dlkm"},
+ propToType{a.partitionProps.Vendor_dlkm_partition_name, "vendor_dlkm"},
+ propToType{a.partitionProps.Odm_dlkm_partition_name, "odm_dlkm"},
+ propToType{a.partitionProps.Userdata_partition_name, "userdata"},
+ // filesystemInfo from init_boot and vendor_boot actually are re-exports of the ramdisk
+ // images inside of them
+ propToType{a.partitionProps.Init_boot_partition_name, "ramdisk"},
+ propToType{a.partitionProps.Vendor_boot_partition_name, "vendor_ramdisk"},
+ }
+ for _, partitionDefinition := range partitionDefinitions {
+ if proptools.String(partitionDefinition.prop) != "" {
+ partition := ctx.GetDirectDepWithTag(*partitionDefinition.prop, filesystemDepTag)
+ if info, ok := android.OtherModuleProvider(ctx, partition, FilesystemProvider); ok {
+ filesystemInfos[partitionDefinition.ty] = info
+ } else {
+ ctx.ModuleErrorf("Super partition %s does not set FilesystemProvider\n", partition.Name())
+ }
+ }
+ }
+ if a.partitionProps.Super_partition_name != nil {
+ superPartition := ctx.GetDirectDepWithTag(*a.partitionProps.Super_partition_name, superPartitionDepTag)
+ if info, ok := android.OtherModuleProvider(ctx, superPartition, SuperImageProvider); ok {
+ for partition := range info.SubImageInfo {
+ filesystemInfos[partition] = info.SubImageInfo[partition]
+ }
+ } else {
+ ctx.ModuleErrorf("Super partition %s does not set SuperImageProvider\n", superPartition.Name())
+ }
+ }
+
+ return filesystemInfos
+}
diff --git a/filesystem/avb_add_hash_footer.go b/filesystem/avb_add_hash_footer.go
index 9d4ba3e..c1e03cb 100644
--- a/filesystem/avb_add_hash_footer.go
+++ b/filesystem/avb_add_hash_footer.go
@@ -46,7 +46,7 @@
type avbAddHashFooterProperties struct {
// Source file of this image. Can reference a genrule type module with the ":module" syntax.
- Src *string `android:"path,arch_variant"`
+ Src proptools.Configurable[string] `android:"path,arch_variant,replace_instead_of_append"`
// Set the name of the output. Defaults to <module_name>.img.
Filename *string
@@ -91,12 +91,13 @@
func (a *avbAddHashFooter) GenerateAndroidBuildActions(ctx android.ModuleContext) {
builder := android.NewRuleBuilder(pctx, ctx)
+ src := a.properties.Src.GetOrDefault(ctx, "")
- if a.properties.Src == nil {
+ if src == "" {
ctx.PropertyErrorf("src", "missing source file")
return
}
- input := android.PathForModuleSrc(ctx, proptools.String(a.properties.Src))
+ input := android.PathForModuleSrc(ctx, src)
output := android.PathForModuleOut(ctx, a.installFileName())
builder.Command().Text("cp").Input(input).Output(output)
@@ -148,6 +149,8 @@
a.installDir = android.PathForModuleInstall(ctx, "etc")
ctx.InstallFile(a.installDir, a.installFileName(), output)
a.output = output
+
+ setCommonFilesystemInfo(ctx, a)
}
func addAvbProp(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, prop avbProp) {
diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go
index 0a3a177..effbd65 100644
--- a/filesystem/bootimg.go
+++ b/filesystem/bootimg.go
@@ -99,6 +99,9 @@
// The index used to prevent rollback of the image on device.
Avb_rollback_index *int64
+ // Rollback index location of this image. Must be 0, 1, 2, etc.
+ Avb_rollback_index_location *int64
+
// The security patch passed to as the com.android.build.<type>.security_patch avb property.
// Replacement for the make variables BOOT_SECURITY_PATCH / INIT_BOOT_SECURITY_PATCH.
Security_patch *string
@@ -227,6 +230,8 @@
ramdiskModule := ctx.GetDirectDepWithTag(ramdisk, bootimgRamdiskDep)
fsInfo, _ := android.OtherModuleProvider(ctx, ramdiskModule, FilesystemProvider)
android.SetProvider(ctx, FilesystemProvider, fsInfo)
+ } else {
+ setCommonFilesystemInfo(ctx, b)
}
// Set BootimgInfo for building target_files.zip
@@ -235,6 +240,28 @@
Kernel: b.getKernelPath(ctx),
Dtb: b.getDtbPath(ctx),
Bootconfig: b.getBootconfigPath(ctx),
+ Output: output,
+ })
+
+ extractedPublicKey := android.PathForModuleOut(ctx, b.partitionName()+".avbpubkey")
+ if b.properties.Avb_private_key != nil {
+ key := android.PathForModuleSrc(ctx, proptools.String(b.properties.Avb_private_key))
+ ctx.Build(pctx, android.BuildParams{
+ Rule: extractPublicKeyRule,
+ Input: key,
+ Output: extractedPublicKey,
+ })
+ }
+ var ril int
+ if b.properties.Avb_rollback_index_location != nil {
+ ril = proptools.Int(b.properties.Avb_rollback_index_location)
+ }
+
+ android.SetProvider(ctx, vbmetaPartitionProvider, vbmetaPartitionInfo{
+ Name: b.bootImageType.String(),
+ RollbackIndexLocation: ril,
+ PublicKey: extractedPublicKey,
+ Output: output,
})
}
@@ -245,6 +272,7 @@
Kernel android.Path
Dtb android.Path
Bootconfig android.Path
+ Output android.Path
}
func (b *bootimg) getKernelPath(ctx android.ModuleContext) android.Path {
@@ -418,10 +446,6 @@
cmd.FlagWithArg("--rollback_index ", strconv.FormatInt(*b.properties.Avb_rollback_index, 10))
}
- if !ctx.Config().KatiEnabled() {
- copyImageFileToProductOut(ctx, builder, b.bootImageType.String(), output)
- }
-
builder.Build("add_avb_footer", fmt.Sprintf("Adding avb footer to %s", b.BaseModuleName()))
return output
}
@@ -437,10 +461,6 @@
Implicits(toolDeps).
Output(output)
- if !ctx.Config().KatiEnabled() {
- copyImageFileToProductOut(ctx, builder, b.bootImageType.String(), output)
- }
-
builder.Build("sign_bootimg", fmt.Sprintf("Signing %s", b.BaseModuleName()))
return output
}
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 993c46e..28eb36d 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -20,6 +20,7 @@
"io"
"path/filepath"
"slices"
+ "sort"
"strconv"
"strings"
@@ -32,9 +33,14 @@
"github.com/google/blueprint/proptools"
)
+var pctx = android.NewPackageContext("android/soong/filesystem")
+
func init() {
registerBuildComponents(android.InitRegistrationContext)
registerMutators(android.InitRegistrationContext)
+ pctx.HostBinToolVariable("fileslist", "fileslist")
+ pctx.HostBinToolVariable("fs_config", "fs_config")
+ pctx.HostBinToolVariable("symbols_map", "symbols_map")
}
func registerBuildComponents(ctx android.RegistrationContext) {
@@ -53,11 +59,28 @@
})
}
-// Remember to add referenced files to implicits!
-var textFileProcessorRule = pctx.AndroidStaticRule("text_file_processing", blueprint.RuleParams{
- Command: "build/soong/scripts/text_file_processor.py $in $out",
- CommandDeps: []string{"build/soong/scripts/text_file_processor.py"},
-})
+var (
+ // Remember to add referenced files to implicits!
+ textFileProcessorRule = pctx.AndroidStaticRule("text_file_processing", blueprint.RuleParams{
+ Command: "build/soong/scripts/text_file_processor.py $in $out",
+ CommandDeps: []string{"build/soong/scripts/text_file_processor.py"},
+ })
+
+ // Remember to add the output image file as an implicit dependency!
+ installedFilesJsonRule = pctx.AndroidStaticRule("installed_files_json", blueprint.RuleParams{
+ Command: `${fileslist} ${rootDir} > ${out}`,
+ CommandDeps: []string{"${fileslist}"},
+ }, "rootDir")
+
+ installedFilesTxtRule = pctx.AndroidStaticRule("installed_files_txt", blueprint.RuleParams{
+ Command: `build/make/tools/fileslist_util.py -c ${in} > ${out}`,
+ CommandDeps: []string{"build/make/tools/fileslist_util.py"},
+ })
+ fsConfigRule = pctx.AndroidStaticRule("fs_config_rule", blueprint.RuleParams{
+ Command: `(cd ${rootDir}; find . -type d | sed 's,$$,/,'; find . \! -type d) | cut -c 3- | sort | sed 's,^,${prefix},' | ${fs_config} -C -D ${rootDir} -R "${prefix}" > ${out}`,
+ CommandDeps: []string{"${fs_config}"},
+ }, "rootDir", "prefix")
+)
type filesystem struct {
android.ModuleBase
@@ -75,10 +98,12 @@
entries []string
filesystemBuilder filesystemBuilder
+
+ selinuxFc android.Path
}
type filesystemBuilder interface {
- BuildLinkerConfigFile(ctx android.ModuleContext, builder *android.RuleBuilder, rebasedDir android.OutputPath)
+ BuildLinkerConfigFile(ctx android.ModuleContext, builder *android.RuleBuilder, rebasedDir android.OutputPath, fullInstallPaths *[]FullInstallPathInfo)
// Function that filters PackagingSpec in PackagingBase.GatherPackagingSpecs()
FilterPackagingSpec(spec android.PackagingSpec) bool
// Function that modifies PackagingSpec in PackagingBase.GatherPackagingSpecs() to customize.
@@ -118,7 +143,7 @@
Avb_algorithm *string
// Hash algorithm used for avbtool (for descriptors). This is passed as hash_algorithm to
- // avbtool. Default used by avbtool is sha1.
+ // avbtool. Default is sha256.
Avb_hash_algorithm *string
// The security patch passed to as the com.android.build.<type>.security_patch avb property.
@@ -130,6 +155,9 @@
// The index used to prevent rollback of the image. Only used if use_avb is true.
Rollback_index *int64
+ // Rollback index location of this image. Must be 1, 2, 3, etc.
+ Rollback_index_location *int64
+
// Name of the partition stored in vbmeta desc. Defaults to the name of this module.
Partition_name *string
@@ -173,12 +201,6 @@
// Mount point for this image. Default is "/"
Mount_point *string
- // If set to the name of a partition ("system", "vendor", etc), this filesystem module
- // will also include the contents of the make-built staging directories. If any soong
- // modules would be installed to the same location as a make module, they will overwrite
- // the make version.
- Include_make_built_files string
-
// When set, builds etc/event-log-tags file by merging logtags from all dependencies.
// Default is false
Build_logtags *bool
@@ -218,6 +240,19 @@
// Name of the output. Default is $(module_name).img
Stem *string
+
+ // The size of the partition on the device. It will be a build error if this built partition
+ // image exceeds this size.
+ Partition_size *int64
+
+ // Whether to format f2fs and ext4 in a way that supports casefolding
+ Support_casefolding *bool
+
+ // Whether to format f2fs and ext4 in a way that supports project quotas
+ Support_project_quota *bool
+
+ // Whether to enable per-file compression in f2fs
+ Enable_compression *bool
}
type AndroidFilesystemDeps struct {
@@ -347,15 +382,94 @@
return fs == unknown
}
+type InstalledFilesStruct struct {
+ Txt android.Path
+ Json android.Path
+}
+
+type InstalledModuleInfo struct {
+ Name string
+ Variation string
+}
+
type FilesystemInfo struct {
// The built filesystem image
Output android.Path
+ // Returns the output file that is signed by avbtool. If this module is not signed, returns
+ // nil.
+ SignedOutputPath android.Path
+ // An additional hermetic filesystem image.
+ // e.g. this will contain inodes with pinned timestamps.
+ // This will be copied to target_files.zip
+ OutputHermetic android.Path
// A text file containing the list of paths installed on the partition.
FileListFile android.Path
// The root staging directory used to build the output filesystem. If consuming this, make sure
// to add a dependency on the Output file, as you cannot add dependencies on directories
// in ninja.
RootDir android.Path
+ // Extra root directories that are also built into the partition. Currently only used for
+ // including the recovery partition files into the vendor_boot image.
+ ExtraRootDirs android.Paths
+ // The rebased staging directory used to build the output filesystem. If consuming this, make
+ // sure to add a dependency on the Output file, as you cannot add dependencies on directories
+ // in ninja. In many cases this is the same as RootDir, only in the system partition is it
+ // different. There, it points to the "system" sub-directory of RootDir.
+ RebasedDir android.Path
+ // A text file with block data of the .img file
+ // This is an implicit output of `build_image`
+ MapFile android.Path
+ // Name of the module that produced this FilesystemInfo origionally. (though it may be
+ // re-exported by super images or boot images)
+ ModuleName string
+ // The property file generated by this module and passed to build_image.
+ // It's exported here so that system_other can reuse system's property file.
+ BuildImagePropFile android.Path
+ // Paths to all the tools referenced inside of the build image property file.
+ BuildImagePropFileDeps android.Paths
+ // Packaging specs to be installed on the system_other image, for the initial boot's dexpreopt.
+ SpecsForSystemOther map[string]android.PackagingSpec
+
+ FullInstallPaths []FullInstallPathInfo
+
+ // Installed files list
+ InstalledFiles InstalledFilesStruct
+
+ // Path to compress hints file for erofs filesystems
+ // This will be nil for other fileystems like ext4
+ ErofsCompressHints android.Path
+
+ SelinuxFc android.Path
+
+ FilesystemConfig android.Path
+
+ Owners []InstalledModuleInfo
+}
+
+// FullInstallPathInfo contains information about the "full install" paths of all the files
+// inside this partition. The full install paths are the files installed in
+// out/target/product/<device>/<partition>. This is essentially legacy behavior, maintained for
+// tools like adb sync and adevice, but we should update them to query the build system for the
+// installed files no matter where they are.
+type FullInstallPathInfo struct {
+ // RequiresFullInstall tells us if the origional module did the install to FullInstallPath
+ // already. If it's false, the android_device module needs to emit the install rule.
+ RequiresFullInstall bool
+ // The "full install" paths for the files in this filesystem. This is the paths in the
+ // out/target/product/<device>/<partition> folder. They're not used by this filesystem,
+ // but can be depended on by the top-level android_device module to cause the staging
+ // directories to be built.
+ FullInstallPath android.InstallPath
+
+ // The file that's copied to FullInstallPath. May be nil if SymlinkTarget is set or IsDir is
+ // true.
+ SourcePath android.Path
+
+ // The target of the symlink, if this file is a symlink.
+ SymlinkTarget string
+
+ // If this file is a directory. Only used for empty directories, which are mostly mount points.
+ IsDir bool
}
var FilesystemProvider = blueprint.NewProvider[FilesystemInfo]()
@@ -408,6 +522,13 @@
if ps.SkipInstall() {
return false
}
+ // "apex" is a fake partition used to install files in out/target/product/<device>/apex/.
+ // Don't include these files in the partition. We should also look into removing the following
+ // TODO to check the PackagingSpec's partition against this filesystem's partition for all
+ // modules, not just autogenerated ones, which will fix this as well.
+ if ps.Partition() == "apex" {
+ return false
+ }
if proptools.Bool(f.properties.Is_auto_generated) { // TODO (spandandas): Remove this.
pt := f.PartitionType()
return ps.Partition() == pt || strings.HasPrefix(ps.Partition(), pt+"/")
@@ -430,7 +551,33 @@
}
}
-var pctx = android.NewPackageContext("android/soong/filesystem")
+func buildInstalledFiles(ctx android.ModuleContext, partition string, rootDir android.Path, image android.Path) (txt android.ModuleOutPath, json android.ModuleOutPath) {
+ fileName := "installed-files"
+ if len(partition) > 0 {
+ fileName += fmt.Sprintf("-%s", partition)
+ }
+ txt = android.PathForModuleOut(ctx, fmt.Sprintf("%s.txt", fileName))
+ json = android.PathForModuleOut(ctx, fmt.Sprintf("%s.json", fileName))
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: installedFilesJsonRule,
+ Implicit: image,
+ Output: json,
+ Description: "Installed file list json",
+ Args: map[string]string{
+ "rootDir": rootDir.String(),
+ },
+ })
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: installedFilesTxtRule,
+ Input: json,
+ Output: txt,
+ Description: "Installed file list txt",
+ })
+
+ return txt, json
+}
func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) {
validatePartitionType(ctx, f)
@@ -442,14 +589,61 @@
ctx.PropertyErrorf("include_files_of", "include_files_of is only supported for cpio and compressed cpio filesystem types.")
}
- var rootDir android.OutputPath
+ rootDir := android.PathForModuleOut(ctx, f.rootDirString()).OutputPath
+ rebasedDir := rootDir
+ if f.properties.Base_dir != nil {
+ rebasedDir = rootDir.Join(ctx, *f.properties.Base_dir)
+ }
+ builder := android.NewRuleBuilder(pctx, ctx)
+
+ // Wipe the root dir to get rid of leftover files from prior builds
+ builder.Command().Textf("rm -rf %s && mkdir -p %s", rootDir, rootDir)
+ specs := f.gatherFilteredPackagingSpecs(ctx)
+
+ var fullInstallPaths []FullInstallPathInfo
+ for _, specRel := range android.SortedKeys(specs) {
+ spec := specs[specRel]
+ fullInstallPaths = append(fullInstallPaths, FullInstallPathInfo{
+ FullInstallPath: spec.FullInstallPath(),
+ RequiresFullInstall: spec.RequiresFullInstall(),
+ SourcePath: spec.SrcPath(),
+ SymlinkTarget: spec.ToGob().SymlinkTarget,
+ })
+ }
+
+ f.entries = f.copyPackagingSpecs(ctx, builder, specs, rootDir, rebasedDir)
+ f.buildNonDepsFiles(ctx, builder, rootDir, rebasedDir, &fullInstallPaths)
+ f.buildFsverityMetadataFiles(ctx, builder, specs, rootDir, rebasedDir, &fullInstallPaths)
+ f.buildEventLogtagsFile(ctx, builder, rebasedDir, &fullInstallPaths)
+ f.buildAconfigFlagsFiles(ctx, builder, specs, rebasedDir, &fullInstallPaths)
+ f.filesystemBuilder.BuildLinkerConfigFile(ctx, builder, rebasedDir, &fullInstallPaths)
+ // Assemeble the staging dir and output a timestamp
+ builder.Command().Text("touch").Output(f.fileystemStagingDirTimestamp(ctx))
+ builder.Build("assemble_filesystem_staging_dir", fmt.Sprintf("Assemble filesystem staging dir %s", f.BaseModuleName()))
+
+ // Create a new rule builder for build_image
+ builder = android.NewRuleBuilder(pctx, ctx)
+ var mapFile android.Path
+ var outputHermetic android.WritablePath
+ var buildImagePropFile android.Path
+ var buildImagePropFileDeps android.Paths
+ var extraRootDirs android.Paths
switch f.fsType(ctx) {
case ext4Type, erofsType, f2fsType:
- f.output, rootDir = f.buildImageUsingBuildImage(ctx)
+ buildImagePropFile, buildImagePropFileDeps = f.buildPropFile(ctx)
+ output := android.PathForModuleOut(ctx, f.installFileName())
+ f.buildImageUsingBuildImage(ctx, builder, buildImageParams{rootDir, buildImagePropFile, buildImagePropFileDeps, output})
+ f.output = output
+ // Create the hermetic img file using a separate rule builder so that it can be built independently
+ hermeticBuilder := android.NewRuleBuilder(pctx, ctx)
+ outputHermetic = android.PathForModuleOut(ctx, "for_target_files", f.installFileName())
+ propFileHermetic := f.propFileForHermeticImg(ctx, hermeticBuilder, buildImagePropFile)
+ f.buildImageUsingBuildImage(ctx, hermeticBuilder, buildImageParams{rootDir, propFileHermetic, buildImagePropFileDeps, outputHermetic})
+ mapFile = f.getMapFile(ctx)
case compressedCpioType:
- f.output, rootDir = f.buildCpioImage(ctx, true)
+ f.output, extraRootDirs = f.buildCpioImage(ctx, builder, rootDir, true)
case cpioType:
- f.output, rootDir = f.buildCpioImage(ctx, false)
+ f.output, extraRootDirs = f.buildCpioImage(ctx, builder, rootDir, false)
default:
return
}
@@ -465,17 +659,108 @@
fileListFile := android.PathForModuleOut(ctx, "fileList")
android.WriteFileRule(ctx, fileListFile, f.installedFilesList())
- android.SetProvider(ctx, FilesystemProvider, FilesystemInfo{
- Output: f.output,
- FileListFile: fileListFile,
- RootDir: rootDir,
- })
+ partitionName := f.partitionName()
+ if partitionName == "system" {
+ partitionName = ""
+ }
+ installedFileTxt, installedFileJson := buildInstalledFiles(ctx, partitionName, rootDir, f.output)
+
+ var erofsCompressHints android.Path
+ if f.properties.Erofs.Compress_hints != nil {
+ erofsCompressHints = android.PathForModuleSrc(ctx, *f.properties.Erofs.Compress_hints)
+ }
+
+ fsInfo := FilesystemInfo{
+ Output: f.OutputPath(),
+ SignedOutputPath: f.SignedOutputPath(),
+ OutputHermetic: outputHermetic,
+ FileListFile: fileListFile,
+ RootDir: rootDir,
+ ExtraRootDirs: extraRootDirs,
+ RebasedDir: rebasedDir,
+ MapFile: mapFile,
+ ModuleName: ctx.ModuleName(),
+ BuildImagePropFile: buildImagePropFile,
+ BuildImagePropFileDeps: buildImagePropFileDeps,
+ SpecsForSystemOther: f.systemOtherFiles(ctx),
+ FullInstallPaths: fullInstallPaths,
+ InstalledFiles: InstalledFilesStruct{
+ Txt: installedFileTxt,
+ Json: installedFileJson,
+ },
+ ErofsCompressHints: erofsCompressHints,
+ SelinuxFc: f.selinuxFc,
+ FilesystemConfig: f.generateFilesystemConfig(ctx, rootDir, rebasedDir),
+ Owners: f.gatherOwners(specs),
+ }
+
+ android.SetProvider(ctx, FilesystemProvider, fsInfo)
f.fileListFile = fileListFile
if proptools.Bool(f.properties.Unchecked_module) {
ctx.UncheckedModule()
}
+
+ f.setVbmetaPartitionProvider(ctx)
+}
+
+func (f *filesystem) fileystemStagingDirTimestamp(ctx android.ModuleContext) android.WritablePath {
+ return android.PathForModuleOut(ctx, "staging_dir.timestamp")
+}
+
+func (f *filesystem) generateFilesystemConfig(ctx android.ModuleContext, rootDir android.Path, rebasedDir android.Path) android.Path {
+ rootDirString := rootDir.String()
+ prefix := f.partitionName() + "/"
+ if f.partitionName() == "system" {
+ rootDirString = rebasedDir.String()
+ }
+ if f.partitionName() == "ramdisk" || f.partitionName() == "recovery" {
+ // Hardcoded to match make behavior.
+ // https://cs.android.com/android/_/android/platform/build/+/2a0ef42a432d4da00201e8eb7697dcaa68fd2389:core/Makefile;l=6957-6962;drc=9ea8ad9232cef4d0a24d70133b1b9d2ce2defe5f;bpv=1;bpt=0
+ prefix = ""
+ }
+ out := android.PathForModuleOut(ctx, "filesystem_config.txt")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: fsConfigRule,
+ Input: f.fileystemStagingDirTimestamp(ctx), // assemble the staging directory
+ Output: out,
+ Args: map[string]string{
+ "rootDir": rootDirString,
+ "prefix": prefix,
+ },
+ })
+ return out
+}
+
+func (f *filesystem) setVbmetaPartitionProvider(ctx android.ModuleContext) {
+ var extractedPublicKey android.ModuleOutPath
+ if f.properties.Avb_private_key != nil {
+ key := android.PathForModuleSrc(ctx, proptools.String(f.properties.Avb_private_key))
+ extractedPublicKey = android.PathForModuleOut(ctx, f.partitionName()+".avbpubkey")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: extractPublicKeyRule,
+ Input: key,
+ Output: extractedPublicKey,
+ })
+ }
+
+ var ril int
+ if f.properties.Rollback_index_location != nil {
+ ril = proptools.Int(f.properties.Rollback_index_location)
+ }
+
+ android.SetProvider(ctx, vbmetaPartitionProvider, vbmetaPartitionInfo{
+ Name: f.partitionName(),
+ RollbackIndexLocation: ril,
+ PublicKey: extractedPublicKey,
+ Output: f.output,
+ })
+}
+
+func (f *filesystem) getMapFile(ctx android.ModuleContext) android.WritablePath {
+ // create the filepath by replacing the extension of the corresponding img file
+ return android.PathForModuleOut(ctx, f.installFileName()).ReplaceExtension(ctx, "map")
}
func (f *filesystem) validateVintfFragments(ctx android.ModuleContext) {
@@ -549,11 +834,36 @@
// Copy extra files/dirs that are not from the `deps` property to `rootDir`, checking for conflicts with files
// already in `rootDir`.
-func (f *filesystem) buildNonDepsFiles(ctx android.ModuleContext, builder *android.RuleBuilder, rootDir android.OutputPath) {
+func (f *filesystem) buildNonDepsFiles(
+ ctx android.ModuleContext,
+ builder *android.RuleBuilder,
+ rootDir android.OutputPath,
+ rebasedDir android.OutputPath,
+ fullInstallPaths *[]FullInstallPathInfo,
+) {
+ rebasedPrefix, err := filepath.Rel(rootDir.String(), rebasedDir.String())
+ if err != nil || strings.HasPrefix(rebasedPrefix, "../") {
+ panic("rebasedDir could not be made relative to rootDir")
+ }
+ if !strings.HasSuffix(rebasedPrefix, "/") {
+ rebasedPrefix += "/"
+ }
+ if rebasedPrefix == "./" {
+ rebasedPrefix = ""
+ }
+
// create dirs and symlinks
for _, dir := range f.properties.Dirs.GetOrDefault(ctx, nil) {
// OutputPath.Join verifies dir
builder.Command().Text("mkdir -p").Text(rootDir.Join(ctx, dir).String())
+ // Only add the fullInstallPath logic for files in the rebased dir. The root dir
+ // is harder to install to.
+ if strings.HasPrefix(dir, rebasedPrefix) {
+ *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{
+ FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), strings.TrimPrefix(dir, rebasedPrefix)),
+ IsDir: true,
+ })
+ }
}
for _, symlink := range f.properties.Symlinks {
@@ -576,6 +886,14 @@
builder.Command().Text("mkdir -p").Text(filepath.Dir(dst.String()))
builder.Command().Text("ln -sf").Text(proptools.ShellEscape(target)).Text(dst.String())
f.appendToEntry(ctx, dst)
+ // Only add the fullInstallPath logic for files in the rebased dir. The root dir
+ // is harder to install to.
+ if strings.HasPrefix(name, rebasedPrefix) {
+ *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{
+ FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), strings.TrimPrefix(name, rebasedPrefix)),
+ SymlinkTarget: target,
+ })
+ }
}
// https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=2835;drc=b186569ef00ff2f2a1fab28aedc75ebc32bcd67b
@@ -601,55 +919,35 @@
dirsToSpecs[rootDir] = rootDirSpecs
dirsToSpecs[rebasedDir] = rebasedDirSpecs
- return f.CopySpecsToDirs(ctx, builder, dirsToSpecs)
-}
-
-func (f *filesystem) copyFilesToProductOut(ctx android.ModuleContext, builder *android.RuleBuilder, rebasedDir android.OutputPath) {
- if !(f.Name() == ctx.Config().SoongDefinedSystemImage() || proptools.Bool(f.properties.Is_auto_generated)) {
- return
- }
- installPath := android.PathForModuleInPartitionInstall(ctx, f.partitionName())
- builder.Command().Textf("rsync --checksum %s %s", rebasedDir, installPath)
-}
-
-func copyImageFileToProductOut(ctx android.ModuleContext, builder *android.RuleBuilder, partition string, output android.Path) {
- copyDir := android.PathForModuleInPartitionInstall(ctx, "").Join(ctx, fmt.Sprintf("%s.img", partition))
- builder.Command().Textf("rsync -a %s %s", output, copyDir)
+ // Preserve timestamps for adb sync, so that this staging dir file matches the timestamp in the
+ // out/target/product staging directory.
+ return f.CopySpecsToDirs(ctx, builder, dirsToSpecs, true)
}
func (f *filesystem) rootDirString() string {
return f.partitionName()
}
-func (f *filesystem) buildImageUsingBuildImage(ctx android.ModuleContext) (android.Path, android.OutputPath) {
- rootDir := android.PathForModuleOut(ctx, f.rootDirString()).OutputPath
- rebasedDir := rootDir
- if f.properties.Base_dir != nil {
- rebasedDir = rootDir.Join(ctx, *f.properties.Base_dir)
- }
- builder := android.NewRuleBuilder(pctx, ctx)
- // Wipe the root dir to get rid of leftover files from prior builds
- builder.Command().Textf("rm -rf %s && mkdir -p %s", rootDir, rootDir)
- specs := f.gatherFilteredPackagingSpecs(ctx)
- f.entries = f.copyPackagingSpecs(ctx, builder, specs, rootDir, rebasedDir)
+type buildImageParams struct {
+ // inputs
+ rootDir android.OutputPath
+ propFile android.Path
+ toolDeps android.Paths
+ // outputs
+ output android.WritablePath
+}
- f.buildNonDepsFiles(ctx, builder, rootDir)
- f.addMakeBuiltFiles(ctx, builder, rootDir)
- f.buildFsverityMetadataFiles(ctx, builder, specs, rootDir, rebasedDir)
- f.buildEventLogtagsFile(ctx, builder, rebasedDir)
- f.buildAconfigFlagsFiles(ctx, builder, specs, rebasedDir)
- f.filesystemBuilder.BuildLinkerConfigFile(ctx, builder, rebasedDir)
- f.copyFilesToProductOut(ctx, builder, rebasedDir)
-
+func (f *filesystem) buildImageUsingBuildImage(
+ ctx android.ModuleContext,
+ builder *android.RuleBuilder,
+ params buildImageParams) {
// run host_init_verifier
// Ideally we should have a concept of pluggable linters that verify the generated image.
// While such concept is not implement this will do.
// TODO(b/263574231): substitute with pluggable linter.
builder.Command().
BuiltTool("host_init_verifier").
- FlagWithArg("--out_system=", rootDir.String()+"/system")
-
- propFile, toolDeps := f.buildPropFile(ctx)
+ FlagWithArg("--out_system=", params.rootDir.String()+"/system")
// Most of the time, if build_image were to call a host tool, it accepts the path to the
// host tool in a field in the prop file. However, it doesn't have that option for fec, which
@@ -657,25 +955,32 @@
fec := ctx.Config().HostToolPath(ctx, "fec")
pathToolDirs := []string{filepath.Dir(fec.String())}
- output := android.PathForModuleOut(ctx, f.installFileName())
builder.Command().
Textf("PATH=%s:$PATH", strings.Join(pathToolDirs, ":")).
BuiltTool("build_image").
- Text(rootDir.String()). // input directory
- Input(propFile).
- Implicits(toolDeps).
+ Text(params.rootDir.String()). // input directory
+ Input(params.propFile).
+ Implicits(params.toolDeps).
Implicit(fec).
- Output(output).
- Text(rootDir.String()) // directory where to find fs_config_files|dirs
+ Implicit(f.fileystemStagingDirTimestamp(ctx)). // assemble the staging directory
+ Output(params.output).
+ Text(params.rootDir.String()) // directory where to find fs_config_files|dirs
- if !ctx.Config().KatiEnabled() {
- copyImageFileToProductOut(ctx, builder, f.partitionName(), output)
+ if f.properties.Partition_size != nil {
+ assertMaxImageSize(builder, params.output, *f.properties.Partition_size, false)
}
// rootDir is not deleted. Might be useful for quick inspection.
- builder.Build("build_filesystem_image", fmt.Sprintf("Creating filesystem %s", f.BaseModuleName()))
+ builder.Build("build_"+params.output.String(), fmt.Sprintf("Creating filesystem %s", f.BaseModuleName()))
+}
- return output, rootDir
+func (f *filesystem) propFileForHermeticImg(ctx android.ModuleContext, builder *android.RuleBuilder, inputPropFile android.Path) android.Path {
+ propFilePinnedTimestamp := android.PathForModuleOut(ctx, "for_target_files", "prop")
+ builder.Command().Textf("cat").Input(inputPropFile).Flag(">").Output(propFilePinnedTimestamp).
+ Textf(" && echo use_fixed_timestamp=true >> %s", propFilePinnedTimestamp).
+ Textf(" && echo block_list=%s >> %s", f.getMapFile(ctx).String(), propFilePinnedTimestamp) // mapfile will be an implicit output
+ builder.Command().Text("touch").Output(f.getMapFile(ctx))
+ return propFilePinnedTimestamp
}
func (f *filesystem) buildFileContexts(ctx android.ModuleContext) android.Path {
@@ -690,12 +995,9 @@
func (f *filesystem) buildPropFile(ctx android.ModuleContext) (android.Path, android.Paths) {
var deps android.Paths
- var propFileString strings.Builder
+ var lines []string
addStr := func(name string, value string) {
- propFileString.WriteString(name)
- propFileString.WriteRune('=')
- propFileString.WriteString(value)
- propFileString.WriteRune('\n')
+ lines = append(lines, fmt.Sprintf("%s=%s", name, value))
}
addPath := func(name string, path android.Path) {
addStr(name, path.String())
@@ -739,9 +1041,8 @@
if !proptools.BoolDefault(f.properties.Use_fec, true) {
avb_add_hashtree_footer_args += " --do_not_generate_fec"
}
- if hashAlgorithm := proptools.String(f.properties.Avb_hash_algorithm); hashAlgorithm != "" {
- avb_add_hashtree_footer_args += " --hash_algorithm " + hashAlgorithm
- }
+ hashAlgorithm := proptools.StringDefault(f.properties.Avb_hash_algorithm, "sha256")
+ avb_add_hashtree_footer_args += " --hash_algorithm " + hashAlgorithm
if f.properties.Rollback_index != nil {
rollbackIndex := proptools.Int(f.properties.Rollback_index)
if rollbackIndex < 0 {
@@ -763,12 +1064,12 @@
if f.properties.File_contexts != nil && f.properties.Precompiled_file_contexts != nil {
ctx.ModuleErrorf("file_contexts and precompiled_file_contexts cannot both be set")
} else if f.properties.File_contexts != nil {
- addPath("selinux_fc", f.buildFileContexts(ctx))
+ f.selinuxFc = f.buildFileContexts(ctx)
} else if f.properties.Precompiled_file_contexts != nil {
- src := android.PathForModuleSrc(ctx, *f.properties.Precompiled_file_contexts)
- if src != nil {
- addPath("selinux_fc", src)
- }
+ f.selinuxFc = android.PathForModuleSrc(ctx, *f.properties.Precompiled_file_contexts)
+ }
+ if f.selinuxFc != nil {
+ addPath("selinux_fc", f.selinuxFc)
}
if timestamp := proptools.String(f.properties.Fake_timestamp); timestamp != "" {
addStr("timestamp", timestamp)
@@ -781,12 +1082,11 @@
addStr("hash_seed", uuid)
}
- // TODO(b/381120092): This should only be added if none of the size-related properties are set,
- // but currently soong built partitions don't have size properties. Make code:
- // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=2262;drc=39cd33701c9278db0e7e481a090605f428d5b12d
- // Make uses system_disable_sparse but disable_sparse has the same effect, and we shouldn't need
- // to qualify it because each partition gets its own property file built.
- addStr("disable_sparse", "true")
+ // Disable sparse only when partition size is not defined. disable_sparse has the same
+ // effect as <partition name>_disable_sparse.
+ if f.properties.Partition_size == nil {
+ addStr("disable_sparse", "true")
+ }
fst := f.fsType(ctx)
switch fst {
@@ -809,8 +1109,26 @@
}
f.checkFsTypePropertyError(ctx, fst, fsTypeStr(fst))
+ if f.properties.Partition_size != nil {
+ addStr("partition_size", strconv.FormatInt(*f.properties.Partition_size, 10))
+ }
+
+ if proptools.BoolDefault(f.properties.Support_casefolding, false) {
+ addStr("needs_casefold", "1")
+ }
+
+ if proptools.BoolDefault(f.properties.Support_project_quota, false) {
+ addStr("needs_projid", "1")
+ }
+
+ if proptools.BoolDefault(f.properties.Enable_compression, false) {
+ addStr("needs_compress", "1")
+ }
+
+ sort.Strings(lines)
+
propFilePreProcessing := android.PathForModuleOut(ctx, "prop_pre_processing")
- android.WriteFileRuleVerbatim(ctx, propFilePreProcessing, propFileString.String())
+ android.WriteFileRule(ctx, propFilePreProcessing, strings.Join(lines, "\n"))
propFile := android.PathForModuleOut(ctx, "prop")
ctx.Build(pctx, android.BuildParams{
Rule: textFileProcessorRule,
@@ -853,7 +1171,12 @@
return rootDirs, partitions
}
-func (f *filesystem) buildCpioImage(ctx android.ModuleContext, compressed bool) (android.Path, android.OutputPath) {
+func (f *filesystem) buildCpioImage(
+ ctx android.ModuleContext,
+ builder *android.RuleBuilder,
+ rootDir android.OutputPath,
+ compressed bool,
+) (android.Path, android.Paths) {
if proptools.Bool(f.properties.Use_avb) {
ctx.PropertyErrorf("use_avb", "signing compresed cpio image using avbtool is not supported."+
"Consider adding this to bootimg module and signing the entire boot image.")
@@ -863,33 +1186,12 @@
ctx.PropertyErrorf("file_contexts", "file_contexts is not supported for compressed cpio image.")
}
- if f.properties.Include_make_built_files != "" {
- ctx.PropertyErrorf("include_make_built_files", "include_make_built_files is not supported for compressed cpio image.")
- }
-
- rootDir := android.PathForModuleOut(ctx, f.rootDirString()).OutputPath
- rebasedDir := rootDir
- if f.properties.Base_dir != nil {
- rebasedDir = rootDir.Join(ctx, *f.properties.Base_dir)
- }
- builder := android.NewRuleBuilder(pctx, ctx)
- // Wipe the root dir to get rid of leftover files from prior builds
- builder.Command().Textf("rm -rf %s && mkdir -p %s", rootDir, rootDir)
- specs := f.gatherFilteredPackagingSpecs(ctx)
- f.entries = f.copyPackagingSpecs(ctx, builder, specs, rootDir, rebasedDir)
-
- f.buildNonDepsFiles(ctx, builder, rootDir)
- f.buildFsverityMetadataFiles(ctx, builder, specs, rootDir, rebasedDir)
- f.buildEventLogtagsFile(ctx, builder, rebasedDir)
- f.buildAconfigFlagsFiles(ctx, builder, specs, rebasedDir)
- f.filesystemBuilder.BuildLinkerConfigFile(ctx, builder, rebasedDir)
- f.copyFilesToProductOut(ctx, builder, rebasedDir)
-
rootDirs, partitions := includeFilesRootDir(ctx)
output := android.PathForModuleOut(ctx, f.installFileName())
cmd := builder.Command().
BuiltTool("mkbootfs").
+ Implicit(f.fileystemStagingDirTimestamp(ctx)).
Text(rootDir.String()) // input directory
for i := range len(rootDirs) {
@@ -914,7 +1216,7 @@
// rootDir is not deleted. Might be useful for quick inspection.
builder.Build("build_cpio_image", fmt.Sprintf("Creating filesystem %s", f.BaseModuleName()))
- return output, rootDir
+ return output, rootDirs
}
var validPartitions = []string{
@@ -934,28 +1236,12 @@
"recovery",
}
-func (f *filesystem) addMakeBuiltFiles(ctx android.ModuleContext, builder *android.RuleBuilder, rootDir android.Path) {
- partition := f.properties.Include_make_built_files
- if partition == "" {
- return
- }
- if !slices.Contains(validPartitions, partition) {
- ctx.PropertyErrorf("include_make_built_files", "Expected one of %#v, found %q", validPartitions, partition)
- return
- }
- stampFile := fmt.Sprintf("target/product/%s/obj/PACKAGING/%s_intermediates/staging_dir.stamp", ctx.Config().DeviceName(), partition)
- fileListFile := fmt.Sprintf("target/product/%s/obj/PACKAGING/%s_intermediates/file_list.txt", ctx.Config().DeviceName(), partition)
- stagingDir := fmt.Sprintf("target/product/%s/%s", ctx.Config().DeviceName(), partition)
-
- builder.Command().BuiltTool("merge_directories").
- Implicit(android.PathForArbitraryOutput(ctx, stampFile)).
- Text("--ignore-duplicates").
- FlagWithInput("--file-list", android.PathForArbitraryOutput(ctx, fileListFile)).
- Text(rootDir.String()).
- Text(android.PathForArbitraryOutput(ctx, stagingDir).String())
-}
-
-func (f *filesystem) buildEventLogtagsFile(ctx android.ModuleContext, builder *android.RuleBuilder, rebasedDir android.OutputPath) {
+func (f *filesystem) buildEventLogtagsFile(
+ ctx android.ModuleContext,
+ builder *android.RuleBuilder,
+ rebasedDir android.OutputPath,
+ fullInstallPaths *[]FullInstallPathInfo,
+) {
if !proptools.Bool(f.properties.Build_logtags) {
return
}
@@ -965,10 +1251,20 @@
builder.Command().Text("mkdir").Flag("-p").Text(etcPath.String())
builder.Command().Text("cp").Input(android.MergedLogtagsPath(ctx)).Text(eventLogtagsPath.String())
+ *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{
+ FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), "etc", "event-log-tags"),
+ SourcePath: android.MergedLogtagsPath(ctx),
+ })
+
f.appendToEntry(ctx, eventLogtagsPath)
}
-func (f *filesystem) BuildLinkerConfigFile(ctx android.ModuleContext, builder *android.RuleBuilder, rebasedDir android.OutputPath) {
+func (f *filesystem) BuildLinkerConfigFile(
+ ctx android.ModuleContext,
+ builder *android.RuleBuilder,
+ rebasedDir android.OutputPath,
+ fullInstallPaths *[]FullInstallPathInfo,
+) {
if !proptools.Bool(f.properties.Linker_config.Gen_linker_config) {
return
}
@@ -979,6 +1275,11 @@
output := rebasedDir.Join(ctx, "etc", "linker.config.pb")
builder.Command().Text("cp").Input(intermediateOutput).Output(output)
+ *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{
+ FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), "etc", "linker.config.pb"),
+ SourcePath: intermediateOutput,
+ })
+
f.appendToEntry(ctx, output)
}
@@ -1041,8 +1342,33 @@
// Note that "apex" module installs its contents to "apex"(fake partition) as well
// for symbol lookup by imitating "activated" paths.
func (f *filesystem) gatherFilteredPackagingSpecs(ctx android.ModuleContext) map[string]android.PackagingSpec {
- specs := f.PackagingBase.GatherPackagingSpecsWithFilterAndModifier(ctx, f.filesystemBuilder.FilterPackagingSpec, f.filesystemBuilder.ModifyPackagingSpec)
- return specs
+ return f.PackagingBase.GatherPackagingSpecsWithFilterAndModifier(ctx, f.filesystemBuilder.FilterPackagingSpec, f.filesystemBuilder.ModifyPackagingSpec)
+}
+
+func (f *filesystem) gatherOwners(specs map[string]android.PackagingSpec) []InstalledModuleInfo {
+ var owners []InstalledModuleInfo
+ for _, p := range android.SortedKeys(specs) {
+ spec := specs[p]
+ owners = append(owners, InstalledModuleInfo{
+ Name: spec.Owner(),
+ Variation: spec.Variation(),
+ })
+ }
+ return owners
+}
+
+// Dexpreopt files are installed to system_other. Collect the packaingSpecs for the dexpreopt files
+// from this partition to export to the system_other partition later.
+func (f *filesystem) systemOtherFiles(ctx android.ModuleContext) map[string]android.PackagingSpec {
+ filter := func(spec android.PackagingSpec) bool {
+ // For some reason system_other packaging specs don't set the partition field.
+ return strings.HasPrefix(spec.RelPathInPackage(), "system_other/")
+ }
+ modifier := func(spec *android.PackagingSpec) {
+ spec.SetRelPathInPackage(strings.TrimPrefix(spec.RelPathInPackage(), "system_other/"))
+ spec.SetPartition("system_other")
+ }
+ return f.PackagingBase.GatherPackagingSpecsWithFilterAndModifier(ctx, filter, modifier)
}
func sha1sum(values []string) string {
@@ -1198,3 +1524,16 @@
return true
})
}
+
+func (f *filesystem) MakeVars(ctx android.MakeVarsModuleContext) {
+ if f.Name() == ctx.Config().SoongDefinedSystemImage() {
+ ctx.StrictRaw("SOONG_DEFINED_SYSTEM_IMAGE_PATH", f.output.String())
+ }
+}
+
+func setCommonFilesystemInfo(ctx android.ModuleContext, m Filesystem) {
+ android.SetProvider(ctx, FilesystemProvider, FilesystemInfo{
+ Output: m.OutputPath(),
+ SignedOutputPath: m.SignedOutputPath(),
+ })
+}
diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go
index 33cddf8..6d0b490 100644
--- a/filesystem/filesystem_test.go
+++ b/filesystem/filesystem_test.go
@@ -118,9 +118,9 @@
`)
// produces "myfilesystem.img"
- result.ModuleForTests("myfilesystem", "android_common").Output("myfilesystem.img")
+ result.ModuleForTests(t, "myfilesystem", "android_common").Output("myfilesystem.img")
- fs := result.ModuleForTests("myfilesystem", "android_common").Module().(*filesystem)
+ fs := result.ModuleForTests(t, "myfilesystem", "android_common").Module().(*filesystem)
expected := []string{
"app/myapp/myapp.apk",
"bin/foo",
@@ -136,22 +136,6 @@
}
}
-func TestIncludeMakeBuiltFiles(t *testing.T) {
- result := fixture.RunTestWithBp(t, `
- android_filesystem {
- name: "myfilesystem",
- include_make_built_files: "system",
- }
- `)
-
- output := result.ModuleForTests("myfilesystem", "android_common").Output("myfilesystem.img")
-
- stampFile := "out/target/product/test_device/obj/PACKAGING/system_intermediates/staging_dir.stamp"
- fileListFile := "out/target/product/test_device/obj/PACKAGING/system_intermediates/file_list.txt"
- android.AssertStringListContains(t, "deps of filesystem must include the staging dir stamp file", output.Implicits.Strings(), stampFile)
- android.AssertStringListContains(t, "deps of filesystem must include the staging dir file list", output.Implicits.Strings(), fileListFile)
-}
-
func TestFileSystemFillsLinkerConfigWithStubLibs(t *testing.T) {
result := fixture.RunTestWithBp(t, `
android_system_image {
@@ -179,7 +163,7 @@
}
`)
- module := result.ModuleForTests("myfilesystem", "android_common")
+ module := result.ModuleForTests(t, "myfilesystem", "android_common")
output := module.Output("out/soong/.intermediates/myfilesystem/android_common/linker.config.pb")
linkerConfigCommand := output.RuleParams.Command
@@ -240,7 +224,7 @@
}
`)
- module := result.ModuleForTests("myfilesystem", "android_common").Module().(*systemImage)
+ module := result.ModuleForTests(t, "myfilesystem", "android_common").Module().(*systemImage)
android.AssertDeepEquals(t, "entries should have foo and not bar", []string{"components/foo", "etc/linker.config.pb"}, module.entries)
}
@@ -252,7 +236,7 @@
partition_name: "input_partition_name",
salt: "2222",
}`)
- cmd := result.ModuleForTests("input_hashdesc", "android_arm64_armv8-a").Rule("avbGenVbmetaImage").RuleParams.Command
+ cmd := result.ModuleForTests(t, "input_hashdesc", "android_arm64_armv8-a").Rule("avbGenVbmetaImage").RuleParams.Command
android.AssertStringDoesContain(t, "Can't find correct --partition_name argument",
cmd, "--partition_name input_partition_name")
android.AssertStringDoesContain(t, "Can't find --do_not_append_vbmeta_image",
@@ -292,7 +276,7 @@
include_descriptors_from_images: ["input_hashdesc"],
}
`)
- cmd := result.ModuleForTests("myfooter", "android_arm64_armv8-a").Rule("avbAddHashFooter").RuleParams.Command
+ cmd := result.ModuleForTests(t, "myfooter", "android_arm64_armv8-a").Rule("avbAddHashFooter").RuleParams.Command
android.AssertStringDoesContain(t, "Can't find correct --partition_name argument",
cmd, "--partition_name mypartition")
android.AssertStringDoesContain(t, "Can't find correct --key argument",
@@ -347,8 +331,8 @@
}
`)
- filesystem := result.ModuleForTests("myfilesystem", "android_common_cov")
- inputs := filesystem.Output("myfilesystem.img").Implicits
+ filesystem := result.ModuleForTests(t, "myfilesystem", "android_common_cov")
+ inputs := filesystem.Output("staging_dir.timestamp").Implicits
android.AssertStringListContains(t, "filesystem should have libfoo(cov)",
inputs.Strings(),
"out/soong/.intermediates/libfoo/android_arm64_armv8-a_shared_cov/libfoo.so")
@@ -356,8 +340,8 @@
inputs.Strings(),
"out/soong/.intermediates/libbar/android_arm64_armv8-a_shared_cov/libbar.so")
- filesystemOutput := filesystem.Output("myfilesystem.img").Output
- prebuiltInput := result.ModuleForTests("prebuilt", "android_arm64_armv8-a").Rule("Cp").Input
+ filesystemOutput := filesystem.OutputFiles(result.TestContext, t, "")[0]
+ prebuiltInput := result.ModuleForTests(t, "prebuilt", "android_arm64_armv8-a").Rule("Cp").Input
if filesystemOutput != prebuiltInput {
t.Error("prebuilt should use cov variant of filesystem")
}
@@ -419,7 +403,7 @@
}
`)
- fs := result.ModuleForTests("system", "android_common").Module().(*systemImage)
+ fs := result.ModuleForTests(t, "system", "android_common").Module().(*systemImage)
expected := []string{
"bin/foo",
"lib/libbar.so",
@@ -499,7 +483,7 @@
}
`)
- fs := result.ModuleForTests("fs", "android_common").Module().(*filesystem)
+ fs := result.ModuleForTests(t, "fs", "android_common").Module().(*filesystem)
expected := []string{
"bin/foo",
"lib64/libbar.so",
@@ -562,7 +546,7 @@
},
}
for _, c := range testcases {
- fs := result.ModuleForTests(c.fsName, "android_common").Module().(*filesystem)
+ fs := result.ModuleForTests(t, c.fsName, "android_common").Module().(*filesystem)
for _, e := range c.expected {
android.AssertStringListContains(t, "missing entry", fs.entries, e)
}
@@ -589,7 +573,7 @@
}
`)
- partition := result.ModuleForTests("erofs_partition", "android_common")
+ partition := result.ModuleForTests(t, "erofs_partition", "android_common")
buildImageConfig := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("prop_pre_processing"))
android.AssertStringDoesContain(t, "erofs fs type", buildImageConfig, "fs_type=erofs")
android.AssertStringDoesContain(t, "erofs fs type compress algorithm", buildImageConfig, "erofs_default_compressor=lz4hc,9")
@@ -605,7 +589,7 @@
}
`)
- partition := result.ModuleForTests("f2fs_partition", "android_common")
+ partition := result.ModuleForTests(t, "f2fs_partition", "android_common")
buildImageConfig := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("prop_pre_processing"))
android.AssertStringDoesContain(t, "f2fs fs type", buildImageConfig, "fs_type=f2fs")
android.AssertStringDoesContain(t, "f2fs fs type sparse", buildImageConfig, "f2fs_sparse_flag=-S")
@@ -647,7 +631,7 @@
}
`)
- partition := result.ModuleForTests("myfilesystem", "android_common")
+ partition := result.ModuleForTests(t, "myfilesystem", "android_common")
fileList := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("fileList"))
android.AssertDeepEquals(t, "filesystem with dependencies on different partition", "bin/binfoo\n", fileList)
}
@@ -666,7 +650,7 @@
}
`)
- partition := result.ModuleForTests("myfilesystem", "android_common")
+ partition := result.ModuleForTests(t, "myfilesystem", "android_common")
fileList := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("fileList"))
android.AssertDeepEquals(t, "cc_library listed in deps",
"lib64/bootstrap/libc.so\nlib64/bootstrap/libdl.so\nlib64/bootstrap/libm.so\nlib64/libc++.so\nlib64/libc.so\nlib64/libdl.so\nlib64/libfoo.so\nlib64/libm.so\n",
@@ -703,7 +687,7 @@
}
`)
- partition := result.ModuleForTests("myfilesystem", "android_common")
+ partition := result.ModuleForTests(t, "myfilesystem", "android_common")
fileList := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("fileList"))
android.AssertDeepEquals(t, "Shared library dep of overridden binary should not be installed",
"bin/binfoo1\nlib64/bootstrap/libc.so\nlib64/bootstrap/libdl.so\nlib64/bootstrap/libm.so\nlib64/libc++.so\nlib64/libc.so\nlib64/libdl.so\nlib64/libfoo2.so\nlib64/libm.so\n",
@@ -732,7 +716,7 @@
}
`)
- linkerConfigCmd := result.ModuleForTests("myfilesystem", "android_common").Output("out/soong/.intermediates/myfilesystem/android_common/linker.config.pb").RuleParams.Command
+ linkerConfigCmd := result.ModuleForTests(t, "myfilesystem", "android_common").Output("out/soong/.intermediates/myfilesystem/android_common/linker.config.pb").RuleParams.Command
android.AssertStringDoesContain(t, "Could not find linker.config.json file in cmd", linkerConfigCmd, "conv_linker_config proto --force -s linker.config.json")
android.AssertStringDoesContain(t, "Could not find stub in `provideLibs`", linkerConfigCmd, "--key provideLibs --value libfoo_has_stubs.so")
}
@@ -756,7 +740,7 @@
}
`)
- partition := result.ModuleForTests("myfilesystem", "android_common")
+ partition := result.ModuleForTests(t, "myfilesystem", "android_common")
fileList := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("fileList"))
android.AssertStringEquals(t, "filesystem with override app", "app/myoverrideapp/myoverrideapp.apk\n", fileList)
}
diff --git a/filesystem/fsverity_metadata.go b/filesystem/fsverity_metadata.go
index 91b8c57..89da318 100644
--- a/filesystem/fsverity_metadata.go
+++ b/filesystem/fsverity_metadata.go
@@ -20,6 +20,26 @@
"strings"
"android/soong/android"
+
+ "github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
+)
+
+func init() {
+ pctx.HostBinToolVariable("fsverity_metadata_generator", "fsverity_metadata_generator")
+ pctx.HostBinToolVariable("fsverity_manifest_generator", "fsverity_manifest_generator")
+ pctx.HostBinToolVariable("fsverity", "fsverity")
+}
+
+var (
+ buildFsverityMeta = pctx.AndroidStaticRule("build_fsverity_meta", blueprint.RuleParams{
+ Command: `$fsverity_metadata_generator --fsverity-path $fsverity --signature none --hash-alg sha256 --output $out $in`,
+ CommandDeps: []string{"$fsverity_metadata_generator", "$fsverity"},
+ })
+ buildFsverityManifest = pctx.AndroidStaticRule("build_fsverity_manifest", blueprint.RuleParams{
+ Command: `$fsverity_manifest_generator --fsverity-path $fsverity --output $out @$in`,
+ CommandDeps: []string{"$fsverity_manifest_generator", "$fsverity"},
+ })
)
type fsverityProperties struct {
@@ -27,24 +47,75 @@
// will be generated and included to the filesystem image.
// etc/security/fsverity/BuildManifest.apk will also be generated which contains information
// about generated .fsv_meta files.
- Inputs []string
+ Inputs proptools.Configurable[[]string]
// APK libraries to link against, for etc/security/fsverity/BuildManifest.apk
- Libs []string `android:"path"`
+ Libs proptools.Configurable[[]string] `android:"path"`
}
-func (f *filesystem) writeManifestGeneratorListFile(ctx android.ModuleContext, outputPath android.WritablePath, matchedSpecs []android.PackagingSpec, rebasedDir android.OutputPath) {
+// Mapping of a given fsverity file, which may be a real file or a symlink, and the on-device
+// path it should have relative to the filesystem root.
+type fsveritySrcDest struct {
+ src android.Path
+ dest string
+}
+
+func (f *filesystem) writeManifestGeneratorListFile(
+ ctx android.ModuleContext,
+ outputPath android.WritablePath,
+ matchedFiles []fsveritySrcDest,
+ rootDir android.OutputPath,
+ rebasedDir android.OutputPath,
+) []android.Path {
+ prefix, err := filepath.Rel(rootDir.String(), rebasedDir.String())
+ if err != nil {
+ panic("rebasedDir should be relative to rootDir")
+ }
+ if prefix == "." {
+ prefix = ""
+ }
+ if f.PartitionType() == "system_ext" {
+ // Use the equivalent of $PRODUCT_OUT as the base dir.
+ // This ensures that the paths in build_manifest.pb contain on-device paths
+ // e.g. system_ext/framework/javalib.jar
+ // and not framework/javalib.jar.
+ //
+ // Although base-dir is outside the rootdir provided for packaging, this action
+ // is hermetic since it uses `manifestGeneratorListPath` to filter the files to be written to build_manifest.pb
+ prefix = "system_ext"
+ }
+
+ var deps []android.Path
var buf strings.Builder
- for _, spec := range matchedSpecs {
- buf.WriteString(rebasedDir.Join(ctx, spec.RelPathInPackage()).String())
- buf.WriteRune('\n')
+ for _, spec := range matchedFiles {
+ src := spec.src.String()
+ dst := filepath.Join(prefix, spec.dest)
+ if strings.Contains(src, ",") {
+ ctx.ModuleErrorf("Path cannot contain a comma: %s", src)
+ }
+ if strings.Contains(dst, ",") {
+ ctx.ModuleErrorf("Path cannot contain a comma: %s", dst)
+ }
+ buf.WriteString(src)
+ buf.WriteString(",")
+ buf.WriteString(dst)
+ buf.WriteString("\n")
+ deps = append(deps, spec.src)
}
android.WriteFileRuleVerbatim(ctx, outputPath, buf.String())
+ return deps
}
-func (f *filesystem) buildFsverityMetadataFiles(ctx android.ModuleContext, builder *android.RuleBuilder, specs map[string]android.PackagingSpec, rootDir android.OutputPath, rebasedDir android.OutputPath) {
+func (f *filesystem) buildFsverityMetadataFiles(
+ ctx android.ModuleContext,
+ builder *android.RuleBuilder,
+ specs map[string]android.PackagingSpec,
+ rootDir android.OutputPath,
+ rebasedDir android.OutputPath,
+ fullInstallPaths *[]FullInstallPathInfo,
+) {
match := func(path string) bool {
- for _, pattern := range f.properties.Fsverity.Inputs {
+ for _, pattern := range f.properties.Fsverity.Inputs.GetOrDefault(ctx, nil) {
if matched, err := filepath.Match(pattern, path); matched {
return true
} else if err != nil {
@@ -55,65 +126,98 @@
return false
}
- var matchedSpecs []android.PackagingSpec
+ var matchedFiles []android.PackagingSpec
+ var matchedSymlinks []android.PackagingSpec
for _, relPath := range android.SortedKeys(specs) {
if match(relPath) {
- matchedSpecs = append(matchedSpecs, specs[relPath])
+ spec := specs[relPath]
+ if spec.SrcPath() != nil {
+ matchedFiles = append(matchedFiles, spec)
+ } else if spec.SymlinkTarget() != "" {
+ matchedSymlinks = append(matchedSymlinks, spec)
+ } else {
+ ctx.ModuleErrorf("Expected a file or symlink for fsverity packaging spec")
+ }
}
}
- if len(matchedSpecs) == 0 {
+ if len(matchedFiles) == 0 && len(matchedSymlinks) == 0 {
return
}
- fsverityPath := ctx.Config().HostToolPath(ctx, "fsverity")
-
// STEP 1: generate .fsv_meta
- var sb strings.Builder
- sb.WriteString("set -e\n")
- for _, spec := range matchedSpecs {
+ var fsverityFileSpecs []fsveritySrcDest
+ for _, spec := range matchedFiles {
+ rel := spec.RelPathInPackage() + ".fsv_meta"
+ outPath := android.PathForModuleOut(ctx, "fsverity/meta_files", rel)
+ destPath := rebasedDir.Join(ctx, rel)
// srcPath is copied by CopySpecsToDir()
- srcPath := rebasedDir.Join(ctx, spec.RelPathInPackage())
- destPath := rebasedDir.Join(ctx, spec.RelPathInPackage()+".fsv_meta")
- builder.Command().
- BuiltTool("fsverity_metadata_generator").
- FlagWithInput("--fsverity-path ", fsverityPath).
- FlagWithArg("--signature ", "none").
- FlagWithArg("--hash-alg ", "sha256").
- FlagWithArg("--output ", destPath.String()).
- Text(srcPath.String())
+ ctx.Build(pctx, android.BuildParams{
+ Rule: buildFsverityMeta,
+ Input: spec.SrcPath(),
+ Output: outPath,
+ })
+ builder.Command().Textf("cp").Input(outPath).Output(destPath)
f.appendToEntry(ctx, destPath)
+ *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{
+ SourcePath: destPath,
+ FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), rel),
+ })
+ fsverityFileSpecs = append(fsverityFileSpecs, fsveritySrcDest{
+ src: spec.SrcPath(),
+ dest: spec.RelPathInPackage(),
+ })
}
-
- fsVerityBaseDir := rootDir.String()
- if f.PartitionType() == "system_ext" {
- // Use the equivalent of $PRODUCT_OUT as the base dir.
- // This ensures that the paths in build_manifest.pb contain on-device paths
- // e.g. system_ext/framework/javalib.jar
- // and not framework/javalib.jar.
- //
- // Although base-dir is outside the rootdir provided for packaging, this action
- // is hermetic since it uses `manifestGeneratorListPath` to filter the files to be written to build_manifest.pb
- fsVerityBaseDir = filepath.Dir(rootDir.String())
+ for _, spec := range matchedSymlinks {
+ rel := spec.RelPathInPackage() + ".fsv_meta"
+ outPath := android.PathForModuleOut(ctx, "fsverity/meta_files", rel)
+ destPath := rebasedDir.Join(ctx, rel)
+ target := spec.SymlinkTarget() + ".fsv_meta"
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Symlink,
+ Output: outPath,
+ Args: map[string]string{
+ "fromPath": target,
+ },
+ })
+ builder.Command().
+ Textf("cp").
+ Flag(ctx.Config().CpPreserveSymlinksFlags()).
+ Input(outPath).
+ Output(destPath)
+ f.appendToEntry(ctx, destPath)
+ *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{
+ SymlinkTarget: target,
+ FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), rel),
+ })
+ // The fsverity manifest tool needs to actually look at the symlink. But symlink
+ // packagingSpecs are not actually created on disk, at least until the staging dir is
+ // built for the partition. Create a fake one now so the tool can see it.
+ realizedSymlink := android.PathForModuleOut(ctx, "fsverity/realized_symlinks", spec.RelPathInPackage())
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Symlink,
+ Output: realizedSymlink,
+ Args: map[string]string{
+ "fromPath": spec.SymlinkTarget(),
+ },
+ })
+ fsverityFileSpecs = append(fsverityFileSpecs, fsveritySrcDest{
+ src: realizedSymlink,
+ dest: spec.RelPathInPackage(),
+ })
}
// STEP 2: generate signed BuildManifest.apk
// STEP 2-1: generate build_manifest.pb
- manifestGeneratorListPath := android.PathForModuleOut(ctx, "fsverity_manifest.list")
- f.writeManifestGeneratorListFile(ctx, manifestGeneratorListPath, matchedSpecs, rebasedDir)
- assetsPath := android.PathForModuleOut(ctx, "fsverity_manifest/assets")
- manifestPbPath := assetsPath.Join(ctx, "build_manifest.pb")
- builder.Command().Text("rm -rf " + assetsPath.String())
- builder.Command().Text("mkdir -p " + assetsPath.String())
- builder.Command().
- BuiltTool("fsverity_manifest_generator").
- FlagWithInput("--fsverity-path ", fsverityPath).
- FlagWithArg("--base-dir ", fsVerityBaseDir).
- FlagWithArg("--output ", manifestPbPath.String()).
- FlagWithInput("@", manifestGeneratorListPath)
-
- f.appendToEntry(ctx, manifestPbPath)
- f.appendToEntry(ctx, manifestGeneratorListPath)
+ manifestGeneratorListPath := android.PathForModuleOut(ctx, "fsverity/fsverity_manifest.list")
+ manifestDeps := f.writeManifestGeneratorListFile(ctx, manifestGeneratorListPath, fsverityFileSpecs, rootDir, rebasedDir)
+ manifestPbPath := android.PathForModuleOut(ctx, "fsverity/build_manifest.pb")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: buildFsverityManifest,
+ Input: manifestGeneratorListPath,
+ Implicits: manifestDeps,
+ Output: manifestPbPath,
+ })
// STEP 2-2: generate BuildManifest.apk (unsigned)
apkNameSuffix := ""
@@ -121,22 +225,33 @@
//https://source.corp.google.com/h/googleplex-android/platform/build/+/e392d2b486c2d4187b20a72b1c67cc737ecbcca5:core/Makefile;l=3410;drc=ea8f34bc1d6e63656b4ec32f2391e9d54b3ebb6b;bpv=1;bpt=0
apkNameSuffix = "SystemExt"
}
- apkPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", fmt.Sprintf("BuildManifest%s.apk", apkNameSuffix))
- idsigPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", fmt.Sprintf("BuildManifest%s.apk.idsig", apkNameSuffix))
+ apkPath := android.PathForModuleOut(ctx, "fsverity", fmt.Sprintf("BuildManifest%s.apk", apkNameSuffix))
+ idsigPath := android.PathForModuleOut(ctx, "fsverity", fmt.Sprintf("BuildManifest%s.apk.idsig", apkNameSuffix))
manifestTemplatePath := android.PathForSource(ctx, "system/security/fsverity/AndroidManifest.xml")
- libs := android.PathsForModuleSrc(ctx, f.properties.Fsverity.Libs)
+ libs := android.PathsForModuleSrc(ctx, f.properties.Fsverity.Libs.GetOrDefault(ctx, nil))
minSdkVersion := ctx.Config().PlatformSdkCodename()
if minSdkVersion == "REL" {
minSdkVersion = ctx.Config().PlatformSdkVersion().String()
}
- unsignedApkCommand := builder.Command().
- Textf("mkdir -p %s && ", filepath.Dir(apkPath.String())).
+ apkBuilder := android.NewRuleBuilder(pctx, ctx)
+
+ // aapt2 doesn't support adding individual asset files. Create a temp directory to hold asset
+ // files and pass it to aapt2.
+ tmpAssetDir := android.PathForModuleOut(ctx, "fsverity/tmp_asset_dir")
+ stagedManifestPbPath := tmpAssetDir.Join(ctx, "build_manifest.pb")
+ apkBuilder.Command().
+ Text("rm -rf").Text(tmpAssetDir.String()).
+ Text("&&").
+ Text("mkdir -p").Text(tmpAssetDir.String())
+ apkBuilder.Command().Text("cp").Input(manifestPbPath).Output(stagedManifestPbPath)
+
+ unsignedApkCommand := apkBuilder.Command().
BuiltTool("aapt2").
Text("link").
FlagWithOutput("-o ", apkPath).
- FlagWithArg("-A ", assetsPath.String())
+ FlagWithArg("-A ", tmpAssetDir.String()).Implicit(stagedManifestPbPath)
for _, lib := range libs {
unsignedApkCommand.FlagWithInput("-I ", lib)
}
@@ -147,17 +262,35 @@
FlagWithInput("--manifest ", manifestTemplatePath).
Text(" --rename-manifest-package com.android.security.fsverity_metadata." + f.partitionName())
- f.appendToEntry(ctx, apkPath)
-
// STEP 2-3: sign BuildManifest.apk
pemPath, keyPath := ctx.Config().DefaultAppCertificate(ctx)
- builder.Command().
+ apkBuilder.Command().
BuiltTool("apksigner").
Text("sign").
FlagWithArg("--in ", apkPath.String()).
FlagWithInput("--cert ", pemPath).
FlagWithInput("--key ", keyPath).
ImplicitOutput(idsigPath)
+ apkBuilder.Build(fmt.Sprintf("%s_fsverity_apk", ctx.ModuleName()), "build fsverity apk")
- f.appendToEntry(ctx, idsigPath)
+ // STEP 2-4: Install the apk into the staging directory
+ installedApkPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", fmt.Sprintf("BuildManifest%s.apk", apkNameSuffix))
+ installedIdsigPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", fmt.Sprintf("BuildManifest%s.apk.idsig", apkNameSuffix))
+ builder.Command().Text("mkdir -p").Text(filepath.Dir(installedApkPath.String()))
+ builder.Command().Text("cp").Input(apkPath).Text(installedApkPath.String())
+ builder.Command().Text("cp").Input(idsigPath).Text(installedIdsigPath.String())
+
+ *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{
+ SourcePath: apkPath,
+ FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), fmt.Sprintf("etc/security/fsverity/BuildManifest%s.apk", apkNameSuffix)),
+ })
+
+ f.appendToEntry(ctx, installedApkPath)
+
+ *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{
+ SourcePath: idsigPath,
+ FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), fmt.Sprintf("etc/security/fsverity/BuildManifest%s.apk.idsig", apkNameSuffix)),
+ })
+
+ f.appendToEntry(ctx, installedIdsigPath)
}
diff --git a/filesystem/logical_partition.go b/filesystem/logical_partition.go
index d0888a9..1fd2e76 100644
--- a/filesystem/logical_partition.go
+++ b/filesystem/logical_partition.go
@@ -198,6 +198,8 @@
ctx.SetOutputFiles([]android.Path{output}, "")
l.output = output
+
+ setCommonFilesystemInfo(ctx, l)
}
// Add a rule that converts the filesystem for the given partition to the given rule builder. The
diff --git a/filesystem/raw_binary.go b/filesystem/raw_binary.go
index 707fba0..6ca155a 100644
--- a/filesystem/raw_binary.go
+++ b/filesystem/raw_binary.go
@@ -88,6 +88,8 @@
ctx.SetOutputFiles([]android.Path{outputFile}, "")
r.output = outputFile
+
+ setCommonFilesystemInfo(ctx, r)
}
var _ android.AndroidMkEntriesProvider = (*rawBinary)(nil)
diff --git a/filesystem/super_image.go b/filesystem/super_image.go
index 0f8f614..58c938a 100644
--- a/filesystem/super_image.go
+++ b/filesystem/super_image.go
@@ -17,10 +17,13 @@
import (
"fmt"
"path/filepath"
+ "regexp"
+ "slices"
"strconv"
"strings"
"android/soong/android"
+
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -49,16 +52,32 @@
Ab_update *bool
// whether dynamic partitions is enabled on devices that were launched without this support
Retrofit *bool
- // whether virtual A/B seamless update is enabled
- Virtual_ab *bool
- // whether retrofitting virtual A/B seamless update is enabled
- Virtual_ab_retrofit *bool
// whether the output is a sparse image
Sparse *bool
// information about how partitions within the super partition are grouped together
Partition_groups []PartitionGroupsInfo
+ // Name of the system_other partition filesystem module. This module will be installed to
+ // the "b" slot of the system partition in a/b partition builds.
+ System_other_partition *string
// whether dynamic partitions is used
Use_dynamic_partitions *bool
+ Virtual_ab struct {
+ // whether virtual A/B seamless update is enabled
+ Enable *bool
+ // whether retrofitting virtual A/B seamless update is enabled
+ Retrofit *bool
+ // If set, device uses virtual A/B Compression
+ Compression *bool
+ // This value controls the compression algorithm used for VABC.
+ // Valid options are defined in system/core/fs_mgr/libsnapshot/cow_writer.cpp
+ // e.g. "none", "gz", "brotli"
+ Compression_method *string
+ // Specifies maximum bytes to be compressed at once during ota. Options: 4096, 8192, 16384, 32768, 65536, 131072, 262144.
+ Compression_factor *int64
+ // Specifies COW version to be used by update_engine and libsnapshot. If this value is not
+ // specified we default to COW version 2 in update_engine for backwards compatibility
+ Cow_version *int64
+ }
}
type PartitionGroupsInfo struct {
@@ -88,6 +107,17 @@
Odm_dlkm_partition *string
}
+type SuperImageInfo struct {
+ // The built super.img file, which contains the sub-partitions
+ SuperImage android.Path
+
+ // Mapping from the sub-partition type to its re-exported FileSystemInfo providers from the
+ // sub-partitions.
+ SubImageInfo map[string]FilesystemInfo
+}
+
+var SuperImageProvider = blueprint.NewProvider[SuperImageInfo]()
+
func SuperImageFactory() android.Module {
module := &superImage{}
module.AddProperties(&module.properties, &module.partitionProps)
@@ -99,12 +129,18 @@
blueprint.BaseDependencyTag
}
-var superImageDepTag superImageDepTagType
+var subImageDepTag superImageDepTagType
+
+type systemOtherDepTagType struct {
+ blueprint.BaseDependencyTag
+}
+
+var systemOtherDepTag systemOtherDepTagType
func (s *superImage) DepsMutator(ctx android.BottomUpMutatorContext) {
addDependencyIfDefined := func(dep *string) {
if dep != nil {
- ctx.AddDependency(ctx.Module(), superImageDepTag, proptools.String(dep))
+ ctx.AddDependency(ctx.Module(), subImageDepTag, proptools.String(dep))
}
}
@@ -117,10 +153,13 @@
addDependencyIfDefined(s.partitionProps.Vendor_dlkm_partition)
addDependencyIfDefined(s.partitionProps.Odm_partition)
addDependencyIfDefined(s.partitionProps.Odm_dlkm_partition)
+ if s.properties.System_other_partition != nil {
+ ctx.AddDependency(ctx.Module(), systemOtherDepTag, *s.properties.System_other_partition)
+ }
}
func (s *superImage) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- miscInfo, deps := s.buildMiscInfo(ctx)
+ miscInfo, deps, subImageInfos := s.buildMiscInfo(ctx)
builder := android.NewRuleBuilder(pctx, ctx)
output := android.PathForModuleOut(ctx, s.installFileName())
lpMake := ctx.Config().HostToolPath(ctx, "lpmake")
@@ -133,14 +172,19 @@
Implicits(deps).
Output(output)
builder.Build("build_super_image", fmt.Sprintf("Creating super image %s", s.BaseModuleName()))
+ android.SetProvider(ctx, SuperImageProvider, SuperImageInfo{
+ SuperImage: output,
+ SubImageInfo: subImageInfos,
+ })
ctx.SetOutputFiles([]android.Path{output}, "")
+ ctx.CheckbuildFile(output)
}
func (s *superImage) installFileName() string {
- return s.BaseModuleName() + ".img"
+ return "super.img"
}
-func (s *superImage) buildMiscInfo(ctx android.ModuleContext) (android.Path, android.Paths) {
+func (s *superImage) buildMiscInfo(ctx android.ModuleContext) (android.Path, android.Paths, map[string]FilesystemInfo) {
var miscInfoString strings.Builder
addStr := func(name string, value string) {
miscInfoString.WriteString(name)
@@ -149,13 +193,18 @@
miscInfoString.WriteRune('\n')
}
+ addStr("build_super_partition", "true")
addStr("use_dynamic_partitions", strconv.FormatBool(proptools.Bool(s.properties.Use_dynamic_partitions)))
- addStr("dynamic_partition_retrofit", strconv.FormatBool(proptools.Bool(s.properties.Retrofit)))
+ if proptools.Bool(s.properties.Retrofit) {
+ addStr("dynamic_partition_retrofit", "true")
+ }
addStr("lpmake", "lpmake")
addStr("super_metadata_device", proptools.String(s.properties.Metadata_device))
if len(s.properties.Block_devices) > 0 {
addStr("super_block_devices", strings.Join(s.properties.Block_devices, " "))
}
+ addStr("super_partition_size", strconv.Itoa(proptools.Int(s.properties.Size)))
+ // TODO: In make, there's more complicated logic than just this surrounding super_*_device_size
addStr("super_super_device_size", strconv.Itoa(proptools.Int(s.properties.Size)))
var groups, partitionList []string
for _, groupInfo := range s.properties.Partition_groups {
@@ -164,73 +213,136 @@
addStr("super_"+groupInfo.Name+"_group_size", groupInfo.GroupSize)
addStr("super_"+groupInfo.Name+"_partition_list", strings.Join(groupInfo.PartitionList, " "))
}
+ initialPartitionListLen := len(partitionList)
+ partitionList = android.SortedUniqueStrings(partitionList)
+ if len(partitionList) != initialPartitionListLen {
+ ctx.ModuleErrorf("Duplicate partitions found in the partition_groups property")
+ }
addStr("super_partition_groups", strings.Join(groups, " "))
addStr("dynamic_partition_list", strings.Join(partitionList, " "))
- addStr("virtual_ab", strconv.FormatBool(proptools.Bool(s.properties.Virtual_ab)))
- addStr("virtual_ab_retrofit", strconv.FormatBool(proptools.Bool(s.properties.Virtual_ab_retrofit)))
addStr("ab_update", strconv.FormatBool(proptools.Bool(s.properties.Ab_update)))
- addStr("build_non_sparse_super_partition", strconv.FormatBool(!proptools.Bool(s.properties.Sparse)))
- partitionToImagePath := make(map[string]string)
- nameToPartition := make(map[string]string)
- var systemOtherPartitionNameNeeded string
- addEntryToPartitionToName := func(p string, s *string) {
- if proptools.String(s) != "" {
- nameToPartition[*s] = p
+ if proptools.Bool(s.properties.Virtual_ab.Enable) {
+ addStr("virtual_ab", "true")
+ if proptools.Bool(s.properties.Virtual_ab.Retrofit) {
+ addStr("virtual_ab_retrofit", "true")
}
+ addStr("virtual_ab_compression", strconv.FormatBool(proptools.Bool(s.properties.Virtual_ab.Compression)))
+ if s.properties.Virtual_ab.Compression_method != nil {
+ matched, _ := regexp.MatchString("^[a-zA-Z0-9_-]+$", *s.properties.Virtual_ab.Compression_method)
+ if !matched {
+ ctx.PropertyErrorf("virtual_ab.compression_method", "compression_method cannot have special characters")
+ }
+ addStr("virtual_ab_compression_method", *s.properties.Virtual_ab.Compression_method)
+ }
+ if s.properties.Virtual_ab.Compression_factor != nil {
+ addStr("virtual_ab_compression_factor", strconv.FormatInt(*s.properties.Virtual_ab.Compression_factor, 10))
+ }
+ if s.properties.Virtual_ab.Cow_version != nil {
+ addStr("virtual_ab_cow_version", strconv.FormatInt(*s.properties.Virtual_ab.Cow_version, 10))
+ }
+
+ } else {
+ if s.properties.Virtual_ab.Retrofit != nil {
+ ctx.PropertyErrorf("virtual_ab.retrofit", "This property cannot be set when virtual_ab is disabled")
+ }
+ if s.properties.Virtual_ab.Compression != nil {
+ ctx.PropertyErrorf("virtual_ab.compression", "This property cannot be set when virtual_ab is disabled")
+ }
+ if s.properties.Virtual_ab.Compression_method != nil {
+ ctx.PropertyErrorf("virtual_ab.compression_method", "This property cannot be set when virtual_ab is disabled")
+ }
+ if s.properties.Virtual_ab.Compression_factor != nil {
+ ctx.PropertyErrorf("virtual_ab.compression_factor", "This property cannot be set when virtual_ab is disabled")
+ }
+ }
+
+ subImageInfo := make(map[string]FilesystemInfo)
+ var deps android.Paths
+
+ missingPartitionErrorMessage := ""
+ handleSubPartition := func(partitionType string, name *string) {
+ if proptools.String(name) == "" {
+ missingPartitionErrorMessage += fmt.Sprintf("%s image listed in partition groups, but its module was not specified. ", partitionType)
+ return
+ }
+ mod := ctx.GetDirectDepWithTag(*name, subImageDepTag)
+ if mod == nil {
+ ctx.ModuleErrorf("Could not get dep %q", *name)
+ return
+ }
+ info, ok := android.OtherModuleProvider(ctx, mod, FilesystemProvider)
+ if !ok {
+ ctx.ModuleErrorf("Expected dep %q to provide FilesystemInfo", *name)
+ return
+ }
+ addStr(partitionType+"_image", info.Output.String())
+ deps = append(deps, info.Output)
+ if _, ok := subImageInfo[partitionType]; ok {
+ ctx.ModuleErrorf("Already set subimageInfo for %q", partitionType)
+ }
+ subImageInfo[partitionType] = info
}
// Build partitionToImagePath, because system partition may need system_other
// partition image path
for _, p := range partitionList {
- if _, ok := nameToPartition[p]; ok {
- continue
- }
switch p {
case "system":
- addEntryToPartitionToName(p, s.partitionProps.System_partition)
- systemOtherPartitionNameNeeded = proptools.String(s.partitionProps.System_other_partition)
+ handleSubPartition("system", s.partitionProps.System_partition)
case "system_dlkm":
- addEntryToPartitionToName(p, s.partitionProps.System_dlkm_partition)
+ handleSubPartition("system_dlkm", s.partitionProps.System_dlkm_partition)
case "system_ext":
- addEntryToPartitionToName(p, s.partitionProps.System_ext_partition)
+ handleSubPartition("system_ext", s.partitionProps.System_ext_partition)
case "product":
- addEntryToPartitionToName(p, s.partitionProps.Product_partition)
+ handleSubPartition("product", s.partitionProps.Product_partition)
case "vendor":
- addEntryToPartitionToName(p, s.partitionProps.Vendor_partition)
+ handleSubPartition("vendor", s.partitionProps.Vendor_partition)
case "vendor_dlkm":
- addEntryToPartitionToName(p, s.partitionProps.Vendor_dlkm_partition)
+ handleSubPartition("vendor_dlkm", s.partitionProps.Vendor_dlkm_partition)
case "odm":
- addEntryToPartitionToName(p, s.partitionProps.Odm_partition)
+ handleSubPartition("odm", s.partitionProps.Odm_partition)
case "odm_dlkm":
- addEntryToPartitionToName(p, s.partitionProps.Odm_dlkm_partition)
+ handleSubPartition("odm_dlkm", s.partitionProps.Odm_dlkm_partition)
default:
- ctx.ModuleErrorf("current partition %s not a super image supported partition", p)
+ ctx.ModuleErrorf("partition %q is not a super image supported partition", p)
}
}
- var deps android.Paths
- ctx.VisitDirectDeps(func(m android.Module) {
- if p, ok := nameToPartition[m.Name()]; ok {
- if output, ok := android.OtherModuleProvider(ctx, m, android.OutputFilesProvider); ok {
- partitionToImagePath[p] = output.DefaultOutputFiles[0].String()
- deps = append(deps, output.DefaultOutputFiles[0])
- }
- } else if systemOtherPartitionNameNeeded != "" && m.Name() == systemOtherPartitionNameNeeded {
- if output, ok := android.OtherModuleProvider(ctx, m, android.OutputFilesProvider); ok {
- partitionToImagePath["system_other"] = output.DefaultOutputFiles[0].String()
- // TODO: add system_other to deps after it can be generated
- // deps = append(deps, output.DefaultOutputFiles[0])
- }
+ if s.properties.System_other_partition != nil {
+ if !slices.Contains(partitionList, "system") {
+ ctx.PropertyErrorf("system_other_partition", "Must have a system partition to use a system_other partition")
}
- })
+ systemOther := ctx.GetDirectDepProxyWithTag(*s.properties.System_other_partition, systemOtherDepTag)
+ systemOtherFiles := android.OutputFilesForModule(ctx, systemOther, "")
+ if len(systemOtherFiles) != 1 {
+ ctx.PropertyErrorf("system_other_partition", "Expected 1 output file from module %q", *&s.properties.System_other_partition)
+ } else {
+ handleSubPartition("system_other", s.partitionProps.System_other_partition)
+ }
+ }
- for _, p := range android.SortedKeys(partitionToImagePath) {
- addStr(p+"_image", partitionToImagePath[p])
+ // Delay the error message until execution time because on aosp-main-future-without-vendor,
+ // BUILDING_VENDOR_IMAGE is false so we don't get the vendor image, but it's still listed in
+ // BOARD_GOOGLE_DYNAMIC_PARTITIONS_PARTITION_LIST.
+ missingPartitionErrorMessageFile := android.PathForModuleOut(ctx, "missing_partition_error.txt")
+ if missingPartitionErrorMessage != "" {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.ErrorRule,
+ Output: missingPartitionErrorMessageFile,
+ Args: map[string]string{
+ "error": missingPartitionErrorMessage,
+ },
+ })
+ } else {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Touch,
+ Output: missingPartitionErrorMessageFile,
+ })
}
miscInfo := android.PathForModuleOut(ctx, "misc_info.txt")
- android.WriteFileRule(ctx, miscInfo, miscInfoString.String())
- return miscInfo, deps
+ android.WriteFileRule(ctx, miscInfo, miscInfoString.String(), missingPartitionErrorMessageFile)
+ return miscInfo, deps, subImageInfo
}
diff --git a/filesystem/system_image.go b/filesystem/system_image.go
index 874d20d..cc9093f 100644
--- a/filesystem/system_image.go
+++ b/filesystem/system_image.go
@@ -44,7 +44,12 @@
return s.filesystem.properties
}
-func (s *systemImage) BuildLinkerConfigFile(ctx android.ModuleContext, builder *android.RuleBuilder, rebasedDir android.OutputPath) {
+func (s *systemImage) BuildLinkerConfigFile(
+ ctx android.ModuleContext,
+ builder *android.RuleBuilder,
+ rebasedDir android.OutputPath,
+ fullInstallPaths *[]FullInstallPathInfo,
+) {
if !proptools.Bool(s.filesystem.properties.Linker_config.Gen_linker_config) {
return
}
@@ -55,6 +60,11 @@
intermediateOutput := android.PathForModuleOut(ctx, "linker.config.pb")
linkerconfig.BuildLinkerConfig(ctx, android.PathsForModuleSrc(ctx, s.filesystem.properties.Linker_config.Linker_config_srcs), provideModules, requireModules, intermediateOutput)
builder.Command().Text("cp").Input(intermediateOutput).Output(output)
+
+ *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{
+ FullInstallPath: android.PathForModuleInPartitionInstall(ctx, s.PartitionType(), "etc", "linker.config.pb"),
+ SourcePath: intermediateOutput,
+ })
} else {
// TODO: This branch is the logic that make uses for the linker config file, which is
// different than linkerconfig.BuildLinkerConfig used above. Keeping both branches for now
@@ -87,6 +97,11 @@
Implicit(llndkMovedToApexLibraries)
// TODO: Make also supports adding an extra append command with PRODUCT_EXTRA_STUB_LIBRARIES,
// but that variable appears to have no usages.
+
+ *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{
+ FullInstallPath: android.PathForModuleInPartitionInstall(ctx, s.PartitionType(), "etc", "linker.config.pb"),
+ SourcePath: output,
+ })
}
s.appendToEntry(ctx, output)
diff --git a/filesystem/system_other.go b/filesystem/system_other.go
new file mode 100644
index 0000000..5309e90
--- /dev/null
+++ b/filesystem/system_other.go
@@ -0,0 +1,191 @@
+// Copyright (C) 2024 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 filesystem
+
+import (
+ "android/soong/android"
+ "path/filepath"
+ "strings"
+
+ "github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
+)
+
+var (
+ systemOtherPropFileTweaks = pctx.AndroidStaticRule("system_other_prop_file_tweaks", blueprint.RuleParams{
+ Command: `rm -rf $out && sed -e 's@^mount_point=/$$@mount_point=system_other@g' -e 's@^partition_name=system$$@partition_name=system_other@g' $in > $out`,
+ })
+)
+
+type SystemOtherImageProperties struct {
+ // The system_other image always requires a reference to the system image. The system_other
+ // partition gets built into the system partition's "b" slot in a/b partition builds. Thus, it
+ // copies most of its configuration from the system image, such as filesystem type, avb signing
+ // info, etc. Including it here does not automatically mean that it will pick up the system
+ // image's dexpropt files, it must also be listed in Preinstall_dexpreopt_files_from for that.
+ System_image *string
+
+ // This system_other partition will include all the dexpreopt files from the apps on these
+ // partitions.
+ Preinstall_dexpreopt_files_from []string
+}
+
+type systemOtherImage struct {
+ android.ModuleBase
+ android.DefaultableModuleBase
+ properties SystemOtherImageProperties
+}
+
+// The system_other image is the default contents of the "b" slot of the system image.
+// It contains the dexpreopt files of all the apps on the device, for a faster first boot.
+// Afterwards, at runtime, it will be used as a regular b slot for OTA updates, and the initial
+// dexpreopt files will be deleted.
+func SystemOtherImageFactory() android.Module {
+ module := &systemOtherImage{}
+ module.AddProperties(&module.properties)
+ android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
+ android.InitDefaultableModule(module)
+ return module
+}
+
+type systemImageDeptag struct {
+ blueprint.BaseDependencyTag
+}
+
+var systemImageDependencyTag = systemImageDeptag{}
+
+type dexpreoptDeptag struct {
+ blueprint.BaseDependencyTag
+}
+
+var dexpreoptDependencyTag = dexpreoptDeptag{}
+
+func (m *systemOtherImage) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if proptools.String(m.properties.System_image) == "" {
+ ctx.ModuleErrorf("system_image property must be set")
+ return
+ }
+ ctx.AddDependency(ctx.Module(), systemImageDependencyTag, *m.properties.System_image)
+ ctx.AddDependency(ctx.Module(), dexpreoptDependencyTag, m.properties.Preinstall_dexpreopt_files_from...)
+}
+
+func (m *systemOtherImage) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ systemImage := ctx.GetDirectDepProxyWithTag(*m.properties.System_image, systemImageDependencyTag)
+ systemInfo, ok := android.OtherModuleProvider(ctx, systemImage, FilesystemProvider)
+ if !ok {
+ ctx.PropertyErrorf("system_image", "Expected system_image module to provide FilesystemProvider")
+ return
+ }
+
+ output := android.PathForModuleOut(ctx, "system_other.img")
+ stagingDir := android.PathForModuleOut(ctx, "staging_dir")
+ stagingDirTimestamp := android.PathForModuleOut(ctx, "staging_dir.timestamp")
+
+ builder := android.NewRuleBuilder(pctx, ctx)
+ builder.Command().Textf("rm -rf %s && mkdir -p %s", stagingDir, stagingDir)
+
+ specs := make(map[string]android.PackagingSpec)
+ for _, otherPartition := range m.properties.Preinstall_dexpreopt_files_from {
+ dexModule := ctx.GetDirectDepProxyWithTag(otherPartition, dexpreoptDependencyTag)
+ fsInfo, ok := android.OtherModuleProvider(ctx, dexModule, FilesystemProvider)
+ if !ok {
+ ctx.PropertyErrorf("preinstall_dexpreopt_files_from", "Expected module %q to provide FilesystemProvider", otherPartition)
+ return
+ }
+ // Merge all the packaging specs into 1 map
+ for k := range fsInfo.SpecsForSystemOther {
+ if _, ok := specs[k]; ok {
+ ctx.ModuleErrorf("Packaging spec %s given by two different partitions", k)
+ continue
+ }
+ specs[k] = fsInfo.SpecsForSystemOther[k]
+ }
+ }
+
+ // TOOD: CopySpecsToDir only exists on PackagingBase, but doesn't use any fields from it. Clean this up.
+ (&android.PackagingBase{}).CopySpecsToDir(ctx, builder, specs, stagingDir)
+
+ if len(m.properties.Preinstall_dexpreopt_files_from) > 0 {
+ builder.Command().Textf("touch %s", filepath.Join(stagingDir.String(), "system-other-odex-marker"))
+ }
+ builder.Command().Textf("touch").Output(stagingDirTimestamp)
+ builder.Build("assemble_filesystem_staging_dir", "Assemble filesystem staging dir")
+
+ // Most of the time, if build_image were to call a host tool, it accepts the path to the
+ // host tool in a field in the prop file. However, it doesn't have that option for fec, which
+ // it expects to just be on the PATH. Add fec to the PATH.
+ fec := ctx.Config().HostToolPath(ctx, "fec")
+ pathToolDirs := []string{filepath.Dir(fec.String())}
+
+ // In make, the exact same prop file is used for both system and system_other. However, I
+ // believe make goes through a different build_image code path that is based on the name of
+ // the output file. So it sees the output file is named system_other.img and makes some changes.
+ // We don't use that codepath, so make the changes manually to the prop file.
+ propFile := android.PathForModuleOut(ctx, "prop")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: systemOtherPropFileTweaks,
+ Input: systemInfo.BuildImagePropFile,
+ Output: propFile,
+ })
+
+ builder = android.NewRuleBuilder(pctx, ctx)
+ builder.Command().
+ Textf("PATH=%s:$PATH", strings.Join(pathToolDirs, ":")).
+ BuiltTool("build_image").
+ Text(stagingDir.String()). // input directory
+ Input(propFile).
+ Implicits(systemInfo.BuildImagePropFileDeps).
+ Implicit(fec).
+ Implicit(stagingDirTimestamp).
+ Output(output).
+ Text(stagingDir.String())
+
+ builder.Build("build_system_other", "build system other")
+
+ // Create a hermetic system_other.img with pinned timestamps
+ builder = android.NewRuleBuilder(pctx, ctx)
+ outputHermetic := android.PathForModuleOut(ctx, "for_target_files", "system_other.img")
+ outputHermeticPropFile := m.propFileForHermeticImg(ctx, builder, propFile)
+ builder.Command().
+ Textf("PATH=%s:$PATH", strings.Join(pathToolDirs, ":")).
+ BuiltTool("build_image").
+ Text(stagingDir.String()). // input directory
+ Input(outputHermeticPropFile).
+ Implicits(systemInfo.BuildImagePropFileDeps).
+ Implicit(fec).
+ Implicit(stagingDirTimestamp).
+ Output(outputHermetic).
+ Text(stagingDir.String())
+
+ builder.Build("build_system_other_hermetic", "build system other")
+
+ fsInfo := FilesystemInfo{
+ Output: output,
+ OutputHermetic: outputHermetic,
+ RootDir: stagingDir,
+ }
+
+ android.SetProvider(ctx, FilesystemProvider, fsInfo)
+
+ ctx.SetOutputFiles(android.Paths{output}, "")
+ ctx.CheckbuildFile(output)
+}
+
+func (f *systemOtherImage) propFileForHermeticImg(ctx android.ModuleContext, builder *android.RuleBuilder, inputPropFile android.Path) android.Path {
+ propFilePinnedTimestamp := android.PathForModuleOut(ctx, "for_target_files", "prop")
+ builder.Command().Textf("cat").Input(inputPropFile).Flag(">").Output(propFilePinnedTimestamp).
+ Textf(" && echo use_fixed_timestamp=true >> %s", propFilePinnedTimestamp)
+ return propFilePinnedTimestamp
+}
diff --git a/filesystem/vbmeta.go b/filesystem/vbmeta.go
index c8b4675..01b453e 100644
--- a/filesystem/vbmeta.go
+++ b/filesystem/vbmeta.go
@@ -97,7 +97,7 @@
// Name of the chained partition
Name *string
- // Rollback index location of the chained partition. Must be 0, 1, 2, etc. Default is the
+ // Rollback index location of the chained partition. Must be 1, 2, 3, etc. Default is the
// index of this partition in the list + 1.
Rollback_index_location *int64
@@ -121,6 +121,9 @@
// The path to the public key of the private key used to sign this partition. Derived from
// the private key.
PublicKey android.Path
+
+ // The output of the vbmeta module
+ Output android.Path
}
var vbmetaPartitionProvider = blueprint.NewProvider[vbmetaPartitionInfo]()
@@ -145,8 +148,8 @@
var vbmetaChainedPartitionDep = chainedPartitionDep{}
func (v *vbmeta) DepsMutator(ctx android.BottomUpMutatorContext) {
- ctx.AddDependency(ctx.Module(), vbmetaPartitionDep, v.properties.Partitions.GetOrDefault(ctx, nil)...)
- ctx.AddDependency(ctx.Module(), vbmetaChainedPartitionDep, v.properties.Chained_partitions...)
+ ctx.AddVariationDependencies(ctx.Config().AndroidFirstDeviceTarget.Variations(), vbmetaPartitionDep, v.properties.Partitions.GetOrDefault(ctx, nil)...)
+ ctx.AddVariationDependencies(ctx.Config().AndroidFirstDeviceTarget.Variations(), vbmetaChainedPartitionDep, v.properties.Chained_partitions...)
}
func (v *vbmeta) installFileName() string {
@@ -170,13 +173,14 @@
algorithm := proptools.StringDefault(v.properties.Algorithm, "SHA256_RSA4096")
cmd.FlagWithArg("--algorithm ", algorithm)
+ cmd.FlagWithArg("--padding_size ", "4096")
+
cmd.FlagWithArg("--rollback_index ", v.rollbackIndexCommand(ctx))
ril := proptools.IntDefault(v.properties.Rollback_index_location, 0)
if ril < 0 {
ctx.PropertyErrorf("rollback_index_location", "must be 0, 1, 2, ...")
return
}
- cmd.FlagWithArg("--rollback_index_location ", strconv.Itoa(ril))
for _, avb_prop := range v.properties.Avb_properties {
key := proptools.String(avb_prop.Key)
@@ -221,8 +225,8 @@
}
ril := info.RollbackIndexLocation
- if ril < 0 {
- ctx.PropertyErrorf("chained_partitions", "rollback index location must be 0, 1, 2, ...")
+ if ril < 1 {
+ ctx.PropertyErrorf("chained_partitions", "rollback index location must be 1, 2, 3, ...")
continue
} else if seenRils[ril] {
ctx.PropertyErrorf("chained_partitions", "Multiple chained partitions with the same rollback index location %d", ril)
@@ -237,13 +241,13 @@
for _, cpm := range v.properties.Chained_partition_metadata {
name := proptools.String(cpm.Name)
if name == "" {
- ctx.PropertyErrorf("chained_partitions", "name must be specified")
+ ctx.PropertyErrorf("chained_partition_metadata", "name must be specified")
continue
}
- ril := proptools.IntDefault(cpm.Rollback_index_location, -1)
- if ril < 0 {
- ctx.PropertyErrorf("chained_partition_metadata", "rollback index location must be 0, 1, 2, ...")
+ ril := proptools.IntDefault(cpm.Rollback_index_location, 0)
+ if ril < 1 {
+ ctx.PropertyErrorf("chained_partition_metadata", "rollback index location must be 1, 2, 3, ...")
continue
} else if seenRils[ril] {
ctx.PropertyErrorf("chained_partition_metadata", "Multiple chained partitions with the same rollback index location %d", ril)
@@ -281,10 +285,6 @@
FlagWithArg("-s ", strconv.Itoa(vbmetaMaxSize)).
Output(output)
- if !ctx.Config().KatiEnabled() {
- copyImageFileToProductOut(ctx, builder, v.partitionName(), output)
- }
-
builder.Build("vbmeta", fmt.Sprintf("vbmeta %s", ctx.ModuleName()))
v.installDir = android.PathForModuleInstall(ctx, "etc")
@@ -301,10 +301,13 @@
Name: v.partitionName(),
RollbackIndexLocation: ril,
PublicKey: extractedPublicKey,
+ Output: output,
})
ctx.SetOutputFiles([]android.Path{output}, "")
v.output = output
+
+ setCommonFilesystemInfo(ctx, v)
}
// Returns the embedded shell command that prints the rollback index
diff --git a/fsgen/boot_imgs.go b/fsgen/boot_imgs.go
index 914d35b..58ebcc4 100644
--- a/fsgen/boot_imgs.go
+++ b/fsgen/boot_imgs.go
@@ -69,22 +69,26 @@
ctx.CreateModule(
filesystem.BootimgFactory,
&filesystem.BootimgProperties{
- Kernel_prebuilt: proptools.StringPtr(":" + kernelFilegroupName),
- Header_version: proptools.StringPtr(partitionVariables.BoardBootHeaderVersion),
- Partition_size: partitionSize,
- Use_avb: avbInfo.avbEnable,
- Avb_mode: avbInfo.avbMode,
- Avb_private_key: avbInfo.avbkeyFilegroup,
- Avb_rollback_index: avbInfo.avbRollbackIndex,
- Avb_algorithm: avbInfo.avbAlgorithm,
- Security_patch: securityPatch,
- Dtb_prebuilt: dtbPrebuilt,
- Cmdline: cmdline,
+ Kernel_prebuilt: proptools.StringPtr(":" + kernelFilegroupName),
+ Header_version: proptools.StringPtr(partitionVariables.BoardBootHeaderVersion),
+ Partition_size: partitionSize,
+ Use_avb: avbInfo.avbEnable,
+ Avb_mode: avbInfo.avbMode,
+ Avb_private_key: avbInfo.avbkeyFilegroup,
+ Avb_rollback_index: avbInfo.avbRollbackIndex,
+ Avb_rollback_index_location: avbInfo.avbRollbackIndexLocation,
+ Avb_algorithm: avbInfo.avbAlgorithm,
+ Security_patch: securityPatch,
+ Dtb_prebuilt: dtbPrebuilt,
+ Cmdline: cmdline,
+ Stem: proptools.StringPtr("boot.img"),
},
&struct {
- Name *string
+ Name *string
+ Visibility []string
}{
- Name: proptools.StringPtr(bootImageName),
+ Name: proptools.StringPtr(bootImageName),
+ Visibility: []string{"//visibility:public"},
},
)
return true
@@ -122,22 +126,26 @@
ctx.CreateModule(
filesystem.BootimgFactory,
&filesystem.BootimgProperties{
- Boot_image_type: proptools.StringPtr("vendor_boot"),
- Ramdisk_module: proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor_ramdisk")),
- Header_version: proptools.StringPtr(partitionVariables.BoardBootHeaderVersion),
- Partition_size: partitionSize,
- Use_avb: avbInfo.avbEnable,
- Avb_mode: avbInfo.avbMode,
- Avb_private_key: avbInfo.avbkeyFilegroup,
- Avb_rollback_index: avbInfo.avbRollbackIndex,
- Dtb_prebuilt: dtbPrebuilt,
- Cmdline: cmdline,
- Bootconfig: vendorBootConfigImg,
+ Boot_image_type: proptools.StringPtr("vendor_boot"),
+ Ramdisk_module: proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor_ramdisk")),
+ Header_version: proptools.StringPtr(partitionVariables.BoardBootHeaderVersion),
+ Partition_size: partitionSize,
+ Use_avb: avbInfo.avbEnable,
+ Avb_mode: avbInfo.avbMode,
+ Avb_private_key: avbInfo.avbkeyFilegroup,
+ Avb_rollback_index: avbInfo.avbRollbackIndex,
+ Avb_rollback_index_location: avbInfo.avbRollbackIndexLocation,
+ Dtb_prebuilt: dtbPrebuilt,
+ Cmdline: cmdline,
+ Bootconfig: vendorBootConfigImg,
+ Stem: proptools.StringPtr("vendor_boot.img"),
},
&struct {
- Name *string
+ Name *string
+ Visibility []string
}{
- Name: proptools.StringPtr(bootImageName),
+ Name: proptools.StringPtr(bootImageName),
+ Visibility: []string{"//visibility:public"},
},
)
return true
@@ -170,21 +178,25 @@
ctx.CreateModule(
filesystem.BootimgFactory,
&filesystem.BootimgProperties{
- Boot_image_type: proptools.StringPtr("init_boot"),
- Ramdisk_module: proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "ramdisk")),
- Header_version: proptools.StringPtr(partitionVariables.BoardBootHeaderVersion),
- Security_patch: securityPatch,
- Partition_size: partitionSize,
- Use_avb: avbInfo.avbEnable,
- Avb_mode: avbInfo.avbMode,
- Avb_private_key: avbInfo.avbkeyFilegroup,
- Avb_rollback_index: avbInfo.avbRollbackIndex,
- Avb_algorithm: avbInfo.avbAlgorithm,
+ Boot_image_type: proptools.StringPtr("init_boot"),
+ Ramdisk_module: proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "ramdisk")),
+ Header_version: proptools.StringPtr(partitionVariables.BoardBootHeaderVersion),
+ Security_patch: securityPatch,
+ Partition_size: partitionSize,
+ Use_avb: avbInfo.avbEnable,
+ Avb_mode: avbInfo.avbMode,
+ Avb_private_key: avbInfo.avbkeyFilegroup,
+ Avb_rollback_index: avbInfo.avbRollbackIndex,
+ Avb_rollback_index_location: avbInfo.avbRollbackIndexLocation,
+ Avb_algorithm: avbInfo.avbAlgorithm,
+ Stem: proptools.StringPtr("init_boot.img"),
},
&struct {
- Name *string
+ Name *string
+ Visibility []string
}{
- Name: proptools.StringPtr(bootImageName),
+ Name: proptools.StringPtr(bootImageName),
+ Visibility: []string{"//visibility:public"},
},
)
return true
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index a070e01..e2485a1 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -42,8 +42,85 @@
ctx.PreDepsMutators(RegisterCollectFileSystemDepsMutators)
}
+type generatedPartitionData struct {
+ partitionType string
+ moduleName string
+ // supported is true if the module was created successfully, false if there was some problem
+ // and the module couldn't be created.
+ supported bool
+ handwritten bool
+}
+
+type allGeneratedPartitionData []generatedPartitionData
+
+func (d allGeneratedPartitionData) moduleNames() []string {
+ var result []string
+ for _, data := range d {
+ if data.supported {
+ result = append(result, data.moduleName)
+ }
+ }
+ return result
+}
+
+func (d allGeneratedPartitionData) types() []string {
+ var result []string
+ for _, data := range d {
+ if data.supported {
+ result = append(result, data.partitionType)
+ }
+ }
+ return result
+}
+
+func (d allGeneratedPartitionData) unsupportedTypes() []string {
+ var result []string
+ for _, data := range d {
+ if !data.supported {
+ result = append(result, data.partitionType)
+ }
+ }
+ return result
+}
+
+func (d allGeneratedPartitionData) names() []string {
+ var result []string
+ for _, data := range d {
+ if data.supported {
+ result = append(result, data.moduleName)
+ }
+ }
+ return result
+}
+
+func (d allGeneratedPartitionData) nameForType(ty string) string {
+ for _, data := range d {
+ if data.supported && data.partitionType == ty {
+ return data.moduleName
+ }
+ }
+ return ""
+}
+
+func (d allGeneratedPartitionData) typeForName(name string) string {
+ for _, data := range d {
+ if data.supported && data.moduleName == name {
+ return data.partitionType
+ }
+ }
+ return ""
+}
+
+func (d allGeneratedPartitionData) isHandwritten(name string) bool {
+ for _, data := range d {
+ if data.supported && data.moduleName == name {
+ return data.handwritten
+ }
+ }
+ return false
+}
+
type filesystemCreatorProps struct {
- Generated_partition_types []string `blueprint:"mutated"`
Unsupported_partition_types []string `blueprint:"mutated"`
Vbmeta_module_names []string `blueprint:"mutated"`
@@ -78,55 +155,71 @@
return module
}
-func generatedPartitions(ctx android.EarlyModuleContext) []string {
+func generatedPartitions(ctx android.EarlyModuleContext) allGeneratedPartitionData {
partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
- generatedPartitions := []string{"system"}
+
+ var result allGeneratedPartitionData
+ addGenerated := func(ty string) {
+ result = append(result, generatedPartitionData{
+ partitionType: ty,
+ moduleName: generatedModuleNameForPartition(ctx.Config(), ty),
+ supported: true,
+ })
+ }
+
+ if ctx.Config().UseSoongSystemImage() {
+ if ctx.Config().SoongDefinedSystemImage() == "" {
+ panic("PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE must be set if USE_SOONG_DEFINED_SYSTEM_IMAGE is true")
+ }
+ result = append(result, generatedPartitionData{
+ partitionType: "system",
+ moduleName: ctx.Config().SoongDefinedSystemImage(),
+ supported: true,
+ handwritten: true,
+ })
+ } else {
+ addGenerated("system")
+ }
if ctx.DeviceConfig().SystemExtPath() == "system_ext" {
- generatedPartitions = append(generatedPartitions, "system_ext")
+ addGenerated("system_ext")
}
if ctx.DeviceConfig().BuildingVendorImage() && ctx.DeviceConfig().VendorPath() == "vendor" {
- generatedPartitions = append(generatedPartitions, "vendor")
+ addGenerated("vendor")
}
if ctx.DeviceConfig().BuildingProductImage() && ctx.DeviceConfig().ProductPath() == "product" {
- generatedPartitions = append(generatedPartitions, "product")
+ addGenerated("product")
}
if ctx.DeviceConfig().BuildingOdmImage() && ctx.DeviceConfig().OdmPath() == "odm" {
- generatedPartitions = append(generatedPartitions, "odm")
+ addGenerated("odm")
}
if ctx.DeviceConfig().BuildingUserdataImage() && ctx.DeviceConfig().UserdataPath() == "data" {
- generatedPartitions = append(generatedPartitions, "userdata")
+ addGenerated("userdata")
}
if partitionVars.BuildingSystemDlkmImage {
- generatedPartitions = append(generatedPartitions, "system_dlkm")
+ addGenerated("system_dlkm")
}
if partitionVars.BuildingVendorDlkmImage {
- generatedPartitions = append(generatedPartitions, "vendor_dlkm")
+ addGenerated("vendor_dlkm")
}
if partitionVars.BuildingOdmDlkmImage {
- generatedPartitions = append(generatedPartitions, "odm_dlkm")
+ addGenerated("odm_dlkm")
}
if partitionVars.BuildingRamdiskImage {
- generatedPartitions = append(generatedPartitions, "ramdisk")
+ addGenerated("ramdisk")
}
if buildingVendorBootImage(partitionVars) {
- generatedPartitions = append(generatedPartitions, "vendor_ramdisk")
+ addGenerated("vendor_ramdisk")
}
if ctx.DeviceConfig().BuildingRecoveryImage() && ctx.DeviceConfig().RecoveryPath() == "recovery" {
- generatedPartitions = append(generatedPartitions, "recovery")
+ addGenerated("recovery")
}
- return generatedPartitions
+ return result
}
func (f *filesystemCreator) createInternalModules(ctx android.LoadHookContext) {
- soongGeneratedPartitions := generatedPartitions(ctx)
- finalSoongGeneratedPartitions := make([]string, 0, len(soongGeneratedPartitions))
- for _, partitionType := range soongGeneratedPartitions {
- if f.createPartition(ctx, partitionType) {
- f.properties.Generated_partition_types = append(f.properties.Generated_partition_types, partitionType)
- finalSoongGeneratedPartitions = append(finalSoongGeneratedPartitions, partitionType)
- } else {
- f.properties.Unsupported_partition_types = append(f.properties.Unsupported_partition_types, partitionType)
- }
+ partitions := generatedPartitions(ctx)
+ for i := range partitions {
+ f.createPartition(ctx, partitions, &partitions[i])
}
// Create android_info.prop
f.createAndroidInfo(ctx)
@@ -156,18 +249,37 @@
}
}
- for _, x := range createVbmetaPartitions(ctx, finalSoongGeneratedPartitions) {
+ var systemOtherImageName string
+ if buildingSystemOtherImage(partitionVars) {
+ systemModule := partitions.nameForType("system")
+ systemOtherImageName = generatedModuleNameForPartition(ctx.Config(), "system_other")
+ ctx.CreateModule(
+ filesystem.SystemOtherImageFactory,
+ &filesystem.SystemOtherImageProperties{
+ System_image: &systemModule,
+ Preinstall_dexpreopt_files_from: partitions.moduleNames(),
+ },
+ &struct {
+ Name *string
+ }{
+ Name: proptools.StringPtr(systemOtherImageName),
+ },
+ )
+ }
+
+ for _, x := range f.createVbmetaPartitions(ctx, partitions) {
f.properties.Vbmeta_module_names = append(f.properties.Vbmeta_module_names, x.moduleName)
f.properties.Vbmeta_partition_names = append(f.properties.Vbmeta_partition_names, x.partitionName)
}
+ var superImageSubpartitions []string
if buildingSuperImage(partitionVars) {
- createSuperImage(ctx, finalSoongGeneratedPartitions, partitionVars)
+ superImageSubpartitions = createSuperImage(ctx, partitions, partitionVars, systemOtherImageName)
f.properties.Super_image = ":" + generatedModuleNameForPartition(ctx.Config(), "super")
}
- ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).soongGeneratedPartitions = finalSoongGeneratedPartitions
- f.createDeviceModule(ctx, finalSoongGeneratedPartitions, f.properties.Vbmeta_module_names)
+ ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).soongGeneratedPartitions = partitions
+ f.createDeviceModule(ctx, partitions, f.properties.Vbmeta_module_names, superImageSubpartitions)
}
func generatedModuleName(cfg android.Config, suffix string) string {
@@ -182,6 +294,12 @@
return generatedModuleName(cfg, fmt.Sprintf("%s_image", partitionType))
}
+func buildingSystemOtherImage(partitionVars android.PartitionVariables) bool {
+ // TODO: Recreate this logic from make instead of just depending on the final result variable:
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/board_config.mk;l=429;drc=15a0df840e7093f65518003ab80cf24a3d9e8e6a
+ return partitionVars.BuildingSystemOtherImage
+}
+
func (f *filesystemCreator) createBootloaderFilegroup(ctx android.LoadHookContext) (string, bool) {
bootloaderPath := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.PrebuiltBootloader
if len(bootloaderPath) == 0 {
@@ -202,10 +320,31 @@
return bootloaderFilegroupName, true
}
+func (f *filesystemCreator) createReleaseToolsFilegroup(ctx android.LoadHookContext) (string, bool) {
+ releaseToolsDir := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.ReleaseToolsExtensionDir
+ if releaseToolsDir == "" {
+ return "", false
+ }
+
+ releaseToolsFilegroupName := generatedModuleName(ctx.Config(), "releasetools")
+ filegroupProps := &struct {
+ Name *string
+ Srcs []string
+ Visibility []string
+ }{
+ Name: proptools.StringPtr(releaseToolsFilegroupName),
+ Srcs: []string{"releasetools.py"},
+ Visibility: []string{"//visibility:public"},
+ }
+ ctx.CreateModuleInDirectory(android.FileGroupFactory, releaseToolsDir, filegroupProps)
+ return releaseToolsFilegroupName, true
+}
+
func (f *filesystemCreator) createDeviceModule(
ctx android.LoadHookContext,
- generatedPartitionTypes []string,
+ partitions allGeneratedPartitionData,
vbmetaPartitions []string,
+ superImageSubPartitions []string,
) {
baseProps := &struct {
Name *string
@@ -217,35 +356,38 @@
// Currently, only the system and system_ext partition module is created.
partitionProps := &filesystem.PartitionNameProperties{}
- if android.InList("system", generatedPartitionTypes) {
- partitionProps.System_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system"))
+ if f.properties.Super_image != "" {
+ partitionProps.Super_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "super"))
}
- if android.InList("system_ext", generatedPartitionTypes) {
- partitionProps.System_ext_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_ext"))
+ if modName := partitions.nameForType("system"); modName != "" && !android.InList("system", superImageSubPartitions) {
+ partitionProps.System_partition_name = proptools.StringPtr(modName)
}
- if android.InList("vendor", generatedPartitionTypes) {
- partitionProps.Vendor_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor"))
+ if modName := partitions.nameForType("system_ext"); modName != "" && !android.InList("system_ext", superImageSubPartitions) {
+ partitionProps.System_ext_partition_name = proptools.StringPtr(modName)
}
- if android.InList("product", generatedPartitionTypes) {
- partitionProps.Product_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "product"))
+ if modName := partitions.nameForType("vendor"); modName != "" && !android.InList("vendor", superImageSubPartitions) {
+ partitionProps.Vendor_partition_name = proptools.StringPtr(modName)
}
- if android.InList("odm", generatedPartitionTypes) {
- partitionProps.Odm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "odm"))
+ if modName := partitions.nameForType("product"); modName != "" && !android.InList("product", superImageSubPartitions) {
+ partitionProps.Product_partition_name = proptools.StringPtr(modName)
}
- if android.InList("userdata", f.properties.Generated_partition_types) {
- partitionProps.Userdata_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "userdata"))
+ if modName := partitions.nameForType("odm"); modName != "" && !android.InList("odm", superImageSubPartitions) {
+ partitionProps.Odm_partition_name = proptools.StringPtr(modName)
}
- if android.InList("recovery", f.properties.Generated_partition_types) {
- partitionProps.Recovery_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "recovery"))
+ if modName := partitions.nameForType("userdata"); modName != "" {
+ partitionProps.Userdata_partition_name = proptools.StringPtr(modName)
}
- if android.InList("system_dlkm", f.properties.Generated_partition_types) {
- partitionProps.System_dlkm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_dlkm"))
+ if modName := partitions.nameForType("recovery"); modName != "" && !ctx.DeviceConfig().BoardMoveRecoveryResourcesToVendorBoot() {
+ partitionProps.Recovery_partition_name = proptools.StringPtr(modName)
}
- if android.InList("vendor_dlkm", f.properties.Generated_partition_types) {
- partitionProps.Vendor_dlkm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor_dlkm"))
+ if modName := partitions.nameForType("system_dlkm"); modName != "" && !android.InList("system_dlkm", superImageSubPartitions) {
+ partitionProps.System_dlkm_partition_name = proptools.StringPtr(modName)
}
- if android.InList("odm_dlkm", f.properties.Generated_partition_types) {
- partitionProps.Odm_dlkm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "odm_dlkm"))
+ if modName := partitions.nameForType("vendor_dlkm"); modName != "" && !android.InList("vendor_dlkm", superImageSubPartitions) {
+ partitionProps.Vendor_dlkm_partition_name = proptools.StringPtr(modName)
+ }
+ if modName := partitions.nameForType("odm_dlkm"); modName != "" && !android.InList("odm_dlkm", superImageSubPartitions) {
+ partitionProps.Odm_dlkm_partition_name = proptools.StringPtr(modName)
}
if f.properties.Boot_image != "" {
partitionProps.Boot_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "boot"))
@@ -258,15 +400,26 @@
}
partitionProps.Vbmeta_partitions = vbmetaPartitions
- deviceProps := &filesystem.DeviceProperties{}
+ deviceProps := &filesystem.DeviceProperties{
+ Main_device: proptools.BoolPtr(true),
+ Ab_ota_updater: proptools.BoolPtr(ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.AbOtaUpdater),
+ Ab_ota_partitions: ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.AbOtaPartitions,
+ Ab_ota_postinstall_config: ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.AbOtaPostInstallConfig,
+ Ramdisk_node_list: proptools.StringPtr(":ramdisk_node_list"),
+ }
+
if bootloader, ok := f.createBootloaderFilegroup(ctx); ok {
deviceProps.Bootloader = proptools.StringPtr(":" + bootloader)
}
+ if releaseTools, ok := f.createReleaseToolsFilegroup(ctx); ok {
+ deviceProps.Releasetools_extension = proptools.StringPtr(":" + releaseTools)
+ }
ctx.CreateModule(filesystem.AndroidDeviceFactory, baseProps, partitionProps, deviceProps)
}
-func partitionSpecificFsProps(ctx android.EarlyModuleContext, fsProps *filesystem.FilesystemProperties, partitionVars android.PartitionVariables, partitionType string) {
+func partitionSpecificFsProps(ctx android.EarlyModuleContext, partitions allGeneratedPartitionData, fsProps *filesystem.FilesystemProperties, partitionType string) {
+ partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
switch partitionType {
case "system":
fsProps.Build_logtags = proptools.BoolPtr(true)
@@ -274,7 +427,7 @@
fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(true)
// Identical to that of the aosp_shared_system_image
if partitionVars.ProductFsverityGenerateMetadata {
- fsProps.Fsverity.Inputs = []string{
+ fsProps.Fsverity.Inputs = proptools.NewSimpleConfigurable([]string{
"etc/boot-image.prof",
"etc/dirty-image-objects",
"etc/preloaded-classes",
@@ -282,8 +435,8 @@
"framework/*",
"framework/*/*", // framework/{arch}
"framework/oat/*/*", // framework/oat/{arch}
- }
- fsProps.Fsverity.Libs = []string{":framework-res{.export-package.apk}"}
+ })
+ fsProps.Fsverity.Libs = proptools.NewSimpleConfigurable([]string{":framework-res{.export-package.apk}"})
}
fsProps.Symlinks = commonSymlinksFromRoot
fsProps.Symlinks = append(fsProps.Symlinks,
@@ -318,26 +471,26 @@
fsProps.Dirs = proptools.NewSimpleConfigurable(commonPartitionDirs)
fsProps.Security_patch = proptools.StringPtr(ctx.Config().PlatformSecurityPatch())
- if ctx.DeviceConfig().SystemExtPath() == "system_ext" {
- fsProps.Import_aconfig_flags_from = []string{generatedModuleNameForPartition(ctx.Config(), "system_ext")}
+ if systemExtName := partitions.nameForType("system_ext"); systemExtName != "" {
+ fsProps.Import_aconfig_flags_from = []string{systemExtName}
}
fsProps.Stem = proptools.StringPtr("system.img")
case "system_ext":
if partitionVars.ProductFsverityGenerateMetadata {
- fsProps.Fsverity.Inputs = []string{
+ fsProps.Fsverity.Inputs = proptools.NewSimpleConfigurable([]string{
"framework/*",
"framework/*/*", // framework/{arch}
"framework/oat/*/*", // framework/oat/{arch}
- }
- fsProps.Fsverity.Libs = []string{":framework-res{.export-package.apk}"}
+ })
+ fsProps.Fsverity.Libs = proptools.NewSimpleConfigurable([]string{":framework-res{.export-package.apk}"})
}
fsProps.Security_patch = proptools.StringPtr(ctx.Config().PlatformSecurityPatch())
fsProps.Stem = proptools.StringPtr("system_ext.img")
case "product":
fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(true)
- fsProps.Android_filesystem_deps.System = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system"))
- if ctx.DeviceConfig().SystemExtPath() == "system_ext" {
- fsProps.Android_filesystem_deps.System_ext = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_ext"))
+ fsProps.Android_filesystem_deps.System = proptools.StringPtr(partitions.nameForType("system"))
+ if systemExtName := partitions.nameForType("system_ext"); systemExtName != "" {
+ fsProps.Android_filesystem_deps.System_ext = proptools.StringPtr(systemExtName)
}
fsProps.Security_patch = proptools.StringPtr(ctx.Config().PlatformSecurityPatch())
fsProps.Stem = proptools.StringPtr("product.img")
@@ -353,9 +506,9 @@
Name: proptools.StringPtr("lib/modules"),
},
}
- fsProps.Android_filesystem_deps.System = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system"))
- if ctx.DeviceConfig().SystemExtPath() == "system_ext" {
- fsProps.Android_filesystem_deps.System_ext = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_ext"))
+ fsProps.Android_filesystem_deps.System = proptools.StringPtr(partitions.nameForType("system"))
+ if systemExtName := partitions.nameForType("system_ext"); systemExtName != "" {
+ fsProps.Android_filesystem_deps.System_ext = proptools.StringPtr(systemExtName)
}
fsProps.Security_patch = proptools.StringPtr(partitionVars.VendorSecurityPatch)
fsProps.Stem = proptools.StringPtr("vendor.img")
@@ -369,8 +522,33 @@
fsProps.Security_patch = proptools.StringPtr(partitionVars.OdmSecurityPatch)
fsProps.Stem = proptools.StringPtr("odm.img")
case "userdata":
- fsProps.Base_dir = proptools.StringPtr("data")
fsProps.Stem = proptools.StringPtr("userdata.img")
+ if vars, ok := partitionVars.PartitionQualifiedVariables["userdata"]; ok {
+ parsed, err := strconv.ParseInt(vars.BoardPartitionSize, 10, 64)
+ if err != nil {
+ panic(fmt.Sprintf("Partition size must be an int, got %s", vars.BoardPartitionSize))
+ }
+ fsProps.Partition_size = &parsed
+ // Disable avb for userdata partition
+ fsProps.Use_avb = nil
+ }
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=2265;drc=7f50a123045520f2c5e18e9eb4e83f92244a1459
+ if s, err := strconv.ParseBool(partitionVars.ProductFsCasefold); err == nil {
+ fsProps.Support_casefolding = proptools.BoolPtr(s)
+ } else if len(partitionVars.ProductFsCasefold) > 0 {
+ ctx.ModuleErrorf("Unrecognized PRODUCT_FS_CASEFOLD value %s", partitionVars.ProductFsCasefold)
+ }
+ if s, err := strconv.ParseBool(partitionVars.ProductQuotaProjid); err == nil {
+ fsProps.Support_project_quota = proptools.BoolPtr(s)
+ } else if len(partitionVars.ProductQuotaProjid) > 0 {
+ ctx.ModuleErrorf("Unrecognized PRODUCT_QUOTA_PROJID value %s", partitionVars.ProductQuotaProjid)
+ }
+ if s, err := strconv.ParseBool(partitionVars.ProductFsCompression); err == nil {
+ fsProps.Enable_compression = proptools.BoolPtr(s)
+ } else if len(partitionVars.ProductFsCompression) > 0 {
+ ctx.ModuleErrorf("Unrecognized PRODUCT_FS_COMPRESSION value %s", partitionVars.ProductFsCompression)
+ }
+
case "ramdisk":
// Following the logic in https://cs.android.com/android/platform/superproject/main/+/c3c5063df32748a8806ce5da5dd0db158eab9ad9:build/make/core/Makefile;l=1307
fsProps.Dirs = android.NewSimpleConfigurable([]string{
@@ -420,8 +598,8 @@
fsProps.Security_patch = proptools.StringPtr(partitionVars.OdmDlkmSecurityPatch)
fsProps.Stem = proptools.StringPtr("odm_dlkm.img")
case "vendor_ramdisk":
- if android.InList("recovery", generatedPartitions(ctx)) {
- fsProps.Include_files_of = []string{generatedModuleNameForPartition(ctx.Config(), "recovery")}
+ if recoveryName := partitions.nameForType("recovery"); recoveryName != "" {
+ fsProps.Include_files_of = []string{recoveryName}
}
fsProps.Stem = proptools.StringPtr("vendor_ramdisk.img")
}
@@ -435,16 +613,22 @@
}
)
-// Creates a soong module to build the given partition. Returns false if we can't support building
-// it.
-func (f *filesystemCreator) createPartition(ctx android.LoadHookContext, partitionType string) bool {
- baseProps := generateBaseProps(proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), partitionType)))
-
- fsProps, supported := generateFsProps(ctx, partitionType)
- if !supported {
- return false
+// Creates a soong module to build the given partition.
+func (f *filesystemCreator) createPartition(ctx android.LoadHookContext, partitions allGeneratedPartitionData, partition *generatedPartitionData) {
+ // Nextgen team's handwritten soong system image, don't need to create anything ourselves
+ if partition.partitionType == "system" && ctx.Config().UseSoongSystemImage() {
+ return
}
+ baseProps := generateBaseProps(proptools.StringPtr(partition.moduleName))
+
+ fsProps, supported := generateFsProps(ctx, partitions, partition.partitionType)
+ if !supported {
+ partition.supported = false
+ return
+ }
+
+ partitionType := partition.partitionType
if partitionType == "vendor" || partitionType == "product" || partitionType == "system" {
fsProps.Linker_config.Gen_linker_config = proptools.BoolPtr(true)
if partitionType != "system" {
@@ -468,7 +652,6 @@
if partitionType == "vendor" {
f.createVendorBuildProp(ctx)
}
- return true
}
// Creates filegroups for the files specified in BOARD_(partition_)AVB_KEY_PATH
@@ -670,7 +853,7 @@
moduleName := generatedModuleName(ctx.Config(), "recovery-prop.default")
var vendorBuildProp *string
- if android.InList("vendor", generatedPartitions(ctx)) {
+ if ctx.DeviceConfig().BuildingVendorImage() && ctx.DeviceConfig().VendorPath() == "vendor" {
vendorBuildProp = proptools.StringPtr(":" + generatedModuleName(ctx.Config(), "vendor-build.prop"))
}
@@ -760,7 +943,7 @@
}
}
-func generateFsProps(ctx android.EarlyModuleContext, partitionType string) (*filesystem.FilesystemProperties, bool) {
+func generateFsProps(ctx android.EarlyModuleContext, partitions allGeneratedPartitionData, partitionType string) (*filesystem.FilesystemProperties, bool) {
fsProps := &filesystem.FilesystemProperties{}
partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
@@ -804,6 +987,8 @@
fsProps.Avb_algorithm = avbInfo.avbAlgorithm
// BOARD_AVB_SYSTEM_ROLLBACK_INDEX
fsProps.Rollback_index = avbInfo.avbRollbackIndex
+ // BOARD_AVB_SYSTEM_ROLLBACK_INDEX_LOCATION
+ fsProps.Rollback_index_location = avbInfo.avbRollbackIndexLocation
fsProps.Avb_hash_algorithm = avbInfo.avbHashAlgorithm
fsProps.Partition_name = proptools.StringPtr(partitionType)
@@ -817,22 +1002,29 @@
fsProps.Is_auto_generated = proptools.BoolPtr(true)
if partitionType != "system" {
- fsProps.Mount_point = proptools.StringPtr(partitionType)
+ mountPoint := proptools.StringPtr(partitionType)
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/make/tools/releasetools/build_image.py;l=1012;drc=3f576a753594bad3fc838ccb8b1b72f7efac1d50
+ if partitionType == "userdata" {
+ mountPoint = proptools.StringPtr("data")
+ }
+ fsProps.Mount_point = mountPoint
+
}
- partitionSpecificFsProps(ctx, fsProps, partitionVars, partitionType)
+ partitionSpecificFsProps(ctx, partitions, fsProps, partitionType)
return fsProps, true
}
type avbInfo struct {
- avbEnable *bool
- avbKeyPath *string
- avbkeyFilegroup *string
- avbAlgorithm *string
- avbRollbackIndex *int64
- avbMode *string
- avbHashAlgorithm *string
+ avbEnable *bool
+ avbKeyPath *string
+ avbkeyFilegroup *string
+ avbAlgorithm *string
+ avbRollbackIndex *int64
+ avbRollbackIndexLocation *int64
+ avbMode *string
+ avbHashAlgorithm *string
}
func getAvbInfo(config android.Config, partitionType string) avbInfo {
@@ -872,12 +1064,12 @@
}
result.avbRollbackIndex = &parsed
}
- if specificPartitionVars.BoardAvbRollbackIndex != "" {
- parsed, err := strconv.ParseInt(specificPartitionVars.BoardAvbRollbackIndex, 10, 64)
+ if specificPartitionVars.BoardAvbRollbackIndexLocation != "" {
+ parsed, err := strconv.ParseInt(specificPartitionVars.BoardAvbRollbackIndexLocation, 10, 64)
if err != nil {
- panic(fmt.Sprintf("Rollback index must be an int, got %s", specificPartitionVars.BoardAvbRollbackIndex))
+ panic(fmt.Sprintf("Rollback index location must be an int, got %s", specificPartitionVars.BoardAvbRollbackIndexLocation))
}
- result.avbRollbackIndex = &parsed
+ result.avbRollbackIndexLocation = &parsed
}
// Make allows you to pass arbitrary arguments to avbtool via this variable, but in practice
@@ -899,12 +1091,12 @@
return result
}
-func (f *filesystemCreator) createFileListDiffTest(ctx android.ModuleContext, partitionType string) android.Path {
- partitionModuleName := generatedModuleNameForPartition(ctx.Config(), partitionType)
+func (f *filesystemCreator) createFileListDiffTest(ctx android.ModuleContext, partitionType string, partitionModuleName string) android.Path {
partitionImage := ctx.GetDirectDepWithTag(partitionModuleName, generatedFilesystemDepTag)
filesystemInfo, ok := android.OtherModuleProvider(ctx, partitionImage, filesystem.FilesystemProvider)
if !ok {
ctx.ModuleErrorf("Expected module %s to provide FileysystemInfo", partitionModuleName)
+ return nil
}
makeFileList := android.PathForArbitraryOutput(ctx, fmt.Sprintf("target/product/%s/obj/PACKAGING/%s_intermediates/file_list.txt", ctx.Config().DeviceName(), partitionType))
diffTestResultFile := android.PathForModuleOut(ctx, fmt.Sprintf("diff_test_%s.txt", partitionModuleName))
@@ -965,8 +1157,8 @@
var generatedVbmetaPartitionDepTag imageDepTagType
func (f *filesystemCreator) DepsMutator(ctx android.BottomUpMutatorContext) {
- for _, partitionType := range f.properties.Generated_partition_types {
- ctx.AddDependency(ctx.Module(), generatedFilesystemDepTag, generatedModuleNameForPartition(ctx.Config(), partitionType))
+ for _, name := range ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).soongGeneratedPartitions.names() {
+ ctx.AddDependency(ctx.Module(), generatedFilesystemDepTag, name)
}
for _, vbmetaModule := range f.properties.Vbmeta_module_names {
ctx.AddDependency(ctx.Module(), generatedVbmetaPartitionDepTag, vbmetaModule)
@@ -979,9 +1171,11 @@
}
f.HideFromMake()
+ partitions := ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).soongGeneratedPartitions
+
var content strings.Builder
generatedBp := android.PathForModuleOut(ctx, "soong_generated_product_config.bp")
- for _, partition := range ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).soongGeneratedPartitions {
+ for _, partition := range partitions.types() {
content.WriteString(generateBpContent(ctx, partition))
content.WriteString("\n")
}
@@ -989,13 +1183,17 @@
ctx.Phony("product_config_to_bp", generatedBp)
+ if !ctx.Config().KatiEnabled() {
+ // Cannot diff since the kati packaging rules will not be created.
+ return
+ }
var diffTestFiles []android.Path
- for _, partitionType := range f.properties.Generated_partition_types {
- diffTestFile := f.createFileListDiffTest(ctx, partitionType)
+ for _, partitionType := range partitions.types() {
+ diffTestFile := f.createFileListDiffTest(ctx, partitionType, partitions.nameForType(partitionType))
diffTestFiles = append(diffTestFiles, diffTestFile)
ctx.Phony(fmt.Sprintf("soong_generated_%s_filesystem_test", partitionType), diffTestFile)
}
- for _, partitionType := range f.properties.Unsupported_partition_types {
+ for _, partitionType := range slices.Concat(partitions.unsupportedTypes(), f.properties.Unsupported_partition_types) {
diffTestFile := createFailingCommand(ctx, fmt.Sprintf("Couldn't build %s partition", partitionType))
diffTestFiles = append(diffTestFiles, diffTestFile)
ctx.Phony(fmt.Sprintf("soong_generated_%s_filesystem_test", partitionType), diffTestFile)
@@ -1041,13 +1239,13 @@
}
func generateBpContent(ctx android.EarlyModuleContext, partitionType string) string {
- fsProps, fsTypeSupported := generateFsProps(ctx, partitionType)
+ fsGenState := ctx.Config().Get(fsGenStateOnceKey).(*FsGenState)
+ fsProps, fsTypeSupported := generateFsProps(ctx, fsGenState.soongGeneratedPartitions, partitionType)
if !fsTypeSupported {
return ""
}
baseProps := generateBaseProps(proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), partitionType)))
- fsGenState := ctx.Config().Get(fsGenStateOnceKey).(*FsGenState)
deps := fsGenState.fsDeps[partitionType]
highPriorityDeps := fsGenState.generatedPrebuiltEtcModuleNames
depProps := generateDepStruct(*deps, highPriorityDeps)
diff --git a/fsgen/filesystem_creator_test.go b/fsgen/filesystem_creator_test.go
index 5657608..418e48b 100644
--- a/fsgen/filesystem_creator_test.go
+++ b/fsgen/filesystem_creator_test.go
@@ -15,17 +15,29 @@
package fsgen
import (
+ "strings"
+ "testing"
+
"android/soong/android"
"android/soong/etc"
"android/soong/filesystem"
"android/soong/java"
- "testing"
"github.com/google/blueprint/proptools"
)
var prepareForTestWithFsgenBuildComponents = android.FixtureRegisterWithContext(registerBuildComponents)
+var prepareMockRamdiksNodeList = android.FixtureMergeMockFs(android.MockFS{
+ "ramdisk_node_list/ramdisk_node_list": nil,
+ "ramdisk_node_list/Android.bp": []byte(`
+ filegroup {
+ name: "ramdisk_node_list",
+ srcs: ["ramdisk_node_list"],
+ }
+ `),
+})
+
func TestFileSystemCreatorSystemImageProps(t *testing.T) {
result := android.GroupFixturePreparers(
android.PrepareForIntegrationTestWithAndroid,
@@ -45,6 +57,7 @@
},
}
}),
+ prepareMockRamdiksNodeList,
android.FixtureMergeMockFs(android.MockFS{
"external/avb/test/data/testkey_rsa4096.pem": nil,
"external/avb/test/Android.bp": []byte(`
@@ -61,7 +74,7 @@
}),
).RunTest(t)
- fooSystem := result.ModuleForTests("test_product_generated_system_image", "android_common").Module().(interface {
+ fooSystem := result.ModuleForTests(t, "test_product_generated_system_image", "android_common").Module().(interface {
FsProps() filesystem.FilesystemProperties
})
android.AssertBoolEquals(
@@ -114,6 +127,7 @@
},
}
}),
+ prepareMockRamdiksNodeList,
android.FixtureMergeMockFs(android.MockFS{
"external/avb/test/data/testkey_rsa4096.pem": nil,
"build/soong/fsgen/Android.bp": []byte(`
@@ -170,6 +184,7 @@
}
}),
android.PrepareForNativeBridgeEnabled,
+ prepareMockRamdiksNodeList,
android.FixtureMergeMockFs(android.MockFS{
"external/avb/test/data/testkey_rsa4096.pem": nil,
"build/soong/fsgen/Android.bp": []byte(`
@@ -198,14 +213,14 @@
).RunTest(t)
var packagingProps android.PackagingProperties
- for _, prop := range result.ModuleForTests("test_product_generated_system_image", "android_common").Module().GetProperties() {
+ for _, prop := range result.ModuleForTests(t, "test_product_generated_system_image", "android_common").Module().GetProperties() {
if packagingPropStruct, ok := prop.(*android.PackagingProperties); ok {
packagingProps = *packagingPropStruct
}
}
moduleDeps := packagingProps.Multilib.Lib64.Deps
- eval := result.ModuleForTests("test_product_generated_system_image", "android_common").Module().ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext))
+ eval := result.ModuleForTests(t, "test_product_generated_system_image", "android_common").Module().ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext))
android.AssertStringListContains(
t,
"Generated system image expected to depend on \"bar\" defined in \"a/b\" namespace",
@@ -227,6 +242,7 @@
android.PrepareForTestWithAllowMissingDependencies,
prepareForTestWithFsgenBuildComponents,
java.PrepareForTestWithJavaBuildComponents,
+ prepareMockRamdiksNodeList,
android.FixtureMergeMockFs(android.MockFS{
"external/avb/test/data/testkey_rsa4096.pem": nil,
"build/soong/fsgen/Android.bp": []byte(`
@@ -279,6 +295,7 @@
},
}
}),
+ prepareMockRamdiksNodeList,
android.FixtureMergeMockFs(android.MockFS{
"external/avb/test/data/testkey_rsa4096.pem": nil,
"build/soong/fsgen/Android.bp": []byte(`
@@ -304,7 +321,7 @@
}
// check generated prebuilt_* module type install path and install partition
- generatedModule := result.ModuleForTests("system-frameworks_base_config-etc-0", "android_arm64_armv8-a").Module()
+ generatedModule := result.ModuleForTests(t, "system-frameworks_base_config-etc-0", "android_arm64_armv8-a").Module()
etcModule, _ := generatedModule.(*etc.PrebuiltEtc)
android.AssertStringEquals(
t,
@@ -322,7 +339,7 @@
)
// check generated prebuilt_* module specifies correct relative_install_path property
- generatedModule = result.ModuleForTests("system-frameworks_base_data_keyboards-usr_keylayout_subdir-0", "android_arm64_armv8-a").Module()
+ generatedModule = result.ModuleForTests(t, "system-frameworks_base_data_keyboards-usr_keylayout_subdir-0", "android_arm64_armv8-a").Module()
etcModule, _ = generatedModule.(*etc.PrebuiltEtc)
android.AssertStringEquals(
t,
@@ -332,16 +349,16 @@
)
// check that prebuilt_* module is not generated for non existing source file
- android.AssertPanicMessageContains(
+ android.AssertStringEquals(
t,
"prebuilt_* module not generated for non existing source file",
- "failed to find module \"system-some_non_existing-etc-0\"",
- func() { result.ModuleForTests("system-some_non_existing-etc-0", "android_arm64_armv8-a") },
+ "",
+ strings.Join(result.ModuleVariantsForTests("system-some_non_existing-etc-0"), ","),
)
// check that duplicate src file can exist in PRODUCT_COPY_FILES and generates separate modules
- generatedModule0 := result.ModuleForTests("product-device_sample_etc-etc-0", "android_arm64_armv8-a").Module()
- generatedModule1 := result.ModuleForTests("product-device_sample_etc-etc-1", "android_arm64_armv8-a").Module()
+ generatedModule0 := result.ModuleForTests(t, "product-device_sample_etc-etc-0", "android_arm64_armv8-a").Module()
+ generatedModule1 := result.ModuleForTests(t, "product-device_sample_etc-etc-1", "android_arm64_armv8-a").Module()
// check that generated prebuilt_* module sets correct srcs and dsts property
eval := generatedModule0.ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext))
diff --git a/fsgen/fsgen_mutators.go b/fsgen/fsgen_mutators.go
index 9327669..9b25e77 100644
--- a/fsgen/fsgen_mutators.go
+++ b/fsgen/fsgen_mutators.go
@@ -60,8 +60,8 @@
depCandidates []string
// Map of names of partition to the information of modules to be added as deps
fsDeps map[string]*multilibDeps
- // List of name of partitions to be generated by the filesystem_creator module
- soongGeneratedPartitions []string
+ // Information about the main soong-generated partitions
+ soongGeneratedPartitions allGeneratedPartitionData
// Mutex to protect the fsDeps
fsDepsMutex sync.Mutex
// Map of _all_ soong module names to their corresponding installation properties
@@ -282,9 +282,12 @@
removeOverriddenDeps(mctx)
fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState)
fsDeps := fsGenState.fsDeps
- soongGeneratedPartitionMap := getAllSoongGeneratedPartitionNames(mctx.Config(), fsGenState.soongGeneratedPartitions)
m := mctx.Module()
- if partition, ok := soongGeneratedPartitionMap[m.Name()]; ok {
+ if partition := fsGenState.soongGeneratedPartitions.typeForName(m.Name()); partition != "" {
+ if fsGenState.soongGeneratedPartitions.isHandwritten(m.Name()) {
+ // Handwritten image, don't modify it
+ return
+ }
depsStruct := generateDepStruct(*fsDeps[partition], fsGenState.generatedPrebuiltEtcModuleNames)
if err := proptools.AppendMatchingProperties(m.GetProperties(), depsStruct, nil); err != nil {
mctx.ModuleErrorf(err.Error())
diff --git a/fsgen/super_img.go b/fsgen/super_img.go
index a36f614..569f780 100644
--- a/fsgen/super_img.go
+++ b/fsgen/super_img.go
@@ -27,7 +27,12 @@
return partitionVars.ProductBuildSuperPartition
}
-func createSuperImage(ctx android.LoadHookContext, partitions []string, partitionVars android.PartitionVariables) {
+func createSuperImage(
+ ctx android.LoadHookContext,
+ partitions allGeneratedPartitionData,
+ partitionVars android.PartitionVariables,
+ systemOtherImageName string,
+) []string {
baseProps := &struct {
Name *string
}{
@@ -39,10 +44,30 @@
Block_devices: partitionVars.BoardSuperPartitionBlockDevices,
Ab_update: proptools.BoolPtr(partitionVars.AbOtaUpdater),
Retrofit: proptools.BoolPtr(partitionVars.ProductRetrofitDynamicPartitions),
- Virtual_ab: proptools.BoolPtr(partitionVars.ProductVirtualAbOta),
- Virtual_ab_retrofit: proptools.BoolPtr(partitionVars.ProductVirtualAbOtaRetrofit),
Use_dynamic_partitions: proptools.BoolPtr(partitionVars.ProductUseDynamicPartitions),
}
+ if partitionVars.ProductVirtualAbOta {
+ superImageProps.Virtual_ab.Enable = proptools.BoolPtr(true)
+ superImageProps.Virtual_ab.Retrofit = proptools.BoolPtr(partitionVars.ProductVirtualAbOtaRetrofit)
+ superImageProps.Virtual_ab.Compression = proptools.BoolPtr(partitionVars.ProductVirtualAbCompression)
+ if partitionVars.ProductVirtualAbCompressionMethod != "" {
+ superImageProps.Virtual_ab.Compression_method = proptools.StringPtr(partitionVars.ProductVirtualAbCompressionMethod)
+ }
+ if partitionVars.ProductVirtualAbCompressionFactor != "" {
+ factor, err := strconv.ParseInt(partitionVars.ProductVirtualAbCompressionFactor, 10, 32)
+ if err != nil {
+ ctx.ModuleErrorf("Compression factor must be an int, got %q", partitionVars.ProductVirtualAbCompressionFactor)
+ }
+ superImageProps.Virtual_ab.Compression_factor = proptools.Int64Ptr(factor)
+ }
+ if partitionVars.ProductVirtualAbCowVersion != "" {
+ version, err := strconv.ParseInt(partitionVars.ProductVirtualAbCowVersion, 10, 32)
+ if err != nil {
+ ctx.ModuleErrorf("COW version must be an int, got %q", partitionVars.ProductVirtualAbCowVersion)
+ }
+ superImageProps.Virtual_ab.Cow_version = proptools.Int64Ptr(version)
+ }
+ }
size, _ := strconv.ParseInt(partitionVars.BoardSuperPartitionSize, 10, 64)
superImageProps.Size = proptools.Int64Ptr(size)
sparse := !partitionVars.TargetUserimagesSparseExtDisabled && !partitionVars.TargetUserimagesSparseF2fsDisabled
@@ -59,34 +84,49 @@
}
superImageProps.Partition_groups = partitionGroupsInfo
+ if systemOtherImageName != "" {
+ superImageProps.System_other_partition = proptools.StringPtr(systemOtherImageName)
+ }
+
+ var superImageSubpartitions []string
partitionNameProps := &filesystem.SuperImagePartitionNameProperties{}
- if android.InList("system", partitions) {
- partitionNameProps.System_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system"))
+ if modName := partitions.nameForType("system"); modName != "" {
+ partitionNameProps.System_partition = proptools.StringPtr(modName)
+ superImageSubpartitions = append(superImageSubpartitions, "system")
}
- if android.InList("system_ext", partitions) {
- partitionNameProps.System_ext_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_ext"))
+ if modName := partitions.nameForType("system_ext"); modName != "" {
+ partitionNameProps.System_ext_partition = proptools.StringPtr(modName)
+ superImageSubpartitions = append(superImageSubpartitions, "system_ext")
}
- if android.InList("system_dlkm", partitions) {
- partitionNameProps.System_dlkm_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_dlkm"))
+ if modName := partitions.nameForType("system_dlkm"); modName != "" {
+ partitionNameProps.System_dlkm_partition = proptools.StringPtr(modName)
+ superImageSubpartitions = append(superImageSubpartitions, "system_dlkm")
}
- if android.InList("system_other", partitions) {
- partitionNameProps.System_other_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_other"))
+ if modName := partitions.nameForType("system_other"); modName != "" {
+ partitionNameProps.System_other_partition = proptools.StringPtr(modName)
+ superImageSubpartitions = append(superImageSubpartitions, "system_other")
}
- if android.InList("product", partitions) {
- partitionNameProps.Product_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "product"))
+ if modName := partitions.nameForType("product"); modName != "" {
+ partitionNameProps.Product_partition = proptools.StringPtr(modName)
+ superImageSubpartitions = append(superImageSubpartitions, "product")
}
- if android.InList("vendor", partitions) {
- partitionNameProps.Vendor_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor"))
+ if modName := partitions.nameForType("vendor"); modName != "" {
+ partitionNameProps.Vendor_partition = proptools.StringPtr(modName)
+ superImageSubpartitions = append(superImageSubpartitions, "vendor")
}
- if android.InList("vendor_dlkm", partitions) {
- partitionNameProps.Vendor_dlkm_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor_dlkm"))
+ if modName := partitions.nameForType("vendor_dlkm"); modName != "" {
+ partitionNameProps.Vendor_dlkm_partition = proptools.StringPtr(modName)
+ superImageSubpartitions = append(superImageSubpartitions, "vendor_dlkm")
}
- if android.InList("odm", partitions) {
- partitionNameProps.Odm_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "odm"))
+ if modName := partitions.nameForType("odm"); modName != "" {
+ partitionNameProps.Odm_partition = proptools.StringPtr(modName)
+ superImageSubpartitions = append(superImageSubpartitions, "odm")
}
- if android.InList("odm_dlkm", partitions) {
- partitionNameProps.Odm_dlkm_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "odm_dlkm"))
+ if modName := partitions.nameForType("odm_dlkm"); modName != "" {
+ partitionNameProps.Odm_dlkm_partition = proptools.StringPtr(modName)
+ superImageSubpartitions = append(superImageSubpartitions, "odm_dlkm")
}
ctx.CreateModule(filesystem.SuperImageFactory, baseProps, superImageProps, partitionNameProps)
+ return superImageSubpartitions
}
diff --git a/fsgen/vbmeta_partitions.go b/fsgen/vbmeta_partitions.go
index 11c5759..11f4bd0 100644
--- a/fsgen/vbmeta_partitions.go
+++ b/fsgen/vbmeta_partitions.go
@@ -17,9 +17,7 @@
import (
"android/soong/android"
"android/soong/filesystem"
- "slices"
"strconv"
- "strings"
"github.com/google/blueprint/proptools"
)
@@ -32,6 +30,27 @@
partitionName string
}
+// https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=4849;drc=62e20f0d218f60bae563b4ee742d88cca1fc1901
+var avbPartitions = []string{
+ "boot",
+ "init_boot",
+ "vendor_boot",
+ "vendor_kernel_boot",
+ "system",
+ "vendor",
+ "product",
+ "system_ext",
+ "odm",
+ "vendor_dlkm",
+ "odm_dlkm",
+ "system_dlkm",
+ "dtbo",
+ "pvmfw",
+ "recovery",
+ "vbmeta_system",
+ "vbmeta_vendor",
+}
+
// Creates the vbmeta partition and the chained vbmeta partitions. Returns the list of module names
// that the function created. May return nil if the product isn't using avb.
//
@@ -43,7 +62,7 @@
// like vbmeta_system might contain the avb metadata for just a few products. In cuttlefish
// vbmeta_system contains metadata about product, system, and system_ext. Using chained partitions,
// that group of partitions can be updated independently from the other signed partitions.
-func createVbmetaPartitions(ctx android.LoadHookContext, generatedPartitionTypes []string) []vbmetaModuleInfo {
+func (f *filesystemCreator) createVbmetaPartitions(ctx android.LoadHookContext, partitions allGeneratedPartitionData) []vbmetaModuleInfo {
partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
// Some products seem to have BuildingVbmetaImage as true even when BoardAvbEnable is false
if !partitionVars.BuildingVbmetaImage || !partitionVars.BoardAvbEnable {
@@ -52,14 +71,16 @@
var result []vbmetaModuleInfo
- var chainedPartitions []string
- var partitionTypesHandledByChainedPartitions []string
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=4593;drc=62e20f0d218f60bae563b4ee742d88cca1fc1901
+ var internalAvbPartitionsInChainedVbmetaImages []string
+ var chainedPartitionTypes []string
for _, chainedName := range android.SortedKeys(partitionVars.ChainedVbmetaPartitions) {
props := partitionVars.ChainedVbmetaPartitions[chainedName]
chainedName = "vbmeta_" + chainedName
if len(props.Partitions) == 0 {
continue
}
+ internalAvbPartitionsInChainedVbmetaImages = append(internalAvbPartitionsInChainedVbmetaImages, props.Partitions...)
if len(props.Key) == 0 {
ctx.ModuleErrorf("No key found for chained avb partition %q", chainedName)
continue
@@ -92,15 +113,12 @@
var partitionModules []string
for _, partition := range props.Partitions {
- partitionTypesHandledByChainedPartitions = append(partitionTypesHandledByChainedPartitions, partition)
- if !slices.Contains(generatedPartitionTypes, partition) {
- // The partition is probably unsupported.
- continue
+ if modName := partitions.nameForType(partition); modName != "" {
+ partitionModules = append(partitionModules, modName)
}
- partitionModules = append(partitionModules, generatedModuleNameForPartition(ctx.Config(), partition))
}
- name := generatedModuleName(ctx.Config(), chainedName)
+ name := generatedModuleNameForPartition(ctx.Config(), chainedName)
ctx.CreateModuleInDirectory(
filesystem.VbmetaFactory,
".", // Create in the root directory for now so its easy to get the key
@@ -119,15 +137,15 @@
},
).HideFromMake()
- chainedPartitions = append(chainedPartitions, name)
-
result = append(result, vbmetaModuleInfo{
moduleName: name,
partitionName: chainedName,
})
+
+ chainedPartitionTypes = append(chainedPartitionTypes, chainedName)
}
- vbmetaModuleName := generatedModuleName(ctx.Config(), "vbmeta")
+ vbmetaModuleName := generatedModuleNameForPartition(ctx.Config(), "vbmeta")
var algorithm *string
var ri *int64
@@ -148,19 +166,83 @@
ri = &parsedRi
}
- var partitionModules []string
- for _, partitionType := range generatedPartitionTypes {
- if slices.Contains(partitionTypesHandledByChainedPartitions, partitionType) {
- // Already handled by a chained vbmeta partition
+ // --chain_partition argument is only set for partitions that set
+ // `BOARD_AVB_<partition name>_KEY_PATH` value and is not "recovery"
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=4823;drc=62e20f0d218f60bae563b4ee742d88cca1fc1901
+ includeAsChainedPartitionInVbmeta := func(partition string) bool {
+ val, ok := partitionVars.PartitionQualifiedVariables[partition]
+ return ok && len(val.BoardAvbKeyPath) > 0 && partition != "recovery"
+ }
+
+ // --include_descriptors_from_image is passed if both conditions are met:
+ // - `BOARD_AVB_<partition name>_KEY_PATH` value is not set
+ // - not included in INTERNAL_AVB_PARTITIONS_IN_CHAINED_VBMETA_IMAGES
+ // for partitions that set INSTALLED_<partition name>IMAGE_TARGET
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=4827;drc=62e20f0d218f60bae563b4ee742d88cca1fc1901
+ includeAsIncludedPartitionInVbmeta := func(partition string) bool {
+ if android.InList(partition, internalAvbPartitionsInChainedVbmetaImages) {
+ // Already handled by chained vbmeta partitions
+ return false
+ }
+ partitionQualifiedVars := partitionVars.PartitionQualifiedVariables[partition]
+
+ // The return logic in the switch cases below are identical to
+ // ifdef INSTALLED_<partition name>IMAGE_TARGET
+ switch partition {
+ case "boot":
+ return partitionQualifiedVars.BuildingImage || partitionQualifiedVars.PrebuiltImage || partitionVars.BoardUsesRecoveryAsBoot
+ case "vendor_kernel_boot", "dtbo":
+ return partitionQualifiedVars.PrebuiltImage
+ case "system":
+ return partitionQualifiedVars.BuildingImage
+ case "init_boot", "vendor_boot", "vendor", "product", "system_ext", "odm", "vendor_dlkm", "odm_dlkm", "system_dlkm":
+ return partitionQualifiedVars.BuildingImage || partitionQualifiedVars.PrebuiltImage
+ // TODO: Import BOARD_USES_PVMFWIMAGE
+ // ifeq ($(BOARD_USES_PVMFWIMAGE),true)
+ // case "pvmfw":
+ case "recovery":
+ // ifdef INSTALLED_RECOVERYIMAGE_TARGET
+ return !ctx.DeviceConfig().BoardUsesRecoveryAsBoot() && !ctx.DeviceConfig().BoardMoveRecoveryResourcesToVendorBoot()
+ // Technically these partitions are determined based on len(BOARD_AVB_VBMETA_SYSTEM) and
+ // len(BOARD_AVB_VBMETA_VENDOR) but if these are non empty these partitions are
+ // already included in the chained partitions.
+ case "vbmeta_system", "vbmeta_vendor":
+ return false
+ default:
+ return false
+ }
+ }
+
+ var chainedPartitionModules []string
+ var includePartitionModules []string
+ allGeneratedPartitionTypes := append(partitions.types(),
+ chainedPartitionTypes...,
+ )
+ if len(f.properties.Boot_image) > 0 {
+ allGeneratedPartitionTypes = append(allGeneratedPartitionTypes, "boot")
+ }
+ if len(f.properties.Init_boot_image) > 0 {
+ allGeneratedPartitionTypes = append(allGeneratedPartitionTypes, "init_boot")
+ }
+ if len(f.properties.Vendor_boot_image) > 0 {
+ allGeneratedPartitionTypes = append(allGeneratedPartitionTypes, "vendor_boot")
+ }
+
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=4919;drc=62e20f0d218f60bae563b4ee742d88cca1fc1901
+ for _, partitionType := range android.SortedUniqueStrings(append(avbPartitions, chainedPartitionTypes...)) {
+ if !android.InList(partitionType, allGeneratedPartitionTypes) {
+ // Skip if the partition is not auto generated
continue
}
- if strings.Contains(partitionType, "ramdisk") || strings.Contains(partitionType, "boot") {
- // ramdisk is never signed with avb information
- // boot partitions just have the avb footer, and don't have a corresponding vbmeta
- // partition.
- continue
+ name := partitions.nameForType(partitionType)
+ if name == "" {
+ name = generatedModuleNameForPartition(ctx.Config(), partitionType)
}
- partitionModules = append(partitionModules, generatedModuleNameForPartition(ctx.Config(), partitionType))
+ if includeAsChainedPartitionInVbmeta(partitionType) {
+ chainedPartitionModules = append(chainedPartitionModules, name)
+ } else if includeAsIncludedPartitionInVbmeta(partitionType) {
+ includePartitionModules = append(includePartitionModules, name)
+ }
}
ctx.CreateModuleInDirectory(
@@ -171,8 +253,9 @@
Algorithm: algorithm,
Private_key: key,
Rollback_index: ri,
- Chained_partitions: chainedPartitions,
- Partitions: proptools.NewSimpleConfigurable(partitionModules),
+ Chained_partitions: chainedPartitionModules,
+ Partitions: proptools.NewSimpleConfigurable(includePartitionModules),
+ Partition_name: proptools.StringPtr("vbmeta"),
}, &struct {
Name *string
}{
diff --git a/fuzz/fuzz_common.go b/fuzz/fuzz_common.go
index 3fd79a7..83ccd89 100644
--- a/fuzz/fuzz_common.go
+++ b/fuzz/fuzz_common.go
@@ -427,6 +427,12 @@
// device's first architecture's variant. Can be useful to add device-built apps to the data
// of a host test.
Device_first_data []string `android:"path_device_first"`
+
+ // Same as data, but will add dependencies on modules using the host's os variation and
+ // the common arch variation. Useful for a device test that wants to depend on a host
+ // module, for example to include a custom Tradefed test runner.
+ Host_common_data []string `android:"path_host_common"`
+
// Optional dictionary to be installed to the fuzz target's output directory.
Dictionary *string `android:"path"`
// Define the fuzzing frameworks this fuzz target can be built for. If
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 9a8524b..6bd1fcc 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -281,6 +281,7 @@
"hardware/google/camera/common/hal/aidl_service:aidl_camera_build_version",
"tools/tradefederation/core:tradefed_zip",
"vendor/google/services/LyricCameraHAL/src/apex:com.google.pixel.camera.hal.manifest",
+ "vendor/google_tradefederation/core:gen_google_tradefed_zip",
// go/keep-sorted end
}
allowlistMap := make(map[string]bool, len(allowlist))
@@ -349,7 +350,7 @@
// replaced the dependency.
module := android.PrebuiltGetPreferred(ctx, proxy)
tool := ctx.OtherModuleName(module)
- if h, ok := android.OtherModuleProvider(ctx, module, android.HostToolProviderKey); ok {
+ if h, ok := android.OtherModuleProvider(ctx, module, android.HostToolProviderInfoProvider); ok {
// A HostToolProvider provides the path to a tool, which will be copied
// into the sandbox.
if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled {
@@ -726,11 +727,8 @@
var _ android.ApexModule = (*Module)(nil)
// Implements android.ApexModule
-func (g *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
- sdkVersion android.ApiLevel) error {
- // Because generated outputs are checked by client modules(e.g. cc_library, ...)
- // we can safely ignore the check here.
- return nil
+func (m *Module) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
+ return android.MinApiLevel
}
func generatorFactory(taskGenerator taskFunc, props ...interface{}) *Module {
diff --git a/genrule/genrule_test.go b/genrule/genrule_test.go
index 688db07..dcec297 100644
--- a/genrule/genrule_test.go
+++ b/genrule/genrule_test.go
@@ -515,7 +515,7 @@
for _, test := range testcases {
t.Run(test.name, func(t *testing.T) {
- gen := result.ModuleForTests(test.name, "")
+ gen := result.ModuleForTests(t, test.name, "")
manifest := android.RuleBuilderSboxProtoForTests(t, result.TestContext, gen.Output("genrule.sbox.textproto"))
hash := manifest.Commands[0].GetInputHash()
@@ -643,7 +643,7 @@
ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern(expectedErrors)).
RunTestWithBp(t, testGenruleBp()+bp)
- mod := result.ModuleForTests("gen", "")
+ mod := result.ModuleForTests(t, "gen", "")
if expectedErrors != nil {
return
}
@@ -719,7 +719,7 @@
ctx.SetAllowMissingDependencies(true)
})).RunTestWithBp(t, bp)
- gen := result.ModuleForTests("gen", "").Output("out")
+ gen := result.ModuleForTests(t, "gen", "").Output("out")
if gen.Rule != android.ErrorRule {
t.Errorf("Expected missing dependency error rule for gen, got %q", gen.Rule.String())
}
@@ -750,15 +750,15 @@
android.AssertPathsRelativeToTopEquals(t,
"genrule.tag with output",
[]string{"out/soong/.intermediates/gen/gen/foo"},
- result.ModuleForTests("gen_foo", "").Module().(*useSource).srcs)
+ result.ModuleForTests(t, "gen_foo", "").Module().(*useSource).srcs)
android.AssertPathsRelativeToTopEquals(t,
"genrule.tag with output in subdir",
[]string{"out/soong/.intermediates/gen/gen/sub/bar"},
- result.ModuleForTests("gen_bar", "").Module().(*useSource).srcs)
+ result.ModuleForTests(t, "gen_bar", "").Module().(*useSource).srcs)
android.AssertPathsRelativeToTopEquals(t,
"genrule.tag with all",
[]string{"out/soong/.intermediates/gen/gen/foo", "out/soong/.intermediates/gen/gen/sub/bar"},
- result.ModuleForTests("gen_all", "").Module().(*useSource).srcs)
+ result.ModuleForTests(t, "gen_all", "").Module().(*useSource).srcs)
}
func TestGenruleInterface(t *testing.T) {
diff --git a/golang/golang.go b/golang/golang.go
index d33f5e0..9e0744a 100644
--- a/golang/golang.go
+++ b/golang/golang.go
@@ -97,17 +97,16 @@
outputFile := android.PathForArbitraryOutput(ctx, android.Rel(ctx, ctx.Config().OutDir(), g.IntermediateFile())).WithoutRel()
g.outputFile = outputFile
- // Don't create install rules for modules used by bootstrap, the install command line will differ from
- // what was used during bootstrap, which will cause ninja to rebuild the module on the next run,
- // triggering reanalysis.
- if !usedByBootstrap(ctx.ModuleName()) {
- installPath := ctx.InstallFile(android.PathForModuleInstall(ctx, "bin"), ctx.ModuleName(), outputFile)
+ installPath := ctx.InstallFile(android.PathForModuleInstall(ctx, "bin"), ctx.ModuleName(), outputFile)
- // Modules in an unexported namespace have no install rule, only add modules in the exported namespaces
- // to the blueprint_tools phony rules.
- if !ctx.Config().KatiEnabled() || g.ExportedToMake() {
- ctx.Phony("blueprint_tools", installPath)
- }
+ // Modules in an unexported namespace have no install rule, only add modules in the exported namespaces
+ // to the blueprint_tools phony rules.
+ if g.ExportedToMake() && !usedByBootstrap(ctx.ModuleName()) {
+ // Don't add the installed file of bootstrap tools to the deps of `blueprint_tools`.
+ // The install command line will differ from what was used during bootstrap,
+ // which will cause ninja to rebuild the module on the next run,
+ // triggering reanalysis.
+ ctx.Phony("blueprint_tools", installPath)
}
ctx.SetOutputFiles(android.Paths{outputFile}, "")
diff --git a/golang/golang_test.go b/golang/golang_test.go
index d555d14..89a8761 100644
--- a/golang/golang_test.go
+++ b/golang/golang_test.go
@@ -45,7 +45,7 @@
}),
).RunTestWithBp(t, bp)
- bin := result.ModuleForTests("gobin", result.Config.BuildOSTarget.String())
+ bin := result.ModuleForTests(t, "gobin", result.Config.BuildOSTarget.String())
expected := "^out/host/" + result.Config.PrebuiltOS() + "/bin/go/gobin/?[^/]*/obj/gobin$"
actual := android.PathsRelativeToTop(bin.OutputFiles(result.TestContext, t, ""))
diff --git a/java/Android.bp b/java/Android.bp
index 885e682..911af83 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -51,6 +51,7 @@
"gen.go",
"generated_java_library.go",
"genrule.go",
+ "genrule_combiner.go",
"hiddenapi.go",
"hiddenapi_modular.go",
"hiddenapi_monolithic.go",
@@ -95,6 +96,7 @@
"droiddoc_test.go",
"droidstubs_test.go",
"fuzz_test.go",
+ "genrule_combiner_test.go",
"genrule_test.go",
"generated_java_library_test.go",
"hiddenapi_singleton_test.go",
diff --git a/java/aar.go b/java/aar.go
index 7c63a29..976e4fc 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -217,7 +217,7 @@
}
func (a *aapt) useResourceProcessorBusyBox(ctx android.BaseModuleContext) bool {
- return BoolDefault(a.aaptProperties.Use_resource_processor, ctx.Config().UseResourceProcessorByDefault()) &&
+ return BoolDefault(a.aaptProperties.Use_resource_processor, true) &&
// TODO(b/331641946): remove this when ResourceProcessorBusyBox supports generating shared libraries.
!slices.Contains(a.aaptProperties.Aaptflags, "--shared-lib") &&
// Use the legacy resource processor in kythe builds.
@@ -939,6 +939,12 @@
return staticResourcesNodes, sharedResourcesNodes, staticRRODirs, staticManifests, sharedLibs, flags
}
+type AndroidLibraryInfo struct {
+ // Empty for now
+}
+
+var AndroidLibraryInfoProvider = blueprint.NewProvider[AndroidLibraryInfo]()
+
type AndroidLibrary struct {
Library
aapt
@@ -1034,7 +1040,7 @@
}
prebuiltJniPackages := android.Paths{}
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
}
@@ -1057,6 +1063,8 @@
}
a.setOutputFiles(ctx)
+
+ buildComplianceMetadata(ctx)
}
func (a *AndroidLibrary) setOutputFiles(ctx android.ModuleContext) {
@@ -1449,7 +1457,7 @@
var transitiveStaticLibsImplementationJars []depset.DepSet[android.Path]
var transitiveStaticLibsResourceJars []depset.DepSet[android.Path]
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
tag := ctx.OtherModuleDependencyTag(module)
switch tag {
@@ -1471,12 +1479,7 @@
completeStaticLibsResourceJars := depset.New(depset.PREORDER, nil, transitiveStaticLibsResourceJars)
var implementationJarFile android.Path
- var combineJars android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- combineJars = completeStaticLibsImplementationJars.ToList()
- } else {
- combineJars = append(android.Paths{classpathFile}, staticJars...)
- }
+ combineJars := completeStaticLibsImplementationJars.ToList()
if len(combineJars) > 1 {
implementationJarOutputPath := android.PathForModuleOut(ctx, "combined", jarName)
@@ -1487,12 +1490,8 @@
}
var resourceJarFile android.Path
- var resourceJars android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- resourceJars = completeStaticLibsResourceJars.ToList()
- } else {
- resourceJars = staticResourceJars
- }
+ resourceJars := completeStaticLibsResourceJars.ToList()
+
if len(resourceJars) > 1 {
combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName)
TransformJarsToJar(ctx, combinedJar, "for resources", resourceJars, android.OptionalPath{},
@@ -1503,12 +1502,8 @@
}
// merge implementation jar with resources if necessary
- var implementationAndResourcesJars android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- implementationAndResourcesJars = append(slices.Clone(resourceJars), combineJars...)
- } else {
- implementationAndResourcesJars = android.PathsIfNonNil(resourceJarFile, implementationJarFile)
- }
+ implementationAndResourcesJars := append(slices.Clone(resourceJars), combineJars...)
+
var implementationAndResourcesJar android.Path
if len(implementationAndResourcesJars) > 1 {
combinedJar := android.PathForModuleOut(ctx, "withres", jarName)
@@ -1523,12 +1518,7 @@
// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
a.implementationAndResourcesJarFile = implementationAndResourcesJar.WithoutRel()
- var headerJars android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- headerJars = completeStaticLibsHeaderJars.ToList()
- } else {
- headerJars = append(android.Paths{classpathFile}, staticHeaderJars...)
- }
+ headerJars := completeStaticLibsHeaderJars.ToList()
if len(headerJars) > 1 {
headerJarFile := android.PathForModuleOut(ctx, "turbine-combined", jarName)
TransformJarsToJar(ctx, headerJarFile, "combine header jars", headerJars, android.OptionalPath{}, false, nil, nil)
@@ -1537,12 +1527,7 @@
a.headerJarFile = headerJars[0]
}
- if ctx.Config().UseTransitiveJarsInClasspath() {
- ctx.CheckbuildFile(classpathFile)
- } else {
- ctx.CheckbuildFile(a.headerJarFile)
- ctx.CheckbuildFile(a.implementationJarFile)
- }
+ ctx.CheckbuildFile(classpathFile)
javaInfo := &JavaInfo{
HeaderJars: android.PathsIfNonNil(a.headerJarFile),
@@ -1586,10 +1571,10 @@
JniPackages: a.jniPackages,
})
- android.SetProvider(ctx, AndroidLibraryInfoProvider, AndroidLibraryInfo{})
-
ctx.SetOutputFiles([]android.Path{a.implementationAndResourcesJarFile}, "")
ctx.SetOutputFiles([]android.Path{a.aarPath}, ".aar")
+
+ buildComplianceMetadata(ctx)
}
func (a *AARImport) HeaderJars() android.Paths {
@@ -1617,14 +1602,21 @@
var _ android.ApexModule = (*AARImport)(nil)
// Implements android.ApexModule
-func (a *AARImport) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
- return a.depIsInSameApex(tag)
+func (m *AARImport) GetDepInSameApexChecker() android.DepInSameApexChecker {
+ return AARImportDepInSameApexChecker{}
+}
+
+type AARImportDepInSameApexChecker struct {
+ android.BaseDepInSameApexChecker
+}
+
+func (m AARImportDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
+ return depIsInSameApex(tag)
}
// Implements android.ApexModule
-func (a *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
- sdkVersion android.ApiLevel) error {
- return nil
+func (a *AARImport) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
+ return android.MinApiLevel
}
var _ android.PrebuiltInterface = (*AARImport)(nil)
diff --git a/java/aar_test.go b/java/aar_test.go
index aa4f0af..088ad6c 100644
--- a/java/aar_test.go
+++ b/java/aar_test.go
@@ -21,6 +21,7 @@
)
func TestAarImportProducesJniPackages(t *testing.T) {
+ t.Parallel()
ctx := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, `
@@ -50,8 +51,9 @@
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
appMod := ctx.Module(tc.name, "android_common")
- appTestMod := ctx.ModuleForTests(tc.name, "android_common")
+ appTestMod := ctx.ModuleForTests(t, tc.name, "android_common")
info, ok := android.OtherModuleProvider(ctx, appMod, JniPackageProvider)
if !ok {
@@ -84,6 +86,7 @@
}
func TestLibraryFlagsPackages(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
).RunTestWithBp(t, `
@@ -114,7 +117,7 @@
}
`)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
// android_library module depends on aconfig_declarations listed in flags_packages
android.AssertBoolEquals(t, "foo expected to depend on bar", true,
@@ -133,6 +136,7 @@
}
func TestAndroidLibraryOutputFilesRel(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, `
@@ -155,9 +159,9 @@
}
`)
- foo := result.ModuleForTests("foo", "android_common")
- bar := result.ModuleForTests("bar", "android_common")
- baz := result.ModuleForTests("baz", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
+ bar := result.ModuleForTests(t, "bar", "android_common")
+ baz := result.ModuleForTests(t, "baz", "android_common")
fooOutputPaths := foo.OutputFiles(result.TestContext, t, "")
barOutputPaths := bar.OutputFiles(result.TestContext, t, "")
diff --git a/java/android_manifest_test.go b/java/android_manifest_test.go
index 7c91884..ce227b9 100644
--- a/java/android_manifest_test.go
+++ b/java/android_manifest_test.go
@@ -21,6 +21,7 @@
)
func TestManifestMerger(t *testing.T) {
+ t.Parallel()
bp := `
android_app {
name: "app",
@@ -80,7 +81,7 @@
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, bp)
- manifestMergerRule := result.ModuleForTests("app", "android_common").Rule("manifestMerger")
+ manifestMergerRule := result.ModuleForTests(t, "app", "android_common").Rule("manifestMerger")
android.AssertPathRelativeToTopEquals(t, "main manifest",
"out/soong/.intermediates/app/android_common/manifest_fixer/AndroidManifest.xml",
manifestMergerRule.Input)
@@ -100,6 +101,7 @@
}
func TestManifestValuesApplicationIdSetsPackageName(t *testing.T) {
+ t.Parallel()
bp := `
android_test {
name: "test",
@@ -127,7 +129,7 @@
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, bp)
- manifestMergerRule := result.ModuleForTests("test", "android_common").Rule("manifestMerger")
+ manifestMergerRule := result.ModuleForTests(t, "test", "android_common").Rule("manifestMerger")
android.AssertStringMatches(t,
"manifest merger args",
manifestMergerRule.Args["args"],
diff --git a/java/androidmk.go b/java/androidmk.go
index 039e847..c9de7e6 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -23,13 +23,12 @@
"github.com/google/blueprint/proptools"
)
-func (library *Library) AndroidMkEntriesHostDex() android.AndroidMkEntries {
- hostDexNeeded := Bool(library.deviceProperties.Hostdex) && !library.Host()
- if library.hideApexVariantFromMake {
- hostDexNeeded = false
- }
+func (library *Library) hostDexNeeded() bool {
+ return Bool(library.deviceProperties.Hostdex) && !library.Host() && !library.hideApexVariantFromMake
+}
- if hostDexNeeded {
+func (library *Library) AndroidMkEntriesHostDex() android.AndroidMkEntries {
+ if library.hostDexNeeded() {
var output android.Path
if library.dexJarFile.IsSet() {
output = library.dexJarFile.Path()
@@ -71,11 +70,7 @@
if library.hideApexVariantFromMake {
// For a java library built for an APEX, we don't need a Make module for itself. Otherwise, it
// will conflict with the platform variant because they have the same module name in the
- // makefile. However, we need to add its dexpreopt outputs as sub-modules, if it is preopted.
- dexpreoptEntries := library.dexpreopter.AndroidMkEntriesForApex()
- if len(dexpreoptEntries) > 0 {
- entriesList = append(entriesList, dexpreoptEntries...)
- }
+ // makefile.
entriesList = append(entriesList, android.AndroidMkEntries{Disabled: true})
} else if !library.ApexModuleBase.AvailableFor(android.AvailableToPlatform) {
// Platform variant. If not available for the platform, we don't need Make module.
@@ -125,6 +120,14 @@
}
},
},
+ ExtraFooters: []android.AndroidMkExtraFootersFunc{
+ func(w io.Writer, name, prefix, moduleDir string) {
+ if library.apiXmlFile != nil {
+ fmt.Fprintf(w, "$(call declare-1p-target,%s,)\n", library.apiXmlFile.String())
+ fmt.Fprintf(w, "$(eval $(call copy-one-file,%s,$(TARGET_OUT_COMMON_INTERMEDIATES)/%s))\n", library.apiXmlFile.String(), library.apiXmlFile.Base())
+ }
+ },
+ },
})
}
@@ -555,73 +558,11 @@
},
ExtraFooters: []android.AndroidMkExtraFootersFunc{
func(w io.Writer, name, prefix, moduleDir string) {
- if dstubs.apiFile != nil {
- fmt.Fprintf(w, ".PHONY: %s %s.txt\n", dstubs.Name(), dstubs.Name())
- fmt.Fprintf(w, "%s %s.txt: %s\n", dstubs.Name(), dstubs.Name(), dstubs.apiFile)
- }
- if dstubs.removedApiFile != nil {
- fmt.Fprintf(w, ".PHONY: %s %s.txt\n", dstubs.Name(), dstubs.Name())
- fmt.Fprintf(w, "%s %s.txt: %s\n", dstubs.Name(), dstubs.Name(), dstubs.removedApiFile)
- }
- if dstubs.checkCurrentApiTimestamp != nil {
- fmt.Fprintln(w, ".PHONY:", dstubs.Name()+"-check-current-api")
- fmt.Fprintln(w, dstubs.Name()+"-check-current-api:",
- dstubs.checkCurrentApiTimestamp.String())
-
- fmt.Fprintln(w, ".PHONY: checkapi")
- fmt.Fprintln(w, "checkapi:",
- dstubs.checkCurrentApiTimestamp.String())
-
- fmt.Fprintln(w, ".PHONY: droidcore")
- fmt.Fprintln(w, "droidcore: checkapi")
- }
- if dstubs.updateCurrentApiTimestamp != nil {
- fmt.Fprintln(w, ".PHONY:", dstubs.Name()+"-update-current-api")
- fmt.Fprintln(w, dstubs.Name()+"-update-current-api:",
- dstubs.updateCurrentApiTimestamp.String())
-
- fmt.Fprintln(w, ".PHONY: update-api")
- fmt.Fprintln(w, "update-api:",
- dstubs.updateCurrentApiTimestamp.String())
- }
- if dstubs.checkLastReleasedApiTimestamp != nil {
- fmt.Fprintln(w, ".PHONY:", dstubs.Name()+"-check-last-released-api")
- fmt.Fprintln(w, dstubs.Name()+"-check-last-released-api:",
- dstubs.checkLastReleasedApiTimestamp.String())
-
- fmt.Fprintln(w, ".PHONY: checkapi")
- fmt.Fprintln(w, "checkapi:",
- dstubs.checkLastReleasedApiTimestamp.String())
-
- fmt.Fprintln(w, ".PHONY: droidcore")
- fmt.Fprintln(w, "droidcore: checkapi")
- }
if dstubs.apiLintTimestamp != nil {
- fmt.Fprintln(w, ".PHONY:", dstubs.Name()+"-api-lint")
- fmt.Fprintln(w, dstubs.Name()+"-api-lint:",
- dstubs.apiLintTimestamp.String())
-
- fmt.Fprintln(w, ".PHONY: checkapi")
- fmt.Fprintln(w, "checkapi:",
- dstubs.Name()+"-api-lint")
-
- fmt.Fprintln(w, ".PHONY: droidcore")
- fmt.Fprintln(w, "droidcore: checkapi")
-
if dstubs.apiLintReport != nil {
- fmt.Fprintf(w, "$(call dist-for-goals,%s,%s:%s)\n", dstubs.Name()+"-api-lint",
- dstubs.apiLintReport.String(), "apilint/"+dstubs.Name()+"-lint-report.txt")
fmt.Fprintf(w, "$(call declare-0p-target,%s)\n", dstubs.apiLintReport.String())
}
}
- if dstubs.checkNullabilityWarningsTimestamp != nil {
- fmt.Fprintln(w, ".PHONY:", dstubs.Name()+"-check-nullability-warnings")
- fmt.Fprintln(w, dstubs.Name()+"-check-nullability-warnings:",
- dstubs.checkNullabilityWarningsTimestamp.String())
-
- fmt.Fprintln(w, ".PHONY:", "droidcore")
- fmt.Fprintln(w, "droidcore: ", dstubs.Name()+"-check-nullability-warnings")
- }
},
},
}}
diff --git a/java/androidmk_test.go b/java/androidmk_test.go
index 1d98b18..b4b13b1 100644
--- a/java/androidmk_test.go
+++ b/java/androidmk_test.go
@@ -23,6 +23,7 @@
)
func TestRequired(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -31,7 +32,7 @@
}
`)
- mod := ctx.ModuleForTests("foo", "android_common").Module()
+ mod := ctx.ModuleForTests(t, "foo", "android_common").Module()
entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
expected := []string{"libfoo"}
@@ -42,6 +43,7 @@
}
func TestHostdex(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -50,7 +52,7 @@
}
`)
- mod := ctx.ModuleForTests("foo", "android_common").Module()
+ mod := ctx.ModuleForTests(t, "foo", "android_common").Module()
entriesList := android.AndroidMkEntriesForTest(t, ctx, mod)
if len(entriesList) != 2 {
t.Errorf("two entries are expected, but got %d", len(entriesList))
@@ -72,6 +74,7 @@
}
func TestHostdexRequired(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -81,7 +84,7 @@
}
`)
- mod := ctx.ModuleForTests("foo", "android_common").Module()
+ mod := ctx.ModuleForTests(t, "foo", "android_common").Module()
entriesList := android.AndroidMkEntriesForTest(t, ctx, mod)
if len(entriesList) != 2 {
t.Errorf("two entries are expected, but got %d", len(entriesList))
@@ -103,6 +106,7 @@
}
func TestHostdexSpecificRequired(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -116,7 +120,7 @@
}
`)
- mod := ctx.ModuleForTests("foo", "android_common").Module()
+ mod := ctx.ModuleForTests(t, "foo", "android_common").Module()
entriesList := android.AndroidMkEntriesForTest(t, ctx, mod)
if len(entriesList) != 2 {
t.Errorf("two entries are expected, but got %d", len(entriesList))
@@ -136,6 +140,7 @@
}
func TestJavaSdkLibrary_RequireXmlPermissionFile(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -153,7 +158,7 @@
`)
// Verify the existence of internal modules
- result.ModuleForTests("foo-shared_library.xml", "android_common")
+ result.ModuleForTests(t, "foo-shared_library.xml", "android_common")
testCases := []struct {
moduleName string
@@ -163,7 +168,7 @@
{"foo-no_shared_library", []string{"foo-no_shared_library.impl"}},
}
for _, tc := range testCases {
- mod := result.ModuleForTests(tc.moduleName, "android_common").Module()
+ mod := result.ModuleForTests(t, tc.moduleName, "android_common").Module()
entries := android.AndroidMkEntriesForTest(t, result.TestContext, mod)[0]
actual := entries.EntryMap["LOCAL_REQUIRED_MODULES"]
if !reflect.DeepEqual(tc.expected, actual) {
@@ -173,6 +178,7 @@
}
func TestImportSoongDexJar(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
java_import {
name: "my-java-import",
@@ -191,6 +197,7 @@
}
func TestAndroidTestHelperApp_LocalDisableTestConfig(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_test_helper_app {
name: "foo",
@@ -198,7 +205,7 @@
}
`)
- mod := ctx.ModuleForTests("foo", "android_common").Module()
+ mod := ctx.ModuleForTests(t, "foo", "android_common").Module()
entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
expected := []string{"true"}
@@ -209,6 +216,7 @@
}
func TestGetOverriddenPackages(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(
t, `
android_app {
@@ -246,7 +254,7 @@
}
for _, expected := range expectedVariants {
- mod := ctx.ModuleForTests(expected.name, expected.variantName).Module()
+ mod := ctx.ModuleForTests(t, expected.name, expected.variantName).Module()
entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
actual := entries.EntryMap["LOCAL_OVERRIDES_PACKAGES"]
@@ -255,6 +263,7 @@
}
func TestJniAsRequiredDeps(t *testing.T) {
+ t.Parallel()
ctx := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
cc.PrepareForTestWithCcDefaultModules,
@@ -295,7 +304,7 @@
}
for _, tc := range testcases {
- mod := ctx.ModuleForTests(tc.name, "android_common").Module()
+ mod := ctx.ModuleForTests(t, tc.name, "android_common").Module()
entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, mod)[0]
required := entries.EntryMap["LOCAL_REQUIRED_MODULES"]
android.AssertDeepEquals(t, "unexpected required deps", tc.expected, required)
diff --git a/java/app.go b/java/app.go
index 31c338f..17548e7 100644
--- a/java/app.go
+++ b/java/app.go
@@ -52,12 +52,6 @@
var FlagsPackagesProvider = blueprint.NewProvider[FlagsPackages]()
-type AndroidLibraryInfo struct {
- // Empty for now
-}
-
-var AndroidLibraryInfoProvider = blueprint.NewProvider[AndroidLibraryInfo]()
-
func RegisterAppBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("android_app", AndroidAppFactory)
ctx.RegisterModuleType("android_test", AndroidTestFactory)
@@ -76,6 +70,18 @@
// EmbeddedJNILibs is the list of paths to JNI libraries that were embedded in the APK.
EmbeddedJNILibs android.Paths
+
+ MergedManifestFile android.Path
+
+ Prebuilt bool
+ AppSet bool
+ Privileged bool
+ OutputFile android.Path
+ InstallApkName string
+ JacocoReportClassesFile android.Path
+ Certificate Certificate
+ PrivAppAllowlist android.OptionalPath
+ OverriddenManifestPackageName *string
}
var AppInfoProvider = blueprint.NewProvider[*AppInfo]()
@@ -405,10 +411,20 @@
android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
TestOnly: true,
})
- android.SetProvider(ctx, AppInfoProvider, &AppInfo{
+ appInfo := &AppInfo{
Updatable: Bool(a.appProperties.Updatable),
TestHelperApp: true,
- })
+ }
+ setCommonAppInfo(appInfo, a)
+ android.SetProvider(ctx, AppInfoProvider, appInfo)
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
+ if len(a.appTestHelperAppProperties.Test_suites) > 0 {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, a.appTestHelperAppProperties.Test_suites...)
+ } else {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
+ }
}
func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -424,15 +440,28 @@
embeddedJniLibs = append(embeddedJniLibs, jni.path)
}
}
- android.SetProvider(ctx, AppInfoProvider, &AppInfo{
- Updatable: Bool(a.appProperties.Updatable),
- TestHelperApp: false,
- EmbeddedJNILibs: embeddedJniLibs,
- })
-
- android.SetProvider(ctx, AndroidLibraryInfoProvider, AndroidLibraryInfo{})
+ overriddenName := a.OverriddenManifestPackageName()
+ appInfo := &AppInfo{
+ Updatable: Bool(a.appProperties.Updatable),
+ TestHelperApp: false,
+ EmbeddedJNILibs: embeddedJniLibs,
+ MergedManifestFile: a.mergedManifest,
+ OverriddenManifestPackageName: &overriddenName,
+ }
+ setCommonAppInfo(appInfo, a)
+ android.SetProvider(ctx, AppInfoProvider, appInfo)
a.requiredModuleNames = a.getRequiredModuleNames(ctx)
+
+ if a.dexer.proguardDictionary.Valid() {
+ android.SetProvider(ctx, ProguardProvider, ProguardInfo{
+ ModuleName: ctx.ModuleName(),
+ Class: "APPS",
+ ProguardDictionary: a.dexer.proguardDictionary.Path(),
+ ProguardUsageZip: a.dexer.proguardUsageZip.Path(),
+ ClassesJar: a.implementationAndResourcesJar,
+ })
+ }
}
func (a *AndroidApp) getRequiredModuleNames(ctx android.ModuleContext) []string {
@@ -509,10 +538,14 @@
// The domain of cc.sdk_version is "current" and <number>
// We can rely on android.SdkSpec to convert it to <number> so that "current" is
// handled properly regardless of sdk finalization.
- jniSdkVersion, err := android.SdkSpecFrom(ctx, commonInfo.MinSdkVersion).EffectiveVersion(ctx)
+ ver := ""
+ if !commonInfo.MinSdkVersion.IsPlatform {
+ ver = commonInfo.MinSdkVersion.ApiLevel.String()
+ }
+ jniSdkVersion, err := android.SdkSpecFrom(ctx, ver).EffectiveVersion(ctx)
if err != nil || minSdkVersion.LessThan(jniSdkVersion) {
ctx.OtherModuleErrorf(m, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
- commonInfo.MinSdkVersion, minSdkVersion, ctx.ModuleName())
+ ver, minSdkVersion, ctx.ModuleName())
return
}
@@ -681,7 +714,7 @@
func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
var staticLibProguardFlagFiles android.Paths
- ctx.VisitDirectDeps(func(m android.Module) {
+ ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.UnconditionallyExportedProguardFlags.ToList()...)
if ctx.OtherModuleDependencyTag(m) == staticLibTag {
@@ -715,7 +748,7 @@
return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
}
-func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path) {
+func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path, *JavaInfo) {
a.dexpreopter.installPath = a.installPath(ctx)
a.dexpreopter.isApp = true
if a.dexProperties.Uncompress_dex == nil {
@@ -761,12 +794,8 @@
packageResources = binaryResources
}
}
- if javaInfo != nil {
- setExtraJavaInfo(ctx, a, javaInfo)
- android.SetProvider(ctx, JavaInfoProvider, javaInfo)
- }
- return a.dexJarFile.PathOrNil(), packageResources
+ return a.dexJarFile.PathOrNil(), packageResources, javaInfo
}
func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
@@ -973,7 +1002,7 @@
a.linter.resources = a.aapt.resourceFiles
a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
- dexJarFile, packageResources := a.dexBuildActions(ctx)
+ dexJarFile, packageResources, javaInfo := a.dexBuildActions(ctx)
// No need to check the SDK version of the JNI deps unless we embed them
checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)
@@ -1089,7 +1118,23 @@
},
)
+ if javaInfo != nil {
+ javaInfo.OutputFile = a.outputFile
+ setExtraJavaInfo(ctx, a, javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+ }
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Class = []string{"APPS"}
+ if !a.embeddedJniLibs {
+ for _, jniLib := range a.jniLibs {
+ moduleInfoJSON.ExtraRequired = append(moduleInfoJSON.ExtraRequired, jniLib.name)
+ }
+ }
+
a.setOutputFiles(ctx)
+
+ buildComplianceMetadata(ctx)
}
func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) {
@@ -1121,29 +1166,35 @@
app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
}
jniLib, prebuiltJniPackages := collectJniDeps(ctx, shouldCollectRecursiveNativeDeps,
- checkNativeSdkVersion, func(parent, child android.Module) bool {
+ checkNativeSdkVersion, func(parent, child android.ModuleProxy) bool {
apkInApex := ctx.Module().(android.ApexModule).NotInPlatform()
- childLinkable, _ := child.(cc.LinkableInterface)
- parentLinkable, _ := parent.(cc.LinkableInterface)
- useStubsOfDep := childLinkable.IsStubs()
- if apkInApex && parentLinkable != nil {
+ childLinkable, _ := android.OtherModuleProvider(ctx, child, cc.LinkableInfoProvider)
+ parentIsLinkable := false
+ if ctx.EqualModules(ctx.Module(), parent) {
+ parentLinkable, _ := ctx.Module().(cc.LinkableInterface)
+ parentIsLinkable = parentLinkable != nil
+ } else {
+ _, parentIsLinkable = android.OtherModuleProvider(ctx, parent, cc.LinkableInfoProvider)
+ }
+ useStubsOfDep := childLinkable.IsStubs
+ if apkInApex && parentIsLinkable {
// APK-in-APEX
// If the parent is a linkable interface, use stubs if the dependency edge crosses an apex boundary.
- useStubsOfDep = useStubsOfDep || (childLinkable.HasStubsVariants() && cc.ShouldUseStubForApex(ctx, parent, child))
+ useStubsOfDep = useStubsOfDep || (childLinkable.HasStubsVariants && cc.ShouldUseStubForApex(ctx, parent, child))
}
- return !childLinkable.IsNdk(ctx.Config()) && !useStubsOfDep
+ return !childLinkable.IsNdk && !useStubsOfDep
})
var certificates []Certificate
var directImplementationDeps android.Paths
var transitiveImplementationDeps []depset.DepSet[android.Path]
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
if tag == certificateTag {
- if dep, ok := module.(*AndroidAppCertificate); ok {
+ if dep, ok := android.OtherModuleProvider(ctx, module, AndroidAppCertificateInfoProvider); ok {
certificates = append(certificates, dep.Certificate)
} else {
ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
@@ -1167,22 +1218,25 @@
func collectJniDeps(ctx android.ModuleContext,
shouldCollectRecursiveNativeDeps bool,
checkNativeSdkVersion bool,
- filter func(parent, child android.Module) bool) ([]jniLib, android.Paths) {
+ filter func(parent, child android.ModuleProxy) bool) ([]jniLib, android.Paths) {
var jniLibs []jniLib
var prebuiltJniPackages android.Paths
seenModulePaths := make(map[string]bool)
- ctx.WalkDeps(func(module android.Module, parent android.Module) bool {
+ ctx.WalkDepsProxy(func(module, parent android.ModuleProxy) bool {
+ if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled {
+ return false
+ }
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
- if dep, ok := module.(cc.LinkableInterface); ok {
+ if dep, ok := android.OtherModuleProvider(ctx, module, cc.LinkableInfoProvider); ok {
if filter != nil && !filter(parent, module) {
return false
}
- lib := dep.OutputFile()
+ lib := dep.OutputFile
if lib.Valid() {
path := lib.Path()
if seenModulePaths[path.String()] {
@@ -1190,7 +1244,8 @@
}
seenModulePaths[path.String()] = true
- if checkNativeSdkVersion && dep.SdkVersion() == "" {
+ commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey)
+ if checkNativeSdkVersion && commonInfo.SdkVersion == "" {
ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
otherName)
}
@@ -1198,11 +1253,11 @@
jniLibs = append(jniLibs, jniLib{
name: ctx.OtherModuleName(module),
path: path,
- target: module.Target(),
- coverageFile: dep.CoverageOutputFile(),
- unstrippedFile: dep.UnstrippedOutputFile(),
- partition: dep.Partition(),
- installPaths: android.OtherModuleProviderOrDefault(ctx, dep, android.InstallFilesProvider).InstallFiles,
+ target: commonInfo.Target,
+ coverageFile: dep.CoverageOutputFile,
+ unstrippedFile: dep.UnstrippedOutputFile,
+ partition: dep.Partition,
+ installPaths: android.OtherModuleProviderOrDefault(ctx, module, android.InstallFilesProvider).InstallFiles,
})
} else if ctx.Config().AllowMissingDependencies() {
ctx.AddMissingDependencies([]string{otherName})
@@ -1231,7 +1286,7 @@
// TODO(ccross): Should this use android.DepIsInSameApex? Right now it is applying the android app
// heuristics to every transitive dependency, when it should probably be using the heuristics of the
// immediate parent.
- isExternal := !a.OutgoingDepIsInSameApex(ctx.OtherModuleDependencyTag(child))
+ isExternal := !a.GetDepInSameApexChecker().OutgoingDepIsInSameApex(ctx.OtherModuleDependencyTag(child))
if am, ok := child.(android.ApexModule); ok {
if !do(ctx, parent, am, isExternal) {
return false
@@ -1252,7 +1307,7 @@
// Skip dependencies that are only available to APEXes; they are developed with updatability
// in mind and don't need manual approval.
- if to.(android.ApexModule).NotAvailableForPlatform() {
+ if android.OtherModuleProviderOrDefault(ctx, to, android.CommonModuleInfoKey).NotAvailableForPlatform {
return true
}
@@ -1262,18 +1317,9 @@
depsInfo[depName] = info
} else {
toMinSdkVersion := "(no version)"
- if m, ok := to.(interface {
- MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
- }); ok {
- if v := m.MinSdkVersion(ctx); !v.IsNone() {
- toMinSdkVersion = v.String()
- }
- } else if m, ok := to.(interface{ MinSdkVersion() string }); ok {
- // TODO(b/175678607) eliminate the use of MinSdkVersion returning
- // string
- if v := m.MinSdkVersion(); v != "" {
- toMinSdkVersion = v
- }
+ if info, ok := android.OtherModuleProvider(ctx, to, android.CommonModuleInfoKey); ok &&
+ !info.MinSdkVersion.IsPlatform && info.MinSdkVersion.ApiLevel != nil {
+ toMinSdkVersion = info.MinSdkVersion.ApiLevel.String()
}
depsInfo[depName] = android.ApexModuleDepInfo{
To: depName,
@@ -1308,11 +1354,19 @@
return a.overridableAppProperties.Certificate.GetOrDefault(ctx, "")
}
-func (a *AndroidApp) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
+func (m *AndroidApp) GetDepInSameApexChecker() android.DepInSameApexChecker {
+ return AppDepInSameApexChecker{}
+}
+
+type AppDepInSameApexChecker struct {
+ android.BaseDepInSameApexChecker
+}
+
+func (m AppDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
if IsJniDepTag(tag) {
return true
}
- return a.Library.OutgoingDepIsInSameApex(tag)
+ return depIsInSameApex(tag)
}
func (a *AndroidApp) Privileged() bool {
@@ -1592,6 +1646,24 @@
a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_common_data)...)
a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_data)...)
a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_prefer32_data)...)
+ a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Host_common_data)...)
+
+ // Install test deps
+ if !ctx.Config().KatiEnabled() {
+ pathInTestCases := android.PathForModuleInstall(ctx, ctx.Module().Name())
+ if a.testConfig != nil {
+ ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".config", a.testConfig)
+ }
+ dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml")
+ if dynamicConfig.Valid() {
+ ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".dynamic", dynamicConfig.Path())
+ }
+ testDeps := append(a.data, a.extraTestConfigs...)
+ for _, data := range android.SortedUniquePaths(testDeps) {
+ dataPath := android.DataPath{SrcPath: data}
+ ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath})
+ }
+ }
android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
TestcaseRelDataFiles: testcaseRel(a.data),
@@ -1610,6 +1682,22 @@
TopLevelTarget: true,
})
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
+ if a.testConfig != nil {
+ moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, a.testConfig.String())
+ }
+ moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, a.extraTestConfigs.Strings()...)
+ if len(a.testProperties.Test_suites) > 0 {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, a.testProperties.Test_suites...)
+ } else {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
+ }
+
+ if _, ok := testConfig.(android.WritablePath); ok {
+ moduleInfoJSON.AutoTestConfig = []string{"true"}
+ }
+ moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, a.testProperties.Test_mainline_modules...)
}
func testcaseRel(paths android.Paths) []string {
@@ -1783,6 +1871,12 @@
Certificate *string
}
+type AndroidAppCertificateInfo struct {
+ Certificate Certificate
+}
+
+var AndroidAppCertificateInfoProvider = blueprint.NewProvider[AndroidAppCertificateInfo]()
+
// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
// the signing key.
func AndroidAppCertificateFactory() android.Module {
@@ -1798,6 +1892,10 @@
Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
Key: android.PathForModuleSrc(ctx, cert+".pk8"),
}
+
+ android.SetProvider(ctx, AndroidAppCertificateInfoProvider, AndroidAppCertificateInfo{
+ Certificate: c.Certificate,
+ })
}
type OverrideAndroidApp struct {
@@ -1952,7 +2050,7 @@
return clcMap
}
- ctx.VisitDirectDeps(func(m android.Module) {
+ ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
if !isUsesLibTag {
return
@@ -1960,31 +2058,35 @@
dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
+ javaInfo, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider)
+ if !ok {
+ return
+ }
// Skip stub libraries. A dependency on the implementation library has been added earlier,
// so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
// from implementation libraries by their name, which is different as it has a suffix.
- if comp, ok := m.(SdkLibraryComponentDependency); ok {
- if impl := comp.OptionalSdkLibraryImplementation(); impl != nil && *impl != dep {
+ if comp := javaInfo.SdkLibraryComponentDependencyInfo; comp != nil {
+ if impl := comp.OptionalSdkLibraryImplementation; impl != nil && *impl != dep {
return
}
}
- if lib, ok := m.(UsesLibraryDependency); ok {
+ if lib := javaInfo.UsesLibraryDependencyInfo; lib != nil {
if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
// Skip java_sdk_library dependencies that provide stubs, but not an implementation.
// This will be restricted to optional_uses_libs
- if tag == usesLibOptTag && lib.DexJarBuildPath(ctx).PathOrNil() == nil {
+ if tag == usesLibOptTag && javaInfo.DexJarBuildPath.PathOrNil() == nil {
u.shouldDisableDexpreopt = true
return
}
}
libName := dep
- if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
- libName = *ulib.ProvidesUsesLib()
+ if ulib := javaInfo.ProvidesUsesLibInfo; ulib != nil && ulib.ProvidesUsesLib != nil {
+ libName = *ulib.ProvidesUsesLib
}
clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
- lib.DexJarBuildPath(ctx).PathOrNil(), lib.DexJarInstallPath(),
- lib.ClassLoaderContexts())
+ javaInfo.DexJarBuildPath.PathOrNil(), lib.DexJarInstallPath,
+ lib.ClassLoaderContexts)
} else if ctx.Config().AllowMissingDependencies() {
ctx.AddMissingDependencies([]string{dep})
} else {
@@ -2076,3 +2178,29 @@
classLoaderContexts *dexpreopt.ClassLoaderContextMap) {
u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file
}
+
+// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
+// the same way.
+type androidApp interface {
+ android.Module
+ Privileged() bool
+ InstallApkName() string
+ OutputFile() android.Path
+ JacocoReportClassesFile() android.Path
+ Certificate() Certificate
+ BaseModuleName() string
+ PrivAppAllowlist() android.OptionalPath
+}
+
+var _ androidApp = (*AndroidApp)(nil)
+var _ androidApp = (*AndroidAppImport)(nil)
+var _ androidApp = (*AndroidTestHelperApp)(nil)
+
+func setCommonAppInfo(appInfo *AppInfo, m androidApp) {
+ appInfo.Privileged = m.Privileged()
+ appInfo.OutputFile = m.OutputFile()
+ appInfo.InstallApkName = m.InstallApkName()
+ appInfo.JacocoReportClassesFile = m.JacocoReportClassesFile()
+ appInfo.Certificate = m.Certificate()
+ appInfo.PrivAppAllowlist = m.PrivAppAllowlist()
+}
diff --git a/java/app_import.go b/java/app_import.go
index 35a054f..37c673c 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -62,6 +62,18 @@
CommandDeps: []string{"build/soong/scripts/check_prebuilt_presigned_apk.py", "${config.Aapt2Cmd}", "${config.ZipAlign}"},
Description: "Check presigned apk",
}, "extraArgs")
+
+ extractApkRule = pctx.AndroidStaticRule("extract-apk", blueprint.RuleParams{
+ Command: "unzip -p $in $extract_apk > $out",
+ Description: "Extract specific sub apk",
+ }, "extract_apk")
+
+ gzipRule = pctx.AndroidStaticRule("gzip",
+ blueprint.RuleParams{
+ Command: "prebuilts/build-tools/path/linux-x86/gzip -9 -c $in > $out",
+ CommandDeps: []string{"prebuilts/build-tools/path/linux-x86/gzip"},
+ Description: "gzip $out",
+ })
)
func RegisterAppImportBuildComponents(ctx android.RegistrationContext) {
@@ -163,6 +175,12 @@
// In case of mainline modules, the .prebuilt_info file contains the build_id that was used
// to generate the prebuilt.
Prebuilt_info *string `android:"path"`
+
+ // Path of extracted apk which is extracted from prebuilt apk. Use this extracted to import.
+ Extract_apk *string
+
+ // Compress the output APK using gzip. Defaults to false.
+ Compress_apk proptools.Configurable[bool] `android:"arch_variant,replace_instead_of_append"`
}
func (a *AndroidAppImport) IsInstallable() bool {
@@ -287,6 +305,19 @@
})
}
+func (a *AndroidAppImport) extractSubApk(
+ ctx android.ModuleContext, inputPath android.Path, outputPath android.WritablePath) {
+ extractApkPath := *a.properties.Extract_apk
+ ctx.Build(pctx, android.BuildParams{
+ Rule: extractApkRule,
+ Input: inputPath,
+ Output: outputPath,
+ Args: map[string]string{
+ "extract_apk": extractApkPath,
+ },
+ })
+}
+
// Returns whether this module should have the dex file stored uncompressed in the APK.
func (a *AndroidAppImport) shouldUncompressDex(ctx android.ModuleContext) bool {
if ctx.Config().UnbundledBuild() || proptools.Bool(a.properties.Preprocessed) {
@@ -323,6 +354,12 @@
func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.generateAndroidBuildActions(ctx)
+
+ appInfo := &AppInfo{
+ Prebuilt: true,
+ }
+ setCommonAppInfo(appInfo, a)
+ android.SetProvider(ctx, AppInfoProvider, appInfo)
}
func (a *AndroidAppImport) InstallApkName() string {
@@ -365,10 +402,14 @@
ctx.ModuleErrorf("One and only one of certficate, presigned (implied by preprocessed), and default_dev_cert properties must be set")
}
- // TODO: LOCAL_EXTRACT_APK/LOCAL_EXTRACT_DPI_APK
// TODO: LOCAL_PACKAGE_SPLITS
srcApk := a.prebuilt.SingleSourcePath(ctx)
+ if a.properties.Extract_apk != nil {
+ extract_apk := android.PathForModuleOut(ctx, "extract-apk", ctx.ModuleName()+".apk")
+ a.extractSubApk(ctx, srcApk, extract_apk)
+ srcApk = extract_apk
+ }
// TODO: Install or embed JNI libraries
@@ -402,7 +443,9 @@
a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries(ctx)
a.dexpreopter.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
- if a.usesLibrary.shouldDisableDexpreopt {
+
+ // Disable Dexpreopt if Compress_apk is true. It follows the build/make/core/app_prebuilt_internal.mk
+ if a.usesLibrary.shouldDisableDexpreopt || a.properties.Compress_apk.GetOrDefault(ctx, false) {
a.dexpreopter.disableDexpreopt()
}
@@ -421,7 +464,13 @@
jnisUncompressed = dexUncompressed
}
- apkFilename := proptools.StringDefault(a.properties.Filename, a.BaseModuleName()+".apk")
+ defaultApkFilename := a.BaseModuleName()
+ if a.properties.Compress_apk.GetOrDefault(ctx, false) {
+ defaultApkFilename += ".apk.gz"
+ } else {
+ defaultApkFilename += ".apk"
+ }
+ apkFilename := proptools.StringDefault(a.properties.Filename, defaultApkFilename)
// TODO: Handle EXTERNAL
@@ -461,7 +510,16 @@
a.certificate = PresignedCertificate
}
- // TODO: Optionally compress the output apk.
+ if a.properties.Compress_apk.GetOrDefault(ctx, false) {
+ outputFile := android.PathForModuleOut(ctx, "compressed_apk", apkFilename)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: gzipRule,
+ Input: a.outputFile,
+ Output: outputFile,
+ Description: "Compressing " + a.outputFile.Base(),
+ })
+ a.outputFile = outputFile
+ }
if apexInfo.IsForPlatform() {
a.installPath = ctx.InstallFile(installDir, apkFilename, a.outputFile)
@@ -479,6 +537,8 @@
ctx.SetOutputFiles([]android.Path{a.outputFile}, "")
+ buildComplianceMetadata(ctx)
+
// TODO: androidmk converter jni libs
}
@@ -574,7 +634,15 @@
return Bool(a.properties.Privileged)
}
-func (a *AndroidAppImport) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
+func (m *AndroidAppImport) GetDepInSameApexChecker() android.DepInSameApexChecker {
+ return AppImportDepInSameApexChecker{}
+}
+
+type AppImportDepInSameApexChecker struct {
+ android.BaseDepInSameApexChecker
+}
+
+func (m AppImportDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
// android_app_import might have extra dependencies via uses_libs property.
// Don't track the dependency as we don't automatically add those libraries
// to the classpath. It should be explicitly added to java_libs property of APEX
@@ -592,10 +660,8 @@
var _ android.ApexModule = (*AndroidAppImport)(nil)
// Implements android.ApexModule
-func (j *AndroidAppImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
- sdkVersion android.ApiLevel) error {
- // Do not check for prebuilts against the min_sdk_version of enclosing APEX
- return nil
+func (m *AndroidAppImport) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
+ return android.MinApiLevel
}
func createVariantGroupType(variants []string, variantGroupName string) reflect.Type {
@@ -718,9 +784,27 @@
func (a *AndroidTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.generateAndroidBuildActions(ctx)
+ a.updateModuleInfoJSON(ctx)
+
a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
}
+func (a *AndroidTestImport) updateModuleInfoJSON(ctx android.ModuleContext) {
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Class = []string{"APPS"}
+ moduleInfoJSON.CompatibilitySuites = []string{"null-suite"}
+ if len(a.testProperties.Test_suites) > 0 {
+ moduleInfoJSON.CompatibilitySuites = a.testProperties.Test_suites
+ }
+ moduleInfoJSON.SystemSharedLibs = []string{"none"}
+ moduleInfoJSON.Tags = []string{"tests"}
+ moduleInfoJSON.RegisterNameOverride = a.BaseModuleName()
+ testConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml")
+ if testConfig.Valid() {
+ moduleInfoJSON.TestConfig = []string{testConfig.String()}
+ }
+}
+
func (a *AndroidTestImport) InstallInTestcases() bool {
return true
}
diff --git a/java/app_import_test.go b/java/app_import_test.go
index 70c487c..2600767 100644
--- a/java/app_import_test.go
+++ b/java/app_import_test.go
@@ -26,6 +26,7 @@
)
func TestAndroidAppImport(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app_import {
name: "foo",
@@ -37,7 +38,47 @@
}
`)
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
+
+ // Check dexpreopt outputs.
+ if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil ||
+ variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule == nil {
+ t.Errorf("can't find dexpreopt outputs")
+ }
+
+ // Check cert signing flag.
+ signedApk := variant.Output("signed/foo.apk")
+ signingFlag := signedApk.Args["certificates"]
+ expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8"
+ if expected != signingFlag {
+ t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
+ }
+ rule := variant.Rule("genProvenanceMetaData")
+ android.AssertStringEquals(t, "Invalid input", "prebuilts/apk/app.apk", rule.Inputs[0].String())
+ android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String())
+ android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"])
+ android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", rule.Args["install_path"])
+}
+
+func TestAndroidAppImportWithDefaults(t *testing.T) {
+ t.Parallel()
+ ctx, _ := testJava(t, `
+ android_app_import {
+ name: "foo",
+ defaults: ["foo_defaults"],
+ }
+
+ java_defaults {
+ name: "foo_defaults",
+ apk: "prebuilts/apk/app.apk",
+ certificate: "platform",
+ dex_preopt: {
+ enabled: true,
+ },
+ }
+ `)
+
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
// Check dexpreopt outputs.
if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil ||
@@ -60,6 +101,7 @@
}
func TestAndroidAppImport_NoDexPreopt(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app_import {
name: "foo",
@@ -71,7 +113,7 @@
}
`)
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
// Check dexpreopt outputs. They shouldn't exist.
if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule != nil ||
@@ -87,6 +129,7 @@
}
func TestAndroidAppImport_Presigned(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app_import {
name: "foo",
@@ -98,7 +141,7 @@
}
`)
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
// Check dexpreopt outputs.
if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil ||
@@ -121,6 +164,7 @@
}
func TestAndroidAppImport_SigningLineage(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app_import {
name: "foo",
@@ -137,7 +181,7 @@
}
`)
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
signedApk := variant.Output("signed/foo.apk")
// Check certificates
@@ -164,6 +208,7 @@
}
func TestAndroidAppImport_SigningLineageFilegroup(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app_import {
name: "foo",
@@ -178,7 +223,7 @@
}
`)
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
signedApk := variant.Output("signed/foo.apk")
// Check cert signing lineage flag.
@@ -196,6 +241,7 @@
}
func TestAndroidAppImport_DefaultDevCert(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app_import {
name: "foo",
@@ -207,7 +253,7 @@
}
`)
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
// Check dexpreopt outputs.
if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil ||
@@ -231,6 +277,7 @@
}
func TestAndroidAppImport_DpiVariants(t *testing.T) {
+ t.Parallel()
bp := `
android_app_import {
name: "foo",
@@ -302,7 +349,7 @@
}),
).RunTestWithBp(t, bp)
- variant := result.ModuleForTests("foo", "android_common")
+ variant := result.ModuleForTests(t, "foo", "android_common")
input := variant.Output("jnis-uncompressed/foo.apk").Input.String()
if strings.HasSuffix(input, test.expected) {
t.Errorf("wrong src apk, expected: %q got: %q", test.expected, input)
@@ -317,6 +364,7 @@
}
func TestAndroidAppImport_Filename(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app_import {
name: "foo",
@@ -325,10 +373,25 @@
}
android_app_import {
+ name: "foo_compressed",
+ apk: "prebuilts/apk/app.apk",
+ presigned: true,
+ compress_apk: true,
+ }
+
+ android_app_import {
name: "bar",
apk: "prebuilts/apk/app.apk",
presigned: true,
- filename: "bar_sample.apk"
+ filename: "bar_sample.apk",
+ }
+
+ android_app_import {
+ name: "compressed_bar",
+ apk: "prebuilts/apk/app.apk",
+ presigned: true,
+ filename: "bar_sample.apk",
+ compress_apk: true,
}
`)
@@ -347,16 +410,30 @@
expectedMetaDataPath: "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto",
},
{
+ name: "foo_compressed",
+ expected: "foo_compressed.apk.gz",
+ onDevice: "/system/app/foo_compressed/foo_compressed.apk.gz",
+ expectedArtifactPath: "prebuilts/apk/app.apk",
+ expectedMetaDataPath: "out/soong/.intermediates/provenance_metadata/foo_compressed/provenance_metadata.textproto",
+ },
+ {
name: "bar",
expected: "bar_sample.apk",
onDevice: "/system/app/bar/bar_sample.apk",
expectedArtifactPath: "prebuilts/apk/app.apk",
expectedMetaDataPath: "out/soong/.intermediates/provenance_metadata/bar/provenance_metadata.textproto",
},
+ {
+ name: "compressed_bar",
+ expected: "bar_sample.apk",
+ onDevice: "/system/app/compressed_bar/bar_sample.apk",
+ expectedArtifactPath: "prebuilts/apk/app.apk",
+ expectedMetaDataPath: "out/soong/.intermediates/provenance_metadata/compressed_bar/provenance_metadata.textproto",
+ },
}
for _, test := range testCases {
- variant := ctx.ModuleForTests(test.name, "android_common")
+ variant := ctx.ModuleForTests(t, test.name, "android_common")
if variant.MaybeOutput(test.expected).Rule == nil {
t.Errorf("can't find output named %q - all outputs: %v", test.expected, variant.AllOutputs())
}
@@ -380,6 +457,7 @@
}
func TestAndroidAppImport_ArchVariants(t *testing.T) {
+ t.Parallel()
// The test config's target arch is ARM64.
testCases := []struct {
name string
@@ -505,9 +583,10 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, test.bp)
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
if test.expected == "" {
if variant.Module().Enabled(android.PanickingConfigAndErrorContext(ctx)) {
t.Error("module should have been disabled, but wasn't")
@@ -530,6 +609,7 @@
}
func TestAndroidAppImport_SoongConfigVariables(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
bp string
@@ -572,6 +652,7 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
ctx := android.GroupFixturePreparers(
prepareForJavaTest,
android.PrepareForTestWithSoongConfigModuleBuildComponents,
@@ -584,7 +665,7 @@
}),
).RunTestWithBp(t, test.bp).TestContext
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
if test.expected == "" {
if variant.Module().Enabled(android.PanickingConfigAndErrorContext(ctx)) {
t.Error("module should have been disabled, but wasn't")
@@ -607,6 +688,7 @@
}
func TestAndroidAppImport_overridesDisabledAndroidApp(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app {
name: "foo",
@@ -622,7 +704,7 @@
}
`)
- variant := ctx.ModuleForTests("prebuilt_foo", "android_common")
+ variant := ctx.ModuleForTests(t, "prebuilt_foo", "android_common")
a := variant.Module().(*AndroidAppImport)
// The prebuilt module should still be enabled and active even if the source-based counterpart
// is disabled.
@@ -635,6 +717,7 @@
}
func TestAndroidAppImport_relativeInstallPath(t *testing.T) {
+ t.Parallel()
bp := `
android_app_import {
name: "no_relative_install_path",
@@ -679,13 +762,34 @@
},
}
for _, testCase := range testCases {
- ctx, _ := testJava(t, bp)
- mod := ctx.ModuleForTests(testCase.name, "android_common").Module().(*AndroidAppImport)
- android.AssertPathRelativeToTopEquals(t, testCase.errorMessage, testCase.expectedInstallPath, mod.installPath)
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+ ctx, _ := testJava(t, bp)
+ mod := ctx.ModuleForTests(t, testCase.name, "android_common").Module().(*AndroidAppImport)
+ android.AssertPathRelativeToTopEquals(t, testCase.errorMessage, testCase.expectedInstallPath, mod.installPath)
+ })
}
}
+func TestAndroidAppImport_ExtractApk(t *testing.T) {
+ t.Parallel()
+ ctx, _ := testJava(t, `
+ android_app_import {
+ name: "foo",
+ apk: "prebuilts/apk/app.apk",
+ certificate: "platform",
+ extract_apk: "extract_path/sub_app.apk"
+ }
+ `)
+
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
+ extractRuleArgs := variant.Output("extract-apk/foo.apk").BuildParams.Args
+ if extractRuleArgs["extract_apk"] != "extract_path/sub_app.apk" {
+ t.Errorf("Unexpected extract apk args: %s", extractRuleArgs["extract_apk"])
+ }
+}
func TestAndroidTestImport(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_test_import {
name: "foo",
@@ -697,7 +801,7 @@
}
`)
- test := ctx.ModuleForTests("foo", "android_common").Module().(*AndroidTestImport)
+ test := ctx.ModuleForTests(t, "foo", "android_common").Module().(*AndroidTestImport)
// Check android mks.
entries := android.AndroidMkEntriesForTest(t, ctx, test)[0]
@@ -714,6 +818,7 @@
}
func TestAndroidTestImport_NoJinUncompressForPresigned(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_test_import {
name: "foo",
@@ -734,13 +839,13 @@
}
`)
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
jniRule := variant.Output("jnis-uncompressed/foo.apk").BuildParams.Rule.String()
if jniRule == android.Cp.String() {
t.Errorf("Unexpected JNI uncompress rule command: %s", jniRule)
}
- variant = ctx.ModuleForTests("foo_presigned", "android_common")
+ variant = ctx.ModuleForTests(t, "foo_presigned", "android_common")
jniRule = variant.Output("jnis-uncompressed/foo_presigned.apk").BuildParams.Rule.String()
if jniRule != android.Cp.String() {
t.Errorf("Unexpected JNI uncompress rule: %s", jniRule)
@@ -751,6 +856,7 @@
}
func TestAndroidTestImport_Preprocessed(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_test_import {
name: "foo",
@@ -761,7 +867,7 @@
`)
apkName := "foo.apk"
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
jniRule := variant.Output("jnis-uncompressed/" + apkName).BuildParams.Rule.String()
if jniRule != android.Cp.String() {
t.Errorf("Unexpected JNI uncompress rule: %s", jniRule)
@@ -777,9 +883,11 @@
}
func TestAndroidAppImport_Preprocessed(t *testing.T) {
+ t.Parallel()
for _, dontUncompressPrivAppDexs := range []bool{false, true} {
name := fmt.Sprintf("dontUncompressPrivAppDexs:%t", dontUncompressPrivAppDexs)
t.Run(name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
@@ -804,7 +912,7 @@
// non-privileged app
apkName := "foo.apk"
- variant := result.ModuleForTests("foo", "android_common")
+ variant := result.ModuleForTests(t, "foo", "android_common")
outputBuildParams := variant.Output(apkName).BuildParams
if outputBuildParams.Rule.String() != android.Cp.String() {
t.Errorf("Unexpected prebuilt android_app_import rule: %s", outputBuildParams.Rule.String())
@@ -826,7 +934,7 @@
// privileged app
apkName = "bar.apk"
- variant = result.ModuleForTests("bar", "android_common")
+ variant = result.ModuleForTests(t, "bar", "android_common")
outputBuildParams = variant.Output(apkName).BuildParams
if outputBuildParams.Rule.String() != android.Cp.String() {
t.Errorf("Unexpected prebuilt android_app_import rule: %s", outputBuildParams.Rule.String())
@@ -854,6 +962,7 @@
}
func TestAndroidTestImport_UncompressDex(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
bp string
@@ -894,7 +1003,7 @@
}),
).RunTestWithBp(t, bp)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
actual := foo.MaybeRule("uncompress-dex").Rule != nil
expect := !unbundled
@@ -917,6 +1026,7 @@
name := fmt.Sprintf("%s,unbundled:%t,dontUncompressPrivAppDexs:%t",
tt.name, unbundled, dontUncompressPrivAppDexs)
t.Run(name, func(t *testing.T) {
+ t.Parallel()
test(t, tt.bp, unbundled, dontUncompressPrivAppDexs)
})
}
@@ -925,6 +1035,7 @@
}
func TestAppImportMissingCertificateAllowMissingDependencies(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.PrepareForTestWithAllowMissingDependencies,
@@ -936,7 +1047,7 @@
certificate: ":missing_certificate",
}`)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
fooApk := foo.Output("signed/foo.apk")
if fooApk.Rule != android.ErrorRule {
t.Fatalf("expected ErrorRule for foo.apk, got %s", fooApk.Rule.String())
diff --git a/java/app_set.go b/java/app_set.go
index 7997570..2e9d314 100644
--- a/java/app_set.go
+++ b/java/app_set.go
@@ -192,6 +192,11 @@
},
)
+ android.SetProvider(ctx, AppInfoProvider, &AppInfo{
+ AppSet: true,
+ Privileged: as.Privileged(),
+ OutputFile: as.OutputFile(),
+ })
}
func (as *AndroidAppSet) InstallBypassMake() bool { return true }
diff --git a/java/app_set_test.go b/java/app_set_test.go
index c02b359..9b4c44b 100644
--- a/java/app_set_test.go
+++ b/java/app_set_test.go
@@ -24,13 +24,14 @@
)
func TestAndroidAppSet(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
android_app_set {
name: "foo",
set: "prebuilts/apks/app.apks",
prerelease: true,
}`)
- module := result.ModuleForTests("foo", "android_common")
+ module := result.ModuleForTests(t, "foo", "android_common")
const packedSplitApks = "foo.zip"
params := module.Output(packedSplitApks)
if params.Rule == nil {
@@ -65,6 +66,7 @@
}
func TestAndroidAppSet_Variants(t *testing.T) {
+ t.Parallel()
bp := `
android_app_set {
name: "foo",
@@ -113,24 +115,24 @@
}
for _, test := range testCases {
- ctx := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.AAPTPrebuiltDPI = test.aaptPrebuiltDPI
- variables.Platform_sdk_version = &test.sdkVersion
- }),
- android.FixtureModifyConfig(func(config android.Config) {
- config.Targets[android.Android] = test.targets
- }),
- ).RunTestWithBp(t, bp)
+ t.Run(test.name, func(t *testing.T) {
+ ctx := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.AAPTPrebuiltDPI = test.aaptPrebuiltDPI
+ variables.Platform_sdk_version = &test.sdkVersion
+ }),
+ android.FixtureModifyConfig(func(config android.Config) {
+ config.Targets[android.Android] = test.targets
+ }),
+ ).RunTestWithBp(t, bp)
- module := ctx.ModuleForTests("foo", "android_common")
- const packedSplitApks = "foo.zip"
- params := module.Output(packedSplitApks)
- for k, v := range test.expected {
- t.Run(test.name, func(t *testing.T) {
+ module := ctx.ModuleForTests(t, "foo", "android_common")
+ const packedSplitApks = "foo.zip"
+ params := module.Output(packedSplitApks)
+ for k, v := range test.expected {
android.AssertStringEquals(t, fmt.Sprintf("arg value for `%s`", k), v, params.Args[k])
- })
- }
+ }
+ })
}
}
diff --git a/java/app_test.go b/java/app_test.go
index bde801b..5f5f04d 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -42,6 +42,7 @@
}
func TestApp(t *testing.T) {
+ t.Parallel()
resourceFiles := []string{
"res/layout/layout.xml",
"res/values/strings.xml",
@@ -56,6 +57,7 @@
for _, moduleType := range []string{"android_app", "android_library"} {
t.Run(moduleType, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
android.FixtureModifyMockFS(func(fs android.MockFS) {
@@ -70,14 +72,14 @@
}
`)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
var expectedLinkImplicits []string
manifestFixer := foo.Output("manifest_fixer/AndroidManifest.xml")
expectedLinkImplicits = append(expectedLinkImplicits, manifestFixer.Output.String())
- frameworkRes := result.ModuleForTests("framework-res", "android_common")
+ frameworkRes := result.ModuleForTests(t, "framework-res", "android_common")
expectedLinkImplicits = append(expectedLinkImplicits,
frameworkRes.Output("package-res.apk").Output.String())
@@ -94,13 +96,14 @@
expectedLinkImplicits = append(expectedLinkImplicits, list.Output.String())
// Check that the link rule uses
- res := result.ModuleForTests("foo", "android_common").Output("package-res.apk")
+ res := result.ModuleForTests(t, "foo", "android_common").Output("package-res.apk")
android.AssertDeepEquals(t, "aapt2 link implicits", expectedLinkImplicits, res.Implicits.Strings())
})
}
}
func TestAppSplits(t *testing.T) {
+ t.Parallel()
ctx := testApp(t, `
android_app {
name: "foo",
@@ -109,7 +112,7 @@
sdk_version: "current"
}`)
- foo := ctx.ModuleForTests("foo", "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
expectedOutputs := []string{
"out/soong/.intermediates/foo/android_common/foo.apk",
@@ -125,6 +128,7 @@
}
func TestPlatformAPIs(t *testing.T) {
+ t.Parallel()
testJava(t, `
android_app {
name: "foo",
@@ -159,6 +163,7 @@
}
func TestAndroidAppLinkType(t *testing.T) {
+ t.Parallel()
testJava(t, `
android_app {
name: "foo",
@@ -248,6 +253,7 @@
}
func TestUpdatableApps(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
bp string
@@ -359,6 +365,7 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
errorHandler := android.FixtureExpectsNoErrors
if test.expectedError != "" {
errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(test.expectedError)
@@ -373,6 +380,7 @@
}
func TestUpdatableApps_TransitiveDepsShouldSetMinSdkVersion(t *testing.T) {
+ t.Parallel()
testJavaError(t, `module "bar".*: should support min_sdk_version\(29\)`, cc.GatherRequiredDepsForTest(android.Android)+`
android_app {
name: "foo",
@@ -391,6 +399,7 @@
}
func TestUpdatableApps_JniLibsShouldShouldSupportMinSdkVersion(t *testing.T) {
+ t.Parallel()
testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
android_app {
name: "foo",
@@ -411,6 +420,7 @@
}
func TestUpdatableApps_JniLibShouldBeBuiltAgainstMinSdkVersion(t *testing.T) {
+ t.Parallel()
bp := cc.GatherRequiredDepsForTest(android.Android) + `
android_app {
name: "foo",
@@ -438,11 +448,11 @@
ctx, _ := testJavaWithFS(t, bp, fs)
- inputs := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").Description("link").Implicits
+ inputs := ctx.ModuleForTests(t, "libjni", "android_arm64_armv8-a_sdk_shared").Description("link").Implicits
var crtbeginFound, crtendFound bool
- expectedCrtBegin := ctx.ModuleForTests("crtbegin_so",
+ expectedCrtBegin := ctx.ModuleForTests(t, "crtbegin_so",
"android_arm64_armv8-a_sdk_29").Rule("noAddrSig").Output
- expectedCrtEnd := ctx.ModuleForTests("crtend_so",
+ expectedCrtEnd := ctx.ModuleForTests(t, "crtend_so",
"android_arm64_armv8-a_sdk_29").Rule("noAddrSig").Output
implicits := []string{}
for _, input := range inputs {
@@ -466,6 +476,7 @@
}
func TestUpdatableApps_ErrorIfJniLibDoesntSupportMinSdkVersion(t *testing.T) {
+ t.Parallel()
bp := cc.GatherRequiredDepsForTest(android.Android) + `
android_app {
name: "foo",
@@ -487,6 +498,7 @@
}
func TestUpdatableApps_ErrorIfDepMinSdkVersionIsHigher(t *testing.T) {
+ t.Parallel()
bp := cc.GatherRequiredDepsForTest(android.Android) + `
android_app {
name: "foo",
@@ -518,6 +530,7 @@
}
func TestUpdatableApps_ApplyDefaultUpdatableModuleVersion(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, `
@@ -529,7 +542,7 @@
updatable: true,
}
`)
- foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer")
+ foo := result.ModuleForTests(t, "com.android.foo", "android_common").Rule("manifestFixer")
android.AssertStringDoesContain(t,
"com.android.foo: expected manifest fixer to set override-placeholder-version to RELEASE_DEFAULT_UPDATABLE_MODULE_VERSION",
foo.BuildParams.Args["args"],
@@ -538,6 +551,7 @@
}
func TestUpdatableApps_ApplyOverrideApexManifestDefaultVersion(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.FixtureMergeEnv(map[string]string{
@@ -552,7 +566,7 @@
updatable: true,
}
`)
- foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer")
+ foo := result.ModuleForTests(t, "com.android.foo", "android_common").Rule("manifestFixer")
android.AssertStringDoesContain(t,
"com.android.foo: expected manifest fixer to set override-placeholder-version to 1234",
foo.BuildParams.Args["args"],
@@ -561,6 +575,7 @@
}
func TestResourceDirs(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
prop string
@@ -597,12 +612,13 @@
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
fs.AddToFixture(),
).RunTestWithBp(t, fmt.Sprintf(bp, testCase.prop))
- module := result.ModuleForTests("foo", "android_common")
+ module := result.ModuleForTests(t, "foo", "android_common")
resourceList := module.MaybeOutput("aapt2/res.list")
var resources []string
@@ -618,6 +634,7 @@
}
func TestLibraryAssets(t *testing.T) {
+ t.Parallel()
bp := `
android_app {
name: "foo",
@@ -712,7 +729,8 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
- m := ctx.ModuleForTests(test.name, "android_common")
+ t.Parallel()
+ m := ctx.ModuleForTests(t, test.name, "android_common")
// Check asset flag in aapt2 link flags
var aapt2link android.TestingBuildParams
@@ -747,6 +765,7 @@
}
func TestAppJavaResources(t *testing.T) {
+ t.Parallel()
bp := `
android_app {
name: "foo",
@@ -764,7 +783,7 @@
ctx := testApp(t, bp)
- foo := ctx.ModuleForTests("foo", "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
fooResources := foo.Output("res/foo.jar")
fooDexJar := foo.Output("dex-withres/foo.jar")
fooDexJarAligned := foo.Output("dex-withres-aligned/foo.jar")
@@ -782,7 +801,7 @@
t.Errorf("expected aligned dex jar %q in foo apk inputs %q", w, g)
}
- bar := ctx.ModuleForTests("bar", "android_common")
+ bar := ctx.ModuleForTests(t, "bar", "android_common")
barResources := bar.Output("res/bar.jar")
barApk := bar.Rule("combineApk")
@@ -792,6 +811,7 @@
}
func TestAndroidResourceProcessor(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
appUsesRP bool
@@ -867,15 +887,24 @@
},
appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"},
appClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
- "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
- "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
+ "out/soong/.intermediates/shared/android_common/turbine/shared.jar",
+ "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar",
+ "out/soong/.intermediates/direct/android_common/turbine/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/javac/app.jar",
- "out/soong/.intermediates/direct/android_common/combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
+ "out/soong/.intermediates/direct/android_common/javac/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
directResources: nil,
@@ -888,21 +917,23 @@
directImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
directSrcJars: []string{"out/soong/.intermediates/direct/android_common/gen/android/R.srcjar"},
directClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
- "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
},
directCombined: []string{
"out/soong/.intermediates/direct/android_common/javac/direct.jar",
"out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
},
transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},
transitiveOverlays: nil,
transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
transitiveSrcJars: []string{"out/soong/.intermediates/transitive/android_common/gen/android/R.srcjar"},
- transitiveClasspath: []string{"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar"},
+ transitiveClasspath: []string{"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar"},
transitiveCombined: nil,
sharedResources: nil,
@@ -916,9 +947,9 @@
},
sharedSrcJars: []string{"out/soong/.intermediates/shared/android_common/gen/android/R.srcjar"},
sharedClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
- "out/soong/.intermediates/shared_transitive_shared/android_common/turbine-combined/shared_transitive_shared.jar",
- "out/soong/.intermediates/shared_transitive_static/android_common/turbine-combined/shared_transitive_static.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
+ "out/soong/.intermediates/shared_transitive_shared/android_common/turbine/shared_transitive_shared.jar",
+ "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar",
},
sharedCombined: []string{
"out/soong/.intermediates/shared/android_common/javac/shared.jar",
@@ -965,17 +996,26 @@
},
appSrcJars: nil,
appClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
"out/soong/.intermediates/app/android_common/busybox/R.jar",
- "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
- "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
+ "out/soong/.intermediates/shared/android_common/turbine/shared.jar",
+ "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar",
+ "out/soong/.intermediates/direct/android_common/turbine/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/javac/app.jar",
"out/soong/.intermediates/app/android_common/busybox/R.jar",
- "out/soong/.intermediates/direct/android_common/combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
+ "out/soong/.intermediates/direct/android_common/javac/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
directResources: nil,
@@ -988,18 +1028,20 @@
},
directSrcJars: nil,
directClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
"out/soong/.intermediates/direct/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
- "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
},
directCombined: []string{
"out/soong/.intermediates/direct/android_common/javac/direct.jar",
"out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
},
transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},
@@ -1007,7 +1049,7 @@
transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
transitiveSrcJars: nil,
transitiveClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
"out/soong/.intermediates/transitive/android_common/busybox/R.jar",
},
transitiveCombined: nil,
@@ -1021,12 +1063,12 @@
},
sharedSrcJars: nil,
sharedClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
"out/soong/.intermediates/shared/android_common/busybox/R.jar",
"out/soong/.intermediates/shared_transitive_static/android_common/busybox/R.jar",
"out/soong/.intermediates/shared_transitive_shared/android_common/busybox/R.jar",
- "out/soong/.intermediates/shared_transitive_shared/android_common/turbine-combined/shared_transitive_shared.jar",
- "out/soong/.intermediates/shared_transitive_static/android_common/turbine-combined/shared_transitive_static.jar",
+ "out/soong/.intermediates/shared_transitive_shared/android_common/turbine/shared_transitive_shared.jar",
+ "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar",
},
sharedCombined: []string{
"out/soong/.intermediates/shared/android_common/javac/shared.jar",
@@ -1070,18 +1112,27 @@
},
appSrcJars: nil,
appClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
// R.jar has to come before direct.jar
"out/soong/.intermediates/app/android_common/busybox/R.jar",
- "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
- "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
+ "out/soong/.intermediates/shared/android_common/turbine/shared.jar",
+ "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar",
+ "out/soong/.intermediates/direct/android_common/turbine/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/javac/app.jar",
"out/soong/.intermediates/app/android_common/busybox/R.jar",
- "out/soong/.intermediates/direct/android_common/combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
+ "out/soong/.intermediates/direct/android_common/javac/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
dontVerifyDirect: true,
@@ -1113,15 +1164,24 @@
},
appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"},
appClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
- "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
- "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
+ "out/soong/.intermediates/shared/android_common/turbine/shared.jar",
+ "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar",
+ "out/soong/.intermediates/direct/android_common/turbine/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/javac/app.jar",
- "out/soong/.intermediates/direct/android_common/combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
+ "out/soong/.intermediates/direct/android_common/javac/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
directResources: nil,
@@ -1134,17 +1194,19 @@
},
directSrcJars: nil,
directClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
"out/soong/.intermediates/direct/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
- "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
},
directCombined: []string{
"out/soong/.intermediates/direct/android_common/javac/direct.jar",
"out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
},
dontVerifyTransitive: true,
@@ -1175,15 +1237,24 @@
},
appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"},
appClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
- "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
- "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
+ "out/soong/.intermediates/shared/android_common/turbine/shared.jar",
+ "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar",
+ "out/soong/.intermediates/direct/android_common/turbine/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/javac/app.jar",
- "out/soong/.intermediates/direct/android_common/combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
+ "out/soong/.intermediates/direct/android_common/javac/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
directResources: nil,
@@ -1196,14 +1267,16 @@
directImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
directSrcJars: []string{"out/soong/.intermediates/direct/android_common/gen/android/R.srcjar"},
directClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
- "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
},
directCombined: []string{
"out/soong/.intermediates/direct/android_common/javac/direct.jar",
"out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
},
transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},
@@ -1211,7 +1284,7 @@
transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
transitiveSrcJars: nil,
transitiveClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
"out/soong/.intermediates/transitive/android_common/busybox/R.jar",
},
transitiveCombined: nil,
@@ -1224,6 +1297,7 @@
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
bp := fmt.Sprintf(`
android_app {
name: "app",
@@ -1331,7 +1405,7 @@
}
getAaptInfo := func(moduleName string) (aaptInfo aaptInfo) {
- mod := result.ModuleForTests(moduleName, "android_common")
+ mod := result.ModuleForTests(t, moduleName, "android_common")
resourceListRule := mod.MaybeOutput("aapt2/res.list")
overlayListRule := mod.MaybeOutput("aapt2/overlay.list")
aaptRule := mod.Rule("aapt2Link")
@@ -1420,6 +1494,7 @@
}
func TestAndroidResourceOverlays(t *testing.T) {
+ t.Parallel()
type moduleAndVariant struct {
module string
variant string
@@ -1458,7 +1533,6 @@
"device/vendor/blah/overlay/bar/res/values/strings.xml",
},
{"lib", "android_common"}: {
- "out/soong/.intermediates/lib2/android_common/package-res.apk",
"lib/res/res/values/strings.xml",
"device/vendor/blah/overlay/lib/res/values/strings.xml",
},
@@ -1493,12 +1567,10 @@
"device/vendor/blah/overlay/bar/res/values/strings.xml",
},
{"lib", "android_common"}: {
- "out/soong/.intermediates/lib2/android_common/package-res.apk",
"lib/res/res/values/strings.xml",
"device/vendor/blah/overlay/lib/res/values/strings.xml",
},
{"lib", "android_common_rro"}: {
- "out/soong/.intermediates/lib2/android_common_rro/package-res.apk",
"lib/res/res/values/strings.xml",
},
},
@@ -1538,7 +1610,6 @@
},
{"bar", "android_common"}: {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
{"lib", "android_common"}: {
- "out/soong/.intermediates/lib2/android_common/package-res.apk",
"lib/res/res/values/strings.xml",
},
},
@@ -1616,6 +1687,7 @@
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
fs.AddToFixture(),
@@ -1647,7 +1719,7 @@
}
getResources := func(moduleName, variantName string) (resourceFiles, overlayFiles, rroDirs []string) {
- module := result.ModuleForTests(moduleName, variantName)
+ module := result.ModuleForTests(t, moduleName, variantName)
resourceList := module.MaybeOutput("aapt2/res.list")
if resourceList.Rule != nil {
resourceFiles = resourceListToFiles(module, android.PathsRelativeToTop(resourceList.Inputs))
@@ -1706,7 +1778,7 @@
}
func checkSdkVersion(t *testing.T, result *android.TestResult, expectedSdkVersion string) {
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
link := foo.Output("package-res.apk")
linkFlags := strings.Split(link.Args["flags"], " ")
min := android.IndexList("--min-sdk-version", linkFlags)
@@ -1725,6 +1797,7 @@
}
func TestAppSdkVersion(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
sdkVersion string
@@ -1792,6 +1865,7 @@
for _, moduleType := range []string{"android_app", "android_library"} {
for _, test := range testCases {
t.Run(moduleType+" "+test.name, func(t *testing.T) {
+ t.Parallel()
platformApiProp := ""
if test.platformApis {
platformApiProp = "platform_apis: true,"
@@ -1828,6 +1902,7 @@
}
func TestVendorAppSdkVersion(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
sdkVersion string
@@ -1870,6 +1945,7 @@
for _, sdkKind := range []string{"", "system_"} {
for _, test := range testCases {
t.Run(moduleType+" "+test.name, func(t *testing.T) {
+ t.Parallel()
bp := fmt.Sprintf(`%s {
name: "foo",
srcs: ["a.java"],
@@ -1901,6 +1977,7 @@
}
func TestJNIABI(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
cc_library {
name: "libjni",
@@ -1957,7 +2034,8 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
- app := ctx.ModuleForTests(test.name, "android_common")
+ t.Parallel()
+ app := ctx.ModuleForTests(t, test.name, "android_common")
jniLibZip := app.Output("jnilibs.zip")
var abis []string
args := strings.Fields(jniLibZip.Args["jarArgs"])
@@ -1975,6 +2053,7 @@
}
func TestAppSdkVersionByPartition(t *testing.T) {
+ t.Parallel()
testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", `
android_app {
name: "foo",
@@ -2019,6 +2098,7 @@
}
func TestJNIPackaging(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
cc_library {
name: "libjni",
@@ -2090,7 +2170,8 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
- app := ctx.ModuleForTests(test.name, "android_common")
+ t.Parallel()
+ app := ctx.ModuleForTests(t, test.name, "android_common")
jniLibZip := app.MaybeOutput("jnilibs.zip")
if g, w := (jniLibZip.Rule != nil), test.packaged; g != w {
t.Errorf("expected jni packaged %v, got %v", w, g)
@@ -2110,6 +2191,7 @@
}
func TestJNISDK(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
cc_library {
name: "libjni",
@@ -2171,16 +2253,17 @@
{name: "app_vendor", vendorJNI: true},
}
- platformJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_shared").
+ platformJNI := ctx.ModuleForTests(t, "libjni", "android_arm64_armv8-a_shared").
Output("libjni.so").Output.String()
- sdkJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").
+ sdkJNI := ctx.ModuleForTests(t, "libjni", "android_arm64_armv8-a_sdk_shared").
Output("libjni.so").Output.String()
- vendorJNI := ctx.ModuleForTests("libvendorjni", "android_vendor_arm64_armv8-a_shared").
+ vendorJNI := ctx.ModuleForTests(t, "libvendorjni", "android_vendor_arm64_armv8-a_shared").
Output("libvendorjni.so").Output.String()
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
- app := ctx.ModuleForTests(test.name, "android_common")
+ t.Parallel()
+ app := ctx.ModuleForTests(t, test.name, "android_common")
jniLibZip := app.MaybeOutput("jnilibs.zip")
if len(jniLibZip.Implicits) != 1 {
@@ -2205,6 +2288,7 @@
}
t.Run("jni_uses_platform_apis_error", func(t *testing.T) {
+ t.Parallel()
testJavaError(t, `jni_uses_platform_apis: can only be set for modules that set sdk_version`, `
android_test {
name: "app_platform",
@@ -2215,6 +2299,7 @@
})
t.Run("jni_uses_sdk_apis_error", func(t *testing.T) {
+ t.Parallel()
testJavaError(t, `jni_uses_sdk_apis: can only be set for modules that do not set sdk_version`, `
android_test {
name: "app_sdk",
@@ -2227,6 +2312,7 @@
}
func TestCertificates(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
bp string
@@ -2364,6 +2450,7 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
@@ -2379,7 +2466,7 @@
}),
).RunTestWithBp(t, test.bp)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
certificate := foo.Module().(*AndroidApp).certificate
android.AssertPathRelativeToTopEquals(t, "certificates key", test.expectedCertificate+".pk8", certificate.Key)
@@ -2401,6 +2488,7 @@
}
func TestRequestV4SigningFlag(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
bp string
@@ -2445,11 +2533,12 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, test.bp)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
signapk := foo.Output("foo.apk")
signFlags := signapk.Args["flags"]
@@ -2459,6 +2548,7 @@
}
func TestPackageNameOverride(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
bp string
@@ -2516,6 +2606,7 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
@@ -2525,7 +2616,7 @@
}),
).RunTestWithBp(t, test.bp)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
outSoongDir := result.Config.SoongOutDir()
@@ -2544,6 +2635,7 @@
}
func TestInstrumentationTargetOverridden(t *testing.T) {
+ t.Parallel()
bp := `
android_app {
name: "foo",
@@ -2565,7 +2657,7 @@
}),
).RunTestWithBp(t, bp)
- bar := result.ModuleForTests("bar", "android_common")
+ bar := result.ModuleForTests(t, "bar", "android_common")
res := bar.Output("package-res.apk")
aapt2Flags := res.Args["flags"]
e := "--rename-instrumentation-target-package org.dandroid.bp"
@@ -2575,6 +2667,7 @@
}
func TestOverrideAndroidApp(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(
t, `
android_app {
@@ -2722,7 +2815,7 @@
},
}
for _, expected := range expectedVariants {
- variant := result.ModuleForTests(expected.name, expected.variantName)
+ variant := result.ModuleForTests(t, expected.name, expected.variantName)
// Check the final apk name
variant.Output(expected.apkPath)
@@ -2757,6 +2850,7 @@
}
func TestOverrideAndroidAppOverrides(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(
t, `
android_app {
@@ -2806,7 +2900,7 @@
},
}
for _, expected := range expectedVariants {
- variant := ctx.ModuleForTests(expected.name, expected.variantName)
+ variant := ctx.ModuleForTests(t, expected.name, expected.variantName)
// Check if the overrides field values are correctly aggregated.
mod := variant.Module().(*AndroidApp)
@@ -2815,6 +2909,7 @@
}
func TestOverrideAndroidAppWithPrebuilt(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(
t, `
android_app {
@@ -2837,19 +2932,20 @@
`)
// An app that has an override that also has a prebuilt should not be hidden.
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
if foo.Module().IsHideFromMake() {
t.Errorf("expected foo to have HideFromMake false")
}
// An override that also has a prebuilt should be hidden.
- barOverride := result.ModuleForTests("foo", "android_common_bar")
+ barOverride := result.ModuleForTests(t, "foo", "android_common_bar")
if !barOverride.Module().IsHideFromMake() {
t.Errorf("expected bar override variant of foo to have HideFromMake true")
}
}
func TestOverrideAndroidAppStem(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app {
name: "foo",
@@ -2918,12 +3014,13 @@
apkPath: "out/target/product/test_device/system/app/baz2_stem/baz2_stem.apk",
},
} {
- variant := ctx.ModuleForTests(expected.moduleName, expected.variantName)
+ variant := ctx.ModuleForTests(t, expected.moduleName, expected.variantName)
variant.Output(expected.apkPath)
}
}
func TestOverrideAndroidAppDependency(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app {
name: "foo",
@@ -2951,15 +3048,15 @@
`)
// Verify baz, which depends on the overridden module foo, has the correct classpath javac arg.
- javac := ctx.ModuleForTests("baz", "android_common").Rule("javac")
- fooTurbine := "out/soong/.intermediates/foo/android_common/turbine-combined/foo.jar"
+ javac := ctx.ModuleForTests(t, "baz", "android_common").Rule("javac")
+ fooTurbine := "out/soong/.intermediates/foo/android_common/turbine/foo.jar"
if !strings.Contains(javac.Args["classpath"], fooTurbine) {
t.Errorf("baz classpath %v does not contain %q", javac.Args["classpath"], fooTurbine)
}
// Verify qux, which depends on the overriding module bar, has the correct classpath javac arg.
- javac = ctx.ModuleForTests("qux", "android_common").Rule("javac")
- barTurbine := "out/soong/.intermediates/foo/android_common_bar/turbine-combined/foo.jar"
+ javac = ctx.ModuleForTests(t, "qux", "android_common").Rule("javac")
+ barTurbine := "out/soong/.intermediates/foo/android_common_bar/turbine/foo.jar"
if !strings.Contains(javac.Args["classpath"], barTurbine) {
t.Errorf("qux classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
}
@@ -3022,7 +3119,7 @@
},
}
for _, expected := range expectedVariants {
- variant := ctx.ModuleForTests("foo_test", expected.variantName)
+ variant := ctx.ModuleForTests(t, "foo_test", expected.variantName)
// Check the final apk name
variant.Output("out" + expected.apkPath)
@@ -3036,7 +3133,7 @@
// Check if javac classpath has the correct jar file path. This checks instrumentation_for overrides.
javac := variant.Rule("javac")
- turbine := filepath.Join("out", "soong", ".intermediates", "foo", expected.targetVariant, "turbine-combined", "foo.jar")
+ turbine := filepath.Join("out", "soong", ".intermediates", "foo", expected.targetVariant, "turbine", "foo.jar")
if !strings.Contains(javac.Args["classpath"], turbine) {
t.Errorf("classpath %q does not contain %q", javac.Args["classpath"], turbine)
}
@@ -3113,7 +3210,7 @@
}
for _, test := range testCases {
- variant := ctx.ModuleForTests(test.moduleName, test.variantName)
+ variant := ctx.ModuleForTests(t, test.moduleName, test.variantName)
params := variant.MaybeOutput("test_config_fixer/AndroidTest.xml")
if len(test.expectedFlags) > 0 {
@@ -3159,6 +3256,7 @@
}
func TestStl(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
cc_library {
name: "libjni",
@@ -3201,7 +3299,8 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
- app := ctx.ModuleForTests(test.name, "android_common")
+ t.Parallel()
+ app := ctx.ModuleForTests(t, test.name, "android_common")
jniLibZip := app.Output("jnilibs.zip")
var jnis []string
args := strings.Fields(jniLibZip.Args["jarArgs"])
@@ -3378,8 +3477,8 @@
}),
).RunTestWithBp(t, bp)
- app := result.ModuleForTests("app", "android_common")
- prebuilt := result.ModuleForTests("prebuilt", "android_common")
+ app := result.ModuleForTests(t, "app", "android_common")
+ prebuilt := result.ModuleForTests(t, "prebuilt", "android_common")
// Test that implicit dependencies on java_sdk_library instances are passed to the manifest.
// These also include explicit `uses_libs`/`optional_uses_libs` entries, as they may be
@@ -3431,6 +3530,7 @@
}
func TestDexpreoptBcp(t *testing.T) {
+ t.Parallel()
bp := `
java_sdk_library {
name: "foo",
@@ -3473,6 +3573,7 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -3482,7 +3583,7 @@
dexpreopt.FixtureSetPreoptWithUpdatableBcp(test.with),
).RunTestWithBp(t, bp)
- app := result.ModuleForTests("app", "android_common")
+ app := result.ModuleForTests(t, "app", "android_common")
cmd := app.Rule("dexpreopt").RuleParams.Command
bcp := " -Xbootclasspath-locations:" + test.expect + " " // space at the end matters
android.AssertStringDoesContain(t, "dexpreopt app bcp", cmd, bcp)
@@ -3491,6 +3592,7 @@
}
func TestCodelessApp(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
bp string
@@ -3555,9 +3657,10 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
ctx := testApp(t, test.bp)
- foo := ctx.ModuleForTests("foo", "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
if strings.Contains(manifestFixerArgs, "--has-no-code") != test.noCode {
t.Errorf("unexpected manifest_fixer args: %q", manifestFixerArgs)
@@ -3567,6 +3670,7 @@
}
func TestUncompressDex(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
bp string
@@ -3654,7 +3758,7 @@
}),
).RunTestWithBp(t, bp)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
dex := foo.Rule("r8")
uncompressedInDexJar := strings.Contains(dex.Args["zipFlags"], "-L 0")
aligned := foo.MaybeRule("zipalign").Rule != nil
@@ -3666,10 +3770,13 @@
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
+ t.Parallel()
t.Run("platform", func(t *testing.T) {
+ t.Parallel()
test(t, tt.bp, tt.uncompressedPlatform, false)
})
t.Run("unbundled", func(t *testing.T) {
+ t.Parallel()
test(t, tt.bp, tt.uncompressedUnbundled, true)
})
})
@@ -3691,6 +3798,7 @@
}
func TestExportedProguardFlagFiles(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app {
name: "foo",
@@ -3736,7 +3844,7 @@
`)
- m := ctx.ModuleForTests("foo", "android_common")
+ m := ctx.ModuleForTests(t, "foo", "android_common")
r8 := m.Rule("java.r8")
implicits := r8.Implicits.RelativeToTop().Strings()
android.AssertStringListContains(t, "r8 implicits", implicits, "lib1proguard.cfg")
@@ -3752,6 +3860,7 @@
}
func TestTargetSdkVersionManifestFixer(t *testing.T) {
+ t.Parallel()
platform_sdk_codename := "Tiramisu"
platform_sdk_version := 33
testCases := []struct {
@@ -3804,43 +3913,47 @@
},
}
for _, testCase := range testCases {
- targetSdkVersionTemplate := ""
- if testCase.targetSdkVersionInBp != "" {
- targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, testCase.targetSdkVersionInBp)
- }
- bp := fmt.Sprintf(`
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+ targetSdkVersionTemplate := ""
+ if testCase.targetSdkVersionInBp != "" {
+ targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, testCase.targetSdkVersionInBp)
+ }
+ bp := fmt.Sprintf(`
android_app {
name: "foo",
sdk_version: "current",
%s
}
`, targetSdkVersionTemplate)
- fixture := android.GroupFixturePreparers(
- prepareForJavaTest,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- if testCase.platformSdkFinal {
- variables.Platform_sdk_final = proptools.BoolPtr(true)
- }
- // explicitly set platform_sdk_codename to make the test deterministic
- variables.Platform_sdk_codename = &platform_sdk_codename
- variables.Platform_sdk_version = &platform_sdk_version
- variables.Platform_version_active_codenames = []string{platform_sdk_codename}
- // create a non-empty list if unbundledBuild==true
- if testCase.unbundledBuild {
- variables.Unbundled_build_apps = []string{"apex_a", "apex_b"}
- }
- }),
- )
+ fixture := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ if testCase.platformSdkFinal {
+ variables.Platform_sdk_final = proptools.BoolPtr(true)
+ }
+ // explicitly set platform_sdk_codename to make the test deterministic
+ variables.Platform_sdk_codename = &platform_sdk_codename
+ variables.Platform_sdk_version = &platform_sdk_version
+ variables.Platform_version_active_codenames = []string{platform_sdk_codename}
+ // create a non-empty list if unbundledBuild==true
+ if testCase.unbundledBuild {
+ variables.Unbundled_build_apps = []string{"apex_a", "apex_b"}
+ }
+ }),
+ )
- result := fixture.RunTestWithBp(t, bp)
- foo := result.ModuleForTests("foo", "android_common")
+ result := fixture.RunTestWithBp(t, bp)
+ foo := result.ModuleForTests(t, "foo", "android_common")
- manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
- android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
+ manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
+ android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
+ })
}
}
func TestDefaultAppTargetSdkVersionForUpdatableModules(t *testing.T) {
+ t.Parallel()
platform_sdk_codename := "Tiramisu"
platform_sdk_version := 33
testCases := []struct {
@@ -3896,11 +4009,13 @@
},
}
for _, testCase := range testCases {
- targetSdkVersionTemplate := ""
- if testCase.targetSdkVersionInBp != nil {
- targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, *testCase.targetSdkVersionInBp)
- }
- bp := fmt.Sprintf(`
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+ targetSdkVersionTemplate := ""
+ if testCase.targetSdkVersionInBp != nil {
+ targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, *testCase.targetSdkVersionInBp)
+ }
+ bp := fmt.Sprintf(`
android_app {
name: "foo",
sdk_version: "current",
@@ -3911,30 +4026,32 @@
}
`, targetSdkVersionTemplate, testCase.updatable, testCase.updatable) // enforce default target sdk version if app is updatable
- fixture := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.PrepareForTestWithAllowMissingDependencies,
- android.PrepareForTestWithAndroidMk,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- // explicitly set following platform variables to make the test deterministic
- variables.Platform_sdk_final = &testCase.platform_sdk_final
- variables.Platform_sdk_version = &platform_sdk_version
- variables.Platform_sdk_codename = &platform_sdk_codename
- variables.Platform_version_active_codenames = []string{platform_sdk_codename}
- variables.Unbundled_build = proptools.BoolPtr(true)
- variables.Unbundled_build_apps = []string{"sampleModule"}
- }),
- )
+ fixture := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.PrepareForTestWithAllowMissingDependencies,
+ android.PrepareForTestWithAndroidMk,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ // explicitly set following platform variables to make the test deterministic
+ variables.Platform_sdk_final = &testCase.platform_sdk_final
+ variables.Platform_sdk_version = &platform_sdk_version
+ variables.Platform_sdk_codename = &platform_sdk_codename
+ variables.Platform_version_active_codenames = []string{platform_sdk_codename}
+ variables.Unbundled_build = proptools.BoolPtr(true)
+ variables.Unbundled_build_apps = []string{"sampleModule"}
+ }),
+ )
- result := fixture.RunTestWithBp(t, bp)
- foo := result.ModuleForTests("foo", "android_common")
+ result := fixture.RunTestWithBp(t, bp)
+ foo := result.ModuleForTests(t, "foo", "android_common")
- manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
- android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+*testCase.targetSdkVersionExpected)
+ manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
+ android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+*testCase.targetSdkVersionExpected)
+ })
}
}
func TestEnforceDefaultAppTargetSdkVersionFlag(t *testing.T) {
+ t.Parallel()
platform_sdk_codename := "Tiramisu"
platform_sdk_version := 33
testCases := []struct {
@@ -3979,8 +4096,10 @@
},
}
for _, testCase := range testCases {
- errExpected := testCase.expectedError != ""
- bp := fmt.Sprintf(`
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+ errExpected := testCase.expectedError != ""
+ bp := fmt.Sprintf(`
android_app {
name: "foo",
enforce_default_target_sdk_version: %t,
@@ -3991,35 +4110,37 @@
}
`, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp, testCase.updatable)
- fixture := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.PrepareForTestWithAllowMissingDependencies,
- android.PrepareForTestWithAndroidMk,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- // explicitly set following platform variables to make the test deterministic
- variables.Platform_sdk_final = &testCase.platform_sdk_final
- variables.Platform_sdk_version = &platform_sdk_version
- variables.Platform_sdk_codename = &platform_sdk_codename
- variables.Unbundled_build = proptools.BoolPtr(true)
- variables.Unbundled_build_apps = []string{"sampleModule"}
- }),
- )
+ fixture := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.PrepareForTestWithAllowMissingDependencies,
+ android.PrepareForTestWithAndroidMk,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ // explicitly set following platform variables to make the test deterministic
+ variables.Platform_sdk_final = &testCase.platform_sdk_final
+ variables.Platform_sdk_version = &platform_sdk_version
+ variables.Platform_sdk_codename = &platform_sdk_codename
+ variables.Unbundled_build = proptools.BoolPtr(true)
+ variables.Unbundled_build_apps = []string{"sampleModule"}
+ }),
+ )
- errorHandler := android.FixtureExpectsNoErrors
- if errExpected {
- errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
- }
- result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)
+ errorHandler := android.FixtureExpectsNoErrors
+ if errExpected {
+ errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
+ }
+ result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)
- if !errExpected {
- foo := result.ModuleForTests("foo", "android_common")
- manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
- android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
- }
+ if !errExpected {
+ foo := result.ModuleForTests(t, "foo", "android_common")
+ manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
+ android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
+ }
+ })
}
}
func TestEnforceDefaultAppTargetSdkVersionFlagForTests(t *testing.T) {
+ t.Parallel()
platform_sdk_codename := "Tiramisu"
platform_sdk_version := 33
testCases := []struct {
@@ -4052,8 +4173,10 @@
},
}
for _, testCase := range testCases {
- errExpected := testCase.expectedError != ""
- bp := fmt.Sprintf(`
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+ errExpected := testCase.expectedError != ""
+ bp := fmt.Sprintf(`
android_test {
name: "foo",
enforce_default_target_sdk_version: %t,
@@ -4062,35 +4185,37 @@
}
`, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp)
- fixture := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.PrepareForTestWithAllowMissingDependencies,
- android.PrepareForTestWithAndroidMk,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- // explicitly set following platform variables to make the test deterministic
- variables.Platform_sdk_final = &testCase.platform_sdk_final
- variables.Platform_sdk_version = &platform_sdk_version
- variables.Platform_sdk_codename = &platform_sdk_codename
- variables.Unbundled_build = proptools.BoolPtr(true)
- variables.Unbundled_build_apps = []string{"sampleModule"}
- }),
- )
+ fixture := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.PrepareForTestWithAllowMissingDependencies,
+ android.PrepareForTestWithAndroidMk,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ // explicitly set following platform variables to make the test deterministic
+ variables.Platform_sdk_final = &testCase.platform_sdk_final
+ variables.Platform_sdk_version = &platform_sdk_version
+ variables.Platform_sdk_codename = &platform_sdk_codename
+ variables.Unbundled_build = proptools.BoolPtr(true)
+ variables.Unbundled_build_apps = []string{"sampleModule"}
+ }),
+ )
- errorHandler := android.FixtureExpectsNoErrors
- if errExpected {
- errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
- }
- result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)
+ errorHandler := android.FixtureExpectsNoErrors
+ if errExpected {
+ errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
+ }
+ result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)
- if !errExpected {
- foo := result.ModuleForTests("foo", "android_common")
- manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
- android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
- }
+ if !errExpected {
+ foo := result.ModuleForTests(t, "foo", "android_common")
+ manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
+ android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
+ }
+ })
}
}
func TestAppMissingCertificateAllowMissingDependencies(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.PrepareForTestWithAllowMissingDependencies,
@@ -4111,7 +4236,7 @@
sdk_version: "current",
}`)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
fooApk := foo.Output("foo.apk")
if fooApk.Rule != android.ErrorRule {
t.Fatalf("expected ErrorRule for foo.apk, got %s", fooApk.Rule.String())
@@ -4120,6 +4245,7 @@
}
func TestAppIncludesJniPackages(t *testing.T) {
+ t.Parallel()
ctx := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, `
@@ -4182,7 +4308,8 @@
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
- app := ctx.ModuleForTests(tc.name, "android_common")
+ t.Parallel()
+ app := ctx.ModuleForTests(t, tc.name, "android_common")
outputFile := "jnilibs.zip"
jniOutputLibZip := app.MaybeOutput(outputFile)
@@ -4206,6 +4333,7 @@
}
func TestTargetSdkVersionMtsTests(t *testing.T) {
+ t.Parallel()
platformSdkCodename := "Tiramisu"
android_test := "android_test"
android_test_helper_app := "android_test_helper_app"
@@ -4261,14 +4389,18 @@
}),
)
for _, testCase := range testCases {
- result := fixture.RunTestWithBp(t, fmt.Sprintf(bpTemplate, testCase.moduleType, testCase.targetSdkVersionInBp, testCase.testSuites))
- mytest := result.ModuleForTests("mytest", "android_common")
- manifestFixerArgs := mytest.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
- android.AssertStringDoesContain(t, testCase.desc, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
+ t.Run(testCase.desc, func(t *testing.T) {
+ t.Parallel()
+ result := fixture.RunTestWithBp(t, fmt.Sprintf(bpTemplate, testCase.moduleType, testCase.targetSdkVersionInBp, testCase.testSuites))
+ mytest := result.ModuleForTests(t, "mytest", "android_common")
+ manifestFixerArgs := mytest.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
+ android.AssertStringDoesContain(t, testCase.desc, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
+ })
}
}
func TestPrivappAllowlist(t *testing.T) {
+ t.Parallel()
testJavaError(t, "privileged must be set in order to use privapp_allowlist", `
android_app {
name: "foo",
@@ -4294,8 +4426,8 @@
}
`,
)
- app := result.ModuleForTests("foo", "android_common")
- overrideApp := result.ModuleForTests("foo", "android_common_bar")
+ app := result.ModuleForTests(t, "foo", "android_common")
+ overrideApp := result.ModuleForTests(t, "foo", "android_common_bar")
// verify that privapp allowlist is created for override apps
overrideApp.Output("out/soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml")
@@ -4311,6 +4443,7 @@
}
func TestPrivappAllowlistAndroidMk(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.PrepareForTestWithAndroidMk,
@@ -4331,8 +4464,8 @@
}
`,
)
- baseApp := result.ModuleForTests("foo", "android_common")
- overrideApp := result.ModuleForTests("foo", "android_common_bar")
+ baseApp := result.ModuleForTests(t, "foo", "android_common")
+ overrideApp := result.ModuleForTests(t, "foo", "android_common_bar")
baseAndroidApp := baseApp.Module().(*AndroidApp)
baseEntries := android.AndroidMkEntriesForTest(t, result.TestContext, baseAndroidApp)[0]
@@ -4390,6 +4523,7 @@
}
func TestAppFlagsPackages(t *testing.T) {
+ t.Parallel()
ctx := android.GroupFixturePreparers(
prepareForJavaTest,
android.FixtureMergeMockFs(
@@ -4427,7 +4561,7 @@
}
`)
- foo := ctx.ModuleForTests("foo", "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
// android_app module depends on aconfig_declarations listed in flags_packages
android.AssertBoolEquals(t, "foo expected to depend on bar", true,
@@ -4454,6 +4588,7 @@
}
func TestAppFlagsPackagesPropagation(t *testing.T) {
+ t.Parallel()
ctx := testApp(t, `
aconfig_declarations {
name: "foo",
@@ -4511,7 +4646,7 @@
}
`)
- bazApp := ctx.ModuleForTests("baz_app", "android_common")
+ bazApp := ctx.ModuleForTests(t, "baz_app", "android_common")
// android_app module depends on aconfig_declarations listed in flags_packages
// and that of static libs, but not libs
@@ -4531,6 +4666,7 @@
// Test that dexpreopt is disabled if an optional_uses_libs exists, but does not provide an implementation.
func TestNoDexpreoptOptionalUsesLibDoesNotHaveImpl(t *testing.T) {
+ t.Parallel()
bp := `
java_sdk_library_import {
name: "sdklib_noimpl",
@@ -4548,7 +4684,7 @@
}
`
result := prepareForJavaTest.RunTestWithBp(t, bp)
- dexpreopt := result.ModuleForTests("app", "android_common").MaybeRule("dexpreopt").Rule
+ dexpreopt := result.ModuleForTests(t, "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)
}
@@ -4644,7 +4780,7 @@
}
return ret
}
- rule := ctx.ModuleForTests("android-test", "android_common").Rule("autogenInstrumentationTest")
+ rule := ctx.ModuleForTests(t, "android-test", "android_common").Rule("autogenInstrumentationTest")
android.AssertSameArray(t, "extraConfigs mismatch",
[]option{
{"name1", "key1", "value1"},
@@ -4660,6 +4796,7 @@
}
func TestAppStem(t *testing.T) {
+ t.Parallel()
ctx := testApp(t, `
android_app {
name: "foo",
@@ -4668,7 +4805,7 @@
sdk_version: "current",
}`)
- foo := ctx.ModuleForTests("foo", "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
outputs := fmt.Sprint(foo.AllOutputs())
if !strings.Contains(outputs, "foo-new.apk") {
@@ -4677,6 +4814,7 @@
}
func TestAppMinSdkVersionOverride(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, `
@@ -4693,8 +4831,8 @@
min_sdk_version: "33",
}
`)
- foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer")
- fooOverride := result.ModuleForTests("com.android.foo", "android_common_com.android.go.foo").Rule("manifestFixer")
+ foo := result.ModuleForTests(t, "com.android.foo", "android_common").Rule("manifestFixer")
+ fooOverride := result.ModuleForTests(t, "com.android.foo", "android_common_com.android.go.foo").Rule("manifestFixer")
android.AssertStringDoesContain(t,
"com.android.foo: expected manifest fixer to set minSdkVersion to T",
@@ -4710,6 +4848,7 @@
}
func TestNotApplyDefaultUpdatableModuleVersion(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, `
@@ -4720,7 +4859,7 @@
min_sdk_version: "31",
}
`)
- foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer")
+ foo := result.ModuleForTests(t, "com.android.foo", "android_common").Rule("manifestFixer")
android.AssertStringDoesNotContain(t,
"com.android.foo: expected manifest fixer to not set override-placeholder-version",
foo.BuildParams.Args["args"],
@@ -4729,6 +4868,7 @@
}
func TestNotApplyOverrideApexManifestDefaultVersion(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.FixtureMergeEnv(map[string]string{
@@ -4742,7 +4882,7 @@
min_sdk_version: "31",
}
`)
- foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer")
+ foo := result.ModuleForTests(t, "com.android.foo", "android_common").Rule("manifestFixer")
android.AssertStringDoesNotContain(t,
"com.android.foo: expected manifest fixer to not set override-placeholder-version",
foo.BuildParams.Args["args"],
@@ -4751,6 +4891,7 @@
}
func TestResourcesWithFlagDirectories(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.FixtureMergeMockFs(android.MockFS{
@@ -4769,7 +4910,7 @@
],
}
`)
- fooModule := result.ModuleForTests("foo", "android_common")
+ fooModule := result.ModuleForTests(t, "foo", "android_common")
compileOutputPaths := fooModule.Rule("aapt2Compile").Outputs.Strings()
android.AssertStringListContains(
@@ -4855,17 +4996,20 @@
},
}
for _, tc := range testCases {
- result := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.EnforceRROTargets = []string{"*"}
- }),
- android.OptionalFixturePreparer(tc.preparer),
- ).RunTestWithBp(t, bp)
- vendorOverlayApk := result.ModuleForTests("foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").MaybeOutput("foo__test_product__auto_generated_rro_vendor.apk")
- android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, vendorOverlayApk.Rule != nil)
- overrideVendorOverlayApk := result.ModuleForTests("override_foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").MaybeOutput("override_foo__test_product__auto_generated_rro_vendor.apk")
- android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, overrideVendorOverlayApk.Rule != nil)
+ t.Run(tc.desc, func(t *testing.T) {
+ t.Parallel()
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.EnforceRROTargets = []string{"*"}
+ }),
+ android.OptionalFixturePreparer(tc.preparer),
+ ).RunTestWithBp(t, bp)
+ vendorOverlayApk := result.ModuleForTests(t, "foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").MaybeOutput("foo__test_product__auto_generated_rro_vendor.apk")
+ android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, vendorOverlayApk.Rule != nil)
+ overrideVendorOverlayApk := result.ModuleForTests(t, "override_foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").MaybeOutput("override_foo__test_product__auto_generated_rro_vendor.apk")
+ android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, overrideVendorOverlayApk.Rule != nil)
+ })
}
}
@@ -4922,22 +5066,25 @@
},
}
for _, tc := range testCases {
- result := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.PrepareForTestWithSoongConfigModuleBuildComponents,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.EnforceRROTargets = []string{"*"}
- }),
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.DeviceResourceOverlays = []string{"device/company/test_product"}
- }),
- android.MockFS{
- "res/foo.xml": nil,
- "device/company/test_product/res/foo.xml": nil,
- }.AddToFixture(),
- android.OptionalFixturePreparer(tc.preparer),
- ).RunTestWithBp(t, bp)
- overrideVendorOverlayApk := result.ModuleForTests("override_foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").Module().(*AutogenRuntimeResourceOverlay)
- android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, overrideVendorOverlayApk.exportPackage != nil)
+ t.Run(tc.desc, func(t *testing.T) {
+ t.Parallel()
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.PrepareForTestWithSoongConfigModuleBuildComponents,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.EnforceRROTargets = []string{"*"}
+ }),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.DeviceResourceOverlays = []string{"device/company/test_product"}
+ }),
+ android.MockFS{
+ "res/foo.xml": nil,
+ "device/company/test_product/res/foo.xml": nil,
+ }.AddToFixture(),
+ android.OptionalFixturePreparer(tc.preparer),
+ ).RunTestWithBp(t, bp)
+ overrideVendorOverlayApk := result.ModuleForTests(t, "override_foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").Module().(*AutogenRuntimeResourceOverlay)
+ android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, overrideVendorOverlayApk.exportPackage != nil)
+ })
}
}
diff --git a/java/base.go b/java/base.go
index f8050de..0833831 100644
--- a/java/base.go
+++ b/java/base.go
@@ -377,7 +377,7 @@
//
// This cannot implement OutgoingDepIsInSameApex(...) directly as that leads to ambiguity with
// the one provided by ApexModuleBase.
-func (e *embeddableInModuleAndImport) depIsInSameApex(tag blueprint.DependencyTag) bool {
+func depIsInSameApex(tag blueprint.DependencyTag) bool {
// dependencies other than the static linkage are all considered crossing APEX boundary
if tag == staticLibTag {
return true
@@ -656,14 +656,17 @@
// Make sure this module doesn't statically link to modules with lower-ranked SDK link type.
// See rank() for details.
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(module)
- switch module.(type) {
- // TODO(satayev): cover other types as well, e.g. imports
- case *Library, *AndroidLibrary:
+ libInfo, isJavaLibrary := android.OtherModuleProvider(ctx, module, JavaLibraryInfoProvider)
+ _, isAndroidLibrary := android.OtherModuleProvider(ctx, module, AndroidLibraryInfoProvider)
+ _, isJavaAconfigLibrary := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider)
+ // Exclude java_aconfig_library modules to maintain consistency with existing behavior.
+ if (isJavaLibrary && !libInfo.Prebuilt && !isJavaAconfigLibrary) || isAndroidLibrary {
+ // TODO(satayev): cover other types as well, e.g. imports
switch tag {
case bootClasspathTag, sdkLibTag, libTag, staticLibTag, java9LibTag:
- j.checkSdkLinkType(ctx, module.(moduleWithSdkDep), tag.(dependencyTag))
+ j.checkSdkLinkType(ctx, module)
}
}
})
@@ -1295,15 +1298,11 @@
}
j.headerJarFile = combinedHeaderJarFile
- if ctx.Config().UseTransitiveJarsInClasspath() {
- if len(localHeaderJars) > 0 {
- ctx.CheckbuildFile(localHeaderJars...)
- } else {
- // There are no local sources or resources in this module, so there is nothing to checkbuild.
- ctx.UncheckedModule()
- }
+ if len(localHeaderJars) > 0 {
+ ctx.CheckbuildFile(localHeaderJars...)
} else {
- ctx.CheckbuildFile(j.headerJarFile)
+ // There are no local sources or resources in this module, so there is nothing to checkbuild.
+ ctx.UncheckedModule()
}
j.outputFile = j.headerJarFile
@@ -1333,14 +1332,24 @@
kotlincFlags := j.properties.Kotlincflags
CheckKotlincFlags(ctx, kotlincFlags)
- kotlin_lang_version := proptools.StringDefault(j.properties.Kotlin_lang_version, "1.9")
- if kotlin_lang_version == "1.9" {
+ // Available kotlin versions can be found at
+ // https://github.com/JetBrains/kotlin/blob/master/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt#L560
+ // in the `LanguageVersion` class.
+ // For now, avoid targeting language versions directly, as we'd like to kee our source
+ // code version aligned as much as possible. Ideally, after defaulting to "2", we
+ // can remove the "1.9" option entirely, or at least make it emit a warning.
+ kotlin_default_lang_version := "1.9"
+ if build_flag_lang_version, ok := ctx.Config().GetBuildFlag("RELEASE_KOTLIN_LANG_VERSION"); ok {
+ kotlin_default_lang_version = build_flag_lang_version
+ }
+ kotlin_lang_version := proptools.StringDefault(j.properties.Kotlin_lang_version, kotlin_default_lang_version)
+ switch kotlin_lang_version {
+ case "1.9":
kotlincFlags = append(kotlincFlags, "-language-version 1.9")
- } else if kotlin_lang_version == "2" {
+ case "2":
kotlincFlags = append(kotlincFlags, "-Xsuppress-version-warnings", "-Xconsistent-data-class-copy-visibility")
- } else {
+ default:
ctx.PropertyErrorf("kotlin_lang_version", "Must be one of `1.9` or `2`")
-
}
// Workaround for KT-46512
@@ -1591,12 +1600,7 @@
completeStaticLibsResourceJars := depset.New(depset.PREORDER, localResourceJars, deps.transitiveStaticLibsResourceJars)
var combinedResourceJar android.Path
- var resourceJars android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- resourceJars = completeStaticLibsResourceJars.ToList()
- } else {
- resourceJars = append(slices.Clone(localResourceJars), deps.staticResourceJars...)
- }
+ resourceJars := completeStaticLibsResourceJars.ToList()
if len(resourceJars) == 1 {
combinedResourceJar = resourceJars[0]
} else if len(resourceJars) > 0 {
@@ -1617,12 +1621,7 @@
completeStaticLibsImplementationJars := depset.New(depset.PREORDER, localImplementationJars, deps.transitiveStaticLibsImplementationJars)
- var jars android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- jars = completeStaticLibsImplementationJars.ToList()
- } else {
- jars = append(slices.Clone(localImplementationJars), deps.staticJars...)
- }
+ jars := completeStaticLibsImplementationJars.ToList()
jars = append(jars, extraDepCombinedJars...)
@@ -1753,7 +1752,7 @@
headerJarFile := android.PathForModuleOut(ctx, "javac-header", jarName)
convertImplementationJarToHeaderJar(ctx, j.implementationJarFile, headerJarFile)
j.headerJarFile = headerJarFile
- if len(localImplementationJars) == 1 && ctx.Config().UseTransitiveJarsInClasspath() {
+ if len(localImplementationJars) == 1 {
localHeaderJarFile := android.PathForModuleOut(ctx, "local-javac-header", jarName)
convertImplementationJarToHeaderJar(ctx, localImplementationJars[0], localHeaderJarFile)
localHeaderJars = append(localHeaderJars, localHeaderJarFile)
@@ -1783,16 +1782,10 @@
// merge implementation jar with resources if necessary
var implementationAndResourcesJarsToCombine android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- resourceJars := completeStaticLibsResourceJars.ToList()
- if len(resourceJars) > 0 {
- implementationAndResourcesJarsToCombine = append(resourceJars, completeStaticLibsImplementationJarsToCombine.ToList()...)
- implementationAndResourcesJarsToCombine = append(implementationAndResourcesJarsToCombine, extraDepCombinedJars...)
- }
- } else {
- if combinedResourceJar != nil {
- implementationAndResourcesJarsToCombine = android.Paths{combinedResourceJar, outputFile}
- }
+ combinedResourceJars := completeStaticLibsResourceJars.ToList()
+ if len(combinedResourceJars) > 0 {
+ implementationAndResourcesJarsToCombine = slices.Concat(combinedResourceJars,
+ completeStaticLibsImplementationJarsToCombine.ToList(), extraDepCombinedJars)
}
if len(implementationAndResourcesJarsToCombine) > 0 {
@@ -1842,18 +1835,9 @@
}
// merge dex jar with resources if necessary
- var dexAndResourceJarsToCombine android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- resourceJars := completeStaticLibsResourceJars.ToList()
- if len(resourceJars) > 0 {
- dexAndResourceJarsToCombine = append(android.Paths{dexOutputFile}, resourceJars...)
- }
- } else {
- if combinedResourceJar != nil {
- dexAndResourceJarsToCombine = android.Paths{dexOutputFile, combinedResourceJar}
- }
- }
- if len(dexAndResourceJarsToCombine) > 0 {
+ if len(combinedResourceJars) > 0 {
+ dexAndResourceJarsToCombine := append(android.Paths{dexOutputFile}, combinedResourceJars...)
+
combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName)
TransformJarsToJar(ctx, combinedJar, "for dex resources", dexAndResourceJarsToCombine, android.OptionalPath{},
false, nil, nil)
@@ -1925,18 +1909,13 @@
j.collectTransitiveSrcFiles(ctx, srcFiles)
- if ctx.Config().UseTransitiveJarsInClasspath() {
- if len(localImplementationJars) > 0 || len(localResourceJars) > 0 || len(localHeaderJars) > 0 {
- ctx.CheckbuildFile(localImplementationJars...)
- ctx.CheckbuildFile(localResourceJars...)
- ctx.CheckbuildFile(localHeaderJars...)
- } else {
- // There are no local sources or resources in this module, so there is nothing to checkbuild.
- ctx.UncheckedModule()
- }
+ if len(localImplementationJars) > 0 || len(localResourceJars) > 0 || len(localHeaderJars) > 0 {
+ ctx.CheckbuildFile(localImplementationJars...)
+ ctx.CheckbuildFile(localResourceJars...)
+ ctx.CheckbuildFile(localHeaderJars...)
} else {
- ctx.CheckbuildFile(j.implementationJarFile)
- ctx.CheckbuildFile(j.headerJarFile)
+ // There are no local sources or resources in this module, so there is nothing to checkbuild.
+ ctx.UncheckedModule()
}
// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
@@ -1967,6 +1946,7 @@
StubsLinkType: j.stubsLinkType,
AconfigIntermediateCacheOutputPaths: j.aconfigCacheFiles,
SdkVersion: j.SdkVersion(ctx),
+ OutputFile: j.outputFile,
}
}
@@ -1975,7 +1955,7 @@
}
func collectDepProguardSpecInfo(ctx android.ModuleContext) (transitiveProguardFlags, transitiveUnconditionalExportedFlags []depset.DepSet[android.Path]) {
- ctx.VisitDirectDeps(func(m android.Module) {
+ ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
depTag := ctx.OtherModuleDependencyTag(m)
@@ -2102,13 +2082,8 @@
// Combine any static header libraries into classes-header.jar. If there is only
// one input jar this step will be skipped.
- var jars android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- depSet := depset.New(depset.PREORDER, localHeaderJars, deps.transitiveStaticLibsHeaderJars)
- jars = depSet.ToList()
- } else {
- jars = append(slices.Clone(localHeaderJars), deps.staticHeaderJars...)
- }
+ depSet := depset.New(depset.PREORDER, localHeaderJars, deps.transitiveStaticLibsHeaderJars)
+ jars := depSet.ToList()
// we cannot skip the combine step for now if there is only one jar
// since we have to strip META-INF/TRANSITIVE dir from turbine.jar
@@ -2148,7 +2123,7 @@
directStaticLibs := android.Paths{}
transitiveLibs := []depset.DepSet[android.Path]{}
transitiveStaticLibs := []depset.DepSet[android.Path]{}
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
// don't add deps of the prebuilt version of the same library
if ctx.ModuleName() == android.RemoveOptionalPrebuiltPrefix(module.Name()) {
return
@@ -2216,6 +2191,8 @@
func (j *Module) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
if j.expandJarjarRules != nil {
dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String())
+ }
+ if j.headerJarFile != nil {
// Add the header jar so that the rdeps can be resolved to the repackaged classes.
dpInfo.Jars = append(dpInfo.Jars, j.headerJarFile.String())
}
@@ -2238,25 +2215,29 @@
}
// Implements android.ApexModule
-func (j *Module) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
- return j.depIsInSameApex(tag)
+func (m *Module) GetDepInSameApexChecker() android.DepInSameApexChecker {
+ return JavaDepInSameApexChecker{}
+}
+
+type JavaDepInSameApexChecker struct {
+ android.BaseDepInSameApexChecker
+}
+
+func (m JavaDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
+ return depIsInSameApex(tag)
}
// Implements android.ApexModule
-func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
+func (j *Module) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
sdkVersionSpec := j.SdkVersion(ctx)
minSdkVersion := j.MinSdkVersion(ctx)
- if !minSdkVersion.Specified() {
- return fmt.Errorf("min_sdk_version is not specified")
- }
+
// If the module is compiling against core (via sdk_version), skip comparison check.
if sdkVersionSpec.Kind == android.SdkCore {
- return nil
+ return android.MinApiLevel
}
- if minSdkVersion.GreaterThan(sdkVersion) {
- return fmt.Errorf("newer SDK(%v)", minSdkVersion)
- }
- return nil
+
+ return minSdkVersion
}
func (j *Module) Stem() string {
@@ -2272,7 +2253,7 @@
func (j *Module) collectTransitiveSrcFiles(ctx android.ModuleContext, mine android.Paths) {
var fromDeps []depset.DepSet[android.Path]
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(module)
if tag == staticLibTag {
if depInfo, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
@@ -2391,7 +2372,7 @@
// checkSdkLinkType make sures the given dependency doesn't have a lower SDK link type rank than
// this module's. See the comment on rank() for details and an example.
func (j *Module) checkSdkLinkType(
- ctx android.ModuleContext, dep moduleWithSdkDep, tag dependencyTag) {
+ ctx android.ModuleContext, dep android.ModuleProxy) {
if ctx.Host() {
return
}
@@ -2400,7 +2381,12 @@
if stubs {
return
}
- depLinkType, _ := dep.getSdkLinkType(ctx, ctx.OtherModuleName(dep))
+ info, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider)
+ if !ok || info.ModuleWithSdkDepInfo == nil {
+ panic(fmt.Errorf("dependency doesn't have ModuleWithSdkDepInfo: %v", dep))
+ }
+
+ depLinkType := info.ModuleWithSdkDepInfo.SdkLinkType
if myLinkType.rank() < depLinkType.rank() {
ctx.ModuleErrorf("compiles against %v, but dependency %q is compiling against %v. "+
@@ -2425,7 +2411,7 @@
var transitiveStaticJarsImplementationLibs []depset.DepSet[android.Path]
var transitiveStaticJarsResourceLibs []depset.DepSet[android.Path]
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
@@ -2459,7 +2445,7 @@
deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars...)
transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
case sdkLibTag, libTag, instrumentationForTag:
- if _, ok := module.(*Plugin); ok {
+ if _, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok {
ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a libs dependency", otherName)
}
deps.classpath = append(deps.classpath, dep.HeaderJars...)
@@ -2477,7 +2463,7 @@
deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
transitiveJava9ClasspathHeaderJars = append(transitiveJava9ClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
case staticLibTag:
- if _, ok := module.(*Plugin); ok {
+ if _, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok {
ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a static_libs dependency", otherName)
}
deps.classpath = append(deps.classpath, dep.HeaderJars...)
@@ -2497,40 +2483,40 @@
transitiveStaticJarsImplementationLibs = append(transitiveStaticJarsImplementationLibs, dep.TransitiveStaticLibsImplementationJars)
transitiveStaticJarsResourceLibs = append(transitiveStaticJarsResourceLibs, dep.TransitiveStaticLibsResourceJars)
case pluginTag:
- if plugin, ok := module.(*Plugin); ok {
- if plugin.pluginProperties.Processor_class != nil {
- addPlugins(&deps, dep.ImplementationAndResourcesJars, *plugin.pluginProperties.Processor_class)
+ if plugin, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok {
+ if plugin.ProcessorClass != nil {
+ addPlugins(&deps, dep.ImplementationAndResourcesJars, *plugin.ProcessorClass)
} else {
addPlugins(&deps, dep.ImplementationAndResourcesJars)
}
// Turbine doesn't run annotation processors, so any module that uses an
// annotation processor that generates API is incompatible with the turbine
// optimization.
- deps.disableTurbine = deps.disableTurbine || Bool(plugin.pluginProperties.Generates_api)
+ deps.disableTurbine = deps.disableTurbine || plugin.GeneratesApi
} else {
ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
}
case errorpronePluginTag:
- if _, ok := module.(*Plugin); ok {
+ if _, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok {
deps.errorProneProcessorPath = append(deps.errorProneProcessorPath, dep.ImplementationAndResourcesJars...)
} else {
ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
}
case exportedPluginTag:
- if plugin, ok := module.(*Plugin); ok {
+ if plugin, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok {
j.exportedPluginJars = append(j.exportedPluginJars, dep.ImplementationAndResourcesJars...)
- if plugin.pluginProperties.Processor_class != nil {
- j.exportedPluginClasses = append(j.exportedPluginClasses, *plugin.pluginProperties.Processor_class)
+ if plugin.ProcessorClass != nil {
+ j.exportedPluginClasses = append(j.exportedPluginClasses, *plugin.ProcessorClass)
}
// Turbine doesn't run annotation processors, so any module that uses an
// annotation processor that generates API is incompatible with the turbine
// optimization.
- j.exportedDisableTurbine = Bool(plugin.pluginProperties.Generates_api)
+ j.exportedDisableTurbine = plugin.GeneratesApi
} else {
ctx.PropertyErrorf("exported_plugins", "%q is not a java_plugin module", otherName)
}
case kotlinPluginTag:
- if _, ok := module.(*KotlinPlugin); ok {
+ if _, ok := android.OtherModuleProvider(ctx, module, KotlinPluginInfoProvider); ok {
deps.kotlinPlugins = append(deps.kotlinPlugins, dep.ImplementationAndResourcesJars...)
} else {
ctx.PropertyErrorf("kotlin_plugins", "%q is not a kotlin_plugin module", otherName)
@@ -2542,21 +2528,21 @@
JavaInfo: dep,
})
}
- } else if dep, ok := module.(android.SourceFileProducer); ok {
+ } else if dep, ok := android.OtherModuleProvider(ctx, module, android.SourceFilesInfoProvider); ok {
switch tag {
case sdkLibTag, libTag:
- checkProducesJars(ctx, dep)
- deps.classpath = append(deps.classpath, dep.Srcs()...)
- deps.dexClasspath = append(deps.classpath, dep.Srcs()...)
+ checkProducesJars(ctx, dep, module)
+ deps.classpath = append(deps.classpath, dep.Srcs...)
+ deps.dexClasspath = append(deps.classpath, dep.Srcs...)
transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars,
- depset.New(depset.PREORDER, dep.Srcs(), nil))
+ depset.New(depset.PREORDER, dep.Srcs, nil))
case staticLibTag:
- checkProducesJars(ctx, dep)
- deps.classpath = append(deps.classpath, dep.Srcs()...)
- deps.staticJars = append(deps.staticJars, dep.Srcs()...)
- deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...)
+ checkProducesJars(ctx, dep, module)
+ deps.classpath = append(deps.classpath, dep.Srcs...)
+ deps.staticJars = append(deps.staticJars, dep.Srcs...)
+ deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs...)
- depHeaderJars := depset.New(depset.PREORDER, dep.Srcs(), nil)
+ depHeaderJars := depset.New(depset.PREORDER, dep.Srcs, nil)
transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, depHeaderJars)
transitiveStaticJarsHeaderLibs = append(transitiveStaticJarsHeaderLibs, depHeaderJars)
transitiveStaticJarsImplementationLibs = append(transitiveStaticJarsImplementationLibs, depHeaderJars)
@@ -2609,14 +2595,12 @@
deps.transitiveStaticLibsImplementationJars = transitiveStaticJarsImplementationLibs
deps.transitiveStaticLibsResourceJars = transitiveStaticJarsResourceLibs
- if ctx.Config().UseTransitiveJarsInClasspath() {
- depSet := depset.New(depset.PREORDER, nil, transitiveClasspathHeaderJars)
- deps.classpath = depSet.ToList()
- depSet = depset.New(depset.PREORDER, nil, transitiveBootClasspathHeaderJars)
- deps.bootClasspath = depSet.ToList()
- depSet = depset.New(depset.PREORDER, nil, transitiveJava9ClasspathHeaderJars)
- deps.java9Classpath = depSet.ToList()
- }
+ depSet := depset.New(depset.PREORDER, nil, transitiveClasspathHeaderJars)
+ deps.classpath = depSet.ToList()
+ depSet = depset.New(depset.PREORDER, nil, transitiveBootClasspathHeaderJars)
+ deps.bootClasspath = depSet.ToList()
+ depSet = depset.New(depset.PREORDER, nil, transitiveJava9ClasspathHeaderJars)
+ deps.java9Classpath = depSet.ToList()
if ctx.Device() {
sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
@@ -2732,7 +2716,7 @@
module := ctx.Module()
moduleName := module.Name()
- ctx.VisitDirectDeps(func(m android.Module) {
+ ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
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
@@ -2771,10 +2755,8 @@
//fmt.Printf("collectDirectDepsProviders: %v -> %v StubsLinkType unknown\n", module, m)
// Fall through to the heuristic logic.
}
- switch reflect.TypeOf(m).String() {
- case "*java.GeneratedJavaLibraryModule":
+ if _, ok := android.OtherModuleProvider(ctx, m, android.CodegenInfoProvider); ok {
// Probably a java_aconfig_library module.
- // TODO: make this check better.
return RenameUseInclude
}
switch tag {
@@ -2797,7 +2779,7 @@
default:
return RenameUseExclude
}
- } else if _, ok := m.(android.SourceFileProducer); ok {
+ } else if _, ok := android.OtherModuleProvider(ctx, m, android.SourceFilesInfoProvider); ok {
switch tag {
case sdkLibTag, libTag, staticLibTag:
return RenameUseInclude
@@ -2929,14 +2911,18 @@
// Get the jarjar rule text for a given provider for the fully resolved rules. Classes that map
// to "" won't be in this list because they shouldn't be renamed yet.
func getJarJarRuleText(provider *JarJarProviderData) string {
- result := ""
+ result := strings.Builder{}
for _, orig := range android.SortedKeys(provider.Rename) {
renamed := provider.Rename[orig]
if renamed != "" {
- result += "rule " + orig + " " + renamed + "\n"
+ result.WriteString("rule ")
+ result.WriteString(orig)
+ result.WriteString(" ")
+ result.WriteString(renamed)
+ result.WriteString("\n")
}
}
- return result
+ return result.String()
}
// Repackage the flags if the jarjar rule txt for the flags is generated
diff --git a/java/bootclasspath.go b/java/bootclasspath.go
index 3413cf3..98fb417 100644
--- a/java/bootclasspath.go
+++ b/java/bootclasspath.go
@@ -15,6 +15,8 @@
package java
import (
+ "fmt"
+
"android/soong/android"
"github.com/google/blueprint"
@@ -23,36 +25,9 @@
// Contains code that is common to both platform_bootclasspath and bootclasspath_fragment.
-func init() {
- registerBootclasspathBuildComponents(android.InitRegistrationContext)
-}
-
-func registerBootclasspathBuildComponents(ctx android.RegistrationContext) {
- ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("bootclasspath_deps", bootclasspathDepsMutator)
- })
-}
-
-// BootclasspathDepsMutator is the interface that a module must implement if it wants to add
-// dependencies onto APEX specific variants of bootclasspath fragments or bootclasspath contents.
-type BootclasspathDepsMutator interface {
- // BootclasspathDepsMutator implementations should add dependencies using
- // addDependencyOntoApexModulePair and addDependencyOntoApexVariants.
- BootclasspathDepsMutator(ctx android.BottomUpMutatorContext)
-}
-
-// bootclasspathDepsMutator is called during the final deps phase after all APEX variants have
-// been created so can add dependencies onto specific APEX variants of modules.
-func bootclasspathDepsMutator(ctx android.BottomUpMutatorContext) {
- m := ctx.Module()
- if p, ok := m.(BootclasspathDepsMutator); ok {
- p.BootclasspathDepsMutator(ctx)
- }
-}
-
// addDependencyOntoApexVariants adds dependencies onto the appropriate apex specific variants of
// the module as specified in the ApexVariantReference list.
-func addDependencyOntoApexVariants(ctx android.BottomUpMutatorContext, propertyName string, refs []ApexVariantReference, tag blueprint.DependencyTag) {
+func addDependencyOntoApexVariants(ctx android.BottomUpMutatorContext, propertyName string, refs []ApexVariantReference, tagType bootclasspathDependencyTagType) {
for i, ref := range refs {
apex := proptools.StringDefault(ref.Apex, "platform")
@@ -62,7 +37,7 @@
}
name := proptools.String(ref.Module)
- addDependencyOntoApexModulePair(ctx, apex, name, tag)
+ addDependencyOntoApexModulePair(ctx, apex, name, tagType)
}
}
@@ -75,68 +50,154 @@
// module when both source and prebuilt modules are available.
//
// Use gatherApexModulePairDepsWithTag to retrieve the dependencies.
-func addDependencyOntoApexModulePair(ctx android.BottomUpMutatorContext, apex string, name string, tag blueprint.DependencyTag) {
- var variations []blueprint.Variation
- if !android.IsConfiguredJarForPlatform(apex) {
- // Pick the correct apex variant.
- variations = []blueprint.Variation{
- {Mutator: "apex", Variation: apex},
- }
+func addDependencyOntoApexModulePair(ctx android.BottomUpMutatorContext, apex string, name string, tagType bootclasspathDependencyTagType) {
+ tag := bootclasspathDependencyTag{
+ typ: tagType,
}
-
target := ctx.Module().Target()
- variations = append(variations, target.Variations()...)
-
- addedDep := false
- if ctx.OtherModuleDependencyVariantExists(variations, name) {
- ctx.AddFarVariationDependencies(variations, tag, name)
- addedDep = true
+ if android.IsConfiguredJarForPlatform(apex) {
+ // Platform variant, add a direct dependency.
+ ctx.AddFarVariationDependencies(target.Variations(), tag, name)
+ } else {
+ // A module in an apex. Dependencies can't be added directly onto an apex variation, as that would
+ // require constructing a full ApexInfo configuration, which can't be predicted here. Add a dependency
+ // on the apex instead, and annotate the dependency tag with the desired module in the apex.
+ tag.moduleInApex = name
+ ctx.AddFarVariationDependencies(target.Variations(), tag, apex)
}
- // Add a dependency on the prebuilt module if it exists.
- prebuiltName := android.PrebuiltNameFromSource(name)
- if ctx.OtherModuleDependencyVariantExists(variations, prebuiltName) {
- ctx.AddVariationDependencies(variations, tag, prebuiltName)
- addedDep = true
- }
-
- // If no appropriate variant existing for this, so no dependency could be added, then it is an
- // error, unless missing dependencies are allowed. The simplest way to handle that is to add a
- // dependency that will not be satisfied and the default behavior will handle it.
- if !addedDep {
- // Add dependency on the unprefixed (i.e. source or renamed prebuilt) module which we know does
- // not exist. The resulting error message will contain useful information about the available
- // variants.
- reportMissingVariationDependency(ctx, variations, name)
-
- // Add dependency on the missing prefixed prebuilt variant too if a module with that name exists
- // so that information about its available variants will be reported too.
- if ctx.OtherModuleExists(prebuiltName) {
- reportMissingVariationDependency(ctx, variations, prebuiltName)
- }
- }
}
-// reportMissingVariationDependency intentionally adds a dependency on a missing variation in order
-// to generate an appropriate error message with information about the available variations.
-func reportMissingVariationDependency(ctx android.BottomUpMutatorContext, variations []blueprint.Variation, name string) {
- ctx.AddFarVariationDependencies(variations, nil, name)
+// gatherFragments collects fragments that are direct dependencies of this module, as well as
+// any fragments in apexes via the dependency on the apex. It returns a list of the fragment
+// modules and map from apex name to the fragment in that apex.
+func gatherFragments(ctx android.BaseModuleContext) ([]android.Module, map[string]android.Module) {
+ var fragments []android.Module
+
+ type fragmentInApex struct {
+ module string
+ apex string
+ }
+
+ var fragmentsInApexes []fragmentInApex
+
+ // Find any direct dependencies, as well as a list of the modules in apexes.
+ ctx.VisitDirectDeps(func(module android.Module) {
+ t := ctx.OtherModuleDependencyTag(module)
+ if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == fragment {
+ if bcpTag.moduleInApex != "" {
+ fragmentsInApexes = append(fragmentsInApexes, fragmentInApex{bcpTag.moduleInApex, ctx.OtherModuleName(module)})
+ } else {
+ fragments = append(fragments, module)
+ }
+ }
+ })
+
+ fragmentsMap := make(map[string]android.Module)
+ for _, fragmentInApex := range fragmentsInApexes {
+ var found android.Module
+ // Find a desired module in an apex.
+ ctx.WalkDeps(func(child, parent android.Module) bool {
+ t := ctx.OtherModuleDependencyTag(child)
+ if parent == ctx.Module() {
+ if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == fragment && ctx.OtherModuleName(child) == fragmentInApex.apex {
+ // This is the dependency from this module to the apex, recurse into it.
+ return true
+ }
+ } else if android.IsDontReplaceSourceWithPrebuiltTag(t) {
+ return false
+ } else if t == android.PrebuiltDepTag {
+ return false
+ } else if IsBootclasspathFragmentContentDepTag(t) {
+ return false
+ } else if android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child)) == fragmentInApex.module {
+ // This is the desired module inside the apex.
+ if found != nil && child != found {
+ panic(fmt.Errorf("found two conflicting modules %q in apex %q: %s and %s",
+ fragmentInApex.module, fragmentInApex.apex, found, child))
+ }
+ found = child
+ }
+ return false
+ })
+ if found != nil {
+ if existing, exists := fragmentsMap[fragmentInApex.apex]; exists {
+ ctx.ModuleErrorf("apex %s has multiple fragments, %s and %s", fragmentInApex.apex, fragmentInApex.module, existing)
+ } else {
+ fragmentsMap[fragmentInApex.apex] = found
+ fragments = append(fragments, found)
+ }
+ } else if !ctx.Config().AllowMissingDependencies() {
+ ctx.ModuleErrorf("failed to find fragment %q in apex %q\n",
+ fragmentInApex.module, fragmentInApex.apex)
+ }
+ }
+ return fragments, fragmentsMap
}
// gatherApexModulePairDepsWithTag returns the list of dependencies with the supplied tag that was
// added by addDependencyOntoApexModulePair.
-func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext, tag blueprint.DependencyTag) []android.Module {
+func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext, tagType bootclasspathDependencyTagType) ([]android.Module, map[android.Module]string) {
var modules []android.Module
- isActiveModulePred := func(module android.Module) bool {
- return isActiveModule(ctx, module)
+ modulesToApex := make(map[android.Module]string)
+
+ type moduleInApex struct {
+ module string
+ apex string
}
- ctx.VisitDirectDepsIf(isActiveModulePred, func(module android.Module) {
+
+ var modulesInApexes []moduleInApex
+
+ ctx.VisitDirectDeps(func(module android.Module) {
t := ctx.OtherModuleDependencyTag(module)
- if t == tag {
- modules = append(modules, module)
+ if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == tagType {
+ if bcpTag.moduleInApex != "" {
+ modulesInApexes = append(modulesInApexes, moduleInApex{bcpTag.moduleInApex, ctx.OtherModuleName(module)})
+ } else {
+ modules = append(modules, module)
+ }
}
})
- return modules
+
+ for _, moduleInApex := range modulesInApexes {
+ var found android.Module
+ ctx.WalkDeps(func(child, parent android.Module) bool {
+ t := ctx.OtherModuleDependencyTag(child)
+ if parent == ctx.Module() {
+ if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == tagType && ctx.OtherModuleName(child) == moduleInApex.apex {
+ // recurse into the apex
+ return true
+ }
+ } else if tagType != fragment && android.IsFragmentInApexTag(t) {
+ return true
+ } else if android.IsDontReplaceSourceWithPrebuiltTag(t) {
+ return false
+ } else if t == android.PrebuiltDepTag {
+ return false
+ } else if IsBootclasspathFragmentContentDepTag(t) {
+ return false
+ } else if android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child)) == moduleInApex.module {
+ if found != nil && child != found {
+ panic(fmt.Errorf("found two conflicting modules %q in apex %q: %s and %s",
+ moduleInApex.module, moduleInApex.apex, found, child))
+ }
+ found = child
+ }
+ return false
+ })
+ if found != nil {
+ modules = append(modules, found)
+ if existing, exists := modulesToApex[found]; exists && existing != moduleInApex.apex {
+ ctx.ModuleErrorf("module %s is in two apexes, %s and %s", moduleInApex.module, existing, moduleInApex.apex)
+ } else {
+ modulesToApex[found] = moduleInApex.apex
+ }
+ } else if !ctx.Config().AllowMissingDependencies() {
+ ctx.ModuleErrorf("failed to find module %q in apex %q\n",
+ moduleInApex.module, moduleInApex.apex)
+ }
+ }
+ return modules, modulesToApex
}
// ApexVariantReference specifies a particular apex variant of a module.
@@ -165,7 +226,7 @@
// addDependenciesOntoFragments adds dependencies to the fragments specified in this properties
// structure.
func (p *BootclasspathFragmentsDepsProperties) addDependenciesOntoFragments(ctx android.BottomUpMutatorContext) {
- addDependencyOntoApexVariants(ctx, "fragments", p.Fragments, bootclasspathFragmentDepTag)
+ addDependencyOntoApexVariants(ctx, "fragments", p.Fragments, fragment)
}
// bootclasspathDependencyTag defines dependencies from/to bootclasspath_fragment,
@@ -174,23 +235,38 @@
type bootclasspathDependencyTag struct {
blueprint.BaseDependencyTag
- name string
+ typ bootclasspathDependencyTagType
+
+ // moduleInApex is set to the name of the desired module when this dependency points
+ // to the apex that the modules is contained in.
+ moduleInApex string
}
+type bootclasspathDependencyTagType int
+
+const (
+ // The tag used for dependencies onto bootclasspath_fragments.
+ fragment bootclasspathDependencyTagType = iota
+ // The tag used for dependencies onto platform_bootclasspath.
+ platform
+ dexpreoptBootJar
+ artBootJar
+ platformBootJar
+ apexBootJar
+)
+
func (t bootclasspathDependencyTag) ExcludeFromVisibilityEnforcement() {
}
+func (t bootclasspathDependencyTag) LicenseAnnotations() []android.LicenseAnnotation {
+ return []android.LicenseAnnotation{android.LicenseAnnotationSharedDependency}
+}
+
// Dependencies that use the bootclasspathDependencyTag instances are only added after all the
// visibility checking has been done so this has no functional effect. However, it does make it
// clear that visibility is not being enforced on these tags.
var _ android.ExcludeFromVisibilityEnforcementTag = bootclasspathDependencyTag{}
-// The tag used for dependencies onto bootclasspath_fragments.
-var bootclasspathFragmentDepTag = bootclasspathDependencyTag{name: "fragment"}
-
-// The tag used for dependencies onto platform_bootclasspath.
-var platformBootclasspathDepTag = bootclasspathDependencyTag{name: "platform"}
-
// BootclasspathNestedAPIProperties defines properties related to the API provided by parts of the
// bootclasspath that are nested within the main BootclasspathAPIProperties.
type BootclasspathNestedAPIProperties struct {
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index d6777e5..a09416d 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -41,6 +41,10 @@
ctx.RegisterModuleType("prebuilt_bootclasspath_fragment", prebuiltBootclasspathFragmentFactory)
}
+type BootclasspathFragmentInfo struct{}
+
+var BootclasspathFragmentInfoProvider = blueprint.NewProvider[BootclasspathFragmentInfo]()
+
// BootclasspathFragmentSdkMemberType is the member type used to add bootclasspath_fragments to
// the SDK snapshot. It is exported for use by apex.
var BootclasspathFragmentSdkMemberType = &bootclasspathFragmentMemberType{
@@ -89,6 +93,19 @@
// The tag used for the dependency between the bootclasspath_fragment module and its contents.
var bootclasspathFragmentContentDepTag = bootclasspathFragmentContentDependencyTag{}
+type moduleInFragmentDependencyTag struct {
+ blueprint.DependencyTag
+}
+
+func (m moduleInFragmentDependencyTag) ExcludeFromVisibilityEnforcement() {
+}
+
+// moduleInFragmentDepTag is added alongside bootclasspathFragmentContentDependencyTag,
+// but doesn't set ReplaceSourceWithPrebuilt. It is used to find modules in the fragment
+// by traversing from the apex to the fragment to the module, which prevents having to
+// construct a dependency on the apex variant of the fragment directly.
+var moduleInFragmentDepTag = moduleInFragmentDependencyTag{}
+
var _ android.ExcludeFromVisibilityEnforcementTag = bootclasspathFragmentContentDepTag
var _ android.ReplaceSourceWithPrebuilt = bootclasspathFragmentContentDepTag
var _ android.SdkMemberDependencyTag = bootclasspathFragmentContentDepTag
@@ -239,6 +256,8 @@
profilePathErr error
}
+var _ android.ApexModule = (*BootclasspathFragmentModule)(nil)
+
// commonBootclasspathFragment defines the methods that are implemented by both source and prebuilt
// bootclasspath fragment modules.
type commonBootclasspathFragment interface {
@@ -290,6 +309,10 @@
return m
}
+func (m *BootclasspathFragmentModule) UniqueApexVariations() bool {
+ return true
+}
+
func (m *BootclasspathFragmentModule) bootclasspathFragmentPropertyCheck(ctx android.ModuleContext) {
contents := m.properties.Contents.GetOrDefault(ctx, nil)
if len(contents) == 0 {
@@ -393,7 +416,15 @@
return i.profileInstallPathInApex
}
-func (b *BootclasspathFragmentModule) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
+func (m *BootclasspathFragmentModule) GetDepInSameApexChecker() android.DepInSameApexChecker {
+ return BootclasspathFragmentDepInSameApexChecker{}
+}
+
+type BootclasspathFragmentDepInSameApexChecker struct {
+ android.BaseDepInSameApexChecker
+}
+
+func (b BootclasspathFragmentDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
// If the module is a default module, do not check the tag
if tag == android.DefaultsDepTag {
return true
@@ -406,17 +437,31 @@
// Cross-cutting metadata dependencies are metadata.
return false
}
+ if tag == moduleInFragmentDepTag {
+ return true
+ }
// Dependency to the bootclasspath fragment of another apex
// e.g. concsrypt-bootclasspath-fragment --> art-bootclasspath-fragment
- if tag == bootclasspathFragmentDepTag {
+ if bcpTag, ok := tag.(bootclasspathDependencyTag); ok && bcpTag.typ == fragment {
return false
-
}
- panic(fmt.Errorf("boot_image module %q should not have a dependency tag %s", b, android.PrettyPrintTag(tag)))
+ if tag == moduleInFragmentDepTag {
+ return false
+ }
+ if tag == dexpreopt.Dex2oatDepTag {
+ return false
+ }
+ if tag == android.PrebuiltDepTag {
+ return false
+ }
+ if _, ok := tag.(hiddenAPIStubsDependencyTag); ok {
+ return false
+ }
+ panic(fmt.Errorf("boot_image module should not have a dependency tag %s", android.PrettyPrintTag(tag)))
}
-func (b *BootclasspathFragmentModule) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
- return nil
+func (m *BootclasspathFragmentModule) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
+ return android.MinApiLevel
}
// ComponentDepsMutator adds dependencies onto modules before any prebuilt modules without a
@@ -454,24 +499,24 @@
}
}
- if !dexpreopt.IsDex2oatNeeded(ctx) {
- return
+ if dexpreopt.IsDex2oatNeeded(ctx) {
+ // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
+ // path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
+ dexpreopt.RegisterToolDeps(ctx)
}
- // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
- // path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
- dexpreopt.RegisterToolDeps(ctx)
-
// Add a dependency to `all_apex_contributions` to determine if prebuilts are active.
// If prebuilts are active, `contents` validation on the source bootclasspath fragment should be disabled.
if _, isPrebuiltModule := ctx.Module().(*PrebuiltBootclasspathFragmentModule); !isPrebuiltModule {
ctx.AddDependency(b, android.AcDepTag, "all_apex_contributions")
}
-}
-func (b *BootclasspathFragmentModule) BootclasspathDepsMutator(ctx android.BottomUpMutatorContext) {
// Add dependencies on all the fragments.
b.properties.BootclasspathFragmentsDepsProperties.addDependenciesOntoFragments(ctx)
+
+ for _, name := range b.properties.Contents.GetOrDefault(ctx, nil) {
+ ctx.AddDependency(ctx.Module(), moduleInFragmentDepTag, name)
+ }
}
func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -494,7 +539,7 @@
}
})
- fragments := gatherApexModulePairDepsWithTag(ctx, bootclasspathFragmentDepTag)
+ fragments, _ := gatherFragments(ctx)
// Perform hidden API processing.
hiddenAPIOutput := b.generateHiddenAPIBuildActions(ctx, contents, fragments)
@@ -516,6 +561,8 @@
if !ctx.IsFinalModule(ctx.Module()) {
b.HideFromMake()
}
+
+ android.SetProvider(ctx, BootclasspathFragmentInfoProvider, BootclasspathFragmentInfo{})
}
// getProfileProviderApex returns the name of the apex that provides a boot image profile, or an
@@ -527,19 +574,18 @@
}
// Bootclasspath fragment modules that are for the platform do not produce boot related files.
- apexInfos, _ := android.ModuleProvider(ctx, android.AllApexInfoProvider)
- if apexInfos == nil {
+ apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
+ if apexInfo.IsForPlatform() {
return ""
}
- for _, apexInfo := range apexInfos.ApexInfos {
- for _, apex := range apexInfo.InApexVariants {
- if isProfileProviderApex(ctx, apex) {
- return apex
+ for _, config := range genBootImageConfigs(ctx) {
+ if config.profileProviderModule == b.BaseModuleName() {
+ if len(config.profileImports) > 0 {
+ return config.profileImports[0]
}
}
}
-
return ""
}
@@ -603,7 +649,7 @@
if android.IsModulePrebuilt(ctx.Module()) {
// prebuilt bcpf. the validation of this will be done at the top-level apex
providerClasspathFragmentValidationInfoProvider(ctx, unknown)
- } else if !disableSourceApexVariant(ctx) {
+ } else if !disableSourceApexVariant(ctx) && android.IsModulePreferred(ctx.Module()) {
// source bcpf, and prebuilt apex are not selected.
ctx.ModuleErrorf("%s in contents must also be declared in PRODUCT_APEX_BOOT_JARS", unknown)
}
@@ -1139,6 +1185,13 @@
android.InitPrebuiltModule(m, &[]string{"placeholder"})
android.InitApexModule(m)
android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibCommon)
+ android.InitDefaultableModule(m)
+
+ m.SetDefaultableHook(func(mctx android.DefaultableHookContext) {
+ if mctx.Config().AlwaysUsePrebuiltSdks() {
+ m.prebuilt.ForcePrefer()
+ }
+ })
return m
}
diff --git a/java/bootclasspath_fragment_test.go b/java/bootclasspath_fragment_test.go
index 3aa1258..87b853c 100644
--- a/java/bootclasspath_fragment_test.go
+++ b/java/bootclasspath_fragment_test.go
@@ -31,6 +31,7 @@
)
func TestBootclasspathFragment_UnknownImageName(t *testing.T) {
+ t.Parallel()
prepareForTestWithBootclasspathFragment.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
`\Qimage_name: unknown image name "unknown", expected "art"\E`)).
@@ -50,6 +51,7 @@
}
func TestPrebuiltBootclasspathFragment_UnknownImageName(t *testing.T) {
+ t.Parallel()
prepareForTestWithBootclasspathFragment.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
`\Qimage_name: unknown image name "unknown", expected "art"\E`)).
@@ -68,6 +70,7 @@
}
func TestBootclasspathFragmentInconsistentArtConfiguration_Platform(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForTestWithBootclasspathFragment,
dexpreopt.FixtureSetArtBootJars("platform:foo", "apex:bar"),
@@ -99,6 +102,7 @@
}
func TestBootclasspathFragmentInconsistentArtConfiguration_ApexMixture(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForTestWithBootclasspathFragment,
dexpreopt.FixtureSetArtBootJars("apex1:foo", "apex2:bar"),
@@ -131,6 +135,7 @@
}
func TestBootclasspathFragment_Coverage(t *testing.T) {
+ t.Parallel()
prepareWithBp := android.FixtureWithRootAndroidBp(`
bootclasspath_fragment {
name: "myfragment",
@@ -204,11 +209,13 @@
)
t.Run("without coverage", func(t *testing.T) {
+ t.Parallel()
result := preparer.RunTest(t)
checkContents(t, result, "mybootlib")
})
t.Run("with coverage", func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForTestWithFrameworkJacocoInstrumentation,
preparer,
@@ -364,7 +371,7 @@
}
`)
- fragment := result.ModuleForTests("myfragment", "android_common")
+ fragment := result.ModuleForTests(t, "myfragment", "android_common")
dependencyStubDexFlag := "--dependency-stub-dex=out/soong/.intermediates/default/java/android-non-updatable.stubs.test_module_lib/android_common/dex/android-non-updatable.stubs.test_module_lib.jar"
stubFlagsCommand := fragment.Output("modular-hiddenapi/stub-flags.csv").RuleParams.Command
android.AssertStringDoesContain(t,
@@ -472,7 +479,7 @@
// Make sure that the signature-patterns.csv is passed all the appropriate package properties
// from the bootclasspath_fragment and its contents.
- fragment := result.ModuleForTests("mybootclasspathfragment", "android_common")
+ fragment := result.ModuleForTests(t, "mybootclasspathfragment", "android_common")
rule := fragment.Output("modular-hiddenapi/signature-patterns.csv")
expectedCommand := strings.Join([]string{
"--split-package newlibrary",
diff --git a/java/builder.go b/java/builder.go
index f1d5e99..ade9784 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -323,6 +323,13 @@
Command: `${keep-flagged-apis} ${in} > ${out}`,
CommandDeps: []string{"${keep-flagged-apis}"},
})
+
+ generateApiXMLRule = pctx.AndroidStaticRule("generateApiXMLRule",
+ blueprint.RuleParams{
+ Command: `${config.JavaCmd} ${config.JavaVmFlags} -Xmx4g -jar ${config.MetalavaJar} jar-to-jdiff ${in} ${out}`,
+ CommandDeps: []string{"${config.JavaCmd}", "${config.MetalavaJar}"},
+ Description: "Converting API file to XML",
+ })
)
func init() {
@@ -750,9 +757,9 @@
jar android.Path) {
ctx.Build(pctx, android.BuildParams{
- Rule: extractR8Rules,
- Output: outputFile,
- Input: jar,
+ Rule: extractR8Rules,
+ Output: outputFile,
+ Input: jar,
})
}
@@ -796,7 +803,7 @@
totalStr := strconv.Itoa(totalShards)
for i := 0; i < totalShards; i++ {
iStr := strconv.Itoa(i)
- tempOut := android.PathForOutput(ctx, outputFile.String()+"-"+iStr+".jar")
+ tempOut := outputFile.ReplaceExtension(ctx, "-"+iStr+".jar")
ctx.Build(pctx, android.BuildParams{
Rule: jarjar,
Description: "jarjar (" + iStr + "/" + totalStr + ")",
diff --git a/java/classpath_element.go b/java/classpath_element.go
index abbcae7..4af2770 100644
--- a/java/classpath_element.go
+++ b/java/classpath_element.go
@@ -108,33 +108,18 @@
//
// e.g. Given the following input:
//
-// libraries: com.android.art:core-oj, com.android.art:core-libart, framework, ext
-// fragments: com.android.art:art-bootclasspath-fragment
+// libraries: core-oj, core-libart, framework, ext
+// fragments: art-bootclasspath-fragment
+// libraryToApex: core-oj: com.android.art, core-libart: com.android.art
+// apexNameToFragment: com.android.art: art-bootclasspath-fragment
//
// Then this will return:
//
// ClasspathFragmentElement(art-bootclasspath-fragment, [core-oj, core-libart]),
// ClasspathLibraryElement(framework),
// ClasspathLibraryElement(ext),
-func CreateClasspathElements(ctx ClasspathElementContext, libraries []android.Module, fragments []android.Module) ClasspathElements {
- // Create a map from apex name to the fragment module. This makes it easy to find the fragment
- // associated with a particular apex.
- apexToFragment := map[string]android.Module{}
- for _, fragment := range fragments {
- apexInfo, ok := android.OtherModuleProvider(ctx, fragment, android.ApexInfoProvider)
- if !ok {
- ctx.ModuleErrorf("fragment %s is not part of an apex", fragment)
- continue
- }
-
- for _, apex := range apexInfo.InApexVariants {
- if existing, ok := apexToFragment[apex]; ok {
- ctx.ModuleErrorf("apex %s has multiple fragments, %s and %s", apex, fragment, existing)
- continue
- }
- apexToFragment[apex] = fragment
- }
- }
+func CreateClasspathElements(ctx ClasspathElementContext, libraries []android.Module, fragments []android.Module,
+ libraryToApex map[android.Module]string, apexNameToFragment map[string]android.Module) ClasspathElements {
fragmentToElement := map[android.Module]*ClasspathFragmentElement{}
elements := []ClasspathElement{}
@@ -144,31 +129,28 @@
// Iterate over the libraries to construct the ClasspathElements list.
for _, library := range libraries {
var element ClasspathElement
- if apexInfo, ok := android.OtherModuleProvider(ctx, library, android.ApexInfoProvider); ok {
-
+ if libraryApex, ok := libraryToApex[library]; ok {
var fragment android.Module
// Make sure that the library is in only one fragment of the classpath.
- for _, apex := range apexInfo.InApexVariants {
- if f, ok := apexToFragment[apex]; ok {
- if fragment == nil {
- // This is the first fragment so just save it away.
- fragment = f
- } else if f != fragment {
- // This apex variant of the library is in a different fragment.
- ctx.ModuleErrorf("library %s is in two separate fragments, %s and %s", library, fragment, f)
- // Skip over this library entirely as otherwise the resulting classpath elements would
- // be invalid.
- continue skipLibrary
- }
- } else {
- // There is no fragment associated with the library's apex.
+ if f, ok := apexNameToFragment[libraryApex]; ok {
+ if fragment == nil {
+ // This is the first fragment so just save it away.
+ fragment = f
+ } else if f != fragment {
+ // This apex variant of the library is in a different fragment.
+ ctx.ModuleErrorf("library %s is in two separate fragments, %s and %s", library, fragment, f)
+ // Skip over this library entirely as otherwise the resulting classpath elements would
+ // be invalid.
+ continue skipLibrary
}
+ } else {
+ // There is no fragment associated with the library's apex.
}
if fragment == nil {
ctx.ModuleErrorf("library %s is from apexes %s which have no corresponding fragment in %s",
- library, apexInfo.InApexVariants, fragments)
+ library, []string{libraryApex}, fragments)
// Skip over this library entirely as otherwise the resulting classpath elements would
// be invalid.
continue skipLibrary
diff --git a/java/container_test.go b/java/container_test.go
index 25cfa4c..35a3020 100644
--- a/java/container_test.go
+++ b/java/container_test.go
@@ -26,6 +26,7 @@
}
func TestJavaContainersModuleProperties(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
).RunTestWithBp(t, `
@@ -154,7 +155,7 @@
}
for _, c := range testcases {
- m := result.ModuleForTests(c.moduleName, "android_common")
+ m := result.ModuleForTests(t, c.moduleName, "android_common")
containers, _ := android.OtherModuleProvider(result.TestContext.OtherModuleProviderAdaptor(), m.Module(), android.ContainersInfoProvider)
belongingContainers := containers.BelongingContainers()
checkContainerMatch(t, c.moduleName, "system", c.isSystemContainer, android.InList(android.SystemContainer, belongingContainers))
diff --git a/java/device_host_converter_test.go b/java/device_host_converter_test.go
index 6ccc5c1..42e3b46 100644
--- a/java/device_host_converter_test.go
+++ b/java/device_host_converter_test.go
@@ -15,13 +15,15 @@
package java
import (
- "android/soong/android"
"slices"
"strings"
"testing"
+
+ "android/soong/android"
)
func TestDeviceForHost(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "device_module",
@@ -52,15 +54,15 @@
ctx, config := testJava(t, bp)
- deviceModule := ctx.ModuleForTests("device_module", "android_common")
- deviceTurbineCombined := deviceModule.Output("turbine-combined/device_module.jar")
+ deviceModule := ctx.ModuleForTests(t, "device_module", "android_common")
+ deviceTurbine := deviceModule.Output("turbine/device_module.jar")
deviceJavac := deviceModule.Output("javac/device_module.jar")
deviceRes := deviceModule.Output("res/device_module.jar")
- deviceImportModule := ctx.ModuleForTests("device_import_module", "android_common")
- deviceImportCombined := deviceImportModule.Output("combined/device_import_module.jar")
+ deviceImportModule := ctx.ModuleForTests(t, "device_import_module", "android_common")
+ deviceImportCombined := deviceImportModule.Output("local-combined/device_import_module.jar")
- hostModule := ctx.ModuleForTests("host_module", config.BuildOSCommonTarget.String())
+ hostModule := ctx.ModuleForTests(t, "host_module", config.BuildOSCommonTarget.String())
hostJavac := hostModule.Output("javac/host_module.jar")
hostRes := hostModule.Output("res/host_module.jar")
combined := hostModule.Output("combined/host_module.jar")
@@ -68,7 +70,7 @@
// check classpath of host module with dependency on device_for_host_module
expectedClasspath := "-classpath " + strings.Join(android.Paths{
- deviceTurbineCombined.Output,
+ deviceTurbine.Output,
deviceImportCombined.Output,
}.Strings(), ":")
@@ -102,6 +104,7 @@
}
func TestHostForDevice(t *testing.T) {
+ t.Parallel()
bp := `
java_library_host {
name: "host_module",
@@ -133,15 +136,15 @@
ctx, config := testJava(t, bp)
- hostModule := ctx.ModuleForTests("host_module", config.BuildOSCommonTarget.String())
+ hostModule := ctx.ModuleForTests(t, "host_module", config.BuildOSCommonTarget.String())
hostJavac := hostModule.Output("javac/host_module.jar")
- hostJavacHeader := hostModule.Output("javac-header/host_module.jar")
+ hostJavacHeader := hostModule.Output("local-javac-header/host_module.jar")
hostRes := hostModule.Output("res/host_module.jar")
- hostImportModule := ctx.ModuleForTests("host_import_module", config.BuildOSCommonTarget.String())
- hostImportCombined := hostImportModule.Output("combined/host_import_module.jar")
+ hostImportModule := ctx.ModuleForTests(t, "host_import_module", config.BuildOSCommonTarget.String())
+ hostImportCombined := hostImportModule.Output("local-combined/host_import_module.jar")
- deviceModule := ctx.ModuleForTests("device_module", "android_common")
+ deviceModule := ctx.ModuleForTests(t, "device_module", "android_common")
deviceJavac := deviceModule.Output("javac/device_module.jar")
deviceRes := deviceModule.Output("res/device_module.jar")
combined := deviceModule.Output("combined/device_module.jar")
diff --git a/java/dex.go b/java/dex.go
index 7b99549..ed2df21 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -49,10 +49,28 @@
// Whether to continue building even if warnings are emitted. Defaults to true.
Ignore_warnings *bool
+ // Whether runtime invisible annotations should be kept by R8. Defaults to false.
+ // This is equivalent to:
+ // -keepattributes RuntimeInvisibleAnnotations,
+ // RuntimeInvisibleParameterAnnotations,
+ // RuntimeInvisibleTypeAnnotations
+ // This is only applicable when RELEASE_R8_ONLY_RUNTIME_VISIBLE_ANNOTATIONS is
+ // enabled and will be used to migrate away from keeping runtime invisible
+ // annotations (b/387958004).
+ Keep_runtime_invisible_annotations *bool
+
// If true, runs R8 in Proguard compatibility mode, otherwise runs R8 in full mode.
// Defaults to false for apps and tests, true for libraries.
Proguard_compatibility *bool
+ // If true, R8 will not add public or protected members (fields or methods) to
+ // the API surface of the compilation unit, i.e., classes that are kept or
+ // have kept subclasses will not expose any members added by R8 for internal
+ // use. That includes renamed members if obfuscation is enabled.
+ // This should only be used for building targets that go on the bootclasspath.
+ // Defaults to false.
+ Protect_api_surface *bool
+
// If true, optimize for size by removing unused code. Defaults to true for apps,
// false for libraries and tests.
Shrink *bool
@@ -160,6 +178,71 @@
},
}, []string{"outDir", "d8Flags", "zipFlags", "mergeZipsFlags"}, nil)
+// Include all of the args for d8r8, so that we can generate the partialcompileclean target's build using the same list.
+var d8r8Clean = pctx.AndroidStaticRule("d8r8-partialcompileclean",
+ blueprint.RuleParams{
+ Command: `rm -rf "${outDir}" "${outDict}" "${outConfig}" "${outUsage}" "${outUsageZip}" "${outUsageDir}" ` +
+ `"${resourcesOutput}" "${outR8ArtProfile}" ${builtOut}`,
+ }, "outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir", "builtOut",
+ "d8Flags", "r8Flags", "zipFlags", "mergeZipsFlags", "resourcesOutput", "outR8ArtProfile", "implicits",
+)
+
+var d8r8, d8r8RE = pctx.MultiCommandRemoteStaticRules("d8r8",
+ blueprint.RuleParams{
+ Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
+ `rm -f "$outDict" && rm -f "$outConfig" && rm -rf "${outUsageDir}" && ` +
+ `mkdir -p $$(dirname ${outUsage}) && ` +
+ `if [ -n "$${SOONG_USE_PARTIAL_COMPILE}" ]; then ` +
+ ` for f in "${outConfig}" "${outDict}" "${outUsage}" "${resourcesOutput}"; do ` +
+ ` test -n "$${f}" && test ! -f "$${f}" && mkdir -p "$$(dirname "$${f}")" && touch "$${f}" || true; ` +
+ ` done && ` +
+ ` $d8Template${config.D8Cmd} ${config.D8Flags} $d8Flags --output $outDir --no-dex-input-jar $in; ` +
+ `else ` +
+ ` $r8Template${config.R8Cmd} ${config.R8Flags} $r8Flags -injars $in --output $outDir ` +
+ ` --no-data-resources ` +
+ ` -printmapping ${outDict} ` +
+ ` -printconfiguration ${outConfig} ` +
+ ` -printusage ${outUsage} ` +
+ ` --deps-file ${out}.d && ` +
+ ` touch "${outDict}" "${outConfig}" "${outUsage}"; ` +
+ `fi && ` +
+ `${config.SoongZipCmd} -o ${outUsageZip} -C ${outUsageDir} -f ${outUsage} && ` +
+ `rm -rf ${outUsageDir} && ` +
+ `$zipTemplate${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
+ `${config.MergeZipsCmd} -D -stripFile "**/*.class" $mergeZipsFlags $out $outDir/classes.dex.jar $in && ` +
+ `rm -f "$outDir"/classes*.dex "$outDir/classes.dex.jar" `,
+ CommandDeps: []string{
+ "${config.D8Cmd}",
+ "${config.R8Cmd}",
+ "${config.SoongZipCmd}",
+ "${config.MergeZipsCmd}",
+ },
+ }, map[string]*remoteexec.REParams{
+ "$d8Template": &remoteexec.REParams{
+ Labels: map[string]string{"type": "compile", "compiler": "d8"},
+ Inputs: []string{"${config.D8Jar}"},
+ ExecStrategy: "${config.RED8ExecStrategy}",
+ ToolchainInputs: []string{"${config.JavaCmd}"},
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
+ "$r8Template": &remoteexec.REParams{
+ Labels: map[string]string{"type": "compile", "compiler": "r8"},
+ Inputs: []string{"$implicits", "${config.R8Jar}"},
+ OutputFiles: []string{"${outUsage}", "${outConfig}", "${outDict}", "${resourcesOutput}", "${outR8ArtProfile}"},
+ ExecStrategy: "${config.RER8ExecStrategy}",
+ ToolchainInputs: []string{"${config.JavaCmd}"},
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
+ "$zipTemplate": &remoteexec.REParams{
+ Labels: map[string]string{"type": "tool", "name": "soong_zip"},
+ Inputs: []string{"${config.SoongZipCmd}", "$outDir"},
+ OutputFiles: []string{"$outDir/classes.dex.jar"},
+ ExecStrategy: "${config.RED8ExecStrategy}",
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
+ }, []string{"outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir",
+ "d8Flags", "r8Flags", "zipFlags", "mergeZipsFlags", "resourcesOutput", "outR8ArtProfile"}, []string{"implicits"})
+
var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8",
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
@@ -224,21 +307,29 @@
deps = append(deps, f)
}
- var requestReleaseMode bool
+ var requestReleaseMode, requestDebugMode bool
requestReleaseMode, flags = android.RemoveFromList("--release", flags)
+ requestDebugMode, flags = android.RemoveFromList("--debug", flags)
if ctx.Config().Getenv("NO_OPTIMIZE_DX") != "" || ctx.Config().Getenv("GENERATE_DEX_DEBUG") != "" {
- flags = append(flags, "--debug")
+ requestDebugMode = true
requestReleaseMode = false
}
// Don't strip out debug information for eng builds, unless the target
// explicitly provided the `--release` build flag. This allows certain
// test targets to remain optimized as part of eng test_suites builds.
- if requestReleaseMode {
+ if requestDebugMode {
+ flags = append(flags, "--debug")
+ } else if requestReleaseMode {
flags = append(flags, "--release")
} else if ctx.Config().Eng() {
flags = append(flags, "--debug")
+ } else if !d.effectiveOptimizeEnabled() && d.dexProperties.Optimize.EnabledByDefault {
+ // D8 uses --debug by default, whereas R8 uses --release by default.
+ // For targets that default to R8 usage (e.g., apps), but override this default, we still
+ // want D8 to run in release mode, preserving semantics as much as possible between the two.
+ flags = append(flags, "--release")
}
// Supplying the platform build flag disables various features like API modeling and desugaring.
@@ -310,7 +401,7 @@
// TODO(b/360905238): Remove SdkSystemServer exception after resolving missing class references.
if !dexParams.sdkVersion.Stable() || dexParams.sdkVersion.Kind == android.SdkSystemServer {
var proguardRaiseDeps classpath
- ctx.VisitDirectDepsWithTag(proguardRaiseTag, func(m android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(proguardRaiseTag, func(m android.ModuleProxy) {
if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
proguardRaiseDeps = append(proguardRaiseDeps, dep.RepackagedHeaderJars...)
}
@@ -344,6 +435,11 @@
android.PathForSource(ctx, "build/make/core/proguard.flags"),
}
+ if ctx.Config().UseR8GlobalCheckNotNullFlags() {
+ flagFiles = append(flagFiles, android.PathForSource(ctx,
+ "build/make/core/proguard/checknotnull.flags"))
+ }
+
flagFiles = append(flagFiles, d.extraProguardFlagsFiles...)
// TODO(ccross): static android library proguard files
@@ -364,10 +460,18 @@
r8Flags = append(r8Flags, "--ignore-library-extends-program")
}
- if BoolDefault(opt.Proguard_compatibility, true) {
+ if BoolDefault(opt.Keep_runtime_invisible_annotations, false) {
+ r8Flags = append(r8Flags, "--keep-runtime-invisible-annotations")
+ }
+
+ if BoolDefault(opt.Proguard_compatibility, !ctx.Config().UseR8FullModeByDefault()) {
r8Flags = append(r8Flags, "--force-proguard-compatibility")
}
+ if BoolDefault(opt.Protect_api_surface, false) {
+ r8Flags = append(r8Flags, "--protect-api-surface")
+ }
+
// Avoid unnecessary stack frame noise by only injecting source map ids for non-debug
// optimized or obfuscated targets.
if (Bool(opt.Optimize) || Bool(opt.Obfuscate)) && !debugMode {
@@ -460,6 +564,7 @@
// Compile classes.jar into classes.dex and then javalib.jar
javalibJar := android.PathForModuleOut(ctx, "dex", dexParams.jarName).OutputPath
+ cleanPhonyPath := android.PathForModuleOut(ctx, "dex", dexParams.jarName+"-partialcompileclean").OutputPath
outDir := android.PathForModuleOut(ctx, "dex")
zipFlags := "--ignore_missing_files"
@@ -476,7 +581,19 @@
}
useR8 := d.effectiveOptimizeEnabled()
+ useD8 := !useR8 || ctx.Config().PartialCompileFlags().Use_d8
+ rbeR8 := ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_R8")
+ rbeD8 := ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_D8")
+ var rule blueprint.Rule
+ var description string
var artProfileOutputPath *android.OutputPath
+ var implicitOutputs android.WritablePaths
+ var deps android.Paths
+ args := map[string]string{
+ "zipFlags": zipFlags,
+ "outDir": outDir.String(),
+ "mergeZipsFlags": mergeZipsFlags,
+ }
if useR8 {
proguardDictionary := android.PathForModuleOut(ctx, "proguard_dictionary")
d.proguardDictionary = android.OptionalPathForPath(proguardDictionary)
@@ -489,83 +606,89 @@
d.proguardUsageZip = android.OptionalPathForPath(proguardUsageZip)
resourcesOutput := android.PathForModuleOut(ctx, "package-res-shrunken.apk")
d.resourcesOutput = android.OptionalPathForPath(resourcesOutput)
- implicitOutputs := android.WritablePaths{
+ implicitOutputs = append(implicitOutputs, android.WritablePaths{
proguardDictionary,
proguardUsageZip,
proguardConfiguration,
- }
+ }...)
+ description = "r8"
debugMode := android.InList("--debug", commonFlags)
r8Flags, r8Deps, r8ArtProfileOutputPath := d.r8Flags(ctx, dexParams, debugMode)
- rule := r8
- args := map[string]string{
- "r8Flags": strings.Join(append(commonFlags, r8Flags...), " "),
- "zipFlags": zipFlags,
- "outDict": proguardDictionary.String(),
- "outConfig": proguardConfiguration.String(),
- "outUsageDir": proguardUsageDir.String(),
- "outUsage": proguardUsage.String(),
- "outUsageZip": proguardUsageZip.String(),
- "outDir": outDir.String(),
- "mergeZipsFlags": mergeZipsFlags,
- }
+ deps = append(deps, r8Deps...)
+ args["r8Flags"] = strings.Join(append(commonFlags, r8Flags...), " ")
if r8ArtProfileOutputPath != nil {
artProfileOutputPath = r8ArtProfileOutputPath
- implicitOutputs = append(
- implicitOutputs,
- artProfileOutputPath,
- )
// Add the implicit r8 Art profile output to args so that r8RE knows
// about this implicit output
- args["outR8ArtProfile"] = artProfileOutputPath.String()
+ args["outR8ArtProfile"] = r8ArtProfileOutputPath.String()
}
-
- if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_R8") {
- rule = r8RE
- args["implicits"] = strings.Join(r8Deps.Strings(), ",")
- }
+ args["outDict"] = proguardDictionary.String()
+ args["outConfig"] = proguardConfiguration.String()
+ args["outUsageDir"] = proguardUsageDir.String()
+ args["outUsage"] = proguardUsage.String()
+ args["outUsageZip"] = proguardUsageZip.String()
if d.resourcesInput.Valid() {
implicitOutputs = append(implicitOutputs, resourcesOutput)
args["resourcesOutput"] = resourcesOutput.String()
}
- ctx.Build(pctx, android.BuildParams{
- Rule: rule,
- Description: "r8",
- Output: javalibJar,
- ImplicitOutputs: implicitOutputs,
- Input: dexParams.classesJar,
- Implicits: r8Deps,
- Args: args,
- })
- } else {
- implicitOutputs := android.WritablePaths{}
+
+ rule = r8
+ if rbeR8 {
+ rule = r8RE
+ args["implicits"] = strings.Join(deps.Strings(), ",")
+ }
+ }
+ if useD8 {
+ description = "d8"
d8Flags, d8Deps, d8ArtProfileOutputPath := d.d8Flags(ctx, dexParams)
+ deps = append(deps, d8Deps...)
+ deps = append(deps, commonDeps...)
+ args["d8Flags"] = strings.Join(append(commonFlags, d8Flags...), " ")
if d8ArtProfileOutputPath != nil {
artProfileOutputPath = d8ArtProfileOutputPath
- implicitOutputs = append(
- implicitOutputs,
- artProfileOutputPath,
- )
}
- d8Deps = append(d8Deps, commonDeps...)
- rule := d8
- if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_D8") {
+ // If we are generating both d8 and r8, only use RBE when both are enabled.
+ switch {
+ case useR8 && rule == r8:
+ rule = d8r8
+ description = "d8r8"
+ case useR8 && rule == r8RE && rbeD8:
+ rule = d8r8RE
+ description = "d8r8"
+ case rbeD8:
rule = d8RE
+ default:
+ rule = d8
}
- ctx.Build(pctx, android.BuildParams{
- Rule: rule,
- Description: "d8",
- Output: javalibJar,
- Input: dexParams.classesJar,
- ImplicitOutputs: implicitOutputs,
- Implicits: d8Deps,
- Args: map[string]string{
- "d8Flags": strings.Join(append(commonFlags, d8Flags...), " "),
- "zipFlags": zipFlags,
- "outDir": outDir.String(),
- "mergeZipsFlags": mergeZipsFlags,
- },
- })
}
+ if artProfileOutputPath != nil {
+ implicitOutputs = append(
+ implicitOutputs,
+ artProfileOutputPath,
+ )
+ }
+ ctx.Build(pctx, android.BuildParams{
+ Rule: rule,
+ Description: description,
+ Output: javalibJar,
+ ImplicitOutputs: implicitOutputs,
+ Input: dexParams.classesJar,
+ Implicits: deps,
+ Args: args,
+ })
+ if useR8 && useD8 {
+ // Generate the rule for partial compile clean.
+ args["builtOut"] = javalibJar.String()
+ ctx.Build(pctx, android.BuildParams{
+ Rule: d8r8Clean,
+ Description: "d8r8Clean",
+ Output: cleanPhonyPath,
+ Args: args,
+ PhonyOutput: true,
+ })
+ ctx.Phony("partialcompileclean", cleanPhonyPath)
+ }
+
if proptools.Bool(d.dexProperties.Uncompress_dex) {
alignedJavalibJar := android.PathForModuleOut(ctx, "aligned", dexParams.jarName).OutputPath
TransformZipAlign(ctx, alignedJavalibJar, javalibJar, nil)
@@ -574,3 +697,13 @@
return javalibJar, artProfileOutputPath
}
+
+type ProguardInfo struct {
+ ModuleName string
+ Class string
+ ProguardDictionary android.Path
+ ProguardUsageZip android.Path
+ ClassesJar android.Path
+}
+
+var ProguardProvider = blueprint.NewProvider[ProguardInfo]()
diff --git a/java/dex_test.go b/java/dex_test.go
index 8bc28e6..66d801d 100644
--- a/java/dex_test.go
+++ b/java/dex_test.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "strconv"
"testing"
"android/soong/android"
@@ -24,6 +25,7 @@
)
func TestR8(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
android_app {
name: "app",
@@ -58,26 +60,27 @@
}
`)
- app := result.ModuleForTests("app", "android_common")
- stableApp := result.ModuleForTests("stable_app", "android_common")
- corePlatformApp := result.ModuleForTests("core_platform_app", "android_common")
- lib := result.ModuleForTests("lib", "android_common")
- staticLib := result.ModuleForTests("static_lib", "android_common")
+ app := result.ModuleForTests(t, "app", "android_common")
+ stableApp := result.ModuleForTests(t, "stable_app", "android_common")
+ corePlatformApp := result.ModuleForTests(t, "core_platform_app", "android_common")
+ lib := result.ModuleForTests(t, "lib", "android_common")
+ staticLib := result.ModuleForTests(t, "static_lib", "android_common")
appJavac := app.Rule("javac")
appR8 := app.Rule("r8")
stableAppR8 := stableApp.Rule("r8")
corePlatformAppR8 := corePlatformApp.Rule("r8")
- libHeader := lib.Output("turbine-combined/lib.jar").Output
- staticLibHeader := staticLib.Output("turbine-combined/static_lib.jar").Output
+ libHeader := lib.Output("turbine/lib.jar").Output
+ libCombinedHeader := lib.Output("turbine-combined/lib.jar").Output
+ staticLibHeader := staticLib.Output("turbine/static_lib.jar").Output
android.AssertStringDoesContain(t, "expected lib header jar in app javac classpath",
appJavac.Args["classpath"], libHeader.String())
android.AssertStringDoesContain(t, "expected static_lib header jar in app javac classpath",
appJavac.Args["classpath"], staticLibHeader.String())
- android.AssertStringDoesContain(t, "expected lib header jar in app r8 classpath",
- appR8.Args["r8Flags"], libHeader.String())
+ android.AssertStringDoesContain(t, "expected lib combined header jar in app r8 classpath",
+ appR8.Args["r8Flags"], libCombinedHeader.String())
android.AssertStringDoesNotContain(t, "expected no static_lib header jar in app r8 classpath",
appR8.Args["r8Flags"], staticLibHeader.String())
android.AssertStringDoesContain(t, "expected -ignorewarnings in app r8 flags",
@@ -91,6 +94,7 @@
}
func TestR8TransitiveDeps(t *testing.T) {
+ t.Parallel()
bp := `
override_android_app {
name: "override_app",
@@ -192,6 +196,7 @@
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
fixturePreparer := PrepareForTestWithJavaDefaultModules
if tc.unbundled {
fixturePreparer = android.GroupFixturePreparers(
@@ -206,14 +211,14 @@
result := fixturePreparer.RunTestWithBp(t, bp)
getHeaderJar := func(name string) android.Path {
- mod := result.ModuleForTests(name, "android_common")
+ mod := result.ModuleForTests(t, name, "android_common")
return mod.Output("turbine-combined/" + name + ".jar").Output
}
- appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
- overrideAppR8 := result.ModuleForTests("app", "android_common_override_app").Rule("r8")
+ appR8 := result.ModuleForTests(t, "app", "android_common").Rule("r8")
+ overrideAppR8 := result.ModuleForTests(t, "app", "android_common_override_app").Rule("r8")
appHeader := getHeaderJar("app")
- overrideAppHeader := result.ModuleForTests("app", "android_common_override_app").Output("turbine-combined/app.jar").Output
+ overrideAppHeader := result.ModuleForTests(t, "app", "android_common_override_app").Output("turbine-combined/app.jar").Output
libHeader := getHeaderJar("lib")
transitiveLibHeader := getHeaderJar("transitive_lib")
transitiveLib2Header := getHeaderJar("transitive_lib_2")
@@ -222,7 +227,7 @@
repeatedDepHeader := getHeaderJar("repeated_dep")
usesLibHeader := getHeaderJar("uses_lib")
optionalUsesLibHeader := getHeaderJar("optional_uses_lib")
- prebuiltLibHeader := result.ModuleForTests("prebuilt_lib", "android_common").Output("combined/lib.jar").Output
+ prebuiltLibHeader := result.ModuleForTests(t, "prebuilt_lib", "android_common").Output("combined/lib.jar").Output
for _, rule := range []android.TestingBuildParams{appR8, overrideAppR8} {
android.AssertStringDoesNotContain(t, "expected no app header jar in app r8 classpath",
@@ -259,6 +264,7 @@
}
func TestR8Flags(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
android_app {
name: "app",
@@ -273,7 +279,7 @@
}
`)
- app := result.ModuleForTests("app", "android_common")
+ app := result.ModuleForTests(t, "app", "android_common")
appR8 := app.Rule("r8")
android.AssertStringDoesContain(t, "expected -dontshrink in app r8 flags",
appR8.Args["r8Flags"], "-dontshrink")
@@ -288,6 +294,7 @@
}
func TestD8(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
java_library {
name: "foo",
@@ -306,29 +313,52 @@
name: "static_lib",
srcs: ["foo.java"],
}
+
+ android_app {
+ name: "app",
+ srcs: ["foo.java"],
+ platform_apis: true,
+ optimize: {
+ enabled: false,
+ },
+ }
`)
- foo := result.ModuleForTests("foo", "android_common")
- lib := result.ModuleForTests("lib", "android_common")
- staticLib := result.ModuleForTests("static_lib", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
+ lib := result.ModuleForTests(t, "lib", "android_common")
+ app := result.ModuleForTests(t, "app", "android_common")
+ staticLib := result.ModuleForTests(t, "static_lib", "android_common")
fooJavac := foo.Rule("javac")
fooD8 := foo.Rule("d8")
- libHeader := lib.Output("turbine-combined/lib.jar").Output
- staticLibHeader := staticLib.Output("turbine-combined/static_lib.jar").Output
+ appD8 := app.Rule("d8")
+ libHeader := lib.Output("turbine/lib.jar").Output
+ libCombinedHeader := lib.Output("turbine-combined/lib.jar").Output
+ staticLibHeader := staticLib.Output("turbine/static_lib.jar").Output
android.AssertStringDoesContain(t, "expected lib header jar in foo javac classpath",
fooJavac.Args["classpath"], libHeader.String())
android.AssertStringDoesContain(t, "expected static_lib header jar in foo javac classpath",
fooJavac.Args["classpath"], staticLibHeader.String())
- android.AssertStringDoesContain(t, "expected lib header jar in foo d8 classpath",
- fooD8.Args["d8Flags"], libHeader.String())
+ android.AssertStringDoesContain(t, "expected lib combined header jar in foo d8 classpath",
+ fooD8.Args["d8Flags"], libCombinedHeader.String())
android.AssertStringDoesNotContain(t, "expected no static_lib header jar in foo javac classpath",
fooD8.Args["d8Flags"], staticLibHeader.String())
+
+ // A --release flag is added only for targets that opt out of default R8 behavior (e.g., apps).
+ // For library targets that don't use R8 by default, no --debug or --release flag should be
+ // added, instead relying on default D8 behavior (--debug).
+ android.AssertStringDoesContain(t, "expected --release in app d8 flags",
+ appD8.Args["d8Flags"], "--release")
+ android.AssertStringDoesNotContain(t, "expected no --release flag in lib d8 flags",
+ fooD8.Args["d8Flags"], "--release")
+ android.AssertStringDoesNotContain(t, "expected no --debug flag in lib d8 flags",
+ fooD8.Args["d8Flags"], "--debug")
}
func TestProguardFlagsInheritanceStatic(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
android_app {
name: "app",
@@ -370,7 +400,7 @@
}
`)
- app := result.ModuleForTests("app", "android_common")
+ app := result.ModuleForTests(t, "app", "android_common")
appR8 := app.Rule("r8")
android.AssertStringDoesContain(t, "expected primary_lib's proguard flags from direct dep",
appR8.Args["r8Flags"], "primary.flags")
@@ -383,6 +413,7 @@
}
func TestProguardFlagsInheritance(t *testing.T) {
+ t.Parallel()
directDepFlagsFileName := "direct_dep.flags"
transitiveDepFlagsFileName := "transitive_dep.flags"
@@ -601,6 +632,7 @@
for _, topLevelModuleDef := range topLevelModules {
for _, tc := range testcases {
t.Run(topLevelModuleDef.name+"-"+tc.name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.FixtureMergeMockFs(android.MockFS{
@@ -617,7 +649,7 @@
tc.transitiveDepExportsFlagsFiles,
),
)
- appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
+ appR8 := result.ModuleForTests(t, "app", "android_common").Rule("r8")
shouldHaveDepFlags := android.InList(directDepFlagsFileName, tc.expectedFlagsFiles)
if shouldHaveDepFlags {
@@ -642,6 +674,7 @@
}
func TestProguardFlagsInheritanceAppImport(t *testing.T) {
+ t.Parallel()
bp := `
android_app {
name: "app",
@@ -658,12 +691,13 @@
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, bp)
- appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
+ appR8 := result.ModuleForTests(t, "app", "android_common").Rule("r8")
android.AssertStringDoesContain(t, "expected aarimports's proguard flags",
appR8.Args["r8Flags"], "proguard.txt")
}
func TestR8FlagsArtProfile(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
android_app {
name: "app",
@@ -677,7 +711,7 @@
}
`)
- app := result.ModuleForTests("app", "android_common")
+ app := result.ModuleForTests(t, "app", "android_common")
appR8 := app.Rule("r8")
android.AssertStringDoesContain(t, "expected --art-profile in app r8 flags",
appR8.Args["r8Flags"], "--art-profile")
@@ -696,6 +730,7 @@
//
// The rewritten profile should be used since the dex signatures in the checked-in profile will not match the optimized binary.
func TestEnableProfileRewritingIsRequiredForOptimizedApps(t *testing.T) {
+ t.Parallel()
testJavaError(t,
"Enable_profile_rewriting must be true when profile_guided dexpreopt and R8 optimization/obfuscation is turned on",
`
@@ -715,11 +750,15 @@
}
func TestDebugReleaseFlags(t *testing.T) {
+ t.Parallel()
bp := `
android_app {
name: "app",
srcs: ["foo.java"],
platform_apis: true,
+ optimize: {
+ enabled: %s,
+ },
dxflags: ["%s"]
}
`
@@ -728,6 +767,7 @@
name string
envVar string
isEng bool
+ useD8 bool
dxFlags string
expectedFlags string
}{
@@ -767,10 +807,24 @@
// Eng mode does *not* override explicit dxflags.
expectedFlags: "--release",
},
+ {
+ name: "app_d8",
+ useD8: true,
+ // D8 usage w/ apps should explicitly enable --release mode.
+ expectedFlags: "--release",
+ },
+ {
+ name: "app_d8_debug",
+ useD8: true,
+ dxFlags: "--debug",
+ // D8 usage w/ apps respects overriding dxFlags.
+ expectedFlags: "--debug",
+ },
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
fixturePreparer := PrepareForTestWithJavaDefaultModules
fixturePreparer = android.GroupFixturePreparers(
fixturePreparer,
@@ -788,11 +842,16 @@
}),
)
}
- result := fixturePreparer.RunTestWithBp(t, fmt.Sprintf(bp, tc.dxFlags))
+ result := fixturePreparer.RunTestWithBp(t, fmt.Sprintf(bp, strconv.FormatBool(!tc.useD8), tc.dxFlags))
- appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
- android.AssertStringDoesContain(t, "expected flag in R8 flags",
- appR8.Args["r8Flags"], tc.expectedFlags)
+ dexRuleKey := "r8"
+ if tc.useD8 {
+ dexRuleKey = "d8"
+ }
+ dexFlagsKey := dexRuleKey + "Flags"
+ appDex := result.ModuleForTests(t, "app", "android_common").Rule(dexRuleKey)
+ android.AssertStringDoesContain(t, "expected flag in dex flags",
+ appDex.Args[dexFlagsKey], tc.expectedFlags)
var unexpectedFlags string
if tc.expectedFlags == "--debug" {
@@ -801,8 +860,8 @@
unexpectedFlags = "--debug"
}
if unexpectedFlags != "" {
- android.AssertStringDoesNotContain(t, "unexpected flag in R8 flags",
- appR8.Args["r8Flags"], unexpectedFlags)
+ android.AssertStringDoesNotContain(t, "unexpected flag in dex flags",
+ appDex.Args[dexFlagsKey], unexpectedFlags)
}
})
}
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 44ba80a..b21cfc9 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -36,61 +36,24 @@
// If the java module is to be installed into an APEX, this list contains information about the
// dexpreopt outputs to be installed on devices. Note that these dexpreopt outputs are installed
// outside of the APEX.
- DexpreoptBuiltInstalledForApex() []dexpreopterInstall
+ ApexSystemServerDexpreoptInstalls() []DexpreopterInstall
- // The Make entries to install the dexpreopt outputs. Derived from
- // `DexpreoptBuiltInstalledForApex`.
- AndroidMkEntriesForApex() []android.AndroidMkEntries
+ // ApexSystemServerDexJars returns the list of dex jars if this is an apex system server jar.
+ ApexSystemServerDexJars() android.Paths
// See `dexpreopter.outputProfilePathOnHost`.
OutputProfilePathOnHost() android.Path
}
-type dexpreopterInstall struct {
- // A unique name to distinguish an output from others for the same java library module. Usually in
- // the form of `<arch>-<encoded-path>.odex/vdex/art`.
- name string
-
- // The name of the input java module.
- moduleName string
-
+type DexpreopterInstall struct {
// The path to the dexpreopt output on host.
- outputPathOnHost android.Path
+ OutputPathOnHost android.Path
// The directory on the device for the output to install to.
- installDirOnDevice android.InstallPath
+ InstallDirOnDevice android.InstallPath
// The basename (the last segment of the path) for the output to install as.
- installFileOnDevice string
-}
-
-// The full module name of the output in the makefile.
-func (install *dexpreopterInstall) FullModuleName() string {
- return install.moduleName + install.SubModuleName()
-}
-
-// The sub-module name of the output in the makefile (the name excluding the java module name).
-func (install *dexpreopterInstall) SubModuleName() string {
- return "-dexpreopt-" + install.name
-}
-
-// Returns Make entries for installing the file.
-//
-// This function uses a value receiver rather than a pointer receiver to ensure that the object is
-// safe to use in `android.AndroidMkExtraEntriesFunc`.
-func (install dexpreopterInstall) ToMakeEntries() android.AndroidMkEntries {
- return android.AndroidMkEntries{
- Class: "ETC",
- OutputFile: android.OptionalPathForPath(install.outputPathOnHost),
- ExtraEntries: []android.AndroidMkExtraEntriesFunc{
- func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE", install.FullModuleName())
- entries.SetString("LOCAL_MODULE_PATH", install.installDirOnDevice.String())
- entries.SetString("LOCAL_INSTALLED_MODULE_STEM", install.installFileOnDevice)
- entries.SetString("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", "false")
- },
- },
- }
+ InstallFileOnDevice string
}
type Dexpreopter struct {
@@ -120,8 +83,9 @@
classLoaderContexts dexpreopt.ClassLoaderContextMap
// See the `dexpreopt` function for details.
- builtInstalled string
- builtInstalledForApex []dexpreopterInstall
+ builtInstalled string
+ apexSystemServerDexpreoptInstalls []DexpreopterInstall
+ apexSystemServerDexJars android.Paths
// The config is used for two purposes:
// - Passing dexpreopt information about libraries from Soong to Make. This is needed when
@@ -204,7 +168,7 @@
}
apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
psi := android.PrebuiltSelectionInfoMap{}
- ctx.VisitDirectDeps(func(am android.Module) {
+ ctx.VisitDirectDepsProxy(func(am android.ModuleProxy) {
if prebuiltSelectionInfo, ok := android.OtherModuleProvider(ctx, am, android.PrebuiltSelectionInfoProvider); ok {
psi = prebuiltSelectionInfo
}
@@ -213,10 +177,7 @@
// Find the apex variant for this module
apexVariants := []string{}
if apexInfo.BaseApexName != "" {
- // This is a transitive dependency of an override_apex
apexVariants = append(apexVariants, apexInfo.BaseApexName)
- } else {
- apexVariants = append(apexVariants, apexInfo.InApexVariants...)
}
if apexInfo.ApexAvailableName != "" {
apexVariants = append(apexVariants, apexInfo.ApexAvailableName)
@@ -278,20 +239,6 @@
if !isApexSystemServerJar {
return true
}
- ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
- allApexInfos := []android.ApexInfo{}
- if allApexInfosProvider, ok := android.ModuleProvider(ctx, android.AllApexInfoProvider); ok {
- allApexInfos = allApexInfosProvider.ApexInfos
- }
- if len(allApexInfos) > 0 && !ai.MinSdkVersion.EqualTo(allApexInfos[0].MinSdkVersion) {
- // Apex system server jars are dexpreopted and installed on to the system image.
- // Since we can have BigAndroid and Go variants of system server jar providing apexes,
- // and these two variants can have different min_sdk_versions, hide one of the apex variants
- // from make to prevent collisions.
- //
- // Unlike cc, min_sdk_version does not have an effect on the build actions of java libraries.
- ctx.Module().MakeUninstallable()
- }
} else {
// Don't preopt the platform variant of an APEX system server jar to avoid conflicts.
if isApexSystemServerJar {
@@ -346,7 +293,11 @@
d.installPath = android.PathForModuleInPartitionInstall(ctx, "", strings.TrimPrefix(dexpreopt.GetSystemServerDexLocation(ctx, dc, libraryName), "/"))
// generate the rules for creating the .odex and .vdex files for this system server jar
dexJarFile := di.PrebuiltExportPath(ApexRootRelativePathToJavaLib(libraryName))
-
+ if dexJarFile == nil {
+ ctx.ModuleErrorf(
+ `Could not find library %s in prebuilt apex %s.
+Please make sure that the value of PRODUCT_APEX_(SYSTEM_SERVER|STANDALONE_SYSTEM_SERVER)_JARS is correct`, libraryName, ctx.ModuleName())
+ }
d.inputProfilePathOnHost = nil // reset: TODO(spandandas): Make dexpreopter stateless
if android.InList(libraryName, di.GetDexpreoptProfileGuidedExportedModuleNames()) {
// Set the profile path to guide optimization
@@ -538,12 +489,8 @@
Output(appProductPackages)
productPackagesRule.Restat().Build("product_packages."+dexJarStem, "dexpreopt product_packages")
- // Prebuilts are active, do not copy the dexpreopt'd source javalib to out/soong/system_server_dexjars
- // The javalib from the deapexed prebuilt will be copied to this location.
- // TODO (b/331665856): Implement a principled solution for this.
- copyApexSystemServerJarDex := !disableSourceApexVariant(ctx) && !ctx.Module().IsHideFromMake()
dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(
- ctx, globalSoong, global, dexpreoptConfig, appProductPackages, copyApexSystemServerJarDex)
+ ctx, globalSoong, global, dexpreoptConfig, appProductPackages)
if err != nil {
ctx.ModuleErrorf("error generating dexpreopt rule: %s", err.Error())
return
@@ -576,7 +523,6 @@
partition = ""
}
installBase := filepath.Base(install.To)
- arch := filepath.Base(installDir)
installPath := android.PathForModuleInPartitionInstall(ctx, partition, installDir)
isProfile := strings.HasSuffix(installBase, ".prof")
@@ -592,16 +538,13 @@
// libraries, only those in the system server classpath are handled here.
// Preopting of boot classpath jars in the ART APEX are handled in
// java/dexpreopt_bootjars.go, and other APEX jars are not preopted.
- // The installs will be handled by Make as sub-modules of the java library.
- di := dexpreopterInstall{
- name: arch + "-" + installBase,
- moduleName: libName,
- outputPathOnHost: install.From,
- installDirOnDevice: installPath,
- installFileOnDevice: installBase,
+ // The installs will be handled the apex module that includes this library.
+ di := DexpreopterInstall{
+ OutputPathOnHost: install.From,
+ InstallDirOnDevice: installPath,
+ InstallFileOnDevice: installBase,
}
- ctx.InstallFile(di.installDirOnDevice, di.installFileOnDevice, di.outputPathOnHost)
- d.builtInstalledForApex = append(d.builtInstalledForApex, di)
+ d.apexSystemServerDexpreoptInstalls = append(d.apexSystemServerDexpreoptInstalls, di)
}
} else if !d.preventInstall {
@@ -610,9 +553,22 @@
}
}
+ if isApexSystemServerJar {
+ // Store the dex jar location for system server jars in apexes, the apex will copy the file into
+ // a known location for dex2oat.
+ d.apexSystemServerDexJars = append(d.apexSystemServerDexJars, dexJarFile)
+ } else if isSystemServerJar && !d.preventInstall {
+ // Copy the dex jar into a known location for dex2oat for non-apex system server jars.
+ android.CopyFileRule(ctx, dexJarFile, android.PathForOutput(ctx, dexpreopt.SystemServerDexjarsDir, dexJarFile.Base()))
+ }
+
if !isApexSystemServerJar {
d.builtInstalled = dexpreoptRule.Installs().String()
}
+
+ if isSystemServerJar {
+ checkSystemServerOrder(ctx, libName)
+ }
}
func getModuleInstallPathInfo(ctx android.ModuleContext, fullInstallPath string) (android.InstallPath, string, string) {
@@ -644,16 +600,12 @@
}
}
-func (d *dexpreopter) DexpreoptBuiltInstalledForApex() []dexpreopterInstall {
- return d.builtInstalledForApex
+func (d *dexpreopter) ApexSystemServerDexpreoptInstalls() []DexpreopterInstall {
+ return d.apexSystemServerDexpreoptInstalls
}
-func (d *dexpreopter) AndroidMkEntriesForApex() []android.AndroidMkEntries {
- var entries []android.AndroidMkEntries
- for _, install := range d.builtInstalledForApex {
- entries = append(entries, install.ToMakeEntries())
- }
- return entries
+func (d *dexpreopter) ApexSystemServerDexJars() android.Paths {
+ return d.apexSystemServerDexJars
}
func (d *dexpreopter) OutputProfilePathOnHost() android.Path {
@@ -683,3 +635,30 @@
func (d *dexpreopter) SetRewrittenProfile(p android.Path) {
d.rewrittenProfile = p
}
+
+// Check the order of jars on the system server classpath and give a warning/error if a jar precedes
+// one of its dependencies. This is not an error, but a missed optimization, as dexpreopt won't
+// have the dependency jar in the class loader context, and it won't be able to resolve any
+// references to its classes and methods.
+func checkSystemServerOrder(ctx android.ModuleContext, libName string) {
+ config := dexpreopt.GetGlobalConfig(ctx)
+ jars := config.AllSystemServerClasspathJars(ctx)
+ jarIndex := config.AllSystemServerJars(ctx).IndexOfJar(libName)
+ ctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
+ tag := ctx.OtherModuleDependencyTag(dep)
+ // Ideally this should only be walking relevant dependencies, but to maintain existing behavior
+ // for now just exclude any known irrelevant dependencies that would lead to incorrect errors.
+ if _, ok := tag.(bootclasspathDependencyTag); ok {
+ return false
+ }
+ depIndex := jars.IndexOfJar(dep.Name())
+ if jarIndex < depIndex && !config.BrokenSuboptimalOrderOfSystemServerJars {
+ jar := jars.Jar(jarIndex)
+ dep := jars.Jar(depIndex)
+ ctx.ModuleErrorf("non-optimal order of jars on the system server classpath:"+
+ " '%s' precedes its dependency '%s', so dexpreopt is unable to resolve any"+
+ " references from '%s' to '%s'.\n", jar, dep, jar, dep)
+ }
+ return true
+ })
+}
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 8c60d23..313d8c7 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -15,6 +15,7 @@
package java
import (
+ "fmt"
"path/filepath"
"strings"
@@ -225,7 +226,6 @@
}
var (
- dexpreoptBootJarDepTag = bootclasspathDependencyTag{name: "dexpreopt-boot-jar"}
dexBootJarsFragmentsKey = android.NewOnceKey("dexBootJarsFragments")
apexContributionsMetadataDepTag = dependencyTag{name: "all_apex_contributions"}
)
@@ -293,6 +293,9 @@
// Profiles imported from APEXes, in addition to the profile at the default path. Each entry must
// be the name of an APEX module.
profileImports []string
+
+ // The name of the module that provides boot image profiles, if any.
+ profileProviderModule string
}
// Target-dependent description of a boot image.
@@ -464,9 +467,6 @@
func RegisterDexpreoptBootJarsComponents(ctx android.RegistrationContext) {
ctx.RegisterParallelSingletonModuleType("dex_bootjars", dexpreoptBootJarsFactory)
ctx.RegisterModuleType("art_boot_images", artBootImagesFactory)
- ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("dex_bootjars_deps", DexpreoptBootJarsMutator)
- })
}
func SkipDexpreoptBootJars(ctx android.PathContext) bool {
@@ -502,12 +502,6 @@
func (dbj *dexpreoptBootJars) DepsMutator(ctx android.BottomUpMutatorContext) {
// Create a dependency on all_apex_contributions to determine the selected mainline module
ctx.AddDependency(ctx.Module(), apexContributionsMetadataDepTag, "all_apex_contributions")
-}
-
-func DexpreoptBootJarsMutator(ctx android.BottomUpMutatorContext) {
- if _, ok := ctx.Module().(*dexpreoptBootJars); !ok {
- return
- }
if dexpreopt.IsDex2oatNeeded(ctx) {
// Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
@@ -521,7 +515,7 @@
continue
}
// For accessing the boot jars.
- addDependenciesOntoBootImageModules(ctx, config.modules, dexpreoptBootJarDepTag)
+ addDependenciesOntoBootImageModules(ctx, config.modules, dexpreoptBootJar)
// Create a dependency on the apex selected using RELEASE_APEX_CONTRIBUTIONS_*
// TODO: b/308174306 - Remove the direct depedendency edge to the java_library (source/prebuilt) once all mainline modules
// have been flagged using RELEASE_APEX_CONTRIBUTIONS_*
@@ -534,11 +528,11 @@
if ctx.OtherModuleExists("platform-bootclasspath") {
// For accessing all bootclasspath fragments.
- addDependencyOntoApexModulePair(ctx, "platform", "platform-bootclasspath", platformBootclasspathDepTag)
+ addDependencyOntoApexModulePair(ctx, "platform", "platform-bootclasspath", platform)
} else if ctx.OtherModuleExists("art-bootclasspath-fragment") {
// For accessing the ART bootclasspath fragment on a thin manifest (e.g., master-art) where
// platform-bootclasspath doesn't exist.
- addDependencyOntoApexModulePair(ctx, "com.android.art", "art-bootclasspath-fragment", bootclasspathFragmentDepTag)
+ addDependencyOntoApexModulePair(ctx, "com.android.art", "art-bootclasspath-fragment", fragment)
}
}
@@ -556,13 +550,13 @@
// We need to add a dep on only the apex listed in `contents` of the selected apex_contributions module
// This is not available in a structured format in `apex_contributions`, so this hack adds a dep on all `contents`
// (some modules like art.module.public.api do not have an apex variation since it is a pure stub module that does not get installed)
- apexVariationOfSelected := append(ctx.Target().Variations(), blueprint.Variation{Mutator: "apex", Variation: apex})
- if ctx.OtherModuleDependencyVariantExists(apexVariationOfSelected, selected) {
- ctx.AddFarVariationDependencies(apexVariationOfSelected, dexpreoptBootJarDepTag, selected)
- } else if ctx.OtherModuleDependencyVariantExists(apexVariationOfSelected, android.RemoveOptionalPrebuiltPrefix(selected)) {
- // The prebuilt might have been renamed by prebuilt_rename mutator if the source module does not exist.
- // Remove the prebuilt_ prefix.
- ctx.AddFarVariationDependencies(apexVariationOfSelected, dexpreoptBootJarDepTag, android.RemoveOptionalPrebuiltPrefix(selected))
+ tag := bootclasspathDependencyTag{
+ typ: dexpreoptBootJar,
+ }
+
+ dep := android.RemoveOptionalPrebuiltPrefix(selected)
+ if ctx.OtherModuleDependencyVariantExists(ctx.Target().Variations(), dep) {
+ ctx.AddFarVariationDependencies(ctx.Target().Variations(), tag, dep)
}
}
}
@@ -571,23 +565,55 @@
func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android.Module {
return ctx.Config().Once(dexBootJarsFragmentsKey, func() interface{} {
fragments := make(map[string]android.Module)
+
+ type moduleInApexPair struct {
+ module string
+ apex string
+ }
+
+ var modulesInApexes []moduleInApexPair
+
+ // Find the list of modules in apexes.
ctx.WalkDeps(func(child, parent android.Module) bool {
if !isActiveModule(ctx, child) {
return false
}
tag := ctx.OtherModuleDependencyTag(child)
- if tag == platformBootclasspathDepTag {
- return true
- }
- if tag == bootclasspathFragmentDepTag {
- apexInfo, _ := android.OtherModuleProvider(ctx, child, android.ApexInfoProvider)
- for _, apex := range apexInfo.InApexVariants {
- fragments[apex] = child
+ if bcpTag, ok := tag.(bootclasspathDependencyTag); ok {
+ if bcpTag.typ == platform {
+ return true
}
- return false
+ if bcpTag.typ == fragment {
+ if bcpTag.moduleInApex == "" {
+ panic(fmt.Errorf("expected fragment to be in apex"))
+ }
+ modulesInApexes = append(modulesInApexes, moduleInApexPair{bcpTag.moduleInApex, ctx.OtherModuleName(child)})
+ return true
+ }
}
return false
})
+
+ for _, moduleInApex := range modulesInApexes {
+ // Find a desired module in an apex.
+ ctx.WalkDeps(func(child, parent android.Module) bool {
+ t := ctx.OtherModuleDependencyTag(child)
+ if bcpTag, ok := t.(bootclasspathDependencyTag); ok {
+ if bcpTag.typ == platform {
+ return true
+ }
+ if bcpTag.typ == fragment && ctx.OtherModuleName(child) == moduleInApex.apex {
+ // This is the dependency from this module to the apex, recurse into it.
+ return true
+ }
+ } else if android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child)) == moduleInApex.module {
+ // This is the desired module inside the apex.
+ fragments[android.RemoveOptionalPrebuiltPrefix(moduleInApex.apex)] = child
+ }
+ return false
+ })
+ }
+
return fragments
}).(map[string]android.Module)
}
@@ -711,7 +737,8 @@
modules := make([]apexJarModulePair, 0, imageConfig.modules.Len())
for i := 0; i < imageConfig.modules.Len(); i++ {
found := false
- for _, module := range gatherApexModulePairDepsWithTag(ctx, dexpreoptBootJarDepTag) {
+ dexpreoptBootJarModules, _ := gatherApexModulePairDepsWithTag(ctx, dexpreoptBootJar)
+ for _, module := range dexpreoptBootJarModules {
name := android.RemoveOptionalPrebuiltPrefix(module.Name())
if name == imageConfig.modules.Jar(i) {
modules = append(modules, apexJarModulePair{
@@ -794,11 +821,16 @@
"APEX '%[2]s' doesn't exist or is not added as a dependency of dex_bootjars",
pair.jarModule.Name(),
pair.apex)
+ return nil
}
bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, fragment, BootclasspathFragmentApexContentInfoProvider)
jar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(pair.jarModule)
if err != nil {
- ctx.ModuleErrorf("%s", err)
+ if ctx.Config().AllowMissingDependencies() {
+ ctx.AddMissingDependencies([]string{pair.jarModule.String()})
+ } else {
+ ctx.ModuleErrorf("%s", err)
+ }
}
return jar
}
@@ -957,9 +989,16 @@
func getApexNameToApexExportsInfoMap(ctx android.ModuleContext) apexNameToApexExportsInfoMap {
apexNameToApexExportsInfoMap := apexNameToApexExportsInfoMap{}
- ctx.VisitDirectDepsWithTag(dexpreoptBootJarDepTag, func(am android.Module) {
- if info, exists := android.OtherModuleProvider(ctx, am, android.ApexExportsInfoProvider); exists {
- apexNameToApexExportsInfoMap[info.ApexName] = info
+
+ ctx.VisitDirectDeps(func(am android.Module) {
+ tag := ctx.OtherModuleDependencyTag(am)
+ if bcpTag, ok := tag.(bootclasspathDependencyTag); ok && bcpTag.typ == dexpreoptBootJar {
+ if bcpTag.moduleInApex == "" {
+ info, exists := android.OtherModuleProvider(ctx, am, android.ApexExportsInfoProvider)
+ if exists {
+ apexNameToApexExportsInfoMap[info.ApexName] = info
+ }
+ }
}
})
return apexNameToApexExportsInfoMap
@@ -1442,24 +1481,33 @@
func (dbj *artBootImages) DepsMutator(ctx android.BottomUpMutatorContext) {
// Create a dependency on `dex_bootjars` to access the intermediate locations of host art boot image.
- ctx.AddVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), dexpreoptBootJarDepTag, "dex_bootjars")
+ tag := bootclasspathDependencyTag{
+ typ: dexpreoptBootJar,
+ }
+ ctx.AddVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), tag, "dex_bootjars")
}
func (d *artBootImages) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- ctx.VisitDirectDepsWithTag(dexpreoptBootJarDepTag, func(m android.Module) {
- hostInstallsInfo, ok := android.OtherModuleProvider(ctx, m, artBootImageHostInfoProvider)
- if !ok {
- ctx.ModuleErrorf("Could not find information about the host variant of ART boot image")
- }
- installs := d.installFile(ctx, hostInstallsInfo.installs)
- if len(installs) > 0 {
- d.outputFile = android.OptionalPathForPath(installs[0])
- // Create a phony target that can ART run-tests can depend on.
- ctx.Phony(d.Name(), installs...)
- } else {
- // this might be true e.g. when building with `WITH_DEXPREOPT=false`
- // create an empty file so that the `art_boot_images` is known to the packaging system.
- d.outputFile = android.OptionalPathForPath(android.PathForModuleOut(ctx, "undefined_art_boot_images"))
+ ctx.VisitDirectDeps(func(m android.Module) {
+ tag := ctx.OtherModuleDependencyTag(m)
+ if bcpTag, ok := tag.(bootclasspathDependencyTag); ok && bcpTag.typ == dexpreoptBootJar {
+ if bcpTag.moduleInApex != "" {
+ panic("unhandled moduleInApex")
+ }
+ hostInstallsInfo, ok := android.OtherModuleProvider(ctx, m, artBootImageHostInfoProvider)
+ if !ok {
+ ctx.ModuleErrorf("Could not find information about the host variant of ART boot image")
+ }
+ installs := d.installFile(ctx, hostInstallsInfo.installs)
+ if len(installs) > 0 {
+ d.outputFile = android.OptionalPathForPath(installs[0])
+ // Create a phony target that can ART run-tests can depend on.
+ ctx.Phony(d.Name(), installs...)
+ } else {
+ // this might be true e.g. when building with `WITH_DEXPREOPT=false`
+ // create an empty file so that the `art_boot_images` is known to the packaging system.
+ d.outputFile = android.OptionalPathForPath(android.PathForModuleOut(ctx, "undefined_art_boot_images"))
+ }
}
})
}
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index dc0973c..fb5c325 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -67,15 +67,16 @@
// ART boot image for testing only. Do not rely on it to make any build-time decision.
artCfg := bootImageConfig{
- name: artBootImageName,
- enabledIfExists: "art-bootclasspath-fragment",
- stem: bootImageStem,
- installDir: "apex/art_boot_images/javalib",
- modules: global.TestOnlyArtBootImageJars,
- preloadedClassesFile: "art/build/boot/preloaded-classes",
- compilerFilter: "speed-profile",
- singleImage: false,
- profileImports: profileImports,
+ name: artBootImageName,
+ enabledIfExists: "art-bootclasspath-fragment",
+ stem: bootImageStem,
+ installDir: "apex/art_boot_images/javalib",
+ modules: global.TestOnlyArtBootImageJars,
+ preloadedClassesFile: "art/build/boot/preloaded-classes",
+ compilerFilter: "speed-profile",
+ singleImage: false,
+ profileImports: profileImports,
+ profileProviderModule: "art-bootclasspath-fragment",
}
// Framework config for the boot image extension.
diff --git a/java/dexpreopt_config_test.go b/java/dexpreopt_config_test.go
index 44d2127..99b1f23 100644
--- a/java/dexpreopt_config_test.go
+++ b/java/dexpreopt_config_test.go
@@ -23,6 +23,7 @@
)
func TestBootImageConfig(t *testing.T) {
+ t.Parallel()
if runtime.GOOS != "linux" {
t.Skipf("Skipping as boot image config test is only supported on linux not %s", runtime.GOOS)
}
diff --git a/java/dexpreopt_config_testing.go b/java/dexpreopt_config_testing.go
index 33c682b..241941e 100644
--- a/java/dexpreopt_config_testing.go
+++ b/java/dexpreopt_config_testing.go
@@ -1217,6 +1217,7 @@
}
t.Run(imageConfig.name, func(t *testing.T) {
+ t.Parallel()
nestedCheckBootImageConfig(t, result, imageConfig, mutated, expected)
})
}
@@ -1236,7 +1237,7 @@
android.AssertPathRelativeToTopEquals(t, "zip", expected.zip, imageConfig.zip)
if !mutated {
- dexBootJarModule := result.ModuleForTests("dex_bootjars", "android_common")
+ dexBootJarModule := result.ModuleForTests(t, "dex_bootjars", "android_common")
profileInstallInfo, _ := android.OtherModuleProvider(result, dexBootJarModule.Module(), profileInstallInfoProvider)
assertInstallsEqual(t, "profileInstalls", expected.profileInstalls, profileInstallInfo.profileInstalls)
android.AssertStringEquals(t, "profileLicenseMetadataFile", expected.profileLicenseMetadataFile, profileInstallInfo.profileLicenseMetadataFile.RelativeToTop().String())
@@ -1246,6 +1247,7 @@
for i, variant := range imageConfig.variants {
expectedVariant := expected.variants[i]
t.Run(variant.target.Arch.ArchType.String(), func(t *testing.T) {
+ t.Parallel()
android.AssertDeepEquals(t, "archType", expectedVariant.archType, variant.target.Arch.ArchType)
android.AssertDeepEquals(t, "dexLocations", expectedVariant.dexLocations, variant.dexLocations)
android.AssertDeepEquals(t, "dexLocationsDeps", expectedVariant.dexLocationsDeps, variant.dexLocationsDeps)
@@ -1279,7 +1281,7 @@
// checkDexpreoptMakeVars checks the DEXPREOPT_ prefixed make vars produced by dexpreoptBootJars
// singleton.
func checkDexpreoptMakeVars(t *testing.T, result *android.TestResult, expectedLicenseMetadataFile string) {
- vars := result.MakeVarsForTesting(func(variable android.MakeVarVariable) bool {
+ vars := result.MakeVarsForTesting(t, func(variable android.MakeVarVariable) bool {
return strings.HasPrefix(variable.Name(), "DEXPREOPT_")
})
diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go
index 207ff65..f437da0 100644
--- a/java/dexpreopt_test.go
+++ b/java/dexpreopt_test.go
@@ -17,7 +17,6 @@
import (
"fmt"
"runtime"
- "strings"
"testing"
"android/soong/android"
@@ -30,6 +29,7 @@
}
func TestDexpreoptEnabled(t *testing.T) {
+ t.Parallel()
tests := []struct {
name string
bp string
@@ -219,6 +219,7 @@
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
preparers := android.GroupFixturePreparers(
PrepareForTestWithDexpreopt,
PrepareForTestWithFakeApexMutator,
@@ -238,7 +239,7 @@
variant += "_apex1000"
}
- dexpreopt := ctx.ModuleForTests(moduleName, variant).MaybeRule("dexpreopt")
+ dexpreopt := ctx.ModuleForTests(t, moduleName, variant).MaybeRule("dexpreopt")
enabled := dexpreopt.Rule != nil
if enabled != test.enabled {
@@ -258,6 +259,7 @@
}
func TestDex2oatToolDeps(t *testing.T) {
+ t.Parallel()
if runtime.GOOS != "linux" {
// The host binary paths checked below are build OS dependent.
t.Skipf("Unsupported build OS %s", runtime.GOOS)
@@ -273,6 +275,7 @@
name := fmt.Sprintf("sourceEnabled:%t,prebuiltEnabled:%t,prebuiltPreferred:%t",
sourceEnabled, prebuiltEnabled, prebuiltPreferred)
t.Run(name, func(t *testing.T) {
+ t.Parallel()
result := preparers.RunTestWithBp(t, fmt.Sprintf(`
cc_binary {
name: "dex2oatd",
@@ -305,7 +308,7 @@
testDex2oatToolDep(false, true, false, prebuiltDex2oatPath)
}
-func TestDexpreoptBuiltInstalledForApex(t *testing.T) {
+func TestApexSystemServerDexpreoptInstalls(t *testing.T) {
preparers := android.GroupFixturePreparers(
PrepareForTestWithDexpreopt,
PrepareForTestWithFakeApexMutator,
@@ -322,28 +325,38 @@
sdk_version: "current",
}`)
ctx := result.TestContext
- module := ctx.ModuleForTests("service-foo", "android_common_apex1000")
+ module := ctx.ModuleForTests(t, "service-foo", "android_common_apex1000")
library := module.Module().(*Library)
- installs := library.dexpreopter.DexpreoptBuiltInstalledForApex()
+ installs := library.dexpreopter.ApexSystemServerDexpreoptInstalls()
+ dexJars := library.dexpreopter.ApexSystemServerDexJars()
android.AssertIntEquals(t, "install count", 2, len(installs))
+ android.AssertIntEquals(t, "dexjar count", 1, len(dexJars))
- android.AssertStringEquals(t, "installs[0] FullModuleName",
- "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
- installs[0].FullModuleName())
+ android.AssertPathRelativeToTopEquals(t, "installs[0] OutputPathOnHost",
+ "out/soong/.intermediates/service-foo/android_common_apex1000/dexpreopt/service-foo/oat/arm64/javalib.odex",
+ installs[0].OutputPathOnHost)
- android.AssertStringEquals(t, "installs[0] SubModuleName",
- "-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
- installs[0].SubModuleName())
+ android.AssertPathRelativeToTopEquals(t, "installs[0] InstallDirOnDevice",
+ "out/target/product/test_device/system/framework/oat/arm64",
+ installs[0].InstallDirOnDevice)
- android.AssertStringEquals(t, "installs[1] FullModuleName",
- "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
- installs[1].FullModuleName())
+ android.AssertStringEquals(t, "installs[0] InstallFileOnDevice",
+ "apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
+ installs[0].InstallFileOnDevice)
- android.AssertStringEquals(t, "installs[1] SubModuleName",
- "-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
- installs[1].SubModuleName())
+ android.AssertPathRelativeToTopEquals(t, "installs[1] OutputPathOnHost",
+ "out/soong/.intermediates/service-foo/android_common_apex1000/dexpreopt/service-foo/oat/arm64/javalib.vdex",
+ installs[1].OutputPathOnHost)
+
+ android.AssertPathRelativeToTopEquals(t, "installs[1] InstallDirOnDevice",
+ "out/target/product/test_device/system/framework/oat/arm64",
+ installs[1].InstallDirOnDevice)
+
+ android.AssertStringEquals(t, "installs[1] InstallFileOnDevice",
+ "apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
+ installs[1].InstallFileOnDevice)
// Not an APEX system server jar.
result = preparers.RunTestWithBp(t, `
@@ -354,101 +367,14 @@
sdk_version: "current",
}`)
ctx = result.TestContext
- module = ctx.ModuleForTests("foo", "android_common")
+ module = ctx.ModuleForTests(t, "foo", "android_common")
library = module.Module().(*Library)
- installs = library.dexpreopter.DexpreoptBuiltInstalledForApex()
+ installs = library.dexpreopter.ApexSystemServerDexpreoptInstalls()
+ dexJars = library.dexpreopter.ApexSystemServerDexJars()
android.AssertIntEquals(t, "install count", 0, len(installs))
-}
-
-func filterDexpreoptEntriesList(entriesList []android.AndroidMkEntries) []android.AndroidMkEntries {
- var results []android.AndroidMkEntries
- for _, entries := range entriesList {
- if strings.Contains(entries.EntryMap["LOCAL_MODULE"][0], "-dexpreopt-") {
- results = append(results, entries)
- }
- }
- return results
-}
-
-func verifyEntries(t *testing.T, message string, expectedModule string,
- expectedPrebuiltModuleFile string, expectedModulePath string, expectedInstalledModuleStem string,
- entries android.AndroidMkEntries) {
- android.AssertStringEquals(t, message+" LOCAL_MODULE", expectedModule,
- entries.EntryMap["LOCAL_MODULE"][0])
-
- android.AssertStringEquals(t, message+" LOCAL_MODULE_CLASS", "ETC",
- entries.EntryMap["LOCAL_MODULE_CLASS"][0])
-
- android.AssertStringDoesContain(t, message+" LOCAL_PREBUILT_MODULE_FILE",
- entries.EntryMap["LOCAL_PREBUILT_MODULE_FILE"][0], expectedPrebuiltModuleFile)
-
- android.AssertStringDoesContain(t, message+" LOCAL_MODULE_PATH",
- entries.EntryMap["LOCAL_MODULE_PATH"][0], expectedModulePath)
-
- android.AssertStringEquals(t, message+" LOCAL_INSTALLED_MODULE_STEM",
- expectedInstalledModuleStem, entries.EntryMap["LOCAL_INSTALLED_MODULE_STEM"][0])
-
- android.AssertStringEquals(t, message+" LOCAL_NOT_AVAILABLE_FOR_PLATFORM",
- "false", entries.EntryMap["LOCAL_NOT_AVAILABLE_FOR_PLATFORM"][0])
-}
-
-func TestAndroidMkEntriesForApex(t *testing.T) {
- preparers := android.GroupFixturePreparers(
- PrepareForTestWithDexpreopt,
- PrepareForTestWithFakeApexMutator,
- dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-foo"),
- )
-
- // An APEX system server jar.
- result := preparers.RunTestWithBp(t, `
- java_library {
- name: "service-foo",
- installable: true,
- srcs: ["a.java"],
- apex_available: ["com.android.apex1"],
- sdk_version: "current",
- }`)
- ctx := result.TestContext
- module := ctx.ModuleForTests("service-foo", "android_common_apex1000")
-
- entriesList := android.AndroidMkEntriesForTest(t, ctx, module.Module())
- entriesList = filterDexpreoptEntriesList(entriesList)
-
- android.AssertIntEquals(t, "entries count", 2, len(entriesList))
-
- verifyEntries(t,
- "entriesList[0]",
- "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
- "/dexpreopt/service-foo/oat/arm64/javalib.odex",
- "/system/framework/oat/arm64",
- "apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
- entriesList[0])
-
- verifyEntries(t,
- "entriesList[1]",
- "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
- "/dexpreopt/service-foo/oat/arm64/javalib.vdex",
- "/system/framework/oat/arm64",
- "apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
- entriesList[1])
-
- // Not an APEX system server jar.
- result = preparers.RunTestWithBp(t, `
- java_library {
- name: "foo",
- installable: true,
- srcs: ["a.java"],
- sdk_version: "current",
- }`)
- ctx = result.TestContext
- module = ctx.ModuleForTests("foo", "android_common")
-
- entriesList = android.AndroidMkEntriesForTest(t, ctx, module.Module())
- entriesList = filterDexpreoptEntriesList(entriesList)
-
- android.AssertIntEquals(t, "entries count", 0, len(entriesList))
+ android.AssertIntEquals(t, "dexjar count", 0, len(dexJars))
}
func TestGenerateProfileEvenIfDexpreoptIsDisabled(t *testing.T) {
@@ -470,7 +396,7 @@
}`)
ctx := result.TestContext
- dexpreopt := ctx.ModuleForTests("foo", "android_common").MaybeRule("dexpreopt")
+ dexpreopt := ctx.ModuleForTests(t, "foo", "android_common").MaybeRule("dexpreopt")
expected := []string{"out/soong/.intermediates/foo/android_common/dexpreopt/foo/profile.prof"}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 2dda72b..225f201 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -19,6 +19,7 @@
"path/filepath"
"strings"
+ "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
"android/soong/android"
@@ -357,7 +358,7 @@
deps.aidlPreprocess = sdkDep.aidl
}
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
@@ -381,9 +382,9 @@
deps.classpath = append(deps.classpath, dep.HeaderJars...)
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.AconfigIntermediateCacheOutputPaths...)
- } else if dep, ok := module.(android.SourceFileProducer); ok {
- checkProducesJars(ctx, dep)
- deps.classpath = append(deps.classpath, dep.Srcs()...)
+ } else if dep, ok := android.OtherModuleProvider(ctx, module, android.SourceFilesInfoProvider); ok {
+ checkProducesJars(ctx, dep, module)
+ deps.classpath = append(deps.classpath, dep.Srcs...)
} else {
ctx.ModuleErrorf("depends on non-java module %q", otherName)
}
@@ -874,6 +875,13 @@
Path *string
}
+type ExportedDroiddocDirInfo struct {
+ Deps android.Paths
+ Dir android.Path
+}
+
+var ExportedDroiddocDirInfoProvider = blueprint.NewProvider[ExportedDroiddocDirInfo]()
+
type ExportedDroiddocDir struct {
android.ModuleBase
@@ -897,6 +905,11 @@
path := String(d.properties.Path)
d.dir = android.PathForModuleSrc(ctx, path)
d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
+
+ android.SetProvider(ctx, ExportedDroiddocDirInfoProvider, ExportedDroiddocDirInfo{
+ Dir: d.dir,
+ Deps: d.deps,
+ })
}
// Defaults
diff --git a/java/droiddoc_test.go b/java/droiddoc_test.go
index 9e1ebbe..0c977bc 100644
--- a/java/droiddoc_test.go
+++ b/java/droiddoc_test.go
@@ -23,6 +23,7 @@
)
func TestDroiddoc(t *testing.T) {
+ t.Parallel()
ctx, _ := testJavaWithFS(t, `
droiddoc_exported_dir {
name: "droiddoc-templates-sdk",
@@ -69,13 +70,13 @@
"bar-doc/a.java": nil,
"bar-doc/b.java": nil,
})
- barStubsOutputs := ctx.ModuleForTests("bar-stubs", "android_common").OutputFiles(ctx, t, "")
+ barStubsOutputs := ctx.ModuleForTests(t, "bar-stubs", "android_common").OutputFiles(ctx, t, "")
if len(barStubsOutputs) != 1 {
t.Errorf("Expected one output from \"bar-stubs\" got %s", barStubsOutputs)
}
barStubsOutput := barStubsOutputs[0]
- barDoc := ctx.ModuleForTests("bar-doc", "android_common")
+ barDoc := ctx.ModuleForTests(t, "bar-doc", "android_common")
javaDoc := barDoc.Rule("javadoc")
if g, w := android.PathsRelativeToTop(javaDoc.Implicits), android.PathRelativeToTop(barStubsOutput); !inList(w, g) {
t.Errorf("implicits of bar-doc must contain %q, but was %q.", w, g)
@@ -97,6 +98,7 @@
}
func TestDroiddocArgsAndFlagsCausesError(t *testing.T) {
+ t.Parallel()
testJavaError(t, "flags is set. Cannot set args", `
droiddoc_exported_dir {
name: "droiddoc-templates-sdk",
diff --git a/java/droidstubs.go b/java/droidstubs.go
index fa1fb86..caad688 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -20,6 +20,7 @@
"regexp"
"strings"
+ "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
"android/soong/android"
@@ -27,6 +28,28 @@
"android/soong/remoteexec"
)
+type StubsInfo struct {
+ ApiVersionsXml android.Path
+ AnnotationsZip android.Path
+ ApiFile android.Path
+ RemovedApiFile android.Path
+}
+
+type DroidStubsInfo struct {
+ CurrentApiTimestamp android.Path
+ EverythingStubsInfo StubsInfo
+ ExportableStubsInfo StubsInfo
+}
+
+var DroidStubsInfoProvider = blueprint.NewProvider[DroidStubsInfo]()
+
+type StubsSrcInfo struct {
+ EverythingStubsSrcJar android.Path
+ ExportableStubsSrcJar android.Path
+}
+
+var StubsSrcInfoProvider = blueprint.NewProvider[StubsSrcInfo]()
+
// The values allowed for Droidstubs' Api_levels_sdk_type
var allowedApiLevelSdkTypes = []string{"public", "system", "module-lib", "system-server"}
@@ -498,9 +521,9 @@
}
func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
- ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
- if t, ok := m.(*ExportedDroiddocDir); ok {
- cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
+ ctx.VisitDirectDepsProxyWithTag(metalavaMergeAnnotationsDirTag, func(m android.ModuleProxy) {
+ if t, ok := android.OtherModuleProvider(ctx, m, ExportedDroiddocDirInfoProvider); ok {
+ cmd.FlagWithArg("--merge-qualifier-annotations ", t.Dir.String()).Implicits(t.Deps)
} else {
ctx.PropertyErrorf("merge_annotations_dirs",
"module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
@@ -509,9 +532,9 @@
}
func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
- ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
- if t, ok := m.(*ExportedDroiddocDir); ok {
- cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
+ ctx.VisitDirectDepsProxyWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.ModuleProxy) {
+ if t, ok := android.OtherModuleProvider(ctx, m, ExportedDroiddocDirInfoProvider); ok {
+ cmd.FlagWithArg("--merge-inclusion-annotations ", t.Dir.String()).Implicits(t.Deps)
} else {
ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
"module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
@@ -525,12 +548,12 @@
d.apiLevelsGenerationFlags(ctx, cmd, stubsType, apiVersionsXml)
apiVersions = apiVersionsXml
} else {
- ctx.VisitDirectDepsWithTag(metalavaAPILevelsModuleTag, func(m android.Module) {
- if s, ok := m.(*Droidstubs); ok {
+ ctx.VisitDirectDepsProxyWithTag(metalavaAPILevelsModuleTag, func(m android.ModuleProxy) {
+ if s, ok := android.OtherModuleProvider(ctx, m, DroidStubsInfoProvider); ok {
if stubsType == Everything {
- apiVersions = s.everythingArtifacts.apiVersionsXml
+ apiVersions = s.EverythingStubsInfo.ApiVersionsXml
} else if stubsType == Exportable {
- apiVersions = s.exportableArtifacts.apiVersionsXml
+ apiVersions = s.ExportableStubsInfo.ApiVersionsXml
} else {
ctx.ModuleErrorf("%s stubs type does not generate api-versions.xml file", stubsType.String())
}
@@ -603,18 +626,18 @@
var dirs []string
var extensions_dir string
- ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
- if t, ok := m.(*ExportedDroiddocDir); ok {
- extRegex := regexp.MustCompile(t.dir.String() + extensionsPattern)
+ ctx.VisitDirectDepsProxyWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.ModuleProxy) {
+ if t, ok := android.OtherModuleProvider(ctx, m, ExportedDroiddocDirInfoProvider); ok {
+ extRegex := regexp.MustCompile(t.Dir.String() + extensionsPattern)
// Grab the first extensions_dir and we find while scanning ExportedDroiddocDir.deps;
// ideally this should be read from prebuiltApis.properties.Extensions_*
- for _, dep := range t.deps {
+ for _, dep := range t.Deps {
// Check to see if it matches an extension first.
depBase := dep.Base()
if extRegex.MatchString(dep.String()) && d.properties.Extensions_info_file != nil {
if extensions_dir == "" {
- extensions_dir = t.dir.String() + "/extensions"
+ extensions_dir = t.Dir.String() + "/extensions"
}
cmd.Implicit(dep)
} else if depBase == filename {
@@ -622,23 +645,17 @@
cmd.Implicit(dep)
} else if depBase == AndroidPlusUpdatableJar && d.properties.Extensions_info_file != nil {
// The output api-versions.xml has been requested to include information on SDK
- // extensions. That means it also needs to include
- // so
- // The module-lib and system-server directories should use `android-plus-updatable.jar`
- // instead of `android.jar`. See AndroidPlusUpdatableJar for more information.
- cmd.Implicit(dep)
- } else if filename != "android.jar" && depBase == "android.jar" {
- // Metalava implicitly searches these patterns:
- // prebuilts/tools/common/api-versions/android-{version:level}/android.jar
- // prebuilts/sdk/{version:level}/public/android.jar
- // Add android.jar files from the api_levels_annotations_dirs directories to try
- // to satisfy these patterns. If Metalava can't find a match for an API level
- // between 1 and 28 in at least one pattern it will fail.
+ // extensions, i.e. updatable Apis. That means it also needs to include the history of
+ // those updatable APIs. Usually, they would be included in the `android.jar` file but
+ // unfortunately, the `module-lib` and `system-server` cannot as it would lead to build
+ // cycles. So, the module-lib and system-server directories contain an
+ // `android-plus-updatable.jar` that should be used instead of `android.jar`. See
+ // AndroidPlusUpdatableJar for more information.
cmd.Implicit(dep)
}
}
- dirs = append(dirs, t.dir.String())
+ dirs = append(dirs, t.Dir.String())
} else {
ctx.PropertyErrorf("api_levels_annotations_dirs",
"module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
@@ -650,7 +667,7 @@
for _, sdkDir := range sdkDirs {
for _, dir := range dirs {
addPattern := func(jarFilename string) {
- cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/{version:level}/%s/%s", dir, sdkDir, jarFilename))
+ cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/{version:major.minor?}/%s/%s", dir, sdkDir, jarFilename))
}
if sdkDir == "module-lib" || sdkDir == "system-server" {
@@ -665,6 +682,10 @@
addPattern(filename)
}
+
+ if extensions_dir != "" {
+ cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/{version:extension}/%s/{module}.jar", extensions_dir, sdkDir))
+ }
}
if d.properties.Extensions_info_file != nil {
@@ -673,7 +694,6 @@
}
info_file := android.PathForModuleSrc(ctx, *d.properties.Extensions_info_file)
cmd.Implicit(info_file)
- cmd.FlagWithArg("--sdk-extensions-root ", extensions_dir)
cmd.FlagWithArg("--sdk-extensions-info ", info_file.String())
}
}
@@ -700,7 +720,8 @@
}
func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
- srcJarList android.Path, homeDir android.WritablePath, params stubsCommandConfigParams, configFiles android.Paths) *android.RuleBuilderCommand {
+ srcJarList android.Path, homeDir android.WritablePath, params stubsCommandConfigParams,
+ configFiles android.Paths, apiSurface *string) *android.RuleBuilderCommand {
rule.Command().Text("rm -rf").Flag(homeDir.String())
rule.Command().Text("mkdir -p").Flag(homeDir.String())
@@ -746,6 +767,8 @@
addMetalavaConfigFilesToCmd(cmd, configFiles)
+ addOptionalApiSurfaceToCmd(cmd, apiSurface)
+
return cmd
}
@@ -764,6 +787,14 @@
cmd.FlagForEachInput("--config-file ", configFiles)
}
+// addOptionalApiSurfaceToCmd adds --api-surface option is apiSurface is not `nil`.
+func addOptionalApiSurfaceToCmd(cmd *android.RuleBuilderCommand, apiSurface *string) {
+ if apiSurface != nil {
+ cmd.Flag("--api-surface")
+ cmd.Flag(*apiSurface)
+ }
+}
+
// Pass flagged apis related flags to metalava. When aconfig_declarations property is not
// defined for a module, simply revert all flagged apis annotations. If aconfig_declarations
// property is defined, apply transformations and only revert the flagged apis that are not
@@ -838,7 +869,8 @@
configFiles := android.PathsForModuleSrc(ctx, d.properties.ConfigFiles)
- cmd := metalavaCmd(ctx, rule, d.Javadoc.srcFiles, srcJarList, homeDir, params.stubConfig, configFiles)
+ cmd := metalavaCmd(ctx, rule, d.Javadoc.srcFiles, srcJarList, homeDir, params.stubConfig,
+ configFiles, d.properties.Api_surface)
cmd.Implicits(d.Javadoc.implicits)
d.stubsFlags(ctx, cmd, params.stubsDir, params.stubConfig.stubsType, params.stubConfig.checkApi)
@@ -1177,6 +1209,34 @@
rule.Build(fmt.Sprintf("metalava_%s", params.stubConfig.stubsType.String()), "metalava merged")
}
+func (d *Droidstubs) setPhonyRules(ctx android.ModuleContext) {
+ if d.apiFile != nil {
+ ctx.Phony(d.Name(), d.apiFile)
+ ctx.Phony(fmt.Sprintf("%s.txt", d.Name()), d.apiFile)
+ }
+ if d.removedApiFile != nil {
+ ctx.Phony(d.Name(), d.removedApiFile)
+ ctx.Phony(fmt.Sprintf("%s.txt", d.Name()), d.removedApiFile)
+ }
+ if d.checkCurrentApiTimestamp != nil {
+ ctx.Phony(fmt.Sprintf("%s-check-current-api", d.Name()), d.checkCurrentApiTimestamp)
+ ctx.Phony("checkapi", d.checkCurrentApiTimestamp)
+ }
+ if d.updateCurrentApiTimestamp != nil {
+ ctx.Phony(fmt.Sprintf("%s-update-current-api", d.Name()), d.updateCurrentApiTimestamp)
+ ctx.Phony("update-api", d.updateCurrentApiTimestamp)
+ }
+ if d.checkLastReleasedApiTimestamp != nil {
+ ctx.Phony(fmt.Sprintf("%s-check-last-released-api", d.Name()), d.checkLastReleasedApiTimestamp)
+ }
+ if d.apiLintTimestamp != nil {
+ ctx.Phony(fmt.Sprintf("%s-api-lint", d.Name()), d.apiLintTimestamp)
+ }
+ if d.checkNullabilityWarningsTimestamp != nil {
+ ctx.Phony(fmt.Sprintf("%s-check-nullability-warnings", d.Name()), d.checkNullabilityWarningsTimestamp)
+ }
+}
+
func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
deps := d.Javadoc.collectDeps(ctx)
@@ -1220,6 +1280,41 @@
stubCmdParams.stubsType = Exportable
d.exportableStubCmd(ctx, stubCmdParams)
+ if String(d.properties.Check_nullability_warnings) != "" {
+ if d.everythingArtifacts.nullabilityWarningsFile == nil {
+ ctx.PropertyErrorf("check_nullability_warnings",
+ "Cannot specify check_nullability_warnings unless validating nullability")
+ }
+
+ checkNullabilityWarningsPath := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
+
+ d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_nullability_warnings.timestamp")
+
+ msg := fmt.Sprintf(`\n******************************\n`+
+ `The warnings encountered during nullability annotation validation did\n`+
+ `not match the checked in file of expected warnings. The diffs are shown\n`+
+ `above. You have two options:\n`+
+ ` 1. Resolve the differences by editing the nullability annotations.\n`+
+ ` 2. Update the file of expected warnings by running:\n`+
+ ` cp %s %s\n`+
+ ` and submitting the updated file as part of your change.`,
+ d.everythingArtifacts.nullabilityWarningsFile, checkNullabilityWarningsPath)
+
+ rule := android.NewRuleBuilder(pctx, ctx)
+
+ rule.Command().
+ Text("(").
+ Text("diff").Input(checkNullabilityWarningsPath).Input(d.everythingArtifacts.nullabilityWarningsFile).
+ Text("&&").
+ Text("touch").Output(d.checkNullabilityWarningsTimestamp).
+ Text(") || (").
+ Text("echo").Flag("-e").Flag(`"` + msg + `"`).
+ Text("; exit 38").
+ Text(")")
+
+ rule.Build("nullabilityWarningsCheck", "nullability warnings check")
+ }
+
if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
if len(d.Javadoc.properties.Out) > 0 {
@@ -1269,13 +1364,25 @@
`Note that DISABLE_STUB_VALIDATION=true does not bypass checkapi.\n`+
`******************************\n`, ctx.ModuleName())
- rule.Command().
+ cmd := rule.Command().
Text("touch").Output(d.checkCurrentApiTimestamp).
Text(") || (").
Text("echo").Flag("-e").Flag(`"` + msg + `"`).
Text("; exit 38").
Text(")")
+ if d.apiLintTimestamp != nil {
+ cmd.Validation(d.apiLintTimestamp)
+ }
+
+ if d.checkLastReleasedApiTimestamp != nil {
+ cmd.Validation(d.checkLastReleasedApiTimestamp)
+ }
+
+ if d.checkNullabilityWarningsTimestamp != nil {
+ cmd.Validation(d.checkNullabilityWarningsTimestamp)
+ }
+
rule.Build("metalavaCurrentApiCheck", "check current API")
d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "update_current_api.timestamp")
@@ -1305,42 +1412,49 @@
rule.Build("metalavaCurrentApiUpdate", "update current API")
}
- if String(d.properties.Check_nullability_warnings) != "" {
- if d.everythingArtifacts.nullabilityWarningsFile == nil {
- ctx.PropertyErrorf("check_nullability_warnings",
- "Cannot specify check_nullability_warnings unless validating nullability")
- }
-
- checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
-
- d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_nullability_warnings.timestamp")
-
- msg := fmt.Sprintf(`\n******************************\n`+
- `The warnings encountered during nullability annotation validation did\n`+
- `not match the checked in file of expected warnings. The diffs are shown\n`+
- `above. You have two options:\n`+
- ` 1. Resolve the differences by editing the nullability annotations.\n`+
- ` 2. Update the file of expected warnings by running:\n`+
- ` cp %s %s\n`+
- ` and submitting the updated file as part of your change.`,
- d.everythingArtifacts.nullabilityWarningsFile, checkNullabilityWarnings)
-
- rule := android.NewRuleBuilder(pctx, ctx)
-
- rule.Command().
- Text("(").
- Text("diff").Input(checkNullabilityWarnings).Input(d.everythingArtifacts.nullabilityWarningsFile).
- Text("&&").
- Text("touch").Output(d.checkNullabilityWarningsTimestamp).
- Text(") || (").
- Text("echo").Flag("-e").Flag(`"` + msg + `"`).
- Text("; exit 38").
- Text(")")
-
- rule.Build("nullabilityWarningsCheck", "nullability warnings check")
+ droidInfo := DroidStubsInfo{
+ CurrentApiTimestamp: d.CurrentApiTimestamp(),
+ EverythingStubsInfo: StubsInfo{},
+ ExportableStubsInfo: StubsInfo{},
}
+ setDroidInfo(ctx, d, &droidInfo.EverythingStubsInfo, Everything)
+ setDroidInfo(ctx, d, &droidInfo.ExportableStubsInfo, Exportable)
+ android.SetProvider(ctx, DroidStubsInfoProvider, droidInfo)
+
+ android.SetProvider(ctx, StubsSrcInfoProvider, StubsSrcInfo{
+ EverythingStubsSrcJar: d.stubsSrcJar,
+ ExportableStubsSrcJar: d.exportableStubsSrcJar,
+ })
d.setOutputFiles(ctx)
+
+ d.setPhonyRules(ctx)
+
+ if d.apiLintTimestamp != nil {
+ if d.apiLintReport != nil {
+ ctx.DistForGoalsWithFilename(
+ []string{fmt.Sprintf("%s-api-lint", d.Name()), "droidcore"},
+ d.apiLintReport,
+ fmt.Sprintf("apilint/%s-lint-report.txt", d.Name()),
+ )
+ }
+ }
+}
+
+func setDroidInfo(ctx android.ModuleContext, d *Droidstubs, info *StubsInfo, typ StubsType) {
+ if typ == Everything {
+ info.ApiFile = d.apiFile
+ info.RemovedApiFile = d.removedApiFile
+ info.AnnotationsZip = d.everythingArtifacts.annotationsZip
+ info.ApiVersionsXml = d.everythingArtifacts.apiVersionsXml
+ } else if typ == Exportable {
+ info.ApiFile = d.exportableApiFile
+ info.RemovedApiFile = d.exportableRemovedApiFile
+ info.AnnotationsZip = d.exportableArtifacts.annotationsZip
+ info.ApiVersionsXml = d.exportableArtifacts.apiVersionsXml
+ } else {
+ ctx.ModuleErrorf("failed to set ApiVersionsXml, stubs type not supported: %d", typ)
+ }
}
// This method sets the outputFiles property, which is used to set the
@@ -1508,6 +1622,11 @@
p.stubsSrcJar = outPath
}
+ android.SetProvider(ctx, StubsSrcInfoProvider, StubsSrcInfo{
+ EverythingStubsSrcJar: p.stubsSrcJar,
+ ExportableStubsSrcJar: p.stubsSrcJar,
+ })
+
ctx.SetOutputFiles(android.Paths{p.stubsSrcJar}, "")
// prebuilt droidstubs does not output "exportable" stubs.
// Output the "everything" stubs srcjar file if the tag is ".exportable".
diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go
index 37740ae..dfdf877 100644
--- a/java/droidstubs_test.go
+++ b/java/droidstubs_test.go
@@ -27,6 +27,7 @@
)
func TestDroidstubs(t *testing.T) {
+ t.Parallel()
ctx, _ := testJavaWithFS(t, `
droiddoc_exported_dir {
name: "droiddoc-templates-sdk",
@@ -82,13 +83,13 @@
},
}
for _, c := range testcases {
- m := ctx.ModuleForTests(c.moduleName, "android_common")
+ m := ctx.ModuleForTests(t, c.moduleName, "android_common")
manifest := m.Output("metalava.sbox.textproto")
sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, manifest)
cmdline := String(sboxProto.Commands[0].Command)
android.AssertStringContainsEquals(t, "api-versions generation flag", cmdline, "--generate-api-levels", c.generate_xml)
if c.expectedJarFilename != "" {
- expected := "--android-jar-pattern ./{version:level}/public/" + c.expectedJarFilename
+ expected := "--android-jar-pattern ./{version:major.minor?}/public/" + c.expectedJarFilename
if !strings.Contains(cmdline, expected) {
t.Errorf("For %q, expected metalava argument %q, but was not found %q", c.moduleName, expected, cmdline)
}
@@ -131,7 +132,7 @@
"foo-doc/a.java": nil,
})
- m := ctx.ModuleForTests("foo-stubs", "android_common")
+ m := ctx.ModuleForTests(t, "foo-stubs", "android_common")
manifest := m.Output("metalava.sbox.textproto")
cmd := String(android.RuleBuilderSboxProtoForTests(t, ctx, manifest).Commands[0].Command)
r := regexp.MustCompile(`--android-jar-pattern [^ ]+/android.jar`)
@@ -139,35 +140,38 @@
}
func TestPublicDroidstubs(t *testing.T) {
+ t.Parallel()
patterns := getAndroidJarPatternsForDroidstubs(t, "public")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/{version:level}/public/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/public/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/public/android.jar",
}, patterns)
}
func TestSystemDroidstubs(t *testing.T) {
+ t.Parallel()
patterns := getAndroidJarPatternsForDroidstubs(t, "system")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/{version:level}/system/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/system/android.jar",
- "--android-jar-pattern somedir/{version:level}/public/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/public/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/system/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/system/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/public/android.jar",
}, patterns)
}
func TestModuleLibDroidstubs(t *testing.T) {
+ t.Parallel()
patterns := getAndroidJarPatternsForDroidstubs(t, "module-lib")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/{version:level}/module-lib/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/module-lib/android.jar",
- "--android-jar-pattern somedir/{version:level}/system/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/system/android.jar",
- "--android-jar-pattern somedir/{version:level}/public/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/public/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/module-lib/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/module-lib/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/system/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/system/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/public/android.jar",
}, patterns)
}
@@ -175,14 +179,14 @@
patterns := getAndroidJarPatternsForDroidstubs(t, "system-server")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/{version:level}/system-server/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/system-server/android.jar",
- "--android-jar-pattern somedir/{version:level}/module-lib/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/module-lib/android.jar",
- "--android-jar-pattern somedir/{version:level}/system/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/system/android.jar",
- "--android-jar-pattern somedir/{version:level}/public/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/public/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/system-server/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/system-server/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/module-lib/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/module-lib/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/system/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/system/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/public/android.jar",
}, patterns)
}
@@ -206,7 +210,7 @@
"bar-doc/a.java": nil,
})
- m := ctx.ModuleForTests("bar-stubs", "android_common")
+ m := ctx.ModuleForTests(t, "bar-stubs", "android_common")
metalava := m.Rule("metalava")
if g, w := metalava.Inputs.Strings(), []string{"bar-doc/a.java"}; !reflect.DeepEqual(w, g) {
t.Errorf("Expected inputs %q, got %q", w, g)
@@ -267,7 +271,7 @@
}
func checkSystemModulesUseByDroidstubs(t *testing.T, ctx *android.TestContext, moduleName string, systemJar string) {
- metalavaRule := ctx.ModuleForTests(moduleName, "android_common").Rule("metalava")
+ metalavaRule := ctx.ModuleForTests(t, moduleName, "android_common").Rule("metalava")
var systemJars []string
for _, i := range metalavaRule.Implicits {
systemJars = append(systemJars, i.Base())
@@ -300,10 +304,10 @@
"sdk/extensions/1/public/some-mainline-module-stubs.jar": nil,
"sdk/extensions/info.txt": nil,
})
- m := ctx.ModuleForTests("baz-stubs", "android_common")
+ m := ctx.ModuleForTests(t, "baz-stubs", "android_common")
manifest := m.Output("metalava.sbox.textproto")
cmdline := String(android.RuleBuilderSboxProtoForTests(t, ctx, manifest).Commands[0].Command)
- android.AssertStringDoesContain(t, "sdk-extensions-root present", cmdline, "--sdk-extensions-root sdk/extensions")
+ android.AssertStringDoesContain(t, "android-jar-pattern present", cmdline, "--android-jar-pattern sdk/extensions/{version:extension}/public/{module}.jar")
android.AssertStringDoesContain(t, "sdk-extensions-info present", cmdline, "--sdk-extensions-info sdk/extensions/info.txt")
}
@@ -328,7 +332,7 @@
},
)
- ctx.ModuleForTests("foo.api.contribution", "")
+ ctx.ModuleForTests(t, "foo.api.contribution", "")
}
func TestGeneratedApiContributionVisibilityTest(t *testing.T) {
@@ -362,7 +366,7 @@
},
)
- ctx.ModuleForTests("bar", "android_common")
+ ctx.ModuleForTests(t, "bar", "android_common")
}
func TestAconfigDeclarations(t *testing.T) {
@@ -404,7 +408,7 @@
android.AssertBoolEquals(t, "foo expected to depend on bar",
CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "bar"), true)
- m := result.ModuleForTests("foo", "android_common")
+ m := result.ModuleForTests(t, "foo", "android_common")
android.AssertStringDoesContain(t, "foo generates revert annotations file",
strings.Join(m.AllOutputs(), ""), "revert-annotations-exportable.txt")
@@ -454,7 +458,7 @@
}
`)
- m := result.ModuleForTests("foo", "android_common")
+ m := result.ModuleForTests(t, "foo", "android_common")
rule := m.Output("released-flagged-apis-exportable.txt")
exposeWritableApisFilter := "--filter='state:ENABLED+permission:READ_ONLY' --filter='permission:READ_WRITE'"
diff --git a/java/fuzz_test.go b/java/fuzz_test.go
index f29c913..735b8da 100644
--- a/java/fuzz_test.go
+++ b/java/fuzz_test.go
@@ -30,6 +30,7 @@
)
func TestJavaFuzz(t *testing.T) {
+ t.Parallel()
result := prepForJavaFuzzTest.RunTestWithBp(t, `
java_fuzz {
name: "foo",
@@ -63,16 +64,16 @@
osCommonTarget := result.Config.BuildOSCommonTarget.String()
- javac := result.ModuleForTests("foo", osCommonTarget).Rule("javac")
- combineJar := result.ModuleForTests("foo", osCommonTarget).Description("for javac")
+ javac := result.ModuleForTests(t, "foo", osCommonTarget).Rule("javac")
+ combineJar := result.ModuleForTests(t, "foo", osCommonTarget).Description("for javac")
if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
}
- baz := result.ModuleForTests("baz", osCommonTarget).Rule("javac").Output.String()
- barOut := filepath.Join("out", "soong", ".intermediates", "bar", osCommonTarget, "javac-header", "bar.jar")
- bazOut := filepath.Join("out", "soong", ".intermediates", "baz", osCommonTarget, "javac-header", "baz.jar")
+ baz := result.ModuleForTests(t, "baz", osCommonTarget).Rule("javac").Output.String()
+ barOut := filepath.Join("out", "soong", ".intermediates", "bar", osCommonTarget, "local-javac-header", "bar.jar")
+ bazOut := filepath.Join("out", "soong", ".intermediates", "baz", osCommonTarget, "local-javac-header", "baz.jar")
android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], barOut)
android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], bazOut)
@@ -82,7 +83,7 @@
}
ctx := result.TestContext
- foo := ctx.ModuleForTests("foo", osCommonTarget).Module().(*JavaFuzzTest)
+ foo := ctx.ModuleForTests(t, "foo", osCommonTarget).Module().(*JavaFuzzTest)
expected := "lib64/libjni.so"
if runtime.GOOS == "darwin" {
diff --git a/java/generated_java_library_test.go b/java/generated_java_library_test.go
index a5c4be1..e5ee586 100644
--- a/java/generated_java_library_test.go
+++ b/java/generated_java_library_test.go
@@ -52,6 +52,7 @@
}
func TestGenLib(t *testing.T) {
+ t.Parallel()
bp := `
test_java_gen_lib {
name: "javagenlibtest",
@@ -60,6 +61,6 @@
`
result := testGenLib(t, android.FixtureExpectsNoErrors, bp)
- javagenlibtest := result.ModuleForTests("javagenlibtest", "android_common").Module().(*GeneratedJavaLibraryModule)
+ javagenlibtest := result.ModuleForTests(t, "javagenlibtest", "android_common").Module().(*GeneratedJavaLibraryModule)
android.AssertPathsEndWith(t, "Generated_srcjars", []string{"/blah.srcjar"}, javagenlibtest.Library.properties.Generated_srcjars)
}
diff --git a/java/genrule_combiner.go b/java/genrule_combiner.go
new file mode 100644
index 0000000..357dc2c
--- /dev/null
+++ b/java/genrule_combiner.go
@@ -0,0 +1,252 @@
+// Copyright 2019 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 java
+
+import (
+ "fmt"
+ "io"
+
+ "android/soong/android"
+ "android/soong/dexpreopt"
+
+ "github.com/google/blueprint/depset"
+ "github.com/google/blueprint/proptools"
+)
+
+type GenruleCombiner struct {
+ android.ModuleBase
+ android.DefaultableModuleBase
+
+ genruleCombinerProperties GenruleCombinerProperties
+
+ headerJars android.Paths
+ implementationJars android.Paths
+ implementationAndResourceJars android.Paths
+ resourceJars android.Paths
+ aconfigProtoFiles android.Paths
+
+ srcJarArgs []string
+ srcJarDeps android.Paths
+
+ headerDirs android.Paths
+
+ combinedHeaderJar android.Path
+ combinedImplementationJar android.Path
+}
+
+type GenruleCombinerProperties struct {
+ // List of modules whose implementation (and resources) jars will be visible to modules
+ // that depend on this module.
+ Static_libs proptools.Configurable[[]string] `android:"arch_variant"`
+
+ // List of modules whose header jars will be visible to modules that depend on this module.
+ Headers proptools.Configurable[[]string] `android:"arch_variant"`
+}
+
+// java_genrule_combiner provides the implementation and resource jars from `static_libs`, with
+// the header jars from `headers`.
+//
+// This is useful when a java_genrule is used to change the implementation of a java library
+// without requiring a change in the header jars.
+func GenruleCombinerFactory() android.Module {
+ module := &GenruleCombiner{}
+
+ module.AddProperties(&module.genruleCombinerProperties)
+ InitJavaModule(module, android.HostAndDeviceSupported)
+ return module
+}
+
+var genruleCombinerHeaderDepTag = dependencyTag{name: "genrule_combiner_header"}
+
+func (j *GenruleCombiner) DepsMutator(ctx android.BottomUpMutatorContext) {
+ ctx.AddVariationDependencies(nil, staticLibTag,
+ j.genruleCombinerProperties.Static_libs.GetOrDefault(ctx, nil)...)
+ ctx.AddVariationDependencies(nil, genruleCombinerHeaderDepTag,
+ j.genruleCombinerProperties.Headers.GetOrDefault(ctx, nil)...)
+}
+
+func (j *GenruleCombiner) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ if len(j.genruleCombinerProperties.Static_libs.GetOrDefault(ctx, nil)) < 1 {
+ ctx.PropertyErrorf("static_libs", "at least one dependency is required")
+ }
+
+ if len(j.genruleCombinerProperties.Headers.GetOrDefault(ctx, nil)) < 1 {
+ ctx.PropertyErrorf("headers", "at least one dependency is required")
+ }
+
+ var transitiveHeaderJars []depset.DepSet[android.Path]
+ var transitiveImplementationJars []depset.DepSet[android.Path]
+ var transitiveResourceJars []depset.DepSet[android.Path]
+ var sdkVersion android.SdkSpec
+ var stubsLinkType StubsLinkType
+ moduleWithSdkDepInfo := &ModuleWithSdkDepInfo{}
+
+ // Collect the headers first, so that aconfig flag values for the libraries will override
+ // values from the headers (if they are different).
+ ctx.VisitDirectDepsWithTag(genruleCombinerHeaderDepTag, func(m android.Module) {
+ if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
+ j.headerJars = append(j.headerJars, dep.HeaderJars...)
+
+ j.srcJarArgs = append(j.srcJarArgs, dep.SrcJarArgs...)
+ j.srcJarDeps = append(j.srcJarDeps, dep.SrcJarDeps...)
+ j.aconfigProtoFiles = append(j.aconfigProtoFiles, dep.AconfigIntermediateCacheOutputPaths...)
+ sdkVersion = dep.SdkVersion
+ stubsLinkType = dep.StubsLinkType
+ *moduleWithSdkDepInfo = *dep.ModuleWithSdkDepInfo
+
+ transitiveHeaderJars = append(transitiveHeaderJars, dep.TransitiveStaticLibsHeaderJars)
+ } else if dep, ok := android.OtherModuleProvider(ctx, m, android.CodegenInfoProvider); ok {
+ j.aconfigProtoFiles = append(j.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
+ } else {
+ ctx.PropertyErrorf("headers", "module %q cannot be used as a dependency", ctx.OtherModuleName(m))
+ }
+ })
+ ctx.VisitDirectDepsWithTag(staticLibTag, func(m android.Module) {
+ if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
+ j.implementationJars = append(j.implementationJars, dep.ImplementationJars...)
+ j.implementationAndResourceJars = append(j.implementationAndResourceJars, dep.ImplementationAndResourcesJars...)
+ j.resourceJars = append(j.resourceJars, dep.ResourceJars...)
+
+ transitiveImplementationJars = append(transitiveImplementationJars, dep.TransitiveStaticLibsImplementationJars)
+ transitiveResourceJars = append(transitiveResourceJars, dep.TransitiveStaticLibsResourceJars)
+ j.aconfigProtoFiles = append(j.aconfigProtoFiles, dep.AconfigIntermediateCacheOutputPaths...)
+ } else if dep, ok := android.OtherModuleProvider(ctx, m, android.OutputFilesProvider); ok {
+ // This is provided by `java_genrule` modules.
+ j.implementationJars = append(j.implementationJars, dep.DefaultOutputFiles...)
+ j.implementationAndResourceJars = append(j.implementationAndResourceJars, dep.DefaultOutputFiles...)
+ stubsLinkType = Implementation
+ } else {
+ ctx.PropertyErrorf("static_libs", "module %q cannot be used as a dependency", ctx.OtherModuleName(m))
+ }
+ })
+
+ jarName := ctx.ModuleName() + ".jar"
+
+ if len(j.implementationAndResourceJars) > 1 {
+ outputFile := android.PathForModuleOut(ctx, "combined", jarName)
+ TransformJarsToJar(ctx, outputFile, "combine", j.implementationAndResourceJars,
+ android.OptionalPath{}, false, nil, nil)
+ j.combinedImplementationJar = outputFile
+ } else if len(j.implementationAndResourceJars) == 1 {
+ j.combinedImplementationJar = j.implementationAndResourceJars[0]
+ }
+
+ if len(j.headerJars) > 1 {
+ outputFile := android.PathForModuleOut(ctx, "turbine-combined", jarName)
+ TransformJarsToJar(ctx, outputFile, "turbine combine", j.headerJars,
+ android.OptionalPath{}, false, nil, []string{"META-INF/TRANSITIVE"})
+ j.combinedHeaderJar = outputFile
+ j.headerDirs = append(j.headerDirs, android.PathForModuleOut(ctx, "turbine-combined"))
+ } else if len(j.headerJars) == 1 {
+ j.combinedHeaderJar = j.headerJars[0]
+ }
+
+ javaInfo := &JavaInfo{
+ HeaderJars: android.Paths{j.combinedHeaderJar},
+ LocalHeaderJars: android.Paths{j.combinedHeaderJar},
+ TransitiveStaticLibsHeaderJars: depset.New(depset.PREORDER, android.Paths{j.combinedHeaderJar}, transitiveHeaderJars),
+ TransitiveStaticLibsImplementationJars: depset.New(depset.PREORDER, android.Paths{j.combinedImplementationJar}, transitiveImplementationJars),
+ TransitiveStaticLibsResourceJars: depset.New(depset.PREORDER, nil, transitiveResourceJars),
+ GeneratedSrcjars: android.Paths{j.combinedImplementationJar},
+ ImplementationAndResourcesJars: android.Paths{j.combinedImplementationJar},
+ ImplementationJars: android.Paths{j.combinedImplementationJar},
+ ModuleWithSdkDepInfo: moduleWithSdkDepInfo,
+ ResourceJars: j.resourceJars,
+ OutputFile: j.combinedImplementationJar,
+ SdkVersion: sdkVersion,
+ SrcJarArgs: j.srcJarArgs,
+ SrcJarDeps: j.srcJarDeps,
+ StubsLinkType: stubsLinkType,
+ AconfigIntermediateCacheOutputPaths: j.aconfigProtoFiles,
+ }
+ setExtraJavaInfo(ctx, j, javaInfo)
+ ctx.SetOutputFiles(android.Paths{javaInfo.OutputFile}, "")
+ ctx.SetOutputFiles(android.Paths{javaInfo.OutputFile}, android.DefaultDistTag)
+ ctx.SetOutputFiles(javaInfo.ImplementationAndResourcesJars, ".jar")
+ ctx.SetOutputFiles(javaInfo.HeaderJars, ".hjar")
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+
+}
+
+func (j *GenruleCombiner) GeneratedSourceFiles() android.Paths {
+ return append(android.Paths{}, j.combinedImplementationJar)
+}
+
+func (j *GenruleCombiner) GeneratedHeaderDirs() android.Paths {
+ return append(android.Paths{}, j.headerDirs...)
+}
+
+func (j *GenruleCombiner) GeneratedDeps() android.Paths {
+ return append(android.Paths{}, j.combinedImplementationJar)
+}
+
+func (j *GenruleCombiner) Srcs() android.Paths {
+ return append(android.Paths{}, j.implementationAndResourceJars...)
+}
+
+func (j *GenruleCombiner) HeaderJars() android.Paths {
+ return j.headerJars
+}
+
+func (j *GenruleCombiner) ImplementationAndResourcesJars() android.Paths {
+ return j.implementationAndResourceJars
+}
+
+func (j *GenruleCombiner) DexJarBuildPath(ctx android.ModuleErrorfContext) android.Path {
+ return nil
+}
+
+func (j *GenruleCombiner) DexJarInstallPath() android.Path {
+ return nil
+}
+
+func (j *GenruleCombiner) AidlIncludeDirs() android.Paths {
+ return nil
+}
+
+func (j *GenruleCombiner) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
+ return nil
+}
+
+func (j *GenruleCombiner) JacocoReportClassesFile() android.Path {
+ return nil
+}
+
+func (j *GenruleCombiner) AndroidMk() android.AndroidMkData {
+ return android.AndroidMkData{
+ Class: "JAVA_LIBRARIES",
+ OutputFile: android.OptionalPathForPath(j.combinedImplementationJar),
+ // Make does not support Windows Java modules
+ Disabled: j.Os() == android.Windows,
+ Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
+ Extra: []android.AndroidMkExtraFunc{
+ func(w io.Writer, outputFile android.Path) {
+ fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
+ fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", j.combinedHeaderJar.String())
+ fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", j.combinedImplementationJar.String())
+ },
+ },
+ }
+}
+
+// implement the following interface for IDE completion.
+var _ android.IDEInfo = (*GenruleCombiner)(nil)
+
+func (j *GenruleCombiner) IDEInfo(ctx android.BaseModuleContext, ideInfo *android.IdeInfo) {
+ ideInfo.Deps = append(ideInfo.Deps, j.genruleCombinerProperties.Static_libs.GetOrDefault(ctx, nil)...)
+ ideInfo.Libs = append(ideInfo.Libs, j.genruleCombinerProperties.Static_libs.GetOrDefault(ctx, nil)...)
+ ideInfo.Deps = append(ideInfo.Deps, j.genruleCombinerProperties.Headers.GetOrDefault(ctx, nil)...)
+ ideInfo.Libs = append(ideInfo.Libs, j.genruleCombinerProperties.Headers.GetOrDefault(ctx, nil)...)
+}
diff --git a/java/genrule_combiner_test.go b/java/genrule_combiner_test.go
new file mode 100644
index 0000000..7d024cf
--- /dev/null
+++ b/java/genrule_combiner_test.go
@@ -0,0 +1,237 @@
+// Copyright 2018 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 java
+
+import (
+ "reflect"
+ "testing"
+
+ "android/soong/android"
+)
+
+func TestJarGenruleCombinerSingle(t *testing.T) {
+ t.Parallel()
+ t.Helper()
+ ctx := prepareForJavaTest.RunTestWithBp(t, `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ }
+
+ java_genrule {
+ name: "gen",
+ tool_files: ["b.java"],
+ cmd: "$(location b.java) $(in) $(out)",
+ out: ["gen.jar"],
+ srcs: [":foo"],
+ }
+
+ java_genrule_combiner {
+ name: "jarcomb",
+ static_libs: ["gen"],
+ headers: ["foo"],
+ }
+
+ java_library {
+ name: "bar",
+ static_libs: ["jarcomb"],
+ srcs: ["c.java"],
+ }
+
+ java_library {
+ name: "baz",
+ libs: ["jarcomb"],
+ srcs: ["c.java"],
+ }
+ `).TestContext
+
+ fooMod := ctx.ModuleForTests(t, "foo", "android_common")
+ fooCombined := fooMod.Output("turbine-combined/foo.jar")
+ fooOutputFiles, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), fooMod.Module(), android.OutputFilesProvider)
+ fooHeaderJars := fooOutputFiles.TaggedOutputFiles[".hjar"]
+
+ genMod := ctx.ModuleForTests(t, "gen", "android_common")
+ gen := genMod.Output("gen.jar")
+
+ jarcombMod := ctx.ModuleForTests(t, "jarcomb", "android_common")
+ jarcombInfo, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), jarcombMod.Module(), JavaInfoProvider)
+ jarcombOutputFiles, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), jarcombMod.Module(), android.OutputFilesProvider)
+
+ // Confirm that jarcomb simply forwards the jarcomb implementation and the foo headers.
+ if len(jarcombOutputFiles.DefaultOutputFiles) != 1 ||
+ android.PathRelativeToTop(jarcombOutputFiles.DefaultOutputFiles[0]) != android.PathRelativeToTop(gen.Output) {
+ t.Errorf("jarcomb Implementation %v is not [%q]",
+ android.PathsRelativeToTop(jarcombOutputFiles.DefaultOutputFiles), android.PathRelativeToTop(gen.Output))
+ }
+ jarcombHeaderJars := jarcombOutputFiles.TaggedOutputFiles[".hjar"]
+ if !reflect.DeepEqual(jarcombHeaderJars, fooHeaderJars) {
+ t.Errorf("jarcomb Header jar %v is not %q",
+ jarcombHeaderJars, fooHeaderJars)
+ }
+
+ // Confirm that JavaInfoProvider agrees.
+ if len(jarcombInfo.ImplementationJars) != 1 ||
+ android.PathRelativeToTop(jarcombInfo.ImplementationJars[0]) != android.PathRelativeToTop(gen.Output) {
+ t.Errorf("jarcomb ImplementationJars %v is not [%q]",
+ android.PathsRelativeToTop(jarcombInfo.ImplementationJars), android.PathRelativeToTop(gen.Output))
+ }
+ if len(jarcombInfo.HeaderJars) != 1 ||
+ android.PathRelativeToTop(jarcombInfo.HeaderJars[0]) != android.PathRelativeToTop(fooCombined.Output) {
+ t.Errorf("jarcomb HeaderJars %v is not [%q]",
+ android.PathsRelativeToTop(jarcombInfo.HeaderJars), android.PathRelativeToTop(fooCombined.Output))
+ }
+
+ barMod := ctx.ModuleForTests(t, "bar", "android_common")
+ bar := barMod.Output("javac/bar.jar")
+ barCombined := barMod.Output("combined/bar.jar")
+
+ // Confirm that bar uses the Implementation from gen and headerJars from foo.
+ if len(barCombined.Inputs) != 2 ||
+ barCombined.Inputs[0].String() != bar.Output.String() ||
+ barCombined.Inputs[1].String() != gen.Output.String() {
+ t.Errorf("bar combined jar inputs %v is not [%q, %q]",
+ barCombined.Inputs.Strings(), bar.Output.String(), gen.Output.String())
+ }
+
+ bazMod := ctx.ModuleForTests(t, "baz", "android_common")
+ baz := bazMod.Output("javac/baz.jar")
+
+ string_in_list := func(s string, l []string) bool {
+ for _, v := range l {
+ if s == v {
+ return true
+ }
+ }
+ return false
+ }
+
+ // Confirm that baz uses the headerJars from foo.
+ bazImplicitsRel := android.PathsRelativeToTop(baz.Implicits)
+ for _, v := range android.PathsRelativeToTop(fooHeaderJars) {
+ if !string_in_list(v, bazImplicitsRel) {
+ t.Errorf("baz Implicits %v does not contain %q", bazImplicitsRel, v)
+ }
+ }
+}
+
+func TestJarGenruleCombinerMulti(t *testing.T) {
+ t.Parallel()
+ t.Helper()
+ ctx := prepareForJavaTest.RunTestWithBp(t, `
+ java_library {
+ name: "foo1",
+ srcs: ["foo1_a.java"],
+ }
+
+ java_library {
+ name: "foo2",
+ srcs: ["foo2_a.java"],
+ }
+
+ java_genrule {
+ name: "gen1",
+ tool_files: ["b.java"],
+ cmd: "$(location b.java) $(in) $(out)",
+ out: ["gen1.jar"],
+ srcs: [":foo1"],
+ }
+
+ java_genrule {
+ name: "gen2",
+ tool_files: ["b.java"],
+ cmd: "$(location b.java) $(in) $(out)",
+ out: ["gen2.jar"],
+ srcs: [":foo2"],
+ }
+
+ // Combine multiple java_genrule modules.
+ java_genrule_combiner {
+ name: "jarcomb",
+ static_libs: ["gen1", "gen2"],
+ headers: ["foo1", "foo2"],
+ }
+
+ java_library {
+ name: "bar",
+ static_libs: ["jarcomb"],
+ srcs: ["c.java"],
+ }
+
+ java_library {
+ name: "baz",
+ libs: ["jarcomb"],
+ srcs: ["c.java"],
+ }
+ `).TestContext
+
+ gen1Mod := ctx.ModuleForTests(t, "gen1", "android_common")
+ gen1 := gen1Mod.Output("gen1.jar")
+ gen2Mod := ctx.ModuleForTests(t, "gen2", "android_common")
+ gen2 := gen2Mod.Output("gen2.jar")
+
+ jarcombMod := ctx.ModuleForTests(t, "jarcomb", "android_common")
+ jarcomb := jarcombMod.Output("combined/jarcomb.jar")
+ jarcombTurbine := jarcombMod.Output("turbine-combined/jarcomb.jar")
+ _ = jarcombTurbine
+ jarcombInfo, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), jarcombMod.Module(), JavaInfoProvider)
+ _ = jarcombInfo
+ jarcombOutputFiles, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), jarcombMod.Module(), android.OutputFilesProvider)
+ jarcombHeaderJars := jarcombOutputFiles.TaggedOutputFiles[".hjar"]
+
+ if len(jarcomb.Inputs) != 2 ||
+ jarcomb.Inputs[0].String() != gen1.Output.String() ||
+ jarcomb.Inputs[1].String() != gen2.Output.String() {
+ t.Errorf("jarcomb inputs %v are not [%q, %q]",
+ jarcomb.Inputs.Strings(), gen1.Output.String(), gen2.Output.String())
+ }
+
+ if len(jarcombHeaderJars) != 1 ||
+ android.PathRelativeToTop(jarcombHeaderJars[0]) != android.PathRelativeToTop(jarcombTurbine.Output) {
+ t.Errorf("jarcomb Header jars %v is not [%q]",
+ android.PathsRelativeToTop(jarcombHeaderJars), android.PathRelativeToTop(jarcombTurbine.Output))
+ }
+
+ barMod := ctx.ModuleForTests(t, "bar", "android_common")
+ bar := barMod.Output("javac/bar.jar")
+ barCombined := barMod.Output("combined/bar.jar")
+
+ // Confirm that bar uses the Implementation and Headers from jarcomb.
+ if len(barCombined.Inputs) != 2 ||
+ barCombined.Inputs[0].String() != bar.Output.String() ||
+ barCombined.Inputs[1].String() != jarcomb.Output.String() {
+ t.Errorf("bar combined jar inputs %v is not [%q, %q]",
+ barCombined.Inputs.Strings(), bar.Output.String(), jarcomb.Output.String())
+ }
+
+ bazMod := ctx.ModuleForTests(t, "baz", "android_common")
+ baz := bazMod.Output("javac/baz.jar")
+
+ string_in_list := func(s string, l []string) bool {
+ for _, v := range l {
+ if s == v {
+ return true
+ }
+ }
+ return false
+ }
+
+ // Confirm that baz uses the headerJars from foo.
+ bazImplicitsRel := android.PathsRelativeToTop(baz.Implicits)
+ for _, v := range android.PathsRelativeToTop(jarcombHeaderJars) {
+ if !string_in_list(v, bazImplicitsRel) {
+ t.Errorf("baz Implicits %v does not contain %q", bazImplicitsRel, v)
+ }
+ }
+}
diff --git a/java/genrule_test.go b/java/genrule_test.go
index 1c294b2..c112e45 100644
--- a/java/genrule_test.go
+++ b/java/genrule_test.go
@@ -31,6 +31,7 @@
}
func TestGenruleCmd(t *testing.T) {
+ t.Parallel()
fs := map[string][]byte{
"tool": nil,
"foo": nil,
@@ -56,7 +57,7 @@
t.Fatal(errs)
}
- gen := ctx.ModuleForTests("gen", "android_common").Output("out")
+ gen := ctx.ModuleForTests(t, "gen", "android_common").Output("out")
expected := []string{"foo"}
if !reflect.DeepEqual(expected, gen.Implicits.Strings()[:len(expected)]) {
t.Errorf(`want arm inputs %v, got %v`, expected, gen.Implicits.Strings())
@@ -64,6 +65,7 @@
}
func TestJarGenrules(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -91,11 +93,11 @@
}
`)
- foo := ctx.ModuleForTests("foo", "android_common").Output("javac/foo.jar")
- jargen := ctx.ModuleForTests("jargen", "android_common").Output("jargen.jar")
- bar := ctx.ModuleForTests("bar", "android_common").Output("javac/bar.jar")
- baz := ctx.ModuleForTests("baz", "android_common").Output("javac/baz.jar")
- barCombined := ctx.ModuleForTests("bar", "android_common").Output("combined/bar.jar")
+ foo := ctx.ModuleForTests(t, "foo", "android_common").Output("javac/foo.jar")
+ jargen := ctx.ModuleForTests(t, "jargen", "android_common").Output("jargen.jar")
+ bar := ctx.ModuleForTests(t, "bar", "android_common").Output("javac/bar.jar")
+ baz := ctx.ModuleForTests(t, "baz", "android_common").Output("javac/baz.jar")
+ barCombined := ctx.ModuleForTests(t, "bar", "android_common").Output("combined/bar.jar")
if g, w := jargen.Implicits.Strings(), foo.Output.String(); !android.InList(w, g) {
t.Errorf("expected jargen inputs [%q], got %q", w, g)
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index b1a9deb..c9a1f2b 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -97,7 +97,7 @@
// Save the classes jars even if this is not active as they may be used by modular hidden API
// processing.
classesJars := android.Paths{classesJar}
- ctx.VisitDirectDepsWithTag(hiddenApiAnnotationsTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(hiddenApiAnnotationsTag, func(dep android.ModuleProxy) {
if javaInfo, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok {
classesJars = append(classesJars, javaInfo.ImplementationJars...)
}
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index 7d21b7a..2c86942 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -171,11 +171,11 @@
// Now match the apex part of the boot image configuration.
requiredApex := configuredBootJars.Apex(index)
if android.IsConfiguredJarForPlatform(requiredApex) {
- if len(apexInfo.InApexVariants) != 0 {
+ if apexInfo.ApexVariationName != "" {
// A platform variant is required but this is for an apex so ignore it.
return false
}
- } else if !apexInfo.InApexVariant(requiredApex) {
+ } else if apexInfo.BaseApexName != requiredApex {
// An apex variant for a specific apex is required but this is the wrong apex.
return false
}
diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go
index afe8b4c..147f326 100644
--- a/java/hiddenapi_singleton_test.go
+++ b/java/hiddenapi_singleton_test.go
@@ -44,6 +44,7 @@
)
func TestHiddenAPISingleton(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
FixtureConfigureBootJars("platform:foo"),
@@ -56,13 +57,14 @@
}
`)
- hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
+ hiddenAPI := result.ModuleForTests(t, "platform-bootclasspath", "android_common")
hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
want := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar"
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, want)
}
func TestHiddenAPISingletonWithSourceAndPrebuiltPreferredButNoDex(t *testing.T) {
+ t.Parallel()
expectedErrorMessage := "module prebuilt_foo{os:android,arch:common} does not provide a dex jar"
android.GroupFixturePreparers(
@@ -86,6 +88,7 @@
}
func TestHiddenAPISingletonWithPrebuilt(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
FixtureConfigureBootJars("platform:foo"),
@@ -98,13 +101,14 @@
}
`)
- hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
+ hiddenAPI := result.ModuleForTests(t, "platform-bootclasspath", "android_common")
hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
want := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar"
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, want)
}
func TestHiddenAPISingletonWithPrebuiltUseSource(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
FixtureConfigureBootJars("platform:foo"),
@@ -124,7 +128,7 @@
}
`)
- hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
+ hiddenAPI := result.ModuleForTests(t, "platform-bootclasspath", "android_common")
hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
fromSourceJarArg := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar"
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, fromSourceJarArg)
@@ -134,6 +138,7 @@
}
func TestHiddenAPISingletonWithPrebuiltOverrideSource(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
FixtureConfigureBootJars("platform:foo"),
@@ -153,7 +158,7 @@
}
`)
- hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
+ hiddenAPI := result.ModuleForTests(t, "platform-bootclasspath", "android_common")
hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
prebuiltJarArg := "--boot-dex=out/soong/.intermediates/prebuilt_foo/android_common/dex/foo.jar"
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, prebuiltJarArg)
@@ -163,6 +168,7 @@
}
func TestHiddenAPISingletonSdks(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
unbundledBuild bool
@@ -213,7 +219,7 @@
}
`)
- hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
+ hiddenAPI := result.ModuleForTests(t, "platform-bootclasspath", "android_common")
hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
wantPublicStubs := "--public-stub-classpath=" + generateSdkDexPath(tc.publicStub, tc.unbundledBuild)
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, wantPublicStubs)
@@ -246,6 +252,7 @@
}
func TestHiddenAPISingletonWithPrebuiltCsvFile(t *testing.T) {
+ t.Parallel()
// The idea behind this test is to ensure that when the build is
// confugured with a PrebuiltHiddenApiDir that the rules for the
@@ -272,9 +279,9 @@
expectedCpOutput := "out/soong/hiddenapi/hiddenapi-flags.csv"
expectedFlagsCsv := "out/soong/hiddenapi/hiddenapi-flags.csv"
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
- hiddenAPI := result.SingletonForTests("hiddenapi")
+ hiddenAPI := result.SingletonForTests(t, "hiddenapi")
cpRule := hiddenAPI.Rule("Cp")
actualCpInput := cpRule.BuildParams.Input
actualCpOutput := cpRule.BuildParams.Output
@@ -289,6 +296,7 @@
}
func TestHiddenAPIEncoding_JavaSdkLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
@@ -310,7 +318,7 @@
`)
checkDexEncoded := func(t *testing.T, name, unencodedDexJar, encodedDexJar string) {
- moduleForTests := result.ModuleForTests(name+".impl", "android_common")
+ moduleForTests := result.ModuleForTests(t, name+".impl", "android_common")
encodeDexRule := moduleForTests.Rule("hiddenAPIEncodeDex")
actualUnencodedDexJar := encodeDexRule.Input
@@ -324,10 +332,7 @@
android.AssertPathRelativeToTopEquals(t, "encode embedded java_library", encodedDexJar, exportedDexJar)
}
- // The java_library embedded with the java_sdk_library must be dex encoded.
- t.Run("foo", func(t *testing.T) {
- expectedUnencodedDexJar := "out/soong/.intermediates/foo.impl/android_common/aligned/foo.jar"
- expectedEncodedDexJar := "out/soong/.intermediates/foo.impl/android_common/hiddenapi/foo.jar"
- checkDexEncoded(t, "foo", expectedUnencodedDexJar, expectedEncodedDexJar)
- })
+ expectedUnencodedDexJar := "out/soong/.intermediates/foo.impl/android_common/aligned/foo.jar"
+ expectedEncodedDexJar := "out/soong/.intermediates/foo.impl/android_common/hiddenapi/foo.jar"
+ checkDexEncoded(t, "foo", expectedUnencodedDexJar, expectedEncodedDexJar)
}
diff --git a/java/jacoco_test.go b/java/jacoco_test.go
index 1882908..58a091e 100644
--- a/java/jacoco_test.go
+++ b/java/jacoco_test.go
@@ -17,6 +17,7 @@
import "testing"
func TestJacocoFilterToSpecs(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name, in, out string
}{
@@ -54,6 +55,7 @@
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
got, err := jacocoFilterToSpec(testCase.in)
if err != nil {
t.Error(err)
@@ -66,6 +68,7 @@
}
func TestJacocoFiltersToZipCommand(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
includes, excludes []string
@@ -96,6 +99,7 @@
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
got := jacocoFiltersToZipCommand(testCase.includes, testCase.excludes)
if got != testCase.out {
t.Errorf("expected %q got %q", testCase.out, got)
diff --git a/java/jarjar_test.go b/java/jarjar_test.go
index 82bfa2b..b689761 100644
--- a/java/jarjar_test.go
+++ b/java/jarjar_test.go
@@ -22,7 +22,7 @@
)
func AssertJarJarRename(t *testing.T, result *android.TestResult, libName, original, expectedRename string) {
- module := result.ModuleForTests(libName, "android_common")
+ module := result.ModuleForTests(t, libName, "android_common")
provider, found := android.OtherModuleProvider(result.OtherModuleProviderAdaptor(), module.Module(), JarJarProvider)
android.AssertBoolEquals(t, fmt.Sprintf("found provider (%s)", libName), true, found)
diff --git a/java/java.go b/java/java.go
index 48ba8de..b18c561 100644
--- a/java/java.go
+++ b/java/java.go
@@ -64,6 +64,7 @@
ctx.RegisterModuleType("java_api_library", ApiLibraryFactory)
ctx.RegisterModuleType("java_api_contribution", ApiContributionFactory)
ctx.RegisterModuleType("java_api_contribution_import", ApiContributionImportFactory)
+ ctx.RegisterModuleType("java_genrule_combiner", GenruleCombinerFactory)
// This mutator registers dependencies on dex2oat for modules that should be
// dexpreopted. This is done late when the final variants have been
@@ -258,7 +259,6 @@
}
type UsesLibraryDependencyInfo struct {
- DexJarBuildPath OptionalDexJarPath
DexJarInstallPath android.Path
ClassLoaderContexts dexpreopt.ClassLoaderContextMap
}
@@ -276,6 +276,11 @@
UsesLibrary *usesLibrary
}
+type ModuleWithSdkDepInfo struct {
+ SdkLinkType sdkLinkType
+ Stubs bool
+}
+
// JavaInfo contains information about a java module for use by modules that depend on it.
type JavaInfo struct {
// HeaderJars is a list of jars that can be passed as the javac classpath in order to link
@@ -355,6 +360,11 @@
SdkVersion android.SdkSpec
+ // output file of the module, which may be a classes jar or a dex jar
+ OutputFile android.Path
+
+ ExtraOutputFiles android.Paths
+
AndroidLibraryDependencyInfo *AndroidLibraryDependencyInfo
UsesLibraryDependencyInfo *UsesLibraryDependencyInfo
@@ -363,11 +373,92 @@
ProvidesUsesLibInfo *ProvidesUsesLibInfo
- ModuleWithUsesLibraryInfo *ModuleWithUsesLibraryInfo
+ MissingOptionalUsesLibs []string
+
+ ModuleWithSdkDepInfo *ModuleWithSdkDepInfo
+
+ // output file containing classes.dex and resources
+ DexJarFile OptionalDexJarPath
+
+ // installed file for binary dependency
+ InstallFile android.Path
+
+ // The path to the dex jar that is in the boot class path. If this is unset then the associated
+ // module is not a boot jar, but could be one of the <x>-hiddenapi modules that provide additional
+ // annotations for the <x> boot dex jar but which do not actually provide a boot dex jar
+ // themselves.
+ //
+ // This must be the path to the unencoded dex jar as the encoded dex jar indirectly depends on
+ // this file so using the encoded dex jar here would result in a cycle in the ninja rules.
+ BootDexJarPath OptionalDexJarPath
+
+ // The compressed state of the dex file being encoded. This is used to ensure that the encoded
+ // dex file has the same state.
+ UncompressDexState *bool
+
+ // True if the module containing this structure contributes to the hiddenapi information or has
+ // that information encoded within it.
+ Active bool
+
+ BuiltInstalled string
+
+ // The config is used for two purposes:
+ // - Passing dexpreopt information about libraries from Soong to Make. This is needed when
+ // a <uses-library> is defined in Android.bp, but used in Android.mk (see dex_preopt_config_merger.py).
+ // Note that dexpreopt.config might be needed even if dexpreopt is disabled for the library itself.
+ // - Dexpreopt post-processing (using dexpreopt artifacts from a prebuilt system image to incrementally
+ // dexpreopt another partition).
+ ConfigPath android.WritablePath
+
+ LogtagsSrcs android.Paths
+
+ ProguardDictionary android.OptionalPath
+
+ ProguardUsageZip android.OptionalPath
+
+ LinterReports android.Paths
+
+ // installed file for hostdex copy
+ HostdexInstallFile android.InstallPath
+
+ // Additional srcJars tacked in by GeneratedJavaLibraryModule
+ GeneratedSrcjars []android.Path
+
+ // True if profile-guided optimization is actually enabled.
+ ProfileGuided bool
+
+ Stem string
+
+ DexJarBuildPath OptionalDexJarPath
+
+ DexpreopterInfo *DexpreopterInfo
}
var JavaInfoProvider = blueprint.NewProvider[*JavaInfo]()
+type DexpreopterInfo struct {
+ // The path to the profile on host that dexpreopter generates. This is used as the input for
+ // dex2oat.
+ OutputProfilePathOnHost android.Path
+ // If the java module is to be installed into an APEX, this list contains information about the
+ // dexpreopt outputs to be installed on devices. Note that these dexpreopt outputs are installed
+ // outside of the APEX.
+ ApexSystemServerDexpreoptInstalls []DexpreopterInstall
+
+ // ApexSystemServerDexJars returns the list of dex jars if this is an apex system server jar.
+ ApexSystemServerDexJars android.Paths
+}
+
+type JavaLibraryInfo struct {
+ Prebuilt bool
+}
+
+var JavaLibraryInfoProvider = blueprint.NewProvider[JavaLibraryInfo]()
+
+type JavaDexImportInfo struct{}
+
+var JavaDexImportInfoProvider = blueprint.NewProvider[JavaDexImportInfo]()
+
// SyspropPublicStubInfo contains info about the sysprop public stub library that corresponds to
// the sysprop implementation library.
type SyspropPublicStubInfo struct {
@@ -518,7 +609,7 @@
)
func IsLibDepTag(depTag blueprint.DependencyTag) bool {
- return depTag == libTag || depTag == sdkLibTag
+ return depTag == libTag
}
func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool {
@@ -629,11 +720,11 @@
transitiveStaticLibsResourceJars []depset.DepSet[android.Path]
}
-func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer) {
- for _, f := range dep.Srcs() {
+func checkProducesJars(ctx android.ModuleContext, dep android.SourceFilesInfo, module android.ModuleProxy) {
+ for _, f := range dep.Srcs {
if f.Ext() != ".jar" {
ctx.ModuleErrorf("genrule %q must generate files ending with .jar to be used as a libs or static_libs dependency",
- ctx.OtherModuleName(dep.(blueprint.Module)))
+ ctx.OtherModuleName(module))
}
}
}
@@ -751,6 +842,8 @@
combinedExportedProguardFlagsFile android.Path
InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.InstallPaths)
+
+ apiXmlFile android.WritablePath
}
var _ android.ApexModule = (*Library)(nil)
@@ -1047,12 +1140,97 @@
TopLevelTarget: j.sourceProperties.Top_level_test_target,
})
+ android.SetProvider(ctx, JavaLibraryInfoProvider, JavaLibraryInfo{
+ Prebuilt: false,
+ })
+
if javaInfo != nil {
setExtraJavaInfo(ctx, j, javaInfo)
+ javaInfo.ExtraOutputFiles = j.extraOutputFiles
+ javaInfo.DexJarFile = j.dexJarFile
+ javaInfo.InstallFile = j.installFile
+ javaInfo.BootDexJarPath = j.bootDexJarPath
+ javaInfo.UncompressDexState = j.uncompressDexState
+ javaInfo.Active = j.active
+ javaInfo.BuiltInstalled = j.builtInstalled
+ javaInfo.ConfigPath = j.configPath
+ javaInfo.LogtagsSrcs = j.logtagsSrcs
+ javaInfo.ProguardDictionary = j.proguardDictionary
+ javaInfo.ProguardUsageZip = j.proguardUsageZip
+ javaInfo.LinterReports = j.reports
+ javaInfo.HostdexInstallFile = j.hostdexInstallFile
+ javaInfo.GeneratedSrcjars = j.properties.Generated_srcjars
+ javaInfo.ProfileGuided = j.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided
+
android.SetProvider(ctx, JavaInfoProvider, javaInfo)
}
setOutputFiles(ctx, j.Module)
+
+ j.javaLibraryModuleInfoJSON(ctx)
+
+ buildComplianceMetadata(ctx)
+
+ j.createApiXmlFile(ctx)
+
+ if j.dexer.proguardDictionary.Valid() {
+ android.SetProvider(ctx, ProguardProvider, ProguardInfo{
+ ModuleName: ctx.ModuleName(),
+ Class: "JAVA_LIBRARIES",
+ ProguardDictionary: j.dexer.proguardDictionary.Path(),
+ ProguardUsageZip: j.dexer.proguardUsageZip.Path(),
+ ClassesJar: j.implementationAndResourcesJar,
+ })
+ }
+}
+
+func (j *Library) javaLibraryModuleInfoJSON(ctx android.ModuleContext) *android.ModuleInfoJSON {
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Class = []string{"JAVA_LIBRARIES"}
+ if j.implementationAndResourcesJar != nil {
+ moduleInfoJSON.ClassesJar = []string{j.implementationAndResourcesJar.String()}
+ }
+ moduleInfoJSON.SystemSharedLibs = []string{"none"}
+
+ if j.hostDexNeeded() {
+ hostDexModuleInfoJSON := ctx.ExtraModuleInfoJSON()
+ hostDexModuleInfoJSON.SubName = "-hostdex"
+ hostDexModuleInfoJSON.Class = []string{"JAVA_LIBRARIES"}
+ if j.implementationAndResourcesJar != nil {
+ hostDexModuleInfoJSON.ClassesJar = []string{j.implementationAndResourcesJar.String()}
+ }
+ hostDexModuleInfoJSON.SystemSharedLibs = []string{"none"}
+ hostDexModuleInfoJSON.SupportedVariantsOverride = []string{"HOST"}
+ }
+
+ if j.hideApexVariantFromMake {
+ moduleInfoJSON.Disabled = true
+ }
+ return moduleInfoJSON
+}
+
+func buildComplianceMetadata(ctx android.ModuleContext) {
+ // Dump metadata that can not be done in android/compliance-metadata.go
+ complianceMetadataInfo := ctx.ComplianceMetadataInfo()
+ builtFiles := ctx.GetOutputFiles().DefaultOutputFiles.Strings()
+ for _, paths := range ctx.GetOutputFiles().TaggedOutputFiles {
+ builtFiles = append(builtFiles, paths.Strings()...)
+ }
+ complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.BUILT_FILES, android.SortedUniqueStrings(builtFiles))
+
+ // Static deps
+ staticDepNames := make([]string, 0)
+ staticDepFiles := android.Paths{}
+ ctx.VisitDirectDepsWithTag(staticLibTag, func(module android.Module) {
+ if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
+ staticDepNames = append(staticDepNames, module.Name())
+ staticDepFiles = append(staticDepFiles, dep.ImplementationJars...)
+ staticDepFiles = append(staticDepFiles, dep.HeaderJars...)
+ staticDepFiles = append(staticDepFiles, dep.ResourceJars...)
+ }
+ })
+ complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEPS, android.SortedUniqueStrings(staticDepNames))
+ complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEP_FILES, android.SortedUniqueStrings(staticDepFiles.Strings()))
}
func (j *Library) getJarInstallDir(ctx android.ModuleContext) android.InstallPath {
@@ -1108,6 +1286,28 @@
}
}
+var apiXMLGeneratingApiSurfaces = []android.SdkKind{
+ android.SdkPublic,
+ android.SdkSystem,
+ android.SdkModule,
+ android.SdkSystemServer,
+ android.SdkTest,
+}
+
+func (j *Library) createApiXmlFile(ctx android.ModuleContext) {
+ if kind, ok := android.JavaLibraryNameToSdkKind(ctx.ModuleName()); ok && android.InList(kind, apiXMLGeneratingApiSurfaces) {
+ scopePrefix := AllApiScopes.matchingScopeFromSdkKind(kind).apiFilePrefix
+ j.apiXmlFile = android.PathForModuleOut(ctx, fmt.Sprintf("%sapi.xml", scopePrefix))
+ ctx.Build(pctx, android.BuildParams{
+ Rule: generateApiXMLRule,
+ // LOCAL_SOONG_CLASSES_JAR
+ Input: j.implementationAndResourcesJar,
+ Output: j.apiXmlFile,
+ })
+ ctx.DistForGoal("dist_files", j.apiXmlFile)
+ }
+}
+
const (
aidlIncludeDir = "aidl"
javaDir = "java"
@@ -1349,6 +1549,11 @@
// host test.
Device_first_prefer32_data []string `android:"path_device_first_prefer32"`
+ // Same as data, but will add dependencies on modules using the host's os variation and
+ // the common arch variation. Useful for a device test that wants to depend on a host
+ // module, for example to include a custom Tradefed test runner.
+ Host_common_data []string `android:"path_host_common"`
+
// Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
// doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
// explicitly.
@@ -1611,6 +1816,11 @@
MkInclude: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
MkAppClass: "JAVA_LIBRARIES",
})
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ if proptools.Bool(j.testProperties.Test_options.Unit_test) {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "host-unit-tests")
+ }
}
func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -1642,20 +1852,21 @@
j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Device_common_data)...)
j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Device_first_data)...)
j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Device_first_prefer32_data)...)
+ j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Host_common_data)...)
j.extraTestConfigs = android.PathsForModuleSrc(ctx, j.testProperties.Test_options.Extra_test_configs)
- ctx.VisitDirectDepsWithTag(dataNativeBinsTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(dataNativeBinsTag, func(dep android.ModuleProxy) {
j.data = append(j.data, android.OutputFileForModule(ctx, dep, ""))
})
- ctx.VisitDirectDepsWithTag(dataDeviceBinsTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(dataDeviceBinsTag, func(dep android.ModuleProxy) {
j.data = append(j.data, android.OutputFileForModule(ctx, dep, ""))
})
var directImplementationDeps android.Paths
var transitiveImplementationDeps []depset.DepSet[android.Path]
- ctx.VisitDirectDepsWithTag(jniLibTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(jniLibTag, func(dep android.ModuleProxy) {
sharedLibInfo, _ := android.OtherModuleProvider(ctx, dep, cc.SharedLibraryInfoProvider)
if sharedLibInfo.SharedLibrary != nil {
// Copy to an intermediate output directory to append "lib[64]" to the path,
@@ -1688,10 +1899,74 @@
})
j.Library.GenerateAndroidBuildActions(ctx)
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ // LOCAL_MODULE_TAGS
+ moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
+ var allTestConfigs android.Paths
+ if j.testConfig != nil {
+ allTestConfigs = append(allTestConfigs, j.testConfig)
+ }
+ allTestConfigs = append(allTestConfigs, j.extraTestConfigs...)
+ if len(allTestConfigs) > 0 {
+ moduleInfoJSON.TestConfig = allTestConfigs.Strings()
+ } else {
+ optionalConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml")
+ if optionalConfig.Valid() {
+ moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, optionalConfig.String())
+ }
+ }
+ if len(j.testProperties.Test_suites) > 0 {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, j.testProperties.Test_suites...)
+ } else {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
+ }
+ if _, ok := j.testConfig.(android.WritablePath); ok {
+ moduleInfoJSON.AutoTestConfig = []string{"true"}
+ }
+ if proptools.Bool(j.testProperties.Test_options.Unit_test) {
+ moduleInfoJSON.IsUnitTest = "true"
+ if ctx.Host() {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "host-unit-tests")
+ }
+ }
+ moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, j.testProperties.Test_mainline_modules...)
+
+ // Install test deps
+ if !ctx.Config().KatiEnabled() {
+ pathInTestCases := android.PathForModuleInstall(ctx, "testcases", ctx.ModuleName())
+ if j.testConfig != nil {
+ ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".config", j.testConfig)
+ }
+ dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml")
+ if dynamicConfig.Valid() {
+ ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".dynamic", dynamicConfig.Path())
+ }
+ testDeps := append(j.data, j.extraTestConfigs...)
+ for _, data := range android.SortedUniquePaths(testDeps) {
+ dataPath := android.DataPath{SrcPath: data}
+ ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath})
+ }
+ if j.outputFile != nil {
+ ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".jar", j.outputFile)
+ }
+ }
}
func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.Library.GenerateAndroidBuildActions(ctx)
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
+ if len(j.testHelperLibraryProperties.Test_suites) > 0 {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, j.testHelperLibraryProperties.Test_suites...)
+ } else {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
+ }
+ optionalConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml")
+ if optionalConfig.Valid() {
+ moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, optionalConfig.String())
+ }
}
func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -1945,13 +2220,13 @@
// Set the jniLibs of this binary.
// These will be added to `LOCAL_REQUIRED_MODULES`, and the kati packaging system will
// install these alongside the java binary.
- ctx.VisitDirectDepsWithTag(jniInstallTag, func(jni android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(jniInstallTag, func(jni android.ModuleProxy) {
// Use the BaseModuleName of the dependency (without any prebuilt_ prefix)
- bmn, _ := jni.(interface{ BaseModuleName() string })
- j.androidMkNamesOfJniLibs = append(j.androidMkNamesOfJniLibs, bmn.BaseModuleName()+":"+jni.Target().Arch.ArchType.Bitness())
+ commonInfo, _ := android.OtherModuleProvider(ctx, jni, android.CommonModuleInfoKey)
+ j.androidMkNamesOfJniLibs = append(j.androidMkNamesOfJniLibs, commonInfo.BaseModuleName+":"+commonInfo.Target.Arch.ArchType.Bitness())
})
// Check that native libraries are not listed in `required`. Prompt users to use `jni_libs` instead.
- ctx.VisitDirectDepsWithTag(android.RequiredDepTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(android.RequiredDepTag, func(dep android.ModuleProxy) {
if _, hasSharedLibraryInfo := android.OtherModuleProvider(ctx, dep, cc.SharedLibraryInfoProvider); hasSharedLibraryInfo {
ctx.ModuleErrorf("cc_library %s is no longer supported in `required` of java_binary modules. Please use jni_libs instead.", dep.Name())
}
@@ -2170,7 +2445,7 @@
func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
srcs android.Paths, homeDir android.WritablePath,
- classpath android.Paths, configFiles android.Paths) *android.RuleBuilderCommand {
+ classpath android.Paths, configFiles android.Paths, apiSurface *string) *android.RuleBuilderCommand {
rule.Command().Text("rm -rf").Flag(homeDir.String())
rule.Command().Text("mkdir -p").Flag(homeDir.String())
@@ -2211,6 +2486,8 @@
addMetalavaConfigFilesToCmd(cmd, configFiles)
+ addOptionalApiSurfaceToCmd(cmd, apiSurface)
+
if len(classpath) == 0 {
// The main purpose of the `--api-class-resolution api` option is to force metalava to ignore
// classes on the classpath when an API file contains missing classes. However, as this command
@@ -2294,6 +2571,17 @@
var scopeOrderMap = AllApiScopes.MapToIndex(
func(s *apiScope) string { return s.name })
+// Add some extra entries into scopeOrderMap for some special api surface names needed by libcore,
+// external/conscrypt and external/icu and java/core-libraries.
+func init() {
+ count := len(scopeOrderMap)
+ scopeOrderMap["core"] = count + 1
+ scopeOrderMap["core-platform"] = count + 2
+ scopeOrderMap["intra-core"] = count + 3
+ scopeOrderMap["core-platform-plus-public"] = count + 4
+ scopeOrderMap["core-platform-legacy"] = count + 5
+}
+
func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFilesInfo []JavaApiImportInfo) []JavaApiImportInfo {
for _, srcFileInfo := range srcFilesInfo {
if srcFileInfo.ApiSurface == "" {
@@ -2342,7 +2630,7 @@
var bootclassPaths android.Paths
var staticLibs android.Paths
var systemModulesPaths android.Paths
- ctx.VisitDirectDeps(func(dep android.Module) {
+ ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(dep)
switch tag {
case javaApiContributionTag:
@@ -2371,8 +2659,8 @@
systemModulesPaths = append(systemModulesPaths, sm.HeaderJars...)
}
case metalavaCurrentApiTimestampTag:
- if currentApiTimestampProvider, ok := dep.(currentApiTimestampProvider); ok {
- al.validationPaths = append(al.validationPaths, currentApiTimestampProvider.CurrentApiTimestamp())
+ if currentApiTimestampProvider, ok := android.OtherModuleProvider(ctx, dep, DroidStubsInfoProvider); ok {
+ al.validationPaths = append(al.validationPaths, currentApiTimestampProvider.CurrentApiTimestamp)
}
case aconfigDeclarationTag:
if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
@@ -2404,7 +2692,7 @@
combinedPaths := append(([]android.Path)(nil), systemModulesPaths...)
combinedPaths = append(combinedPaths, classPaths...)
combinedPaths = append(combinedPaths, bootclassPaths...)
- cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir, combinedPaths, configFiles)
+ cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir, combinedPaths, configFiles, al.properties.Api_surface)
al.stubsFlags(ctx, cmd, stubsDir)
@@ -2748,7 +3036,7 @@
var staticJars android.Paths
var staticResourceJars android.Paths
var staticHeaderJars android.Paths
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(module)
if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
switch tag {
@@ -2800,12 +3088,7 @@
// file of the module to be named jarName.
var outputFile android.Path
combinedImplementationJar := android.PathForModuleOut(ctx, "combined", jarName)
- var implementationJars android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- implementationJars = completeStaticLibsImplementationJars.ToList()
- } else {
- implementationJars = append(slices.Clone(localJars), staticJars...)
- }
+ implementationJars := completeStaticLibsImplementationJars.ToList()
TransformJarsToJar(ctx, combinedImplementationJar, "combine prebuilt implementation jars", implementationJars, android.OptionalPath{},
false, j.properties.Exclude_files, j.properties.Exclude_dirs)
outputFile = combinedImplementationJar
@@ -2828,12 +3111,7 @@
if reuseImplementationJarAsHeaderJar {
headerJar = outputFile
} else {
- var headerJars android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- headerJars = completeStaticLibsHeaderJars.ToList()
- } else {
- headerJars = append(slices.Clone(localJars), staticHeaderJars...)
- }
+ headerJars := completeStaticLibsHeaderJars.ToList()
headerOutputFile := android.PathForModuleOut(ctx, "turbine-combined", jarName)
TransformJarsToJar(ctx, headerOutputFile, "combine prebuilt header jars", headerJars, android.OptionalPath{},
false, j.properties.Exclude_files, j.properties.Exclude_dirs)
@@ -2897,11 +3175,7 @@
j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs)
- if ctx.Config().UseTransitiveJarsInClasspath() {
- ctx.CheckbuildFile(localJars...)
- } else {
- ctx.CheckbuildFile(outputFile)
- }
+ ctx.CheckbuildFile(localJars...)
if ctx.Device() {
// Shared libraries deapexed from prebuilt apexes are no longer supported.
@@ -2973,8 +3247,14 @@
setExtraJavaInfo(ctx, j, javaInfo)
android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+ android.SetProvider(ctx, JavaLibraryInfoProvider, JavaLibraryInfo{
+ Prebuilt: true,
+ })
+
ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, "")
ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, ".jar")
+
+ buildComplianceMetadata(ctx)
}
func (j *Import) maybeInstall(ctx android.ModuleContext, jarName string, outputFile android.Path) {
@@ -3021,26 +3301,29 @@
var _ android.ApexModule = (*Import)(nil)
// Implements android.ApexModule
-func (j *Import) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
- return j.depIsInSameApex(tag)
+func (m *Import) GetDepInSameApexChecker() android.DepInSameApexChecker {
+ return JavaImportDepInSameApexChecker{}
+}
+
+type JavaImportDepInSameApexChecker struct {
+ android.BaseDepInSameApexChecker
+}
+
+func (m JavaImportDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
+ return depIsInSameApex(tag)
}
// Implements android.ApexModule
-func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
- sdkVersion android.ApiLevel) error {
+func (j *Import) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
sdkVersionSpec := j.SdkVersion(ctx)
minSdkVersion := j.MinSdkVersion(ctx)
- if !minSdkVersion.Specified() {
- return fmt.Errorf("min_sdk_version is not specified")
- }
+
// If the module is compiling against core (via sdk_version), skip comparison check.
if sdkVersionSpec.Kind == android.SdkCore {
- return nil
+ return android.MinApiLevel
}
- if minSdkVersion.GreaterThan(sdkVersion) {
- return fmt.Errorf("newer SDK(%v)", minSdkVersion)
- }
- return nil
+
+ return minSdkVersion
}
// requiredFilesFromPrebuiltApexForImport returns information about the files that a java_import or
@@ -3247,6 +3530,12 @@
ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
j.Stem()+".jar", dexOutputFile)
}
+
+ javaInfo := &JavaInfo{}
+ setExtraJavaInfo(ctx, j, javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+
+ android.SetProvider(ctx, JavaDexImportInfoProvider, JavaDexImportInfo{})
}
func (j *DexImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
@@ -3256,10 +3545,8 @@
var _ android.ApexModule = (*DexImport)(nil)
// Implements android.ApexModule
-func (j *DexImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
- sdkVersion android.ApiLevel) error {
- // we don't check prebuilt modules for sdk_version
- return nil
+func (m *DexImport) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
+ return android.MinApiLevel
}
// dex_import imports a `.jar` file containing classes.dex files.
@@ -3281,7 +3568,6 @@
type Defaults struct {
android.ModuleBase
android.DefaultsModuleBase
- android.ApexModuleBase
}
// java_defaults provides a set of properties that can be inherited by other java or android modules.
@@ -3345,6 +3631,8 @@
&bootclasspathFragmentProperties{},
&SourceOnlyBootclasspathProperties{},
&ravenwoodTestProperties{},
+ &AndroidAppImportProperties{},
+ &UsesLibraryProperties{},
)
android.InitDefaultsModule(module)
@@ -3382,7 +3670,7 @@
var inList = android.InList[string]
// Add class loader context (CLC) of a given dependency to the current CLC.
-func addCLCFromDep(ctx android.ModuleContext, depModule android.Module,
+func addCLCFromDep(ctx android.ModuleContext, depModule android.ModuleProxy,
clcMap dexpreopt.ClassLoaderContextMap) {
dep, ok := android.OtherModuleProvider(ctx, depModule, JavaInfoProvider)
@@ -3435,22 +3723,22 @@
}
}
clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, optional,
- dep.UsesLibraryDependencyInfo.DexJarBuildPath.PathOrNil(),
+ dep.DexJarBuildPath.PathOrNil(),
dep.UsesLibraryDependencyInfo.DexJarInstallPath, dep.UsesLibraryDependencyInfo.ClassLoaderContexts)
} else {
clcMap.AddContextMap(dep.UsesLibraryDependencyInfo.ClassLoaderContexts, depName)
}
}
-func addMissingOptionalUsesLibsFromDep(ctx android.ModuleContext, depModule android.Module,
+func addMissingOptionalUsesLibsFromDep(ctx android.ModuleContext, depModule android.ModuleProxy,
usesLibrary *usesLibrary) {
dep, ok := android.OtherModuleProvider(ctx, depModule, JavaInfoProvider)
- if !ok || dep.ModuleWithUsesLibraryInfo == nil {
+ if !ok {
return
}
- for _, lib := range dep.ModuleWithUsesLibraryInfo.UsesLibrary.usesLibraryProperties.Missing_optional_uses_libs {
+ for _, lib := range dep.MissingOptionalUsesLibs {
if !android.InList(lib, usesLibrary.usesLibraryProperties.Missing_optional_uses_libs) {
usesLibrary.usesLibraryProperties.Missing_optional_uses_libs =
append(usesLibrary.usesLibraryProperties.Missing_optional_uses_libs, lib)
@@ -3519,7 +3807,6 @@
if ulDep, ok := module.(UsesLibraryDependency); ok {
javaInfo.UsesLibraryDependencyInfo = &UsesLibraryDependencyInfo{
- DexJarBuildPath: ulDep.DexJarBuildPath(ctx),
DexJarInstallPath: ulDep.DexJarInstallPath(),
ClassLoaderContexts: ulDep.ClassLoaderContexts(),
}
@@ -3538,8 +3825,32 @@
}
if mwul, ok := module.(ModuleWithUsesLibrary); ok {
- javaInfo.ModuleWithUsesLibraryInfo = &ModuleWithUsesLibraryInfo{
- UsesLibrary: mwul.UsesLibrary(),
+ javaInfo.MissingOptionalUsesLibs = mwul.UsesLibrary().usesLibraryProperties.Missing_optional_uses_libs
+ }
+
+ if mwsd, ok := module.(moduleWithSdkDep); ok {
+ linkType, stubs := mwsd.getSdkLinkType(ctx, ctx.ModuleName())
+ javaInfo.ModuleWithSdkDepInfo = &ModuleWithSdkDepInfo{
+ SdkLinkType: linkType,
+ Stubs: stubs,
+ }
+ }
+
+ if st, ok := module.(ModuleWithStem); ok {
+ javaInfo.Stem = st.Stem()
+ }
+
+ if mm, ok := module.(interface {
+ DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath
+ }); ok {
+ javaInfo.DexJarBuildPath = mm.DexJarBuildPath(ctx)
+ }
+
+ if di, ok := module.(DexpreopterInterface); ok {
+ javaInfo.DexpreopterInfo = &DexpreopterInfo{
+ OutputProfilePathOnHost: di.OutputProfilePathOnHost(),
+ ApexSystemServerDexpreoptInstalls: di.ApexSystemServerDexpreoptInstalls(),
+ ApexSystemServerDexJars: di.ApexSystemServerDexJars(),
}
}
}
diff --git a/java/java_test.go b/java/java_test.go
index d415679..a6290a6 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -110,13 +110,14 @@
case strings.HasSuffix(name, ".jar"):
return name
default:
- return filepath.Join("out", "soong", ".intermediates", defaultJavaDir, name, "android_common", "turbine-combined", name+".jar")
+ return filepath.Join("out", "soong", ".intermediates", defaultJavaDir, name, "android_common", "turbine", name+".jar")
}
}
// Test that the PrepareForTestWithJavaDefaultModules provides all the files that it uses by
// running it in a fixture that requires all source files to exist.
func TestPrepareForTestWithJavaDefaultModules(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.PrepareForTestDisallowNonExistentPaths,
@@ -124,6 +125,7 @@
}
func TestJavaLinkType(t *testing.T) {
+ t.Parallel()
testJava(t, `
java_library {
name: "foo",
@@ -212,6 +214,7 @@
}
func TestSimple(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "foo",
@@ -237,11 +240,6 @@
srcs: ["d.java"],
}`
- frameworkTurbineCombinedJars := []string{
- "out/soong/.intermediates/default/java/ext/android_common/turbine-combined/ext.jar",
- "out/soong/.intermediates/default/java/framework/android_common/turbine-combined/framework.jar",
- }
-
frameworkTurbineJars := []string{
"out/soong/.intermediates/default/java/ext/android_common/turbine/ext.jar",
"out/soong/.intermediates/default/java/framework/android_common/turbine/framework.jar",
@@ -267,43 +265,6 @@
preparer: android.NullFixturePreparer,
fooJavacInputs: []string{"a.java"},
fooJavacClasspath: slices.Concat(
- frameworkTurbineCombinedJars,
- []string{
- "out/soong/.intermediates/bar/android_common/turbine-combined/bar.jar",
- "out/soong/.intermediates/baz/android_common/turbine-combined/baz.jar",
- },
- ),
- fooCombinedInputs: []string{
- "out/soong/.intermediates/foo/android_common/javac/foo.jar",
- "out/soong/.intermediates/baz/android_common/combined/baz.jar",
- },
-
- fooHeaderCombinedInputs: []string{
- "out/soong/.intermediates/foo/android_common/turbine/foo.jar",
- "out/soong/.intermediates/baz/android_common/turbine-combined/baz.jar",
- },
-
- barJavacInputs: []string{"b.java"},
- barJavacClasspath: slices.Concat(
- frameworkTurbineCombinedJars,
- []string{
- "out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar",
- },
- ),
- barCombinedInputs: []string{
- "out/soong/.intermediates/bar/android_common/javac/bar.jar",
- "out/soong/.intermediates/quz/android_common/javac/quz.jar",
- },
- barHeaderCombinedInputs: []string{
- "out/soong/.intermediates/bar/android_common/turbine/bar.jar",
- "out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar",
- },
- },
- {
- name: "transitive classpath",
- preparer: PrepareForTestWithTransitiveClasspathEnabled,
- fooJavacInputs: []string{"a.java"},
- fooJavacClasspath: slices.Concat(
frameworkTurbineJars,
[]string{
"out/soong/.intermediates/bar/android_common/turbine/bar.jar",
@@ -341,11 +302,12 @@
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
tt.preparer,
).RunTestWithBp(t, bp)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
fooJavac := foo.Rule("javac")
android.AssertPathsRelativeToTopEquals(t, "foo javac inputs", tt.fooJavacInputs, fooJavac.Inputs)
@@ -360,7 +322,7 @@
fooCombinedHeaderJar := foo.Output("turbine-combined/foo.jar")
android.AssertPathsRelativeToTopEquals(t, "foo header combined inputs", tt.fooHeaderCombinedInputs, fooCombinedHeaderJar.Inputs)
- bar := result.ModuleForTests("bar", "android_common")
+ bar := result.ModuleForTests(t, "bar", "android_common")
barJavac := bar.Rule("javac")
android.AssertPathsRelativeToTopEquals(t, "bar javac inputs", tt.barJavacInputs, barJavac.Inputs)
@@ -378,6 +340,7 @@
}
func TestExportedPlugins(t *testing.T) {
+ t.Parallel()
type Result struct {
library string
processors string
@@ -456,6 +419,7 @@
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_plugin {
name: "plugin",
@@ -469,11 +433,11 @@
`+test.extra)
for _, want := range test.results {
- javac := ctx.ModuleForTests(want.library, "android_common").Rule("javac")
+ javac := ctx.ModuleForTests(t, want.library, "android_common").Rule("javac")
if javac.Args["processor"] != want.processors {
t.Errorf("For library %v, expected %v, found %v", want.library, want.processors, javac.Args["processor"])
}
- turbine := ctx.ModuleForTests(want.library, "android_common").MaybeRule("turbine")
+ turbine := ctx.ModuleForTests(t, want.library, "android_common").MaybeRule("turbine")
disableTurbine := turbine.BuildParams.Rule == nil
if disableTurbine != want.disableTurbine {
t.Errorf("For library %v, expected disableTurbine %v, found %v", want.library, want.disableTurbine, disableTurbine)
@@ -484,6 +448,7 @@
}
func TestSdkVersionByPartition(t *testing.T) {
+ t.Parallel()
testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", `
java_library {
name: "foo",
@@ -525,6 +490,7 @@
}
func TestArchSpecific(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -537,13 +503,14 @@
}
`)
- javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac")
if len(javac.Inputs) != 2 || javac.Inputs[0].String() != "a.java" || javac.Inputs[1].String() != "b.java" {
t.Errorf(`foo inputs %v != ["a.java", "b.java"]`, javac.Inputs)
}
}
func TestBinary(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library_host {
name: "foo",
@@ -567,11 +534,11 @@
buildOS := ctx.Config().BuildOS.String()
- bar := ctx.ModuleForTests("bar", buildOS+"_common")
+ bar := ctx.ModuleForTests(t, "bar", buildOS+"_common")
barJar := bar.Output("bar.jar").Output.String()
barWrapperDeps := bar.Output("bar").Implicits.Strings()
- libjni := ctx.ModuleForTests("libjni", buildOS+"_x86_64_shared")
+ libjni := ctx.ModuleForTests(t, "libjni", buildOS+"_x86_64_shared")
libjniSO := libjni.Rule("Cp").Output.String()
// Test that the install binary wrapper depends on the installed jar file
@@ -586,6 +553,7 @@
}
func TestTest(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_test_host {
name: "foo",
@@ -603,7 +571,7 @@
buildOS := ctx.Config().BuildOS.String()
- foo := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost)
+ foo := ctx.ModuleForTests(t, "foo", buildOS+"_common").Module().(*TestHost)
expected := "lib64/libjni.so"
if runtime.GOOS == "darwin" {
@@ -617,7 +585,31 @@
}
}
+func TestHostCommonData(t *testing.T) {
+ t.Parallel()
+ ctx, _ := testJava(t, `
+ java_library_host {
+ name: "host",
+ srcs: ["a.java"],
+ }
+
+ java_test {
+ name: "foo",
+ srcs: ["a.java"],
+ host_common_data: [":host"],
+ }
+ `)
+
+ foo := ctx.ModuleForTests(t, "foo", "android_common").Module().(*Test)
+ host := ctx.ModuleForTests(t, "host", ctx.Config().BuildOSCommonTarget.String()).Module().(*Library)
+
+ if g, w := foo.data.RelativeToTop().Strings(), []string{host.outputFile.RelativeToTop().String()}; !slices.Equal(g, w) {
+ t.Errorf("expected test data %q, got %q\n", w, g)
+ }
+}
+
func TestHostBinaryNoJavaDebugInfoOverride(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "target_library",
@@ -638,7 +630,7 @@
).RunTestWithBp(t, bp)
// first, check that the -g flag is added to target modules
- targetLibrary := result.ModuleForTests("target_library", "android_common")
+ targetLibrary := result.ModuleForTests(t, "target_library", "android_common")
targetJavaFlags := targetLibrary.Module().VariablesForTests()["javacFlags"]
if !strings.Contains(targetJavaFlags, "-g:source,lines") {
t.Errorf("target library javac flags %v should contain "+
@@ -647,7 +639,7 @@
// check that -g is not overridden for host modules
buildOS := result.Config.BuildOS.String()
- hostBinary := result.ModuleForTests("host_binary", buildOS+"_common")
+ hostBinary := result.ModuleForTests(t, "host_binary", buildOS+"_common")
hostJavaFlags := hostBinary.Module().VariablesForTests()["javacFlags"]
if strings.Contains(hostJavaFlags, "-g:source,lines") {
t.Errorf("java_binary_host javac flags %v should not have "+
@@ -665,6 +657,7 @@
var _ android.ModuleErrorfContext = (*moduleErrorfTestCtx)(nil)
func TestPrebuilts(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -710,15 +703,15 @@
}
`)
- fooModule := ctx.ModuleForTests("foo", "android_common")
+ fooModule := ctx.ModuleForTests(t, "foo", "android_common")
javac := fooModule.Rule("javac")
- combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
- barModule := ctx.ModuleForTests("bar", "android_common")
- barJar := barModule.Output("combined/bar.jar").Output
- bazModule := ctx.ModuleForTests("baz", "android_common")
- bazJar := bazModule.Output("combined/baz.jar").Output
- sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").
- Output("combined/sdklib.stubs.jar").Output
+ combineJar := ctx.ModuleForTests(t, "foo", "android_common").Description("for javac")
+ barModule := ctx.ModuleForTests(t, "bar", "android_common")
+ barJar := barModule.Output("local-combined/bar.jar").Output
+ bazModule := ctx.ModuleForTests(t, "baz", "android_common")
+ bazJar := bazModule.Output("local-combined/baz.jar").Output
+ sdklibStubsJar := ctx.ModuleForTests(t, "sdklib.stubs", "android_common").
+ Output("local-combined/sdklib.stubs.jar").Output
fooLibrary := fooModule.Module().(*Library)
assertDeepEquals(t, "foo unique sources incorrect",
@@ -750,7 +743,7 @@
expectedDexJar := "out/soong/.intermediates/baz/android_common/dex/baz.jar"
android.AssertPathRelativeToTopEquals(t, "baz dex jar build path", expectedDexJar, bazDexJar)
- ctx.ModuleForTests("qux", "android_common").Rule("Cp")
+ ctx.ModuleForTests(t, "qux", "android_common").Rule("Cp")
entries := android.AndroidMkEntriesForTest(t, ctx, fooModule.Module())[0]
android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_library", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
@@ -765,6 +758,7 @@
}
func TestPrebuiltStubsSources(t *testing.T) {
+ t.Parallel()
test := func(t *testing.T, sourcesPath string, expectedInputs []string) {
ctx, _ := testJavaWithFS(t, fmt.Sprintf(`
prebuilt_stubs_sources {
@@ -775,17 +769,19 @@
"stubs/sources/pkg/B.java": nil,
})
- zipSrc := ctx.ModuleForTests("stubs-source", "android_common").Rule("zip_src")
+ zipSrc := ctx.ModuleForTests(t, "stubs-source", "android_common").Rule("zip_src")
if expected, actual := expectedInputs, zipSrc.Inputs.Strings(); !reflect.DeepEqual(expected, actual) {
t.Errorf("mismatch of inputs to soong_zip: expected %q, actual %q", expected, actual)
}
}
t.Run("empty/missing directory", func(t *testing.T) {
+ t.Parallel()
test(t, "empty-directory", nil)
})
t.Run("non-empty set of sources", func(t *testing.T) {
+ t.Parallel()
test(t, "stubs/sources", []string{
"stubs/sources/pkg/A.java",
"stubs/sources/pkg/B.java",
@@ -794,6 +790,7 @@
}
func TestDefaults(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_defaults {
name: "defaults",
@@ -835,40 +832,41 @@
}
`)
- javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
- combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac")
+ combineJar := ctx.ModuleForTests(t, "foo", "android_common").Description("for javac")
if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
}
- barTurbine := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar")
+ barTurbine := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar")
if !strings.Contains(javac.Args["classpath"], barTurbine) {
t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
}
- baz := ctx.ModuleForTests("baz", "android_common").Rule("javac").Output.String()
+ baz := ctx.ModuleForTests(t, "baz", "android_common").Rule("javac").Output.String()
if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz {
t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz)
}
- atestOptimize := ctx.ModuleForTests("atestOptimize", "android_common").MaybeRule("r8")
+ atestOptimize := ctx.ModuleForTests(t, "atestOptimize", "android_common").MaybeRule("r8")
if atestOptimize.Output == nil {
t.Errorf("atestOptimize should optimize APK")
}
- atestNoOptimize := ctx.ModuleForTests("atestNoOptimize", "android_common").MaybeRule("d8")
+ atestNoOptimize := ctx.ModuleForTests(t, "atestNoOptimize", "android_common").MaybeRule("d8")
if atestNoOptimize.Output == nil {
t.Errorf("atestNoOptimize should not optimize APK")
}
- atestDefault := ctx.ModuleForTests("atestDefault", "android_common").MaybeRule("d8")
+ atestDefault := ctx.ModuleForTests(t, "atestDefault", "android_common").MaybeRule("d8")
if atestDefault.Output == nil {
t.Errorf("atestDefault should not optimize APK")
}
}
func TestResources(t *testing.T) {
+ t.Parallel()
var table = []struct {
name string
prop string
@@ -940,6 +938,7 @@
for _, test := range table {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
ctx, _ := testJavaWithFS(t, `
java_library {
name: "foo",
@@ -958,8 +957,8 @@
},
)
- foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar")
- fooRes := ctx.ModuleForTests("foo", "android_common").Output("res/foo.jar")
+ foo := ctx.ModuleForTests(t, "foo", "android_common").Output("withres/foo.jar")
+ fooRes := ctx.ModuleForTests(t, "foo", "android_common").Output("res/foo.jar")
if !inList(fooRes.Output.String(), foo.Inputs.Strings()) {
t.Errorf("foo combined jars %v does not contain %q",
@@ -975,6 +974,7 @@
}
func TestIncludeSrcs(t *testing.T) {
+ t.Parallel()
ctx, _ := testJavaWithFS(t, `
java_library {
name: "foo",
@@ -1003,8 +1003,8 @@
})
// Test a library with include_srcs: true
- foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar")
- fooSrcJar := ctx.ModuleForTests("foo", "android_common").Output("foo.srcjar")
+ foo := ctx.ModuleForTests(t, "foo", "android_common").Output("withres/foo.jar")
+ fooSrcJar := ctx.ModuleForTests(t, "foo", "android_common").Output("foo.srcjar")
if g, w := fooSrcJar.Output.String(), foo.Inputs.Strings(); !inList(g, w) {
t.Errorf("foo combined jars %v does not contain %q", w, g)
@@ -1015,10 +1015,10 @@
}
// Test a library with include_srcs: true and resources
- bar := ctx.ModuleForTests("bar", "android_common").Output("withres/bar.jar")
- barResCombined := ctx.ModuleForTests("bar", "android_common").Output("res-combined/bar.jar")
- barRes := ctx.ModuleForTests("bar", "android_common").Output("res/bar.jar")
- barSrcJar := ctx.ModuleForTests("bar", "android_common").Output("bar.srcjar")
+ bar := ctx.ModuleForTests(t, "bar", "android_common").Output("withres/bar.jar")
+ barResCombined := ctx.ModuleForTests(t, "bar", "android_common").Output("res-combined/bar.jar")
+ barRes := ctx.ModuleForTests(t, "bar", "android_common").Output("res/bar.jar")
+ barSrcJar := ctx.ModuleForTests(t, "bar", "android_common").Output("bar.srcjar")
if g, w := barSrcJar.Output.String(), barResCombined.Inputs.Strings(); !inList(g, w) {
t.Errorf("bar combined resource jars %v does not contain %q", w, g)
@@ -1028,7 +1028,7 @@
t.Errorf("bar combined resource jars %v does not contain %q", w, g)
}
- if g, w := barResCombined.Output.String(), bar.Inputs.Strings(); !inList(g, w) {
+ if g, w := barRes.Output.String(), bar.Inputs.Strings(); !inList(g, w) {
t.Errorf("bar combined jars %v does not contain %q", w, g)
}
@@ -1042,6 +1042,7 @@
}
func TestGeneratedSources(t *testing.T) {
+ t.Parallel()
ctx, _ := testJavaWithFS(t, `
java_library {
name: "foo",
@@ -1062,8 +1063,8 @@
"b.java": nil,
})
- javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
- genrule := ctx.ModuleForTests("gen", "").Rule("generator")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac")
+ genrule := ctx.ModuleForTests(t, "gen", "").Rule("generator")
if filepath.Base(genrule.Output.String()) != "gen.java" {
t.Fatalf(`gen output file %v is not ".../gen.java"`, genrule.Output.String())
@@ -1078,6 +1079,7 @@
}
func TestTurbine(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{"14": {"foo"}})).
RunTestWithBp(t, `
@@ -1102,15 +1104,15 @@
}
`)
- fooTurbine := result.ModuleForTests("foo", "android_common").Rule("turbine")
- barTurbine := result.ModuleForTests("bar", "android_common").Rule("turbine")
- barJavac := result.ModuleForTests("bar", "android_common").Rule("javac")
- barTurbineCombined := result.ModuleForTests("bar", "android_common").Description("for turbine")
- bazJavac := result.ModuleForTests("baz", "android_common").Rule("javac")
+ fooTurbine := result.ModuleForTests(t, "foo", "android_common").Rule("turbine")
+ barTurbine := result.ModuleForTests(t, "bar", "android_common").Rule("turbine")
+ barJavac := result.ModuleForTests(t, "bar", "android_common").Rule("javac")
+ barTurbineCombined := result.ModuleForTests(t, "bar", "android_common").Description("for turbine")
+ bazJavac := result.ModuleForTests(t, "baz", "android_common").Rule("javac")
android.AssertPathsRelativeToTopEquals(t, "foo inputs", []string{"a.java"}, fooTurbine.Inputs)
- fooHeaderJar := filepath.Join("out", "soong", ".intermediates", "foo", "android_common", "turbine-combined", "foo.jar")
+ fooHeaderJar := filepath.Join("out", "soong", ".intermediates", "foo", "android_common", "turbine", "foo.jar")
barTurbineJar := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar")
android.AssertStringDoesContain(t, "bar turbine classpath", barTurbine.Args["turbineFlags"], fooHeaderJar)
android.AssertStringDoesContain(t, "bar javac classpath", barJavac.Args["classpath"], fooHeaderJar)
@@ -1119,6 +1121,7 @@
}
func TestSharding(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "bar",
@@ -1129,7 +1132,7 @@
barHeaderJar := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar")
for i := 0; i < 3; i++ {
- barJavac := ctx.ModuleForTests("bar", "android_common").Description("javac" + strconv.Itoa(i))
+ barJavac := ctx.ModuleForTests(t, "bar", "android_common").Description("javac" + strconv.Itoa(i))
if !strings.HasPrefix(barJavac.Args["classpath"], "-classpath "+barHeaderJar+":") {
t.Errorf("bar javac classpath %v does start with %q", barJavac.Args["classpath"], barHeaderJar)
}
@@ -1137,6 +1140,7 @@
}
func TestExcludeFileGroupInSrcs(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -1155,7 +1159,7 @@
}
`)
- javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac")
if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "java-fg/c.java" {
t.Errorf(`foo inputs %v != ["java-fg/c.java"]`, javac.Inputs)
@@ -1163,6 +1167,7 @@
}
func TestJavaLibraryOutputFiles(t *testing.T) {
+ t.Parallel()
testJavaWithFS(t, "", map[string][]byte{
"libcore/Android.bp": []byte(`
java_library {
@@ -1180,6 +1185,7 @@
}
func TestJavaImportOutputFiles(t *testing.T) {
+ t.Parallel()
testJavaWithFS(t, "", map[string][]byte{
"libcore/Android.bp": []byte(`
java_import {
@@ -1196,6 +1202,7 @@
}
func TestJavaImport(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "source_library",
@@ -1223,18 +1230,20 @@
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, bp)
- source := ctx.ModuleForTests("source_library", "android_common")
+ source := ctx.ModuleForTests(t, "source_library", "android_common")
sourceJar := source.Output("javac/source_library.jar")
- sourceHeaderJar := source.Output("turbine-combined/source_library.jar")
+ sourceHeaderJar := source.Output("turbine/source_library.jar")
+ sourceCombinedHeaderJar := source.Output("turbine-combined/source_library.jar")
sourceJavaInfo, _ := android.OtherModuleProvider(ctx, source.Module(), JavaInfoProvider)
// The source library produces separate implementation and header jars
android.AssertPathsRelativeToTopEquals(t, "source library implementation jar",
[]string{sourceJar.Output.String()}, sourceJavaInfo.ImplementationAndResourcesJars)
android.AssertPathsRelativeToTopEquals(t, "source library header jar",
- []string{sourceHeaderJar.Output.String()}, sourceJavaInfo.HeaderJars)
+ []string{sourceCombinedHeaderJar.Output.String()}, sourceJavaInfo.HeaderJars)
- importWithNoDeps := ctx.ModuleForTests("import_with_no_deps", "android_common")
+ importWithNoDeps := ctx.ModuleForTests(t, "import_with_no_deps", "android_common")
+ importWithNoDepsLocalJar := importWithNoDeps.Output("local-combined/import_with_no_deps.jar")
importWithNoDepsJar := importWithNoDeps.Output("combined/import_with_no_deps.jar")
importWithNoDepsJavaInfo, _ := android.OtherModuleProvider(ctx, importWithNoDeps.Module(), JavaInfoProvider)
@@ -1244,10 +1253,14 @@
android.AssertPathsRelativeToTopEquals(t, "import with no deps header jar",
[]string{importWithNoDepsJar.Output.String()}, importWithNoDepsJavaInfo.HeaderJars)
android.AssertPathsRelativeToTopEquals(t, "import with no deps combined inputs",
- []string{"no_deps.jar"}, importWithNoDepsJar.Inputs)
+ []string{importWithNoDepsLocalJar.Output.String()}, importWithNoDepsJar.Inputs)
+ android.AssertPathsRelativeToTopEquals(t, "import with no deps local combined inputs",
+ []string{"no_deps.jar"}, importWithNoDepsLocalJar.Inputs)
- importWithSourceDeps := ctx.ModuleForTests("import_with_source_deps", "android_common")
+ importWithSourceDeps := ctx.ModuleForTests(t, "import_with_source_deps", "android_common")
+ importWithSourceDepsLocalJar := importWithSourceDeps.Output("local-combined/import_with_source_deps.jar")
importWithSourceDepsJar := importWithSourceDeps.Output("combined/import_with_source_deps.jar")
+ importWithSourceDepsLocalHeaderJar := importWithSourceDeps.Output("local-combined/import_with_source_deps.jar")
importWithSourceDepsHeaderJar := importWithSourceDeps.Output("turbine-combined/import_with_source_deps.jar")
importWithSourceDepsJavaInfo, _ := android.OtherModuleProvider(ctx, importWithSourceDeps.Module(), JavaInfoProvider)
@@ -1257,11 +1270,16 @@
android.AssertPathsRelativeToTopEquals(t, "import with source deps header jar",
[]string{importWithSourceDepsHeaderJar.Output.String()}, importWithSourceDepsJavaInfo.HeaderJars)
android.AssertPathsRelativeToTopEquals(t, "import with source deps combined implementation jar inputs",
- []string{"source_deps.jar", sourceJar.Output.String()}, importWithSourceDepsJar.Inputs)
+ []string{importWithSourceDepsLocalJar.Output.String(), sourceJar.Output.String()}, importWithSourceDepsJar.Inputs)
android.AssertPathsRelativeToTopEquals(t, "import with source deps combined header jar inputs",
- []string{"source_deps.jar", sourceHeaderJar.Output.String()}, importWithSourceDepsHeaderJar.Inputs)
+ []string{importWithSourceDepsLocalHeaderJar.Output.String(), sourceHeaderJar.Output.String()}, importWithSourceDepsHeaderJar.Inputs)
+ android.AssertPathsRelativeToTopEquals(t, "import with source deps local combined implementation jar inputs",
+ []string{"source_deps.jar"}, importWithSourceDepsLocalJar.Inputs)
+ android.AssertPathsRelativeToTopEquals(t, "import with source deps local combined header jar inputs",
+ []string{"source_deps.jar"}, importWithSourceDepsLocalHeaderJar.Inputs)
- importWithImportDeps := ctx.ModuleForTests("import_with_import_deps", "android_common")
+ importWithImportDeps := ctx.ModuleForTests(t, "import_with_import_deps", "android_common")
+ importWithImportDepsLocalJar := importWithImportDeps.Output("local-combined/import_with_import_deps.jar")
importWithImportDepsJar := importWithImportDeps.Output("combined/import_with_import_deps.jar")
importWithImportDepsJavaInfo, _ := android.OtherModuleProvider(ctx, importWithImportDeps.Module(), JavaInfoProvider)
@@ -1271,7 +1289,9 @@
android.AssertPathsRelativeToTopEquals(t, "import with import deps header jar",
[]string{importWithImportDepsJar.Output.String()}, importWithImportDepsJavaInfo.HeaderJars)
android.AssertPathsRelativeToTopEquals(t, "import with import deps combined implementation jar inputs",
- []string{"import_deps.jar", importWithNoDepsJar.Output.String()}, importWithImportDepsJar.Inputs)
+ []string{importWithImportDepsLocalJar.Output.String(), importWithNoDepsLocalJar.Output.String()}, importWithImportDepsJar.Inputs)
+ android.AssertPathsRelativeToTopEquals(t, "import with import deps local combined implementation jar inputs",
+ []string{"import_deps.jar"}, importWithImportDepsLocalJar.Inputs)
}
var compilerFlagsTestCases = []struct {
@@ -1323,6 +1343,7 @@
}
func TestCompilerFlags(t *testing.T) {
+ t.Parallel()
for _, testCase := range compilerFlagsTestCases {
ctx := &mockContext{result: true}
CheckKotlincFlags(ctx, []string{testCase.in})
@@ -1337,7 +1358,8 @@
// TODO(jungjw): Consider making this more robust by ignoring path order.
func checkPatchModuleFlag(t *testing.T, ctx *android.TestContext, moduleName string, expected string) {
- variables := ctx.ModuleForTests(moduleName, "android_common").VariablesForTestsRelativeToTop()
+ t.Helper()
+ variables := ctx.ModuleForTests(t, moduleName, "android_common").VariablesForTestsRelativeToTop()
flags := strings.Split(variables["javacFlags"], " ")
got := ""
for _, flag := range flags {
@@ -1353,7 +1375,9 @@
}
func TestPatchModule(t *testing.T) {
+ t.Parallel()
t.Run("Java language level 8", func(t *testing.T) {
+ t.Parallel()
// Test with legacy javac -source 1.8 -target 1.8
bp := `
java_library {
@@ -1386,6 +1410,7 @@
})
t.Run("Java language level 9", func(t *testing.T) {
+ t.Parallel()
// Test with default javac -source 9 -target 9
bp := `
java_library {
@@ -1426,6 +1451,7 @@
}
func TestJavaLibraryWithSystemModules(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "lib-with-source-system-modules",
@@ -1474,7 +1500,7 @@
}
func checkBootClasspathForLibWithSystemModule(t *testing.T, ctx *android.TestContext, moduleName string, expectedSuffix string) {
- javacRule := ctx.ModuleForTests(moduleName, "android_common").Rule("javac")
+ javacRule := ctx.ModuleForTests(t, moduleName, "android_common").Rule("javac")
bootClasspath := javacRule.Args["bootClasspath"]
if strings.HasPrefix(bootClasspath, "--system ") && strings.HasSuffix(bootClasspath, expectedSuffix) {
t.Errorf("bootclasspath of %q must start with --system and end with %q, but was %#v.", moduleName, expectedSuffix, bootClasspath)
@@ -1482,6 +1508,7 @@
}
func TestAidlExportIncludeDirsFromImports(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -1498,7 +1525,7 @@
}
`)
- aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
+ aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command
expectedAidlFlag := "-Iaidl/bar"
if !strings.Contains(aidlCommand, expectedAidlFlag) {
t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
@@ -1506,6 +1533,7 @@
}
func TestAidlFlagsArePassedToTheAidlCompiler(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -1514,7 +1542,7 @@
}
`)
- aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
+ aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command
expectedAidlFlag := "-Werror"
if !strings.Contains(aidlCommand, expectedAidlFlag) {
t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
@@ -1522,6 +1550,7 @@
}
func TestAidlFlagsWithMinSdkVersion(t *testing.T) {
+ t.Parallel()
fixture := android.GroupFixturePreparers(
prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{"14": {"foo"}}))
@@ -1535,6 +1564,7 @@
{"system_current", `sdk_version: "system_current"`, "current"},
} {
t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
ctx := fixture.RunTestWithBp(t, `
java_library {
name: "foo",
@@ -1542,7 +1572,7 @@
`+tc.sdkVersion+`
}
`)
- aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
+ aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command
expectedAidlFlag := "--min_sdk_version=" + tc.expected
if !strings.Contains(aidlCommand, expectedAidlFlag) {
t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
@@ -1552,6 +1582,7 @@
}
func TestAidlFlagsMinSdkVersionDroidstubs(t *testing.T) {
+ t.Parallel()
bpTemplate := `
droidstubs {
name: "foo-stubs",
@@ -1578,13 +1609,14 @@
}
for _, tc := range testCases {
ctx := prepareForJavaTest.RunTestWithBp(t, fmt.Sprintf(bpTemplate, tc.sdkVersionBp))
- aidlCmd := ctx.ModuleForTests("foo-stubs", "android_common").Rule("aidl").RuleParams.Command
+ aidlCmd := ctx.ModuleForTests(t, "foo-stubs", "android_common").Rule("aidl").RuleParams.Command
expected := "--min_sdk_version=" + tc.minSdkVersionExpected
android.AssertStringDoesContain(t, "aidl command conatins incorrect min_sdk_version for testCse: "+tc.desc, aidlCmd, expected)
}
}
func TestAidlEnforcePermissions(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -1593,7 +1625,7 @@
}
`)
- aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
+ aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command
expectedAidlFlag := "-Wmissing-permission-annotation -Werror"
if !strings.Contains(aidlCommand, expectedAidlFlag) {
t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
@@ -1601,6 +1633,7 @@
}
func TestAidlEnforcePermissionsException(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -1609,7 +1642,7 @@
}
`)
- aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
+ aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command
expectedAidlFlag := "$$FLAGS -Wmissing-permission-annotation -Werror aidl/foo/IFoo.aidl"
if !strings.Contains(aidlCommand, expectedAidlFlag) {
t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
@@ -1621,6 +1654,7 @@
}
func TestDataNativeBinaries(t *testing.T) {
+ t.Parallel()
ctx := android.GroupFixturePreparers(
prepareForJavaTest,
android.PrepareForTestWithAllowMissingDependencies).RunTestWithBp(t, `
@@ -1638,7 +1672,7 @@
buildOS := ctx.Config().BuildOS.String()
- test := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost)
+ test := ctx.ModuleForTests(t, "foo", buildOS+"_common").Module().(*TestHost)
entries := android.AndroidMkEntriesForTest(t, ctx, test)[0]
expected := []string{"out/soong/.intermediates/bin/" + buildOS + "_x86_64/bin:bin"}
actual := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
@@ -1646,6 +1680,7 @@
}
func TestDefaultInstallable(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_test_host {
name: "foo"
@@ -1653,12 +1688,13 @@
`)
buildOS := ctx.Config().BuildOS.String()
- module := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost)
+ module := ctx.ModuleForTests(t, "foo", buildOS+"_common").Module().(*TestHost)
assertDeepEquals(t, "Default installable value should be true.", proptools.BoolPtr(true),
module.properties.Installable)
}
func TestErrorproneEnabled(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -1669,7 +1705,7 @@
}
`)
- javac := ctx.ModuleForTests("foo", "android_common").Description("javac")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Description("javac")
// Test that the errorprone plugins are passed to javac
expectedSubstring := "-Xplugin:ErrorProne"
@@ -1680,13 +1716,14 @@
// Modules with errorprone { enabled: true } will include errorprone checks
// in the main javac build rule. Only when RUN_ERROR_PRONE is true will
// the explicit errorprone build rule be created.
- errorprone := ctx.ModuleForTests("foo", "android_common").MaybeDescription("errorprone")
+ errorprone := ctx.ModuleForTests(t, "foo", "android_common").MaybeDescription("errorprone")
if errorprone.RuleParams.Description != "" {
t.Errorf("expected errorprone build rule to not exist, but it did")
}
}
func TestErrorproneDisabled(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "foo",
@@ -1703,7 +1740,7 @@
}),
).RunTestWithBp(t, bp)
- javac := ctx.ModuleForTests("foo", "android_common").Description("javac")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Description("javac")
// Test that the errorprone plugins are not passed to javac, like they would
// be if enabled was true.
@@ -1714,13 +1751,14 @@
// Check that no errorprone build rule is created, like there would be
// if enabled was unset and RUN_ERROR_PRONE was true.
- errorprone := ctx.ModuleForTests("foo", "android_common").MaybeDescription("errorprone")
+ errorprone := ctx.ModuleForTests(t, "foo", "android_common").MaybeDescription("errorprone")
if errorprone.RuleParams.Description != "" {
t.Errorf("expected errorprone build rule to not exist, but it did")
}
}
func TestErrorproneEnabledOnlyByEnvironmentVariable(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "foo",
@@ -1734,8 +1772,8 @@
}),
).RunTestWithBp(t, bp)
- javac := ctx.ModuleForTests("foo", "android_common").Description("javac")
- errorprone := ctx.ModuleForTests("foo", "android_common").Description("errorprone")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Description("javac")
+ errorprone := ctx.ModuleForTests(t, "foo", "android_common").Description("errorprone")
// Check that the errorprone plugins are not passed to javac, because they
// will instead be passed to the separate errorprone compilation
@@ -1751,6 +1789,7 @@
}
func TestDataDeviceBinsBuildsDeviceBinary(t *testing.T) {
+ t.Parallel()
testCases := []struct {
dataDeviceBinType string
depCompileMultilib string
@@ -1887,6 +1926,7 @@
testName := fmt.Sprintf(`data_device_bins_%s with compile_multilib:"%s"`, tc.dataDeviceBinType, tc.depCompileMultilib)
t.Run(testName, func(t *testing.T) {
+ t.Parallel()
ctx := android.GroupFixturePreparers(PrepareForIntegrationTestWithJava).
ExtendWithErrorHandler(errorHandler).
RunTestWithBp(t, bp)
@@ -1895,7 +1935,7 @@
}
buildOS := ctx.Config.BuildOS.String()
- fooVariant := ctx.ModuleForTests("foo", buildOS+"_common")
+ fooVariant := ctx.ModuleForTests(t, "foo", buildOS+"_common")
fooMod := fooVariant.Module().(*TestHost)
entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, fooMod)[0]
@@ -1907,7 +1947,7 @@
expectedData := []string{}
for _, variant := range tc.variants {
- barVariant := ctx.ModuleForTests("bar", variant)
+ barVariant := ctx.ModuleForTests(t, "bar", variant)
relocated := barVariant.Output("bar")
expectedInput := fmt.Sprintf("out/soong/.intermediates/bar/%s/unstripped/bar", variant)
android.AssertPathRelativeToTopEquals(t, "relocation input", expectedInput, relocated.Input)
@@ -1916,12 +1956,13 @@
}
actualData := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
- android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_TEST_DATA", ctx.Config, expectedData, actualData)
+ android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_TEST_DATA", ctx.Config, android.SortedUniqueStrings(expectedData), android.SortedUniqueStrings(actualData))
})
}
}
func TestDeviceBinaryWrapperGeneration(t *testing.T) {
+ t.Parallel()
// Scenario 1: java_binary has main_class property in its bp
ctx, _ := testJava(t, `
java_binary {
@@ -1930,7 +1971,7 @@
main_class: "foo.bar.jb",
}
`)
- wrapperPath := fmt.Sprint(ctx.ModuleForTests("foo", "android_common").AllOutputs())
+ wrapperPath := fmt.Sprint(ctx.ModuleForTests(t, "foo", "android_common").AllOutputs())
if !strings.Contains(wrapperPath, "foo.sh") {
t.Errorf("wrapper file foo.sh is not generated")
}
@@ -1945,6 +1986,7 @@
}
func TestJavaApiContributionEmptyApiFile(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
android.FixtureMergeEnv(
@@ -1968,6 +2010,7 @@
}
func TestJavaApiLibraryAndProviderLink(t *testing.T) {
+ t.Parallel()
provider_bp_a := `
java_api_contribution {
name: "foo1",
@@ -2024,7 +2067,7 @@
},
}
for _, c := range testcases {
- m := ctx.ModuleForTests(c.moduleName, "android_common")
+ m := ctx.ModuleForTests(t, c.moduleName, "android_common")
manifest := m.Output("metalava.sbox.textproto")
sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest)
manifestCommand := sboxProto.Commands[0].GetCommand()
@@ -2034,6 +2077,7 @@
}
func TestJavaApiLibraryAndDefaultsLink(t *testing.T) {
+ t.Parallel()
provider_bp_a := `
java_api_contribution {
name: "foo1",
@@ -2132,7 +2176,7 @@
},
}
for _, c := range testcases {
- m := ctx.ModuleForTests(c.moduleName, "android_common")
+ m := ctx.ModuleForTests(t, c.moduleName, "android_common")
manifest := m.Output("metalava.sbox.textproto")
sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest)
manifestCommand := sboxProto.Commands[0].GetCommand()
@@ -2142,6 +2186,7 @@
}
func TestJavaApiLibraryJarGeneration(t *testing.T) {
+ t.Parallel()
provider_bp_a := `
java_api_contribution {
name: "foo1",
@@ -2199,7 +2244,7 @@
},
}
for _, c := range testcases {
- m := ctx.ModuleForTests(c.moduleName, "android_common")
+ m := ctx.ModuleForTests(t, c.moduleName, "android_common")
outputs := fmt.Sprint(m.AllOutputs())
if !strings.Contains(outputs, c.outputJarName) {
t.Errorf("Module output does not contain expected jar %s", c.outputJarName)
@@ -2208,6 +2253,7 @@
}
func TestJavaApiLibraryLibsLink(t *testing.T) {
+ t.Parallel()
provider_bp_a := `
java_api_contribution {
name: "foo1",
@@ -2284,7 +2330,7 @@
},
}
for _, c := range testcases {
- m := ctx.ModuleForTests(c.moduleName, "android_common")
+ m := ctx.ModuleForTests(t, c.moduleName, "android_common")
javacRules := m.Rule("javac")
classPathArgs := javacRules.Args["classpath"]
for _, jarName := range c.classPathJarNames {
@@ -2296,6 +2342,7 @@
}
func TestJavaApiLibraryStaticLibsLink(t *testing.T) {
+ t.Parallel()
provider_bp_a := `
java_api_contribution {
name: "foo1",
@@ -2372,7 +2419,7 @@
},
}
for _, c := range testcases {
- m := ctx.ModuleForTests(c.moduleName, "android_common")
+ m := ctx.ModuleForTests(t, c.moduleName, "android_common")
mergeZipsCommand := m.Rule("merge_zips").RuleParams.Command
for _, jarName := range c.staticLibJarNames {
if !strings.Contains(mergeZipsCommand, jarName) {
@@ -2383,6 +2430,7 @@
}
func TestTransitiveSrcFiles(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "a",
@@ -2399,13 +2447,14 @@
static_libs: ["b"],
}
`)
- c := ctx.ModuleForTests("c", "android_common").Module()
+ c := ctx.ModuleForTests(t, "c", "android_common").Module()
javaInfo, _ := android.OtherModuleProvider(ctx, c, JavaInfoProvider)
transitiveSrcFiles := android.Paths(javaInfo.TransitiveSrcFiles.ToList())
android.AssertArrayString(t, "unexpected jar deps", []string{"b.java", "c.java"}, transitiveSrcFiles.Strings())
}
func TestTradefedOptions(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, `
java_test_host {
name: "foo",
@@ -2421,7 +2470,7 @@
`)
buildOS := result.Config.BuildOS.String()
- args := result.ModuleForTests("foo", buildOS+"_common").
+ args := result.ModuleForTests(t, "foo", buildOS+"_common").
Output("out/soong/.intermediates/foo/" + buildOS + "_common/foo.config").Args
expected := proptools.NinjaAndShellEscape("<option name=\"exclude-path\" value=\"org/apache\" />")
if args["extraConfigs"] != expected {
@@ -2430,6 +2479,7 @@
}
func TestTestRunnerOptions(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, `
java_test_host {
name: "foo",
@@ -2445,7 +2495,7 @@
`)
buildOS := result.Config.BuildOS.String()
- args := result.ModuleForTests("foo", buildOS+"_common").
+ args := result.ModuleForTests(t, "foo", buildOS+"_common").
Output("out/soong/.intermediates/foo/" + buildOS + "_common/foo.config").Args
expected := proptools.NinjaAndShellEscape("<option name=\"test-timeout\" value=\"10m\" />\\n ")
if args["extraTestRunnerConfigs"] != expected {
@@ -2454,6 +2504,7 @@
}
func TestJavaLibraryWithResourcesStem(t *testing.T) {
+ t.Parallel()
ctx, _ := testJavaWithFS(t, `
java_library {
name: "foo",
@@ -2465,7 +2516,7 @@
"test-jar/test/resource.txt": nil,
})
- m := ctx.ModuleForTests("foo", "android_common")
+ m := ctx.ModuleForTests(t, "foo", "android_common")
outputs := fmt.Sprint(m.AllOutputs())
if !strings.Contains(outputs, "test.jar") {
t.Errorf("Module output does not contain expected jar %s", "test.jar")
@@ -2473,6 +2524,7 @@
}
func TestHeadersOnly(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -2481,16 +2533,17 @@
}
`)
- turbine := ctx.ModuleForTests("foo", "android_common").Rule("turbine")
+ turbine := ctx.ModuleForTests(t, "foo", "android_common").Rule("turbine")
if len(turbine.Inputs) != 1 || turbine.Inputs[0].String() != "a.java" {
t.Errorf(`foo inputs %v != ["a.java"]`, turbine.Inputs)
}
- javac := ctx.ModuleForTests("foo", "android_common").MaybeRule("javac")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").MaybeRule("javac")
android.AssertDeepEquals(t, "javac rule", nil, javac.Rule)
}
func TestJavaApiContributionImport(t *testing.T) {
+ t.Parallel()
ctx := android.GroupFixturePreparers(
prepareForJavaTest,
android.FixtureMergeEnv(
@@ -2510,7 +2563,7 @@
api_surface: "public",
}
`)
- m := ctx.ModuleForTests("foo", "android_common")
+ m := ctx.ModuleForTests(t, "foo", "android_common")
manifest := m.Output("metalava.sbox.textproto")
sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest)
manifestCommand := sboxProto.Commands[0].GetCommand()
@@ -2519,6 +2572,7 @@
}
func TestJavaApiLibraryApiFilesSorting(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_api_library {
name: "foo",
@@ -2532,7 +2586,7 @@
stubs_type: "everything",
}
`)
- m := ctx.ModuleForTests("foo", "android_common")
+ m := ctx.ModuleForTests(t, "foo", "android_common")
manifest := m.Output("metalava.sbox.textproto")
sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, manifest)
manifestCommand := sboxProto.Commands[0].GetCommand()
@@ -2547,6 +2601,7 @@
}
func TestSdkLibraryProvidesSystemModulesToApiLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -2576,6 +2631,7 @@
}
func TestApiLibraryDroidstubsDependency(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -2605,9 +2661,9 @@
`)
currentApiTimestampPath := "api-stubs-docs-non-updatable/android_common/everything/check_current_api.timestamp"
- foo := result.ModuleForTests("foo", "android_common").Module().(*ApiLibrary)
+ foo := result.ModuleForTests(t, "foo", "android_common").Module().(*ApiLibrary)
fooValidationPathsString := strings.Join(foo.validationPaths.Strings(), " ")
- bar := result.ModuleForTests("bar", "android_common").Module().(*ApiLibrary)
+ bar := result.ModuleForTests(t, "bar", "android_common").Module().(*ApiLibrary)
barValidationPathsString := strings.Join(bar.validationPaths.Strings(), " ")
android.AssertStringDoesContain(t,
"Module expected to have validation",
@@ -2622,6 +2678,7 @@
}
func TestDisableFromTextStubForCoverageBuild(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -2651,6 +2708,7 @@
}
func TestMultiplePrebuilts(t *testing.T) {
+ t.Parallel()
bp := `
// an rdep
java_library {
@@ -2733,8 +2791,8 @@
).RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName))
// check that rdep gets the correct variation of dep
- foo := ctx.ModuleForTests("foo", "android_common")
- expectedDependency := ctx.ModuleForTests(tc.expectedDependencyName, "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
+ expectedDependency := ctx.ModuleForTests(t, tc.expectedDependencyName, "android_common")
android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", foo.Module().Name(), tc.expectedDependencyName), true, hasDep(ctx, foo.Module(), expectedDependency.Module()))
// check that output file of dep is always bar.jar
@@ -2749,6 +2807,7 @@
}
func TestMultiplePlatformCompatConfigPrebuilts(t *testing.T) {
+ t.Parallel()
bp := `
// multiple variations of platform_compat_config
// source
@@ -2802,13 +2861,14 @@
android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", "myapex_contributions"),
).RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName))
- mergedGlobalConfig := ctx.SingletonForTests("platform_compat_config_singleton").Output("compat_config/merged_compat_config.xml")
+ mergedGlobalConfig := ctx.SingletonForTests(t, "platform_compat_config_singleton").Output("compat_config/merged_compat_config.xml")
android.AssertIntEquals(t, "The merged compat config file should only have a single dependency", 1, len(mergedGlobalConfig.Implicits))
android.AssertStringEquals(t, "The merged compat config file is missing the appropriate platform compat config", mergedGlobalConfig.Implicits[0].String(), tc.expectedPlatformCompatConfigXml)
}
}
func TestApiLibraryAconfigDeclarations(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
@@ -2850,7 +2910,7 @@
android.AssertBoolEquals(t, "foo expected to depend on bar",
CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "bar"), true)
- m := result.ModuleForTests("foo", "android_common")
+ m := result.ModuleForTests(t, "foo", "android_common")
android.AssertStringDoesContain(t, "foo generates revert annotations file",
strings.Join(m.AllOutputs(), ""), "revert-annotations-exportable.txt")
@@ -2919,6 +2979,7 @@
// Don't allow setting test-only on things that are always tests or never tests.
func TestInvalidTestOnlyTargets(t *testing.T) {
+ t.Parallel()
testCases := []string{
` java_test { name: "java-test", test_only: true, srcs: ["foo.java"], } `,
` java_test_host { name: "java-test-host", test_only: true, srcs: ["foo.java"], } `,
@@ -2954,6 +3015,7 @@
}
func TestJavaLibHostWithStem(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library_host {
name: "foo",
@@ -2963,7 +3025,7 @@
`)
buildOS := ctx.Config().BuildOS.String()
- foo := ctx.ModuleForTests("foo", buildOS+"_common")
+ foo := ctx.ModuleForTests(t, "foo", buildOS+"_common")
outputs := fmt.Sprint(foo.AllOutputs())
if !strings.Contains(outputs, "foo-new.jar") {
@@ -2972,6 +3034,7 @@
}
func TestJavaLibWithStem(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -2980,7 +3043,7 @@
}
`)
- foo := ctx.ModuleForTests("foo", "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
outputs := fmt.Sprint(foo.AllOutputs())
if !strings.Contains(outputs, "foo-new.jar") {
@@ -2989,6 +3052,7 @@
}
func TestJavaLibraryOutputFilesRel(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, `
@@ -3010,9 +3074,9 @@
}
`)
- foo := result.ModuleForTests("foo", "android_common")
- bar := result.ModuleForTests("bar", "android_common")
- baz := result.ModuleForTests("baz", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
+ bar := result.ModuleForTests(t, "bar", "android_common")
+ baz := result.ModuleForTests(t, "baz", "android_common")
fooOutputPaths := foo.OutputFiles(result.TestContext, t, "")
barOutputPaths := bar.OutputFiles(result.TestContext, t, "")
@@ -3034,10 +3098,10 @@
}
func TestCoverage(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
prepareForTestWithFrameworkJacocoInstrumentation,
- PrepareForTestWithTransitiveClasspathEnabled,
).RunTestWithBp(t, `
android_app {
name: "foo",
@@ -3054,8 +3118,8 @@
}
`)
- foo := result.ModuleForTests("foo", "android_common")
- androidCar := result.ModuleForTests("android.car", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
+ androidCar := result.ModuleForTests(t, "android.car", "android_common")
fooJacoco := foo.Rule("jacoco")
fooCombine := foo.Description("for javac")
@@ -3104,6 +3168,7 @@
// Test that a dependency edge is created to the matching variant of a native library listed in `jni_libs` of java_binary
func TestNativeRequiredDepOfJavaBinary(t *testing.T) {
+ t.Parallel()
findDepsOfModule := func(ctx *android.TestContext, module android.Module, depName string) []blueprint.Module {
var ret []blueprint.Module
ctx.VisitDirectDeps(module, func(dep blueprint.Module) {
@@ -3125,6 +3190,6 @@
}
`
res, _ := testJava(t, bp)
- deps := findDepsOfModule(res, res.ModuleForTests("myjavabin", "android_common").Module(), "mynativelib")
+ deps := findDepsOfModule(res, res.ModuleForTests(t, "myjavabin", "android_common").Module(), "mynativelib")
android.AssertIntEquals(t, "Create a dep on the first variant", 1, len(deps))
}
diff --git a/java/jdeps.go b/java/jdeps.go
index c2ce503..07f8c43 100644
--- a/java/jdeps.go
+++ b/java/jdeps.go
@@ -37,8 +37,6 @@
outputPath android.Path
}
-var _ android.SingletonMakeVarsProvider = (*jdepsGeneratorSingleton)(nil)
-
const (
jdepsJsonFileName = "module_bp_java_deps.json"
)
@@ -101,14 +99,7 @@
Rule: android.Touch,
Output: jfpath,
})
-}
-
-func (j *jdepsGeneratorSingleton) MakeVars(ctx android.MakeVarsContext) {
- if j.outputPath == nil {
- return
- }
-
- ctx.DistForGoal("general-tests", j.outputPath)
+ ctx.DistForGoals([]string{"general-tests", "dist_files"}, j.outputPath)
}
func createJsonFile(moduleInfos map[string]android.IdeInfo, jfpath android.WritablePath) error {
diff --git a/java/jdeps_test.go b/java/jdeps_test.go
index 1435000..00f3839 100644
--- a/java/jdeps_test.go
+++ b/java/jdeps_test.go
@@ -22,6 +22,7 @@
)
func TestCollectJavaLibraryPropertiesAddLibsDeps(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t,
`
java_library {name: "Foo"}
@@ -31,7 +32,7 @@
libs: ["Foo", "Bar"],
}
`)
- module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+ module := ctx.ModuleForTests(t, "javalib", "android_common").Module().(*Library)
dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
for _, expected := range []string{"Foo", "Bar"} {
@@ -42,6 +43,7 @@
}
func TestCollectJavaLibraryPropertiesAddStaticLibsDeps(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t,
`
java_library {name: "Foo"}
@@ -51,7 +53,7 @@
static_libs: ["Foo", "Bar"],
}
`)
- module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+ module := ctx.ModuleForTests(t, "javalib", "android_common").Module().(*Library)
dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
for _, expected := range []string{"Foo", "Bar"} {
@@ -62,6 +64,7 @@
}
func TestCollectJavaLibraryPropertiesAddScrs(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t,
`
java_library {
@@ -69,7 +72,7 @@
srcs: ["Foo.java", "Bar.java"],
}
`)
- module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+ module := ctx.ModuleForTests(t, "javalib", "android_common").Module().(*Library)
dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
expected := []string{"Foo.java", "Bar.java"}
@@ -79,6 +82,7 @@
}
func TestCollectJavaLibraryPropertiesAddAidlIncludeDirs(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t,
`
java_library {
@@ -88,7 +92,7 @@
},
}
`)
- module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+ module := ctx.ModuleForTests(t, "javalib", "android_common").Module().(*Library)
dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
expected := []string{"Foo", "Bar"}
@@ -98,6 +102,7 @@
}
func TestCollectJavaLibraryWithJarJarRules(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t,
`
java_library {
@@ -106,7 +111,7 @@
jarjar_rules: "jarjar_rules.txt",
}
`)
- module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+ module := ctx.ModuleForTests(t, "javalib", "android_common").Module().(*Library)
dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
android.AssertStringEquals(t, "IdeInfo.Srcs of repackaged library should not be empty", "foo.java", dpInfo.Srcs[0])
@@ -117,6 +122,7 @@
}
func TestCollectJavaLibraryLinkingAgainstVersionedSdk(t *testing.T) {
+ t.Parallel()
ctx := android.GroupFixturePreparers(
prepareForJavaTest,
FixtureWithPrebuiltApis(map[string][]string{
@@ -129,7 +135,7 @@
sdk_version: "29",
}
`)
- module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+ module := ctx.ModuleForTests(t, "javalib", "android_common").Module().(*Library)
dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
android.AssertStringListContains(t, "IdeInfo.Deps should contain versioned sdk module", dpInfo.Deps, "sdk_public_29_android")
@@ -165,11 +171,11 @@
api_surface: "public",
}
`)
- javalib := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+ javalib := ctx.ModuleForTests(t, "javalib", "android_common").Module().(*Library)
dpInfo, _ := android.OtherModuleProvider(ctx, javalib, android.IdeInfoProviderKey)
android.AssertStringListDoesNotContain(t, "IdeInfo.Deps should contain not contain `none`", dpInfo.Deps, "none")
- javalib_stubs := ctx.ModuleForTests("javalib.stubs", "android_common").Module().(*ApiLibrary)
+ javalib_stubs := ctx.ModuleForTests(t, "javalib.stubs", "android_common").Module().(*ApiLibrary)
dpInfo, _ = android.OtherModuleProvider(ctx, javalib_stubs, android.IdeInfoProviderKey)
android.AssertStringListDoesNotContain(t, "IdeInfo.Deps should contain not contain `none`", dpInfo.Deps, "none")
}
diff --git a/java/kotlin_test.go b/java/kotlin_test.go
index ad8734d..4b56cff 100644
--- a/java/kotlin_test.go
+++ b/java/kotlin_test.go
@@ -24,6 +24,7 @@
)
func TestKotlin(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "foo",
@@ -49,13 +50,6 @@
srcs: ["d.kt"],
}`
- kotlinStdlibTurbineCombinedJars := []string{
- "out/soong/.intermediates/default/java/kotlin-stdlib/android_common/turbine-combined/kotlin-stdlib.jar",
- "out/soong/.intermediates/default/java/kotlin-stdlib-jdk7/android_common/turbine-combined/kotlin-stdlib-jdk7.jar",
- "out/soong/.intermediates/default/java/kotlin-stdlib-jdk8/android_common/turbine-combined/kotlin-stdlib-jdk8.jar",
- "out/soong/.intermediates/default/java/kotlin-annotations/android_common/turbine-combined/kotlin-annotations.jar",
- }
-
kotlinStdlibTurbineJars := []string{
"out/soong/.intermediates/default/java/kotlin-stdlib/android_common/turbine/kotlin-stdlib.jar",
"out/soong/.intermediates/default/java/kotlin-stdlib-jdk7/android_common/turbine/kotlin-stdlib-jdk7.jar",
@@ -70,21 +64,11 @@
"out/soong/.intermediates/default/java/kotlin-annotations/android_common/javac/kotlin-annotations.jar",
}
- bootclasspathTurbineCombinedJars := []string{
- "out/soong/.intermediates/default/java/stable.core.platform.api.stubs/android_common/turbine-combined/stable.core.platform.api.stubs.jar",
- "out/soong/.intermediates/default/java/core-lambda-stubs/android_common/turbine-combined/core-lambda-stubs.jar",
- }
-
bootclasspathTurbineJars := []string{
"out/soong/.intermediates/default/java/stable.core.platform.api.stubs/android_common/turbine/stable.core.platform.api.stubs.jar",
"out/soong/.intermediates/default/java/core-lambda-stubs/android_common/turbine/core-lambda-stubs.jar",
}
- frameworkTurbineCombinedJars := []string{
- "out/soong/.intermediates/default/java/ext/android_common/turbine-combined/ext.jar",
- "out/soong/.intermediates/default/java/framework/android_common/turbine-combined/framework.jar",
- }
-
frameworkTurbineJars := []string{
"out/soong/.intermediates/default/java/ext/android_common/turbine/ext.jar",
"out/soong/.intermediates/default/java/framework/android_common/turbine/framework.jar",
@@ -108,68 +92,8 @@
barHeaderCombinedInputs []string
}{
{
- name: "normal",
- preparer: android.NullFixturePreparer,
- fooKotlincInputs: []string{"a.java", "b.kt"},
- fooJavacInputs: []string{"a.java"},
- fooKotlincClasspath: slices.Concat(
- bootclasspathTurbineCombinedJars,
- frameworkTurbineCombinedJars,
- []string{"out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar"},
- kotlinStdlibTurbineCombinedJars,
- ),
- fooJavacClasspath: slices.Concat(
- []string{"out/soong/.intermediates/foo/android_common/kotlin_headers/foo.jar"},
- frameworkTurbineCombinedJars,
- []string{"out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar"},
- kotlinStdlibTurbineCombinedJars,
- ),
- fooCombinedInputs: slices.Concat(
- []string{
- "out/soong/.intermediates/foo/android_common/kotlin/foo.jar",
- "out/soong/.intermediates/foo/android_common/javac/foo.jar",
- "out/soong/.intermediates/quz/android_common/combined/quz.jar",
- },
- kotlinStdlibJavacJars,
- ),
- fooHeaderCombinedInputs: slices.Concat(
- []string{
- "out/soong/.intermediates/foo/android_common/turbine/foo.jar",
- "out/soong/.intermediates/foo/android_common/kotlin_headers/foo.jar",
- "out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar",
- },
- kotlinStdlibTurbineCombinedJars,
- ),
-
- barKotlincInputs: []string{"b.kt"},
- barKotlincClasspath: slices.Concat(
- bootclasspathTurbineCombinedJars,
- frameworkTurbineCombinedJars,
- []string{
- "out/soong/.intermediates/foo/android_common/turbine-combined/foo.jar",
- "out/soong/.intermediates/baz/android_common/turbine-combined/baz.jar",
- },
- kotlinStdlibTurbineCombinedJars,
- ),
- barCombinedInputs: slices.Concat(
- []string{
- "out/soong/.intermediates/bar/android_common/kotlin/bar.jar",
- "out/soong/.intermediates/baz/android_common/combined/baz.jar",
- },
- kotlinStdlibJavacJars,
- []string{},
- ),
- barHeaderCombinedInputs: slices.Concat(
- []string{
- "out/soong/.intermediates/bar/android_common/kotlin_headers/bar.jar",
- "out/soong/.intermediates/baz/android_common/turbine-combined/baz.jar",
- },
- kotlinStdlibTurbineCombinedJars,
- ),
- },
- {
name: "transitive classpath",
- preparer: PrepareForTestWithTransitiveClasspathEnabled,
+ preparer: android.NullFixturePreparer,
fooKotlincInputs: []string{"a.java", "b.kt"},
fooJavacInputs: []string{"a.java"},
fooKotlincClasspath: slices.Concat(
@@ -234,11 +158,12 @@
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
tt.preparer,
).RunTestWithBp(t, bp)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
fooKotlinc := foo.Rule("kotlinc")
android.AssertPathsRelativeToTopEquals(t, "foo kotlinc inputs", tt.fooKotlincInputs, fooKotlinc.Inputs)
@@ -258,7 +183,7 @@
fooCombinedHeaderJar := foo.Output("turbine-combined/foo.jar")
android.AssertPathsRelativeToTopEquals(t, "foo header combined inputs", tt.fooHeaderCombinedInputs, fooCombinedHeaderJar.Inputs)
- bar := result.ModuleForTests("bar", "android_common")
+ bar := result.ModuleForTests(t, "bar", "android_common")
barKotlinc := bar.Rule("kotlinc")
android.AssertPathsRelativeToTopEquals(t, "bar kotlinc inputs", tt.barKotlincInputs, barKotlinc.Inputs)
@@ -275,6 +200,7 @@
}
func TestKapt(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "foo",
@@ -303,18 +229,19 @@
}
`
t.Run("", func(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, bp)
buildOS := ctx.Config().BuildOS.String()
- foo := ctx.ModuleForTests("foo", "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
kaptStubs := foo.Rule("kapt")
turbineApt := foo.Description("turbine apt")
kotlinc := foo.Rule("kotlinc")
javac := foo.Rule("javac")
- bar := ctx.ModuleForTests("bar", buildOS+"_common").Rule("javac").Output.String()
- baz := ctx.ModuleForTests("baz", buildOS+"_common").Rule("javac").Output.String()
+ bar := ctx.ModuleForTests(t, "bar", buildOS+"_common").Rule("javac").Output.String()
+ baz := ctx.ModuleForTests(t, "baz", buildOS+"_common").Rule("javac").Output.String()
// Test that the kotlin and java sources are passed to kapt and kotlinc
if len(kaptStubs.Inputs) != 2 || kaptStubs.Inputs[0].String() != "a.java" || kaptStubs.Inputs[1].String() != "b.kt" {
@@ -384,6 +311,7 @@
})
t.Run("errorprone", func(t *testing.T) {
+ t.Parallel()
env := map[string]string{
"RUN_ERROR_PRONE": "true",
}
@@ -395,13 +323,13 @@
buildOS := result.Config.BuildOS.String()
- kapt := result.ModuleForTests("foo", "android_common").Rule("kapt")
- javac := result.ModuleForTests("foo", "android_common").Description("javac")
- errorprone := result.ModuleForTests("foo", "android_common").Description("errorprone")
+ kapt := result.ModuleForTests(t, "foo", "android_common").Rule("kapt")
+ javac := result.ModuleForTests(t, "foo", "android_common").Description("javac")
+ errorprone := result.ModuleForTests(t, "foo", "android_common").Description("errorprone")
- bar := result.ModuleForTests("bar", buildOS+"_common").Description("javac").Output.String()
- baz := result.ModuleForTests("baz", buildOS+"_common").Description("javac").Output.String()
- myCheck := result.ModuleForTests("my_check", buildOS+"_common").Description("javac").Output.String()
+ bar := result.ModuleForTests(t, "bar", buildOS+"_common").Description("javac").Output.String()
+ baz := result.ModuleForTests(t, "baz", buildOS+"_common").Description("javac").Output.String()
+ myCheck := result.ModuleForTests(t, "my_check", buildOS+"_common").Description("javac").Output.String()
// Test that the errorprone plugins are not passed to kapt
expectedProcessorPath := "-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + bar +
@@ -434,6 +362,7 @@
}
func TestKaptEncodeFlags(t *testing.T) {
+ t.Parallel()
// Compares the kaptEncodeFlags against the results of the example implementation at
// https://kotlinlang.org/docs/reference/kapt.html#apjavac-options-encoding
tests := []struct {
@@ -484,6 +413,7 @@
for i, test := range tests {
t.Run(strconv.Itoa(i), func(t *testing.T) {
+ t.Parallel()
got := kaptEncodeFlags(test.in)
if got != test.out {
t.Errorf("\nwant %q\n got %q", test.out, got)
@@ -493,6 +423,7 @@
}
func TestKotlinCompose(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, `
@@ -523,9 +454,9 @@
buildOS := result.Config.BuildOS.String()
- composeCompiler := result.ModuleForTests("kotlin-compose-compiler-plugin", buildOS+"_common").Rule("combineJar").Output
- withCompose := result.ModuleForTests("withcompose", "android_common")
- noCompose := result.ModuleForTests("nocompose", "android_common")
+ composeCompiler := result.ModuleForTests(t, "kotlin-compose-compiler-plugin", buildOS+"_common").Rule("combineJar").Output
+ withCompose := result.ModuleForTests(t, "withcompose", "android_common")
+ noCompose := result.ModuleForTests(t, "nocompose", "android_common")
android.AssertStringListContains(t, "missing compose compiler dependency",
withCompose.Rule("kotlinc").Implicits.Strings(), composeCompiler.String())
@@ -544,6 +475,7 @@
}
func TestKotlinPlugin(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, `
@@ -570,9 +502,9 @@
buildOS := result.Config.BuildOS.String()
- kotlinPlugin := result.ModuleForTests("kotlin_plugin", buildOS+"_common").Rule("combineJar").Output
- withKotlinPlugin := result.ModuleForTests("with_kotlin_plugin", "android_common")
- noKotlinPlugin := result.ModuleForTests("no_kotlin_plugin", "android_common")
+ kotlinPlugin := result.ModuleForTests(t, "kotlin_plugin", buildOS+"_common").Rule("combineJar").Output
+ withKotlinPlugin := result.ModuleForTests(t, "with_kotlin_plugin", "android_common")
+ noKotlinPlugin := result.ModuleForTests(t, "no_kotlin_plugin", "android_common")
android.AssertStringListContains(t, "missing plugin compiler dependency",
withKotlinPlugin.Rule("kotlinc").Implicits.Strings(), kotlinPlugin.String())
diff --git a/java/lint.go b/java/lint.go
index cee25a8..66f7f85 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -398,7 +398,7 @@
}
}
- extraLintCheckModules := ctx.GetDirectDepsWithTag(extraLintCheckTag)
+ extraLintCheckModules := ctx.GetDirectDepsProxyWithTag(extraLintCheckTag)
for _, extraLintCheckModule := range extraLintCheckModules {
if dep, ok := android.OtherModuleProvider(ctx, extraLintCheckModule, JavaInfoProvider); ok {
l.extraLintCheckJars = append(l.extraLintCheckJars, dep.ImplementationAndResourcesJars...)
@@ -423,7 +423,7 @@
depSetsBuilder := NewLintDepSetBuilder().Direct(html, text, xml, baseline)
- ctx.VisitDirectDepsWithTag(staticLibTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(staticLibTag, func(dep android.ModuleProxy) {
if info, ok := android.OtherModuleProvider(ctx, dep, LintProvider); ok {
depSetsBuilder.Transitive(info)
}
@@ -704,16 +704,12 @@
zip(l.referenceBaselineZip, func(l *LintInfo) android.Path { return l.ReferenceBaseline })
ctx.Phony("lint-check", l.htmlZip, l.textZip, l.xmlZip, l.referenceBaselineZip)
-}
-func (l *lintSingleton) MakeVars(ctx android.MakeVarsContext) {
if !ctx.Config().UnbundledBuild() {
ctx.DistForGoal("lint-check", l.htmlZip, l.textZip, l.xmlZip, l.referenceBaselineZip)
}
}
-var _ android.SingletonMakeVarsProvider = (*lintSingleton)(nil)
-
func init() {
android.RegisterParallelSingletonType("lint",
func() android.Singleton { return &lintSingleton{} })
diff --git a/java/lint_test.go b/java/lint_test.go
index 617dc54..236fa63 100644
--- a/java/lint_test.go
+++ b/java/lint_test.go
@@ -22,6 +22,7 @@
)
func TestJavaLintDoesntUseBaselineImplicitly(t *testing.T) {
+ t.Parallel()
ctx, _ := testJavaWithFS(t, `
java_library {
name: "foo",
@@ -37,7 +38,7 @@
"lint-baseline.xml": nil,
})
- foo := ctx.ModuleForTests("foo", "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, foo.Output("lint.sbox.textproto"))
if strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml") {
@@ -46,6 +47,7 @@
}
func TestJavaLintRequiresCustomLintFileToExist(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.PrepareForTestDisallowNonExistentPaths,
@@ -65,6 +67,7 @@
}
func TestJavaLintUsesCorrectBpConfig(t *testing.T) {
+ t.Parallel()
ctx, _ := testJavaWithFS(t, `
java_library {
name: "foo",
@@ -84,7 +87,7 @@
"mybaseline.xml": nil,
})
- foo := ctx.ModuleForTests("foo", "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, foo.Output("lint.sbox.textproto"))
if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline mybaseline.xml") {
@@ -101,6 +104,7 @@
}
func TestJavaLintBypassUpdatableChecks(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
bp string
@@ -144,6 +148,7 @@
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
errorHandler := android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.error)
android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules).
ExtendWithErrorHandler(errorHandler).
@@ -153,6 +158,7 @@
}
func TestJavaLintStrictUpdatabilityLinting(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "foo",
@@ -187,7 +193,7 @@
result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules, fs.AddToFixture()).
RunTestWithBp(t, bp)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
strictUpdatabilityCheck := foo.Output("lint_strict_updatability_check.stamp")
if !strings.Contains(strictUpdatabilityCheck.RuleParams.Command,
"--disallowed_issues NewApi") {
@@ -250,7 +256,7 @@
})).
RunTestWithBp(t, thisBp)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
sboxProto := android.RuleBuilderSboxProtoForTests(t, result.TestContext, foo.Output("lint.sbox.textproto"))
if !strings.Contains(*sboxProto.Commands[0].Command, "/"+testCase.expected_file) {
t.Error("did not use full api database for case", testCase)
@@ -307,7 +313,7 @@
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, bp)
ctx := result.TestContext
- foo := ctx.ModuleForTests("foo", "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, foo.Output("lint.sbox.textproto"))
command := *sboxProto.Commands[0].Command
@@ -315,7 +321,7 @@
t.Fatalf("Expected command to not contain --test")
}
- foo2 := ctx.ModuleForTests("foo2", "android_common")
+ foo2 := ctx.ModuleForTests(t, "foo2", "android_common")
sboxProto2 := android.RuleBuilderSboxProtoForTests(t, ctx, foo2.Output("lint.sbox.textproto"))
command2 := *sboxProto2.Commands[0].Command
diff --git a/java/metalava/main-config.xml b/java/metalava/main-config.xml
index c61196f..c2881ac 100644
--- a/java/metalava/main-config.xml
+++ b/java/metalava/main-config.xml
@@ -16,4 +16,20 @@
<config xmlns="http://www.google.com/tools/metalava/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.google.com/tools/metalava/config ../../../../tools/metalava/metalava/src/main/resources/schemas/config.xsd"/>
+ xsi:schemaLocation="http://www.google.com/tools/metalava/config ../../../../tools/metalava/metalava/src/main/resources/schemas/config.xsd">
+ <api-surfaces>
+ <!-- These are hard coded into java_sdk_library. -->
+ <api-surface name="public"/>
+ <api-surface name="system" extends="public"/>
+ <api-surface name="module-lib" extends="system"/>
+ <api-surface name="test" extends="system"/>
+ <api-surface name="system-server" extends="public"/>
+ <!-- This is used in java/core-libraries/Android.bp. -->
+ <api-surface name="core"/>
+ <!-- These are used in libcore, external/conscrypt and external/icu. -->
+ <api-surface name="core-platform" extends="public"/>
+ <api-surface name="core-platform-legacy" extends="public"/>
+ <api-surface name="core-platform-plus-public"/>
+ <api-surface name="intra-core" extends="public"/>
+ </api-surfaces>
+</config>
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index 152eb1e..155afc6 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -15,6 +15,11 @@
package java
import (
+ "maps"
+ "slices"
+
+ "github.com/google/blueprint"
+
"android/soong/android"
"android/soong/dexpreopt"
)
@@ -29,12 +34,15 @@
// The tags used for the dependencies between the platform bootclasspath and any configured boot
// jars.
-var (
- platformBootclasspathArtBootJarDepTag = bootclasspathDependencyTag{name: "art-boot-jar"}
- platformBootclasspathBootJarDepTag = bootclasspathDependencyTag{name: "platform-boot-jar"}
- platformBootclasspathApexBootJarDepTag = bootclasspathDependencyTag{name: "apex-boot-jar"}
- platformBootclasspathImplLibDepTag = dependencyTag{name: "impl-lib-tag"}
-)
+type platformBootclasspathImplLibDepTagType struct {
+ blueprint.BaseDependencyTag
+}
+
+func (p platformBootclasspathImplLibDepTagType) ExcludeFromVisibilityEnforcement() {}
+
+var platformBootclasspathImplLibDepTag platformBootclasspathImplLibDepTagType
+
+var _ android.ExcludeFromVisibilityEnforcementTag = platformBootclasspathImplLibDepTag
type platformBootclasspathModule struct {
android.ModuleBase
@@ -48,6 +56,12 @@
// The apex:module pairs obtained from the fragments.
fragments []android.Module
+ // The map of apex to the fragments they contain.
+ apexNameToFragment map[string]android.Module
+
+ // The map of library modules in the bootclasspath to the fragments that contain them.
+ libraryToApex map[android.Module]string
+
// Path to the monolithic hiddenapi-flags.csv file.
hiddenAPIFlagsCSV android.OutputPath
@@ -89,26 +103,12 @@
b.hiddenAPIDepsMutator(ctx)
- if !dexpreopt.IsDex2oatNeeded(ctx) {
- return
+ if dexpreopt.IsDex2oatNeeded(ctx) {
+ // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
+ // path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
+ dexpreopt.RegisterToolDeps(ctx)
}
- // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
- // path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
- dexpreopt.RegisterToolDeps(ctx)
-}
-
-func (b *platformBootclasspathModule) hiddenAPIDepsMutator(ctx android.BottomUpMutatorContext) {
- if ctx.Config().DisableHiddenApiChecks() {
- return
- }
-
- // Add dependencies onto the stub lib modules.
- apiLevelToStubLibModules := hiddenAPIComputeMonolithicStubLibModules(ctx.Config())
- hiddenAPIAddStubLibDependencies(ctx, apiLevelToStubLibModules)
-}
-
-func (b *platformBootclasspathModule) BootclasspathDepsMutator(ctx android.BottomUpMutatorContext) {
// Add dependencies on all the ART jars.
global := dexpreopt.GetGlobalConfig(ctx)
addDependenciesOntoSelectedBootImageApexes(ctx, "com.android.art")
@@ -116,13 +116,13 @@
var bootImageModuleNames []string
// TODO: b/308174306 - Remove the mechanism of depending on the java_sdk_library(_import) directly
- addDependenciesOntoBootImageModules(ctx, global.ArtApexJars, platformBootclasspathArtBootJarDepTag)
+ addDependenciesOntoBootImageModules(ctx, global.ArtApexJars, artBootJar)
bootImageModuleNames = append(bootImageModuleNames, global.ArtApexJars.CopyOfJars()...)
// Add dependencies on all the non-updatable jars, which are on the platform or in non-updatable
// APEXes.
platformJars := b.platformJars(ctx)
- addDependenciesOntoBootImageModules(ctx, platformJars, platformBootclasspathBootJarDepTag)
+ addDependenciesOntoBootImageModules(ctx, platformJars, platformBootJar)
bootImageModuleNames = append(bootImageModuleNames, platformJars.CopyOfJars()...)
// Add dependencies on all the updatable jars, except the ART jars.
@@ -133,7 +133,7 @@
}
addDependenciesOntoSelectedBootImageApexes(ctx, android.FirstUniqueStrings(apexes)...)
// TODO: b/308174306 - Remove the mechanism of depending on the java_sdk_library(_import) directly
- addDependenciesOntoBootImageModules(ctx, apexJars, platformBootclasspathApexBootJarDepTag)
+ addDependenciesOntoBootImageModules(ctx, apexJars, apexBootJar)
bootImageModuleNames = append(bootImageModuleNames, apexJars.CopyOfJars()...)
// Add dependencies on all the fragments.
@@ -147,27 +147,37 @@
}
}
-func addDependenciesOntoBootImageModules(ctx android.BottomUpMutatorContext, modules android.ConfiguredJarList, tag bootclasspathDependencyTag) {
+func (b *platformBootclasspathModule) hiddenAPIDepsMutator(ctx android.BottomUpMutatorContext) {
+ if ctx.Config().DisableHiddenApiChecks() {
+ return
+ }
+
+ // Add dependencies onto the stub lib modules.
+ apiLevelToStubLibModules := hiddenAPIComputeMonolithicStubLibModules(ctx.Config())
+ hiddenAPIAddStubLibDependencies(ctx, apiLevelToStubLibModules)
+}
+
+func addDependenciesOntoBootImageModules(ctx android.BottomUpMutatorContext, modules android.ConfiguredJarList, tagType bootclasspathDependencyTagType) {
for i := 0; i < modules.Len(); i++ {
apex := modules.Apex(i)
name := modules.Jar(i)
- addDependencyOntoApexModulePair(ctx, apex, name, tag)
+ addDependencyOntoApexModulePair(ctx, apex, name, tagType)
}
}
func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// Gather all the dependencies from the art, platform, and apex boot jars.
- artModules := gatherApexModulePairDepsWithTag(ctx, platformBootclasspathArtBootJarDepTag)
- platformModules := gatherApexModulePairDepsWithTag(ctx, platformBootclasspathBootJarDepTag)
- apexModules := gatherApexModulePairDepsWithTag(ctx, platformBootclasspathApexBootJarDepTag)
+ artModules, artModulesToApex := gatherApexModulePairDepsWithTag(ctx, artBootJar)
+ platformModules, platformModulesToApex := gatherApexModulePairDepsWithTag(ctx, platformBootJar)
+ apexModules, apexModulesToApex := gatherApexModulePairDepsWithTag(ctx, apexBootJar)
// Concatenate them all, in order as they would appear on the bootclasspath.
- var allModules []android.Module
- allModules = append(allModules, artModules...)
- allModules = append(allModules, platformModules...)
- allModules = append(allModules, apexModules...)
+ allModules := slices.Concat(artModules, platformModules, apexModules)
b.configuredModules = allModules
+ b.libraryToApex = maps.Clone(artModulesToApex)
+ maps.Copy(b.libraryToApex, platformModulesToApex)
+ maps.Copy(b.libraryToApex, apexModulesToApex)
// Do not add implLibModule to allModules as the impl lib is only used to collect the
// transitive source files
@@ -188,7 +198,7 @@
TransformResourcesToJar(ctx, srcjar, jarArgs, transitiveSrcFiles)
// Gather all the fragments dependencies.
- b.fragments = gatherApexModulePairDepsWithTag(ctx, bootclasspathFragmentDepTag)
+ b.fragments, b.apexNameToFragment = gatherFragments(ctx)
// Check the configuration of the boot modules.
// ART modules are checked by the art-bootclasspath-fragment.
@@ -197,7 +207,7 @@
b.generateClasspathProtoBuildActions(ctx)
- bootDexJarByModule := b.generateHiddenAPIBuildActions(ctx, b.configuredModules, b.fragments)
+ bootDexJarByModule := b.generateHiddenAPIBuildActions(ctx, b.configuredModules, b.fragments, b.libraryToApex, b.apexNameToFragment)
buildRuleForBootJarsPackageCheck(ctx, bootDexJarByModule)
ctx.SetOutputFiles(android.Paths{b.hiddenAPIFlagsCSV}, "hiddenapi-flags.csv")
@@ -248,7 +258,7 @@
fromUpdatableApex := apexInfo.Updatable
if fromUpdatableApex {
// error: this jar is part of an updatable apex
- ctx.ModuleErrorf("module %q from updatable apexes %q is not allowed in the platform bootclasspath", ctx.OtherModuleName(m), apexInfo.InApexVariants)
+ ctx.ModuleErrorf("module %q from updatable apex %q is not allowed in the platform bootclasspath", ctx.OtherModuleName(m), apexInfo.BaseApexName)
} else {
// ok: this jar is part of the platform or a non-updatable apex
}
@@ -272,7 +282,11 @@
// modules is complete.
if !ctx.Config().AlwaysUsePrebuiltSdks() {
// error: this jar is part of the platform
- ctx.ModuleErrorf("module %q from platform is not allowed in the apex boot jars list", name)
+ if ctx.Config().AllowMissingDependencies() {
+ ctx.AddMissingDependencies([]string{"module_" + name + "_from_platform_is_not_allowed_in_the_apex_boot_jars_list"})
+ } else {
+ ctx.ModuleErrorf("module %q from platform is not allowed in the apex boot jars list", name)
+ }
}
} else {
// TODO(b/177892522): Treat this as an error.
@@ -284,7 +298,8 @@
}
// generateHiddenAPIBuildActions generates all the hidden API related build rules.
-func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, modules []android.Module, fragments []android.Module) bootDexJarByModule {
+func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, modules []android.Module,
+ fragments []android.Module, libraryToApex map[android.Module]string, apexNameToFragment map[string]android.Module) bootDexJarByModule {
createEmptyHiddenApiFiles := func() {
paths := android.OutputPaths{b.hiddenAPIFlagsCSV, b.hiddenAPIIndexCSV, b.hiddenAPIMetadataCSV}
for _, path := range paths {
@@ -311,7 +326,7 @@
}
// Construct a list of ClasspathElement objects from the modules and fragments.
- classpathElements := CreateClasspathElements(ctx, modules, fragments)
+ classpathElements := CreateClasspathElements(ctx, modules, fragments, libraryToApex, apexNameToFragment)
monolithicInfo := b.createAndProvideMonolithicHiddenAPIInfo(ctx, classpathElements)
diff --git a/java/platform_bootclasspath_test.go b/java/platform_bootclasspath_test.go
index 1f691a0..727e306 100644
--- a/java/platform_bootclasspath_test.go
+++ b/java/platform_bootclasspath_test.go
@@ -27,6 +27,7 @@
)
func TestPlatformBootclasspath(t *testing.T) {
+ t.Parallel()
preparer := android.GroupFixturePreparers(
prepareForTestWithPlatformBootclasspath,
FixtureConfigureBootJars("platform:foo", "system_ext:bar"),
@@ -81,6 +82,7 @@
`)
t.Run("missing", func(t *testing.T) {
+ t.Parallel()
preparer.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`"platform-bootclasspath" depends on undefined module "foo"`)).
RunTest(t)
@@ -91,11 +93,12 @@
checkSrcJarInputs := func(t *testing.T, result *android.TestResult, name string, expected []string) {
t.Helper()
- srcjar := result.ModuleForTests(name, "android_common").Output(name + "-transitive.srcjar")
+ srcjar := result.ModuleForTests(t, name, "android_common").Output(name + "-transitive.srcjar")
android.AssertStringDoesContain(t, "srcjar arg", srcjar.Args["jarArgs"], "-srcjar")
android.AssertArrayString(t, "srcjar inputs", expected, srcjar.Implicits.Strings())
}
t.Run("source", func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
preparer,
addSourceBootclassPathModule,
@@ -112,6 +115,7 @@
})
t.Run("prebuilt", func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
preparer,
addPrebuiltBootclassPathModule,
@@ -128,6 +132,7 @@
})
t.Run("source+prebuilt - source preferred", func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
preparer,
addSourceBootclassPathModule,
@@ -145,6 +150,7 @@
})
t.Run("source+prebuilt - prebuilt preferred", func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
preparer,
addSourceBootclassPathModule,
@@ -162,6 +168,7 @@
})
t.Run("dex import", func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
preparer,
android.FixtureAddTextFile("deximport/Android.bp", `
@@ -184,6 +191,7 @@
}
func TestPlatformBootclasspathVariant(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForTestWithPlatformBootclasspath,
android.FixtureWithRootAndroidBp(`
@@ -198,6 +206,7 @@
}
func TestPlatformBootclasspath_ClasspathFragmentPaths(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForTestWithPlatformBootclasspath,
android.FixtureWithRootAndroidBp(`
@@ -213,6 +222,7 @@
}
func TestPlatformBootclasspathModule_AndroidMkEntries(t *testing.T) {
+ t.Parallel()
preparer := android.GroupFixturePreparers(
prepareForTestWithPlatformBootclasspath,
android.FixtureWithRootAndroidBp(`
@@ -223,6 +233,7 @@
)
t.Run("AndroidMkEntries", func(t *testing.T) {
+ t.Parallel()
result := preparer.RunTest(t)
p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
@@ -232,6 +243,7 @@
})
t.Run("hiddenapi-flags-entry", func(t *testing.T) {
+ t.Parallel()
result := preparer.RunTest(t)
p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
@@ -243,6 +255,7 @@
})
t.Run("classpath-fragment-entry", func(t *testing.T) {
+ t.Parallel()
result := preparer.RunTest(t)
want := map[string][]string{
@@ -267,6 +280,7 @@
}
func TestPlatformBootclasspath_Dist(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForTestWithPlatformBootclasspath,
FixtureConfigureBootJars("platform:foo", "platform:bar"),
@@ -310,6 +324,7 @@
}
func TestPlatformBootclasspath_HiddenAPIMonolithicFiles(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -352,7 +367,7 @@
// Make sure that the foo-hiddenapi-annotations.jar is included in the inputs to the rules that
// creates the index.csv file.
- platformBootclasspath := result.ModuleForTests("myplatform-bootclasspath", "android_common")
+ platformBootclasspath := result.ModuleForTests(t, "myplatform-bootclasspath", "android_common")
var rule android.TestingBuildParams
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
index bb98944..363521a 100644
--- a/java/platform_compat_config.go
+++ b/java/platform_compat_config.go
@@ -43,6 +43,13 @@
ctx.RegisterModuleType("global_compat_config", globalCompatConfigFactory)
}
+type PlatformCompatConfigInfo struct {
+ CompatConfig android.OutputPath
+ SubDir string
+}
+
+var PlatformCompatConfigInfoProvider = blueprint.NewProvider[PlatformCompatConfigInfo]()
+
var PrepareForTestWithPlatformCompatConfig = android.FixtureRegisterWithContext(registerPlatformCompatConfigBuildComponents)
func platformCompatConfigPath(ctx android.PathContext) android.OutputPath {
@@ -124,6 +131,11 @@
rule.Build(configFileName, "Extract compat/compat_config.xml and install it")
ctx.InstallFile(p.installDirPath, p.configFile.Base(), p.configFile)
ctx.SetOutputFiles(android.Paths{p.configFile}, "")
+
+ android.SetProvider(ctx, PlatformCompatConfigInfoProvider, PlatformCompatConfigInfo{
+ CompatConfig: p.CompatConfig(),
+ SubDir: p.SubDir(),
+ })
}
func (p *platformCompatConfig) AndroidMkEntries() []android.AndroidMkEntries {
@@ -278,12 +290,7 @@
rule.Build("merged-compat-config", "Merge compat config")
p.metadata = outputPath
-}
-
-func (p *platformCompatConfigSingleton) MakeVars(ctx android.MakeVarsContext) {
- if p.metadata != nil {
- ctx.DistForGoal("droidcore", p.metadata)
- }
+ ctx.DistForGoal("droidcore", p.metadata)
}
func platformCompatConfigSingletonFactory() android.Singleton {
diff --git a/java/platform_compat_config_test.go b/java/platform_compat_config_test.go
index f7529a7..72f81e0 100644
--- a/java/platform_compat_config_test.go
+++ b/java/platform_compat_config_test.go
@@ -21,6 +21,7 @@
)
func TestPlatformCompatConfig(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithPlatformCompatConfig,
android.FixtureWithRootAndroidBp(`
diff --git a/java/plugin.go b/java/plugin.go
index 610c9fd..3534c7b 100644
--- a/java/plugin.go
+++ b/java/plugin.go
@@ -16,8 +16,21 @@
import (
"android/soong/android"
+ "github.com/google/blueprint"
)
+type JavaPluginInfo struct {
+ ProcessorClass *string
+ GeneratesApi bool
+}
+
+var JavaPluginInfoProvider = blueprint.NewProvider[JavaPluginInfo]()
+
+type KotlinPluginInfo struct {
+}
+
+var KotlinPluginInfoProvider = blueprint.NewProvider[KotlinPluginInfo]()
+
func init() {
registerJavaPluginBuildComponents(android.InitRegistrationContext)
}
@@ -65,7 +78,22 @@
Generates_api *bool
}
+func (p *Plugin) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ p.Library.GenerateAndroidBuildActions(ctx)
+
+ android.SetProvider(ctx, JavaPluginInfoProvider, JavaPluginInfo{
+ ProcessorClass: p.pluginProperties.Processor_class,
+ GeneratesApi: Bool(p.pluginProperties.Generates_api),
+ })
+}
+
// Plugin describes a kotlin_plugin module, a host java/kotlin library that will be used by kotlinc as a compiler plugin.
type KotlinPlugin struct {
Library
}
+
+func (p *KotlinPlugin) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ p.Library.GenerateAndroidBuildActions(ctx)
+
+ android.SetProvider(ctx, KotlinPluginInfoProvider, KotlinPluginInfo{})
+}
diff --git a/java/plugin_test.go b/java/plugin_test.go
index dc29b1c..007b74a 100644
--- a/java/plugin_test.go
+++ b/java/plugin_test.go
@@ -19,6 +19,7 @@
)
func TestNoPlugin(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -26,8 +27,8 @@
}
`)
- javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
- turbine := ctx.ModuleForTests("foo", "android_common").MaybeRule("turbine")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac")
+ turbine := ctx.ModuleForTests(t, "foo", "android_common").MaybeRule("turbine")
if turbine.Rule == nil {
t.Errorf("expected turbine to be enabled")
@@ -43,6 +44,7 @@
}
func TestPlugin(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -59,14 +61,14 @@
buildOS := ctx.Config().BuildOS.String()
- javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
- turbine := ctx.ModuleForTests("foo", "android_common").MaybeRule("turbine")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac")
+ turbine := ctx.ModuleForTests(t, "foo", "android_common").MaybeRule("turbine")
if turbine.Rule == nil {
t.Errorf("expected turbine to be enabled")
}
- bar := ctx.ModuleForTests("bar", buildOS+"_common").Rule("javac").Output.String()
+ bar := ctx.ModuleForTests(t, "bar", buildOS+"_common").Rule("javac").Output.String()
if !inList(bar, javac.Implicits.Strings()) {
t.Errorf("foo implicits %v does not contain %q", javac.Implicits.Strings(), bar)
@@ -82,6 +84,7 @@
}
func TestPluginGeneratesApi(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -99,14 +102,14 @@
buildOS := ctx.Config().BuildOS.String()
- javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
- turbine := ctx.ModuleForTests("foo", "android_common").MaybeRule("turbine")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac")
+ turbine := ctx.ModuleForTests(t, "foo", "android_common").MaybeRule("turbine")
if turbine.Rule != nil {
t.Errorf("expected turbine to be disabled")
}
- bar := ctx.ModuleForTests("bar", buildOS+"_common").Rule("javac").Output.String()
+ bar := ctx.ModuleForTests(t, "bar", buildOS+"_common").Rule("javac").Output.String()
if !inList(bar, javac.Implicits.Strings()) {
t.Errorf("foo implicits %v does not contain %q", javac.Implicits.Strings(), bar)
diff --git a/java/prebuilt_apis_test.go b/java/prebuilt_apis_test.go
index b6fb2c6..1f095e4 100644
--- a/java/prebuilt_apis_test.go
+++ b/java/prebuilt_apis_test.go
@@ -29,6 +29,7 @@
}
func TestPrebuiltApis_SystemModulesCreation(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
FixtureWithPrebuiltApis(map[string][]string{
@@ -61,6 +62,7 @@
}
func TestPrebuiltApis_WithExtensions(t *testing.T) {
+ t.Parallel()
runTestWithBaseExtensionLevel := func(v int) (foo_input, bar_input, baz_input string) {
result := android.GroupFixturePreparers(
prepareForJavaTest,
@@ -76,9 +78,9 @@
"2": {"foo", "bar"},
}),
).RunTest(t)
- foo_input = result.ModuleForTests("foo.api.public.latest", "").Rule("generator").Implicits[0].String()
- bar_input = result.ModuleForTests("bar.api.public.latest", "").Rule("generator").Implicits[0].String()
- baz_input = result.ModuleForTests("baz.api.public.latest", "").Rule("generator").Implicits[0].String()
+ foo_input = result.ModuleForTests(t, "foo.api.public.latest", "").Rule("generator").Implicits[0].String()
+ bar_input = result.ModuleForTests(t, "bar.api.public.latest", "").Rule("generator").Implicits[0].String()
+ baz_input = result.ModuleForTests(t, "baz.api.public.latest", "").Rule("generator").Implicits[0].String()
return
}
// Extension 2 is the latest for both foo and bar, finalized after the base extension version.
@@ -101,6 +103,7 @@
}
func TestPrebuiltApis_WithIncrementalApi(t *testing.T) {
+ t.Parallel()
runTestWithIncrementalApi := func() (foo_input, bar_input, baz_input string) {
result := android.GroupFixturePreparers(
prepareForJavaTest,
@@ -111,9 +114,9 @@
"current": {"foo", "bar"},
}),
).RunTest(t)
- foo_input = result.ModuleForTests("foo.api.public.latest", "").Rule("generator").Implicits[0].String()
- bar_input = result.ModuleForTests("bar.api.public.latest", "").Rule("generator").Implicits[0].String()
- baz_input = result.ModuleForTests("baz.api.public.latest", "").Rule("generator").Implicits[0].String()
+ foo_input = result.ModuleForTests(t, "foo.api.public.latest", "").Rule("generator").Implicits[0].String()
+ bar_input = result.ModuleForTests(t, "bar.api.public.latest", "").Rule("generator").Implicits[0].String()
+ baz_input = result.ModuleForTests(t, "baz.api.public.latest", "").Rule("generator").Implicits[0].String()
return
}
// 33.1 is the latest for baz, 33.2 is the latest for both foo & bar
diff --git a/java/proto_test.go b/java/proto_test.go
index d1cb714..3fbe3e6 100644
--- a/java/proto_test.go
+++ b/java/proto_test.go
@@ -28,6 +28,7 @@
`
func TestProtoStream(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "java-stream-protos",
@@ -45,7 +46,7 @@
PrepareForIntegrationTestWithJava,
).RunTestWithBp(t, protoModules+bp)
- proto0 := ctx.ModuleForTests("java-stream-protos", "android_common").Output("proto/proto0.srcjar")
+ proto0 := ctx.ModuleForTests(t, "java-stream-protos", "android_common").Output("proto/proto0.srcjar")
if cmd := proto0.RuleParams.Command; !strings.Contains(cmd, "--javastream_out=") {
t.Errorf("expected '--javastream_out' in %q", cmd)
diff --git a/java/ravenwood.go b/java/ravenwood.go
index 84d6a9f..c4078c5 100644
--- a/java/ravenwood.go
+++ b/java/ravenwood.go
@@ -185,26 +185,24 @@
// All JNI libraries included in the runtime
var runtimeJniModuleNames map[string]bool
- if utils := ctx.GetDirectDepsWithTag(ravenwoodUtilsTag)[0]; utils != nil {
- for _, installFile := range android.OtherModuleProviderOrDefault(
- ctx, utils, android.InstallFilesProvider).InstallFiles {
- installDeps = append(installDeps, installFile)
- }
- jniDeps, ok := android.OtherModuleProvider(ctx, utils, ravenwoodLibgroupJniDepProvider)
- if ok {
- runtimeJniModuleNames = jniDeps.names
- }
+ utils := ctx.GetDirectDepsProxyWithTag(ravenwoodUtilsTag)[0]
+ for _, installFile := range android.OtherModuleProviderOrDefault(
+ ctx, utils, android.InstallFilesProvider).InstallFiles {
+ installDeps = append(installDeps, installFile)
+ }
+ jniDeps, ok := android.OtherModuleProvider(ctx, utils, ravenwoodLibgroupJniDepProvider)
+ if ok {
+ runtimeJniModuleNames = jniDeps.names
}
- if runtime := ctx.GetDirectDepsWithTag(ravenwoodRuntimeTag)[0]; runtime != nil {
- for _, installFile := range android.OtherModuleProviderOrDefault(
- ctx, runtime, android.InstallFilesProvider).InstallFiles {
- installDeps = append(installDeps, installFile)
- }
- jniDeps, ok := android.OtherModuleProvider(ctx, runtime, ravenwoodLibgroupJniDepProvider)
- if ok {
- runtimeJniModuleNames = jniDeps.names
- }
+ runtime := ctx.GetDirectDepsProxyWithTag(ravenwoodRuntimeTag)[0]
+ for _, installFile := range android.OtherModuleProviderOrDefault(
+ ctx, runtime, android.InstallFilesProvider).InstallFiles {
+ installDeps = append(installDeps, installFile)
+ }
+ jniDeps, ok = android.OtherModuleProvider(ctx, runtime, ravenwoodLibgroupJniDepProvider)
+ if ok {
+ runtimeJniModuleNames = jniDeps.names
}
// Also remember what JNI libs are in the runtime.
@@ -228,7 +226,7 @@
resApkInstallPath := installPath.Join(ctx, "ravenwood-res-apks")
copyResApk := func(tag blueprint.DependencyTag, toFileName string) {
- if resApk := ctx.GetDirectDepsWithTag(tag); len(resApk) > 0 {
+ if resApk := ctx.GetDirectDepsProxyWithTag(tag); len(resApk) > 0 {
installFile := android.OutputFileForModule(ctx, resApk[0], "")
installResApk := ctx.InstallFile(resApkInstallPath, toFileName, installFile)
installDeps = append(installDeps, installResApk)
@@ -260,6 +258,19 @@
// Install our JAR with all dependencies
ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.outputFile, installDeps...)
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ if _, ok := r.testConfig.(android.WritablePath); ok {
+ moduleInfoJSON.AutoTestConfig = []string{"true"}
+ }
+ if r.testConfig != nil {
+ moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, r.testConfig.String())
+ }
+ moduleInfoJSON.CompatibilitySuites = []string{"general-tests", "ravenwood-tests"}
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: r.TestSuites(),
+ })
}
func (r *ravenwoodTest) AndroidMkEntries() []android.AndroidMkEntries {
@@ -345,7 +356,7 @@
// Install our runtime into expected location for packaging
installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
for _, lib := range r.ravenwoodLibgroupProperties.Libs {
- libModule := ctx.GetDirectDepWithTag(lib, ravenwoodLibContentTag)
+ libModule := ctx.GetDirectDepProxyWithTag(lib, ravenwoodLibContentTag)
if libModule == nil {
if ctx.Config().AllowMissingDependencies() {
ctx.AddMissingDependencies([]string{lib})
@@ -377,6 +388,10 @@
// Normal build should perform install steps
ctx.Phony(r.BaseModuleName(), android.PathForPhony(ctx, r.BaseModuleName()+"-install"))
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: r.TestSuites(),
+ })
}
// collectTransitiveJniDeps returns all JNI dependencies, including transitive
diff --git a/java/ravenwood_test.go b/java/ravenwood_test.go
index f7fe8e3..24a02bb 100644
--- a/java/ravenwood_test.go
+++ b/java/ravenwood_test.go
@@ -103,6 +103,7 @@
var installPathPrefix = "out/host/linux-x86/testcases"
func TestRavenwoodRuntime(t *testing.T) {
+ t.Parallel()
if runtime.GOOS != "linux" {
t.Skip("requires linux")
}
@@ -120,7 +121,7 @@
CheckModuleHasDependency(t, ctx.TestContext, "ravenwood-utils", "android_common", "framework-rules.ravenwood")
// Verify that we've emitted artifacts in expected location
- runtime := ctx.ModuleForTests("ravenwood-runtime", "android_common")
+ runtime := ctx.ModuleForTests(t, "ravenwood-runtime", "android_common")
runtime.Output(installPathPrefix + "/ravenwood-runtime/framework-minus-apex.ravenwood.jar")
runtime.Output(installPathPrefix + "/ravenwood-runtime/framework-services.ravenwood.jar")
runtime.Output(installPathPrefix + "/ravenwood-runtime/lib64/ravenwood-runtime-jni1.so")
@@ -128,11 +129,12 @@
runtime.Output(installPathPrefix + "/ravenwood-runtime/lib64/ravenwood-runtime-jni3.so")
runtime.Output(installPathPrefix + "/ravenwood-runtime/ravenwood-data/app1.apk")
runtime.Output(installPathPrefix + "/ravenwood-runtime/fonts/Font.ttf")
- utils := ctx.ModuleForTests("ravenwood-utils", "android_common")
+ utils := ctx.ModuleForTests(t, "ravenwood-utils", "android_common")
utils.Output(installPathPrefix + "/ravenwood-utils/framework-rules.ravenwood.jar")
}
func TestRavenwoodTest(t *testing.T) {
+ t.Parallel()
if runtime.GOOS != "linux" {
t.Skip("requires linux")
}
@@ -191,7 +193,7 @@
CheckModuleHasDependency(t, ctx.TestContext, "ravenwood-test", "android_common", "ravenwood-utils")
CheckModuleHasDependency(t, ctx.TestContext, "ravenwood-test", "android_common", "jni-lib")
- module := ctx.ModuleForTests("ravenwood-test", "android_common")
+ module := ctx.ModuleForTests(t, "ravenwood-test", "android_common")
classpath := module.Rule("javac").Args["classpath"]
// Verify that we're linking against test_current
@@ -212,7 +214,7 @@
module.Output(installPathPrefix + "/ravenwood-test/ravenwood-res-apks/ravenwood-res.apk")
module.Output(installPathPrefix + "/ravenwood-test/ravenwood-res-apks/ravenwood-inst-res.apk")
- module = ctx.ModuleForTests("ravenwood-test-empty", "android_common")
+ module = ctx.ModuleForTests(t, "ravenwood-test-empty", "android_common")
module.Output(installPathPrefix + "/ravenwood-test-empty/ravenwood.properties")
// ravenwood-runtime*.so are included in the runtime, so it shouldn't be emitted.
diff --git a/java/robolectric.go b/java/robolectric.go
index 29aa2f0..be369f7 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -29,6 +29,12 @@
RegisterRobolectricBuildComponents(android.InitRegistrationContext)
}
+type RobolectricRuntimesInfo struct {
+ Runtimes []android.InstallPath
+}
+
+var RobolectricRuntimesInfoProvider = blueprint.NewProvider[RobolectricRuntimesInfo]()
+
type roboRuntimeOnlyDependencyTag struct {
blueprint.BaseDependencyTag
}
@@ -138,39 +144,54 @@
r.forceOSType = ctx.Config().BuildOS
r.forceArchType = ctx.Config().BuildArch
+ var extraTestRunnerOptions []tradefed.Option
+ extraTestRunnerOptions = append(extraTestRunnerOptions, tradefed.Option{Name: "java-flags", Value: "-Drobolectric=true"})
+ if proptools.BoolDefault(r.robolectricProperties.Strict_mode, true) {
+ extraTestRunnerOptions = append(extraTestRunnerOptions, tradefed.Option{Name: "java-flags", Value: "-Drobolectric.strict.mode=true"})
+ }
+
+ var extraOptions []tradefed.Option
+ var javaHome = ctx.Config().Getenv("ANDROID_JAVA_HOME")
+ extraOptions = append(extraOptions, tradefed.Option{Name: "java-folder", Value: javaHome})
+
r.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
- TestConfigProp: r.testProperties.Test_config,
- TestConfigTemplateProp: r.testProperties.Test_config_template,
- TestSuites: r.testProperties.Test_suites,
- AutoGenConfig: r.testProperties.Auto_gen_config,
- DeviceTemplate: "${RobolectricTestConfigTemplate}",
- HostTemplate: "${RobolectricTestConfigTemplate}",
+ TestConfigProp: r.testProperties.Test_config,
+ TestConfigTemplateProp: r.testProperties.Test_config_template,
+ TestSuites: r.testProperties.Test_suites,
+ OptionsForAutogenerated: extraOptions,
+ TestRunnerOptions: extraTestRunnerOptions,
+ AutoGenConfig: r.testProperties.Auto_gen_config,
+ DeviceTemplate: "${RobolectricTestConfigTemplate}",
+ HostTemplate: "${RobolectricTestConfigTemplate}",
})
r.data = android.PathsForModuleSrc(ctx, r.testProperties.Data)
r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Device_common_data)...)
r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Device_first_data)...)
r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Device_first_prefer32_data)...)
+ r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Host_common_data)...)
var ok bool
- var instrumentedApp *AndroidApp
+ var instrumentedApp *JavaInfo
+ var appInfo *AppInfo
// TODO: this inserts paths to built files into the test, it should really be inserting the contents.
- instrumented := ctx.GetDirectDepsWithTag(instrumentationForTag)
+ instrumented := ctx.GetDirectDepsProxyWithTag(instrumentationForTag)
if len(instrumented) == 1 {
- instrumentedApp, ok = instrumented[0].(*AndroidApp)
+ appInfo, ok = android.OtherModuleProvider(ctx, instrumented[0], AppInfoProvider)
if !ok {
ctx.PropertyErrorf("instrumentation_for", "dependency must be an android_app")
}
+ instrumentedApp = android.OtherModuleProviderOrDefault(ctx, instrumented[0], JavaInfoProvider)
} else if !ctx.Config().AllowMissingDependencies() {
panic(fmt.Errorf("expected exactly 1 instrumented dependency, got %d", len(instrumented)))
}
var resourceApk android.Path
var manifest android.Path
- if instrumentedApp != nil {
- manifest = instrumentedApp.mergedManifestFile
- resourceApk = instrumentedApp.outputFile
+ if appInfo != nil {
+ manifest = appInfo.MergedManifestFile
+ resourceApk = instrumentedApp.OutputFile
}
roboTestConfigJar := android.PathForModuleOut(ctx, "robolectric_samedir", "samedir_config.jar")
@@ -178,7 +199,7 @@
extraCombinedJars := android.Paths{roboTestConfigJar}
- handleLibDeps := func(dep android.Module) {
+ handleLibDeps := func(dep android.ModuleProxy) {
if !android.InList(ctx.OtherModuleName(dep), config.FrameworkLibraries) {
if m, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok {
extraCombinedJars = append(extraCombinedJars, m.ImplementationAndResourcesJars...)
@@ -186,19 +207,19 @@
}
}
- for _, dep := range ctx.GetDirectDepsWithTag(libTag) {
+ for _, dep := range ctx.GetDirectDepsProxyWithTag(libTag) {
handleLibDeps(dep)
}
- for _, dep := range ctx.GetDirectDepsWithTag(sdkLibTag) {
+ for _, dep := range ctx.GetDirectDepsProxyWithTag(sdkLibTag) {
handleLibDeps(dep)
}
// handle the runtimeOnly tag for strict_mode
- for _, dep := range ctx.GetDirectDepsWithTag(roboRuntimeOnlyDepTag) {
+ for _, dep := range ctx.GetDirectDepsProxyWithTag(roboRuntimeOnlyDepTag) {
handleLibDeps(dep)
}
- if instrumentedApp != nil {
- extraCombinedJars = append(extraCombinedJars, instrumentedApp.implementationAndResourcesJar)
+ if appInfo != nil {
+ extraCombinedJars = append(extraCombinedJars, instrumentedApp.ImplementationAndResourcesJars...)
}
r.stem = proptools.StringDefault(r.overridableProperties.Stem, ctx.ModuleName())
@@ -226,8 +247,8 @@
installDeps = append(installDeps, installedResourceApk)
}
- runtimes := ctx.GetDirectDepWithTag("robolectric-android-all-prebuilts", roboRuntimesTag)
- for _, runtime := range runtimes.(*robolectricRuntimes).runtimes {
+ runtimes := ctx.GetDirectDepProxyWithTag("robolectric-android-all-prebuilts", roboRuntimesTag)
+ for _, runtime := range android.OtherModuleProviderOrDefault(ctx, runtimes, RobolectricRuntimesInfoProvider).Runtimes {
installDeps = append(installDeps, runtime)
}
@@ -246,6 +267,23 @@
setExtraJavaInfo(ctx, r, javaInfo)
android.SetProvider(ctx, JavaInfoProvider, javaInfo)
}
+
+ moduleInfoJSON := r.javaLibraryModuleInfoJSON(ctx)
+ if _, ok := r.testConfig.(android.WritablePath); ok {
+ moduleInfoJSON.AutoTestConfig = []string{"true"}
+ }
+ if r.testConfig != nil {
+ moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, r.testConfig.String())
+ }
+ if len(r.testProperties.Test_suites) > 0 {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, r.testProperties.Test_suites...)
+ } else {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
+ }
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: r.TestSuites(),
+ })
}
func generateSameDirRoboTestConfigJar(ctx android.ModuleContext, outputFile android.ModuleOutPath) {
@@ -361,7 +399,7 @@
}
if !ctx.Config().AlwaysUsePrebuiltSdks() && r.props.Lib != nil {
- runtimeFromSourceModule := ctx.GetDirectDepWithTag(String(r.props.Lib), libTag)
+ runtimeFromSourceModule := ctx.GetDirectDepProxyWithTag(String(r.props.Lib), libTag)
if runtimeFromSourceModule == nil {
if ctx.Config().AllowMissingDependencies() {
ctx.AddMissingDependencies([]string{String(r.props.Lib)})
@@ -379,6 +417,14 @@
installedRuntime := ctx.InstallFile(androidAllDir, runtimeName, runtimeFromSourceJar)
r.runtimes = append(r.runtimes, installedRuntime)
}
+
+ android.SetProvider(ctx, RobolectricRuntimesInfoProvider, RobolectricRuntimesInfo{
+ Runtimes: r.runtimes,
+ })
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: r.TestSuites(),
+ })
}
func (r *robolectricRuntimes) InstallInTestcases() bool { return true }
diff --git a/java/robolectric_test.go b/java/robolectric_test.go
index 78326ab..4bf224b 100644
--- a/java/robolectric_test.go
+++ b/java/robolectric_test.go
@@ -71,6 +71,7 @@
)
func TestRobolectricJniTest(t *testing.T) {
+ t.Parallel()
if runtime.GOOS != "linux" {
t.Skip("requires linux")
}
@@ -104,6 +105,6 @@
CheckModuleHasDependency(t, ctx.TestContext, "robo-test", "android_common", "jni-lib1")
// Check that the .so files make it into the output.
- module := ctx.ModuleForTests("robo-test", "android_common")
+ module := ctx.ModuleForTests(t, "robo-test", "android_common")
module.Output(installPathPrefix + "/robo-test/lib64/jni-lib1.so")
}
diff --git a/java/rro.go b/java/rro.go
index ab4fafa..f7f85f0 100644
--- a/java/rro.go
+++ b/java/rro.go
@@ -34,6 +34,15 @@
ctx.RegisterModuleType("override_runtime_resource_overlay", OverrideRuntimeResourceOverlayModuleFactory)
}
+type RuntimeResourceOverlayInfo struct {
+ OutputFile android.Path
+ Certificate Certificate
+ Theme string
+ OverriddenManifestPackageName string
+}
+
+var RuntimeResourceOverlayInfoProvider = blueprint.NewProvider[RuntimeResourceOverlayInfo]()
+
type RuntimeResourceOverlay struct {
android.ModuleBase
android.DefaultableModuleBase
@@ -139,6 +148,25 @@
r.aapt.hasNoCode = true
// Do not remove resources without default values nor dedupe resource configurations with the same value
aaptLinkFlags := []string{"--no-resource-deduping", "--no-resource-removal"}
+
+ // Add TARGET_AAPT_CHARACTERISTICS values to AAPT link flags if they exist and --product flags were not provided.
+ hasProduct := android.PrefixInList(r.aaptProperties.Aaptflags, "--product")
+ if !hasProduct && len(ctx.Config().ProductAAPTCharacteristics()) > 0 {
+ aaptLinkFlags = append(aaptLinkFlags, "--product", ctx.Config().ProductAAPTCharacteristics())
+ }
+
+ if !Bool(r.aaptProperties.Aapt_include_all_resources) {
+ // Product AAPT config
+ for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
+ aaptLinkFlags = append(aaptLinkFlags, "-c", aaptConfig)
+ }
+
+ // Product AAPT preferred config
+ if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
+ aaptLinkFlags = append(aaptLinkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
+ }
+ }
+
// Allow the override of "package name" and "overlay target package name"
manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
if overridden || r.overridableProperties.Package_name != nil {
@@ -187,6 +215,14 @@
android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
AconfigTextFiles: aconfigTextFilePaths,
})
+
+ android.SetProvider(ctx, RuntimeResourceOverlayInfoProvider, RuntimeResourceOverlayInfo{
+ OutputFile: r.OutputFile(),
+ Certificate: r.Certificate(),
+ Theme: r.Theme(),
+ })
+
+ buildComplianceMetadata(ctx)
}
func (r *RuntimeResourceOverlay) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
diff --git a/java/rro_test.go b/java/rro_test.go
index b946511..0ccc8e7 100644
--- a/java/rro_test.go
+++ b/java/rro_test.go
@@ -24,6 +24,7 @@
)
func TestRuntimeResourceOverlay(t *testing.T) {
+ t.Parallel()
fs := android.MockFS{
"baz/res/res/values/strings.xml": nil,
"bar/res/res/values/strings.xml": nil,
@@ -66,7 +67,7 @@
fs.AddToFixture(),
).RunTestWithBp(t, bp)
- m := result.ModuleForTests("foo", "android_common")
+ m := result.ModuleForTests(t, "foo", "android_common")
// Check AAPT2 link flags.
aapt2Flags := m.Output("package-res.apk").Args["flags"]
@@ -115,7 +116,7 @@
android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
// A themed module has a different device location
- m = result.ModuleForTests("foo_themed", "android_common")
+ m = result.ModuleForTests(t, "foo_themed", "android_common")
androidMkEntries = android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0]
path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay/faza")}
@@ -129,6 +130,7 @@
}
func TestRuntimeResourceOverlay_JavaDefaults(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.FixtureModifyConfig(android.SetKatiEnabledForTests),
@@ -153,7 +155,7 @@
//
// RRO module with defaults
//
- m := result.ModuleForTests("foo_with_defaults", "android_common")
+ m := result.ModuleForTests(t, "foo_with_defaults", "android_common")
// Check AAPT2 link flags.
aapt2Flags := strings.Split(m.Output("package-res.apk").Args["flags"], " ")
@@ -171,7 +173,7 @@
//
// RRO module without defaults
//
- m = result.ModuleForTests("foo_barebones", "android_common")
+ m = result.ModuleForTests(t, "foo_barebones", "android_common")
// Check AAPT2 link flags.
aapt2Flags = strings.Split(m.Output("package-res.apk").Args["flags"], " ")
@@ -233,7 +235,7 @@
},
}
for _, expected := range expectedVariants {
- variant := ctx.ModuleForTests("foo_overlay", expected.variantName)
+ variant := ctx.ModuleForTests(t, "foo_overlay", expected.variantName)
// Check the final apk name
variant.Output(expected.apkPath)
@@ -304,7 +306,7 @@
}
for _, testCase := range testCases {
ctx, _ := testJava(t, bp)
- mod := ctx.ModuleForTests(testCase.name, "android_common").Module().(*RuntimeResourceOverlay)
+ mod := ctx.ModuleForTests(t, testCase.name, "android_common").Module().(*RuntimeResourceOverlay)
android.AssertPathRelativeToTopEquals(t, "Install dir is not correct for "+testCase.name, testCase.expectedPath, mod.installDir)
}
}
@@ -339,7 +341,7 @@
}
`)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
// runtime_resource_overlay module depends on aconfig_declarations listed in flags_packages
android.AssertBoolEquals(t, "foo expected to depend on bar", true,
diff --git a/java/sdk.go b/java/sdk.go
index bb2aa8d..8510959 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -358,7 +358,7 @@
"api_fingerprint",
}
count := 0
- ctx.VisitAllModules(func(module android.Module) {
+ ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
name := ctx.ModuleName(module)
if android.InList(name, apiTxtFileModules) {
cmd.Inputs(android.OutputFilesForModule(ctx, module, ""))
@@ -381,6 +381,10 @@
}
rule.Build("api_fingerprint", "generate api_fingerprint.txt")
+
+ if ctx.Config().BuildOS == android.Linux {
+ ctx.DistForGoals([]string{"sdk", "droidcore"}, out)
+ }
}
func sdkMakeVars(ctx android.MakeVarsContext) {
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 155bea4..7944bb2 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -316,6 +316,15 @@
return name
}
+func (scopes apiScopes) matchingScopeFromSdkKind(kind android.SdkKind) *apiScope {
+ for _, scope := range scopes {
+ if scope.kind == kind {
+ return scope
+ }
+ }
+ return nil
+}
+
var (
scopeByName = make(map[string]*apiScope)
allScopeNames []string
@@ -480,6 +489,9 @@
// Extra libs used when compiling stubs for this scope.
Libs []string
+
+ // Name to override the api_surface that is passed down to droidstubs.
+ Api_surface *string
}
type sdkLibraryProperties struct {
@@ -690,9 +702,9 @@
paths.stubsHeaderPath = lib.HeaderJars
paths.stubsImplPath = lib.ImplementationJars
- libDep := dep.(UsesLibraryDependency)
- paths.stubsDexJarPath = libDep.DexJarBuildPath(ctx)
- paths.exportableStubsDexJarPath = libDep.DexJarBuildPath(ctx)
+ libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider)
+ paths.stubsDexJarPath = libDep.DexJarBuildPath
+ paths.exportableStubsDexJarPath = libDep.DexJarBuildPath
return nil
} else {
return fmt.Errorf("expected module that has JavaInfoProvider, e.g. java_library")
@@ -706,8 +718,8 @@
paths.stubsImplPath = lib.ImplementationJars
}
- libDep := dep.(UsesLibraryDependency)
- paths.stubsDexJarPath = libDep.DexJarBuildPath(ctx)
+ libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider)
+ paths.stubsDexJarPath = libDep.DexJarBuildPath
return nil
} else {
return fmt.Errorf("expected module that has JavaInfoProvider, e.g. java_library")
@@ -720,58 +732,67 @@
paths.stubsImplPath = lib.ImplementationJars
}
- libDep := dep.(UsesLibraryDependency)
- paths.exportableStubsDexJarPath = libDep.DexJarBuildPath(ctx)
+ libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider)
+ paths.exportableStubsDexJarPath = libDep.DexJarBuildPath
return nil
} else {
return fmt.Errorf("expected module that has JavaInfoProvider, e.g. java_library")
}
}
-func (paths *scopePaths) treatDepAsApiStubsProvider(dep android.Module, action func(provider ApiStubsProvider) error) error {
- if apiStubsProvider, ok := dep.(ApiStubsProvider); ok {
- err := action(apiStubsProvider)
+func (paths *scopePaths) treatDepAsApiStubsProvider(ctx android.ModuleContext, dep android.Module,
+ action func(*DroidStubsInfo, *StubsSrcInfo) error) error {
+ apiStubsProvider, ok := android.OtherModuleProvider(ctx, dep, DroidStubsInfoProvider)
+ if !ok {
+ return fmt.Errorf("expected module that provides DroidStubsInfo, e.g. droidstubs")
+ }
+
+ apiStubsSrcProvider, ok := android.OtherModuleProvider(ctx, dep, StubsSrcInfoProvider)
+ if !ok {
+ return fmt.Errorf("expected module that provides StubsSrcInfo, e.g. droidstubs")
+ }
+ return action(&apiStubsProvider, &apiStubsSrcProvider)
+}
+
+func (paths *scopePaths) treatDepAsApiStubsSrcProvider(
+ ctx android.ModuleContext, dep android.Module, action func(provider *StubsSrcInfo) error) error {
+ if apiStubsProvider, ok := android.OtherModuleProvider(ctx, dep, StubsSrcInfoProvider); ok {
+ err := action(&apiStubsProvider)
if err != nil {
return err
}
return nil
} else {
- return fmt.Errorf("expected module that implements ExportableApiStubsSrcProvider, e.g. droidstubs")
+ return fmt.Errorf("expected module that provides DroidStubsInfo, e.g. droidstubs")
}
}
-func (paths *scopePaths) treatDepAsApiStubsSrcProvider(dep android.Module, action func(provider ApiStubsSrcProvider) error) error {
- if apiStubsProvider, ok := dep.(ApiStubsSrcProvider); ok {
- err := action(apiStubsProvider)
- if err != nil {
- return err
- }
- return nil
- } else {
- return fmt.Errorf("expected module that implements ApiStubsSrcProvider, e.g. droidstubs")
+func (paths *scopePaths) extractApiInfoFromApiStubsProvider(provider *DroidStubsInfo, stubsType StubsType) error {
+ var currentApiFilePathErr, removedApiFilePathErr error
+ info, err := getStubsInfoForType(provider, stubsType)
+ if err != nil {
+ return err
}
-}
-
-func (paths *scopePaths) extractApiInfoFromApiStubsProvider(provider ApiStubsProvider, stubsType StubsType) error {
- var annotationsZip, currentApiFilePath, removedApiFilePath android.Path
- annotationsZip, annotationsZipErr := provider.AnnotationsZip(stubsType)
- currentApiFilePath, currentApiFilePathErr := provider.ApiFilePath(stubsType)
- removedApiFilePath, removedApiFilePathErr := provider.RemovedApiFilePath(stubsType)
-
- combinedError := errors.Join(annotationsZipErr, currentApiFilePathErr, removedApiFilePathErr)
+ if info.ApiFile == nil {
+ currentApiFilePathErr = fmt.Errorf("expected module that provides ApiFile")
+ }
+ if info.RemovedApiFile == nil {
+ removedApiFilePathErr = fmt.Errorf("expected module that provides RemovedApiFile")
+ }
+ combinedError := errors.Join(currentApiFilePathErr, removedApiFilePathErr)
if combinedError == nil {
- paths.annotationsZip = android.OptionalPathForPath(annotationsZip)
- paths.currentApiFilePath = android.OptionalPathForPath(currentApiFilePath)
- paths.removedApiFilePath = android.OptionalPathForPath(removedApiFilePath)
+ paths.annotationsZip = android.OptionalPathForPath(info.AnnotationsZip)
+ paths.currentApiFilePath = android.OptionalPathForPath(info.ApiFile)
+ paths.removedApiFilePath = android.OptionalPathForPath(info.RemovedApiFile)
}
return combinedError
}
-func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider ApiStubsSrcProvider, stubsType StubsType) error {
- stubsSrcJar, err := provider.StubsSrcJar(stubsType)
+func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider *StubsSrcInfo, stubsType StubsType) error {
+ path, err := getStubsSrcInfoForType(provider, stubsType)
if err == nil {
- paths.stubsSrcJar = android.OptionalPathForPath(stubsSrcJar)
+ paths.stubsSrcJar = android.OptionalPathForPath(path)
}
return err
}
@@ -781,7 +802,7 @@
if ctx.Config().ReleaseHiddenApiExportableStubs() {
stubsType = Exportable
}
- return paths.treatDepAsApiStubsSrcProvider(dep, func(provider ApiStubsSrcProvider) error {
+ return paths.treatDepAsApiStubsSrcProvider(ctx, dep, func(provider *StubsSrcInfo) error {
return paths.extractStubsSourceInfoFromApiStubsProviders(provider, stubsType)
})
}
@@ -791,17 +812,17 @@
if ctx.Config().ReleaseHiddenApiExportableStubs() {
stubsType = Exportable
}
- return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) error {
- extractApiInfoErr := paths.extractApiInfoFromApiStubsProvider(provider, stubsType)
- extractStubsSourceInfoErr := paths.extractStubsSourceInfoFromApiStubsProviders(provider, stubsType)
+ return paths.treatDepAsApiStubsProvider(ctx, dep, func(apiStubsProvider *DroidStubsInfo, apiStubsSrcProvider *StubsSrcInfo) error {
+ extractApiInfoErr := paths.extractApiInfoFromApiStubsProvider(apiStubsProvider, stubsType)
+ extractStubsSourceInfoErr := paths.extractStubsSourceInfoFromApiStubsProviders(apiStubsSrcProvider, stubsType)
return errors.Join(extractApiInfoErr, extractStubsSourceInfoErr)
})
}
-func extractOutputPaths(dep android.Module) (android.Paths, error) {
+func extractOutputPaths(ctx android.ModuleContext, dep android.Module) (android.Paths, error) {
var paths android.Paths
- if sourceFileProducer, ok := dep.(android.SourceFileProducer); ok {
- paths = sourceFileProducer.Srcs()
+ if sourceFileProducer, ok := android.OtherModuleProvider(ctx, dep, android.SourceFilesInfoProvider); ok {
+ paths = sourceFileProducer.Srcs
return paths, nil
} else {
return nil, fmt.Errorf("module %q does not produce source files", dep)
@@ -809,17 +830,47 @@
}
func (paths *scopePaths) extractLatestApiPath(ctx android.ModuleContext, dep android.Module) error {
- outputPaths, err := extractOutputPaths(dep)
+ outputPaths, err := extractOutputPaths(ctx, dep)
paths.latestApiPaths = outputPaths
return err
}
func (paths *scopePaths) extractLatestRemovedApiPath(ctx android.ModuleContext, dep android.Module) error {
- outputPaths, err := extractOutputPaths(dep)
+ outputPaths, err := extractOutputPaths(ctx, dep)
paths.latestRemovedApiPaths = outputPaths
return err
}
+func getStubsInfoForType(info *DroidStubsInfo, stubsType StubsType) (ret *StubsInfo, err error) {
+ switch stubsType {
+ case Everything:
+ ret, err = &info.EverythingStubsInfo, nil
+ case Exportable:
+ ret, err = &info.ExportableStubsInfo, nil
+ default:
+ ret, err = nil, fmt.Errorf("stubs info not supported for the stub type %s", stubsType.String())
+ }
+ if ret == nil && err == nil {
+ err = fmt.Errorf("stubs info is null for the stub type %s", stubsType.String())
+ }
+ return ret, err
+}
+
+func getStubsSrcInfoForType(info *StubsSrcInfo, stubsType StubsType) (ret android.Path, err error) {
+ switch stubsType {
+ case Everything:
+ ret, err = info.EverythingStubsSrcJar, nil
+ case Exportable:
+ ret, err = info.ExportableStubsSrcJar, nil
+ default:
+ ret, err = nil, fmt.Errorf("stubs src info not supported for the stub type %s", stubsType.String())
+ }
+ if ret == nil && err == nil {
+ err = fmt.Errorf("stubs src info is null for the stub type %s", stubsType.String())
+ }
+ return ret, err
+}
+
type commonToSdkLibraryAndImportProperties struct {
// Specifies whether this module can be used as an Android shared library; defaults
// to true.
@@ -880,6 +931,8 @@
RootLibraryName() string
}
+var _ android.ApexModule = (*SdkLibrary)(nil)
+
func (m *SdkLibrary) RootLibraryName() string {
return m.BaseModuleName()
}
@@ -908,9 +961,9 @@
// This is non-empty only when api_only is false.
implLibraryHeaderJars android.Paths
- // The reference to the implementation library created by the source module.
- // Is nil if the source module does not exist.
- implLibraryModule *Library
+ // The reference to the JavaInfo provided by implementation library created by
+ // the source module. Is nil if the source module does not exist.
+ implLibraryInfo *JavaInfo
}
func (c *commonToSdkLibraryAndImport) initCommon(module commonSdkLibraryAndImportModule) {
@@ -964,10 +1017,6 @@
removedApiFilePaths[kind] = removedApiFilePath
}
- javaInfo := &JavaInfo{}
- setExtraJavaInfo(ctx, ctx.Module(), javaInfo)
- android.SetProvider(ctx, JavaInfoProvider, javaInfo)
-
return SdkLibraryInfo{
EverythingStubDexJarPaths: everythingStubPaths,
ExportableStubDexJarPaths: exportableStubPaths,
@@ -1174,6 +1223,8 @@
// Whether if this can be used as a shared library.
SharedLibrary bool
+
+ Prebuilt bool
}
var SdkLibraryInfoProvider = blueprint.NewProvider[SdkLibraryInfo]()
@@ -1204,7 +1255,8 @@
commonToSdkLibraryAndImport
- builtInstalledForApex []dexpreopterInstall
+ apexSystemServerDexpreoptInstalls []DexpreopterInstall
+ apexSystemServerDexJars android.Paths
}
func (module *SdkLibrary) generateTestAndSystemScopesByDefault() bool {
@@ -1215,16 +1267,16 @@
// To satisfy the UsesLibraryDependency interface
func (module *SdkLibrary) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
- if module.implLibraryModule != nil {
- return module.implLibraryModule.DexJarBuildPath(ctx)
+ if module.implLibraryInfo != nil {
+ return module.implLibraryInfo.DexJarFile
}
return makeUnsetDexJarPath()
}
// To satisfy the UsesLibraryDependency interface
func (module *SdkLibrary) DexJarInstallPath() android.Path {
- if module.implLibraryModule != nil {
- return module.implLibraryModule.DexJarInstallPath()
+ if module.implLibraryInfo != nil {
+ return module.implLibraryInfo.InstallFile
}
return nil
}
@@ -1411,11 +1463,11 @@
// Collate the components exported by this module. All scope specific modules are exported but
// the impl and xml component modules are not.
exportedComponents := map[string]struct{}{}
-
+ var implLib android.ModuleProxy
// Record the paths to the header jars of the library (stubs and impl).
// When this java_sdk_library is depended upon from others via "libs" property,
// the recorded paths will be returned depending on the link type of the caller.
- ctx.VisitDirectDeps(func(to android.Module) {
+ ctx.VisitDirectDepsProxy(func(to android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(to)
// Extract information from any of the scope specific dependencies.
@@ -1435,7 +1487,8 @@
if tag == implLibraryTag {
if dep, ok := android.OtherModuleProvider(ctx, to, JavaInfoProvider); ok {
module.implLibraryHeaderJars = append(module.implLibraryHeaderJars, dep.HeaderJars...)
- module.implLibraryModule = to.(*Library)
+ module.implLibraryInfo = dep
+ implLib = to
}
}
})
@@ -1446,39 +1499,40 @@
module.hideApexVariantFromMake = true
}
- if module.implLibraryModule != nil {
+ if module.implLibraryInfo != nil {
if ctx.Device() {
- module.classesJarPaths = android.Paths{module.implLibraryModule.implementationJarFile}
- module.bootDexJarPath = module.implLibraryModule.bootDexJarPath
- module.uncompressDexState = module.implLibraryModule.uncompressDexState
- module.active = module.implLibraryModule.active
+ module.classesJarPaths = module.implLibraryInfo.ImplementationJars
+ module.bootDexJarPath = module.implLibraryInfo.BootDexJarPath
+ module.uncompressDexState = module.implLibraryInfo.UncompressDexState
+ module.active = module.implLibraryInfo.Active
}
- module.outputFile = module.implLibraryModule.outputFile
- module.dexJarFile = makeDexJarPathFromPath(module.implLibraryModule.dexJarFile.Path())
- module.headerJarFile = module.implLibraryModule.headerJarFile
- module.implementationAndResourcesJar = module.implLibraryModule.implementationAndResourcesJar
- module.builtInstalledForApex = module.implLibraryModule.builtInstalledForApex
- module.dexpreopter.configPath = module.implLibraryModule.dexpreopter.configPath
- module.dexpreopter.outputProfilePathOnHost = module.implLibraryModule.dexpreopter.outputProfilePathOnHost
+ module.outputFile = module.implLibraryInfo.OutputFile
+ module.dexJarFile = makeDexJarPathFromPath(module.implLibraryInfo.DexJarFile.Path())
+ module.headerJarFile = module.implLibraryInfo.HeaderJars[0]
+ module.implementationAndResourcesJar = module.implLibraryInfo.ImplementationAndResourcesJars[0]
+ module.apexSystemServerDexpreoptInstalls = module.implLibraryInfo.DexpreopterInfo.ApexSystemServerDexpreoptInstalls
+ module.apexSystemServerDexJars = module.implLibraryInfo.DexpreopterInfo.ApexSystemServerDexJars
+ module.dexpreopter.configPath = module.implLibraryInfo.ConfigPath
+ module.dexpreopter.outputProfilePathOnHost = module.implLibraryInfo.DexpreopterInfo.OutputProfilePathOnHost
// Properties required for Library.AndroidMkEntries
- module.logtagsSrcs = module.implLibraryModule.logtagsSrcs
- module.dexpreopter.builtInstalled = module.implLibraryModule.dexpreopter.builtInstalled
- module.jacocoReportClassesFile = module.implLibraryModule.jacocoReportClassesFile
- module.dexer.proguardDictionary = module.implLibraryModule.dexer.proguardDictionary
- module.dexer.proguardUsageZip = module.implLibraryModule.dexer.proguardUsageZip
- module.linter.reports = module.implLibraryModule.linter.reports
+ module.logtagsSrcs = module.implLibraryInfo.LogtagsSrcs
+ module.dexpreopter.builtInstalled = module.implLibraryInfo.BuiltInstalled
+ module.jacocoReportClassesFile = module.implLibraryInfo.JacocoReportClassesFile
+ module.dexer.proguardDictionary = module.implLibraryInfo.ProguardDictionary
+ module.dexer.proguardUsageZip = module.implLibraryInfo.ProguardUsageZip
+ module.linter.reports = module.implLibraryInfo.LinterReports
- if lintInfo, ok := android.OtherModuleProvider(ctx, module.implLibraryModule, LintProvider); ok {
+ if lintInfo, ok := android.OtherModuleProvider(ctx, implLib, LintProvider); ok {
android.SetProvider(ctx, LintProvider, lintInfo)
}
if !module.Host() {
- module.hostdexInstallFile = module.implLibraryModule.hostdexInstallFile
+ module.hostdexInstallFile = module.implLibraryInfo.HostdexInstallFile
}
- if installFilesInfo, ok := android.OtherModuleProvider(ctx, module.implLibraryModule, android.InstallFilesProvider); ok {
+ if installFilesInfo, ok := android.OtherModuleProvider(ctx, implLib, android.InstallFilesProvider); ok {
if installFilesInfo.CheckbuildTarget != nil {
ctx.CheckbuildFile(installFilesInfo.CheckbuildTarget)
}
@@ -1521,17 +1575,37 @@
}
}
- if module.requiresRuntimeImplementationLibrary() && module.implLibraryModule != nil {
+ if module.requiresRuntimeImplementationLibrary() && module.implLibraryInfo != nil {
generatingLibs = append(generatingLibs, module.implLibraryModuleName())
- setOutputFiles(ctx, module.implLibraryModule.Module)
+ setOutputFilesFromJavaInfo(ctx, module.implLibraryInfo)
}
+ javaInfo := &JavaInfo{}
+ setExtraJavaInfo(ctx, ctx.Module(), javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+
sdkLibInfo.GeneratingLibs = generatingLibs
+ sdkLibInfo.Prebuilt = false
android.SetProvider(ctx, SdkLibraryInfoProvider, sdkLibInfo)
}
-func (module *SdkLibrary) BuiltInstalledForApex() []dexpreopterInstall {
- return module.builtInstalledForApex
+func setOutputFilesFromJavaInfo(ctx android.ModuleContext, info *JavaInfo) {
+ ctx.SetOutputFiles(append(android.PathsIfNonNil(info.OutputFile), info.ExtraOutputFiles...), "")
+ ctx.SetOutputFiles(android.PathsIfNonNil(info.OutputFile), android.DefaultDistTag)
+ ctx.SetOutputFiles(info.ImplementationAndResourcesJars, ".jar")
+ ctx.SetOutputFiles(info.HeaderJars, ".hjar")
+ if info.ProguardDictionary.Valid() {
+ ctx.SetOutputFiles(android.Paths{info.ProguardDictionary.Path()}, ".proguard_map")
+ }
+ ctx.SetOutputFiles(info.GeneratedSrcjars, ".generated_srcjars")
+}
+
+func (module *SdkLibrary) ApexSystemServerDexpreoptInstalls() []DexpreopterInstall {
+ return module.apexSystemServerDexpreoptInstalls
+}
+
+func (module *SdkLibrary) ApexSystemServerDexJars() android.Paths {
+ return module.apexSystemServerDexJars
}
func (module *SdkLibrary) AndroidMkEntries() []android.AndroidMkEntries {
@@ -1639,14 +1713,22 @@
}
// Implements android.ApexModule
-func (module *SdkLibrary) OutgoingDepIsInSameApex(depTag blueprint.DependencyTag) bool {
- if depTag == xmlPermissionsFileTag {
+func (m *SdkLibrary) GetDepInSameApexChecker() android.DepInSameApexChecker {
+ return SdkLibraryDepInSameApexChecker{}
+}
+
+type SdkLibraryDepInSameApexChecker struct {
+ android.BaseDepInSameApexChecker
+}
+
+func (m SdkLibraryDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
+ if tag == xmlPermissionsFileTag {
return true
}
- if depTag == implLibraryTag {
+ if tag == implLibraryTag {
return true
}
- return module.Library.OutgoingDepIsInSameApex(depTag)
+ return depIsInSameApex(tag)
}
// Implements android.ApexModule
@@ -1903,10 +1985,6 @@
commonToSdkLibraryAndImport
- // The reference to the xml permissions module created by the source module.
- // Is nil if the source module does not exist.
- xmlPermissionsFileModule *sdkLibraryXml
-
// Build path to the dex implementation jar obtained from the prebuilt_apex, if any.
dexJarFile OptionalDexJarPath
dexJarFileErr error
@@ -2061,8 +2139,16 @@
var _ android.ApexModule = (*SdkLibraryImport)(nil)
// Implements android.ApexModule
-func (module *SdkLibraryImport) OutgoingDepIsInSameApex(depTag blueprint.DependencyTag) bool {
- if depTag == xmlPermissionsFileTag {
+func (m *SdkLibraryImport) GetDepInSameApexChecker() android.DepInSameApexChecker {
+ return SdkLibraryImportDepIsInSameApexChecker{}
+}
+
+type SdkLibraryImportDepIsInSameApexChecker struct {
+ android.BaseDepInSameApexChecker
+}
+
+func (m SdkLibraryImportDepIsInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
+ if tag == xmlPermissionsFileTag {
return true
}
@@ -2072,13 +2158,10 @@
}
// Implements android.ApexModule
-func (module *SdkLibraryImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
- sdkVersion android.ApiLevel) error {
- // we don't check prebuilt modules for sdk_version
- return nil
+func (m *SdkLibraryImport) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
+ return android.MinApiLevel
}
-// Implements android.ApexModule
func (module *SdkLibraryImport) UniqueApexVariations() bool {
return module.uniqueApexVariations()
}
@@ -2095,7 +2178,7 @@
module.installFile = android.PathForModuleInstall(ctx, "framework", module.Stem()+".jar")
// Record the paths to the prebuilt stubs library and stubs source.
- ctx.VisitDirectDeps(func(to android.Module) {
+ ctx.VisitDirectDepsProxy(func(to android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(to)
// Extract information from any of the scope specific dependencies.
@@ -2107,17 +2190,11 @@
// is determined by the nature of the dependency which is determined by the tag.
scopeTag.extractDepInfo(ctx, to, scopePaths)
} else if tag == implLibraryTag {
- if implLibrary, ok := to.(*Library); ok {
- module.implLibraryModule = implLibrary
+ if implInfo, ok := android.OtherModuleProvider(ctx, to, JavaInfoProvider); ok {
+ module.implLibraryInfo = implInfo
} else {
ctx.ModuleErrorf("implementation library must be of type *java.Library but was %T", to)
}
- } else if tag == xmlPermissionsFileTag {
- if xmlPermissionsFileModule, ok := to.(*sdkLibraryXml); ok {
- module.xmlPermissionsFileModule = xmlPermissionsFileModule
- } else {
- ctx.ModuleErrorf("xml permissions file module must be of type *sdkLibraryXml but was %T", to)
- }
}
})
sdkLibInfo := module.generateCommonBuildActions(ctx)
@@ -2157,12 +2234,17 @@
}
module.setOutputFiles(ctx)
- if module.implLibraryModule != nil {
+ if module.implLibraryInfo != nil {
generatingLibs = append(generatingLibs, module.implLibraryModuleName())
- setOutputFiles(ctx, module.implLibraryModule.Module)
+ setOutputFilesFromJavaInfo(ctx, module.implLibraryInfo)
}
+ javaInfo := &JavaInfo{}
+ setExtraJavaInfo(ctx, ctx.Module(), javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+
sdkLibInfo.GeneratingLibs = generatingLibs
+ sdkLibInfo.Prebuilt = true
android.SetProvider(ctx, SdkLibraryInfoProvider, sdkLibInfo)
}
@@ -2178,10 +2260,10 @@
if module.dexJarFile.IsSet() {
return module.dexJarFile
}
- if module.implLibraryModule == nil {
+ if module.implLibraryInfo == nil {
return makeUnsetDexJarPath()
} else {
- return module.implLibraryModule.DexJarBuildPath(ctx)
+ return module.implLibraryInfo.DexJarFile
}
}
@@ -2197,10 +2279,10 @@
// to satisfy apex.javaDependency interface
func (module *SdkLibraryImport) JacocoReportClassesFile() android.Path {
- if module.implLibraryModule == nil {
+ if module.implLibraryInfo == nil {
return nil
} else {
- return module.implLibraryModule.JacocoReportClassesFile()
+ return module.implLibraryInfo.JacocoReportClassesFile
}
}
@@ -2213,19 +2295,19 @@
// to satisfy java.ApexDependency interface
func (module *SdkLibraryImport) HeaderJars() android.Paths {
- if module.implLibraryModule == nil {
+ if module.implLibraryInfo == nil {
return nil
} else {
- return module.implLibraryModule.HeaderJars()
+ return module.implLibraryInfo.HeaderJars
}
}
// to satisfy java.ApexDependency interface
func (module *SdkLibraryImport) ImplementationAndResourcesJars() android.Paths {
- if module.implLibraryModule == nil {
+ if module.implLibraryInfo == nil {
return nil
} else {
- return module.implLibraryModule.ImplementationAndResourcesJars()
+ return module.implLibraryInfo.ImplementationAndResourcesJars
}
}
@@ -2390,8 +2472,7 @@
s.Min_device_sdk = sdk.commonSdkLibraryProperties.Min_device_sdk
s.Max_device_sdk = sdk.commonSdkLibraryProperties.Max_device_sdk
- implLibrary := sdk.implLibraryModule
- if implLibrary != nil && implLibrary.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided {
+ if sdk.implLibraryInfo != nil && sdk.implLibraryInfo.ProfileGuided {
s.DexPreoptProfileGuided = proptools.BoolPtr(true)
}
}
diff --git a/java/sdk_library_internal.go b/java/sdk_library_internal.go
index ec9c160..f5feabe 100644
--- a/java/sdk_library_internal.go
+++ b/java/sdk_library_internal.go
@@ -174,6 +174,20 @@
mctx.CreateModule(LibraryFactory, properties...)
}
+// getApiSurfaceForScope returns the api surface name to use for the apiScope. If one is specified
+// in the corresponding ApiScopeProperties.Api_surface property that is used, otherwise the name of
+// the apiScope is used.
+func (module *SdkLibrary) getApiSurfaceForScope(apiScope *apiScope) *string {
+ scopeProperties := module.scopeToProperties[apiScope]
+
+ apiSurface := scopeProperties.Api_surface
+ if apiSurface == nil {
+ apiSurface = &apiScope.name
+ }
+
+ return apiSurface
+}
+
// Creates the [Droidstubs] module with ".stubs.source.<[apiScope.name]>" that creates stubs
// source files from the given full source files and also updates and checks the API
// specification files (i.e. "*-current.txt", "*-removed.txt" files).
@@ -227,7 +241,7 @@
props.Srcs = append(props.Srcs, module.properties.Srcs...)
props.Srcs = append(props.Srcs, module.sdkLibraryProperties.Api_srcs...)
props.Sdk_version = module.deviceProperties.Sdk_version
- props.Api_surface = &apiScope.name
+ props.Api_surface = module.getApiSurfaceForScope(apiScope)
props.System_modules = module.deviceProperties.System_modules
props.Installable = proptools.BoolPtr(false)
// A droiddoc module has only one Libs property and doesn't distinguish between
@@ -793,10 +807,8 @@
var _ android.ApexModule = (*sdkLibraryXml)(nil)
// Implements android.ApexModule
-func (module *sdkLibraryXml) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
- sdkVersion android.ApiLevel) error {
- // sdkLibraryXml doesn't need to be checked separately because java_sdk_library is checked
- return nil
+func (m *sdkLibraryXml) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
+ return android.MinApiLevel
}
// File path to the runtime implementation library
@@ -924,6 +936,8 @@
ctx.PackageFile(module.installDirPath, libName+".xml", module.outputFilePath)
ctx.SetOutputFiles(android.OutputPaths{module.outputFilePath}.Paths(), "")
+
+ etc.SetCommonPrebuiltEtcInfo(ctx, module)
}
func (module *sdkLibraryXml) AndroidMkEntries() []android.AndroidMkEntries {
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 6031d72..431bbac 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -25,6 +25,7 @@
)
func TestJavaSdkLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -114,19 +115,19 @@
`)
// check the existence of the internal modules
- foo := result.ModuleForTests("foo", "android_common")
- result.ModuleForTests(apiScopePublic.stubsLibraryModuleName("foo"), "android_common")
- result.ModuleForTests(apiScopeSystem.stubsLibraryModuleName("foo"), "android_common")
- result.ModuleForTests(apiScopeTest.stubsLibraryModuleName("foo"), "android_common")
- result.ModuleForTests(apiScopePublic.stubsSourceModuleName("foo"), "android_common")
- result.ModuleForTests(apiScopeSystem.stubsSourceModuleName("foo"), "android_common")
- result.ModuleForTests(apiScopeTest.stubsSourceModuleName("foo"), "android_common")
- result.ModuleForTests(apiScopePublic.stubsSourceModuleName("foo")+".api.contribution", "")
- result.ModuleForTests(apiScopePublic.apiLibraryModuleName("foo"), "android_common")
- result.ModuleForTests("foo"+sdkXmlFileSuffix, "android_common")
- result.ModuleForTests("foo.api.public.28", "")
- result.ModuleForTests("foo.api.system.28", "")
- result.ModuleForTests("foo.api.test.28", "")
+ foo := result.ModuleForTests(t, "foo", "android_common")
+ result.ModuleForTests(t, apiScopePublic.stubsLibraryModuleName("foo"), "android_common")
+ result.ModuleForTests(t, apiScopeSystem.stubsLibraryModuleName("foo"), "android_common")
+ result.ModuleForTests(t, apiScopeTest.stubsLibraryModuleName("foo"), "android_common")
+ result.ModuleForTests(t, apiScopePublic.stubsSourceModuleName("foo"), "android_common")
+ result.ModuleForTests(t, apiScopeSystem.stubsSourceModuleName("foo"), "android_common")
+ result.ModuleForTests(t, apiScopeTest.stubsSourceModuleName("foo"), "android_common")
+ result.ModuleForTests(t, apiScopePublic.stubsSourceModuleName("foo")+".api.contribution", "")
+ result.ModuleForTests(t, apiScopePublic.apiLibraryModuleName("foo"), "android_common")
+ result.ModuleForTests(t, "foo"+sdkXmlFileSuffix, "android_common")
+ result.ModuleForTests(t, "foo.api.public.28", "")
+ result.ModuleForTests(t, "foo.api.system.28", "")
+ result.ModuleForTests(t, "foo.api.test.28", "")
exportedComponentsInfo, _ := android.OtherModuleProvider(result, foo.Module(), android.ExportedComponentsInfoProvider)
expectedFooExportedComponents := []string{
@@ -146,28 +147,28 @@
}
android.AssertArrayString(t, "foo exported components", expectedFooExportedComponents, exportedComponentsInfo.Components)
- bazJavac := result.ModuleForTests("baz", "android_common").Rule("javac")
+ bazJavac := result.ModuleForTests(t, "baz", "android_common").Rule("javac")
// tests if baz is actually linked to the stubs lib
- android.AssertStringDoesContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.stubs.system.jar")
+ android.AssertStringDoesContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.stubs.system.from-text.jar")
// ... and not to the impl lib
android.AssertStringDoesNotContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.jar")
// test if baz is not linked to the system variant of foo
android.AssertStringDoesNotContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.stubs.jar")
- bazTestJavac := result.ModuleForTests("baz-test", "android_common").Rule("javac")
+ bazTestJavac := result.ModuleForTests(t, "baz-test", "android_common").Rule("javac")
// tests if baz-test is actually linked to the test stubs lib
- android.AssertStringDoesContain(t, "baz-test javac classpath", bazTestJavac.Args["classpath"], "foo.stubs.test.jar")
+ android.AssertStringDoesContain(t, "baz-test javac classpath", bazTestJavac.Args["classpath"], "foo.stubs.test.from-text.jar")
- baz29Javac := result.ModuleForTests("baz-29", "android_common").Rule("javac")
+ baz29Javac := result.ModuleForTests(t, "baz-29", "android_common").Rule("javac")
// tests if baz-29 is actually linked to the system 29 stubs lib
- android.AssertStringDoesContain(t, "baz-29 javac classpath", baz29Javac.Args["classpath"], "prebuilts/sdk/sdk_system_29_foo/android_common/combined/sdk_system_29_foo.jar")
+ android.AssertStringDoesContain(t, "baz-29 javac classpath", baz29Javac.Args["classpath"], "prebuilts/sdk/sdk_system_29_foo/android_common/local-combined/sdk_system_29_foo.jar")
- bazModule30Javac := result.ModuleForTests("baz-module-30", "android_common").Rule("javac")
+ bazModule30Javac := result.ModuleForTests(t, "baz-module-30", "android_common").Rule("javac")
// tests if "baz-module-30" is actually linked to the module 30 stubs lib
- android.AssertStringDoesContain(t, "baz-module-30 javac classpath", bazModule30Javac.Args["classpath"], "prebuilts/sdk/sdk_module-lib_30_foo/android_common/combined/sdk_module-lib_30_foo.jar")
+ android.AssertStringDoesContain(t, "baz-module-30 javac classpath", bazModule30Javac.Args["classpath"], "prebuilts/sdk/sdk_module-lib_30_foo/android_common/local-combined/sdk_module-lib_30_foo.jar")
// test if baz has exported SDK lib names foo and bar to qux
- qux := result.ModuleForTests("qux", "android_common")
+ qux := result.ModuleForTests(t, "qux", "android_common")
if quxLib, ok := qux.Module().(*Library); ok {
requiredSdkLibs, optionalSdkLibs := quxLib.ClassLoaderContexts().UsesLibs()
android.AssertDeepEquals(t, "qux exports (required)", []string{"fred", "quuz", "foo", "bar"}, requiredSdkLibs)
@@ -175,18 +176,19 @@
}
// test if quuz have created the api_contribution module
- result.ModuleForTests(apiScopePublic.stubsSourceModuleName("quuz")+".api.contribution", "")
+ result.ModuleForTests(t, apiScopePublic.stubsSourceModuleName("quuz")+".api.contribution", "")
- fooImplDexJar := result.ModuleForTests("foo.impl", "android_common").Rule("d8")
+ fooImplDexJar := result.ModuleForTests(t, "foo.impl", "android_common").Rule("d8")
// tests if kotlinc generated files are NOT excluded from output of foo.impl.
android.AssertStringDoesNotContain(t, "foo.impl dex", fooImplDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/*.kotlin_module")
- barImplDexJar := result.ModuleForTests("bar.impl", "android_common").Rule("d8")
+ barImplDexJar := result.ModuleForTests(t, "bar.impl", "android_common").Rule("d8")
// tests if kotlinc generated files are excluded from output of bar.impl.
android.AssertStringDoesContain(t, "bar.impl dex", barImplDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/*.kotlin_module")
}
func TestJavaSdkLibrary_UpdatableLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -218,7 +220,7 @@
`)
// test that updatability attributes are passed on correctly
- fooUpdatable := result.ModuleForTests("fooUpdatable.xml", "android_common").Output("fooUpdatable.xml")
+ fooUpdatable := result.ModuleForTests(t, "fooUpdatable.xml", "android_common").Output("fooUpdatable.xml")
fooUpdatableContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooUpdatable)
android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `on-bootclasspath-since="U"`)
android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `on-bootclasspath-before="V"`)
@@ -227,7 +229,7 @@
// double check that updatability attributes are not written if they don't exist in the bp file
// the permissions file for the foo library defined above
- fooPermissions := result.ModuleForTests("foo.xml", "android_common").Output("foo.xml")
+ fooPermissions := result.ModuleForTests(t, "foo.xml", "android_common").Output("foo.xml")
fooPermissionsContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooPermissions)
android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `on-bootclasspath-since`)
android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `on-bootclasspath-before`)
@@ -236,6 +238,7 @@
}
func TestJavaSdkLibrary_UpdatableLibrary_Validation_ValidVersion(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -263,6 +266,7 @@
}
func TestJavaSdkLibrary_UpdatableLibrary_Validation_AtLeastTAttributes(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -292,6 +296,7 @@
}
func TestJavaSdkLibrary_UpdatableLibrary_Validation_MinAndMaxDeviceSdk(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -319,6 +324,7 @@
}
func TestJavaSdkLibrary_UpdatableLibrary_Validation_MinAndMaxDeviceSdkAndModuleMinSdk(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -347,6 +353,7 @@
}
func TestJavaSdkLibrary_UpdatableLibrary_usesNewTag(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -363,13 +370,14 @@
}
`)
// test that updatability attributes are passed on correctly
- fooUpdatable := result.ModuleForTests("foo.xml", "android_common").Output("foo.xml")
+ fooUpdatable := result.ModuleForTests(t, "foo.xml", "android_common").Output("foo.xml")
fooUpdatableContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooUpdatable)
android.AssertStringDoesContain(t, "foo.xml contents", fooUpdatableContents, `<apex-library`)
android.AssertStringDoesNotContain(t, "foo.xml contents", fooUpdatableContents, `<library`)
}
func TestJavaSdkLibrary_StubOrImplOnlyLibs(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -409,12 +417,12 @@
{lib: "stub-only-static-lib", in_stub_combined: true},
}
verify := func(sdklib, dep string, cp, combined bool) {
- sdklibCp := result.ModuleForTests(sdklib, "android_common").Rule("javac").Args["classpath"]
+ sdklibCp := result.ModuleForTests(t, sdklib, "android_common").Rule("javac").Args["classpath"]
expected := cp || combined // Every combined jar is also on the classpath.
android.AssertStringContainsEquals(t, "bad classpath for "+sdklib, sdklibCp, "/"+dep+".jar", expected)
- combineJarInputs := result.ModuleForTests(sdklib, "android_common").Rule("combineJar").Inputs.Strings()
- depPath := filepath.Join("out", "soong", ".intermediates", dep, "android_common", "turbine-combined", dep+".jar")
+ combineJarInputs := result.ModuleForTests(t, sdklib, "android_common").Rule("combineJar").Inputs.Strings()
+ depPath := filepath.Join("out", "soong", ".intermediates", dep, "android_common", "turbine", dep+".jar")
android.AssertStringListContainsEquals(t, "bad combined inputs for "+sdklib, combineJarInputs, depPath, combined)
}
for _, expectation := range expectations {
@@ -426,6 +434,7 @@
}
func TestJavaSdkLibrary_DoNotAccessImplWhenItIsNotBuilt(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -448,13 +457,14 @@
`)
// The bar library should depend on the stubs jar.
- barLibrary := result.ModuleForTests("bar", "android_common").Rule("javac")
- if expected, actual := `^-classpath .*:out/soong/[^:]*/turbine-combined/foo\.stubs\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
+ barLibrary := result.ModuleForTests(t, "bar", "android_common").Rule("javac")
+ if expected, actual := `^-classpath .*:out/soong/[^:]*/foo\.stubs\.from-text/foo\.stubs\.from-text\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
t.Errorf("expected %q, found %#q", expected, actual)
}
}
func TestJavaSdkLibrary_AccessOutputFiles(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -478,6 +488,7 @@
}
func TestJavaSdkLibrary_AccessOutputFiles_NoAnnotations(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -503,6 +514,7 @@
}
func TestJavaSdkLibrary_AccessOutputFiles_MissingScope(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -527,6 +539,7 @@
}
func TestJavaSdkLibrary_Deps(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -557,6 +570,7 @@
}
func TestJavaSdkLibraryImport_AccessOutputFiles(t *testing.T) {
+ t.Parallel()
prepareForJavaTest.RunTestWithBp(t, `
java_sdk_library_import {
name: "foo",
@@ -582,6 +596,7 @@
}
func TestJavaSdkLibraryImport_AccessOutputFiles_Invalid(t *testing.T) {
+ t.Parallel()
bp := `
java_sdk_library_import {
name: "foo",
@@ -592,6 +607,7 @@
`
t.Run("stubs.source", func(t *testing.T) {
+ t.Parallel()
prepareForJavaTest.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo" is not a SourceFileProducer or having valid output file for tag ".public.stubs.source"`)).
RunTestWithBp(t, bp+`
@@ -607,6 +623,7 @@
})
t.Run("api.txt", func(t *testing.T) {
+ t.Parallel()
prepareForJavaTest.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo" is not a SourceFileProducer or having valid output file for tag ".public.api.txt"`)).
RunTestWithBp(t, bp+`
@@ -621,6 +638,7 @@
})
t.Run("removed-api.txt", func(t *testing.T) {
+ t.Parallel()
prepareForJavaTest.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo" is not a SourceFileProducer or having valid output file for tag ".public.removed-api.txt"`)).
RunTestWithBp(t, bp+`
@@ -636,6 +654,7 @@
}
func TestJavaSdkLibrary_InvalidScopes(t *testing.T) {
+ t.Parallel()
prepareForJavaTest.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo": enabled api scope "system" depends on disabled scope "public"`)).
RunTestWithBp(t, `
@@ -656,6 +675,7 @@
}
func TestJavaSdkLibrary_SdkVersion_ForScope(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -674,6 +694,7 @@
}
func TestJavaSdkLibrary_ModuleLib(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -694,6 +715,7 @@
}
func TestJavaSdkLibrary_SystemServer(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -714,6 +736,7 @@
}
func TestJavaSdkLibrary_SystemServer_AccessToStubScopeLibs(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -768,13 +791,13 @@
stubsPath := func(name string, scope *apiScope) string {
name = scope.stubsLibraryModuleName(name)
- return fmt.Sprintf("out/soong/.intermediates/%[1]s/android_common/turbine-combined/%[1]s.jar", name)
+ return fmt.Sprintf("out/soong/.intermediates/%[1]s.from-text/android_common/%[1]s.from-text/%[1]s.from-text.jar", name)
}
// The bar library should depend on the highest (where system server is highest and public is
// lowest) API scopes provided by each of the foo-* modules. The highest API scope provided by the
// foo-<x> module is <x>.
- barLibrary := result.ModuleForTests("bar", "android_common").Rule("javac")
+ barLibrary := result.ModuleForTests(t, "bar", "android_common").Rule("javac")
stubLibraries := []string{
stubsPath("foo-public", apiScopePublic),
stubsPath("foo-system", apiScopeSystem),
@@ -788,6 +811,7 @@
}
func TestJavaSdkLibraryImport(t *testing.T) {
+ t.Parallel()
result := prepareForJavaTest.RunTestWithBp(t, `
java_library {
name: "foo",
@@ -826,10 +850,10 @@
`)
for _, scope := range []string{"", ".system", ".test"} {
- fooModule := result.ModuleForTests("foo"+scope, "android_common")
+ fooModule := result.ModuleForTests(t, "foo"+scope, "android_common")
javac := fooModule.Rule("javac")
- sdklibStubsJar := result.ModuleForTests("sdklib.stubs"+scope, "android_common").Output("combined/sdklib.stubs" + scope + ".jar").Output
+ sdklibStubsJar := result.ModuleForTests(t, "sdklib.stubs"+scope, "android_common").Output("local-combined/sdklib.stubs" + scope + ".jar").Output
android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], sdklibStubsJar.String())
}
@@ -844,6 +868,7 @@
}
func TestJavaSdkLibraryImport_WithSource(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -968,25 +993,25 @@
CheckModuleDependencies(t, result.TestContext, "combined", "android_common", []string{
// Each use of :sdklib{...} adds a dependency onto prebuilt_sdklib.
`prebuilt_sdklib`,
- `prebuilt_sdklib`,
- `prebuilt_sdklib`,
`prebuilt_sdklib.stubs`,
`prebuilt_sdklib.stubs.source`,
})
// Make sure that dependencies on sdklib that resolve to one of the child libraries use the
// prebuilt library.
- public := result.ModuleForTests("public", "android_common")
+ public := result.ModuleForTests(t, "public", "android_common")
rule := public.Output("javac/public.jar")
inputs := rule.Implicits.Strings()
- expected := "out/soong/.intermediates/prebuilt_sdklib.stubs/android_common/combined/sdklib.stubs.jar"
+ expected := "out/soong/.intermediates/prebuilt_sdklib.stubs/android_common/local-combined/sdklib.stubs.jar"
if !android.InList(expected, inputs) {
t.Errorf("expected %q to contain %q", inputs, expected)
}
}
func TestJavaSdkLibraryImport_Preferred(t *testing.T) {
+ t.Parallel()
t.Run("prefer", func(t *testing.T) {
+ t.Parallel()
testJavaSdkLibraryImport_Preferred(t, "prefer: true,", android.NullFixturePreparer)
})
}
@@ -994,6 +1019,7 @@
// If a module is listed in `mainline_module_contributions, it should be used
// It will supersede any other source vs prebuilt selection mechanism like `prefer` attribute
func TestSdkLibraryImport_MetadataModuleSupersedesPreferred(t *testing.T) {
+ t.Parallel()
bp := `
apex_contributions {
name: "my_mainline_module_contributions",
@@ -1093,17 +1119,17 @@
).RunTestWithBp(t, bp)
// Make sure that rdeps get the correct source vs prebuilt based on mainline_module_contributions
- public := result.ModuleForTests("public", "android_common")
+ public := result.ModuleForTests(t, "public", "android_common")
rule := public.Output("javac/public.jar")
inputs := rule.Implicits.Strings()
expectedInputs := []string{
// source
- "out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs/android_common/turbine-combined/sdklib.prebuilt_preferred_using_legacy_flags.stubs.jar",
- "out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system/android_common/turbine-combined/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system.jar",
+ "out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs.from-text/android_common/sdklib.prebuilt_preferred_using_legacy_flags.stubs.from-text/sdklib.prebuilt_preferred_using_legacy_flags.stubs.from-text.jar",
+ "out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system.from-text/android_common/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system.from-text/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system.from-text.jar",
// prebuilt
- "out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs/android_common/combined/sdklib.source_preferred_using_legacy_flags.stubs.jar",
- "out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs.system/android_common/combined/sdklib.source_preferred_using_legacy_flags.stubs.system.jar",
+ "out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs/android_common/local-combined/sdklib.source_preferred_using_legacy_flags.stubs.jar",
+ "out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs.system/android_common/local-combined/sdklib.source_preferred_using_legacy_flags.stubs.system.jar",
}
for _, expected := range expectedInputs {
if !android.InList(expected, inputs) {
@@ -1113,6 +1139,7 @@
}
func TestJavaSdkLibraryDist(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaBuildComponents,
PrepareForTestWithJavaDefaultModules,
@@ -1179,7 +1206,8 @@
for _, tt := range testCases {
t.Run(tt.module, func(t *testing.T) {
- m := result.ModuleForTests(apiScopePublic.exportableStubsLibraryModuleName(tt.module), "android_common").Module().(*Library)
+ t.Parallel()
+ m := result.ModuleForTests(t, apiScopePublic.exportableStubsLibraryModuleName(tt.module), "android_common").Module().(*Library)
dists := m.Dists()
if len(dists) != 1 {
t.Fatalf("expected exactly 1 dist entry, got %d", len(dists))
@@ -1195,6 +1223,7 @@
}
func TestSdkLibrary_CheckMinSdkVersion(t *testing.T) {
+ t.Parallel()
preparer := android.GroupFixturePreparers(
PrepareForTestWithJavaBuildComponents,
PrepareForTestWithJavaDefaultModules,
@@ -1279,6 +1308,7 @@
}
func TestJavaSdkLibrary_StubOnlyLibs_PassedToDroidstubs(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -1300,12 +1330,13 @@
`)
// The foo.stubs.source should depend on bar-lib
- fooStubsSources := result.ModuleForTests("foo.stubs.source", "android_common").Module().(*Droidstubs)
+ fooStubsSources := result.ModuleForTests(t, "foo.stubs.source", "android_common").Module().(*Droidstubs)
eval := fooStubsSources.ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext))
android.AssertStringListContains(t, "foo stubs should depend on bar-lib", fooStubsSources.Javadoc.properties.Libs.GetOrDefault(eval, nil), "bar-lib")
}
func TestJavaSdkLibrary_Scope_Libs_PassedToDroidstubs(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -1327,12 +1358,13 @@
`)
// The foo.stubs.source should depend on bar-lib
- fooStubsSources := result.ModuleForTests("foo.stubs.source", "android_common").Module().(*Droidstubs)
+ fooStubsSources := result.ModuleForTests(t, "foo.stubs.source", "android_common").Module().(*Droidstubs)
eval := fooStubsSources.ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext))
android.AssertStringListContains(t, "foo stubs should depend on bar-lib", fooStubsSources.Javadoc.properties.Libs.GetOrDefault(eval, nil), "bar-lib")
}
func TestJavaSdkLibrary_ApiLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -1377,12 +1409,13 @@
}
for _, c := range testCases {
- m := result.ModuleForTests(c.scope.apiLibraryModuleName("foo"), "android_common").Module().(*ApiLibrary)
+ m := result.ModuleForTests(t, c.scope.apiLibraryModuleName("foo"), "android_common").Module().(*ApiLibrary)
android.AssertArrayString(t, "Module expected to contain api contributions", c.apiContributions, m.properties.Api_contributions)
}
}
func TestStaticDepStubLibrariesVisibility(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -1412,6 +1445,7 @@
}
func TestSdkLibraryDependency(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -1438,12 +1472,13 @@
}
`)
- barPermissions := result.ModuleForTests("bar.xml", "android_common").Output("bar.xml")
+ barPermissions := result.ModuleForTests(t, "bar.xml", "android_common").Output("bar.xml")
barContents := android.ContentFromFileRuleForTests(t, result.TestContext, barPermissions)
android.AssertStringDoesContain(t, "bar.xml java_sdk_xml command", barContents, `dependency="foo"`)
}
func TestSdkLibraryExportableStubsLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -1480,8 +1515,8 @@
exportableSourceStubsLibraryModuleName := apiScopePublic.exportableSourceStubsLibraryModuleName("foo")
// Check modules generation
- result.ModuleForTests(exportableStubsLibraryModuleName, "android_common")
- result.ModuleForTests(exportableSourceStubsLibraryModuleName, "android_common")
+ result.ModuleForTests(t, exportableStubsLibraryModuleName, "android_common")
+ result.ModuleForTests(t, exportableSourceStubsLibraryModuleName, "android_common")
// Check static lib dependency
android.AssertBoolEquals(t, "exportable top level stubs library module depends on the"+
@@ -1494,6 +1529,7 @@
// For java libraries depending on java_sdk_library(_import) via libs, assert that
// rdep gets stubs of source if source is listed in apex_contributions and prebuilt has prefer (legacy mechanism)
func TestStubResolutionOfJavaSdkLibraryInLibs(t *testing.T) {
+ t.Parallel()
bp := `
apex_contributions {
name: "my_mainline_module_contributions",
@@ -1539,14 +1575,16 @@
result := fixture.RunTestWithBp(t, bp)
// Make sure that rdeps get the correct source vs prebuilt based on mainline_module_contributions
- public := result.ModuleForTests("mymodule", "android_common")
+ public := result.ModuleForTests(t, "mymodule", "android_common")
rule := public.Output("javac/mymodule.jar")
inputs := rule.Implicits.Strings()
- android.AssertStringListContains(t, "Could not find the expected stub on classpath", inputs, "out/soong/.intermediates/sdklib.stubs/android_common/turbine-combined/sdklib.stubs.jar")
+ android.AssertStringListContains(t, "Could not find the expected stub on classpath", inputs,
+ "out/soong/.intermediates/sdklib.stubs.from-text/android_common/sdklib.stubs.from-text/sdklib.stubs.from-text.jar")
}
// test that rdep gets resolved to the correct version of a java_sdk_library (source or a specific prebuilt)
func TestMultipleSdkLibraryPrebuilts(t *testing.T) {
+ t.Parallel()
bp := `
apex_contributions {
name: "my_mainline_module_contributions",
@@ -1599,17 +1637,17 @@
{
desc: "Source library is selected using apex_contributions",
selectedDependencyName: "sdklib",
- expectedStubPath: "out/soong/.intermediates/sdklib.stubs/android_common/turbine-combined/sdklib.stubs.jar",
+ expectedStubPath: "out/soong/.intermediates/sdklib.stubs.from-text/android_common/sdklib.stubs.from-text/sdklib.stubs.from-text.jar",
},
{
desc: "Prebuilt library v1 is selected using apex_contributions",
selectedDependencyName: "prebuilt_sdklib.v1",
- expectedStubPath: "out/soong/.intermediates/prebuilt_sdklib.v1.stubs/android_common/combined/sdklib.stubs.jar",
+ expectedStubPath: "out/soong/.intermediates/prebuilt_sdklib.v1.stubs/android_common/local-combined/sdklib.stubs.jar",
},
{
desc: "Prebuilt library v2 is selected using apex_contributions",
selectedDependencyName: "prebuilt_sdklib.v2",
- expectedStubPath: "out/soong/.intermediates/prebuilt_sdklib.v2.stubs/android_common/combined/sdklib.stubs.jar",
+ expectedStubPath: "out/soong/.intermediates/prebuilt_sdklib.v2.stubs/android_common/local-combined/sdklib.stubs.jar",
},
}
@@ -1624,7 +1662,7 @@
result := fixture.RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName))
// Make sure that rdeps get the correct source vs prebuilt based on mainline_module_contributions
- public := result.ModuleForTests("mymodule", "android_common")
+ public := result.ModuleForTests(t, "mymodule", "android_common")
rule := public.Output("javac/mymodule.jar")
inputs := rule.Implicits.Strings()
android.AssertStringListContains(t, "Could not find the expected stub on classpath", inputs, tc.expectedStubPath)
@@ -1632,6 +1670,7 @@
}
func TestStubLinkType(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -1668,6 +1707,7 @@
}
func TestSdkLibDirectDependency(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -1732,6 +1772,7 @@
}
func TestSdkLibDirectDependencyWithPrebuiltSdk(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
diff --git a/java/sdk_test.go b/java/sdk_test.go
index 9bfe6a2..6386a00 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -53,6 +53,7 @@
}
func TestClasspath(t *testing.T) {
+ t.Parallel()
const frameworkAidl = "-I" + defaultJavaDir + "/framework/aidl"
var classpathTestcases = []classpathTestCase{
{
@@ -388,22 +389,18 @@
},
}
- t.Parallel()
t.Run("basic", func(t *testing.T) {
t.Parallel()
- testClasspathTestCases(t, classpathTestcases, false, false)
+ testClasspathTestCases(t, classpathTestcases, false)
})
t.Run("Always_use_prebuilt_sdks=true", func(t *testing.T) {
- testClasspathTestCases(t, classpathTestcases, true, false)
- })
-
- t.Run("UseTransitiveJarsInClasspath", func(t *testing.T) {
- testClasspathTestCases(t, classpathTestcases, false, true)
+ t.Parallel()
+ testClasspathTestCases(t, classpathTestcases, true)
})
}
-func testClasspathTestCases(t *testing.T, classpathTestcases []classpathTestCase, alwaysUsePrebuiltSdks, useTransitiveJarsInClasspath bool) {
+func testClasspathTestCases(t *testing.T, classpathTestcases []classpathTestCase, alwaysUsePrebuiltSdks bool) {
for _, testcase := range classpathTestcases {
if testcase.forAlwaysUsePrebuiltSdks != nil && *testcase.forAlwaysUsePrebuiltSdks != alwaysUsePrebuiltSdks {
continue
@@ -444,10 +441,8 @@
switch {
case e == `""`, strings.HasSuffix(e, ".jar"):
ret[i] = e
- case useTransitiveJarsInClasspath:
- ret[i] = filepath.Join("out", "soong", ".intermediates", defaultJavaDir, e, "android_common", "turbine", e+".jar")
default:
- ret[i] = filepath.Join("out", "soong", ".intermediates", defaultJavaDir, e, "android_common", "turbine-combined", e+".jar")
+ ret[i] = filepath.Join("out", "soong", ".intermediates", defaultJavaDir, e, "android_common", "turbine", e+".jar")
}
}
return ret
@@ -499,7 +494,7 @@
}
checkClasspath := func(t *testing.T, result *android.TestResult, isJava8 bool) {
- foo := result.ModuleForTests("foo", variant(result))
+ foo := result.ModuleForTests(t, "foo", variant(result))
javac := foo.Rule("javac")
var deps []string
@@ -542,9 +537,6 @@
variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
})
}
- if useTransitiveJarsInClasspath {
- preparer = PrepareForTestWithTransitiveClasspathEnabled
- }
fixtureFactory := android.GroupFixturePreparers(
prepareForJavaTest,
@@ -571,12 +563,13 @@
// Test with legacy javac -source 1.8 -target 1.8
t.Run("Java language level 8", func(t *testing.T) {
+ t.Parallel()
result := fixtureFactory.RunTestWithBp(t, bpJava8)
checkClasspath(t, result, true /* isJava8 */)
if testcase.host != android.Host {
- aidl := result.ModuleForTests("foo", variant(result)).Rule("aidl")
+ aidl := result.ModuleForTests(t, "foo", variant(result)).Rule("aidl")
android.AssertStringDoesContain(t, "aidl command", aidl.RuleParams.Command, testcase.aidl+" -I.")
}
@@ -584,12 +577,13 @@
// Test with default javac -source 9 -target 9
t.Run("Java language level 9", func(t *testing.T) {
+ t.Parallel()
result := fixtureFactory.RunTestWithBp(t, bp)
checkClasspath(t, result, false /* isJava8 */)
if testcase.host != android.Host {
- aidl := result.ModuleForTests("foo", variant(result)).Rule("aidl")
+ aidl := result.ModuleForTests(t, "foo", variant(result)).Rule("aidl")
android.AssertStringDoesContain(t, "aidl command", aidl.RuleParams.Command, testcase.aidl+" -I.")
}
@@ -602,6 +596,7 @@
// Test again with PLATFORM_VERSION_CODENAME=REL, javac -source 8 -target 8
t.Run("REL + Java language level 8", func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
fixtureFactory, prepareWithPlatformVersionRel).RunTestWithBp(t, bpJava8)
@@ -610,6 +605,7 @@
// Test again with PLATFORM_VERSION_CODENAME=REL, javac -source 9 -target 9
t.Run("REL + Java language level 9", func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
fixtureFactory, prepareWithPlatformVersionRel).RunTestWithBp(t, bp)
diff --git a/java/sdk_version_test.go b/java/sdk_version_test.go
index 88351d2..03d55f7 100644
--- a/java/sdk_version_test.go
+++ b/java/sdk_version_test.go
@@ -25,6 +25,7 @@
}
func TestSystemSdkFromVendor(t *testing.T) {
+ t.Parallel()
fixtures := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
@@ -57,7 +58,7 @@
vendor: true,
sdk_version: "system_current",
}`)
- fooModule := result.ModuleForTests("foo", "android_common")
+ fooModule := result.ModuleForTests(t, "foo", "android_common")
fooClasspath := fooModule.Rule("javac").Args["classpath"]
android.AssertStringDoesContain(t, "foo classpath", fooClasspath, "prebuilts/sdk/34/system/android.jar")
diff --git a/java/system_modules_test.go b/java/system_modules_test.go
index b05b0e4..99301bc 100644
--- a/java/system_modules_test.go
+++ b/java/system_modules_test.go
@@ -51,10 +51,11 @@
`)
func TestJavaSystemModules(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(prepareForJavaTest, addSourceSystemModules).RunTest(t)
// check the existence of the source module
- sourceSystemModules := result.ModuleForTests("system-modules", "android_common")
+ sourceSystemModules := result.ModuleForTests(t, "system-modules", "android_common")
sourceInputs := sourceSystemModules.Rule("jarsTosystemModules").Inputs
// The expected paths are the header jars from the source input modules.
@@ -78,10 +79,11 @@
`)
func TestJavaSystemModulesImport(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(prepareForJavaTest, addPrebuiltSystemModules).RunTest(t)
// check the existence of the renamed prebuilt module
- prebuiltSystemModules := result.ModuleForTests("system-modules", "android_common")
+ prebuiltSystemModules := result.ModuleForTests(t, "system-modules", "android_common")
prebuiltInputs := prebuiltSystemModules.Rule("jarsTosystemModules").Inputs
// The expected paths are the header jars from the renamed prebuilt input modules.
@@ -90,6 +92,7 @@
}
func TestJavaSystemModulesMixSourceAndPrebuilt(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
addSourceSystemModules,
@@ -97,7 +100,7 @@
).RunTest(t)
// check the existence of the source module
- sourceSystemModules := result.ModuleForTests("system-modules", "android_common")
+ sourceSystemModules := result.ModuleForTests(t, "system-modules", "android_common")
sourceInputs := sourceSystemModules.Rule("jarsTosystemModules").Inputs
// The expected paths are the header jars from the source input modules.
@@ -105,7 +108,7 @@
android.AssertArrayString(t, "source system modules inputs", expectedSourcePaths, sourceInputs.RelativeToTop().Strings())
// check the existence of the renamed prebuilt module
- prebuiltSystemModules := result.ModuleForTests("prebuilt_system-modules", "android_common")
+ prebuiltSystemModules := result.ModuleForTests(t, "prebuilt_system-modules", "android_common")
prebuiltInputs := prebuiltSystemModules.Rule("jarsTosystemModules").Inputs
// The expected paths are the header jars from the renamed prebuilt input modules.
@@ -114,6 +117,7 @@
}
func TestMultipleSystemModulesPrebuilts(t *testing.T) {
+ t.Parallel()
bp := `
// an rdep
java_library {
diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go
index 3176ad9..a60f6b8 100644
--- a/java/systemserver_classpath_fragment.go
+++ b/java/systemserver_classpath_fragment.go
@@ -58,6 +58,10 @@
return m
}
+func (m *platformSystemServerClasspathModule) UniqueApexVariations() bool {
+ return true
+}
+
func (p *platformSystemServerClasspathModule) AndroidMkEntries() (entries []android.AndroidMkEntries) {
return p.classpathFragmentBase().androidMkEntries()
}
@@ -91,8 +95,10 @@
properties systemServerClasspathFragmentProperties
}
-func (s *SystemServerClasspathModule) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
- return nil
+var _ android.ApexModule = (*SystemServerClasspathModule)(nil)
+
+func (m *SystemServerClasspathModule) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
+ return android.MinApiLevel
}
type systemServerClasspathFragmentProperties struct {
@@ -116,6 +122,10 @@
return m
}
+func (m *SystemServerClasspathModule) UniqueApexVariations() bool {
+ return true
+}
+
func (s *SystemServerClasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if len(s.properties.Contents.GetOrDefault(ctx, nil)) == 0 && len(s.properties.Standalone_contents.GetOrDefault(ctx, nil)) == 0 {
ctx.PropertyErrorf("contents", "Either contents or standalone_contents needs to be non-empty")
diff --git a/java/systemserver_classpath_fragment_test.go b/java/systemserver_classpath_fragment_test.go
index 2a1728b..704f5a4 100644
--- a/java/systemserver_classpath_fragment_test.go
+++ b/java/systemserver_classpath_fragment_test.go
@@ -25,6 +25,7 @@
)
func TestPlatformSystemServerClasspathVariant(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForTestWithSystemServerClasspath,
android.FixtureWithRootAndroidBp(`
@@ -39,6 +40,7 @@
}
func TestPlatformSystemServerClasspath_ClasspathFragmentPaths(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForTestWithSystemServerClasspath,
android.FixtureWithRootAndroidBp(`
@@ -54,6 +56,7 @@
}
func TestPlatformSystemServerClasspathModule_AndroidMkEntries(t *testing.T) {
+ t.Parallel()
preparer := android.GroupFixturePreparers(
prepareForTestWithSystemServerClasspath,
android.FixtureWithRootAndroidBp(`
@@ -97,6 +100,7 @@
}
func TestSystemServerClasspathFragmentWithoutContents(t *testing.T) {
+ t.Parallel()
prepareForTestWithSystemServerClasspath.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
`\QEither contents or standalone_contents needs to be non-empty\E`)).
diff --git a/java/testing.go b/java/testing.go
index 0ea4e64..3abbb84 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -18,7 +18,6 @@
"fmt"
"reflect"
"regexp"
- "sort"
"strings"
"testing"
@@ -378,7 +377,6 @@
RegisterAppBuildComponents(ctx)
RegisterAppImportBuildComponents(ctx)
RegisterAppSetBuildComponents(ctx)
- registerBootclasspathBuildComponents(ctx)
registerBootclasspathFragmentBuildComponents(ctx)
RegisterDexpreoptBootJarsComponents(ctx)
RegisterDocsBuildComponents(ctx)
@@ -607,19 +605,18 @@
func getModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string) []string {
t.Helper()
- module := ctx.ModuleForTests(name, variant).Module()
+ module := ctx.ModuleForTests(t, name, variant).Module()
deps := []string{}
ctx.VisitDirectDeps(module, func(m blueprint.Module) {
deps = append(deps, m.Name())
})
- sort.Strings(deps)
-
- return deps
+ return android.SortedUniqueStrings(deps)
}
// CheckModuleDependencies checks if the expected dependencies of the module are
// identical to the actual dependencies.
func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) {
+ t.Helper()
deps := getModuleDependencies(t, ctx, name, variant)
if actual := deps; !reflect.DeepEqual(expected, actual) {
@@ -639,7 +636,7 @@
// CheckModuleHasDependency returns true if the module depends on the expected dependency.
func CheckModuleHasDependencyWithTag(t *testing.T, ctx *android.TestContext, name, variant string, desiredTag blueprint.DependencyTag, expected string) bool {
- module := ctx.ModuleForTests(name, variant).Module()
+ module := ctx.ModuleForTests(t, name, variant).Module()
found := false
ctx.VisitDirectDepsWithTags(module, func(m blueprint.Module, tag blueprint.DependencyTag) {
if tag == desiredTag && m.Name() == expected {
@@ -654,7 +651,7 @@
func CheckPlatformBootclasspathModules(t *testing.T, result *android.TestResult, name string, expected []string) {
t.Helper()
platformBootclasspath := result.Module(name, "android_common").(*platformBootclasspathModule)
- pairs := ApexNamePairsFromModules(result.TestContext, platformBootclasspath.configuredModules)
+ pairs := apexNamePairsFromModules(result.TestContext, platformBootclasspath.configuredModules, platformBootclasspath.libraryToApex)
android.AssertDeepEquals(t, fmt.Sprintf("%s modules", "platform-bootclasspath"), expected, pairs)
}
@@ -669,23 +666,54 @@
android.AssertPathRelativeToTopEquals(t, "install filepath", installDir, info.ClasspathFragmentProtoInstallDir)
}
-// ApexNamePairsFromModules returns the apex:module pair for the supplied modules.
-func ApexNamePairsFromModules(ctx *android.TestContext, modules []android.Module) []string {
+// CheckPlatformBootclasspathDependencies checks the dependencies of the selected module against the expected list.
+//
+// The expected list must be a list of strings of the form "<apex>:<module>", where <apex> is the
+// name of the apex, or platform is it is not part of an apex and <module> is the module name.
+func CheckPlatformBootclasspathDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) {
+ t.Helper()
+ platformBootclasspath := ctx.ModuleForTests(t, name, variant).Module().(*platformBootclasspathModule)
+ modules := []android.Module{}
+ ctx.VisitDirectDeps(platformBootclasspath, func(m blueprint.Module) {
+ modules = append(modules, m.(android.Module))
+ })
+
+ pairs := apexNamePairsFromModules(ctx, modules, platformBootclasspath.libraryToApex)
+ android.AssertDeepEquals(t, "module dependencies", expected, pairs)
+}
+
+// apexNamePairsFromModules returns the apex:module pair for the supplied modules.
+func apexNamePairsFromModules(ctx *android.TestContext, modules []android.Module, modulesToApex map[android.Module]string) []string {
pairs := []string{}
for _, module := range modules {
- pairs = append(pairs, apexNamePairFromModule(ctx, module))
+ pairs = append(pairs, apexNamePairFromModule(ctx, module, modulesToApex))
}
return pairs
}
-func apexNamePairFromModule(ctx *android.TestContext, module android.Module) string {
+// ApexFragmentPairsFromModules returns the apex:fragment pair for the supplied fragments.
+func ApexFragmentPairsFromModules(ctx *android.TestContext, fragments []android.Module, apexNameToFragment map[string]android.Module) []string {
+ pairs := []string{}
+ for _, fragment := range fragments {
+ found := false
+ for apex, apexFragment := range apexNameToFragment {
+ if apexFragment == fragment {
+ pairs = append(pairs, apex+":"+ctx.ModuleName(fragment))
+ found = true
+ }
+ }
+ if !found {
+ pairs = append(pairs, "platform:"+ctx.ModuleName(fragment))
+ }
+ }
+ return pairs
+}
+
+func apexNamePairFromModule(ctx *android.TestContext, module android.Module, modulesToApex map[android.Module]string) string {
name := module.Name()
- var apex string
- apexInfo, _ := android.OtherModuleProvider(ctx, module, android.ApexInfoProvider)
- if apexInfo.IsForPlatform() {
+ apex := modulesToApex[module]
+ if apex == "" {
apex = "platform"
- } else {
- apex = apexInfo.InApexVariants[0]
}
return fmt.Sprintf("%s:%s", apex, name)
@@ -696,7 +724,7 @@
func CheckPlatformBootclasspathFragments(t *testing.T, result *android.TestResult, name string, expected []string) {
t.Helper()
platformBootclasspath := result.Module(name, "android_common").(*platformBootclasspathModule)
- pairs := ApexNamePairsFromModules(result.TestContext, platformBootclasspath.fragments)
+ pairs := ApexFragmentPairsFromModules(result.TestContext, platformBootclasspath.fragments, platformBootclasspath.apexNameToFragment)
android.AssertDeepEquals(t, fmt.Sprintf("%s fragments", "platform-bootclasspath"), expected, pairs)
}
@@ -719,7 +747,7 @@
// Check that the merged file create by platform_compat_config_singleton has the correct inputs.
func CheckMergedCompatConfigInputs(t *testing.T, result *android.TestResult, message string, expectedPaths ...string) {
- sourceGlobalCompatConfig := result.SingletonForTests("platform_compat_config_singleton")
+ sourceGlobalCompatConfig := result.SingletonForTests(t, "platform_compat_config_singleton")
allOutputs := sourceGlobalCompatConfig.AllOutputs()
android.AssertIntEquals(t, message+": output len", 1, len(allOutputs))
output := sourceGlobalCompatConfig.Output(allOutputs[0])
@@ -797,5 +825,3 @@
config.installDir = installDir
})
}
-
-var PrepareForTestWithTransitiveClasspathEnabled = android.PrepareForTestWithBuildFlag("RELEASE_USE_TRANSITIVE_JARS_IN_CLASSPATH", "true")
diff --git a/kernel/prebuilt_kernel_modules_test.go b/kernel/prebuilt_kernel_modules_test.go
index 7b81869..0fc2720 100644
--- a/kernel/prebuilt_kernel_modules_test.go
+++ b/kernel/prebuilt_kernel_modules_test.go
@@ -50,7 +50,7 @@
var actual []string
for _, ps := range android.OtherModuleProviderOrDefault(
- ctx, ctx.ModuleForTests("foo", "android_arm64_armv8-a").Module(), android.InstallFilesProvider).PackagingSpecs {
+ ctx, ctx.ModuleForTests(t, "foo", "android_arm64_armv8-a").Module(), android.InstallFilesProvider).PackagingSpecs {
actual = append(actual, ps.RelPathInPackage())
}
actual = android.SortedUniqueStrings(actual)
diff --git a/linkerconfig/linkerconfig.go b/linkerconfig/linkerconfig.go
index 4f1ef9d..43fe8aa 100644
--- a/linkerconfig/linkerconfig.go
+++ b/linkerconfig/linkerconfig.go
@@ -86,6 +86,8 @@
ctx.InstallFile(l.installDirPath, l.outputFilePath.Base(), l.outputFilePath)
ctx.SetOutputFiles(android.Paths{l.outputFilePath}, "")
+
+ etc.SetCommonPrebuiltEtcInfo(ctx, l)
}
func BuildLinkerConfig(
diff --git a/linkerconfig/linkerconfig_test.go b/linkerconfig/linkerconfig_test.go
index 939e4bb..9e08b19 100644
--- a/linkerconfig/linkerconfig_test.go
+++ b/linkerconfig/linkerconfig_test.go
@@ -46,7 +46,7 @@
"LOCAL_INSTALLED_MODULE_STEM": {"linker.config.pb"},
}
- p := result.ModuleForTests("linker-config-base", "android_arm64_armv8-a").Module().(*linkerConfig)
+ p := result.ModuleForTests(t, "linker-config-base", "android_arm64_armv8-a").Module().(*linkerConfig)
if p.outputFilePath.Base() != "linker.config.pb" {
t.Errorf("expected linker.config.pb, got %q", p.outputFilePath.Base())
@@ -79,7 +79,7 @@
expected := []string{"true"}
- p := result.ModuleForTests("linker-config-base", "android_arm64_armv8-a").Module().(*linkerConfig)
+ p := result.ModuleForTests(t, "linker-config-base", "android_arm64_armv8-a").Module().(*linkerConfig)
entries := android.AndroidMkEntriesForTest(t, result.TestContext, p)[0]
if value, ok := entries.EntryMap["LOCAL_UNINSTALLABLE_MODULE"]; ok {
if !reflect.DeepEqual(value, expected) {
diff --git a/phony/phony.go b/phony/phony.go
index 807b95b..4f61c45 100644
--- a/phony/phony.go
+++ b/phony/phony.go
@@ -38,9 +38,11 @@
type phony struct {
android.ModuleBase
+
requiredModuleNames []string
hostRequiredModuleNames []string
targetRequiredModuleNames []string
+ outputDeps android.Paths
}
func PhonyFactory() android.Module {
@@ -54,6 +56,14 @@
p.requiredModuleNames = ctx.RequiredModuleNames(ctx)
p.hostRequiredModuleNames = ctx.HostRequiredModuleNames()
p.targetRequiredModuleNames = ctx.TargetRequiredModuleNames()
+
+ ctx.VisitDirectDepsWithTag(android.RequiredDepTag, func(dep android.Module) {
+ if o, ok := android.OtherModuleProvider(ctx, dep, android.OutputFilesProvider); ok {
+ p.outputDeps = append(p.outputDeps, o.DefaultOutputFiles...)
+ }
+ })
+
+ ctx.Phony(p.Name(), p.outputDeps...)
}
func (p *phony) AndroidMk() android.AndroidMkData {
@@ -77,6 +87,10 @@
fmt.Fprintln(w, "LOCAL_TARGET_REQUIRED_MODULES :=",
strings.Join(p.targetRequiredModuleNames, " "))
}
+ if len(p.outputDeps) > 0 {
+ fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES :=",
+ strings.Join(p.outputDeps.Strings(), " "))
+ }
// AconfigUpdateAndroidMkData may have added elements to Extra. Process them here.
for _, extra := range data.Extra {
extra(w, nil)
diff --git a/provenance/provenance_singleton.go b/provenance/provenance_singleton.go
index c372db2..c1bc1c7 100644
--- a/provenance/provenance_singleton.go
+++ b/provenance/provenance_singleton.go
@@ -99,6 +99,7 @@
})
context.Phony("droidcore", android.PathForPhony(context, "provenance_metadata"))
+ context.DistForGoal("droidcore", p.mergedMetaDataFile)
}
func GenerateArtifactProvenanceMetaData(ctx android.ModuleContext, artifactPath android.Path, installedFile android.InstallPath) android.Path {
@@ -116,9 +117,3 @@
return artifactMetaDataFile
}
-
-func (p *provenanceInfoSingleton) MakeVars(ctx android.MakeVarsContext) {
- ctx.DistForGoal("droidcore", p.mergedMetaDataFile)
-}
-
-var _ android.SingletonMakeVarsProvider = (*provenanceInfoSingleton)(nil)
diff --git a/provenance/provenance_singleton_test.go b/provenance/provenance_singleton_test.go
index 0f1eae2..05f3474 100644
--- a/provenance/provenance_singleton_test.go
+++ b/provenance/provenance_singleton_test.go
@@ -28,9 +28,9 @@
PrepareForTestWithProvenanceSingleton,
android.PrepareForTestWithAndroidMk).RunTestWithBp(t, "")
- outputs := result.SingletonForTests("provenance_metadata_singleton").AllOutputs()
+ outputs := result.SingletonForTests(t, "provenance_metadata_singleton").AllOutputs()
for _, output := range outputs {
- testingBuildParam := result.SingletonForTests("provenance_metadata_singleton").Output(output)
+ testingBuildParam := result.SingletonForTests(t, "provenance_metadata_singleton").Output(output)
switch {
case strings.Contains(output, "soong/provenance_metadata.textproto"):
android.AssertStringEquals(t, "Invalid build rule", "android/soong/provenance.mergeProvenanceMetaData", testingBuildParam.Rule.String())
diff --git a/python/binary.go b/python/binary.go
index 5f60761..feac72a 100644
--- a/python/binary.go
+++ b/python/binary.go
@@ -22,8 +22,15 @@
"strings"
"android/soong/android"
+ "android/soong/cc"
+
+ "github.com/google/blueprint"
)
+type PythonBinaryInfo struct{}
+
+var PythonBinaryInfoProvider = blueprint.NewProvider[PythonBinaryInfo]()
+
func init() {
registerPythonBinaryComponents(android.InitRegistrationContext)
}
@@ -103,7 +110,16 @@
p.buildBinary(ctx)
p.installedDest = ctx.InstallFile(installDir(ctx, "bin", "", ""),
p.installSource.Base(), p.installSource)
+
+ android.SetProvider(ctx, PythonBinaryInfoProvider, PythonBinaryInfo{})
+
ctx.SetOutputFiles(android.Paths{p.installSource}, "")
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Class = []string{"EXECUTABLES"}
+ moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, p.androidMkSharedLibs...)
+ moduleInfoJSON.SharedLibs = append(moduleInfoJSON.SharedLibs, p.androidMkSharedLibs...)
+ moduleInfoJSON.SystemSharedLibs = []string{"none"}
}
func (p *PythonBinaryModule) buildBinary(ctx android.ModuleContext) {
@@ -116,13 +132,13 @@
var launcherPath android.OptionalPath
if embeddedLauncher {
- ctx.VisitDirectDepsWithTag(launcherTag, func(m android.Module) {
- if provider, ok := m.(IntermPathProvider); ok {
+ ctx.VisitDirectDepsProxyWithTag(launcherTag, func(m android.ModuleProxy) {
+ if provider, ok := android.OtherModuleProvider(ctx, m, cc.LinkableInfoProvider); ok {
if launcherPath.Valid() {
panic(fmt.Errorf("launcher path was found before: %q",
launcherPath))
}
- launcherPath = provider.IntermPathForModuleOut()
+ launcherPath = provider.OutputFile
}
})
}
@@ -134,13 +150,12 @@
}
srcsZips = append(srcsZips, depsSrcsZips...)
p.installSource = registerBuildActionForParFile(ctx, embeddedLauncher, launcherPath,
- p.getHostInterpreterName(ctx, p.properties.Actual_version),
- main, p.getStem(ctx), srcsZips)
+ "python3", main, p.getStem(ctx), srcsZips)
var sharedLibs []string
// if embedded launcher is enabled, we need to collect the shared library dependencies of the
// launcher
- for _, dep := range ctx.GetDirectDepsWithTag(launcherSharedLibTag) {
+ for _, dep := range ctx.GetDirectDepsProxyWithTag(launcherSharedLibTag) {
sharedLibs = append(sharedLibs, ctx.OtherModuleName(dep))
}
p.androidMkSharedLibs = sharedLibs
@@ -196,23 +211,6 @@
return BoolDefault(b.binaryProperties.Autorun, true)
}
-// get host interpreter name.
-func (p *PythonBinaryModule) getHostInterpreterName(ctx android.ModuleContext,
- actualVersion string) string {
- var interp string
- switch actualVersion {
- case pyVersion2:
- interp = "python2.7"
- case pyVersion3:
- interp = "python3"
- default:
- panic(fmt.Errorf("unknown Python actualVersion: %q for module: %q.",
- actualVersion, ctx.ModuleName()))
- }
-
- return interp
-}
-
// find main program path within runfiles tree.
func (p *PythonBinaryModule) getPyMainFile(ctx android.ModuleContext,
srcsPathMappings []pathMapping) string {
diff --git a/python/defaults.go b/python/defaults.go
index 3dc5bc4..b5ee2bc 100644
--- a/python/defaults.go
+++ b/python/defaults.go
@@ -18,10 +18,6 @@
"android/soong/android"
)
-func init() {
- android.RegisterModuleType("python_defaults", DefaultsFactory)
-}
-
type Defaults struct {
android.ModuleBase
android.DefaultsModuleBase
diff --git a/python/library.go b/python/library.go
index 7cdb80b..c197028 100644
--- a/python/library.go
+++ b/python/library.go
@@ -27,6 +27,7 @@
func registerPythonLibraryComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("python_library_host", PythonLibraryHostFactory)
ctx.RegisterModuleType("python_library", PythonLibraryFactory)
+ ctx.RegisterModuleType("python_defaults", DefaultsFactory)
}
func PythonLibraryHostFactory() android.Module {
diff --git a/python/python.go b/python/python.go
index 914b77e..f8f4165 100644
--- a/python/python.go
+++ b/python/python.go
@@ -22,24 +22,23 @@
"regexp"
"strings"
+ "android/soong/cc"
+
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
"android/soong/android"
)
-func init() {
- registerPythonMutators(android.InitRegistrationContext)
+type PythonLibraryInfo struct {
+ SrcsPathMappings []pathMapping
+ DataPathMappings []pathMapping
+ SrcsZip android.Path
+ PrecompiledSrcsZip android.Path
+ PkgPath string
}
-func registerPythonMutators(ctx android.RegistrationContext) {
- ctx.PreDepsMutators(RegisterPythonPreDepsMutators)
-}
-
-// Exported to support other packages using Python modules in tests.
-func RegisterPythonPreDepsMutators(ctx android.RegisterMutatorsContext) {
- ctx.Transition("python_version", &versionSplitTransitionMutator{})
-}
+var PythonLibraryInfoProvider = blueprint.NewProvider[PythonLibraryInfo]()
// the version-specific properties that apply to python modules.
type VersionProperties struct {
@@ -116,18 +115,14 @@
Py3 VersionProperties `android:"arch_variant"`
} `android:"arch_variant"`
- // the actual version each module uses after variations created.
- // this property name is hidden from users' perspectives, and soong will populate it during
- // runtime.
- Actual_version string `blueprint:"mutated"`
-
- // whether the module is required to be built with actual_version.
- // this is set by the python version mutator based on version-specific properties
+ // This enabled property is to accept the collapsed enabled property from the VersionProperties.
+ // It is unused now, as all builds should be python3.
Enabled *bool `blueprint:"mutated"`
- // whether the binary is required to be built with embedded launcher for this actual_version.
- // this is set by the python version mutator based on version-specific properties
- Embedded_launcher *bool `blueprint:"mutated"`
+ // whether the binary is required to be built with an embedded python interpreter, defaults to
+ // true. This allows taking the resulting binary outside of the build and running it on machines
+ // that don't have python installed or may have an older version of python.
+ Embedded_launcher *bool
}
// Used to store files of current module after expanding dependencies
@@ -173,16 +168,6 @@
}
}
-// interface implemented by Python modules to provide source and data mappings and zip to python
-// modules that depend on it
-type pythonDependency interface {
- getSrcsPathMappings() []pathMapping
- getDataPathMappings() []pathMapping
- getSrcsZip() android.Path
- getPrecompiledSrcsZip() android.Path
- getPkgPath() string
-}
-
// getSrcsPathMappings gets this module's path mapping of src source path : runfiles destination
func (p *PythonLibraryModule) getSrcsPathMappings() []pathMapping {
return p.srcsPathMappings
@@ -212,8 +197,6 @@
return &p.properties
}
-var _ pythonDependency = (*PythonLibraryModule)(nil)
-
func (p *PythonLibraryModule) init() android.Module {
p.AddProperties(&p.properties, &p.protoProperties, &p.sourceProperties)
android.InitAndroidArchModule(p, p.hod, p.multilib)
@@ -253,8 +236,6 @@
pathComponentRegexp = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_-]*$`)
pyExt = ".py"
protoExt = ".proto"
- pyVersion2 = "PY2"
- pyVersion3 = "PY3"
internalPath = "internal"
)
@@ -262,71 +243,6 @@
getBaseProperties() *BaseProperties
}
-type versionSplitTransitionMutator struct{}
-
-func (versionSplitTransitionMutator) Split(ctx android.BaseModuleContext) []string {
- if base, ok := ctx.Module().(basePropertiesProvider); ok {
- props := base.getBaseProperties()
- var variants []string
- // PY3 is first so that we alias the PY3 variant rather than PY2 if both
- // are available
- if proptools.BoolDefault(props.Version.Py3.Enabled, true) {
- variants = append(variants, pyVersion3)
- }
- if proptools.BoolDefault(props.Version.Py2.Enabled, false) {
- if ctx.ModuleName() != "py2-cmd" &&
- ctx.ModuleName() != "py2-stdlib" {
- ctx.PropertyErrorf("version.py2.enabled", "Python 2 is no longer supported, please convert to python 3.")
- }
- variants = append(variants, pyVersion2)
- }
- return variants
- }
- return []string{""}
-}
-
-func (versionSplitTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
- return ""
-}
-
-func (versionSplitTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
- if incomingVariation != "" {
- return incomingVariation
- }
- if base, ok := ctx.Module().(basePropertiesProvider); ok {
- props := base.getBaseProperties()
- if proptools.BoolDefault(props.Version.Py3.Enabled, true) {
- return pyVersion3
- } else {
- return pyVersion2
- }
- }
-
- return ""
-}
-
-func (versionSplitTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
- if variation == "" {
- return
- }
- if base, ok := ctx.Module().(basePropertiesProvider); ok {
- props := base.getBaseProperties()
- props.Actual_version = variation
-
- var versionProps *VersionProperties
- if variation == pyVersion3 {
- versionProps = &props.Version.Py3
- } else if variation == pyVersion2 {
- versionProps = &props.Version.Py2
- }
-
- err := proptools.AppendMatchingProperties([]interface{}{props}, versionProps, nil)
- if err != nil {
- panic(err)
- }
- }
-}
-
func anyHasExt(paths []string, ext string) bool {
for _, p := range paths {
if filepath.Ext(p) == ext {
@@ -346,19 +262,26 @@
// - if required, specifies launcher and adds launcher dependencies,
// - applies python version mutations to Python dependencies
func (p *PythonLibraryModule) DepsMutator(ctx android.BottomUpMutatorContext) {
- android.ProtoDeps(ctx, &p.protoProperties)
+ // Flatten the version.py3 props down into the main property struct. Leftover from when
+ // there was both python2 and 3 in the build, and properties could be different between them.
+ if base, ok := ctx.Module().(basePropertiesProvider); ok {
+ props := base.getBaseProperties()
- versionVariation := []blueprint.Variation{
- {"python_version", p.properties.Actual_version},
+ err := proptools.AppendMatchingProperties([]interface{}{props}, &props.Version.Py3, nil)
+ if err != nil {
+ panic(err)
+ }
}
+ android.ProtoDeps(ctx, &p.protoProperties)
+
// If sources contain a proto file, add dependency on libprotobuf-python
if p.anySrcHasExt(ctx, protoExt) && p.Name() != "libprotobuf-python" {
- ctx.AddVariationDependencies(versionVariation, pythonLibTag, "libprotobuf-python")
+ ctx.AddDependency(ctx.Module(), pythonLibTag, "libprotobuf-python")
}
// Add python library dependencies for this python version variation
- ctx.AddVariationDependencies(versionVariation, pythonLibTag, android.LastUniqueStrings(p.properties.Libs)...)
+ ctx.AddDependency(ctx.Module(), pythonLibTag, android.LastUniqueStrings(p.properties.Libs)...)
// Emulate the data property for java_data but with the arch variation overridden to "common"
// so that it can point to java modules.
@@ -395,55 +318,38 @@
launcherSharedLibDeps = append(launcherSharedLibDeps, "libc_musl")
}
- switch p.properties.Actual_version {
- case pyVersion2:
- stdLib = "py2-stdlib"
-
- launcherModule = "py2-launcher"
- if autorun {
- launcherModule = "py2-launcher-autorun"
- }
-
- launcherSharedLibDeps = append(launcherSharedLibDeps, "libc++")
- case pyVersion3:
- var prebuiltStdLib bool
- if targetForDeps.Os.Bionic() {
- prebuiltStdLib = false
- } else if ctx.Config().VendorConfig("cpython3").Bool("force_build_host") {
- prebuiltStdLib = false
- } else {
- prebuiltStdLib = true
- }
-
- if prebuiltStdLib {
- stdLib = "py3-stdlib-prebuilt"
- } else {
- stdLib = "py3-stdlib"
- }
-
- launcherModule = "py3-launcher"
- if autorun {
- launcherModule = "py3-launcher-autorun"
- }
- if ctx.Config().HostStaticBinaries() && targetForDeps.Os == android.LinuxMusl {
- launcherModule += "-static"
- }
- if ctx.Device() {
- launcherSharedLibDeps = append(launcherSharedLibDeps, "liblog")
- }
- default:
- panic(fmt.Errorf("unknown Python Actual_version: %q for module: %q.",
- p.properties.Actual_version, ctx.ModuleName()))
+ var prebuiltStdLib bool
+ if targetForDeps.Os.Bionic() {
+ prebuiltStdLib = false
+ } else if ctx.Config().VendorConfig("cpython3").Bool("force_build_host") {
+ prebuiltStdLib = false
+ } else {
+ prebuiltStdLib = true
}
+
+ if prebuiltStdLib {
+ stdLib = "py3-stdlib-prebuilt"
+ } else {
+ stdLib = "py3-stdlib"
+ }
+
+ launcherModule = "py3-launcher"
+ if autorun {
+ launcherModule = "py3-launcher-autorun"
+ }
+ if ctx.Config().HostStaticBinaries() && targetForDeps.Os == android.LinuxMusl {
+ launcherModule += "-static"
+ }
+ if ctx.Device() {
+ launcherSharedLibDeps = append(launcherSharedLibDeps, "liblog")
+ }
+
targetVariations := targetForDeps.Variations()
if ctx.ModuleName() != stdLib {
- stdLibVariations := make([]blueprint.Variation, 0, len(targetVariations)+1)
- stdLibVariations = append(stdLibVariations, blueprint.Variation{Mutator: "python_version", Variation: p.properties.Actual_version})
- stdLibVariations = append(stdLibVariations, targetVariations...)
// Using AddFarVariationDependencies for all of these because they can be for a different
// platform, like if the python module itself was being compiled for device, we may want
// the python interpreter built for host so that we can precompile python sources.
- ctx.AddFarVariationDependencies(stdLibVariations, stdLibTag, stdLib)
+ ctx.AddFarVariationDependencies(targetVariations, stdLibTag, stdLib)
}
ctx.AddFarVariationDependencies(targetVariations, launcherTag, launcherModule)
ctx.AddFarVariationDependencies(targetVariations, launcherSharedLibTag, launcherSharedLibDeps...)
@@ -451,6 +357,9 @@
// GenerateAndroidBuildActions performs build actions common to all Python modules
func (p *PythonLibraryModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ if proptools.BoolDefault(p.properties.Version.Py2.Enabled, false) {
+ ctx.PropertyErrorf("version.py2.enabled", "Python 2 is no longer supported, please convert to python 3.")
+ }
expandedSrcs := android.PathsForModuleSrcExcludes(ctx, p.properties.Srcs, p.properties.Exclude_srcs)
// Keep before any early returns.
android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
@@ -464,7 +373,7 @@
expandedData = append(expandedData, android.PathsForModuleSrc(ctx, p.properties.Device_first_data)...)
// Emulate the data property for java_data dependencies.
- for _, javaData := range ctx.GetDirectDepsWithTag(javaDataTag) {
+ for _, javaData := range ctx.GetDirectDepsProxyWithTag(javaDataTag) {
expandedData = append(expandedData, android.OutputFilesForModule(ctx, javaData, "")...)
}
@@ -491,7 +400,16 @@
// generate the zipfile of all source and data files
p.srcsZip = p.createSrcsZip(ctx, pkgPath)
- p.precompiledSrcsZip = p.precompileSrcs(ctx)
+ // TODO(b/388344853): precompilation temporarily disabled for python3.13 upgrade
+ p.precompiledSrcsZip = p.srcsZip //p.precompileSrcs(ctx)
+
+ android.SetProvider(ctx, PythonLibraryInfoProvider, PythonLibraryInfo{
+ SrcsPathMappings: p.getSrcsPathMappings(),
+ DataPathMappings: p.getDataPathMappings(),
+ SrcsZip: p.getSrcsZip(),
+ PkgPath: p.getPkgPath(),
+ PrecompiledSrcsZip: p.getPrecompiledSrcsZip(),
+ })
}
func isValidPythonPath(path string) error {
@@ -657,16 +575,16 @@
stdLib = p.srcsZip
stdLibPkg = p.getPkgPath()
} else {
- ctx.VisitDirectDepsWithTag(hostStdLibTag, func(module android.Module) {
- if dep, ok := module.(pythonDependency); ok {
- stdLib = dep.getPrecompiledSrcsZip()
- stdLibPkg = dep.getPkgPath()
+ ctx.VisitDirectDepsProxyWithTag(hostStdLibTag, func(module android.ModuleProxy) {
+ if dep, ok := android.OtherModuleProvider(ctx, module, PythonLibraryInfoProvider); ok {
+ stdLib = dep.PrecompiledSrcsZip
+ stdLibPkg = dep.PkgPath
}
})
}
- ctx.VisitDirectDepsWithTag(hostLauncherTag, func(module android.Module) {
- if dep, ok := module.(IntermPathProvider); ok {
- optionalLauncher := dep.IntermPathForModuleOut()
+ ctx.VisitDirectDepsProxyWithTag(hostLauncherTag, func(module android.ModuleProxy) {
+ if dep, ok := android.OtherModuleProvider(ctx, module, cc.LinkableInfoProvider); ok {
+ optionalLauncher := dep.OutputFile
if optionalLauncher.Valid() {
launcher = optionalLauncher.Path()
}
@@ -674,9 +592,9 @@
})
var launcherSharedLibs android.Paths
var ldLibraryPath []string
- ctx.VisitDirectDepsWithTag(hostlauncherSharedLibTag, func(module android.Module) {
- if dep, ok := module.(IntermPathProvider); ok {
- optionalPath := dep.IntermPathForModuleOut()
+ ctx.VisitDirectDepsProxyWithTag(hostlauncherSharedLibTag, func(module android.ModuleProxy) {
+ if dep, ok := android.OtherModuleProvider(ctx, module, cc.LinkableInfoProvider); ok {
+ optionalPath := dep.OutputFile
if optionalPath.Valid() {
launcherSharedLibs = append(launcherSharedLibs, optionalPath.Path())
ldLibraryPath = append(ldLibraryPath, filepath.Dir(optionalPath.Path().String()))
@@ -707,16 +625,6 @@
return out
}
-// isPythonLibModule returns whether the given module is a Python library PythonLibraryModule or not
-func isPythonLibModule(module blueprint.Module) bool {
- if _, ok := module.(*PythonLibraryModule); ok {
- if _, ok := module.(*PythonBinaryModule); !ok {
- return true
- }
- }
- return false
-}
-
// collectPathsFromTransitiveDeps checks for source/data files for duplicate paths
// for module and its transitive dependencies and collects list of data/source file
// zips for transitive dependencies.
@@ -737,7 +645,7 @@
var result android.Paths
// visit all its dependencies in depth first.
- ctx.WalkDeps(func(child, parent android.Module) bool {
+ ctx.WalkDepsProxy(func(child, _ android.ModuleProxy) bool {
// we only collect dependencies tagged as python library deps
if ctx.OtherModuleDependencyTag(child) != pythonLibTag {
return false
@@ -747,27 +655,29 @@
}
seen[child] = true
// Python modules only can depend on Python libraries.
- if !isPythonLibModule(child) {
+ dep, isLibrary := android.OtherModuleProvider(ctx, child, PythonLibraryInfoProvider)
+ _, isBinary := android.OtherModuleProvider(ctx, child, PythonBinaryInfoProvider)
+ if !isLibrary || isBinary {
ctx.PropertyErrorf("libs",
"the dependency %q of module %q is not Python library!",
ctx.OtherModuleName(child), ctx.ModuleName())
}
// collect source and data paths, checking that there are no duplicate output file conflicts
- if dep, ok := child.(pythonDependency); ok {
- srcs := dep.getSrcsPathMappings()
+ if isLibrary {
+ srcs := dep.SrcsPathMappings
for _, path := range srcs {
checkForDuplicateOutputPath(ctx, destToPySrcs,
path.dest, path.src.String(), ctx.ModuleName(), ctx.OtherModuleName(child))
}
- data := dep.getDataPathMappings()
+ data := dep.DataPathMappings
for _, path := range data {
checkForDuplicateOutputPath(ctx, destToPyData,
path.dest, path.src.String(), ctx.ModuleName(), ctx.OtherModuleName(child))
}
if precompiled {
- result = append(result, dep.getPrecompiledSrcsZip())
+ result = append(result, dep.PrecompiledSrcsZip)
} else {
- result = append(result, dep.getSrcsZip())
+ result = append(result, dep.SrcsZip)
}
}
return true
diff --git a/python/python_test.go b/python/python_test.go
index 6a6bd1d..5f971cd 100644
--- a/python/python_test.go
+++ b/python/python_test.go
@@ -36,10 +36,8 @@
}
var (
- buildNamePrefix = "soong_python_test"
- // We allow maching almost anything before the actual variant so that the os/arch variant
- // is matched.
- moduleVariantErrTemplate = `%s: module %q variant "[a-zA-Z0-9_]*%s": `
+ buildNamePrefix = "soong_python_test"
+ moduleVariantErrTemplate = `%s: module %q variant "[a-zA-Z0-9_]*": `
pkgPathErrTemplate = moduleVariantErrTemplate +
"pkg_path: %q must be a relative path contained in par file."
badIdentifierErrTemplate = moduleVariantErrTemplate +
@@ -48,9 +46,8 @@
"found two files to be placed at the same location within zip %q." +
" First file: in module %s at path %q." +
" Second file: in module %s at path %q."
- noSrcFileErr = moduleVariantErrTemplate + "doesn't have any source files!"
- badSrcFileExtErr = moduleVariantErrTemplate + "srcs: found non (.py|.proto) file: %q!"
- badDataFileExtErr = moduleVariantErrTemplate + "data: found (.py) file: %q!"
+ badSrcFileExtErr = moduleVariantErrTemplate + `srcs: found non \(.py\|.proto\) file: %q!`
+ badDataFileExtErr = moduleVariantErrTemplate + `data: found \(.py\) file: %q!`
bpFile = "Android.bp"
data = []struct {
@@ -61,20 +58,6 @@
expectedBinaries []pyModule
}{
{
- desc: "module without any src files",
- mockFiles: map[string][]byte{
- filepath.Join("dir", bpFile): []byte(
- `python_library_host {
- name: "lib1",
- }`,
- ),
- },
- errors: []string{
- fmt.Sprintf(noSrcFileErr,
- "dir/Android.bp:1:1", "lib1", "PY3"),
- },
- },
- {
desc: "module with bad src file ext",
mockFiles: map[string][]byte{
filepath.Join("dir", bpFile): []byte(
@@ -89,7 +72,7 @@
},
errors: []string{
fmt.Sprintf(badSrcFileExtErr,
- "dir/Android.bp:3:11", "lib1", "PY3", "dir/file1.exe"),
+ "dir/Android.bp:3:11", "lib1", "dir/file1.exe"),
},
},
{
@@ -111,7 +94,7 @@
},
errors: []string{
fmt.Sprintf(badDataFileExtErr,
- "dir/Android.bp:6:11", "lib1", "PY3", "dir/file2.py"),
+ "dir/Android.bp:6:11", "lib1", "dir/file2.py"),
},
},
{
@@ -146,9 +129,9 @@
},
errors: []string{
fmt.Sprintf(pkgPathErrTemplate,
- "dir/Android.bp:11:15", "lib2", "PY3", "a/c/../../../"),
+ "dir/Android.bp:11:15", "lib2", "a/c/../../../"),
fmt.Sprintf(pkgPathErrTemplate,
- "dir/Android.bp:19:15", "lib3", "PY3", "/a/c/../../"),
+ "dir/Android.bp:19:15", "lib3", "/a/c/../../"),
},
},
{
@@ -171,11 +154,11 @@
},
errors: []string{
fmt.Sprintf(badIdentifierErrTemplate, "dir/Android.bp:4:11",
- "lib1", "PY3", "a/b/c/-e/f/file1.py", "-e"),
+ "lib1", "a/b/c/-e/f/file1.py", "-e"),
fmt.Sprintf(badIdentifierErrTemplate, "dir/Android.bp:4:11",
- "lib1", "PY3", "a/b/c/.file1.py", ".file1"),
+ "lib1", "a/b/c/.file1.py", ".file1"),
fmt.Sprintf(badIdentifierErrTemplate, "dir/Android.bp:4:11",
- "lib1", "PY3", "a/b/c/123/file1.py", "123"),
+ "lib1", "a/b/c/123/file1.py", "123"),
},
},
{
@@ -219,115 +202,15 @@
},
errors: []string{
fmt.Sprintf(dupRunfileErrTemplate, "dir/Android.bp:20:6",
- "bin", "PY3", "a/b/c/file1.py", "bin", "dir/file1.py",
+ "bin", "a/b/c/file1.py", "bin", "dir/file1.py",
"lib1", "dir/c/file1.py"),
},
},
- {
- desc: "module for testing dependencies",
- mockFiles: map[string][]byte{
- filepath.Join("dir", bpFile): []byte(
- `python_defaults {
- name: "default_lib",
- srcs: [
- "default.py",
- ],
- version: {
- py2: {
- enabled: true,
- srcs: [
- "default_py2.py",
- ],
- },
- py3: {
- enabled: false,
- srcs: [
- "default_py3.py",
- ],
- },
- },
- }
-
- python_library_host {
- name: "lib5",
- pkg_path: "a/b/",
- srcs: [
- "file1.py",
- ],
- version: {
- py2: {
- enabled: true,
- },
- py3: {
- enabled: true,
- },
- },
- }
-
- python_library_host {
- name: "lib6",
- pkg_path: "c/d/",
- srcs: [
- "file2.py",
- ],
- libs: [
- "lib5",
- ],
- }
-
- python_binary_host {
- name: "bin",
- defaults: ["default_lib"],
- pkg_path: "e/",
- srcs: [
- "bin.py",
- ],
- libs: [
- "lib5",
- ],
- version: {
- py3: {
- enabled: true,
- srcs: [
- "file4.py",
- ],
- libs: [
- "lib6",
- ],
- },
- },
- }`,
- ),
- filepath.Join("dir", "default.py"): nil,
- filepath.Join("dir", "default_py2.py"): nil,
- filepath.Join("dir", "default_py3.py"): nil,
- filepath.Join("dir", "file1.py"): nil,
- filepath.Join("dir", "file2.py"): nil,
- filepath.Join("dir", "bin.py"): nil,
- filepath.Join("dir", "file4.py"): nil,
- },
- expectedBinaries: []pyModule{
- {
- name: "bin",
- actualVersion: "PY3",
- pyRunfiles: []string{
- "e/default.py",
- "e/bin.py",
- "e/default_py3.py",
- "e/file4.py",
- },
- srcsZip: "out/soong/.intermediates/dir/bin/PY3/bin.py.srcszip",
- },
- },
- },
}
)
func TestPythonModule(t *testing.T) {
for _, d := range data {
- if d.desc != "module with duplicate runfile path" {
- continue
- }
d.mockFiles[filepath.Join("common", bpFile)] = []byte(`
python_library {
name: "py3-stdlib",
@@ -416,10 +299,6 @@
for i, bp := range testCases {
ctx := android.GroupFixturePreparers(
PrepareForTestWithPythonBuildComponents,
- android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
-
- ctx.RegisterModuleType("python_defaults", DefaultsFactory)
- }),
android.PrepareForTestWithAllowMissingDependencies).
ExtendWithErrorHandler(android.FixtureIgnoreErrors).
RunTestWithBp(t, bp)
@@ -434,7 +313,7 @@
}
func expectModule(t *testing.T, ctx *android.TestContext, name, variant, expectedSrcsZip string, expectedPyRunfiles []string) {
- module := ctx.ModuleForTests(name, variant)
+ module := ctx.ModuleForTests(t, name, variant)
base, baseOk := module.Module().(*PythonLibraryModule)
if !baseOk {
diff --git a/python/test.go b/python/test.go
index 37947dd..df62ab7 100644
--- a/python/test.go
+++ b/python/test.go
@@ -199,13 +199,13 @@
}
if p.isTestHost() && len(p.testProperties.Data_device_bins_both) > 0 {
- ctx.VisitDirectDepsWithTag(dataDeviceBinsTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(dataDeviceBinsTag, func(dep android.ModuleProxy) {
p.data = append(p.data, android.DataPath{SrcPath: android.OutputFileForModule(ctx, dep, "")})
})
}
// Emulate the data property for java_data dependencies.
- for _, javaData := range ctx.GetDirectDepsWithTag(javaDataTag) {
+ for _, javaData := range ctx.GetDirectDepsProxyWithTag(javaDataTag) {
for _, javaDataSrcPath := range android.OutputFilesForModule(ctx, javaData, "") {
p.data = append(p.data, android.DataPath{SrcPath: javaDataSrcPath})
}
@@ -214,6 +214,50 @@
installDir := installDir(ctx, "nativetest", "nativetest64", ctx.ModuleName())
installedData := ctx.InstallTestData(installDir, p.data)
p.installedDest = ctx.InstallFile(installDir, p.installSource.Base(), p.installSource, installedData...)
+
+ // TODO: Remove the special case for kati
+ if !ctx.Config().KatiEnabled() {
+ // Install the test config in testcases/ directory for atest.
+ // Install configs in the root of $PRODUCT_OUT/testcases/$module
+ testCases := android.PathForModuleInPartitionInstall(ctx, "testcases", ctx.ModuleName())
+ if ctx.PrimaryArch() {
+ if p.testConfig != nil {
+ ctx.InstallFile(testCases, ctx.ModuleName()+".config", p.testConfig)
+ }
+ dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml")
+ if dynamicConfig.Valid() {
+ ctx.InstallFile(testCases, ctx.ModuleName()+".dynamic", dynamicConfig.Path())
+ }
+ }
+ // Install tests and data in arch specific subdir $PRODUCT_OUT/testcases/$module/$arch
+ testCases = testCases.Join(ctx, ctx.Target().Arch.ArchType.String())
+ installedData := ctx.InstallTestData(testCases, p.data)
+ ctx.InstallFile(testCases, p.installSource.Base(), p.installSource, installedData...)
+ }
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Class = []string{"NATIVE_TESTS"}
+ if len(p.binaryProperties.Test_suites) > 0 {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, p.binaryProperties.Test_suites...)
+ } else {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
+ }
+ if p.testConfig != nil {
+ moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, p.testConfig.String())
+ }
+ if _, ok := p.testConfig.(android.WritablePath); ok {
+ moduleInfoJSON.AutoTestConfig = []string{"true"}
+ }
+ moduleInfoJSON.TestOptionsTags = append(moduleInfoJSON.TestOptionsTags, p.testProperties.Test_options.Tags...)
+ moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, p.androidMkSharedLibs...)
+ moduleInfoJSON.SharedLibs = append(moduleInfoJSON.Dependencies, p.androidMkSharedLibs...)
+ moduleInfoJSON.SystemSharedLibs = []string{"none"}
+ if proptools.Bool(p.testProperties.Test_options.Unit_test) {
+ moduleInfoJSON.IsUnitTest = "true"
+ if p.isTestHost() {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "host-unit-tests")
+ }
+ }
}
func (p *PythonTestModule) AndroidMkEntries() []android.AndroidMkEntries {
diff --git a/python/testing.go b/python/testing.go
index ce1a5ab..fe53ee5 100644
--- a/python/testing.go
+++ b/python/testing.go
@@ -20,5 +20,4 @@
android.FixtureRegisterWithContext(registerPythonBinaryComponents),
android.FixtureRegisterWithContext(registerPythonLibraryComponents),
android.FixtureRegisterWithContext(registerPythonTestComponents),
- android.FixtureRegisterWithContext(registerPythonMutators),
)
diff --git a/python/tests/runtest.sh b/python/tests/runtest.sh
index c44ec58..9167561 100755
--- a/python/tests/runtest.sh
+++ b/python/tests/runtest.sh
@@ -25,15 +25,9 @@
if [[ ( ! -f $ANDROID_HOST_OUT/nativetest64/par_test/par_test ) ||
( ! -f $ANDROID_HOST_OUT/bin/py3-cmd )]]; then
- echo "Run 'm par_test py2-cmd py3-cmd' first"
+ echo "Run 'm par_test py3-cmd' first"
exit 1
fi
-if [ $(uname -s) = Linux ]; then
- if [[ ! -f $ANDROID_HOST_OUT/bin/py2-cmd ]]; then
- echo "Run 'm par_test py2-cmd py3-cmd' first"
- exit 1
- fi
-fi
export LD_LIBRARY_PATH=$ANDROID_HOST_OUT/lib64
@@ -47,16 +41,8 @@
cd $(dirname ${BASH_SOURCE[0]})
-if [ $(uname -s) = Linux ]; then
- PYTHONPATH=/extra $ANDROID_HOST_OUT/bin/py2-cmd py-cmd_test.py
-fi
PYTHONPATH=/extra $ANDROID_HOST_OUT/bin/py3-cmd py-cmd_test.py
-if [ $(uname -s) = Linux ]; then
- ARGTEST=true PYTHONPATH=/extra $ANDROID_HOST_OUT/bin/py2-cmd py-cmd_test.py arg1 arg2
- ARGTEST2=true PYTHONPATH=/extra $ANDROID_HOST_OUT/bin/py2-cmd py-cmd_test.py --arg1 arg2
-fi
-
ARGTEST=true PYTHONPATH=/extra $ANDROID_HOST_OUT/bin/py3-cmd py-cmd_test.py arg1 arg2
ARGTEST2=true PYTHONPATH=/extra $ANDROID_HOST_OUT/bin/py3-cmd py-cmd_test.py --arg1 arg2
diff --git a/rust/afdo.go b/rust/afdo.go
index 6bd4bae..1bec709 100644
--- a/rust/afdo.go
+++ b/rust/afdo.go
@@ -66,7 +66,7 @@
return flags, deps
}
- ctx.VisitDirectDepsWithTag(cc.FdoProfileTag, func(m android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(cc.FdoProfileTag, func(m android.ModuleProxy) {
if info, ok := android.OtherModuleProvider(ctx, m, cc.FdoProfileProvider); ok {
path := info.Path
profileUseFlag := fmt.Sprintf(afdoFlagFormat, path.String())
diff --git a/rust/afdo_test.go b/rust/afdo_test.go
index 0cdf704..69aa97e 100644
--- a/rust/afdo_test.go
+++ b/rust/afdo_test.go
@@ -50,7 +50,7 @@
rustMockedFiles.AddToFixture(),
).RunTestWithBp(t, bp)
- foo := result.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc")
+ foo := result.ModuleForTests(t, "foo", "android_arm64_armv8-a").Rule("rustc")
expectedCFlag := fmt.Sprintf(afdoFlagFormat, "afdo_profiles_package/foo.afdo")
@@ -96,8 +96,8 @@
rustMockedFiles.AddToFixture(),
).RunTestWithBp(t, bp)
- fooArm := result.ModuleForTests("foo", "android_arm_armv7-a-neon").Rule("rustc")
- fooArm64 := result.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc")
+ fooArm := result.ModuleForTests(t, "foo", "android_arm_armv7-a-neon").Rule("rustc")
+ fooArm64 := result.ModuleForTests(t, "foo", "android_arm64_armv8-a").Rule("rustc")
expectedCFlagArm := fmt.Sprintf(afdoFlagFormat, "afdo_profiles_package/foo_arm.afdo")
expectedCFlagArm64 := fmt.Sprintf(afdoFlagFormat, "afdo_profiles_package/foo_arm64.afdo")
diff --git a/rust/androidmk.go b/rust/androidmk.go
index 8de6b60..9894684 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -92,9 +92,6 @@
func (binary *binaryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkEntries) {
ctx.SubAndroidMk(ret, binary.baseCompiler)
- if binary.distFile.Valid() {
- ret.DistFiles = android.MakeDefaultDistFiles(binary.distFile.Path())
- }
ret.Class = "EXECUTABLES"
}
@@ -143,9 +140,6 @@
} else if library.shared() {
ret.Class = "SHARED_LIBRARIES"
}
- if library.distFile.Valid() {
- ret.DistFiles = android.MakeDefaultDistFiles(library.distFile.Path())
- }
ret.ExtraEntries = append(ret.ExtraEntries,
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
if library.tocFile.Valid() {
@@ -158,10 +152,6 @@
ctx.SubAndroidMk(ret, procMacro.baseCompiler)
ret.Class = "PROC_MACRO_LIBRARIES"
- if procMacro.distFile.Valid() {
- ret.DistFiles = android.MakeDefaultDistFiles(procMacro.distFile.Path())
- }
-
}
func (sourceProvider *BaseSourceProvider) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkEntries) {
diff --git a/rust/benchmark.go b/rust/benchmark.go
index eaa2176..daba964 100644
--- a/rust/benchmark.go
+++ b/rust/benchmark.go
@@ -130,3 +130,20 @@
benchmark.binaryDecorator.install(ctx)
}
+
+func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) {
+ benchmark.binaryDecorator.moduleInfoJSON(ctx, moduleInfoJSON)
+ moduleInfoJSON.Class = []string{"NATIVE_TESTS"}
+ if benchmark.testConfig != nil {
+ if _, ok := benchmark.testConfig.(android.WritablePath); ok {
+ moduleInfoJSON.AutoTestConfig = []string{"true"}
+ }
+ moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, benchmark.testConfig.String())
+ }
+
+ if len(benchmark.Properties.Test_suites) > 0 {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, benchmark.Properties.Test_suites...)
+ } else {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
+ }
+}
diff --git a/rust/benchmark_test.go b/rust/benchmark_test.go
index 734dda7..c239a09 100644
--- a/rust/benchmark_test.go
+++ b/rust/benchmark_test.go
@@ -28,7 +28,7 @@
srcs: ["foo.rs"],
}`)
- testingModule := ctx.ModuleForTests("my_bench", "linux_glibc_x86_64")
+ testingModule := ctx.ModuleForTests(t, "my_bench", "linux_glibc_x86_64")
expectedOut := "my_bench/linux_glibc_x86_64/my_bench"
outPath := testingModule.Output("my_bench").Output.String()
if !strings.Contains(outPath, expectedOut) {
@@ -43,7 +43,7 @@
srcs: ["foo.rs"],
}`)
- testingModule := ctx.ModuleForTests("my_bench", "android_arm64_armv8-a").Module().(*Module)
+ testingModule := ctx.ModuleForTests(t, "my_bench", "android_arm64_armv8-a").Module().(*Module)
if !android.InList("libcriterion.rlib-std", testingModule.Properties.AndroidMkRlibs) {
t.Errorf("rlib-std variant for libcriterion not detected as a rustlib-defined rlib dependency for device rust_benchmark module")
diff --git a/rust/binary.go b/rust/binary.go
index d22041b..5a03d91 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -139,7 +139,10 @@
flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
- flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
+ flags.LinkFlags = append(flags.LinkFlags, deps.rustLibObjects...)
+ flags.LinkFlags = append(flags.LinkFlags, deps.sharedLibObjects...)
+ flags.LinkFlags = append(flags.LinkFlags, deps.staticLibObjects...)
+ flags.LinkFlags = append(flags.LinkFlags, deps.wholeStaticLibObjects...)
if binary.stripper.NeedsStrip(ctx) {
strippedOutputFile := outputFile
@@ -183,3 +186,8 @@
func (binary *binaryDecorator) testBinary() bool {
return false
}
+
+func (binary *binaryDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) {
+ binary.baseCompiler.moduleInfoJSON(ctx, moduleInfoJSON)
+ moduleInfoJSON.Class = []string{"EXECUTABLES"}
+}
diff --git a/rust/binary_test.go b/rust/binary_test.go
index ef93037..33710f9 100644
--- a/rust/binary_test.go
+++ b/rust/binary_test.go
@@ -36,7 +36,7 @@
host_supported: true,
}
`)
- fizzBuzz := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
+ fizzBuzz := ctx.ModuleForTests(t, "fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
if !android.InList("libfoo.rlib-std", fizzBuzz.Properties.AndroidMkRlibs) {
t.Errorf("rustlibs dependency libfoo should be an rlib dep for host binaries")
}
@@ -65,8 +65,8 @@
host_supported: true,
}`)
- fizzBuzzHost := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
- fizzBuzzDevice := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Module().(*Module)
+ fizzBuzzHost := ctx.ModuleForTests(t, "fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
+ fizzBuzzDevice := ctx.ModuleForTests(t, "fizz-buzz", "android_arm64_armv8-a").Module().(*Module)
if !android.InList("libfoo.rlib-std", fizzBuzzHost.Properties.AndroidMkRlibs) {
t.Errorf("rustlibs dependency libfoo should be an rlib dep for host modules")
@@ -76,7 +76,7 @@
t.Errorf("rustlibs dependency libfoo should be an dylib dep for device modules")
}
- rlibLinkDevice := ctx.ModuleForTests("rlib_linked", "android_arm64_armv8-a").Module().(*Module)
+ rlibLinkDevice := ctx.ModuleForTests(t, "rlib_linked", "android_arm64_armv8-a").Module().(*Module)
if !android.InList("libfoo.rlib-std", rlibLinkDevice.Properties.AndroidMkRlibs) {
t.Errorf("rustlibs dependency libfoo should be an rlib dep for device modules when prefer_rlib is set")
@@ -100,7 +100,7 @@
host_supported: true,
}`)
- mod := ctx.ModuleForTests("rlib_linked", "android_arm64_armv8-a").Module().(*Module)
+ mod := ctx.ModuleForTests(t, "rlib_linked", "android_arm64_armv8-a").Module().(*Module)
if !android.InList("libfoo.rlib-std", mod.Properties.AndroidMkRlibs) {
t.Errorf("rustlibs dependency libfoo should be an rlib dep when prefer_rlib is defined")
@@ -119,7 +119,7 @@
srcs: ["foo.rs"],
}`)
- path := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module).HostToolPath()
+ path := ctx.ModuleForTests(t, "fizz-buzz", "linux_glibc_x86_64").Module().(*Module).HostToolPath()
if g, w := path.String(), "/host/linux-x86/bin/fizz-buzz"; !strings.Contains(g, w) {
t.Errorf("wrong host tool path, expected %q got %q", w, g)
}
@@ -133,7 +133,7 @@
srcs: ["foo.rs"],
}`)
- fizzBuzz := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Rule("rustc")
+ fizzBuzz := ctx.ModuleForTests(t, "fizz-buzz", "linux_glibc_x86_64").Rule("rustc")
flags := fizzBuzz.Args["rustcFlags"]
if strings.Contains(flags, "--test") {
@@ -150,7 +150,7 @@
bootstrap: true,
}`)
- foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc")
+ foo := ctx.ModuleForTests(t, "foo", "android_arm64_armv8-a").Rule("rustc")
flag := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker64"
if !strings.Contains(foo.Args["linkFlags"], flag) {
@@ -166,8 +166,8 @@
static_executable: true,
}`)
- fizzOut := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Rule("rustc")
- fizzMod := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Module().(*Module)
+ fizzOut := ctx.ModuleForTests(t, "fizz", "android_arm64_armv8-a").Rule("rustc")
+ fizzMod := ctx.ModuleForTests(t, "fizz", "android_arm64_armv8-a").Module().(*Module)
flags := fizzOut.Args["rustcFlags"]
linkFlags := fizzOut.Args["linkFlags"]
@@ -200,7 +200,7 @@
name: "libfoo",
}`)
- fizzBuzz := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Rule("rustc")
+ fizzBuzz := ctx.ModuleForTests(t, "fizz-buzz", "android_arm64_armv8-a").Rule("rustc")
linkFlags := fizzBuzz.Args["linkFlags"]
if !strings.Contains(linkFlags, "/libfoo.so") {
t.Errorf("missing shared dependency 'libfoo.so' in linkFlags: %#v", linkFlags)
@@ -223,7 +223,7 @@
}
`)
- foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a")
+ foo := ctx.ModuleForTests(t, "foo", "android_arm64_armv8-a")
foo.Output("unstripped/foo")
foo.Output("foo")
@@ -233,7 +233,7 @@
t.Errorf("installed binary not based on stripped version: %v", cp.Input)
}
- fizzBar := ctx.ModuleForTests("bar", "android_arm64_armv8-a").MaybeOutput("unstripped/bar")
+ fizzBar := ctx.ModuleForTests(t, "bar", "android_arm64_armv8-a").MaybeOutput("unstripped/bar")
if fizzBar.Rule != nil {
t.Errorf("unstripped binary exists, so stripped binary has incorrectly been generated")
}
diff --git a/rust/bindgen.go b/rust/bindgen.go
index 898e792..2f84168 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -309,7 +309,8 @@
var cmd, cmdDesc string
if b.Properties.Custom_bindgen != "" {
- cmd = ctx.GetDirectDepWithTag(b.Properties.Custom_bindgen, customBindgenDepTag).(android.HostToolProvider).HostToolPath().String()
+ m := ctx.GetDirectDepProxyWithTag(b.Properties.Custom_bindgen, customBindgenDepTag)
+ cmd = android.OtherModuleProviderOrDefault(ctx, m, android.HostToolProviderInfoProvider).HostToolPath.String()
cmdDesc = b.Properties.Custom_bindgen
} else {
cmd = "$bindgenCmd"
@@ -397,7 +398,7 @@
//
// This is necessary to avoid a circular dependency between the source variant and the
// dependent cc module.
- deps.StaticLibs = append(deps.StaticLibs, String(b.Properties.Static_inline_library))
+ deps.WholeStaticLibs = append(deps.WholeStaticLibs, String(b.Properties.Static_inline_library))
}
deps.SharedLibs = append(deps.SharedLibs, b.ClangProperties.Shared_libs.GetOrDefault(ctx, nil)...)
diff --git a/rust/bindgen_test.go b/rust/bindgen_test.go
index 2b7362f..267fb1c 100644
--- a/rust/bindgen_test.go
+++ b/rust/bindgen_test.go
@@ -67,10 +67,10 @@
cflags: ["--default-flag"],
}
`)
- libbindgen := ctx.ModuleForTests("libbindgen", "android_arm64_armv8-a_source").Output("bindings.rs")
- libbindgenStatic := ctx.ModuleForTests("libbindgen_staticlib", "android_arm64_armv8-a_source").Output("bindings.rs")
- libbindgenHeader := ctx.ModuleForTests("libbindgen_headerlib", "android_arm64_armv8-a_source").Output("bindings.rs")
- libbindgenHeaderModule := ctx.ModuleForTests("libbindgen_headerlib", "android_arm64_armv8-a_source").Module().(*Module)
+ libbindgen := ctx.ModuleForTests(t, "libbindgen", "android_arm64_armv8-a_source").Output("bindings.rs")
+ libbindgenStatic := ctx.ModuleForTests(t, "libbindgen_staticlib", "android_arm64_armv8-a_source").Output("bindings.rs")
+ libbindgenHeader := ctx.ModuleForTests(t, "libbindgen_headerlib", "android_arm64_armv8-a_source").Output("bindings.rs")
+ libbindgenHeaderModule := ctx.ModuleForTests(t, "libbindgen_headerlib", "android_arm64_armv8-a_source").Module().(*Module)
// Ensure that the flags are present and escaped
if !strings.Contains(libbindgen.Args["flags"], "'--bindgen-flag.*'") {
t.Errorf("missing bindgen flags in rust_bindgen rule: flags %#v", libbindgen.Args["flags"])
@@ -113,7 +113,7 @@
}
`)
- libbindgen := ctx.ModuleForTests("libbindgen", "android_arm64_armv8-a_source").Output("bindings.rs")
+ libbindgen := ctx.ModuleForTests(t, "libbindgen", "android_arm64_armv8-a_source").Output("bindings.rs")
// The rule description should contain the custom binary name rather than bindgen, so checking the description
// should be sufficient.
@@ -155,8 +155,8 @@
}
`)
- libbindgen_cstd := ctx.ModuleForTests("libbindgen_cstd", "android_arm64_armv8-a_source").Output("bindings.rs")
- libbindgen_cppstd := ctx.ModuleForTests("libbindgen_cppstd", "android_arm64_armv8-a_source").Output("bindings.rs")
+ libbindgen_cstd := ctx.ModuleForTests(t, "libbindgen_cstd", "android_arm64_armv8-a_source").Output("bindings.rs")
+ libbindgen_cppstd := ctx.ModuleForTests(t, "libbindgen_cppstd", "android_arm64_armv8-a_source").Output("bindings.rs")
if !strings.Contains(libbindgen_cstd.Args["cflags"], "-std=foo") {
t.Errorf("c_std value not passed in to rust_bindgen as a clang flag")
@@ -216,7 +216,7 @@
],
}
`)
- libbindgen := ctx.ModuleForTests("libbindgen", "android_arm64_armv8-a_source").Output("bindings.rs")
+ libbindgen := ctx.ModuleForTests(t, "libbindgen", "android_arm64_armv8-a_source").Output("bindings.rs")
if !strings.Contains(libbindgen.Args["flagfiles"], "/dev/null") {
t.Errorf("missing /dev/null in rust_bindgen rule: flags %#v", libbindgen.Args["flagfiles"])
@@ -246,7 +246,7 @@
include_dirs: ["src/"],
}
`)
- libbindgen := ctx.ModuleForTests("libbindgen", "android_arm64_armv8-a_source").Output("bindings.rs")
+ libbindgen := ctx.ModuleForTests(t, "libbindgen", "android_arm64_armv8-a_source").Output("bindings.rs")
// Make sure the flag to support `static inline` functions is present
if !strings.Contains(libbindgen.Args["flags"], "--wrap-static-fns") {
t.Errorf("missing flag to handle static inlining in rust_bindgen rule: flags %#v", libbindgen.Args["flags"])
diff --git a/rust/builder.go b/rust/builder.go
index 8a869aa..1b6a6c1 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -171,7 +171,7 @@
return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "rlib"))
}
-// TransformRlibstoStaticlib is assumed to be called from the cc module, and
+// TransformRlibstoStaticlib is assumed to be callable from the cc module, and
// thus needs to reconstruct the common set of flags which need to be passed
// to the rustc compiler.
func TransformRlibstoStaticlib(ctx android.ModuleContext, mainSrc android.Path, deps []cc.RustRlibDep,
@@ -185,7 +185,7 @@
rustPathDeps.linkDirs = append(rustPathDeps.linkDirs, rlibDep.LinkDirs...)
}
- ccModule := ctx.(cc.ModuleContext).Module().(*cc.Module)
+ mod := ctx.Module().(cc.LinkableInterface)
toolchain := config.FindToolchain(ctx.Os(), ctx.Arch())
t := transformProperties{
// Crate name can be a predefined value as this is a staticlib and
@@ -195,10 +195,10 @@
crateName: "generated_rust_staticlib",
is64Bit: toolchain.Is64Bit(),
targetTriple: toolchain.RustTriple(),
- bootstrap: ccModule.Bootstrap(),
- inRecovery: ccModule.InRecovery(),
- inRamdisk: ccModule.InRamdisk(),
- inVendorRamdisk: ccModule.InVendorRamdisk(),
+ bootstrap: mod.Bootstrap(),
+ inRecovery: mod.InRecovery(),
+ inRamdisk: mod.InRamdisk(),
+ inVendorRamdisk: mod.InVendorRamdisk(),
// crateType indicates what type of crate to build
crateType: "staticlib",
@@ -402,6 +402,11 @@
linkFlags = append(linkFlags, dynamicLinker)
}
+ if generatedLib := cc.GenerateRustStaticlib(ctx, deps.ccRlibDeps); generatedLib != nil {
+ deps.StaticLibs = append(deps.StaticLibs, generatedLib)
+ linkFlags = append(linkFlags, generatedLib.String())
+ }
+
libFlags := makeLibFlags(deps)
// Collect dependencies
diff --git a/rust/builder_test.go b/rust/builder_test.go
index b4b022e..7d6b56a 100644
--- a/rust/builder_test.go
+++ b/rust/builder_test.go
@@ -160,7 +160,7 @@
}
for _, tc := range testcases {
t.Run(tc.testName, func(t *testing.T) {
- modOutputs := ctx.ModuleForTests(tc.moduleName, tc.variant).AllOutputs()
+ modOutputs := ctx.ModuleForTests(t, tc.moduleName, tc.variant).AllOutputs()
sort.Strings(tc.expectedFiles)
sort.Strings(modOutputs)
android.AssertStringPathsRelativeToTopEquals(
diff --git a/rust/clippy_test.go b/rust/clippy_test.go
index bd3bfb1..3563348 100644
--- a/rust/clippy_test.go
+++ b/rust/clippy_test.go
@@ -62,13 +62,13 @@
android.FixtureAddTextFile(tc.modulePath+"Android.bp", bp),
).RunTest(t)
- r := result.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
+ r := result.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
android.AssertStringEquals(t, "libfoo flags", tc.fooFlags, r.Args["clippyFlags"])
- r = result.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
+ r = result.ModuleForTests(t, "libbar", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
android.AssertStringEquals(t, "libbar flags", "${config.ClippyDefaultLints}", r.Args["clippyFlags"])
- r = result.ModuleForTests("libfoobar", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
+ r = result.ModuleForTests(t, "libfoobar", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
if r.Rule != nil {
t.Errorf("libfoobar is setup to use clippy when explicitly disabled: clippyFlags=%q", r.Args["clippyFlags"])
}
diff --git a/rust/compiler.go b/rust/compiler.go
index b93019b..c3bc937 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -39,6 +39,7 @@
compilerFlags(ctx ModuleContext, flags Flags) Flags
cfgFlags(ctx ModuleContext, flags Flags) Flags
featureFlags(ctx ModuleContext, module *Module, flags Flags) Flags
+ baseCompilerProps() BaseCompilerProperties
compilerProps() []interface{}
compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput
compilerDeps(ctx DepsContext, deps Deps) Deps
@@ -77,6 +78,8 @@
checkedCrateRootPath() (android.Path, error)
Aliases() map[string]string
+
+ moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON)
}
func (compiler *baseCompiler) edition() string {
@@ -149,21 +152,21 @@
Aliases []string
// list of rust rlib crate dependencies
- Rlibs []string `android:"arch_variant"`
+ Rlibs proptools.Configurable[[]string] `android:"arch_variant"`
// list of rust automatic crate dependencies.
// Rustlibs linkage is rlib for host targets and dylib for device targets.
Rustlibs proptools.Configurable[[]string] `android:"arch_variant"`
// list of rust proc_macro crate dependencies
- Proc_macros []string `android:"arch_variant"`
+ Proc_macros proptools.Configurable[[]string] `android:"arch_variant"`
// list of C shared library dependencies
- Shared_libs []string `android:"arch_variant"`
+ Shared_libs proptools.Configurable[[]string] `android:"arch_variant"`
// list of C static library dependencies. These dependencies do not normally propagate to dependents
// and may need to be redeclared. See whole_static_libs for bundling static dependencies into a library.
- Static_libs []string `android:"arch_variant"`
+ Static_libs proptools.Configurable[[]string] `android:"arch_variant"`
// Similar to static_libs, but will bundle the static library dependency into a library. This is helpful
// to avoid having to redeclare the dependency for dependents of this library, but in some cases may also
@@ -178,13 +181,13 @@
//
// For rust_library rlib variants, these libraries will be bundled into the resulting rlib library. This will
// include all of the static libraries symbols in any dylibs or binaries which use this rlib as well.
- Whole_static_libs []string `android:"arch_variant"`
+ Whole_static_libs proptools.Configurable[[]string] `android:"arch_variant"`
// list of Rust system library dependencies.
//
// This is usually only needed when `no_stdlibs` is true, in which case it can be used to depend on system crates
// like `core` and `alloc`.
- Stdlibs []string `android:"arch_variant"`
+ Stdlibs proptools.Configurable[[]string] `android:"arch_variant"`
// crate name, required for modules which produce Rust libraries: rust_library, rust_ffi and SourceProvider
// modules which create library variants (rust_bindgen). This must be the expected extern crate name used in
@@ -254,8 +257,6 @@
location installLocation
sanitize *sanitize
- distFile android.OptionalPath
-
installDeps android.InstallPaths
// unstripped output file.
@@ -326,6 +327,31 @@
}
}
+func (compiler *baseCompiler) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) {
+ moduleInfoJSON.Class = []string{"ETC"}
+
+ mod := ctx.Module().(*Module)
+
+ moduleInfoJSON.SharedLibs = mod.transitiveAndroidMkSharedLibs.ToList()
+ moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, mod.transitiveAndroidMkSharedLibs.ToList()...)
+ moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, mod.Properties.AndroidMkDylibs...)
+ moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, mod.Properties.AndroidMkHeaderLibs...)
+ moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, mod.Properties.AndroidMkProcMacroLibs...)
+ moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, mod.Properties.AndroidMkRlibs...)
+ moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, mod.Properties.AndroidMkStaticLibs...)
+ moduleInfoJSON.SystemSharedLibs = []string{"none"}
+ moduleInfoJSON.StaticLibs = mod.Properties.AndroidMkStaticLibs
+
+ if mod.sourceProvider != nil {
+ moduleInfoJSON.SubName += mod.sourceProvider.getSubName()
+ }
+ moduleInfoJSON.SubName += mod.AndroidMkSuffix()
+
+ if mod.Properties.IsSdkVariant {
+ moduleInfoJSON.Uninstallable = true
+ }
+}
+
var _ compiler = (*baseCompiler)(nil)
func (compiler *baseCompiler) inData() bool {
@@ -336,6 +362,10 @@
return []interface{}{&compiler.Properties}
}
+func (compiler *baseCompiler) baseCompilerProps() BaseCompilerProperties {
+ return compiler.Properties
+}
+
func cfgsToFlags(cfgs []string) []string {
flags := make([]string, 0, len(cfgs))
for _, cfg := range cfgs {
@@ -495,13 +525,13 @@
}
func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
- deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs...)
+ deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs.GetOrDefault(ctx, nil)...)
deps.Rustlibs = append(deps.Rustlibs, compiler.Properties.Rustlibs.GetOrDefault(ctx, nil)...)
- deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros...)
- deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs...)
- deps.WholeStaticLibs = append(deps.WholeStaticLibs, compiler.Properties.Whole_static_libs...)
- deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs...)
- deps.Stdlibs = append(deps.Stdlibs, compiler.Properties.Stdlibs...)
+ deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros.GetOrDefault(ctx, nil)...)
+ deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs.GetOrDefault(ctx, nil)...)
+ deps.WholeStaticLibs = append(deps.WholeStaticLibs, compiler.Properties.Whole_static_libs.GetOrDefault(ctx, nil)...)
+ deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs.GetOrDefault(ctx, nil)...)
+ deps.Stdlibs = append(deps.Stdlibs, compiler.Properties.Stdlibs.GetOrDefault(ctx, nil)...)
if !Bool(compiler.Properties.No_stdlibs) {
for _, stdlib := range config.Stdlibs {
diff --git a/rust/compiler_test.go b/rust/compiler_test.go
index 4caa12b..8805d15 100644
--- a/rust/compiler_test.go
+++ b/rust/compiler_test.go
@@ -34,7 +34,7 @@
],
}`)
- libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
+ libfooDylib := ctx.ModuleForTests(t, "libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
if !strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'feature=\"fizz\"'") ||
!strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'feature=\"buzz\"'") {
@@ -55,7 +55,7 @@
],
}`)
- libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
+ libfooDylib := ctx.ModuleForTests(t, "libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
if !strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'std'") ||
!strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'cfg1=\"one\"'") {
@@ -81,8 +81,8 @@
}
`)
- libfoo := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
- libfooLto := ctx.ModuleForTests("libfoo_lto", "linux_glibc_x86_64_dylib").Rule("rustc")
+ libfoo := ctx.ModuleForTests(t, "libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
+ libfooLto := ctx.ModuleForTests(t, "libfoo_lto", "linux_glibc_x86_64_dylib").Rule("rustc")
if strings.Contains(libfoo.Args["rustcFlags"], "-C lto=thin") {
t.Fatalf("libfoo expected to disable lto -- rustcFlags: %#v", libfoo.Args["rustcFlags"])
@@ -174,7 +174,7 @@
cargo_pkg_version: "1.0.0"
}`)
- fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Rule("rustc")
+ fizz := ctx.ModuleForTests(t, "fizz", "android_arm64_armv8-a").Rule("rustc")
if !strings.Contains(fizz.Args["envVars"], "CARGO_BIN_NAME=fizz") {
t.Fatalf("expected 'CARGO_BIN_NAME=fizz' in envVars, actual envVars: %#v", fizz.Args["envVars"])
@@ -199,11 +199,11 @@
srcs: ["foo.rs"],
}`)
- install_path_lib64 := ctx.ModuleForTests("libfoo",
+ install_path_lib64 := ctx.ModuleForTests(t, "libfoo",
"android_arm64_armv8-a_dylib").Module().(*Module).compiler.(*libraryDecorator).path.String()
- install_path_lib32 := ctx.ModuleForTests("libfoo",
+ install_path_lib32 := ctx.ModuleForTests(t, "libfoo",
"android_arm_armv7-a-neon_dylib").Module().(*Module).compiler.(*libraryDecorator).path.String()
- install_path_bin := ctx.ModuleForTests("fizzbuzz",
+ install_path_bin := ctx.ModuleForTests(t, "fizzbuzz",
"android_arm64_armv8-a").Module().(*Module).compiler.(*binaryDecorator).path.String()
if !strings.HasSuffix(install_path_lib64, "system/lib64/libfoo.dylib.so") {
@@ -259,13 +259,13 @@
android.FixtureAddTextFile(tc.modulePath+"Android.bp", bp),
).RunTest(t)
- r := result.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
+ r := result.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
android.AssertStringDoesContain(t, "libfoo flags", r.Args["rustcFlags"], tc.fooFlags)
- r = result.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
+ r = result.ModuleForTests(t, "libbar", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
android.AssertStringDoesContain(t, "libbar flags", r.Args["rustcFlags"], "${config.RustDefaultLints}")
- r = result.ModuleForTests("libfoobar", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
+ r = result.ModuleForTests(t, "libfoobar", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
android.AssertStringDoesContain(t, "libfoobar flags", r.Args["rustcFlags"], "${config.RustAllowAllLints}")
})
}
@@ -283,9 +283,9 @@
srcs: ["foo.rs"],
crate_name: "foo",
}`)
- fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Module().(*Module)
- fooRlib := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_rlib_dylib-std").Module().(*Module)
- fooDylib := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").Module().(*Module)
+ fizz := ctx.ModuleForTests(t, "fizz", "android_arm64_armv8-a").Module().(*Module)
+ fooRlib := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_rlib_dylib-std").Module().(*Module)
+ fooDylib := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_dylib").Module().(*Module)
if !android.InList("libstd", fizz.Properties.AndroidMkDylibs) {
t.Errorf("libstd is not linked dynamically for device binaries")
diff --git a/rust/config/global.go b/rust/config/global.go
index 0a4b314..907316f 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -25,7 +25,7 @@
var (
pctx = android.NewPackageContext("android/soong/rust/config")
- RustDefaultVersion = "1.81.0"
+ RustDefaultVersion = "1.83.0"
RustDefaultBase = "prebuilts/rust/"
DefaultEdition = "2021"
Stdlibs = []string{
diff --git a/rust/config/lints.go b/rust/config/lints.go
index 735aa16..715e8aa 100644
--- a/rust/config/lints.go
+++ b/rust/config/lints.go
@@ -55,6 +55,7 @@
defaultClippyLints = []string{
// Let people hack in peace. ;)
"-A clippy::disallowed_names",
+ "-A clippy::empty_line_after_doc_comments",
"-A clippy::type-complexity",
"-A clippy::unnecessary_fallible_conversions",
"-A clippy::unnecessary-wraps",
diff --git a/rust/coverage.go b/rust/coverage.go
index 381fcf1..798b21d 100644
--- a/rust/coverage.go
+++ b/rust/coverage.go
@@ -15,12 +15,13 @@
package rust
import (
+ "android/soong/android"
+
"github.com/google/blueprint"
"android/soong/cc"
)
-var CovLibraryName = "libprofile-clang-extras"
var ProfilerBuiltins = "libprofiler_builtins.rust_sysroot"
// Add '%c' to default specifier after we resolve http://b/210012154
@@ -37,12 +38,20 @@
return []interface{}{&cov.Properties}
}
+func getClangProfileLibraryName(ctx ModuleContextIntf) string {
+ if ctx.RustModule().UseSdk() {
+ return "libprofile-clang-extras_ndk"
+ } else {
+ return "libprofile-clang-extras"
+ }
+}
+
func (cov *coverage) deps(ctx DepsContext, deps Deps) Deps {
if cov.Properties.NeedCoverageVariant {
if ctx.Device() {
ctx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
- }, cc.CoverageDepTag, CovLibraryName)
+ }, cc.CoverageDepTag, getClangProfileLibraryName(ctx))
}
// no_std modules are missing libprofiler_builtins which provides coverage, so we need to add it as a dependency.
@@ -65,16 +74,18 @@
flags.RustFlags = append(flags.RustFlags,
"-C instrument-coverage", "-g")
if ctx.Device() {
- coverage := ctx.GetDirectDepWithTag(CovLibraryName, cc.CoverageDepTag).(cc.LinkableInterface)
+ m := ctx.GetDirectDepProxyWithTag(getClangProfileLibraryName(ctx), cc.CoverageDepTag)
+ coverage := android.OtherModuleProviderOrDefault(ctx, m, cc.LinkableInfoProvider)
flags.LinkFlags = append(flags.LinkFlags,
- profileInstrFlag, "-g", coverage.OutputFile().Path().String(), "-Wl,--wrap,open")
- deps.StaticLibs = append(deps.StaticLibs, coverage.OutputFile().Path())
+ profileInstrFlag, "-g", coverage.OutputFile.Path().String(), "-Wl,--wrap,open")
+ deps.StaticLibs = append(deps.StaticLibs, coverage.OutputFile.Path())
}
// no_std modules are missing libprofiler_builtins which provides coverage, so we need to add it as a dependency.
if rustModule, ok := ctx.Module().(*Module); ok && rustModule.compiler.noStdlibs() {
- profiler_builtins := ctx.GetDirectDepWithTag(ProfilerBuiltins, rlibDepTag).(*Module)
- deps.RLibs = append(deps.RLibs, RustLibrary{Path: profiler_builtins.OutputFile().Path(), CrateName: profiler_builtins.CrateName()})
+ m := ctx.GetDirectDepProxyWithTag(ProfilerBuiltins, rlibDepTag)
+ profiler_builtins := android.OtherModuleProviderOrDefault(ctx, m, cc.LinkableInfoProvider)
+ deps.RLibs = append(deps.RLibs, RustLibrary{Path: profiler_builtins.OutputFile.Path(), CrateName: profiler_builtins.CrateName})
}
if cc.EnableContinuousCoverage(ctx) {
diff --git a/rust/coverage_test.go b/rust/coverage_test.go
index 0f599d7..f9198f1 100644
--- a/rust/coverage_test.go
+++ b/rust/coverage_test.go
@@ -51,10 +51,10 @@
}
// Just test the dylib variants unless the library coverage logic changes to distinguish between the types.
- libfooCov := ctx.ModuleForTests("libfoo_cov", "android_arm64_armv8-a_dylib_cov").Rule("rustc")
- libbarNoCov := ctx.ModuleForTests("libbar_nocov", "android_arm64_armv8-a_dylib").Rule("rustc")
- fizzCov := ctx.ModuleForTests("fizz_cov", "android_arm64_armv8-a_cov").Rule("rustc")
- buzzNoCov := ctx.ModuleForTests("buzzNoCov", "android_arm64_armv8-a").Rule("rustc")
+ libfooCov := ctx.ModuleForTests(t, "libfoo_cov", "android_arm64_armv8-a_dylib_cov").Rule("rustc")
+ libbarNoCov := ctx.ModuleForTests(t, "libbar_nocov", "android_arm64_armv8-a_dylib").Rule("rustc")
+ fizzCov := ctx.ModuleForTests(t, "fizz_cov", "android_arm64_armv8-a_cov").Rule("rustc")
+ buzzNoCov := ctx.ModuleForTests(t, "buzzNoCov", "android_arm64_armv8-a").Rule("rustc")
rustcCoverageFlags := []string{"-C instrument-coverage", " -g "}
for _, flag := range rustcCoverageFlags {
@@ -103,7 +103,7 @@
srcs: ["foo.rs"],
}`)
- fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a_cov").Rule("rustc")
+ fizz := ctx.ModuleForTests(t, "fizz", "android_arm64_armv8-a_cov").Rule("rustc")
if !strings.Contains(fizz.Args["linkFlags"], "libprofile-clang-extras.a") {
t.Fatalf("missing expected coverage 'libprofile-clang-extras' dependency in linkFlags: %#v", fizz.Args["linkFlags"])
}
diff --git a/rust/fuzz_test.go b/rust/fuzz_test.go
index 3598c99..bdcfbbb 100644
--- a/rust/fuzz_test.go
+++ b/rust/fuzz_test.go
@@ -41,7 +41,7 @@
`)
// Check that appropriate dependencies are added and that the rustlib linkage is correct.
- fuzz_libtest_mod := ctx.ModuleForTests("fuzz_libtest", "android_arm64_armv8-a_fuzzer").Module().(*Module)
+ fuzz_libtest_mod := ctx.ModuleForTests(t, "fuzz_libtest", "android_arm64_armv8-a_fuzzer").Module().(*Module)
if !android.InList("liblibfuzzer_sys.rlib-std", fuzz_libtest_mod.Properties.AndroidMkRlibs) {
t.Errorf("liblibfuzzer_sys rlib library dependency missing for rust_fuzz module. %#v", fuzz_libtest_mod.Properties.AndroidMkRlibs)
}
@@ -50,21 +50,21 @@
}
// Check that compiler flags are set appropriately .
- fuzz_libtest := ctx.ModuleForTests("fuzz_libtest", "android_arm64_armv8-a_fuzzer").Rule("rustc")
+ fuzz_libtest := ctx.ModuleForTests(t, "fuzz_libtest", "android_arm64_armv8-a_fuzzer").Rule("rustc")
if !strings.Contains(fuzz_libtest.Args["rustcFlags"], "-C passes='sancov-module'") ||
!strings.Contains(fuzz_libtest.Args["rustcFlags"], "--cfg fuzzing") {
t.Errorf("rust_fuzz module does not contain the expected flags (sancov-module, cfg fuzzing).")
}
// Check that host modules support fuzzing.
- host_fuzzer := ctx.ModuleForTests("fuzz_libtest", "android_arm64_armv8-a_fuzzer").Rule("rustc")
+ host_fuzzer := ctx.ModuleForTests(t, "fuzz_libtest", "android_arm64_armv8-a_fuzzer").Rule("rustc")
if !strings.Contains(host_fuzzer.Args["rustcFlags"], "-C passes='sancov-module'") ||
!strings.Contains(host_fuzzer.Args["rustcFlags"], "--cfg fuzzing") {
t.Errorf("rust_fuzz_host module does not contain the expected flags (sancov-module, cfg fuzzing).")
}
// Check that dependencies have 'fuzzer' variants produced for them as well.
- libtest_fuzzer := ctx.ModuleForTests("libtest_fuzzing", "android_arm64_armv8-a_rlib_rlib-std_fuzzer").Output("libtest_fuzzing.rlib")
+ libtest_fuzzer := ctx.ModuleForTests(t, "libtest_fuzzing", "android_arm64_armv8-a_rlib_rlib-std_fuzzer").Output("libtest_fuzzing.rlib")
if !strings.Contains(libtest_fuzzer.Args["rustcFlags"], "-C passes='sancov-module'") ||
!strings.Contains(libtest_fuzzer.Args["rustcFlags"], "--cfg fuzzing") {
t.Errorf("rust_fuzz dependent library does not contain the expected flags (sancov-module, cfg fuzzing).")
@@ -93,7 +93,7 @@
}
`)
- fuzz_libtest := ctx.ModuleForTests("fuzz_libtest", "android_arm64_armv8-a_fuzzer").Module().(*Module)
+ fuzz_libtest := ctx.ModuleForTests(t, "fuzz_libtest", "android_arm64_armv8-a_fuzzer").Module().(*Module)
if !strings.Contains(fuzz_libtest.FuzzSharedLibraries().String(), ":libcc_direct_dep.so") {
t.Errorf("rust_fuzz does not contain the expected bundled direct shared libs ('libcc_direct_dep'): %#v", fuzz_libtest.FuzzSharedLibraries().String())
@@ -134,9 +134,9 @@
}
`)
- fuzz_shared_libtest := ctx.ModuleForTests("fuzz_shared_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface)
- fuzz_static_libtest := ctx.ModuleForTests("fuzz_static_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface)
- fuzz_staticffi_libtest := ctx.ModuleForTests("fuzz_staticffi_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface)
+ fuzz_shared_libtest := ctx.ModuleForTests(t, "fuzz_shared_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface)
+ fuzz_static_libtest := ctx.ModuleForTests(t, "fuzz_static_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface)
+ fuzz_staticffi_libtest := ctx.ModuleForTests(t, "fuzz_staticffi_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface)
if !strings.Contains(fuzz_shared_libtest.FuzzSharedLibraries().String(), ":libcc_transitive_dep.so") {
t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_shared ('libcc_transitive_dep'): %#v", fuzz_shared_libtest.FuzzSharedLibraries().String())
diff --git a/rust/image_test.go b/rust/image_test.go
index 0581fa7..e5ecd79 100644
--- a/rust/image_test.go
+++ b/rust/image_test.go
@@ -45,7 +45,7 @@
}
`)
- vendorBinary := ctx.ModuleForTests("fizz_vendor_available", "android_vendor_arm64_armv8-a").Module().(*cc.Module)
+ vendorBinary := ctx.ModuleForTests(t, "fizz_vendor_available", "android_vendor_arm64_armv8-a").Module().(*cc.Module)
if android.InList("libfoo_vendor.vendor", vendorBinary.Properties.AndroidMkStaticLibs) {
t.Errorf("vendorBinary should not have a staticlib dependency on libfoo_vendor.vendor: %#v", vendorBinary.Properties.AndroidMkStaticLibs)
@@ -64,7 +64,7 @@
}
`)
- vendor := ctx.ModuleForTests("libfoo", "android_vendor_arm64_armv8-a_shared").Rule("rustc")
+ vendor := ctx.ModuleForTests(t, "libfoo", "android_vendor_arm64_armv8-a_shared").Rule("rustc")
if !strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_vndk'") {
t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
@@ -76,7 +76,7 @@
t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
}
- product := ctx.ModuleForTests("libfoo", "android_product_arm64_armv8-a_shared").Rule("rustc")
+ product := ctx.ModuleForTests(t, "libfoo", "android_product_arm64_armv8-a_shared").Rule("rustc")
if !strings.Contains(product.Args["rustcFlags"], "--cfg 'android_vndk'") {
t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"])
}
@@ -87,7 +87,7 @@
t.Errorf("missing \"--cfg 'android_product'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"])
}
- system := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("rustc")
+ system := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Rule("rustc")
if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_vndk'") {
t.Errorf("unexpected \"--cfg 'android_vndk'\" for libfoo system variant, rustcFlags: %#v", system.Args["rustcFlags"])
}
@@ -119,7 +119,7 @@
}
`)
- vendorRamdiskLibrary := ctx.ModuleForTests("libcc_vendor_ramdisk", "android_vendor_ramdisk_arm64_armv8-a_shared").Module().(*cc.Module)
+ vendorRamdiskLibrary := ctx.ModuleForTests(t, "libcc_vendor_ramdisk", "android_vendor_ramdisk_arm64_armv8-a_shared").Module().(*cc.Module)
if android.InList("libfoo_vendor_ramdisk.vendor_ramdisk", vendorRamdiskLibrary.Properties.AndroidMkStaticLibs) {
t.Errorf("libcc_vendor_ramdisk should not have a dependency on the libfoo_vendor_ramdisk static library")
@@ -144,7 +144,7 @@
}
func checkInstallPartition(t *testing.T, ctx *android.TestContext, name, variant, expected string) {
- mod := ctx.ModuleForTests(name, variant).Module().(*Module)
+ mod := ctx.ModuleForTests(t, name, variant).Module().(*Module)
partitionDefined := false
checkPartition := func(specific bool, partition string) {
if specific {
diff --git a/rust/library.go b/rust/library.go
index 2d62dcf..415785a 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -25,6 +25,7 @@
"android/soong/android"
"android/soong/cc"
+ cc_config "android/soong/cc/config"
)
var (
@@ -79,9 +80,13 @@
// Whether this library is part of the Rust toolchain sysroot.
Sysroot *bool
- // Exclude this rust_ffi target from being included in APEXes.
- // TODO(b/362509506): remove this once stubs are properly supported by rust_ffi targets.
+ // Deprecated - exclude this rust_ffi target from being included in APEXes.
+ // TODO(b/362509506): remove this once all apex_exclude uses are switched to stubs.
Apex_exclude *bool
+
+ // Generate stubs to make this library accessible to APEXes.
+ // Can only be set for modules producing shared libraries.
+ Stubs cc.StubsProperties `android:"arch_variant"`
}
type LibraryMutatedProperties struct {
@@ -109,6 +114,15 @@
// Whether this library variant should be link libstd via rlibs
VariantIsStaticStd bool `blueprint:"mutated"`
+
+ // This variant is a stubs lib
+ BuildStubs bool `blueprint:"mutated"`
+ // This variant is the latest version
+ IsLatestVersion bool `blueprint:"mutated"`
+ // Version of the stubs lib
+ StubsVersion string `blueprint:"mutated"`
+ // List of all stubs versions associated with an implementation lib
+ AllStubsVersions []string `blueprint:"mutated"`
}
type libraryDecorator struct {
@@ -123,9 +137,28 @@
// table-of-contents file for cdylib crates to optimize out relinking when possible
tocFile android.OptionalPath
+
+ // Path to the file containing the APIs exported by this library
+ stubsSymbolFilePath android.Path
+ apiListCoverageXmlPath android.ModuleOutPath
+ versionScriptPath android.OptionalPath
+}
+
+func (library *libraryDecorator) stubs() bool {
+ return library.MutatedProperties.BuildStubs
+}
+
+func (library *libraryDecorator) setAPIListCoverageXMLPath(xml android.ModuleOutPath) {
+ library.apiListCoverageXmlPath = xml
+}
+
+func (library *libraryDecorator) libraryProperties() LibraryCompilerProperties {
+ return library.Properties
}
type libraryInterface interface {
+ cc.VersionedInterface
+
rlib() bool
dylib() bool
static() bool
@@ -161,9 +194,17 @@
BuildOnlyShared()
toc() android.OptionalPath
+
+ IsStubsImplementationRequired() bool
+ setAPIListCoverageXMLPath(out android.ModuleOutPath)
+
+ libraryProperties() LibraryCompilerProperties
}
func (library *libraryDecorator) nativeCoverage() bool {
+ if library.BuildStubs() {
+ return false
+ }
return true
}
@@ -276,7 +317,85 @@
var _ compiler = (*libraryDecorator)(nil)
var _ libraryInterface = (*libraryDecorator)(nil)
+var _ cc.VersionedInterface = (*libraryDecorator)(nil)
var _ exportedFlagsProducer = (*libraryDecorator)(nil)
+var _ cc.VersionedInterface = (*libraryDecorator)(nil)
+
+func (library *libraryDecorator) HasLLNDKStubs() bool {
+ // Rust LLNDK is currently unsupported
+ return false
+}
+
+func (library *libraryDecorator) HasVendorPublicLibrary() bool {
+ // Rust does not support vendor_public_library yet.
+ return false
+}
+
+func (library *libraryDecorator) HasLLNDKHeaders() bool {
+ // Rust LLNDK is currently unsupported
+ return false
+}
+
+func (library *libraryDecorator) HasStubsVariants() bool {
+ // Just having stubs.symbol_file is enough to create a stub variant. In that case
+ // the stub for the future API level is created.
+ return library.Properties.Stubs.Symbol_file != nil ||
+ len(library.Properties.Stubs.Versions) > 0
+}
+
+func (library *libraryDecorator) IsStubsImplementationRequired() bool {
+ return BoolDefault(library.Properties.Stubs.Implementation_installable, true)
+}
+
+func (library *libraryDecorator) GetAPIListCoverageXMLPath() android.ModuleOutPath {
+ return library.apiListCoverageXmlPath
+}
+
+func (library *libraryDecorator) AllStubsVersions() []string {
+ return library.MutatedProperties.AllStubsVersions
+}
+
+func (library *libraryDecorator) SetAllStubsVersions(versions []string) {
+ library.MutatedProperties.AllStubsVersions = versions
+}
+
+func (library *libraryDecorator) SetStubsVersion(version string) {
+ library.MutatedProperties.StubsVersion = version
+}
+
+func (library *libraryDecorator) SetBuildStubs(isLatest bool) {
+ library.MutatedProperties.BuildStubs = true
+ library.MutatedProperties.IsLatestVersion = isLatest
+}
+
+func (library *libraryDecorator) BuildStubs() bool {
+ return library.MutatedProperties.BuildStubs
+}
+
+func (library *libraryDecorator) ImplementationModuleName(name string) string {
+ return name
+}
+
+func (library *libraryDecorator) IsLLNDKMovedToApex() bool {
+ // Rust does not support LLNDK.
+ return false
+}
+
+func (library *libraryDecorator) StubsVersion() string {
+ return library.MutatedProperties.StubsVersion
+}
+
+// stubsVersions implements cc.VersionedInterface.
+func (library *libraryDecorator) StubsVersions(ctx android.BaseModuleContext) []string {
+ if !library.HasStubsVariants() {
+ return nil
+ }
+
+ // Future API level is implicitly added if there isn't
+ versions := cc.AddCurrentVersionIfNotPresent(library.Properties.Stubs.Versions)
+ cc.NormalizeVersions(ctx, versions)
+ return versions
+}
// rust_library produces all Rust variants (rust_library_dylib and
// rust_library_rlib).
@@ -355,6 +474,18 @@
return module.Init()
}
+func CheckRustLibraryProperties(mctx android.DefaultableHookContext) {
+ lib := mctx.Module().(*Module).compiler.(libraryInterface)
+ if !lib.buildShared() {
+ if lib.libraryProperties().Stubs.Symbol_file != nil ||
+ lib.libraryProperties().Stubs.Implementation_installable != nil ||
+ len(lib.libraryProperties().Stubs.Versions) > 0 {
+
+ mctx.PropertyErrorf("stubs", "stubs properties can only be set for rust_ffi or rust_ffi_shared modules")
+ }
+ }
+}
+
func (library *libraryDecorator) BuildOnlyFFI() {
library.MutatedProperties.BuildDylib = false
// we build rlibs for later static ffi linkage.
@@ -414,6 +545,7 @@
module.compiler = library
+ module.SetDefaultableHook(CheckRustLibraryProperties)
return module, library
}
@@ -542,7 +674,10 @@
flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
- flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
+ flags.LinkFlags = append(flags.LinkFlags, deps.rustLibObjects...)
+ flags.LinkFlags = append(flags.LinkFlags, deps.sharedLibObjects...)
+ flags.LinkFlags = append(flags.LinkFlags, deps.staticLibObjects...)
+ flags.LinkFlags = append(flags.LinkFlags, deps.wholeStaticLibObjects...)
if String(library.Properties.Version_script) != "" {
if String(library.Properties.Extra_exported_symbols) != "" {
@@ -576,7 +711,11 @@
}
// Call the appropriate builder for this library type
- if library.rlib() {
+ if library.stubs() {
+ ccFlags := library.getApiStubsCcFlags(ctx)
+ stubObjs := library.compileModuleLibApiStubs(ctx, ccFlags)
+ cc.BuildRustStubs(ctx, outputFile, stubObjs, ccFlags)
+ } else if library.rlib() {
ret.kytheFile = TransformSrctoRlib(ctx, crateRootPath, deps, flags, outputFile).kytheFile
} else if library.dylib() {
ret.kytheFile = TransformSrctoDylib(ctx, crateRootPath, deps, flags, outputFile).kytheFile
@@ -586,19 +725,36 @@
ret.kytheFile = TransformSrctoShared(ctx, crateRootPath, deps, flags, outputFile).kytheFile
}
+ // rlibs and dylibs propagate their shared, whole static, and rustlib dependencies
if library.rlib() || library.dylib() {
library.flagExporter.exportLinkDirs(deps.linkDirs...)
- library.flagExporter.exportLinkObjects(deps.linkObjects...)
+ library.flagExporter.exportRustLibs(deps.rustLibObjects...)
+ library.flagExporter.exportSharedLibs(deps.sharedLibObjects...)
+ library.flagExporter.exportWholeStaticLibs(deps.wholeStaticLibObjects...)
}
+ // rlibs also propagate their staticlibs dependencies
+ if library.rlib() {
+ library.flagExporter.exportStaticLibs(deps.staticLibObjects...)
+ }
// Since we have FFI rlibs, we need to collect their includes as well
- if library.static() || library.shared() || library.rlib() {
- android.SetProvider(ctx, cc.FlagExporterInfoProvider, cc.FlagExporterInfo{
+ if library.static() || library.shared() || library.rlib() || library.stubs() {
+ ccExporter := cc.FlagExporterInfo{
IncludeDirs: android.FirstUniquePaths(library.includeDirs),
- })
+ }
+ if library.rlib() {
+ ccExporter.RustRlibDeps = append(ccExporter.RustRlibDeps, deps.reexportedCcRlibDeps...)
+ ccExporter.RustRlibDeps = append(ccExporter.RustRlibDeps, deps.reexportedWholeCcRlibDeps...)
+ }
+ android.SetProvider(ctx, cc.FlagExporterInfoProvider, ccExporter)
}
- if library.shared() {
+ if library.dylib() {
+ // reexport whole-static'd dependencies for dylibs.
+ library.flagExporter.wholeRustRlibDeps = append(library.flagExporter.wholeRustRlibDeps, deps.reexportedWholeCcRlibDeps...)
+ }
+
+ if library.shared() || library.stubs() {
// Optimize out relinking against shared libraries whose interface hasn't changed by
// depending on a table of contents file instead of the library itself.
tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.SharedLibSuffix()[1:]+".toc")
@@ -609,9 +765,7 @@
TableOfContents: android.OptionalPathForPath(tocFile),
SharedLibrary: outputFile,
Target: ctx.Target(),
- // TODO: when rust supports stubs uses the stubs state rather than inferring it from
- // apex_exclude.
- IsStubs: Bool(library.Properties.Apex_exclude),
+ IsStubs: library.BuildStubs(),
})
}
@@ -623,8 +777,10 @@
TransitiveStaticLibrariesForOrdering: depSet,
})
}
+ cc.AddStubDependencyProviders(ctx)
- library.flagExporter.setProvider(ctx)
+ // Set our flagexporter provider to export relevant Rust flags
+ library.flagExporter.setRustProvider(ctx)
return ret
}
@@ -642,6 +798,53 @@
}
}
+func (library *libraryDecorator) getApiStubsCcFlags(ctx ModuleContext) cc.Flags {
+ ccFlags := cc.Flags{}
+ toolchain := cc_config.FindToolchain(ctx.Os(), ctx.Arch())
+
+ platformSdkVersion := ""
+ if ctx.Device() {
+ platformSdkVersion = ctx.Config().PlatformSdkVersion().String()
+ }
+ minSdkVersion := cc.MinSdkVersion(ctx.RustModule(), cc.CtxIsForPlatform(ctx), ctx.Device(), platformSdkVersion)
+
+ // Collect common CC compilation flags
+ ccFlags = cc.CommonLinkerFlags(ctx, ccFlags, true, toolchain, false)
+ ccFlags = cc.CommonLibraryLinkerFlags(ctx, ccFlags, toolchain, library.getStem(ctx))
+ ccFlags = cc.AddStubLibraryCompilerFlags(ccFlags)
+ ccFlags = cc.AddTargetFlags(ctx, ccFlags, toolchain, minSdkVersion, false)
+
+ return ccFlags
+}
+
+func (library *libraryDecorator) compileModuleLibApiStubs(ctx ModuleContext, ccFlags cc.Flags) cc.Objects {
+ mod := ctx.RustModule()
+
+ symbolFile := String(library.Properties.Stubs.Symbol_file)
+ library.stubsSymbolFilePath = android.PathForModuleSrc(ctx, symbolFile)
+
+ apiParams := cc.ApiStubsParams{
+ NotInPlatform: mod.NotInPlatform(),
+ IsNdk: mod.IsNdk(ctx.Config()),
+ BaseModuleName: mod.BaseModuleName(),
+ ModuleName: ctx.ModuleName(),
+ }
+ flag := cc.GetApiStubsFlags(apiParams)
+
+ nativeAbiResult := cc.ParseNativeAbiDefinition(ctx, symbolFile,
+ android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), flag)
+ objs := cc.CompileStubLibrary(ctx, ccFlags, nativeAbiResult.StubSrc, mod.getSharedFlags())
+
+ library.versionScriptPath = android.OptionalPathForPath(nativeAbiResult.VersionScript)
+
+ // Parse symbol file to get API list for coverage
+ if library.StubsVersion() == "current" && ctx.PrimaryArch() && !mod.InRecovery() && !mod.InProduct() && !mod.InVendor() {
+ library.apiListCoverageXmlPath = cc.ParseSymbolFileForAPICoverage(ctx, symbolFile)
+ }
+
+ return objs
+}
+
func (library *libraryDecorator) rustdoc(ctx ModuleContext, flags Flags,
deps PathDeps) android.OptionalPath {
// rustdoc has builtin support for documenting config specific information
@@ -679,6 +882,20 @@
library.MutatedProperties.VariantIsDisabled = true
}
+func (library *libraryDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) {
+ library.baseCompiler.moduleInfoJSON(ctx, moduleInfoJSON)
+
+ if library.rlib() {
+ moduleInfoJSON.Class = []string{"RLIB_LIBRARIES"}
+ } else if library.dylib() {
+ moduleInfoJSON.Class = []string{"DYLIB_LIBRARIES"}
+ } else if library.static() {
+ moduleInfoJSON.Class = []string{"STATIC_LIBRARIES"}
+ } else if library.shared() {
+ moduleInfoJSON.Class = []string{"SHARED_LIBRARIES"}
+ }
+}
+
var validCrateName = regexp.MustCompile("[^a-zA-Z0-9_]+")
func validateLibraryStem(ctx BaseModuleContext, filename string, crate_name string) {
@@ -737,6 +954,9 @@
}
func (libraryTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
+ if ctx.DepTag() == android.PrebuiltDepTag {
+ return sourceVariation
+ }
return ""
}
@@ -804,6 +1024,12 @@
},
sourceDepTag, ctx.ModuleName())
}
+
+ if prebuilt, ok := m.compiler.(*prebuiltLibraryDecorator); ok {
+ if Bool(prebuilt.Properties.Force_use_prebuilt) && len(prebuilt.prebuiltSrcs()) > 0 {
+ m.Prebuilt().SetUsePrebuilt(true)
+ }
+ }
}
type libstdTransitionMutator struct{}
@@ -821,6 +1047,9 @@
}
func (libstdTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
+ if ctx.DepTag() == android.PrebuiltDepTag {
+ return sourceVariation
+ }
return ""
}
diff --git a/rust/library_test.go b/rust/library_test.go
index e5fd5e0..6db9525 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -42,10 +42,10 @@
}`)
// Test all variants are being built.
- libfooRlib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc")
- libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
- libfooFFIRlib := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc")
- libfooShared := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_shared").Rule("rustc")
+ libfooRlib := ctx.ModuleForTests(t, "libfoo", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc")
+ libfooDylib := ctx.ModuleForTests(t, "libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
+ libfooFFIRlib := ctx.ModuleForTests(t, "libfoo.ffi", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc")
+ libfooShared := ctx.ModuleForTests(t, "libfoo.ffi", "linux_glibc_x86_64_shared").Rule("rustc")
rlibCrateType := "rlib"
dylibCrateType := "dylib"
@@ -82,7 +82,7 @@
crate_name: "foo",
}`)
- libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
+ libfooDylib := ctx.ModuleForTests(t, "libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
if !strings.Contains(libfooDylib.Args["rustcFlags"], "prefer-dynamic") {
t.Errorf("missing prefer-dynamic flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
@@ -134,7 +134,7 @@
crate_name: "foo",
}`)
- libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared")
+ libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared")
libfooOutput := libfoo.Rule("rustc")
if !strings.Contains(libfooOutput.Args["linkFlags"], "-Wl,-soname=libfoo.so") {
@@ -160,7 +160,7 @@
shared_libs: ["libfoo"],
}`)
- fizzbuzz := ctx.ModuleForTests("fizzbuzz", "android_arm64_armv8-a").Rule("ld")
+ fizzbuzz := ctx.ModuleForTests(t, "fizzbuzz", "android_arm64_armv8-a").Rule("ld")
if !android.SuffixInList(fizzbuzz.Implicits.Strings(), "libfoo.so.toc") {
t.Errorf("missing expected libfoo.so.toc implicit dependency, instead found: %#v",
@@ -176,7 +176,7 @@
crate_name: "foo",
}`)
- libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_rlib_rlib-std")
+ libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_rlib_rlib-std")
if !android.InList("libstd", libfoo.Module().(*Module).Properties.AndroidMkRlibs) {
t.Errorf("Static libstd rlib expected to be a dependency of Rust rlib libraries. Rlib deps are: %#v",
@@ -209,9 +209,9 @@
}
`)
- rustRlibRlibStd := ctx.ModuleForTests("librust_rlib", "android_arm64_armv8-a_rlib_rlib-std")
- rustRlibDylibStd := ctx.ModuleForTests("librust_rlib", "android_arm64_armv8-a_rlib_dylib-std")
- ffiRlib := ctx.ModuleForTests("libffi_static", "android_arm64_armv8-a_rlib_rlib-std")
+ rustRlibRlibStd := ctx.ModuleForTests(t, "librust_rlib", "android_arm64_armv8-a_rlib_rlib-std")
+ rustRlibDylibStd := ctx.ModuleForTests(t, "librust_rlib", "android_arm64_armv8-a_rlib_dylib-std")
+ ffiRlib := ctx.ModuleForTests(t, "libffi_static", "android_arm64_armv8-a_rlib_rlib-std")
modules := []android.TestingModule{
rustRlibRlibStd,
@@ -285,10 +285,10 @@
],
}`)
- libfooRlib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_rlib_rlib-std")
- libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib")
- libfooFFIRlib := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_rlib_rlib-std")
- libfooShared := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_shared")
+ libfooRlib := ctx.ModuleForTests(t, "libfoo", "linux_glibc_x86_64_rlib_rlib-std")
+ libfooDylib := ctx.ModuleForTests(t, "libfoo", "linux_glibc_x86_64_dylib")
+ libfooFFIRlib := ctx.ModuleForTests(t, "libfoo.ffi", "linux_glibc_x86_64_rlib_rlib-std")
+ libfooShared := ctx.ModuleForTests(t, "libfoo.ffi", "linux_glibc_x86_64_shared")
for _, static := range []android.TestingModule{libfooRlib, libfooFFIRlib} {
if !android.InList("libbar.rlib-std", static.Module().(*Module).Properties.AndroidMkRlibs) {
@@ -330,7 +330,7 @@
}
`)
- foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib")
+ foo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_dylib")
foo.Output("libfoo.dylib.so")
foo.Output("unstripped/libfoo.dylib.so")
// Check that the `cp` rule is using the stripped version as input.
@@ -339,7 +339,7 @@
t.Errorf("installed library not based on stripped version: %v", cp.Input)
}
- fizzBar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeOutput("unstripped/libbar.dylib.so")
+ fizzBar := ctx.ModuleForTests(t, "libbar", "android_arm64_armv8-a_dylib").MaybeOutput("unstripped/libbar.dylib.so")
if fizzBar.Rule != nil {
t.Errorf("unstripped library exists, so stripped library has incorrectly been generated")
}
@@ -372,15 +372,15 @@
prefer_rlib: true,
}`)
- libfooDylib := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").Module().(*Module)
- libfooRlibStatic := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_rlib_rlib-std").Module().(*Module)
- libfooRlibDynamic := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_rlib_dylib-std").Module().(*Module)
+ libfooDylib := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_dylib").Module().(*Module)
+ libfooRlibStatic := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_rlib_rlib-std").Module().(*Module)
+ libfooRlibDynamic := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_rlib_dylib-std").Module().(*Module)
- libbarShared := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module().(*Module)
- libbarFFIRlib := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_rlib_rlib-std").Module().(*Module)
+ libbarShared := ctx.ModuleForTests(t, "libbar", "android_arm64_armv8-a_shared").Module().(*Module)
+ libbarFFIRlib := ctx.ModuleForTests(t, "libbar", "android_arm64_armv8-a_rlib_rlib-std").Module().(*Module)
// prefer_rlib works the same for both rust_library and rust_ffi, so a single check is sufficient here.
- libbarRlibStd := ctx.ModuleForTests("libbar.prefer_rlib", "android_arm64_armv8-a_shared").Module().(*Module)
+ libbarRlibStd := ctx.ModuleForTests(t, "libbar.prefer_rlib", "android_arm64_armv8-a_shared").Module().(*Module)
if !android.InList("libstd", libfooRlibStatic.Properties.AndroidMkRlibs) {
t.Errorf("rlib-std variant for device rust_library_rlib does not link libstd as an rlib")
@@ -422,7 +422,7 @@
shared_libs: ["libbar"],
host_supported: true,
}`)
- libfooStatic := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_static").Rule("cc")
+ libfooStatic := ctx.ModuleForTests(t, "libfoo", "linux_glibc_x86_64_static").Rule("cc")
android.AssertStringDoesContain(t, "cFlags for lib module", libfooStatic.Args["cFlags"], " -Irust_includes ")
}
@@ -443,8 +443,8 @@
`)
//linkFlags
- librs := ctx.ModuleForTests("librs", "android_arm64_armv8-a_dylib").Rule("rustc")
- libffi := ctx.ModuleForTests("libffi", "android_arm64_armv8-a_shared").Rule("rustc")
+ librs := ctx.ModuleForTests(t, "librs", "android_arm64_armv8-a_dylib").Rule("rustc")
+ libffi := ctx.ModuleForTests(t, "libffi", "android_arm64_armv8-a_shared").Rule("rustc")
if !strings.Contains(librs.Args["linkFlags"], "-Wl,--version-script=librs.map.txt") {
t.Errorf("missing expected -Wl,--version-script= linker flag for libextended shared lib, linkFlags: %#v",
@@ -482,3 +482,289 @@
extra_exported_symbols: "libbar.map.txt",
}`)
}
+
+func TestStubsVersions(t *testing.T) {
+ t.Parallel()
+ bp := `
+ rust_ffi {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.rs"],
+ stubs: {
+ versions: ["29", "R", "current"],
+ },
+ }
+ `
+ ctx := android.GroupFixturePreparers(
+ prepareForRustTest,
+ android.PrepareForTestWithVisibility,
+ rustMockedFiles.AddToFixture(),
+ android.FixtureModifyConfigAndContext(func(config android.Config, ctx *android.TestContext) {
+ config.TestProductVariables.Platform_version_active_codenames = []string{"R"}
+ })).RunTestWithBp(t, bp)
+
+ variants := ctx.ModuleVariantsForTests("libfoo")
+ for _, expectedVer := range []string{"29", "R", "current"} {
+ expectedVariant := "android_arm_armv7-a-neon_shared_" + expectedVer
+ if !android.InList(expectedVariant, variants) {
+ t.Errorf("missing expected variant: %q", expectedVariant)
+ }
+ }
+}
+
+func TestStubsVersions_NotSorted(t *testing.T) {
+ t.Parallel()
+ bp := `
+ rust_ffi_shared {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.rs"],
+ stubs: {
+ versions: ["29", "current", "R"],
+ },
+ }
+ `
+ fixture := android.GroupFixturePreparers(
+ prepareForRustTest,
+ android.PrepareForTestWithVisibility,
+ rustMockedFiles.AddToFixture(),
+
+ android.FixtureModifyConfigAndContext(func(config android.Config, ctx *android.TestContext) {
+ config.TestProductVariables.Platform_version_active_codenames = []string{"R"}
+ }))
+
+ fixture.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(`"libfoo" .*: versions: not sorted`)).RunTestWithBp(t, bp)
+}
+
+func TestStubsVersions_ParseError(t *testing.T) {
+ t.Parallel()
+ bp := `
+ rust_ffi_shared {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.rs"],
+ stubs: {
+ versions: ["29", "current", "X"],
+ },
+ }
+ `
+ fixture := android.GroupFixturePreparers(
+ prepareForRustTest,
+ android.PrepareForTestWithVisibility,
+ rustMockedFiles.AddToFixture(),
+
+ android.FixtureModifyConfigAndContext(func(config android.Config, ctx *android.TestContext) {
+ config.TestProductVariables.Platform_version_active_codenames = []string{"R"}
+ }))
+
+ fixture.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(`"libfoo" .*: versions: "X" could not be parsed as an integer and is not a recognized codename`)).RunTestWithBp(t, bp)
+}
+
+func TestVersionedStubs(t *testing.T) {
+ t.Parallel()
+ bp := `
+ rust_ffi_shared {
+ name: "libFoo",
+ crate_name: "Foo",
+ srcs: ["foo.rs"],
+ stubs: {
+ symbol_file: "foo.map.txt",
+ versions: ["1", "2", "3"],
+ },
+ }
+
+ cc_library_shared {
+ name: "libBar",
+ srcs: ["bar.c"],
+ shared_libs: ["libFoo#1"],
+ }
+
+ rust_library {
+ name: "libbar_rs",
+ crate_name: "bar_rs",
+ srcs: ["bar.rs"],
+ shared_libs: ["libFoo#1"],
+ }
+ rust_ffi {
+ name: "libbar_ffi_rs",
+ crate_name: "bar_ffi_rs",
+ srcs: ["bar.rs"],
+ shared_libs: ["libFoo#1"],
+ }
+ `
+
+ ctx := android.GroupFixturePreparers(
+ prepareForRustTest,
+ android.PrepareForTestWithVisibility,
+ rustMockedFiles.AddToFixture()).RunTestWithBp(t, bp)
+
+ variants := ctx.ModuleVariantsForTests("libFoo")
+ expectedVariants := []string{
+ "android_arm64_armv8-a_shared",
+ "android_arm64_armv8-a_shared_1",
+ "android_arm64_armv8-a_shared_2",
+ "android_arm64_armv8-a_shared_3",
+ "android_arm64_armv8-a_shared_current",
+ "android_arm_armv7-a-neon_shared",
+ "android_arm_armv7-a-neon_shared_1",
+ "android_arm_armv7-a-neon_shared_2",
+ "android_arm_armv7-a-neon_shared_3",
+ "android_arm_armv7-a-neon_shared_current",
+ }
+ variantsMismatch := false
+ if len(variants) != len(expectedVariants) {
+ variantsMismatch = true
+ } else {
+ for _, v := range expectedVariants {
+ if !android.InList(v, variants) {
+ variantsMismatch = false
+ }
+ }
+ }
+ if variantsMismatch {
+ t.Errorf("variants of libFoo expected:\n")
+ for _, v := range expectedVariants {
+ t.Errorf("%q\n", v)
+ }
+ t.Errorf(", but got:\n")
+ for _, v := range variants {
+ t.Errorf("%q\n", v)
+ }
+ }
+
+ libBarLinkRule := ctx.ModuleForTests(t, "libBar", "android_arm64_armv8-a_shared").Rule("ld")
+ libBarFlags := libBarLinkRule.Args["libFlags"]
+
+ libBarRsRustcRule := ctx.ModuleForTests(t, "libbar_rs", "android_arm64_armv8-a_dylib").Rule("rustc")
+ libBarRsFlags := libBarRsRustcRule.Args["linkFlags"]
+
+ libBarFfiRsRustcRule := ctx.ModuleForTests(t, "libbar_ffi_rs", "android_arm64_armv8-a_shared").Rule("rustc")
+ libBarFfiRsFlags := libBarFfiRsRustcRule.Args["linkFlags"]
+
+ libFoo1StubPath := "libFoo/android_arm64_armv8-a_shared_1/unstripped/libFoo.so"
+ if !strings.Contains(libBarFlags, libFoo1StubPath) {
+ t.Errorf("%q is not found in %q", libFoo1StubPath, libBarFlags)
+ }
+ if !strings.Contains(libBarRsFlags, libFoo1StubPath) {
+ t.Errorf("%q is not found in %q", libFoo1StubPath, libBarRsFlags)
+ }
+ if !strings.Contains(libBarFfiRsFlags, libFoo1StubPath) {
+ t.Errorf("%q is not found in %q", libFoo1StubPath, libBarFfiRsFlags)
+ }
+}
+
+func TestCheckConflictingExplicitVersions(t *testing.T) {
+ t.Parallel()
+ bp := `
+ cc_library_shared {
+ name: "libbar",
+ srcs: ["bar.c"],
+ shared_libs: ["libfoo", "libfoo#impl"],
+ }
+
+ rust_ffi_shared {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.rs"],
+ stubs: {
+ versions: ["29", "current"],
+ },
+ }
+ `
+ fixture := android.GroupFixturePreparers(
+ prepareForRustTest,
+ android.PrepareForTestWithVisibility,
+ rustMockedFiles.AddToFixture())
+
+ fixture.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(`duplicate shared libraries with different explicit versions`)).RunTestWithBp(t, bp)
+}
+
+func TestAddnoOverride64GlobalCflags(t *testing.T) {
+ t.Parallel()
+ bp := `
+ cc_library_shared {
+ name: "libclient",
+ srcs: ["foo.c"],
+ shared_libs: ["libfoo#1"],
+ }
+
+ rust_ffi_shared {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.c"],
+ shared_libs: ["libbar"],
+ stubs: {
+ symbol_file: "foo.map.txt",
+ versions: ["1", "2", "3"],
+ },
+ }
+
+ cc_library_shared {
+ name: "libbar",
+ export_include_dirs: ["include/libbar"],
+ srcs: ["foo.c"],
+ }`
+ ctx := android.GroupFixturePreparers(
+ prepareForRustTest,
+ android.PrepareForTestWithVisibility,
+ rustMockedFiles.AddToFixture()).RunTestWithBp(t, bp)
+
+ cFlags := ctx.ModuleForTests(t, "libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
+
+ if !strings.Contains(cFlags, "${config.NoOverride64GlobalCflags}") {
+ t.Errorf("expected %q in cflags, got %q", "${config.NoOverride64GlobalCflags}", cFlags)
+ }
+}
+
+// Make sure the stubs properties can only be used in modules producing shared libs
+func TestRustStubsFFIOnly(t *testing.T) {
+ testRustError(t, "stubs properties", `
+ rust_library {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.c"],
+ shared_libs: ["libbar"],
+ stubs: {
+ symbol_file: "foo.map.txt",
+ },
+ }
+ `)
+
+ testRustError(t, "stubs properties", `
+ rust_library {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.c"],
+ shared_libs: ["libbar"],
+ stubs: {
+ versions: ["1"],
+ },
+ }
+ `)
+
+ testRustError(t, "stubs properties", `
+ rust_ffi_static {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.c"],
+ shared_libs: ["libbar"],
+ stubs: {
+ symbol_file: "foo.map.txt",
+ },
+ }
+ `)
+ testRustError(t, "stubs properties", `
+ rust_ffi_static {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.c"],
+ shared_libs: ["libbar"],
+ stubs: {
+ versions: ["1"],
+ },
+ }
+ `)
+}
+
+// TODO: When rust_ffi libraries support export_*_lib_headers,
+// add a test similar to cc.TestStubsLibReexportsHeaders
diff --git a/rust/prebuilt.go b/rust/prebuilt.go
index e35e510..7c92dda 100644
--- a/rust/prebuilt.go
+++ b/rust/prebuilt.go
@@ -30,6 +30,8 @@
Srcs []string `android:"path,arch_variant"`
// directories containing associated rlib dependencies
Link_dirs []string `android:"path,arch_variant"`
+
+ Force_use_prebuilt *bool `android:"arch_variant"`
}
type prebuiltLibraryDecorator struct {
@@ -158,7 +160,7 @@
func (prebuilt *prebuiltLibraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
prebuilt.flagExporter.exportLinkDirs(android.PathsForModuleSrc(ctx, prebuilt.Properties.Link_dirs).Strings()...)
- prebuilt.flagExporter.setProvider(ctx)
+ prebuilt.flagExporter.setRustProvider(ctx)
srcPath := prebuiltPath(ctx, prebuilt)
prebuilt.baseCompiler.unstrippedOutputFile = srcPath
return buildOutput{outputFile: srcPath}
@@ -211,7 +213,7 @@
func (prebuilt *prebuiltProcMacroDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
prebuilt.flagExporter.exportLinkDirs(android.PathsForModuleSrc(ctx, prebuilt.Properties.Link_dirs).Strings()...)
- prebuilt.flagExporter.setProvider(ctx)
+ prebuilt.flagExporter.setRustProvider(ctx)
srcPath := prebuiltPath(ctx, prebuilt)
prebuilt.baseCompiler.unstrippedOutputFile = srcPath
return buildOutput{outputFile: srcPath}
diff --git a/rust/proc_macro.go b/rust/proc_macro.go
index 28ed68b..837e1a6 100644
--- a/rust/proc_macro.go
+++ b/rust/proc_macro.go
@@ -100,3 +100,9 @@
// Proc_macros are never installed
return false
}
+
+func (library *procMacroDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) {
+ library.baseCompiler.moduleInfoJSON(ctx, moduleInfoJSON)
+
+ moduleInfoJSON.Class = []string{"PROC_MACRO_LIBRARIES"}
+}
diff --git a/rust/proc_macro_test.go b/rust/proc_macro_test.go
index cc81938..8a95eb4 100644
--- a/rust/proc_macro_test.go
+++ b/rust/proc_macro_test.go
@@ -28,7 +28,7 @@
}
`)
- libprocmacro := ctx.ModuleForTests("libprocmacro", "linux_glibc_x86_64").Rule("rustc")
+ libprocmacro := ctx.ModuleForTests(t, "libprocmacro", "linux_glibc_x86_64").Rule("rustc")
if !strings.Contains(libprocmacro.Args["rustcFlags"], "--extern proc_macro") {
t.Errorf("--extern proc_macro flag not being passed to rustc for proc macro %#v", libprocmacro.Args["rustcFlags"])
diff --git a/rust/protobuf_test.go b/rust/protobuf_test.go
index cae071b..531e034 100644
--- a/rust/protobuf_test.go
+++ b/rust/protobuf_test.go
@@ -41,13 +41,13 @@
}
`)
// Check that libprotobuf is added as a dependency.
- librust_proto := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_dylib").Module().(*Module)
+ librust_proto := ctx.ModuleForTests(t, "librust_proto", "android_arm64_armv8-a_dylib").Module().(*Module)
if !android.InList("libprotobuf", librust_proto.Properties.AndroidMkDylibs) {
t.Errorf("libprotobuf dependency missing for rust_protobuf (dependency missing from AndroidMkDylibs)")
}
// Make sure the correct plugin is being used.
- librust_proto_out := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_source").Output("buf.rs")
+ librust_proto_out := ctx.ModuleForTests(t, "librust_proto", "android_arm64_armv8-a_source").Output("buf.rs")
cmd := librust_proto_out.RuleParams.Command
if w := "protoc-gen-rust"; !strings.Contains(cmd, w) {
t.Errorf("expected %q in %q", w, cmd)
@@ -62,7 +62,7 @@
}
// Check proto.rs, the second protobuf, is listed as an output
- librust_proto_outputs := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_source").AllOutputs()
+ librust_proto_outputs := ctx.ModuleForTests(t, "librust_proto", "android_arm64_armv8-a_source").AllOutputs()
if android.InList("proto.rs", librust_proto_outputs) {
t.Errorf("rust_protobuf is not producing multiple outputs; expected 'proto.rs' in list, got: %#v ",
librust_proto_outputs)
@@ -92,7 +92,7 @@
}
`)
// Check that librust_exported_proto is added as additional crate to generate source.
- librust_proto := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_source").Module().(*Module).sourceProvider.(*protobufDecorator)
+ librust_proto := ctx.ModuleForTests(t, "librust_proto", "android_arm64_armv8-a_source").Module().(*Module).sourceProvider.(*protobufDecorator)
if !android.InList("rust_exported_proto", librust_proto.additionalCrates) {
t.Errorf("librust_proto should have librust_exported_proto included as an additional crate for generated source, instead got: %#v", librust_proto.additionalCrates)
}
@@ -111,7 +111,7 @@
}
// Check librust_proto args includes -Iproto
- librust_proto_rule := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_source").Output("proto.rs")
+ librust_proto_rule := ctx.ModuleForTests(t, "librust_proto", "android_arm64_armv8-a_source").Output("proto.rs")
cmd := librust_proto_rule.RuleParams.Command
if w := "-Iproto"; !strings.Contains(cmd, w) {
t.Errorf("expected %q in %q", w, cmd)
@@ -131,7 +131,7 @@
`)
// Check that libprotobuf is added as a dependency.
- librust_grpcio_module := ctx.ModuleForTests("librust_grpcio", "android_arm64_armv8-a_dylib").Module().(*Module)
+ librust_grpcio_module := ctx.ModuleForTests(t, "librust_grpcio", "android_arm64_armv8-a_dylib").Module().(*Module)
// Check that libgrpcio is added as a dependency.
if !android.InList("libgrpcio", librust_grpcio_module.Properties.AndroidMkDylibs) {
@@ -144,7 +144,7 @@
}
// Make sure the correct plugin is being used.
- librust_grpcio_out := ctx.ModuleForTests("librust_grpcio", "android_arm64_armv8-a_source").Output("foo_grpc.rs")
+ librust_grpcio_out := ctx.ModuleForTests(t, "librust_grpcio", "android_arm64_armv8-a_source").Output("foo_grpc.rs")
cmd := librust_grpcio_out.RuleParams.Command
if w := "protoc-gen-grpc"; !strings.Contains(cmd, w) {
t.Errorf("expected %q in %q", w, cmd)
@@ -156,7 +156,7 @@
}
// Check proto.rs, the second protobuf, is listed as an output
- librust_grpcio_outputs := ctx.ModuleForTests("librust_grpcio", "android_arm64_armv8-a_source").AllOutputs()
+ librust_grpcio_outputs := ctx.ModuleForTests(t, "librust_grpcio", "android_arm64_armv8-a_source").AllOutputs()
if android.InList("proto_grpc.rs", librust_grpcio_outputs) {
t.Errorf("rust_protobuf is not producing multiple outputs; expected 'proto_grpc.rs' in list, got: %#v ",
librust_grpcio_outputs)
diff --git a/rust/rust.go b/rust/rust.go
index ba6e293..4eebda3 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -49,6 +49,7 @@
type ProtobufDecoratorInfo struct{}
type SourceProviderInfo struct {
+ Srcs android.Paths
ProtobufDecoratorInfo *ProtobufDecoratorInfo
}
@@ -162,9 +163,36 @@
// Make this module available when building for recovery
Recovery_available *bool
- // Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
+ // The API level that this module is built against. The APIs of this API level will be
+ // visible at build time, but use of any APIs newer than min_sdk_version will render the
+ // module unloadable on older devices. In the future it will be possible to weakly-link new
+ // APIs, making the behavior match Java: such modules will load on older devices, but
+ // calling new APIs on devices that do not support them will result in a crash.
+ //
+ // This property has the same behavior as sdk_version does for Java modules. For those
+ // familiar with Android Gradle, the property behaves similarly to how compileSdkVersion
+ // does for Java code.
+ //
+ // In addition, setting this property causes two variants to be built, one for the platform
+ // and one for apps.
+ Sdk_version *string
+
+ // Minimum OS API level supported by this C or C++ module. This property becomes the value
+ // of the __ANDROID_API__ macro. When the C or C++ module is included in an APEX or an APK,
+ // this property is also used to ensure that the min_sdk_version of the containing module is
+ // not older (i.e. less) than this module's min_sdk_version. When not set, this property
+ // defaults to the value of sdk_version. When this is set to "apex_inherit", this tracks
+ // min_sdk_version of the containing APEX. When the module
+ // is not built for an APEX, "apex_inherit" defaults to sdk_version.
Min_sdk_version *string
+ // Variant is an SDK variant created by sdkMutator
+ IsSdkVariant bool `blueprint:"mutated"`
+
+ // Set by factories of module types that can only be referenced from variants compiled against
+ // the SDK.
+ AlwaysSdk bool `blueprint:"mutated"`
+
HideFromMake bool `blueprint:"mutated"`
PreventInstall bool `blueprint:"mutated"`
@@ -209,6 +237,9 @@
apexSdkVersion android.ApiLevel
transitiveAndroidMkSharedLibs depset.DepSet[string]
+
+ // Shared flags among stubs build rules of this module
+ sharedFlags cc.SharedFlags
}
func (mod *Module) Header() bool {
@@ -374,7 +405,8 @@
}
func (mod *Module) IsVendorPublicLibrary() bool {
- return mod.VendorProperties.IsVendorPublicLibrary
+ // Rust modules do not currently support vendor_public_library
+ return false
}
func (mod *Module) SdkAndPlatformVariantVisibleToMake() bool {
@@ -383,10 +415,12 @@
}
func (c *Module) IsVndkPrivate() bool {
+ // Rust modules do not currently support VNDK variants
return false
}
func (c *Module) IsLlndk() bool {
+ // Rust modules do not currently support LLNDK variants
return false
}
@@ -395,35 +429,34 @@
}
func (m *Module) NeedsLlndkVariants() bool {
+ // Rust modules do not currently support LLNDK variants
return false
}
func (m *Module) NeedsVendorPublicLibraryVariants() bool {
+ // Rust modules do not currently support vendor_public_library
return false
}
func (mod *Module) HasLlndkStubs() bool {
+ // Rust modules do not currently support LLNDK stubs
return false
}
-func (mod *Module) StubsVersion() string {
- panic(fmt.Errorf("StubsVersion called on non-versioned module: %q", mod.BaseModuleName()))
-}
-
func (mod *Module) SdkVersion() string {
- return ""
+ return String(mod.Properties.Sdk_version)
}
func (mod *Module) AlwaysSdk() bool {
- return false
+ return mod.Properties.AlwaysSdk
}
func (mod *Module) IsSdkVariant() bool {
- return false
+ return mod.Properties.IsSdkVariant
}
func (mod *Module) SplitPerApiLevel() bool {
- return false
+ return cc.CanUseSdk(mod) && mod.IsCrt()
}
func (mod *Module) XrefRustFiles() android.Paths {
@@ -462,10 +495,18 @@
depFlags []string
depLinkFlags []string
+ // track cc static-libs that have Rlib dependencies
+ reexportedCcRlibDeps []cc.RustRlibDep
+ reexportedWholeCcRlibDeps []cc.RustRlibDep
+ ccRlibDeps []cc.RustRlibDep
+
// linkDirs are link paths passed via -L to rustc. linkObjects are objects passed directly to the linker
// Both of these are exported and propagate to dependencies.
- linkDirs []string
- linkObjects []string
+ linkDirs []string
+ rustLibObjects []string
+ staticLibObjects []string
+ wholeStaticLibObjects []string
+ sharedLibObjects []string
// exportedLinkDirs are exported linkDirs for direct rlib dependencies to
// cc_library_static dependants of rlibs.
@@ -498,7 +539,10 @@
type exportedFlagsProducer interface {
exportLinkDirs(...string)
- exportLinkObjects(...string)
+ exportRustLibs(...string)
+ exportStaticLibs(...string)
+ exportWholeStaticLibs(...string)
+ exportSharedLibs(...string)
}
type xref interface {
@@ -506,23 +550,43 @@
}
type flagExporter struct {
- linkDirs []string
- ccLinkDirs []string
- linkObjects []string
+ linkDirs []string
+ ccLinkDirs []string
+ rustLibPaths []string
+ staticLibObjects []string
+ sharedLibObjects []string
+ wholeStaticLibObjects []string
+ wholeRustRlibDeps []cc.RustRlibDep
}
func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) {
flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...))
}
-func (flagExporter *flagExporter) exportLinkObjects(flags ...string) {
- flagExporter.linkObjects = android.FirstUniqueStrings(append(flagExporter.linkObjects, flags...))
+func (flagExporter *flagExporter) exportRustLibs(flags ...string) {
+ flagExporter.rustLibPaths = android.FirstUniqueStrings(append(flagExporter.rustLibPaths, flags...))
}
-func (flagExporter *flagExporter) setProvider(ctx ModuleContext) {
- android.SetProvider(ctx, FlagExporterInfoProvider, FlagExporterInfo{
- LinkDirs: flagExporter.linkDirs,
- LinkObjects: flagExporter.linkObjects,
+func (flagExporter *flagExporter) exportStaticLibs(flags ...string) {
+ flagExporter.staticLibObjects = android.FirstUniqueStrings(append(flagExporter.staticLibObjects, flags...))
+}
+
+func (flagExporter *flagExporter) exportSharedLibs(flags ...string) {
+ flagExporter.sharedLibObjects = android.FirstUniqueStrings(append(flagExporter.sharedLibObjects, flags...))
+}
+
+func (flagExporter *flagExporter) exportWholeStaticLibs(flags ...string) {
+ flagExporter.wholeStaticLibObjects = android.FirstUniqueStrings(append(flagExporter.wholeStaticLibObjects, flags...))
+}
+
+func (flagExporter *flagExporter) setRustProvider(ctx ModuleContext) {
+ android.SetProvider(ctx, RustFlagExporterInfoProvider, RustFlagExporterInfo{
+ LinkDirs: flagExporter.linkDirs,
+ RustLibObjects: flagExporter.rustLibPaths,
+ StaticLibObjects: flagExporter.staticLibObjects,
+ WholeStaticLibObjects: flagExporter.wholeStaticLibObjects,
+ SharedLibPaths: flagExporter.sharedLibObjects,
+ WholeRustRlibDeps: flagExporter.wholeRustRlibDeps,
})
}
@@ -532,13 +596,17 @@
return &flagExporter{}
}
-type FlagExporterInfo struct {
- Flags []string
- LinkDirs []string // TODO: this should be android.Paths
- LinkObjects []string // TODO: this should be android.Paths
+type RustFlagExporterInfo struct {
+ Flags []string
+ LinkDirs []string
+ RustLibObjects []string
+ StaticLibObjects []string
+ WholeStaticLibObjects []string
+ SharedLibPaths []string
+ WholeRustRlibDeps []cc.RustRlibDep
}
-var FlagExporterInfoProvider = blueprint.NewProvider[FlagExporterInfo]()
+var RustFlagExporterInfoProvider = blueprint.NewProvider[RustFlagExporterInfo]()
func (mod *Module) isCoverageVariant() bool {
return mod.coverage.Properties.IsCoverageVariant
@@ -561,6 +629,9 @@
func (mod *Module) PreventInstall() bool {
return mod.Properties.PreventInstall
}
+func (c *Module) ForceDisableSanitizers() {
+ c.sanitize.Properties.ForceDisable = true
+}
func (mod *Module) MarkAsCoverageVariant(coverage bool) {
mod.coverage.Properties.IsCoverageVariant = coverage
@@ -743,11 +814,51 @@
return false
}
-func (mod *Module) HasStubsVariants() bool {
+func (mod *Module) IsStubs() bool {
+ if lib, ok := mod.compiler.(libraryInterface); ok {
+ return lib.BuildStubs()
+ }
return false
}
-func (mod *Module) IsStubs() bool {
+func (mod *Module) HasStubsVariants() bool {
+ if lib, ok := mod.compiler.(libraryInterface); ok {
+ return lib.HasStubsVariants()
+ }
+ return false
+}
+
+func (mod *Module) ApexSdkVersion() android.ApiLevel {
+ return mod.apexSdkVersion
+}
+
+func (mod *Module) RustApexExclude() bool {
+ return mod.ApexExclude()
+}
+
+func (mod *Module) getSharedFlags() *cc.SharedFlags {
+ shared := &mod.sharedFlags
+ if shared.FlagsMap == nil {
+ shared.NumSharedFlags = 0
+ shared.FlagsMap = make(map[string]string)
+ }
+ return shared
+}
+
+func (mod *Module) ImplementationModuleNameForMake() string {
+ name := mod.BaseModuleName()
+ if versioned, ok := mod.compiler.(cc.VersionedInterface); ok {
+ name = versioned.ImplementationModuleName(name)
+ }
+ return name
+}
+
+func (mod *Module) Multilib() string {
+ return mod.Arch().ArchType.Multilib
+}
+
+func (mod *Module) IsCrt() bool {
+ // Rust does not currently provide any crt modules.
return false
}
@@ -771,6 +882,7 @@
}
var _ cc.LinkableInterface = (*Module)(nil)
+var _ cc.VersionedLinkableInterface = (*Module)(nil)
func (mod *Module) Init() android.Module {
mod.AddProperties(&mod.Properties)
@@ -881,6 +993,25 @@
return mod.compiler != nil && mod.compiler.nativeCoverage()
}
+func (mod *Module) SetStl(s string) {
+ // STL is a CC concept; do nothing for Rust
+}
+
+func (mod *Module) SetSdkVersion(s string) {
+ mod.Properties.Sdk_version = StringPtr(s)
+}
+
+func (mod *Module) SetMinSdkVersion(s string) {
+ mod.Properties.Min_sdk_version = StringPtr(s)
+}
+
+func (mod *Module) VersionedInterface() cc.VersionedInterface {
+ if _, ok := mod.compiler.(cc.VersionedInterface); ok {
+ return mod.compiler.(cc.VersionedInterface)
+ }
+ return nil
+}
+
func (mod *Module) EverInstallable() bool {
return mod.compiler != nil &&
// Check to see whether the module is actually ever installable.
@@ -970,9 +1101,9 @@
mod.sourceProvider.GenerateSource(ctx, deps)
mod.sourceProvider.setSubName(ctx.ModuleSubDir())
} else {
- sourceMod := actx.GetDirectDepWithTag(mod.Name(), sourceDepTag)
- sourceLib := sourceMod.(*Module).compiler.(*libraryDecorator)
- mod.sourceProvider.setOutputFiles(sourceLib.sourceProvider.Srcs())
+ sourceMod := actx.GetDirectDepProxyWithTag(mod.Name(), sourceDepTag)
+ sourceLib := android.OtherModuleProviderOrDefault(ctx, sourceMod, RustInfoProvider).SourceProviderInfo
+ mod.sourceProvider.setOutputFiles(sourceLib.Srcs)
}
ctx.CheckbuildFile(mod.sourceProvider.Srcs()...)
}
@@ -1025,11 +1156,15 @@
ctx.Phony("rust", ctx.RustModule().OutputFile().Path())
}
- linkableInfo := cc.CreateCommonLinkableInfo(mod)
+ linkableInfo := cc.CreateCommonLinkableInfo(ctx, mod)
linkableInfo.Static = mod.Static()
linkableInfo.Shared = mod.Shared()
linkableInfo.CrateName = mod.CrateName()
linkableInfo.ExportedCrateLinkDirs = mod.ExportedCrateLinkDirs()
+ if lib, ok := mod.compiler.(cc.VersionedInterface); ok {
+ linkableInfo.StubsVersion = lib.StubsVersion()
+ }
+
android.SetProvider(ctx, cc.LinkableInfoProvider, linkableInfo)
rustInfo := &RustInfo{
@@ -1056,17 +1191,39 @@
}
}
if mod.sourceProvider != nil {
+ rustInfo.SourceProviderInfo = &SourceProviderInfo{
+ Srcs: mod.sourceProvider.Srcs(),
+ }
if _, ok := mod.sourceProvider.(*protobufDecorator); ok {
- rustInfo.SourceProviderInfo = &SourceProviderInfo{
- ProtobufDecoratorInfo: &ProtobufDecoratorInfo{},
- }
+ rustInfo.SourceProviderInfo.ProtobufDecoratorInfo = &ProtobufDecoratorInfo{}
}
}
android.SetProvider(ctx, RustInfoProvider, rustInfo)
+ ccInfo := &cc.CcInfo{
+ IsPrebuilt: mod.IsPrebuilt(),
+ }
+
+ // Define the linker info if compiler != nil because Rust currently
+ // does compilation and linking in one step. If this changes in the future,
+ // move this as appropriate.
+ baseCompilerProps := mod.compiler.baseCompilerProps()
+ ccInfo.LinkerInfo = &cc.LinkerInfo{
+ WholeStaticLibs: baseCompilerProps.Whole_static_libs.GetOrDefault(ctx, nil),
+ StaticLibs: baseCompilerProps.Static_libs.GetOrDefault(ctx, nil),
+ SharedLibs: baseCompilerProps.Shared_libs.GetOrDefault(ctx, nil),
+ }
+
+ android.SetProvider(ctx, cc.CcInfoProvider, ccInfo)
+
mod.setOutputFiles(ctx)
buildComplianceMetadataInfo(ctx, mod, deps)
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ if mod.compiler != nil {
+ mod.compiler.moduleInfoJSON(ctx, moduleInfoJSON)
+ }
}
func (mod *Module) setOutputFiles(ctx ModuleContext) {
@@ -1089,12 +1246,12 @@
metadataInfo.SetStringValue(android.ComplianceMetadataProp.BUILT_FILES, mod.outputFile.String())
// Static libs
- staticDeps := ctx.GetDirectDepsWithTag(rlibDepTag)
+ staticDeps := ctx.GetDirectDepsProxyWithTag(rlibDepTag)
staticDepNames := make([]string, 0, len(staticDeps))
for _, dep := range staticDeps {
staticDepNames = append(staticDepNames, dep.Name())
}
- ccStaticDeps := ctx.GetDirectDepsWithTag(cc.StaticDepTag(false))
+ ccStaticDeps := ctx.GetDirectDepsProxyWithTag(cc.StaticDepTag(false))
for _, dep := range ccStaticDeps {
staticDepNames = append(staticDepNames, dep.Name())
}
@@ -1112,7 +1269,7 @@
metadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEP_FILES, android.FirstUniqueStrings(staticDepPaths))
// C Whole static libs
- ccWholeStaticDeps := ctx.GetDirectDepsWithTag(cc.StaticDepTag(true))
+ ccWholeStaticDeps := ctx.GetDirectDepsProxyWithTag(cc.StaticDepTag(true))
wholeStaticDepNames := make([]string, 0, len(ccWholeStaticDeps))
for _, dep := range ccStaticDeps {
wholeStaticDepNames = append(wholeStaticDepNames, dep.Name())
@@ -1225,6 +1382,21 @@
if mod.sanitize != nil {
mod.sanitize.begin(ctx)
}
+
+ if mod.UseSdk() && mod.IsSdkVariant() {
+ sdkVersion := ""
+ if ctx.Device() {
+ sdkVersion = mod.SdkVersion()
+ }
+ version, err := cc.NativeApiLevelFromUser(ctx, sdkVersion)
+ if err != nil {
+ ctx.PropertyErrorf("sdk_version", err.Error())
+ mod.Properties.Sdk_version = nil
+ } else {
+ mod.Properties.Sdk_version = StringPtr(version.String())
+ }
+ }
+
}
func (mod *Module) Prebuilt() *android.Prebuilt {
@@ -1243,7 +1415,7 @@
if rustInfo != nil {
// Use base module name for snapshots when exporting to Makefile.
if rustInfo.SnapshotInfo != nil {
- baseName := linkableInfo.BaseModuleName
+ baseName := commonInfo.BaseModuleName
return baseName + rustInfo.SnapshotInfo.SnapshotAndroidMkSuffix + rustInfo.AndroidMkSuffix
}
}
@@ -1367,6 +1539,13 @@
}
}
+ if !mod.Rlib() {
+ depPaths.ccRlibDeps = append(depPaths.ccRlibDeps, exportedInfo.RustRlibDeps...)
+ } else {
+ // rlibs need to reexport these
+ depPaths.reexportedCcRlibDeps = append(depPaths.reexportedCcRlibDeps, exportedInfo.RustRlibDeps...)
+ }
+
case depTag == procMacroDepTag:
directProcMacroDeps = append(directProcMacroDeps, linkableInfo)
mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName)
@@ -1410,12 +1589,21 @@
directSrcProvidersDeps = append(directSrcProvidersDeps, &dep)
}
- exportedInfo, _ := android.OtherModuleProvider(ctx, dep, FlagExporterInfoProvider)
- //Append the dependencies exportedDirs, except for proc-macros which target a different arch/OS
+ exportedRustInfo, _ := android.OtherModuleProvider(ctx, dep, RustFlagExporterInfoProvider)
+ exportedInfo, _ := android.OtherModuleProvider(ctx, dep, RustFlagExporterInfoProvider)
+ //Append the dependencies exported objects, except for proc-macros which target a different arch/OS
if depTag != procMacroDepTag {
depPaths.depFlags = append(depPaths.depFlags, exportedInfo.Flags...)
- depPaths.linkObjects = append(depPaths.linkObjects, exportedInfo.LinkObjects...)
+ depPaths.rustLibObjects = append(depPaths.rustLibObjects, exportedInfo.RustLibObjects...)
+ depPaths.sharedLibObjects = append(depPaths.sharedLibObjects, exportedInfo.SharedLibPaths...)
+ depPaths.staticLibObjects = append(depPaths.staticLibObjects, exportedInfo.StaticLibObjects...)
+ depPaths.wholeStaticLibObjects = append(depPaths.wholeStaticLibObjects, exportedInfo.WholeStaticLibObjects...)
depPaths.linkDirs = append(depPaths.linkDirs, exportedInfo.LinkDirs...)
+
+ depPaths.reexportedWholeCcRlibDeps = append(depPaths.reexportedWholeCcRlibDeps, exportedRustInfo.WholeRustRlibDeps...)
+ if !mod.Rlib() {
+ depPaths.ccRlibDeps = append(depPaths.ccRlibDeps, exportedRustInfo.WholeRustRlibDeps...)
+ }
}
if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag {
@@ -1447,8 +1635,8 @@
return
}
}
- linkObject := linkableInfo.OutputFile
- if !linkObject.Valid() {
+ ccLibPath := linkableInfo.OutputFile
+ if !ccLibPath.Valid() {
if !ctx.Config().AllowMissingDependencies() {
ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName())
} else {
@@ -1457,7 +1645,7 @@
return
}
- linkPath := linkPathFromFilePath(linkObject.Path())
+ linkPath := linkPathFromFilePath(ccLibPath.Path())
exportDep := false
switch {
@@ -1466,27 +1654,47 @@
// rustc will bundle static libraries when they're passed with "-lstatic=<lib>". This will fail
// if the library is not prefixed by "lib".
if mod.Binary() {
- // Binaries may sometimes need to link whole static libraries that don't start with 'lib'.
// Since binaries don't need to 'rebundle' these like libraries and only use these for the
// final linkage, pass the args directly to the linker to handle these cases.
- depPaths.depLinkFlags = append(depPaths.depLinkFlags, []string{"-Wl,--whole-archive", linkObject.Path().String(), "-Wl,--no-whole-archive"}...)
- } else if libName, ok := libNameFromFilePath(linkObject.Path()); ok {
- depPaths.depFlags = append(depPaths.depFlags, "-lstatic="+libName)
+ depPaths.depLinkFlags = append(depPaths.depLinkFlags, []string{"-Wl,--whole-archive", ccLibPath.Path().String(), "-Wl,--no-whole-archive"}...)
+ } else if libName, ok := libNameFromFilePath(ccLibPath.Path()); ok {
+ depPaths.depFlags = append(depPaths.depFlags, "-lstatic:+whole-archive="+libName)
+ depPaths.depLinkFlags = append(depPaths.depLinkFlags, ccLibPath.Path().String())
} else {
ctx.ModuleErrorf("'%q' cannot be listed as a whole_static_library in Rust modules unless the output is prefixed by 'lib'", depName, ctx.ModuleName())
}
}
- // Add this to linkObjects to pass the library directly to the linker as well. This propagates
- // to dependencies to avoid having to redeclare static libraries for dependents of the dylib variant.
- depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String())
- depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
-
exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider)
+ if cc.IsWholeStaticLib(depTag) {
+ // Add whole staticlibs to wholeStaticLibObjects to propagate to Rust all dependents.
+ depPaths.wholeStaticLibObjects = append(depPaths.wholeStaticLibObjects, ccLibPath.String())
+
+ // We also propagate forward whole-static'd cc staticlibs with rust_ffi_rlib dependencies
+ // We don't need to check a hypothetical exportedRustInfo.WholeRustRlibDeps because we
+ // wouldn't expect a rust_ffi_rlib to be listed in `static_libs` (Soong explicitly disallows this)
+ depPaths.reexportedWholeCcRlibDeps = append(depPaths.reexportedWholeCcRlibDeps, exportedInfo.RustRlibDeps...)
+ } else {
+ // If not whole_static, add to staticLibObjects, which only propagate through rlibs to their dependents.
+ depPaths.staticLibObjects = append(depPaths.staticLibObjects, ccLibPath.String())
+
+ if mod.Rlib() {
+ // rlibs propagate their inherited rust_ffi_rlibs forward.
+ depPaths.reexportedCcRlibDeps = append(depPaths.reexportedCcRlibDeps, exportedInfo.RustRlibDeps...)
+ }
+ }
+
+ depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...)
depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...)
depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...)
+
+ if !mod.Rlib() {
+ // rlibs don't need to build the generated static library, so they don't need to track these.
+ depPaths.ccRlibDeps = append(depPaths.ccRlibDeps, exportedInfo.RustRlibDeps...)
+ }
+
directStaticLibDeps = append(directStaticLibDeps, linkableInfo)
// Record baseLibName for snapshots.
@@ -1500,16 +1708,19 @@
sharedLibraryInfo, exportedInfo := cc.ChooseStubOrImpl(ctx, dep)
if !sharedLibraryInfo.IsStubs {
- depPaths.directImplementationDeps = append(depPaths.directImplementationDeps, android.OutputFileForModule(ctx, dep, ""))
- if info, ok := android.OtherModuleProvider(ctx, dep, cc.ImplementationDepInfoProvider); ok {
- depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps)
+ // TODO(b/362509506): remove this additional check once all apex_exclude uses are switched to stubs.
+ if !linkableInfo.RustApexExclude {
+ depPaths.directImplementationDeps = append(depPaths.directImplementationDeps, android.OutputFileForModule(ctx, dep, ""))
+ if info, ok := android.OtherModuleProvider(ctx, dep, cc.ImplementationDepInfoProvider); ok {
+ depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps)
+ }
}
}
// Re-get linkObject as ChooseStubOrImpl actually tells us which
// object (either from stub or non-stub) to use.
- linkObject = android.OptionalPathForPath(sharedLibraryInfo.SharedLibrary)
- if !linkObject.Valid() {
+ ccLibPath = android.OptionalPathForPath(sharedLibraryInfo.SharedLibrary)
+ if !ccLibPath.Valid() {
if !ctx.Config().AllowMissingDependencies() {
ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName())
} else {
@@ -1517,10 +1728,10 @@
}
return
}
- linkPath = linkPathFromFilePath(linkObject.Path())
+ linkPath = linkPathFromFilePath(ccLibPath.Path())
depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
- depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String())
+ depPaths.sharedLibObjects = append(depPaths.sharedLibObjects, ccLibPath.String())
depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...)
depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...)
@@ -1539,15 +1750,15 @@
depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...)
mod.Properties.AndroidMkHeaderLibs = append(mod.Properties.AndroidMkHeaderLibs, makeLibName)
case depTag == cc.CrtBeginDepTag:
- depPaths.CrtBegin = append(depPaths.CrtBegin, linkObject.Path())
+ depPaths.CrtBegin = append(depPaths.CrtBegin, ccLibPath.Path())
case depTag == cc.CrtEndDepTag:
- depPaths.CrtEnd = append(depPaths.CrtEnd, linkObject.Path())
+ depPaths.CrtEnd = append(depPaths.CrtEnd, ccLibPath.Path())
}
- // Make sure these dependencies are propagated
+ // Make sure shared dependencies are propagated
if lib, ok := mod.compiler.(exportedFlagsProducer); ok && exportDep {
lib.exportLinkDirs(linkPath)
- lib.exportLinkObjects(linkObject.String())
+ lib.exportSharedLibs(ccLibPath.String())
}
} else {
switch {
@@ -1558,7 +1769,7 @@
}
}
- if srcDep, ok := android.OtherModuleProvider(ctx, dep, android.SourceFilesInfoKey); ok {
+ if srcDep, ok := android.OtherModuleProvider(ctx, dep, android.SourceFilesInfoProvider); ok {
if android.IsSourceDepTagWithOutputTag(depTag, "") {
// These are usually genrules which don't have per-target variants.
directSrcDeps = append(directSrcDeps, srcDep)
@@ -1630,11 +1841,18 @@
// Dedup exported flags from dependencies
depPaths.linkDirs = android.FirstUniqueStrings(depPaths.linkDirs)
- depPaths.linkObjects = android.FirstUniqueStrings(depPaths.linkObjects)
+ depPaths.rustLibObjects = android.FirstUniqueStrings(depPaths.rustLibObjects)
+ depPaths.staticLibObjects = android.FirstUniqueStrings(depPaths.staticLibObjects)
+ depPaths.wholeStaticLibObjects = android.FirstUniqueStrings(depPaths.wholeStaticLibObjects)
+ depPaths.sharedLibObjects = android.FirstUniqueStrings(depPaths.sharedLibObjects)
depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags)
depPaths.depClangFlags = android.FirstUniqueStrings(depPaths.depClangFlags)
depPaths.depIncludePaths = android.FirstUniquePaths(depPaths.depIncludePaths)
depPaths.depSystemIncludePaths = android.FirstUniquePaths(depPaths.depSystemIncludePaths)
+ depPaths.depLinkFlags = android.FirstUniqueStrings(depPaths.depLinkFlags)
+ depPaths.reexportedCcRlibDeps = android.FirstUniqueFunc(depPaths.reexportedCcRlibDeps, cc.EqRustRlibDeps)
+ depPaths.reexportedWholeCcRlibDeps = android.FirstUniqueFunc(depPaths.reexportedWholeCcRlibDeps, cc.EqRustRlibDeps)
+ depPaths.ccRlibDeps = android.FirstUniqueFunc(depPaths.ccRlibDeps, cc.EqRustRlibDeps)
return depPaths
}
@@ -1870,7 +2088,7 @@
var _ android.ApexModule = (*Module)(nil)
// If a module is marked for exclusion from apexes, don't provide apex variants.
-// TODO(b/362509506): remove this once stubs are properly supported by rust_ffi targets.
+// TODO(b/362509506): remove this once all apex_exclude usages are removed.
func (m *Module) CanHaveApexVariants() bool {
if m.ApexExclude() {
return false
@@ -1884,53 +2102,113 @@
}
// Implements android.ApexModule
-func (mod *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
+func (mod *Module) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
minSdkVersion := mod.MinSdkVersion()
if minSdkVersion == "apex_inherit" {
- return nil
- }
- if minSdkVersion == "" {
- return fmt.Errorf("min_sdk_version is not specificed")
+ return android.MinApiLevel
}
+ if minSdkVersion == "" {
+ return android.NoneApiLevel
+ }
// Not using nativeApiLevelFromUser because the context here is not
// necessarily a native context.
- ver, err := android.ApiLevelFromUser(ctx, minSdkVersion)
+ ver, err := android.ApiLevelFromUserWithConfig(ctx.Config(), minSdkVersion)
if err != nil {
- return err
+ return android.NoneApiLevel
}
- if ver.GreaterThan(sdkVersion) {
- return fmt.Errorf("newer SDK(%v)", ver)
- }
- return nil
+ return ver
}
// Implements android.ApexModule
-func (mod *Module) OutgoingDepIsInSameApex(depTag blueprint.DependencyTag) bool {
+func (mod *Module) AlwaysRequiresPlatformApexVariant() bool {
+ // stub libraries and native bridge libraries are always available to platform
+ // TODO(b/362509506): remove the ApexExclude() check once all apex_exclude uses are switched to stubs.
+ return mod.IsStubs() || mod.Target().NativeBridge == android.NativeBridgeEnabled || mod.ApexExclude()
+}
+
+// Implements android.ApexModule
+type RustDepInSameApexChecker struct {
+ Static bool
+ HasStubsVariants bool
+ ApexExclude bool
+ Host bool
+}
+
+func (mod *Module) GetDepInSameApexChecker() android.DepInSameApexChecker {
+ return RustDepInSameApexChecker{
+ Static: mod.Static(),
+ HasStubsVariants: mod.HasStubsVariants(),
+ ApexExclude: mod.ApexExclude(),
+ Host: mod.Host(),
+ }
+}
+
+func (r RustDepInSameApexChecker) OutgoingDepIsInSameApex(depTag blueprint.DependencyTag) bool {
if depTag == procMacroDepTag || depTag == customBindgenDepTag {
return false
}
- if mod.Static() && cc.IsSharedDepTag(depTag) {
+ if r.Static && cc.IsSharedDepTag(depTag) {
// shared_lib dependency from a static lib is considered as crossing
// the APEX boundary because the dependency doesn't actually is
// linked; the dependency is used only during the compilation phase.
return false
}
+ if depTag == cc.StubImplDepTag {
+ // We don't track from an implementation library to its stubs.
+ return false
+ }
+
+ if cc.ExcludeInApexDepTag(depTag) {
+ return false
+ }
+
+ // TODO(b/362509506): remove once all apex_exclude uses are switched to stubs.
+ if r.ApexExclude {
+ return false
+ }
+
return true
}
-func (mod *Module) IncomingDepIsInSameApex(depTag blueprint.DependencyTag) bool {
- return !mod.ApexExclude()
+func (r RustDepInSameApexChecker) IncomingDepIsInSameApex(depTag blueprint.DependencyTag) bool {
+ if r.Host {
+ return false
+ }
+ // TODO(b/362509506): remove once all apex_exclude uses are switched to stubs.
+ if r.ApexExclude {
+ return false
+ }
+
+ if r.HasStubsVariants {
+ if cc.IsSharedDepTag(depTag) && !cc.IsExplicitImplSharedDepTag(depTag) {
+ // dynamic dep to a stubs lib crosses APEX boundary
+ return false
+ }
+ if cc.IsRuntimeDepTag(depTag) {
+ // runtime dep to a stubs lib also crosses APEX boundary
+ return false
+ }
+ if cc.IsHeaderDepTag(depTag) {
+ return false
+ }
+ }
+ return true
}
// Overrides ApexModule.IsInstallabeToApex()
func (mod *Module) IsInstallableToApex() bool {
+ // TODO(b/362509506): remove once all apex_exclude uses are switched to stubs.
+ if mod.ApexExclude() {
+ return false
+ }
+
if mod.compiler != nil {
- if lib, ok := mod.compiler.(libraryInterface); ok && (lib.shared() || lib.dylib()) {
- return true
+ if lib, ok := mod.compiler.(libraryInterface); ok {
+ return (lib.shared() || lib.dylib()) && !lib.BuildStubs()
}
if _, ok := mod.compiler.(*binaryDecorator); ok {
return true
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 9f65dec..f634bb5 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -184,8 +184,8 @@
srcs: ["foo.rs"],
}
`)
- module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
- rustc := ctx.ModuleForTests("librlib", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc")
+ module := ctx.ModuleForTests(t, "fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
+ rustc := ctx.ModuleForTests(t, "librlib", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc")
// Since dependencies are added to AndroidMk* properties, we can check these to see if they've been picked up.
if !android.InList("librlib.rlib-std", module.Properties.AndroidMkRlibs) {
@@ -204,7 +204,7 @@
t.Errorf("Static library dependency not detected (dependency missing from AndroidMkStaticLibs)")
}
- if !strings.Contains(rustc.Args["rustcFlags"], "-lstatic=wholestatic") {
+ if !strings.Contains(rustc.Args["rustcFlags"], "-lstatic:+whole-archive=wholestatic") {
t.Errorf("-lstatic flag not being passed to rustc for static library %#v", rustc.Args["rustcFlags"])
}
@@ -274,7 +274,7 @@
}
`)
- libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_rlib_dylib-std").Rule("rustc")
+ libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_rlib_dylib-std").Rule("rustc")
if !android.SuffixInList(libfoo.Implicits.Strings(), "/out/bindings.rs") {
t.Errorf("rust_bindgen generated source not included as implicit input for libfoo; Implicits %#v", libfoo.Implicits.Strings())
}
@@ -282,7 +282,7 @@
t.Errorf("genrule generated source not included as implicit input for libfoo; Implicits %#v", libfoo.Implicits.Strings())
}
- fizzBuzz := ctx.ModuleForTests("fizz-buzz-dep", "android_arm64_armv8-a").Rule("rustc")
+ fizzBuzz := ctx.ModuleForTests(t, "fizz-buzz-dep", "android_arm64_armv8-a").Rule("rustc")
if !android.SuffixInList(fizzBuzz.Implicits.Strings(), "/out/bindings.rs") {
t.Errorf("rust_bindgen generated source not included as implicit input for fizz-buzz-dep; Implicits %#v", libfoo.Implicits.Strings())
}
@@ -290,7 +290,7 @@
t.Errorf("genrule generated source not included as implicit input for fizz-buzz-dep; Implicits %#v", libfoo.Implicits.Strings())
}
- libprocmacro := ctx.ModuleForTests("libprocmacro", "linux_glibc_x86_64").Rule("rustc")
+ libprocmacro := ctx.ModuleForTests(t, "libprocmacro", "linux_glibc_x86_64").Rule("rustc")
if !android.SuffixInList(libprocmacro.Implicits.Strings(), "/out/bindings.rs") {
t.Errorf("rust_bindgen generated source not included as implicit input for libprocmacro; Implicits %#v", libfoo.Implicits.Strings())
}
@@ -299,15 +299,15 @@
}
// Check that our bindings are picked up as crate dependencies as well
- libfooMod := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").Module().(*Module)
+ libfooMod := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_dylib").Module().(*Module)
if !android.InList("libbindings", libfooMod.Properties.AndroidMkRlibs) {
t.Errorf("bindgen dependency not detected as a rlib dependency (dependency missing from AndroidMkRlibs)")
}
- fizzBuzzMod := ctx.ModuleForTests("fizz-buzz-dep", "android_arm64_armv8-a").Module().(*Module)
+ fizzBuzzMod := ctx.ModuleForTests(t, "fizz-buzz-dep", "android_arm64_armv8-a").Module().(*Module)
if !android.InList("libbindings", fizzBuzzMod.Properties.AndroidMkRlibs) {
t.Errorf("bindgen dependency not detected as a rlib dependency (dependency missing from AndroidMkRlibs)")
}
- libprocmacroMod := ctx.ModuleForTests("libprocmacro", "linux_glibc_x86_64").Module().(*Module)
+ libprocmacroMod := ctx.ModuleForTests(t, "libprocmacro", "linux_glibc_x86_64").Module().(*Module)
if !android.InList("libbindings.rlib-std", libprocmacroMod.Properties.AndroidMkRlibs) {
t.Errorf("bindgen dependency not detected as a rlib dependency (dependency missing from AndroidMkRlibs)")
}
@@ -354,7 +354,7 @@
srcs: ["foo.rs"],
}
`)
- rustc := ctx.ModuleForTests("libpm", "linux_glibc_x86_64").Rule("rustc")
+ rustc := ctx.ModuleForTests(t, "libpm", "linux_glibc_x86_64").Rule("rustc")
if !strings.Contains(rustc.Args["libFlags"], "libbar/linux_glibc_x86_64") {
t.Errorf("Proc_macro is not using host variant of dependent modules.")
@@ -369,7 +369,7 @@
srcs: ["foo.rs"],
no_stdlibs: true,
}`)
- module := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Module().(*Module)
+ module := ctx.ModuleForTests(t, "fizz-buzz", "android_arm64_armv8-a").Module().(*Module)
if android.InList("libstd", module.Properties.AndroidMkDylibs) {
t.Errorf("no_stdlibs did not suppress dependency on libstd")
@@ -385,8 +385,8 @@
crate_name: "foo",
}`)
- _ = ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_rlib_dylib-std")
- _ = ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_rlib_dylib-std")
+ _ = ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_rlib_dylib-std")
+ _ = ctx.ModuleForTests(t, "libfoo", "android_arm_armv7-a-neon_rlib_dylib-std")
}
// Test that library size measurements are generated.
@@ -398,7 +398,7 @@
crate_name: "waldo",
}`)
- m := ctx.SingletonForTests("file_metrics")
+ m := ctx.SingletonForTests(t, "file_metrics")
m.Output("unstripped/libwaldo.dylib.so.bloaty.csv")
m.Output("libwaldo.dylib.so.bloaty.csv")
}
@@ -423,7 +423,7 @@
aliases: ["bar:bar_renamed"],
}`)
- fooRustc := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc")
+ fooRustc := ctx.ModuleForTests(t, "foo", "android_arm64_armv8-a").Rule("rustc")
if !strings.Contains(fooRustc.Args["libFlags"], "--extern force:bar_renamed=out/soong/.intermediates/libbar/android_arm64_armv8-a_dylib/unstripped/libbar.dylib.so") {
t.Errorf("--extern force:bar_renamed=out/soong/.intermediates/libbar/android_arm64_armv8-a_dylib/unstripped/libbar.dylib.so flag not being passed to rustc for rust_binary with aliases. libFlags: %#v", fooRustc.Args["libFlags"])
}
@@ -432,7 +432,7 @@
}
}
-func TestRustRlibs(t *testing.T) {
+func TestRustFFIRlibs(t *testing.T) {
ctx := testRust(t, `
rust_ffi_static {
name: "libbar",
@@ -449,12 +449,40 @@
}
rust_ffi_static {
+ name: "libfoo_from_rlib",
+ crate_name: "foo_from_rlib",
+ srcs: ["src/lib.rs"],
+ export_include_dirs: ["foo_includes"]
+ }
+
+ rust_ffi_static {
+ name: "libfoo_from_rlib_whole",
+ crate_name: "foo_from_rlib_whole",
+ srcs: ["src/lib.rs"],
+ export_include_dirs: ["foo_includes"]
+ }
+
+ rust_ffi_static {
name: "libbuzz",
crate_name: "buzz",
srcs: ["src/lib.rs"],
export_include_dirs: ["buzz_includes"]
}
+ rust_ffi_static {
+ name: "libbuzz_from_rlib",
+ crate_name: "buzz_from_rlib",
+ srcs: ["src/lib.rs"],
+ export_include_dirs: ["buzz_includes"]
+ }
+
+ rust_ffi_static {
+ name: "libbuzz_from_rlib_whole",
+ crate_name: "buzz_from_rlib_whole",
+ srcs: ["src/lib.rs"],
+ export_include_dirs: ["buzz_includes"]
+ }
+
cc_library_shared {
name: "libcc_shared",
srcs:["foo.c"],
@@ -468,20 +496,64 @@
whole_static_libs: ["libfoo"],
}
+ cc_library_static {
+ name: "libcc_static_from_rlib",
+ srcs:["foo.c"],
+ static_libs: ["libbuzz_from_rlib"],
+ whole_static_libs: ["libfoo_from_rlib"],
+ }
+
+ cc_library_static {
+ name: "libcc_whole_static_from_rlib",
+ srcs:["foo.c"],
+ static_libs: ["libbuzz_from_rlib_whole"],
+ whole_static_libs: ["libfoo_from_rlib_whole"],
+ }
+
cc_binary {
name: "ccBin",
srcs:["foo.c"],
static_libs: ["libcc_static", "libbar"],
}
- `)
- libbar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_rlib_rlib-std").Rule("rustc")
- libcc_shared_rustc := ctx.ModuleForTests("libcc_shared", "android_arm64_armv8-a_shared").Rule("rustc")
- libcc_shared_ld := ctx.ModuleForTests("libcc_shared", "android_arm64_armv8-a_shared").Rule("ld")
- libcc_shared_cc := ctx.ModuleForTests("libcc_shared", "android_arm64_armv8-a_shared").Rule("cc")
- ccbin_rustc := ctx.ModuleForTests("ccBin", "android_arm64_armv8-a").Rule("rustc")
- ccbin_ld := ctx.ModuleForTests("ccBin", "android_arm64_armv8-a").Rule("ld")
- ccbin_cc := ctx.ModuleForTests("ccBin", "android_arm64_armv8-a").Rule("cc")
+ rust_library {
+ name: "librs",
+ srcs:["src/foo.rs"],
+ crate_name: "rs",
+ static_libs: ["libcc_static_from_rlib"],
+ whole_static_libs: ["libcc_whole_static_from_rlib"],
+ }
+
+ rust_library {
+ name: "librs2",
+ srcs:["src/foo.rs"],
+ crate_name: "rs",
+ rustlibs: ["librs"],
+ }
+
+ rust_binary {
+ name: "rsBin",
+ srcs:["src/foo.rs"],
+ crate_name: "rsBin",
+ rlibs: ["librs", "libbar"],
+ static_libs: ["libcc_static"],
+ }
+ `)
+
+ libbar := ctx.ModuleForTests(t, "libbar", "android_arm64_armv8-a_rlib_rlib-std").Rule("rustc")
+ libcc_shared_rustc := ctx.ModuleForTests(t, "libcc_shared", "android_arm64_armv8-a_shared").Rule("rustc")
+ libcc_shared_ld := ctx.ModuleForTests(t, "libcc_shared", "android_arm64_armv8-a_shared").Rule("ld")
+ libcc_shared_cc := ctx.ModuleForTests(t, "libcc_shared", "android_arm64_armv8-a_shared").Rule("cc")
+ ccbin_rustc := ctx.ModuleForTests(t, "ccBin", "android_arm64_armv8-a").Rule("rustc")
+ ccbin_ld := ctx.ModuleForTests(t, "ccBin", "android_arm64_armv8-a").Rule("ld")
+ ccbin_cc := ctx.ModuleForTests(t, "ccBin", "android_arm64_armv8-a").Rule("cc")
+ rustbin_genlib := ctx.ModuleForTests(t, "rsBin", "android_arm64_armv8-a").Output("generated_rust_staticlib/librustlibs.a")
+ rustbin := ctx.ModuleForTests(t, "rsBin", "android_arm64_armv8-a").Output("unstripped/rsBin")
+ librs_rlib := ctx.ModuleForTests(t, "librs", "android_arm64_armv8-a_rlib_dylib-std").MaybeOutput("generated_rust_staticlib/librustlibs.a")
+ librs2_rlib := ctx.ModuleForTests(t, "librs2", "android_arm64_armv8-a_rlib_dylib-std").MaybeOutput("generated_rust_staticlib/librustlibs.a")
+ librs_genlib := ctx.ModuleForTests(t, "librs", "android_arm64_armv8-a_dylib").Output("generated_rust_staticlib/librustlibs.a")
+ librs2_genlib := ctx.ModuleForTests(t, "librs2", "android_arm64_armv8-a_dylib").Output("generated_rust_staticlib/librustlibs.a")
+ librs2_dylib := ctx.ModuleForTests(t, "librs2", "android_arm64_armv8-a_dylib").Output("unstripped/librs2.dylib.so")
if !strings.Contains(libbar.Args["rustcFlags"], "crate-type=rlib") {
t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", "rlib", libbar.Args["rustcFlags"])
@@ -513,7 +585,7 @@
// Make sure the static lib is included in the cc command
if !strings.Contains(ccbin_ld.Args["libFlags"], "generated_rust_staticlib/librustlibs.a") {
t.Errorf("missing generated static library in linker step libFlags, expecting %#v, libFlags: %#v",
- "ccBin.generated_rust_staticlib.a", ccbin_ld.Args["libFlags"])
+ "generated_rust_staticlib/librustlibs.a", ccbin_ld.Args["libFlags"])
}
// Make sure the static lib includes are in the ld command
@@ -534,11 +606,72 @@
t.Errorf("Missing direct dependency libbar when writing generated Rust staticlib: %#v", ccbin_rustc.Args["libFlags"])
}
+ // Make sure the static lib is included in the rustc command
+ if !strings.Contains(rustbin.Args["linkFlags"], "generated_rust_staticlib/librustlibs.a") {
+ t.Errorf("missing generated static library in linker step libFlags in Rust module, expecting %#v, libFlags: %#v",
+ "generated_rust_staticlib/librustlibs.a", rustbin.Args["libFlags"])
+ }
+ if !strings.Contains(librs2_dylib.Args["linkFlags"], "generated_rust_staticlib/librustlibs.a") {
+ t.Errorf("missing generated static library in linker step libFlags in Rust module, expecting %#v, libFlags: %#v",
+ "generated_rust_staticlib/librustlibs.a", librs2_dylib.Args["libFlags"])
+ }
+
+ // Make sure that direct dependencies and indirect whole static dependencies are
+ // propagating correctly for the rlib -> cc_library_static -> rust_* generated library example.
+ if !strings.Contains(rustbin_genlib.Args["libFlags"], "--extern foo=") {
+ t.Errorf("Missing indirect whole_static_lib dependency libfoo from cc static_lib when writing generated Rust staticlib: %#v", rustbin_genlib.Args["libFlags"])
+ }
+ if strings.Contains(rustbin_genlib.Args["libFlags"], "--extern buzz=") {
+ t.Errorf("Indirect rlib dependency libbuzz from cc static_lib found when writing generated Rust staticlib: %#v", rustbin_genlib.Args["libFlags"])
+ }
+ if strings.Contains(rustbin_genlib.Args["libFlags"], "--extern bar=") {
+ t.Errorf("Direct rlib dependency libbar getting included in the generated Rust staticlib: %#v", rustbin_genlib.Args["libFlags"])
+ }
+ if !strings.Contains(rustbin_genlib.Args["libFlags"], "--extern foo_from_rlib=") {
+ t.Errorf("Missing indirect whole_static_lib dependency libfoo_from_rlib from cc static_lib when writing generated Rust staticlib: %#v", rustbin_genlib.Args["libFlags"])
+ }
+ if strings.Contains(rustbin_genlib.Args["libFlags"], "--extern buzz_from_rlib=") {
+ // While static-libs propagate for rust modules, this is not the
+ // expected behavior for cc modules. Thus, libbuzz_from_rlib would
+ // be expected to have to be re-declared as a direct rlib dependency.
+ t.Errorf("Indirect rlib dependency libbuzz_from_rlib from cc static_lib found when writing generated Rust staticlib: %#v", rustbin_genlib.Args["libFlags"])
+ }
+
// Test indirect includes propagation
if !strings.Contains(ccbin_cc.Args["cFlags"], "-Ifoo_includes") {
t.Errorf("missing rlibs includes, expecting %#v, cFlags: %#v",
"-Ifoo_includes", ccbin_cc.Args)
}
+
+ // Make sure we're not generating superfluous mto staticlibs.
+ if librs_rlib.Rule != nil {
+ t.Error("rlibs should not be generating mto staticlibs", "rlib", libbar.Args["rustcFlags"])
+ }
+ if librs2_rlib.Rule != nil {
+ t.Error("rlibs should not be generating mto staticlibs", "rlib", libbar.Args["rustcFlags"])
+ }
+
+ // Make sure that direct whole static dependencies are propagating correctly downstream
+ // foo_from_rlib_whole --(ws)--> libcc_whole_static_from_rlib --(ws)--> librs
+ if !strings.Contains(librs_genlib.Args["libFlags"], "--extern foo_from_rlib_whole=") {
+ t.Errorf("Missing direct whole_static_lib dependency libfoo_from_rlib_whole from rust dylib when writing generated Rust staticlib: %#v", librs_genlib.Args["libFlags"])
+ }
+
+ // Make sure that indirect whole static dependencies are propagating correctly downstream
+ // foo_from_rlib_whole --(ws)--> libcc_whole_static_from_rlib --(ws)--> librs --> rust_*
+ if !strings.Contains(librs2_genlib.Args["libFlags"], "--extern foo_from_rlib_whole=") {
+ t.Errorf("Missing indirect whole_static_lib dependency libfoo_from_rlib_whole from rust dylib when writing generated Rust staticlib: %#v", librs2_genlib.Args["libFlags"])
+ }
+ if !strings.Contains(rustbin_genlib.Args["libFlags"], "--extern foo_from_rlib_whole=") {
+ t.Errorf("Missing indirect whole_static_lib dependency libfoo_from_rlib_whole from rust dylib in rust binary when writing generated Rust staticlib: %#v", rustbin_genlib.Args["libFlags"])
+ }
+
+ // Make sure that normal static dependencies are not propagating through dylib dependencies
+ // buzz_from_rlib_whole --(s)--> libcc_whole_static_from_rlib --(ws)--> librs --> rust_*
+ if strings.Contains(librs2_genlib.Args["libFlags"], "--extern buzz_from_rlib_whole=") {
+ t.Errorf("dependency from indirect cc staticlib from direct dylib dep found in rust dylib when writing generated Rust staticlib: %#v", librs2_genlib.Args["libFlags"])
+ }
+
}
func assertString(t *testing.T, got, expected string) {
@@ -575,3 +708,176 @@
}
`)
}
+
+func TestRustLinkPropagation(t *testing.T) {
+ // Test static and whole static propagation behavior
+ //
+ // Whole static libs propagate through rlibs and through dylibs to
+ // dependencies further down. rustc does not re-export whole-archived
+ // static libs for dylibs, so this simulates re-exporting those symbols.
+ //
+ // Static libs only propagate through rlibs to some final dylib. We propagate
+ // normal static libs because we allow rustlib dependencies to represent
+ // either rlibs or dylibs. Not propagating static libs through rlibs would
+ // mean we'd need to always redeclare static libs throughout a dependency tree
+ // We don't propagate past dylibs because they represent a final link.
+
+ ctx := testRust(t, `
+ rust_library_rlib {
+ name: "librlib1",
+ crate_name: "rlib1",
+ srcs: ["src/lib.rs"],
+ static_libs: ["libcc_static_rlib1"],
+ whole_static_libs: ["libcc_whole_static_rlib1"],
+ }
+
+ rust_library_dylib {
+ name: "libdylib1",
+ crate_name: "dylib1",
+ static_libs: ["libcc_static_dylib1"],
+ srcs: ["src/lib.rs"],
+ whole_static_libs: ["libcc_whole_static_dylib1"],
+ }
+
+ rust_library_rlib {
+ name: "librlib2",
+ crate_name: "rlib2",
+ srcs: ["src/lib.rs"],
+ rlibs: ["librlib1"],
+ static_libs: ["libcc_static_rlib2"],
+ whole_static_libs: ["libcc_whole_static_rlib2"],
+ }
+
+ rust_library_dylib {
+ name: "libdylib2",
+ crate_name: "dylib2",
+ srcs: ["src/lib.rs"],
+ rlibs: ["librlib1"],
+ rustlibs: ["libdylib1"],
+ static_libs: ["libcc_static_dylib2"],
+ whole_static_libs: ["libcc_whole_static_dylib2"],
+ }
+
+ cc_library_static {
+ name: "libcc_static_rlib1",
+ srcs:["foo.c"],
+ }
+
+ cc_library_static {
+ name: "libcc_static_rlib2",
+ srcs:["foo.c"],
+ }
+
+ cc_library_static {
+ name: "libcc_static_dylib1",
+ srcs:["foo.c"],
+ }
+
+ cc_library_static {
+ name: "libcc_static_dylib2",
+ srcs:["foo.c"],
+ }
+
+ cc_library_static {
+ name: "libcc_whole_static_rlib1",
+ srcs:["foo.c"],
+ }
+
+ cc_library_static {
+ name: "libcc_whole_static_rlib2",
+ srcs:["foo.c"],
+ }
+
+ cc_library_static {
+ name: "libcc_whole_static_dylib1",
+ srcs:["foo.c"],
+ }
+
+ cc_library_static {
+ name: "libcc_whole_static_dylib2",
+ srcs:["foo.c"],
+ }
+
+ rust_library_rlib {
+ name: "librlib3",
+ crate_name: "rlib3",
+ srcs: ["src/lib.rs"],
+ rlibs: ["librlib2"],
+ }
+
+ rust_library_dylib {
+ name: "libdylib3",
+ crate_name: "dylib3",
+ srcs: ["src/lib.rs"],
+ rlibs: ["librlib2"],
+ rustlibs: ["libdylib2"],
+ }
+ `)
+
+ librlib3 := ctx.ModuleForTests(t, "librlib3", "android_arm64_armv8-a_rlib_dylib-std").Rule("rustc")
+ libdylib3 := ctx.ModuleForTests(t, "libdylib3", "android_arm64_armv8-a_dylib").Rule("rustc")
+
+ // Test static lib propagation from:
+ // rlib -> rlib
+ if !strings.Contains(librlib3.Args["linkFlags"], "libcc_static_rlib2.a") {
+ t.Errorf("direct dependency static lib not propagating from rlib to rlib; linkFlags %#v",
+ librlib3.Args["linkFlags"])
+ }
+ // rlib -> rlib -> rlib
+ if !strings.Contains(librlib3.Args["linkFlags"], "libcc_static_rlib1.a") {
+ t.Errorf("indirect dependency static lib not propagating from rlib to rlib: linkFlags %#v",
+ librlib3.Args["linkFlags"])
+ }
+ // rlib -> rlib -> dylib
+ if !strings.Contains(libdylib3.Args["linkFlags"], "libcc_static_rlib1.a") {
+ t.Errorf("indirect dependency static lib not propagating from rlib to dylib: linkFlags %#v",
+ libdylib3.Args["linkFlags"])
+ }
+ // rlib -> dylib
+ if !strings.Contains(libdylib3.Args["linkFlags"], "libcc_static_rlib2.a") {
+ t.Errorf("direct dependency static lib not propagating from rlib to dylib: linkFlags: %#v",
+ libdylib3.Args["linkFlags"])
+ }
+ // dylib -> dylib (negative case, should not propagate)
+ if strings.Contains(libdylib3.Args["linkFlags"], "libcc_static_dylib2.a") {
+ t.Errorf("direct dependency static lib propagating from dylib to dylib: linkFlags: %#v",
+ libdylib3.Args["linkFlags"])
+ }
+ // dylib -> dylib -> dylib (negative case, should not propagate)
+ if strings.Contains(libdylib3.Args["linkFlags"], "libcc_static_dylib1.a") {
+ t.Errorf("indirect dependency static lib propagating from dylib to dylib: linkFlags: %#v",
+ libdylib3.Args["linkFlags"])
+ }
+
+ // Test whole static lib propagation from:
+ // rlib -> rlib
+ if !strings.Contains(librlib3.Args["linkFlags"], "libcc_whole_static_rlib2.a") {
+ t.Errorf("direct dependency whole static lib not propagating from rlib to rlib: linkFlags %#v",
+ librlib3.Args["linkFlags"])
+ }
+ // rlib -> rlib -> rlib
+ if !strings.Contains(librlib3.Args["linkFlags"], "libcc_whole_static_rlib1.a") {
+ t.Errorf("indirect dependency whole static lib not propagating from rlib to rlib: linkFlags %#v",
+ librlib3.Args["linkFlags"])
+ }
+ // rlib -> dylib
+ if !strings.Contains(libdylib3.Args["linkFlags"], "libcc_whole_static_rlib2.a") {
+ t.Errorf("direct dependency whole static lib not propagating from rlib to dylib: linkFlags %#v",
+ libdylib3.Args["linkFlags"])
+ }
+ // rlib -> rlib -> dylib
+ if !strings.Contains(libdylib3.Args["linkFlags"], "libcc_whole_static_rlib1.a") {
+ t.Errorf("indirect dependency whole static lib not propagating from rlib to dylib: linkFlags %#v",
+ libdylib3.Args["linkFlags"])
+ }
+ // dylib -> dylib
+ if !strings.Contains(libdylib3.Args["linkFlags"], "libcc_whole_static_dylib2.a") {
+ t.Errorf("direct dependency whole static lib not propagating from dylib to dylib: linkFlags %#v",
+ libdylib3.Args["linkFlags"])
+ }
+ // dylib -> dylib -> dylib
+ if !strings.Contains(libdylib3.Args["linkFlags"], "libcc_whole_static_dylib1.a") {
+ t.Errorf("indirect dependency whole static lib not propagating from dylib to dylib: linkFlags %#v",
+ libdylib3.Args["linkFlags"])
+ }
+}
diff --git a/rust/sanitize.go b/rust/sanitize.go
index b8f922f..50f55ce 100644
--- a/rust/sanitize.go
+++ b/rust/sanitize.go
@@ -53,6 +53,9 @@
// Used when we need to place libraries in their own directory, such as ASAN.
InSanitizerDir bool `blueprint:"mutated"`
+
+ // ForceDisable is set by the version mutator to disable sanitization of stubs variants
+ ForceDisable bool `blueprint:"mutated"`
}
var fuzzerFlags = []string{
@@ -103,6 +106,10 @@
func (sanitize *sanitize) begin(ctx BaseModuleContext) {
s := &sanitize.Properties.Sanitize
+ if sanitize.Properties.ForceDisable {
+ return
+ }
+
// Disable sanitizers for musl x86 modules, rustc does not support any sanitizers.
if ctx.Os() == android.LinuxMusl && ctx.Arch().ArchType == android.X86 {
s.Never = proptools.BoolPtr(true)
@@ -221,6 +228,10 @@
}
func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags, PathDeps) {
+ if sanitize.Properties.ForceDisable {
+ return flags, deps
+ }
+
if !sanitize.Properties.SanitizerEnabled {
return flags, deps
}
@@ -253,6 +264,9 @@
if !mod.Enabled(mctx) {
return
}
+ if mod.sanitize.Properties.ForceDisable {
+ return
+ }
if Bool(mod.sanitize.Properties.Sanitize.Memtag_heap) && mod.Binary() {
noteDep := "note_memtag_heap_async"
@@ -364,7 +378,7 @@
// distinguish between the cases. It isn't needed though - both cases can be
// treated identically.
func (sanitize *sanitize) isSanitizerEnabled(t cc.SanitizerType) bool {
- if sanitize == nil || !sanitize.Properties.SanitizerEnabled {
+ if sanitize == nil || !sanitize.Properties.SanitizerEnabled || sanitize.Properties.ForceDisable {
return false
}
@@ -453,7 +467,7 @@
}
func (mod *Module) SanitizeNever() bool {
- return Bool(mod.sanitize.Properties.Sanitize.Never)
+ return Bool(mod.sanitize.Properties.Sanitize.Never) || mod.sanitize.Properties.ForceDisable
}
var _ cc.PlatformSanitizeable = (*Module)(nil)
diff --git a/rust/sanitize_test.go b/rust/sanitize_test.go
index d6a14b2..a3fe282 100644
--- a/rust/sanitize_test.go
+++ b/rust/sanitize_test.go
@@ -153,65 +153,65 @@
).RunTest(t)
ctx := result.TestContext
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_no_override", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_async", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_sync", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_override_default_sync", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_no_override", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_async", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_sync", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_override_default_sync", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_no_override", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_disable", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_no_override", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_disable", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_sync", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_override_default_sync", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_no_override", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_disable", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_sync", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_override_default_sync", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_no_override", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_no_override", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_override_default_sync", variant), Sync)
}
func TestSanitizeMemtagHeapWithSanitizeDevice(t *testing.T) {
@@ -226,67 +226,67 @@
).RunTest(t)
ctx := result.TestContext
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_no_override", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_async", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_sync", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_override_default_sync", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_no_override", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_async", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_sync", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_override_default_sync", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_no_override", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_disable", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_no_override", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_disable", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_sync", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_override_default_sync", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_no_override", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_disable", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_sync", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_override_default_sync", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_override_default_sync", variant), Sync)
// should sanitize: { diag: { memtag: true } } result in Sync instead of None here?
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_override_default_async", variant), Sync)
// should sanitize: { diag: { memtag: true } } result in Sync instead of None here?
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_no_override", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_override_default_sync", variant), Sync)
}
func TestSanitizeMemtagHeapWithSanitizeDeviceDiag(t *testing.T) {
@@ -302,64 +302,64 @@
).RunTest(t)
ctx := result.TestContext
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_no_override", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_async", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_sync", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_binary_override_default_sync", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_no_override", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_async", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_sync", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "no_memtag_test_override_default_sync", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_test_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_no_override", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_disable", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_sync", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_binary_override_default_sync", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_no_override", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_async", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_disable", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_sync", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_async_test_override_default_sync", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "set_memtag_set_sync_test_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_override_default_async", variant), Sync)
// should sanitize: { diag: { memtag: true } } result in Sync instead of None here?
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_memtag_set_sync_test_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_disable", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_no_override", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_async", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_disable", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_sync", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests(t, "unset_test_override_default_sync", variant), Sync)
}
diff --git a/rust/source_provider.go b/rust/source_provider.go
index 3236bce..27c62c2 100644
--- a/rust/source_provider.go
+++ b/rust/source_provider.go
@@ -43,6 +43,7 @@
SourceProviderProps() []interface{}
SourceProviderDeps(ctx DepsContext, deps Deps) Deps
setSubName(subName string)
+ getSubName() string
setOutputFiles(outputFiles android.Paths)
}
@@ -100,6 +101,10 @@
sp.subName = subName
}
+func (sp *BaseSourceProvider) getSubName() string {
+ return sp.subName
+}
+
func (sp *BaseSourceProvider) setOutputFiles(outputFiles android.Paths) {
sp.OutputFiles = outputFiles
}
diff --git a/rust/test.go b/rust/test.go
index dce5e03..9833ffd 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -46,9 +46,16 @@
// the test
Data []string `android:"path,arch_variant"`
- // Same as data, but will add dependencies on the device's
+ // Same as data, but adds dependencies on modules using the device's os variant, and common
+ // architecture's variant. Can be useful to add device-built apps to the data of a host
+ // test.
Device_common_data []string `android:"path_device_common"`
+ // Same as data, but will add dependencies on modules using the host's os variation and
+ // the common arch variation. Useful for a device test that wants to depend on a host
+ // module, for example to include a custom Tradefed test runner.
+ Host_common_data []string `android:"path_host_common"`
+
// list of shared library modules that should be installed alongside the test
Data_libs []string `android:"arch_variant"`
@@ -147,36 +154,38 @@
dataSrcPaths := android.PathsForModuleSrc(ctx, test.Properties.Data)
dataSrcPaths = append(dataSrcPaths, android.PathsForModuleSrc(ctx, test.Properties.Device_common_data)...)
+ dataSrcPaths = append(dataSrcPaths, android.PathsForModuleSrc(ctx, test.Properties.Host_common_data)...)
- ctx.VisitDirectDepsWithTag(dataLibDepTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(dataLibDepTag, func(dep android.ModuleProxy) {
depName := ctx.OtherModuleName(dep)
- linkableDep, ok := dep.(cc.LinkableInterface)
+ linkableDep, ok := android.OtherModuleProvider(ctx, dep, cc.LinkableInfoProvider)
if !ok {
ctx.ModuleErrorf("data_lib %q is not a linkable module", depName)
}
- if linkableDep.OutputFile().Valid() {
+ if linkableDep.OutputFile.Valid() {
// Copy the output in "lib[64]" so that it's compatible with
// the default rpath values.
+ commonInfo := android.OtherModuleProviderOrDefault(ctx, dep, android.CommonModuleInfoKey)
libDir := "lib"
- if linkableDep.Target().Arch.ArchType.Multilib == "lib64" {
+ if commonInfo.Target.Arch.ArchType.Multilib == "lib64" {
libDir = "lib64"
}
test.data = append(test.data,
- android.DataPath{SrcPath: linkableDep.OutputFile().Path(),
- RelativeInstallPath: filepath.Join(libDir, linkableDep.RelativeInstallPath())})
+ android.DataPath{SrcPath: linkableDep.OutputFile.Path(),
+ RelativeInstallPath: filepath.Join(libDir, linkableDep.RelativeInstallPath)})
}
})
- ctx.VisitDirectDepsWithTag(dataBinDepTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(dataBinDepTag, func(dep android.ModuleProxy) {
depName := ctx.OtherModuleName(dep)
- linkableDep, ok := dep.(cc.LinkableInterface)
+ linkableDep, ok := android.OtherModuleProvider(ctx, dep, cc.LinkableInfoProvider)
if !ok {
ctx.ModuleErrorf("data_bin %q is not a linkable module", depName)
}
- if linkableDep.OutputFile().Valid() {
+ if linkableDep.OutputFile.Valid() {
test.data = append(test.data,
- android.DataPath{SrcPath: linkableDep.OutputFile().Path(),
- RelativeInstallPath: linkableDep.RelativeInstallPath()})
+ android.DataPath{SrcPath: linkableDep.OutputFile.Path(),
+ RelativeInstallPath: linkableDep.RelativeInstallPath})
}
})
@@ -194,6 +203,31 @@
if ctx.Host() && test.Properties.Test_options.Unit_test == nil {
test.Properties.Test_options.Unit_test = proptools.BoolPtr(true)
}
+
+ if !ctx.Config().KatiEnabled() { // TODO(spandandas): Remove the special case for kati
+ // Install the test config in testcases/ directory for atest.
+ r, ok := ctx.Module().(*Module)
+ if !ok {
+ ctx.ModuleErrorf("Not a rust test module")
+ }
+ // Install configs in the root of $PRODUCT_OUT/testcases/$module
+ testCases := android.PathForModuleInPartitionInstall(ctx, "testcases", ctx.ModuleName()+r.SubName())
+ if ctx.PrimaryArch() {
+ if test.testConfig != nil {
+ ctx.InstallFile(testCases, ctx.ModuleName()+".config", test.testConfig)
+ }
+ dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml")
+ if dynamicConfig.Valid() {
+ ctx.InstallFile(testCases, ctx.ModuleName()+".dynamic", dynamicConfig.Path())
+ }
+ }
+ // Install tests and data in arch specific subdir $PRODUCT_OUT/testcases/$module/$arch
+ testCases = testCases.Join(ctx, ctx.Target().Arch.ArchType.String())
+ ctx.InstallTestData(testCases, test.data)
+ testPath := ctx.RustModule().OutputFile().Path()
+ ctx.InstallFile(testCases, testPath.Base(), testPath)
+ }
+
test.binaryDecorator.installTestData(ctx, test.data)
test.binaryDecorator.install(ctx)
}
@@ -202,6 +236,7 @@
flags = test.binaryDecorator.compilerFlags(ctx, flags)
if test.testHarness() {
flags.RustFlags = append(flags.RustFlags, "--test")
+ flags.RustFlags = append(flags.RustFlags, "-A missing-docs")
}
if ctx.Device() {
flags.RustFlags = append(flags.RustFlags, "-Z panic_abort_tests")
@@ -257,6 +292,32 @@
return true
}
+func (test *testDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) {
+ test.binaryDecorator.moduleInfoJSON(ctx, moduleInfoJSON)
+ moduleInfoJSON.Class = []string{"NATIVE_TESTS"}
+ if Bool(test.Properties.Test_options.Unit_test) {
+ moduleInfoJSON.IsUnitTest = "true"
+ if ctx.Host() {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "host-unit-tests")
+ }
+ }
+ moduleInfoJSON.TestOptionsTags = append(moduleInfoJSON.TestOptionsTags, test.Properties.Test_options.Tags...)
+ if test.testConfig != nil {
+ if _, ok := test.testConfig.(android.WritablePath); ok {
+ moduleInfoJSON.AutoTestConfig = []string{"true"}
+ }
+ moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, test.testConfig.String())
+ }
+
+ moduleInfoJSON.DataDependencies = append(moduleInfoJSON.DataDependencies, test.Properties.Data_bins...)
+
+ if len(test.Properties.Test_suites) > 0 {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, test.Properties.Test_suites...)
+ } else {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
+ }
+}
+
func rustTestHostMultilib(ctx android.LoadHookContext) {
type props struct {
Target struct {
diff --git a/rust/test_test.go b/rust/test_test.go
index 1097da2..076a259 100644
--- a/rust/test_test.go
+++ b/rust/test_test.go
@@ -29,7 +29,7 @@
data: ["data.txt"],
}`)
- testingModule := ctx.ModuleForTests("my_test", "linux_glibc_x86_64")
+ testingModule := ctx.ModuleForTests(t, "my_test", "linux_glibc_x86_64")
expectedOut := "my_test/linux_glibc_x86_64/my_test"
outPath := testingModule.Output("my_test").Output.String()
if !strings.Contains(outPath, expectedOut) {
@@ -62,7 +62,7 @@
crate_name: "bar",
}`)
- testingModule := ctx.ModuleForTests("my_test", "android_arm64_armv8-a").Module().(*Module)
+ testingModule := ctx.ModuleForTests(t, "my_test", "android_arm64_armv8-a").Module().(*Module)
if !android.InList("libfoo.rlib-std", testingModule.Properties.AndroidMkRlibs) {
t.Errorf("rlib-std variant for libfoo not detected as a rustlib-defined rlib dependency for device rust_test module")
@@ -106,7 +106,7 @@
ctx := testRust(t, bp)
- testingModule := ctx.ModuleForTests("main_test", "android_arm64_armv8-a")
+ testingModule := ctx.ModuleForTests(t, "main_test", "android_arm64_armv8-a")
testBinary := testingModule.Module().(*Module).compiler.(*testDecorator)
outputFiles := testingModule.OutputFiles(ctx, t, "")
if len(outputFiles) != 1 {
@@ -165,7 +165,7 @@
`
ctx := testRust(t, bp)
- testingModule := ctx.ModuleForTests("main_test", "android_arm64_armv8-a")
+ testingModule := ctx.ModuleForTests(t, "main_test", "android_arm64_armv8-a")
module := testingModule.Module()
testBinary := module.(*Module).compiler.(*testDecorator)
outputFiles := testingModule.OutputFiles(ctx, t, "")
diff --git a/rust/testing.go b/rust/testing.go
index 0ce1b66..2082b52 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -80,7 +80,6 @@
no_libcrt: true,
nocrt: true,
system_shared_libs: [],
- apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
vendor_available: true,
host_supported: true,
@@ -88,6 +87,13 @@
llndk: {
symbol_file: "liblog.map.txt",
},
+ stubs: {
+ symbol_file: "liblog.map.txt",
+ versions: [
+ "29",
+ "30",
+ ],
+ },
}
cc_library {
name: "libprotobuf-cpp-full",
diff --git a/scripts/Android.bp b/scripts/Android.bp
index d39c84a..94163a5 100644
--- a/scripts/Android.bp
+++ b/scripts/Android.bp
@@ -293,14 +293,6 @@
}
python_binary_host {
- name: "merge_directories",
- main: "merge_directories.py",
- srcs: [
- "merge_directories.py",
- ],
-}
-
-python_binary_host {
name: "merge_json",
main: "merge_json.py",
srcs: [
diff --git a/scripts/build-ndk-prebuilts.sh b/scripts/build-ndk-prebuilts.sh
index ef0f44a..b600443 100755
--- a/scripts/build-ndk-prebuilts.sh
+++ b/scripts/build-ndk-prebuilts.sh
@@ -23,9 +23,18 @@
# TODO: remove ALLOW_MISSING_DEPENDENCIES=true when all the riscv64
# dependencies exist (currently blocked by http://b/273792258).
# TODO: remove BUILD_BROKEN_DISABLE_BAZEL=1 when bazel supports riscv64 (http://b/262192655).
+#
+# LTO is disabled because the NDK compiler is not necessarily in-sync with the
+# compiler used to build the platform sysroot, and the sysroot includes static
+# libraries which would be incompatible with mismatched compilers when built
+# with LTO. Disabling LTO globally for the NDK sysroot is okay because the only
+# compiled code in the sysroot that will end up in apps is those static
+# libraries.
+# https://github.com/android/ndk/issues/1591
TARGET_RELEASE=trunk_staging \
ALLOW_MISSING_DEPENDENCIES=true \
BUILD_BROKEN_DISABLE_BAZEL=1 \
+DISABLE_LTO=true \
TARGET_PRODUCT=ndk build/soong/soong_ui.bash --make-mode --soong-only ${OUT_DIR}/soong/ndk.timestamp
if [ -n "${DIST_DIR}" ]; then
diff --git a/scripts/gen_build_prop.py b/scripts/gen_build_prop.py
index 430e613..74befd5 100644
--- a/scripts/gen_build_prop.py
+++ b/scripts/gen_build_prop.py
@@ -308,7 +308,15 @@
props.append(f"ro.sanitize.{sanitize_target}=true")
# Sets the default value of ro.postinstall.fstab.prefix to /system.
- # Device board config should override the value to /product when needed by:
+ #
+ # Device board configs can override this to /product to use a
+ # product-specific fstab.postinstall file (installed to
+ # /product/etc/fstab.postinstall). If not overridden, the
+ # system/extras/cppreopts/fstab.postinstall file (installed to
+ # /system/etc/fstab.postinstall) will be used.
+ # Note: The default fstab.postinstall is generic and may be slower
+ # because it tries different mount options line by line to ensure
+ # compatibility across various devices.
#
# PRODUCT_PRODUCT_PROPERTIES += ro.postinstall.fstab.prefix=/product
#
@@ -361,9 +369,6 @@
props = list(filter(lambda x: not x.startswith("ro.setupwizard.mode="), props))
props.append("ro.setupwizard.mode=OPTIONAL")
- if not config["SdkBuild"]:
- # To speedup startup of non-preopted builds, don't verify or compile the boot image.
- props.append("dalvik.vm.image-dex2oat-filter=extract")
# b/323566535
props.append("init.svc_debug.no_fatal.zygote=true")
diff --git a/scripts/merge_directories.py b/scripts/merge_directories.py
deleted file mode 100755
index 3f8631b..0000000
--- a/scripts/merge_directories.py
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/usr/bin/env python3
-import argparse
-import os
-import shutil
-import sys
-
-def main():
- parser = argparse.ArgumentParser(
- description="Given a list of directories, this script will copy the contents of all of "
- "them into the first directory, erroring out if any duplicate files are found."
- )
- parser.add_argument(
- "--ignore-duplicates",
- action="store_true",
- help="Don't error out on duplicate files, just skip them. The file from the earliest "
- "directory listed on the command line will be the winner."
- )
- parser.add_argument(
- "--file-list",
- help="Path to a text file containing paths relative to in_dir. Only these paths will be "
- "copied out of in_dir."
- )
- parser.add_argument("out_dir")
- parser.add_argument("in_dir")
- args = parser.parse_args()
-
- if not os.path.isdir(args.out_dir):
- sys.exit(f"error: {args.out_dir} must be a directory")
- if not os.path.isdir(args.in_dir):
- sys.exit(f"error: {args.in_dir} must be a directory")
-
- file_list = None
- if args.file_list:
- with open(file_list_file, "r") as f:
- file_list = f.read().strip().splitlines()
-
- in_dir = args.in_dir
- for root, dirs, files in os.walk(in_dir):
- rel_root = os.path.relpath(root, in_dir)
- dst_root = os.path.join(args.out_dir, rel_root)
- made_parent_dirs = False
- for f in files:
- src = os.path.join(root, f)
- dst = os.path.join(dst_root, f)
- p = os.path.normpath(os.path.join(rel_root, f))
- if file_list is not None and p not in file_list:
- continue
- if os.path.lexists(dst):
- if args.ignore_duplicates:
- continue
- sys.exit(f"error: {p} exists in both {args.out_dir} and {in_dir}")
-
- if not made_parent_dirs:
- os.makedirs(dst_root, exist_ok=True)
- made_parent_dirs = True
-
- shutil.copy2(src, dst, follow_symlinks=False)
-
-if __name__ == "__main__":
- main()
diff --git a/scripts/run-soong-tests-with-go-tools.sh b/scripts/run-soong-tests-with-go-tools.sh
index 1fbb1fc..82efaa0 100755
--- a/scripts/run-soong-tests-with-go-tools.sh
+++ b/scripts/run-soong-tests-with-go-tools.sh
@@ -38,6 +38,11 @@
CLANG_VERSION=$(build/soong/scripts/get_clang_version.py)
export CC="${TOP}/prebuilts/clang/host/${OS}-x86/${CLANG_VERSION}/bin/clang"
export CXX="${TOP}/prebuilts/clang/host/${OS}-x86/${CLANG_VERSION}/bin/clang++"
+ glibc_dir="${TOP}/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8"
+ export CGO_CFLAGS="--sysroot ${glibc_dir}/sysroot/"
+ export CGO_CPPFLAGS="--sysroot ${glibc_dir}/sysroot/"
+ export CGO_CXXFLAGS="--sysroot ${glibc_dir}/sysroot/"
+ export CGO_LDFLAGS="--sysroot ${glibc_dir}/sysroot/ -B ${glibc_dir}/lib/gcc/x86_64-linux/4.8.3 -L ${glibc_dir}/lib/gcc/x86_64-linux/4.8.3 -L ${glibc_dir}/x86_64-linux/lib64"
fi
# androidmk_test.go gets confused if ANDROID_BUILD_TOP is set.
diff --git a/scripts/strip.sh b/scripts/strip.sh
index 8d69f0d..5320ef6 100755
--- a/scripts/strip.sh
+++ b/scripts/strip.sh
@@ -101,7 +101,12 @@
do_strip_keep_mini_debug_info_linux() {
rm -f "${outfile}.mini_debuginfo.xz"
local fail=
- "${CLANG_BIN}/llvm-strip" --strip-all --keep-section=.ARM.attributes --remove-section=.comment "${infile}" -o "${outfile}.tmp" || fail=true
+ if [ -z "${windows}" ]; then
+ "${CLANG_BIN}/llvm-strip" --strip-all --keep-section=.ARM.attributes --remove-section=.comment "${infile}" -o "${outfile}.tmp" || fail=true
+ else
+ # --keep-section not supported for Windows COFF.
+ fail=true
+ fi
if [ -z $fail ]; then
# create_minidebuginfo has issues with compressed debug sections. Just
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index 34e11f0..80ced00 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -66,6 +66,7 @@
exported_bootclasspath_fragments: [
"%s",
],
+ prefer: false,
}
`, apex, apexFile, fragment)),
android.FixtureAddFile(filepath.Join(dir, apexFile), nil),
@@ -73,6 +74,7 @@
}
func TestSnapshotWithBootclasspathFragment_ImageName(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
java.PrepareForTestWithDexpreopt,
@@ -225,8 +227,8 @@
checkBootJarsPackageCheckRule(t, result,
append(
[]string{
- "out/soong/.intermediates/prebuilts/apex/com.android.art/android_common_com.android.art/deapexer/javalib/core1.jar",
- "out/soong/.intermediates/prebuilts/apex/com.android.art/android_common_com.android.art/deapexer/javalib/core2.jar",
+ "out/soong/.intermediates/prebuilts/apex/com.android.art/android_common_prebuilt_com.android.art/deapexer/javalib/core1.jar",
+ "out/soong/.intermediates/prebuilts/apex/com.android.art/android_common_prebuilt_com.android.art/deapexer/javalib/core2.jar",
"out/soong/.intermediates/default/java/framework/android_common/aligned/framework.jar",
},
java.ApexBootJarDexJarPaths...,
@@ -270,7 +272,7 @@
// package check rule.
func checkBootJarsPackageCheckRule(t *testing.T, result *android.TestResult, expectedModules ...string) {
t.Helper()
- platformBcp := result.ModuleForTests("platform-bootclasspath", "android_common")
+ platformBcp := result.ModuleForTests(t, "platform-bootclasspath", "android_common")
bootJarsCheckRule := platformBcp.Rule("boot_jars_package_check")
command := bootJarsCheckRule.RuleParams.Command
expectedCommandArgs := " build/soong/scripts/check_boot_jars/package_allowed_list.txt " + strings.Join(expectedModules, " ") + " &&"
@@ -479,7 +481,7 @@
checkAllCopyRules(copyRules),
snapshotTestPreparer(checkSnapshotWithoutSource, preparerForSnapshot),
snapshotTestChecker(checkSnapshotWithoutSource, func(t *testing.T, result *android.TestResult) {
- module := result.ModuleForTests("platform-bootclasspath", "android_common")
+ module := result.ModuleForTests(t, "platform-bootclasspath", "android_common")
var rule android.TestingBuildParams
rule = module.Output("out/soong/hiddenapi/hiddenapi-flags.csv")
java.CheckHiddenAPIRuleInputs(t, "monolithic flags", `
@@ -505,7 +507,7 @@
}),
snapshotTestPreparer(checkSnapshotWithSourcePreferred, preparerForSnapshot),
snapshotTestChecker(checkSnapshotWithSourcePreferred, func(t *testing.T, result *android.TestResult) {
- module := result.ModuleForTests("platform-bootclasspath", "android_common")
+ module := result.ModuleForTests(t, "platform-bootclasspath", "android_common")
rule := module.Output("out/soong/hiddenapi/hiddenapi-flags.csv.valid")
android.AssertStringDoesContain(t, "verify-overlaps", rule.RuleParams.Command, " out/soong/.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/filtered-flags.csv:out/soong/.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv ")
}),
@@ -514,7 +516,9 @@
}
func TestSnapshotWithBootClasspathFragment_Contents(t *testing.T) {
+ t.Parallel()
t.Run("added-directly", func(t *testing.T) {
+ t.Parallel()
testSnapshotWithBootClasspathFragment_Contents(t, `
sdk {
name: "mysdk",
@@ -566,6 +570,7 @@
.intermediates/mycoreplatform.stubs.source/android_common/exportable/mycoreplatform.stubs.source_removed.txt -> sdk_library/public/mycoreplatform-removed.txt
`
t.Run("added-via-apex", func(t *testing.T) {
+ t.Parallel()
testSnapshotWithBootClasspathFragment_Contents(t, `
sdk {
name: "mysdk",
@@ -575,6 +580,7 @@
})
t.Run("added-directly-and-indirectly", func(t *testing.T) {
+ t.Parallel()
testSnapshotWithBootClasspathFragment_Contents(t, `
sdk {
name: "mysdk",
@@ -599,6 +605,7 @@
// TestSnapshotWithBootClasspathFragment_Fragments makes sure that the fragments property of a
// bootclasspath_fragment is correctly output to the sdk snapshot.
func TestSnapshotWithBootClasspathFragment_Fragments(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
java.PrepareForTestWithJavaDefaultModules,
@@ -734,9 +741,11 @@
// Test that bootclasspath_fragment works with sdk.
func TestBasicSdkWithBootclasspathFragment(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForSdkTestWithApex,
prepareForSdkTestWithJava,
+ java.PrepareForTestWithJavaDefaultModules,
android.FixtureMergeMockFs(android.MockFS{
"java/mybootlib.jar": nil,
"hiddenapi/annotation-flags.csv": nil,
@@ -752,6 +761,13 @@
bootclasspath_fragments: ["mybootclasspathfragment"],
}
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ min_sdk_version: "1",
+ bootclasspath_fragments: ["mybootclasspathfragment"],
+ }
+
bootclasspath_fragment {
name: "mybootclasspathfragment",
image_name: "art",
@@ -794,7 +810,7 @@
java_import {
name: "mybootlib",
visibility: ["//visibility:public"],
- apex_available: ["com.android.art"],
+ apex_available: ["myapex"],
jars: ["java/mybootlib.jar"],
}
`),
@@ -802,6 +818,7 @@
}
func TestSnapshotWithBootclasspathFragment_HiddenAPI(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
java.PrepareForTestWithJavaDefaultModules,
@@ -1116,7 +1133,7 @@
`),
).RunTest(t)
- bcpf := result.ModuleForTests("mybootclasspathfragment", "android_common")
+ bcpf := result.ModuleForTests(t, "mybootclasspathfragment", "android_common")
rule := bcpf.Output("out/soong/.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi" + suffix + "/stub-flags.csv")
android.AssertPathsRelativeToTopEquals(t, "stub flags inputs", android.SortedUniqueStrings(expectedStubFlagsInputs), android.SortedUniquePaths(rule.Implicits))
@@ -1127,7 +1144,9 @@
}
func TestSnapshotWithBootClasspathFragment_MinSdkVersion(t *testing.T) {
+ t.Parallel()
t.Run("target S build", func(t *testing.T) {
+ t.Parallel()
expectedSnapshot := `
// This is auto-generated. DO NOT EDIT.
@@ -1184,6 +1203,7 @@
})
t.Run("target-Tiramisu-build", func(t *testing.T) {
+ t.Parallel()
expectedSnapshot := `
// This is auto-generated. DO NOT EDIT.
@@ -1268,6 +1288,7 @@
}
func TestSnapshotWithEmptyBootClasspathFragment(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
java.PrepareForTestWithJavaDefaultModules,
diff --git a/sdk/bp_test.go b/sdk/bp_test.go
index c620ac2..d3eaafe 100644
--- a/sdk/bp_test.go
+++ b/sdk/bp_test.go
@@ -73,6 +73,7 @@
}
func TestAddPropertySimple(t *testing.T) {
+ t.Parallel()
set := newPropertySet()
for name, val := range map[string]interface{}{
"x": "taxi",
@@ -91,14 +92,17 @@
}
func TestAddPropertySubset(t *testing.T) {
+ t.Parallel()
getFixtureMap := map[string]func() interface{}{
"property set": propertySetFixture,
"property struct": propertyStructFixture,
}
t.Run("add new subset", func(t *testing.T) {
+ t.Parallel()
for name, getFixture := range getFixtureMap {
t.Run(name, func(t *testing.T) {
+ t.Parallel()
set := propertySetFixture().(*bpPropertySet)
set.AddProperty("new", getFixture())
checkPropertySetFixture(t, set, true)
@@ -108,8 +112,10 @@
})
t.Run("merge existing subset", func(t *testing.T) {
+ t.Parallel()
for name, getFixture := range getFixtureMap {
t.Run(name, func(t *testing.T) {
+ t.Parallel()
set := newPropertySet()
subset := set.AddPropertySet("sub")
subset.AddProperty("flag", false)
@@ -123,12 +129,14 @@
})
t.Run("add conflicting subset", func(t *testing.T) {
+ t.Parallel()
set := propertySetFixture().(*bpPropertySet)
android.AssertPanicMessageContains(t, "adding x again should panic", `Property "x" already exists in property set`,
func() { set.AddProperty("x", propertySetFixture()) })
})
t.Run("add non-pointer struct", func(t *testing.T) {
+ t.Parallel()
set := propertySetFixture().(*bpPropertySet)
str := propertyStructFixture().(*propertyStruct)
android.AssertPanicMessageContains(t, "adding a non-pointer struct should panic", "Value is a struct, not a pointer to one:",
@@ -137,6 +145,7 @@
}
func TestAddPropertySetNew(t *testing.T) {
+ t.Parallel()
set := newPropertySet()
subset := set.AddPropertySet("sub")
subset.AddProperty("new", "d^^b")
@@ -144,6 +153,7 @@
}
func TestAddPropertySetExisting(t *testing.T) {
+ t.Parallel()
set := propertySetFixture().(*bpPropertySet)
subset := set.AddPropertySet("sub")
subset.AddProperty("new", "d^^b")
@@ -176,6 +186,7 @@
}
func TestTransformRemoveProperty(t *testing.T) {
+ t.Parallel()
set := newPropertySet()
set.AddProperty("name", "name")
set.AddProperty("fred", "12")
@@ -188,6 +199,7 @@
}
func TestTransformRemovePropertySet(t *testing.T) {
+ t.Parallel()
set := newPropertySet()
set.AddProperty("name", "name")
set.AddPropertySet("fred")
diff --git a/sdk/build_release.go b/sdk/build_release.go
index 6bb05a3..3656c98 100644
--- a/sdk/build_release.go
+++ b/sdk/build_release.go
@@ -101,6 +101,8 @@
buildReleaseS = initBuildRelease("S")
buildReleaseT = initBuildRelease("Tiramisu")
buildReleaseU = initBuildRelease("UpsideDownCake")
+ buildReleaseV = initBuildRelease("VanillaIceCream")
+ buildReleaseB = initBuildRelease("Baklava")
// Add the current build release which is always treated as being more recent than any other
// build release, including those added in tests.
diff --git a/sdk/build_release_test.go b/sdk/build_release_test.go
index 5bf57b5..07f99ee 100644
--- a/sdk/build_release_test.go
+++ b/sdk/build_release_test.go
@@ -42,7 +42,7 @@
android.AssertDeepEquals(t, "release", (*buildRelease)(nil), release)
// Uses a wildcard in the error message to allow for additional build releases to be added to
// the supported set without breaking this test.
- android.FailIfNoMatchingErrors(t, `unknown release "A", expected one of \[S,Tiramisu,UpsideDownCake,F1,F2,current\]`, []error{err})
+ android.FailIfNoMatchingErrors(t, `unknown release "A", expected one of \[S,Tiramisu,UpsideDownCake,VanillaIceCream,Baklava,F1,F2,current\]`, []error{err})
})
}
@@ -60,7 +60,7 @@
t.Run("closed range", func(t *testing.T) {
set, err := parseBuildReleaseSet("S-F1")
android.AssertDeepEquals(t, "errors", nil, err)
- android.AssertStringEquals(t, "set", "[S,Tiramisu,UpsideDownCake,F1]", set.String())
+ android.AssertStringEquals(t, "set", "[S,Tiramisu,UpsideDownCake,VanillaIceCream,Baklava,F1]", set.String())
})
invalidAReleaseMessage := `unknown release "A", expected one of ` + allBuildReleaseSet.String()
t.Run("invalid release", func(t *testing.T) {
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index 25839b8..bf4ac13 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -58,6 +58,7 @@
// Contains tests for SDK members provided by the cc package.
func TestSingleDeviceOsAssumption(t *testing.T) {
+ t.Parallel()
// Mock a module with DeviceSupported() == true.
s := &sdk{}
android.InitAndroidArchModule(s, android.DeviceSupported, android.MultilibCommon)
@@ -72,6 +73,7 @@
}
func TestSdkIsCompileMultilibBoth(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
sdk {
name: "mysdk",
@@ -102,6 +104,7 @@
}
func TestSdkCompileMultilibOverride(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
sdk {
name: "mysdk",
@@ -161,6 +164,7 @@
// Make sure the sdk can use host specific cc libraries static/shared and both.
func TestHostSdkWithCc(t *testing.T) {
+ t.Parallel()
testSdkWithCc(t, `
sdk {
name: "mysdk",
@@ -184,6 +188,7 @@
// Make sure the sdk can use cc libraries static/shared and both.
func TestSdkWithCc(t *testing.T) {
+ t.Parallel()
testSdkWithCc(t, `
sdk {
name: "mysdk",
@@ -214,6 +219,7 @@
}
func TestSnapshotWithObject(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
sdk {
name: "mysdk",
@@ -268,6 +274,7 @@
}
func TestSnapshotWithCcDuplicateHeaders(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
sdk {
name: "mysdk",
@@ -305,6 +312,7 @@
}
func TestSnapshotWithCcExportGeneratedHeaders(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
sdk {
name: "mysdk",
@@ -393,6 +401,7 @@
// handling is tested with the sanitize clauses (but note there's a lot of
// built-in logic in sanitize.go that can affect those flags).
func TestSnapshotWithCcSharedLibraryCommonProperties(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
sdk {
name: "mysdk",
@@ -475,6 +484,7 @@
}
func TestSnapshotWithCcBinary(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
module_exports {
name: "mymodule_exports",
@@ -523,6 +533,7 @@
}
func TestMultipleHostOsTypesSnapshotWithCcBinary(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
module_exports {
name: "myexports",
@@ -604,6 +615,7 @@
}
func TestSnapshotWithSingleHostOsType(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTest,
ccTestFs.AddToFixture(),
@@ -721,6 +733,7 @@
// Test that we support the necessary flags for the linker binary, which is
// special in several ways.
func TestSnapshotWithCcStaticNocrtBinary(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
module_exports {
name: "mymodule_exports",
@@ -785,19 +798,26 @@
}
func TestSnapshotWithCcSharedLibrary(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
sdk {
name: "mysdk",
native_shared_libs: ["mynativelib"],
}
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ min_sdk_version: "1",
+ }
+
cc_library_shared {
name: "mynativelib",
srcs: [
"Test.cpp",
"aidl/foo/bar/Test.aidl",
],
- apex_available: ["apex1", "apex2"],
+ apex_available: ["myapex"],
export_include_dirs: ["myinclude"],
aidl: {
export_aidl_headers: true,
@@ -807,6 +827,18 @@
`)
CheckSnapshot(t, result, "mysdk", "",
+ snapshotTestPreparer(checkSnapshotWithoutSource,
+ android.FixtureMergeMockFs(android.MockFS{
+ "myapex/Android.bp": []byte(`
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ min_sdk_version: "1",
+ }
+ `),
+ "myapex/apex_manifest.json": nil,
+ }),
+ ),
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
@@ -819,10 +851,7 @@
name: "mynativelib",
prefer: false,
visibility: ["//visibility:public"],
- apex_available: [
- "apex1",
- "apex2",
- ],
+ apex_available: ["myapex"],
stl: "none",
compile_multilib: "both",
export_include_dirs: ["include/myinclude"],
@@ -856,6 +885,7 @@
}
func TestSnapshotWithCcSharedLibrarySharedLibs(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
sdk {
name: "mysdk",
@@ -1005,6 +1035,7 @@
}
func TestHostSnapshotWithCcSharedLibrary(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
sdk {
name: "mysdk",
@@ -1085,6 +1116,7 @@
}
func TestMultipleHostOsTypesSnapshotWithCcSharedLibrary(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
sdk {
name: "mysdk",
@@ -1168,6 +1200,7 @@
}
func TestSnapshotWithCcStaticLibrary(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
module_exports {
name: "myexports",
@@ -1232,6 +1265,7 @@
}
func TestHostSnapshotWithCcStaticLibrary(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
module_exports {
name: "myexports",
@@ -1307,6 +1341,7 @@
}
func TestSnapshotWithCcLibrary(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
module_exports {
name: "myexports",
@@ -1370,12 +1405,11 @@
.intermediates/mynativelib/android_arm_armv7-a-neon_static/mynativelib.a -> arm/lib/mynativelib.a
.intermediates/mynativelib/android_arm_armv7-a-neon_shared/mynativelib.so -> arm/lib/mynativelib.so
`),
- // TODO(b/183315522): Remove this and fix the issue.
- snapshotTestErrorHandler(checkSnapshotPreferredWithSource, android.FixtureExpectsAtLeastOneErrorMatchingPattern(`\Qunrecognized property "arch.arm.shared.export_include_dirs"\E`)),
)
}
func TestSnapshotSameLibraryWithNativeLibsAndNativeSharedLib(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
module_exports {
host_supported: true,
@@ -1477,6 +1511,7 @@
}
func TestSnapshotSameLibraryWithAndroidNativeLibsAndHostNativeSharedLib(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
module_exports {
host_supported: true,
@@ -1578,6 +1613,7 @@
}
func TestSnapshotSameLibraryWithNativeStaticLibsAndNativeSharedLib(t *testing.T) {
+ t.Parallel()
testSdkError(t, "Incompatible member types", `
module_exports {
host_supported: true,
@@ -1609,6 +1645,7 @@
}
func TestHostSnapshotWithMultiLib64(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
module_exports {
name: "myexports",
@@ -1682,6 +1719,7 @@
}
func TestSnapshotWithCcHeadersLibrary(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
sdk {
name: "mysdk",
@@ -1721,6 +1759,7 @@
}
func TestSnapshotWithCcHeadersLibraryAndNativeBridgeSupport(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
cc.PrepareForTestWithCcDefaultModules,
PrepareForTestWithSdkBuildComponents,
@@ -1778,6 +1817,7 @@
// module that has different output files for a native bridge target requests the native bridge
// variants are copied into the sdk snapshot that it reports an error.
func TestSnapshotWithCcHeadersLibrary_DetectsNativeBridgeSpecificProperties(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
cc.PrepareForTestWithCcDefaultModules,
PrepareForTestWithSdkBuildComponents,
@@ -1814,6 +1854,7 @@
}
func TestSnapshotWithCcHeadersLibraryAndImageVariants(t *testing.T) {
+ t.Parallel()
testImageVariant := func(t *testing.T, property, trait string) {
result := android.GroupFixturePreparers(
cc.PrepareForTestWithCcDefaultModules,
@@ -1877,6 +1918,7 @@
}
func TestHostSnapshotWithCcHeadersLibrary(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
sdk {
name: "mysdk",
@@ -1933,6 +1975,7 @@
}
func TestDeviceAndHostSnapshotWithCcHeadersLibrary(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
sdk {
name: "mysdk",
@@ -2002,6 +2045,7 @@
}
func TestSystemSharedLibPropagation(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
sdk {
name: "mysdk",
@@ -2162,6 +2206,7 @@
}
func TestStubsLibrary(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
sdk {
name: "mysdk",
@@ -2223,6 +2268,7 @@
}
func TestDeviceAndHostSnapshotWithStubsLibrary(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
sdk {
name: "mysdk",
@@ -2299,6 +2345,7 @@
}
func TestUniqueHostSoname(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
sdk {
name: "mysdk",
@@ -2364,6 +2411,7 @@
}
func TestNoSanitizerMembers(t *testing.T) {
+ t.Parallel()
result := testSdkWithCc(t, `
sdk {
name: "mysdk",
diff --git a/sdk/compat_config_sdk_test.go b/sdk/compat_config_sdk_test.go
index 75b5229..1737b3a 100644
--- a/sdk/compat_config_sdk_test.go
+++ b/sdk/compat_config_sdk_test.go
@@ -76,6 +76,7 @@
}
func TestSnapshotWithCompatConfig(t *testing.T) {
+ t.Parallel()
testSnapshotWithCompatConfig(t, `
sdk {
name: "mysdk",
@@ -85,6 +86,7 @@
}
func TestSnapshotWithCompatConfig_Apex(t *testing.T) {
+ t.Parallel()
testSnapshotWithCompatConfig(t, `
apex {
name: "myapex",
diff --git a/sdk/exports_test.go b/sdk/exports_test.go
index 9d0a242..5a7ce84 100644
--- a/sdk/exports_test.go
+++ b/sdk/exports_test.go
@@ -20,6 +20,7 @@
// Ensure that module_exports generates a module_exports_snapshot module.
func TestModuleExportsSnapshot(t *testing.T) {
+ t.Parallel()
packageBp := `
module_exports {
name: "myexports",
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 4db163c..1e545ce 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -51,6 +51,7 @@
// Contains tests for SDK members provided by the java package.
func TestSdkDependsOnSourceEvenWhenPrebuiltPreferred(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(prepareForSdkTestWithJava).RunTestWithBp(t, `
sdk {
name: "mysdk",
@@ -77,6 +78,7 @@
}
func TestSnapshotWithJavaHeaderLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
android.FixtureAddFile("aidl/foo/bar/Test.aidl", nil),
@@ -126,6 +128,7 @@
}
func TestHostSnapshotWithJavaHeaderLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
android.FixtureAddFile("aidl/foo/bar/Test.aidl", nil),
@@ -178,6 +181,7 @@
}
func TestDeviceAndHostSnapshotWithJavaHeaderLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(prepareForSdkTestWithJava).RunTestWithBp(t, `
sdk {
name: "mysdk",
@@ -228,6 +232,7 @@
}
func TestSnapshotWithJavaImplLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
android.FixtureAddFile("aidl/foo/bar/Test.aidl", nil),
@@ -277,6 +282,7 @@
}
func TestSnapshotWithJavaBootLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
android.FixtureAddFile("aidl", nil),
@@ -328,6 +334,7 @@
}
func TestSnapshotWithJavaBootLibrary_UpdatableMedia(t *testing.T) {
+ t.Parallel()
runTest := func(t *testing.T, targetBuildRelease, expectedJarPath, expectedCopyRule string) {
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
@@ -385,6 +392,7 @@
}
func TestSnapshotWithJavaLibrary_MinSdkVersion(t *testing.T) {
+ t.Parallel()
runTest := func(t *testing.T, targetBuildRelease, minSdkVersion, expectedMinSdkVersion string) {
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
@@ -457,6 +465,7 @@
}
func TestSnapshotWithJavaSystemserverLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
android.FixtureAddFile("aidl", nil),
@@ -509,6 +518,7 @@
}
func TestHostSnapshotWithJavaImplLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
android.FixtureAddFile("aidl/foo/bar/Test.aidl", nil),
@@ -561,6 +571,7 @@
}
func TestSnapshotWithJavaTest(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(prepareForSdkTestWithJava).RunTestWithBp(t, `
module_exports {
name: "myexports",
@@ -603,6 +614,7 @@
}
func TestHostSnapshotWithJavaTest(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(prepareForSdkTestWithJava).RunTestWithBp(t, `
module_exports {
name: "myexports",
@@ -650,6 +662,7 @@
}
func TestSnapshotWithJavaSystemModules(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
java.PrepareForTestWithJavaDefaultModules,
@@ -853,6 +866,7 @@
}
func TestHostSnapshotWithJavaSystemModules(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(prepareForSdkTestWithJava).RunTestWithBp(t, `
sdk {
name: "mysdk",
@@ -911,6 +925,7 @@
}
func TestDeviceAndHostSnapshotWithOsSpecificMembers(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(prepareForSdkTestWithJava).RunTestWithBp(t, `
module_exports {
name: "myexports",
@@ -1004,6 +1019,7 @@
}
func TestSnapshotWithJavaSdkLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(prepareForSdkTestWithJavaSdkLibrary).RunTestWithBp(t, `
sdk {
name: "mysdk",
@@ -1081,6 +1097,7 @@
}
func TestSnapshotWithJavaSdkLibrary_DistStem(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(prepareForSdkTestWithJavaSdkLibrary).RunTestWithBp(t, `
sdk {
name: "mysdk",
@@ -1136,6 +1153,7 @@
}
func TestSnapshotWithJavaSdkLibrary_UseSrcJar(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJavaSdkLibrary,
android.FixtureMergeEnv(map[string]string{
@@ -1192,6 +1210,7 @@
}
func TestSnapshotWithJavaSdkLibrary_AnnotationsZip(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(prepareForSdkTestWithJavaSdkLibrary).RunTestWithBp(t, `
sdk {
name: "mysdk",
@@ -1246,6 +1265,7 @@
}
func TestSnapshotWithJavaSdkLibrary_AnnotationsZip_PreT(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJavaSdkLibrary,
android.FixtureMergeEnv(map[string]string{
@@ -1303,6 +1323,7 @@
}
func TestSnapshotWithJavaSdkLibrary_CompileDex(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJavaSdkLibrary,
android.PrepareForTestWithBuildFlag("RELEASE_HIDDEN_API_EXPORTABLE_STUBS", "true"),
@@ -1385,6 +1406,7 @@
}
func TestSnapshotWithJavaSdkLibrary_SdkVersion_None(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(prepareForSdkTestWithJavaSdkLibrary).RunTestWithBp(t, `
sdk {
name: "mysdk",
@@ -1435,6 +1457,7 @@
}
func TestSnapshotWithJavaSdkLibrary_SdkVersion_ForScope(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(prepareForSdkTestWithJavaSdkLibrary).RunTestWithBp(t, `
sdk {
name: "mysdk",
@@ -1488,6 +1511,7 @@
}
func TestSnapshotWithJavaSdkLibrary_ApiScopes(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(prepareForSdkTestWithJavaSdkLibrary).RunTestWithBp(t, `
sdk {
name: "mysdk",
@@ -1555,6 +1579,7 @@
}
func TestSnapshotWithJavaSdkLibrary_ModuleLib(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(prepareForSdkTestWithJavaSdkLibrary).RunTestWithBp(t, `
sdk {
name: "mysdk",
@@ -1636,6 +1661,7 @@
}
func TestSnapshotWithJavaSdkLibrary_SystemServer(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(prepareForSdkTestWithJavaSdkLibrary).RunTestWithBp(t, `
sdk {
name: "mysdk",
@@ -1703,6 +1729,7 @@
}
func TestSnapshotWithJavaSdkLibrary_DoctagFiles(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJavaSdkLibrary,
android.FixtureAddFile("docs/known_doctags", nil),
diff --git a/sdk/license_sdk_test.go b/sdk/license_sdk_test.go
index 754f019..eb8112b 100644
--- a/sdk/license_sdk_test.go
+++ b/sdk/license_sdk_test.go
@@ -21,6 +21,7 @@
)
func TestSnapshotWithPackageDefaultLicense(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
android.PrepareForTestWithLicenses,
diff --git a/sdk/member_trait_test.go b/sdk/member_trait_test.go
index 673d6fb..9b41e9b 100644
--- a/sdk/member_trait_test.go
+++ b/sdk/member_trait_test.go
@@ -116,6 +116,7 @@
}
func TestBasicTrait_WithoutTrait(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
android.FixtureWithRootAndroidBp(`
@@ -154,6 +155,7 @@
}
func TestBasicTrait_MultipleTraits(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
android.FixtureWithRootAndroidBp(`
@@ -262,6 +264,7 @@
}
func TestTraitUnsupportedByMemberType(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForSdkTestWithJava,
android.FixtureWithRootAndroidBp(`
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index 2532a25..985641e 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -40,6 +40,7 @@
// Ensure that prebuilt modules have the same effective visibility as the source
// modules.
func TestSnapshotVisibility(t *testing.T) {
+ t.Parallel()
packageBp := `
package {
default_visibility: ["//other/foo"],
@@ -160,6 +161,7 @@
}
func TestSdkInstall(t *testing.T) {
+ t.Parallel()
sdk := `
sdk {
name: "mysdk",
@@ -326,6 +328,7 @@
// Ensure that sdk snapshot related environment variables work correctly.
func TestSnapshot_EnvConfiguration(t *testing.T) {
+ t.Parallel()
bp := `
sdk {
name: "mysdk",
@@ -347,11 +350,12 @@
)
checkZipFile := func(t *testing.T, result *android.TestResult, expected string) {
- zipRule := result.ModuleForTests("mysdk", "common_os").Rule("SnapshotZipFiles")
+ zipRule := result.ModuleForTests(t, "mysdk", "common_os").Rule("SnapshotZipFiles")
android.AssertStringEquals(t, "snapshot zip file", expected, zipRule.Output.String())
}
t.Run("no env variables", func(t *testing.T) {
+ t.Parallel()
result := preparer.RunTest(t)
checkZipFile(t, result, "out/soong/.intermediates/mysdk/common_os/mysdk-current.zip")
@@ -377,6 +381,7 @@
})
t.Run("SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE=S", func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
java.PrepareForTestWithJavaDefaultModules,
@@ -468,6 +473,7 @@
})
t.Run("test replacing exportable module", func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
java.PrepareForTestWithJavaDefaultModules,
diff --git a/sdk/systemserverclasspath_fragment_sdk_test.go b/sdk/systemserverclasspath_fragment_sdk_test.go
index fd6c4e7..7ebdcd4 100644
--- a/sdk/systemserverclasspath_fragment_sdk_test.go
+++ b/sdk/systemserverclasspath_fragment_sdk_test.go
@@ -87,10 +87,23 @@
CheckSnapshot(t, result, "mysdk", "",
checkAndroidBpContents(expectedSdkSnapshot),
+ snapshotTestPreparer(checkSnapshotWithoutSource,
+ android.FixtureMergeMockFs(android.MockFS{
+ "myapex/Android.bp": []byte(`
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ min_sdk_version: "1",
+ }
+ `),
+ "myapex/apex_manifest.json": nil,
+ }),
+ ),
)
}
func TestSnapshotWithPartialSystemServerClasspathFragment(t *testing.T) {
+ t.Parallel()
commonSdk := `
apex {
name: "myapex",
@@ -185,6 +198,7 @@
}
func TestSnapshotWithEmptySystemServerClasspathFragment(t *testing.T) {
+ t.Parallel()
commonSdk := `
apex {
name: "myapex",
@@ -231,6 +245,7 @@
}
func TestSnapshotWithSystemServerClasspathFragment(t *testing.T) {
+ t.Parallel()
commonSdk := `
sdk {
@@ -298,6 +313,7 @@
`
t.Run("target-s", func(t *testing.T) {
+ t.Parallel()
testSnapshotWithSystemServerClasspathFragment(t, commonSdk, "S", `
// This is auto-generated. DO NOT EDIT.
@@ -319,6 +335,7 @@
})
t.Run("target-t", func(t *testing.T) {
+ t.Parallel()
testSnapshotWithSystemServerClasspathFragment(t, commonSdk, "Tiramisu", `
// This is auto-generated. DO NOT EDIT.
@@ -361,6 +378,7 @@
})
t.Run("target-u", func(t *testing.T) {
+ t.Parallel()
testSnapshotWithSystemServerClasspathFragment(t, commonSdk, "UpsideDownCake", `
// This is auto-generated. DO NOT EDIT.
@@ -409,10 +427,12 @@
})
t.Run("added-directly", func(t *testing.T) {
+ t.Parallel()
testSnapshotWithSystemServerClasspathFragment(t, commonSdk, `latest`, expectedLatestSnapshot)
})
t.Run("added-via-apex", func(t *testing.T) {
+ t.Parallel()
testSnapshotWithSystemServerClasspathFragment(t, `
sdk {
name: "mysdk",
diff --git a/sdk/testing.go b/sdk/testing.go
index f4e2b03..cd7bbf5 100644
--- a/sdk/testing.go
+++ b/sdk/testing.go
@@ -128,12 +128,11 @@
// generated, etc.
func getSdkSnapshotBuildInfo(t *testing.T, result *android.TestResult, sdk *sdk) *snapshotBuildInfo {
info := &snapshotBuildInfo{
- t: t,
- r: result,
- androidBpContents: sdk.GetAndroidBpContentsForTests(),
- infoContents: sdk.GetInfoContentsForTests(),
- snapshotTestCustomizations: map[snapshotTest]*snapshotTestCustomization{},
- targetBuildRelease: sdk.builderForTests.targetBuildRelease,
+ t: t,
+ r: result,
+ androidBpContents: sdk.GetAndroidBpContentsForTests(),
+ infoContents: sdk.GetInfoContentsForTests(),
+ targetBuildRelease: sdk.builderForTests.targetBuildRelease,
}
buildParams := sdk.BuildParamsForTests()
@@ -144,7 +143,7 @@
seenBuildNumberFile := false
for _, bp := range buildParams {
switch bp.Rule.String() {
- case android.Cp.String():
+ case android.Cp.String(), android.CpWithBash.String():
output := bp.Output
// Get destination relative to the snapshot root
dest := output.Rel()
@@ -282,7 +281,7 @@
// Run the snapshot with the snapshot preparer and the extra preparer, which must come after as
// it may need to modify parts of the MockFS populated by the snapshot preparer.
- result := android.GroupFixturePreparers(snapshotPreparer, extraPreparer, customizedPreparers).
+ result := android.GroupFixturePreparers(snapshotPreparer, customizedPreparers, extraPreparer).
ExtendWithErrorHandler(customization.errorHandler).
RunTest(t)
@@ -293,6 +292,7 @@
}
t.Run("snapshot without source", func(t *testing.T) {
+ t.Parallel()
// Remove the source Android.bp file to make sure it works without.
removeSourceAndroidBp := android.FixtureModifyMockFS(func(fs android.MockFS) {
delete(fs, "Android.bp")
@@ -302,16 +302,23 @@
})
t.Run("snapshot with source preferred", func(t *testing.T) {
+ t.Parallel()
runSnapshotTestWithCheckers(t, checkSnapshotWithSourcePreferred, android.NullFixturePreparer)
})
t.Run("snapshot preferred with source", func(t *testing.T) {
+ t.Parallel()
// Replace the snapshot/Android.bp file with one where "prefer: false," has been replaced with
// "prefer: true,"
preferPrebuilts := android.FixtureModifyMockFS(func(fs android.MockFS) {
snapshotBpFile := filepath.Join(snapshotSubDir, "Android.bp")
unpreferred := string(fs[snapshotBpFile])
fs[snapshotBpFile] = []byte(strings.ReplaceAll(unpreferred, "prefer: false,", "prefer: true,"))
+
+ prebuiltApexBpFile := "prebuilts/apex/Android.bp"
+ if prebuiltApexBp, ok := fs[prebuiltApexBpFile]; ok {
+ fs[prebuiltApexBpFile] = []byte(strings.ReplaceAll(string(prebuiltApexBp), "prefer: false,", "prefer: true,"))
+ }
})
runSnapshotTestWithCheckers(t, checkSnapshotPreferredWithSource, preferPrebuilts)
@@ -469,19 +476,40 @@
targetBuildRelease *buildRelease
// The test specific customizations for each snapshot test.
- snapshotTestCustomizations map[snapshotTest]*snapshotTestCustomization
+ snapshotTestCustomizations snapshotTestCustomizationSet
+}
+
+type snapshotTestCustomizationSet struct {
+ snapshotWithoutSource *snapshotTestCustomization
+ snapshotWithSourcePreferred *snapshotTestCustomization
+ snapshotPreferredWithSource *snapshotTestCustomization
+}
+
+func (s *snapshotTestCustomizationSet) customization(snapshotTest snapshotTest) **snapshotTestCustomization {
+ var customization **snapshotTestCustomization
+ switch snapshotTest {
+ case checkSnapshotWithoutSource:
+
+ customization = &s.snapshotWithoutSource
+ case checkSnapshotWithSourcePreferred:
+ customization = &s.snapshotWithSourcePreferred
+ case checkSnapshotPreferredWithSource:
+ customization = &s.snapshotPreferredWithSource
+ default:
+ panic(fmt.Errorf("unsupported snapshotTest %v", snapshotTest))
+ }
+ return customization
}
// snapshotTestCustomization gets the test specific customization for the specified snapshotTest.
//
// If no customization was created previously then it creates a default customization.
func (i *snapshotBuildInfo) snapshotTestCustomization(snapshotTest snapshotTest) *snapshotTestCustomization {
- customization := i.snapshotTestCustomizations[snapshotTest]
- if customization == nil {
- customization = &snapshotTestCustomization{
+ customization := i.snapshotTestCustomizations.customization(snapshotTest)
+ if *customization == nil {
+ *customization = &snapshotTestCustomization{
errorHandler: android.FixtureExpectsNoErrors,
}
- i.snapshotTestCustomizations[snapshotTest] = customization
}
- return customization
+ return *customization
}
diff --git a/sdk/update.go b/sdk/update.go
index 5a899a2..00352cb 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -1145,7 +1145,7 @@
// The licenses are the same for all variants.
mctx := s.ctx
- licenseInfo, _ := android.OtherModuleProvider(mctx, variant, android.LicenseInfoProvider)
+ licenseInfo, _ := android.OtherModuleProvider(mctx, variant, android.LicensesInfoProvider)
if len(licenseInfo.Licenses) > 0 {
m.AddPropertyWithTag("licenses", licenseInfo.Licenses, s.OptionalSdkMemberReferencePropertyTag())
}
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 60c5317..f8d1ce5 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -41,6 +41,14 @@
registerShBuildComponents(android.InitRegistrationContext)
}
+type ShBinaryInfo struct {
+ SubDir string
+ OutputFile android.Path
+ Symlinks []string
+}
+
+var ShBinaryInfoProvider = blueprint.NewProvider[ShBinaryInfo]()
+
func registerShBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("sh_binary", ShBinaryFactory)
ctx.RegisterModuleType("sh_binary_host", ShBinaryHostFactory)
@@ -130,6 +138,11 @@
// host test.
Device_first_data []string `android:"path_device_first"`
+ // Same as data, but will add dependencies on modules using the host's os variation and
+ // the common arch variation. Useful for a device test that wants to depend on a host
+ // module, for example to include a custom Tradefed test runner.
+ Host_common_data []string `android:"path_host_common"`
+
// Add RootTargetPreparer to auto generated test config. This guarantees the test to run
// with root permission.
Require_root *bool
@@ -314,6 +327,12 @@
s.properties.SubName = s.GetSubname(ctx)
+ android.SetProvider(ctx, ShBinaryInfoProvider, ShBinaryInfo{
+ SubDir: s.SubDir(),
+ OutputFile: s.OutputFile(),
+ Symlinks: s.Symlinks(),
+ })
+
ctx.SetOutputFiles(android.Paths{s.outputFilePath}, "")
}
@@ -422,8 +441,9 @@
expandedData := android.PathsForModuleSrc(ctx, s.testProperties.Data)
expandedData = append(expandedData, android.PathsForModuleSrc(ctx, s.testProperties.Device_common_data)...)
expandedData = append(expandedData, android.PathsForModuleSrc(ctx, s.testProperties.Device_first_data)...)
+ expandedData = append(expandedData, android.PathsForModuleSrc(ctx, s.testProperties.Host_common_data)...)
// Emulate the data property for java_data dependencies.
- for _, javaData := range ctx.GetDirectDepsWithTag(shTestJavaDataTag) {
+ for _, javaData := range ctx.GetDirectDepsProxyWithTag(shTestJavaDataTag) {
expandedData = append(expandedData, android.OutputFilesForModule(ctx, javaData, "")...)
}
for _, d := range expandedData {
@@ -476,21 +496,24 @@
s.extraTestConfigs = android.PathsForModuleSrc(ctx, s.testProperties.Extra_test_configs)
s.dataModules = make(map[string]android.Path)
- ctx.VisitDirectDeps(func(dep android.Module) {
+ ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
depTag := ctx.OtherModuleDependencyTag(dep)
switch depTag {
case shTestDataBinsTag, shTestDataDeviceBinsTag:
path := android.OutputFileForModule(ctx, dep, "")
s.addToDataModules(ctx, path.Base(), path)
case shTestDataLibsTag, shTestDataDeviceLibsTag:
- if cc, isCc := dep.(*cc.Module); isCc {
+ if _, isCc := android.OtherModuleProvider(ctx, dep, cc.CcInfoProvider); isCc {
// Copy to an intermediate output directory to append "lib[64]" to the path,
// so that it's compatible with the default rpath values.
var relPath string
- if cc.Arch().ArchType.Multilib == "lib64" {
- relPath = filepath.Join("lib64", cc.OutputFile().Path().Base())
+ linkableInfo := android.OtherModuleProviderOrDefault(ctx, dep, cc.LinkableInfoProvider)
+ commonInfo := android.OtherModuleProviderOrDefault(ctx, dep, android.CommonModuleInfoKey)
+
+ if commonInfo.Target.Arch.ArchType.Multilib == "lib64" {
+ relPath = filepath.Join("lib64", linkableInfo.OutputFile.Path().Base())
} else {
- relPath = filepath.Join("lib", cc.OutputFile().Path().Base())
+ relPath = filepath.Join("lib", linkableInfo.OutputFile.Path().Base())
}
if _, exist := s.dataModules[relPath]; exist {
return
@@ -498,7 +521,7 @@
relocatedLib := android.PathForModuleOut(ctx, "relocated").Join(ctx, relPath)
ctx.Build(pctx, android.BuildParams{
Rule: android.Cp,
- Input: cc.OutputFile().Path(),
+ Input: linkableInfo.OutputFile.Path(),
Output: relocatedLib,
})
s.addToDataModules(ctx, relPath, relocatedLib)
@@ -527,6 +550,28 @@
MkAppClass: mkEntries.Class,
InstallDir: s.installDir,
})
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Class = []string{"NATIVE_TESTS"}
+ if len(s.testProperties.Test_suites) > 0 {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, s.testProperties.Test_suites...)
+ } else {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
+ }
+ if proptools.Bool(s.testProperties.Test_options.Unit_test) {
+ moduleInfoJSON.IsUnitTest = "true"
+ if ctx.Host() {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "host-unit-tests")
+ }
+ }
+ moduleInfoJSON.DataDependencies = append(moduleInfoJSON.DataDependencies, s.testProperties.Data_bins...)
+ if s.testConfig != nil {
+ if _, ok := s.testConfig.(android.WritablePath); ok {
+ moduleInfoJSON.AutoTestConfig = []string{"true"}
+ }
+ moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.testConfig.String())
+ }
+ moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.extraTestConfigs.Strings()...)
}
func addArch(archType string, paths android.Paths) []string {
diff --git a/sh/sh_binary_test.go b/sh/sh_binary_test.go
index 28f997d..c2e2d2b 100644
--- a/sh/sh_binary_test.go
+++ b/sh/sh_binary_test.go
@@ -58,7 +58,7 @@
}
`)
- mod := result.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*ShTest)
+ mod := result.ModuleForTests(t, "foo", "android_arm64_armv8-a").Module().(*ShTest)
entries := android.AndroidMkEntriesForTest(t, result.TestContext, mod)[0]
@@ -83,7 +83,7 @@
}
`)
- mod := result.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*ShTest)
+ mod := result.ModuleForTests(t, "foo", "android_arm64_armv8-a").Module().(*ShTest)
entries := android.AndroidMkEntriesForTest(t, result.TestContext, mod)[0]
@@ -129,7 +129,7 @@
buildOS := config.BuildOS.String()
arches := []string{"android_arm64_armv8-a", buildOS + "_x86_64"}
for _, arch := range arches {
- variant := ctx.ModuleForTests("foo", arch)
+ variant := ctx.ModuleForTests(t, "foo", arch)
libExt := ".so"
if arch == "darwin_x86_64" {
@@ -167,7 +167,7 @@
`)
buildOS := ctx.Config().BuildOS.String()
- mod := ctx.ModuleForTests("foo", buildOS+"_x86_64").Module().(*ShTest)
+ mod := ctx.ModuleForTests(t, "foo", buildOS+"_x86_64").Module().(*ShTest)
if !mod.Host() {
t.Errorf("host bit is not set for a sh_test_host module.")
}
@@ -186,7 +186,7 @@
}
`)
- mod := result.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*ShTest)
+ mod := result.ModuleForTests(t, "foo", "android_arm64_armv8-a").Module().(*ShTest)
entries := android.AndroidMkEntriesForTest(t, result, mod)[0]
actualData := entries.EntryMap["LOCAL_EXTRA_FULL_TEST_CONFIGS"]
android.AssertStringPathsRelativeToTopEquals(t, "extra_configs", result.Config(), []string{"config1.xml", "config2.xml"}, actualData)
@@ -221,7 +221,7 @@
buildOS := config.BuildOS.String()
variant := buildOS + "_x86_64"
- foo := ctx.ModuleForTests("foo", variant)
+ foo := ctx.ModuleForTests(t, "foo", variant)
relocated := foo.Output(filepath.Join("out/soong/.intermediates/foo", variant, "relocated/lib64/libbar.so"))
expectedInput := "out/soong/.intermediates/libbar/android_arm64_armv8-a_shared/libbar.so"
@@ -266,7 +266,7 @@
`)
buildOS := config.BuildOS.String()
- fooModule := ctx.ModuleForTests("foo", buildOS+"_x86_64")
+ fooModule := ctx.ModuleForTests(t, "foo", buildOS+"_x86_64")
expectedBinAutogenConfig := `<option name="push-file" key="bar" value="/data/local/tests/unrestricted/foo/bar" />`
autogen := fooModule.Rule("autogen")
@@ -296,7 +296,7 @@
}
`)
buildOS := ctx.Config().BuildOS.String()
- mod := ctx.ModuleForTests("foo", buildOS+"_x86_64").Module().(*ShTest)
+ mod := ctx.ModuleForTests(t, "foo", buildOS+"_x86_64").Module().(*ShTest)
if !mod.Host() {
t.Errorf("host bit is not set for a sh_test_host module.")
}
@@ -345,7 +345,7 @@
`)
buildOS := ctx.Config().BuildOS.String()
- mod := ctx.ModuleForTests("foo", buildOS+"_x86_64").Module().(*ShTest)
+ mod := ctx.ModuleForTests(t, "foo", buildOS+"_x86_64").Module().(*ShTest)
if !mod.Host() {
t.Errorf("host bit is not set for a sh_test_host module.")
}
@@ -365,7 +365,7 @@
":testdata/data1",
":testdata/sub/data2",
}
- mod = ctx.ModuleForTests("sh-test", "android_arm64_armv8-a").Module().(*ShTest)
+ mod = ctx.ModuleForTests(t, "sh-test", "android_arm64_armv8-a").Module().(*ShTest)
entries = android.AndroidMkEntriesForTest(t, ctx, mod)[0]
actualData = entries.EntryMap["LOCAL_TEST_DATA"]
android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_TEST_DATA", config, expectedData, actualData)
@@ -388,7 +388,7 @@
}
`)
buildOS := ctx.Config().BuildOS.String()
- mod := ctx.ModuleForTests("the-host-binary", buildOS+"_x86_64").Module().(*ShBinary)
+ mod := ctx.ModuleForTests(t, "the-host-binary", buildOS+"_x86_64").Module().(*ShBinary)
if !mod.Host() {
t.Errorf("host bit is not set for a sh_binary_host module.")
}
@@ -396,6 +396,6 @@
expectedFilename := "test.sh"
android.AssertStringEquals(t, "Filename", expectedFilename, *mod.properties.Filename)
- mod = ctx.ModuleForTests("the-binary", "android_arm64_armv8-a").Module().(*ShBinary)
+ mod = ctx.ModuleForTests(t, "the-binary", "android_arm64_armv8-a").Module().(*ShBinary)
android.AssertStringEquals(t, "Filename", expectedFilename, *mod.properties.Filename)
}
diff --git a/snapshot/snapshot_base.go b/snapshot/snapshot_base.go
index 6bf3c87..510e9cf 100644
--- a/snapshot/snapshot_base.go
+++ b/snapshot/snapshot_base.go
@@ -45,14 +45,3 @@
LicenseKinds []string `json:",omitempty"`
LicenseTexts []string `json:",omitempty"`
}
-
-func (prop *SnapshotJsonFlags) InitBaseSnapshotPropsWithName(m android.Module, name string) {
- prop.ModuleName = name
-
- prop.LicenseKinds = m.EffectiveLicenseKinds()
- prop.LicenseTexts = m.EffectiveLicenseFiles().Strings()
-}
-
-func (prop *SnapshotJsonFlags) InitBaseSnapshotProps(m android.Module) {
- prop.InitBaseSnapshotPropsWithName(m, m.Name())
-}
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index 25fbc41..a398cbc 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -226,6 +226,9 @@
// Make this module available when building for ramdisk
Ramdisk_available *bool
+ // Make this module available when building for vendor ramdisk
+ Vendor_ramdisk_available *bool
+
// Make this module available when building for recovery
Recovery_available *bool
@@ -459,9 +462,8 @@
var _ android.ApexModule = (*syspropLibrary)(nil)
// Implements android.ApexModule
-func (m *syspropLibrary) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
- sdkVersion android.ApiLevel) error {
- return fmt.Errorf("sysprop_library is not supposed to be part of apex modules")
+func (m *syspropLibrary) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
+ return android.MinApiLevel
}
// sysprop_library creates schematized APIs from sysprop description files (.sysprop).
@@ -501,17 +503,18 @@
Static_libs []string
}
}
- Required []string
- Recovery *bool
- Recovery_available *bool
- Vendor_available *bool
- Product_available *bool
- Ramdisk_available *bool
- Host_supported *bool
- Apex_available []string
- Min_sdk_version *string
- Cflags []string
- Ldflags []string
+ Required []string
+ Recovery *bool
+ Recovery_available *bool
+ Vendor_available *bool
+ Product_available *bool
+ Ramdisk_available *bool
+ Vendor_ramdisk_available *bool
+ Host_supported *bool
+ Apex_available []string
+ Min_sdk_version *string
+ Cflags []string
+ Ldflags []string
}
type javaLibraryProperties struct {
@@ -604,6 +607,7 @@
ccProps.Vendor_available = m.properties.Vendor_available
ccProps.Product_available = m.properties.Product_available
ccProps.Ramdisk_available = m.properties.Ramdisk_available
+ ccProps.Vendor_ramdisk_available = m.properties.Vendor_ramdisk_available
ccProps.Host_supported = m.properties.Host_supported
ccProps.Apex_available = m.ApexProperties.Apex_available
ccProps.Min_sdk_version = m.properties.Cpp.Min_sdk_version
diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go
index 7d4e69d..b2cfaa7 100644
--- a/sysprop/sysprop_test.go
+++ b/sysprop/sysprop_test.go
@@ -261,9 +261,9 @@
"android_vendor_arm64_armv8-a_shared",
"android_vendor_arm64_armv8-a_static",
} {
- result.ModuleForTests("libsysprop-platform", variant)
- result.ModuleForTests("libsysprop-vendor", variant)
- result.ModuleForTests("libsysprop-odm", variant)
+ result.ModuleForTests(t, "libsysprop-platform", variant)
+ result.ModuleForTests(t, "libsysprop-vendor", variant)
+ result.ModuleForTests(t, "libsysprop-odm", variant)
}
// product variant of vendor-owned sysprop_library
@@ -273,7 +273,7 @@
"android_product_arm64_armv8-a_shared",
"android_product_arm64_armv8-a_static",
} {
- result.ModuleForTests("libsysprop-vendor-on-product", variant)
+ result.ModuleForTests(t, "libsysprop-vendor-on-product", variant)
}
for _, variant := range []string{
@@ -282,15 +282,15 @@
"android_arm64_armv8-a_shared",
"android_arm64_armv8-a_static",
} {
- library := result.ModuleForTests("libsysprop-platform", variant).Module().(*cc.Module)
+ library := result.ModuleForTests(t, "libsysprop-platform", variant).Module().(*cc.Module)
expectedApexAvailableOnLibrary := []string{"//apex_available:platform"}
android.AssertDeepEquals(t, "apex available property on libsysprop-platform", expectedApexAvailableOnLibrary, library.ApexProperties.Apex_available)
}
- result.ModuleForTests("sysprop-platform", "android_common")
- result.ModuleForTests("sysprop-platform_public", "android_common")
- result.ModuleForTests("sysprop-vendor", "android_common")
- result.ModuleForTests("sysprop-vendor-on-product", "android_common")
+ result.ModuleForTests(t, "sysprop-platform", "android_common")
+ result.ModuleForTests(t, "sysprop-platform_public", "android_common")
+ result.ModuleForTests(t, "sysprop-vendor", "android_common")
+ result.ModuleForTests(t, "sysprop-vendor-on-product", "android_common")
// Check for exported includes
coreVariant := "android_arm64_armv8-a_static"
@@ -305,19 +305,19 @@
vendorInternalPath := "libsysprop-vendor/android_vendor_arm64_armv8-a_static/gen/sysprop/include"
vendorOnProductPath := "libsysprop-vendor-on-product/android_product_arm64_armv8-a_static/gen/sysprop/public/include"
- platformClient := result.ModuleForTests("cc-client-platform", coreVariant)
+ platformClient := result.ModuleForTests(t, "cc-client-platform", coreVariant)
platformFlags := platformClient.Rule("cc").Args["cFlags"]
// platform should use platform's internal header
android.AssertStringDoesContain(t, "flags for platform", platformFlags, platformInternalPath)
- platformStaticClient := result.ModuleForTests("cc-client-platform-static", coreVariant)
+ platformStaticClient := result.ModuleForTests(t, "cc-client-platform-static", coreVariant)
platformStaticFlags := platformStaticClient.Rule("cc").Args["cFlags"]
// platform-static should use platform's internal header
android.AssertStringDoesContain(t, "flags for platform-static", platformStaticFlags, platformInternalPath)
- productClient := result.ModuleForTests("cc-client-product", productVariant)
+ productClient := result.ModuleForTests(t, "cc-client-product", productVariant)
productFlags := productClient.Rule("cc").Args["cFlags"]
// Product should use platform's and vendor's public headers
@@ -327,7 +327,7 @@
platformOnProductPath, vendorOnProductPath, productFlags)
}
- vendorClient := result.ModuleForTests("cc-client-vendor", vendorVariant)
+ vendorClient := result.ModuleForTests(t, "cc-client-vendor", vendorVariant)
vendorFlags := vendorClient.Rule("cc").Args["cFlags"]
// Vendor should use platform's public header and vendor's internal header
@@ -338,8 +338,8 @@
}
// Java modules linking against system API should use public stub
- javaSystemApiClient := result.ModuleForTests("java-platform", "android_common").Rule("javac")
- syspropPlatformPublic := result.ModuleForTests("sysprop-platform_public", "android_common").Description("for turbine")
+ javaSystemApiClient := result.ModuleForTests(t, "java-platform", "android_common").Rule("javac")
+ syspropPlatformPublic := result.ModuleForTests(t, "sysprop-platform_public", "android_common").Description("turbine")
if g, w := javaSystemApiClient.Implicits.Strings(), syspropPlatformPublic.Output.String(); !android.InList(w, g) {
t.Errorf("system api client should use public stub %q, got %q", w, g)
}
@@ -358,15 +358,15 @@
expected := []string{"//apex_available:platform"}
- ccModule := result.ModuleForTests("libsysprop-platform", "android_arm64_armv8-a_shared").Module().(*cc.Module)
+ ccModule := result.ModuleForTests(t, "libsysprop-platform", "android_arm64_armv8-a_shared").Module().(*cc.Module)
propFromCc := ccModule.ApexProperties.Apex_available
android.AssertDeepEquals(t, "apex_available forwarding to cc module", expected, propFromCc)
- javaModule := result.ModuleForTests("sysprop-platform", "android_common").Module().(*java.Library)
+ javaModule := result.ModuleForTests(t, "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)
+ rustModule := result.ModuleForTests(t, "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)
}
@@ -390,15 +390,15 @@
}
`)
- ccModule := result.ModuleForTests("libsysprop-platform", "android_arm64_armv8-a_shared").Module().(*cc.Module)
+ ccModule := result.ModuleForTests(t, "libsysprop-platform", "android_arm64_armv8-a_shared").Module().(*cc.Module)
propFromCc := proptools.String(ccModule.Properties.Min_sdk_version)
android.AssertStringEquals(t, "min_sdk_version forwarding to cc module", "29", propFromCc)
- javaModule := result.ModuleForTests("sysprop-platform", "android_common").Module().(*java.Library)
+ javaModule := result.ModuleForTests(t, "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)
+ rustModule := result.ModuleForTests(t, "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)
}
diff --git a/systemfeatures/system_features_test.go b/systemfeatures/system_features_test.go
index 558bb95..58e6a06 100644
--- a/systemfeatures/system_features_test.go
+++ b/systemfeatures/system_features_test.go
@@ -36,7 +36,7 @@
android.PrepareForTestWithBuildFlag("RELEASE_NOT_SYSTEM_FEATURE_FOO", "BAR"),
).RunTestWithBp(t, bp)
- module := res.ModuleForTests("system-features-srcs", "")
+ module := res.ModuleForTests(t, "system-features-srcs", "")
cmd := module.Rule("system-features-srcs").RuleParams.Command
android.AssertStringDoesContain(t, "Expected fully class name", cmd, " com.android.test.RoSystemFeatures ")
android.AssertStringDoesContain(t, "Expected readonly flag", cmd, "--readonly=true")
diff --git a/tests/sbom_test.sh b/tests/sbom_test.sh
index 0471853..2ef9e37 100755
--- a/tests/sbom_test.sh
+++ b/tests/sbom_test.sh
@@ -83,6 +83,12 @@
dump_erofs=$out_dir/host/linux-x86/bin/dump.erofs
lz4=$out_dir/host/linux-x86/bin/lz4
+ declare -A diff_excludes
+ diff_excludes[system]="\
+ -I /etc/NOTICE.xml.gz \
+ -I /odm_dlkm/etc \
+ -I /vendor_dlkm/etc"
+
# Example output of dump.erofs is as below, and the data used in the test start
# at line 11. Column 1 is inode id, column 2 is inode type and column 3 is name.
# Each line is captured in variable "entry", awk is used to get type and name.
@@ -155,7 +161,11 @@
sort -n -o "$files_in_soong_spdx_file" "$files_in_soong_spdx_file"
echo ============ Diffing files in $f and SBOM created by Soong
- diff_files "$file_list_file" "$files_in_soong_spdx_file" "$partition_name" ""
+ exclude=
+ if [ -v 'diff_excludes[$partition_name]' ]; then
+ exclude=${diff_excludes[$partition_name]}
+ fi
+ diff_files "$file_list_file" "$files_in_soong_spdx_file" "$partition_name" "$exclude"
done
RAMDISK_IMAGES="$product_out/ramdisk.img"
@@ -230,10 +240,10 @@
exit 1
fi
- # PRODUCT and 7 prebuilt packages have "PackageLicenseDeclared: NOASSERTION"
+ # PRODUCT and 6 prebuilt packages have "PackageLicenseDeclared: NOASSERTION"
# All other packages have declared licenses
num_of_packages_with_noassertion_license=$(grep 'PackageLicenseDeclared: NOASSERTION' $sbom_file | wc -l)
- if [ $num_of_packages_with_noassertion_license = 15 ]
+ if [ $num_of_packages_with_noassertion_license = 13 ]
then
echo "Number of packages with NOASSERTION license is correct."
else
diff --git a/tradefed/autogen.go b/tradefed/autogen.go
index e230795..89c69bd 100644
--- a/tradefed/autogen.go
+++ b/tradefed/autogen.go
@@ -160,6 +160,7 @@
DeviceTemplate string
HostTemplate string
HostUnitTestTemplate string
+ StandaloneTest *bool
}
func AutoGenTestConfig(ctx android.ModuleContext, options AutoGenTestConfigOptions) android.Path {
@@ -178,6 +179,12 @@
autogenTemplate(ctx, name, autogenPath, templatePath.String(), configs, options.TestRunnerOptions, options.OutputFileName, options.TestInstallBase)
} else {
if ctx.Device() {
+ if Bool(options.StandaloneTest) {
+ options.TestRunnerOptions = append(options.TestRunnerOptions, Option{
+ Name: "ld-library-path",
+ Value: "{TEST_INSTALL_BASE}/" + name + "/" + ctx.Arch().ArchType.String() + "/standalone-libs",
+ })
+ }
autogenTemplate(ctx, name, autogenPath, options.DeviceTemplate, configs, options.TestRunnerOptions, options.OutputFileName, options.TestInstallBase)
} else {
if Bool(options.UnitTest) {
@@ -190,7 +197,10 @@
return autogenPath
}
if len(options.OptionsForAutogenerated) > 0 {
- ctx.ModuleErrorf("Extra tradefed configurations were provided for an autogenerated xml file, but the autogenerated xml file was not used.")
+ ctx.ModuleErrorf("You likely need to delete your soong modules local AndroidTest.xml file. Extra tradefed configurations (%v) were provided for an autogenerated xml file, but the autogenerated xml file was not used.", options.OptionsForAutogenerated)
+ }
+ if len(options.TestRunnerOptions) > 0 {
+ ctx.ModuleErrorf("You likely need to delete your soong modules local AndroidTest.xml file. Extra test runner options (%v) were provided for an autogenerated xml file, but the autogenerated xml file was not used.", options.TestRunnerOptions)
}
return path
}
diff --git a/tradefed_modules/test_module_config_test.go b/tradefed_modules/test_module_config_test.go
index 037dcea..302f9a9 100644
--- a/tradefed_modules/test_module_config_test.go
+++ b/tradefed_modules/test_module_config_test.go
@@ -65,13 +65,13 @@
android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
).RunTestWithBp(t, bp)
- derived := ctx.ModuleForTests("derived_test", variant)
+ derived := ctx.ModuleForTests(t, "derived_test", variant)
// Assert there are rules to create these files.
derived.Output("test_module_config.manifest")
derived.Output("test_config_fixer/derived_test.config")
// Ensure some basic rules exist.
- ctx.ModuleForTests("base", "android_common").Output("package-res.apk")
+ ctx.ModuleForTests(t, "base", "android_common").Output("package-res.apk")
entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, derived.Module())[0]
// Ensure some entries from base are there, specifically support files for data and helper apps.
@@ -136,7 +136,7 @@
options: [{name: "SomeName", value: "OptionValue"}],
}
`)
- derived := ctx.ModuleForTests("conch", variant) //
+ derived := ctx.ModuleForTests(t, "conch", variant) //
conch := derived.Module().(*testModuleConfigModule)
android.AssertArrayString(t, "TestcaseRelDataFiles", []string{"arm64/testdata/data1", "arm64/testdata/sub/data2"}, conch.provider.TestcaseRelDataFiles)
android.AssertStringEquals(t, "Rel OutputFile", "test.sh", conch.provider.OutputFile.Rel())
@@ -191,7 +191,7 @@
).RunTestWithBp(t, bp)
// Check that we generate a rule to make a new AndroidTest.xml/Module.config file.
- derived := ctx.ModuleForTests("derived_test", variant)
+ derived := ctx.ModuleForTests(t, "derived_test", variant)
rule_cmd := derived.Rule("fix_test_config").RuleParams.Command
android.AssertStringDoesContain(t, "Bad FixConfig rule inputs", rule_cmd,
`--test-runner-options='[{"Name":"exclude-filter","Key":"","Value":"android.test.example.devcodelab.DevCodelabTest#testHelloFail"},{"Name":"include-annotation","Key":"","Value":"android.platform.test.annotations.LargeTest"}]'`)
@@ -288,7 +288,7 @@
).ExtendWithErrorHandler(
android.FixtureExpectsAtLeastOneErrorMatchingPattern("Test options must be given")).
RunTestWithBp(t, badBp)
- ctx.ModuleForTests("derived_test", variant)
+ ctx.ModuleForTests(t, "derived_test", variant)
}
func TestModuleConfigMultipleDerivedTestsWriteDistinctMakeEntries(t *testing.T) {
@@ -326,7 +326,7 @@
).RunTestWithBp(t, multiBp)
{
- derived := ctx.ModuleForTests("derived_test", variant)
+ derived := ctx.ModuleForTests(t, "derived_test", variant)
entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, derived.Module())[0]
// All these should be the same in both derived tests
android.AssertStringPathsRelativeToTopEquals(t, "support-files", ctx.Config,
@@ -342,7 +342,7 @@
}
{
- derived := ctx.ModuleForTests("another_derived_test", variant)
+ derived := ctx.ModuleForTests(t, "another_derived_test", variant)
entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, derived.Module())[0]
// All these should be the same in both derived tests
android.AssertStringPathsRelativeToTopEquals(t, "support-files", ctx.Config,
@@ -381,7 +381,7 @@
).RunTestWithBp(t, bp)
variant := ctx.Config.BuildOS.String() + "_common"
- derived := ctx.ModuleForTests("derived_test", variant)
+ derived := ctx.ModuleForTests(t, "derived_test", variant)
mod := derived.Module().(*testModuleConfigHostModule)
allEntries := android.AndroidMkEntriesForTest(t, ctx.TestContext, mod)
entries := allEntries[0]
diff --git a/tradefed_modules/test_suite.go b/tradefed_modules/test_suite.go
index 00585f5..8b7babf 100644
--- a/tradefed_modules/test_suite.go
+++ b/tradefed_modules/test_suite.go
@@ -26,12 +26,12 @@
const testSuiteModuleType = "test_suite"
-type testSuiteTag struct{
+type testSuiteTag struct {
blueprint.BaseDependencyTag
}
type testSuiteManifest struct {
- Name string `json:"name"`
+ Name string `json:"name"`
Files []string `json:"files"`
}
@@ -49,7 +49,7 @@
type testSuiteProperties struct {
Description string
- Tests []string `android:"path,arch_variant"`
+ Tests []string `android:"path,arch_variant"`
}
type testSuiteModule struct {
@@ -109,7 +109,7 @@
}
manifestPath := android.PathForSuiteInstall(ctx, suiteName, suiteName+".json")
- b, err := json.Marshal(testSuiteManifest{Name: suiteName, Files: files})
+ b, err := json.Marshal(testSuiteManifest{Name: suiteName, Files: android.SortedUniqueStrings(files)})
if err != nil {
ctx.ModuleErrorf("Failed to marshal manifest: %v", err)
return
@@ -160,7 +160,7 @@
// Install config file.
if tp.TestConfig != nil {
moduleRoot := suiteRoot.Join(ctx, hostOrTarget, "testcases", module.Name())
- installed = append(installed, ctx.InstallFile(moduleRoot, module.Name() + ".config", tp.TestConfig))
+ installed = append(installed, ctx.InstallFile(moduleRoot, module.Name()+".config", tp.TestConfig))
}
// Add to phony and manifest, manifestpaths are relative to suiteRoot.
diff --git a/tradefed_modules/test_suite_test.go b/tradefed_modules/test_suite_test.go
index 3c0a9eb..3e1472c 100644
--- a/tradefed_modules/test_suite_test.go
+++ b/tradefed_modules/test_suite_test.go
@@ -46,7 +46,7 @@
]
}
`)
- manifestPath := ctx.ModuleForTests("my-suite", "android_common").Output("out/soong/test_suites/my-suite/my-suite.json")
+ manifestPath := ctx.ModuleForTests(t, "my-suite", "android_common").Output("out/soong/test_suites/my-suite/my-suite.json")
var actual testSuiteManifest
if err := json.Unmarshal([]byte(android.ContentFromFileRuleForTests(t, ctx.TestContext, manifestPath)), &actual); err != nil {
t.Errorf("failed to unmarshal manifest: %v", err)
@@ -106,7 +106,7 @@
]
}
`)
- manifestPath := ctx.ModuleForTests("my-all-tests-suite", "android_common").Output("out/soong/test_suites/my-all-tests-suite/my-all-tests-suite.json")
+ manifestPath := ctx.ModuleForTests(t, "my-all-tests-suite", "android_common").Output("out/soong/test_suites/my-all-tests-suite/my-all-tests-suite.json")
var actual testSuiteManifest
if err := json.Unmarshal([]byte(android.ContentFromFileRuleForTests(t, ctx.TestContext, manifestPath)), &actual); err != nil {
t.Errorf("failed to unmarshal manifest: %v", err)
diff --git a/ui/build/androidmk_denylist.go b/ui/build/androidmk_denylist.go
index 6f57cb1..640a82d 100644
--- a/ui/build/androidmk_denylist.go
+++ b/ui/build/androidmk_denylist.go
@@ -85,10 +85,18 @@
"external/webp/",
}
-func ignoreNdkAndroidMks(androidMks []string) (filtered []string) {
- filter := func(s string) bool {
- for _, d := range external_ndk_androidmks {
- if strings.HasPrefix(s, d) {
+var art_androidmks = []string{
+ //"art/",
+}
+
+func ignoreSomeAndroidMks(androidMks []string) (filtered []string) {
+ ignore_androidmks := make([]string, 0, len(external_ndk_androidmks)+len(art_androidmks))
+ ignore_androidmks = append(ignore_androidmks, external_ndk_androidmks...)
+ ignore_androidmks = append(ignore_androidmks, art_androidmks...)
+
+ shouldKeep := func(androidmk string) bool {
+ for _, prefix := range ignore_androidmks {
+ if strings.HasPrefix(androidmk, prefix) {
return false
}
}
@@ -96,10 +104,9 @@
}
for _, l := range androidMks {
- if filter(l) {
+ if shouldKeep(l) {
filtered = append(filtered, l)
}
}
-
return
}
diff --git a/ui/build/build.go b/ui/build/build.go
index 26f5969..781ca18 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -33,26 +33,13 @@
ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "CleanSpec.mk"))
ensureEmptyDirectoriesExist(ctx, config.TempDir())
- // Potentially write a marker file for whether kati is enabled. This is used by soong_build to
- // potentially run the AndroidMk singleton and postinstall commands.
- // Note that the absence of the file does not not preclude running Kati for product
- // configuration purposes.
- katiEnabledMarker := filepath.Join(config.SoongOutDir(), ".soong.kati_enabled")
- if config.SkipKatiNinja() {
- os.Remove(katiEnabledMarker)
- // Note that we can not remove the file for SkipKati builds yet -- some continuous builds
- // --skip-make builds rely on kati targets being defined.
- } else if !config.SkipKati() {
- ensureEmptyFileExists(ctx, katiEnabledMarker)
- }
-
// The ninja_build file is used by our buildbots to understand that the output
// can be parsed as ninja output.
ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "ninja_build"))
ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), ".out-dir"))
if buildDateTimeFile, ok := config.environ.Get("BUILD_DATETIME_FILE"); ok {
- err := ioutil.WriteFile(buildDateTimeFile, []byte(config.buildDateTime), 0666) // a+rw
+ err := os.WriteFile(buildDateTimeFile, []byte(config.buildDateTime), 0666) // a+rw
if err != nil {
ctx.Fatalln("Failed to write BUILD_DATETIME to file:", err)
}
@@ -100,6 +87,21 @@
writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_hostname.txt", hostname)
}
+// SetupKatiEnabledMarker creates or delets a file that tells soong_build if we're running with
+// kati.
+func SetupKatiEnabledMarker(ctx Context, config Config) {
+ // Potentially write a marker file for whether kati is enabled. This is used by soong_build to
+ // potentially run the AndroidMk singleton and postinstall commands.
+ // Note that the absence of the file does not preclude running Kati for product
+ // configuration purposes.
+ katiEnabledMarker := filepath.Join(config.SoongOutDir(), ".soong.kati_enabled")
+ if config.SkipKati() || config.SkipKatiNinja() {
+ os.Remove(katiEnabledMarker)
+ } else {
+ ensureEmptyFileExists(ctx, katiEnabledMarker)
+ }
+}
+
var combinedBuildNinjaTemplate = template.Must(template.New("combined").Parse(`
builddir = {{.OutDir}}
{{if .UseRemoteBuild }}pool local_pool
@@ -329,10 +331,16 @@
if what&RunProductConfig != 0 {
runMakeProductConfig(ctx, config)
+
+ // Re-evaluate what to run because there are product variables that control how
+ // soong and make are run.
+ what = evaluateWhatToRun(config, ctx.Verboseln)
}
// Everything below here depends on product config.
+ SetupKatiEnabledMarker(ctx, config)
+
if inList("installclean", config.Arguments()) ||
inList("install-clean", config.Arguments()) {
logArgsOtherThan("installclean", "install-clean")
@@ -393,6 +401,7 @@
if what&RunKati != 0 {
installCleanIfNecessary(ctx, config)
}
+ partialCompileCleanIfNecessary(ctx, config)
runNinjaForBuild(ctx, config)
updateBuildIdDir(ctx, config)
}
@@ -419,6 +428,9 @@
if config.Checkbuild() {
what |= RunBuildTests
}
+ if value, ok := config.environ.Get("RUN_BUILD_TESTS"); ok && value == "true" {
+ what |= RunBuildTests
+ }
if !config.SkipConfig() {
what |= RunProductConfig
} else {
diff --git a/ui/build/cleanbuild.go b/ui/build/cleanbuild.go
index 41cb5ab..723d90f 100644
--- a/ui/build/cleanbuild.go
+++ b/ui/build/cleanbuild.go
@@ -218,6 +218,52 @@
writeConfig()
}
+// When SOONG_USE_PARTIAL_COMPILE transitions from on to off, we need to remove
+// all files which were potentially built with partial compile, so that they
+// get rebuilt with that turned off.
+func partialCompileCleanIfNecessary(ctx Context, config Config) {
+ configFile := config.DevicePreviousUsePartialCompile()
+ currentValue, _ := config.Environment().Get("SOONG_USE_PARTIAL_COMPILE")
+
+ ensureDirectoriesExist(ctx, filepath.Dir(configFile))
+
+ writeValue := func() {
+ err := ioutil.WriteFile(configFile, []byte(currentValue), 0666) // a+rw
+ if err != nil {
+ ctx.Fatalln("Failed to write use partial compile config:", err)
+ }
+ }
+
+ previousValueBytes, err := ioutil.ReadFile(configFile)
+ if err != nil {
+ if os.IsNotExist(err) {
+ // Just write the new config file, no old config file to worry about.
+ writeValue()
+ return
+ } else {
+ ctx.Fatalln("Failed to read previous use partial compile config:", err)
+ }
+ }
+
+ previousValue := string(previousValueBytes)
+ switch previousValue {
+ case currentValue:
+ // Same value as before - nothing left to do here.
+ return
+ case "true":
+ // Transitioning from on to off. Build (phony) target: partialcompileclean.
+ ctx.BeginTrace(metrics.PrimaryNinja, "partialcompileclean")
+ defer ctx.EndTrace()
+
+ ctx.Printf("SOONG_USE_PARTIAL_COMPILE turned off, forcing partialcompileclean\n")
+
+ runNinja(ctx, config, []string{"partialcompileclean"})
+ default:
+ // Transitioning from off to on. Nothing to do in this case.
+ }
+ writeValue()
+}
+
// cleanOldFiles takes an input file (with all paths relative to basePath), and removes files from
// the filesystem if they were removed from the input file since the last execution.
func cleanOldFiles(ctx Context, basePath, newFile string) {
diff --git a/ui/build/config.go b/ui/build/config.go
index 4f2d213..a4f778d 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -63,6 +63,7 @@
NINJA_NINJA
NINJA_N2
NINJA_SISO
+ NINJA_NINJAGO
)
type Config struct{ *configImpl }
@@ -77,26 +78,31 @@
logsPrefix string
// From the arguments
- parallel int
- keepGoing int
- verbose bool
- checkbuild bool
- dist bool
- jsonModuleGraph bool
- reportMkMetrics bool // Collect and report mk2bp migration progress metrics.
- soongDocs bool
- skipConfig bool
- skipKati bool
- skipKatiNinja bool
- skipSoong bool
- skipNinja bool
- skipSoongTests bool
- searchApiDir bool // Scan the Android.bp files generated in out/api_surfaces
- skipMetricsUpload bool
- buildStartedTime int64 // For metrics-upload-only - manually specify a build-started time
- buildFromSourceStub bool
- incrementalBuildActions bool
- ensureAllowlistIntegrity bool // For CI builds - make sure modules are mixed-built
+ parallel int
+ keepGoing int
+ verbose bool
+ checkbuild bool
+ dist bool
+ jsonModuleGraph bool
+ reportMkMetrics bool // Collect and report mk2bp migration progress metrics.
+ soongDocs bool
+ skipConfig bool
+ // Either the user or product config requested that we skip soong (for the banner). The other
+ // skip flags tell whether *this* soong_ui invocation will skip kati - which will be true
+ // during lunch.
+ soongOnlyRequested bool
+ skipKati bool
+ skipKatiControlledByFlags bool
+ skipKatiNinja bool
+ skipSoong bool
+ skipNinja bool
+ skipSoongTests bool
+ searchApiDir bool // Scan the Android.bp files generated in out/api_surfaces
+ skipMetricsUpload bool
+ buildStartedTime int64 // For metrics-upload-only - manually specify a build-started time
+ buildFromSourceStub bool
+ incrementalBuildActions bool
+ ensureAllowlistIntegrity bool // For CI builds - make sure modules are mixed-built
// From the product config
katiArgs []string
@@ -250,6 +256,19 @@
}
ret.parseArgs(ctx, args)
+ if value, ok := ret.environ.Get("SOONG_ONLY"); ok && !ret.skipKatiControlledByFlags {
+ if value == "true" || value == "1" || value == "y" || value == "yes" {
+ ret.soongOnlyRequested = true
+ ret.skipKatiControlledByFlags = true
+ ret.skipKati = true
+ ret.skipKatiNinja = true
+ } else {
+ ret.skipKatiControlledByFlags = true
+ ret.skipKati = false
+ ret.skipKatiNinja = false
+ }
+ }
+
if ret.ninjaWeightListSource == HINT_FROM_SOONG {
ret.environ.Set("SOONG_GENERATES_NINJA_HINT", "always")
} else if ret.ninjaWeightListSource == DEFAULT {
@@ -323,6 +342,8 @@
ret.ninjaCommand = NINJA_N2
case "siso":
ret.ninjaCommand = NINJA_SISO
+ case "ninjago":
+ ret.ninjaCommand = NINJA_NINJAGO
default:
if os.Getenv("SOONG_USE_N2") == "true" {
ret.ninjaCommand = NINJA_N2
@@ -389,6 +410,9 @@
// Use config.ninjaCommand instead.
"SOONG_NINJA",
"SOONG_USE_N2",
+
+ // Already incorporated into the config object
+ "SOONG_ONLY",
)
if ret.UseGoma() || ret.ForceUseGoma() {
@@ -615,6 +639,7 @@
UseRbe: proto.Bool(config.UseRBE()),
NinjaWeightListSource: getNinjaWeightListSourceInMetric(config.NinjaWeightListSource()),
SoongEnvVars: soongEnvVars,
+ SoongOnly: proto.Bool(config.soongOnlyRequested),
}
c.Targets = append(c.Targets, config.arguments...)
@@ -843,15 +868,21 @@
c.emptyNinjaFile = true
} else if arg == "--skip-ninja" {
c.skipNinja = true
- } else if arg == "--skip-make" {
- // TODO(ccross): deprecate this, it has confusing behaviors. It doesn't run kati,
- // but it does run a Kati ninja file if the .kati_enabled marker file was created
- // by a previous build.
- c.skipConfig = true
- c.skipKati = true
} else if arg == "--soong-only" {
+ if c.skipKatiControlledByFlags {
+ ctx.Fatalf("Cannot specify both --soong-only and --no-soong-only")
+ }
+ c.soongOnlyRequested = true
+ c.skipKatiControlledByFlags = true
c.skipKati = true
c.skipKatiNinja = true
+ } else if arg == "--no-soong-only" {
+ if c.skipKatiControlledByFlags {
+ ctx.Fatalf("Cannot specify both --soong-only and --no-soong-only")
+ }
+ c.skipKatiControlledByFlags = true
+ c.skipKati = false
+ c.skipKatiNinja = false
} else if arg == "--config-only" {
c.skipKati = true
c.skipKatiNinja = true
@@ -1070,7 +1101,7 @@
func (c *configImpl) NinjaArgs() []string {
if c.skipKati {
- return c.arguments
+ return append(c.arguments, c.ninjaArgs...)
}
return c.ninjaArgs
}
@@ -1339,6 +1370,10 @@
}
func (c *configImpl) UseABFS() bool {
+ if c.ninjaCommand == NINJA_NINJAGO {
+ return true
+ }
+
if v, ok := c.environ.Get("NO_ABFS"); ok {
v = strings.ToLower(strings.TrimSpace(v))
if v == "true" || v == "1" {
@@ -1650,6 +1685,10 @@
return filepath.Join(c.ProductOut(), "previous_build_config.mk")
}
+func (c *configImpl) DevicePreviousUsePartialCompile() string {
+ return filepath.Join(c.ProductOut(), "previous_use_partial_compile.txt")
+}
+
func (c *configImpl) KatiPackageMkDir() string {
return filepath.Join(c.SoongOutDir(), "kati_packaging"+c.KatiSuffix())
}
diff --git a/ui/build/config_test.go b/ui/build/config_test.go
index b42edb0..10de1ad 100644
--- a/ui/build/config_test.go
+++ b/ui/build/config_test.go
@@ -30,8 +30,6 @@
smpb "android/soong/ui/metrics/metrics_proto"
"android/soong/ui/status"
- "google.golang.org/protobuf/encoding/prototext"
-
"google.golang.org/protobuf/proto"
)
@@ -1006,6 +1004,12 @@
}
}
+func assertEquals[T ~bool | ~int32](t *testing.T, name string, expected, actual T) {
+ if expected != actual {
+ t.Errorf("Expected %s: %#v\nActual %s: %#v", name, expected, name, actual)
+ }
+}
+
func TestBuildConfig(t *testing.T) {
tests := []struct {
name string
@@ -1063,12 +1067,11 @@
arguments: tc.arguments,
}
config := Config{c}
- actualBuildConfig := buildConfig(config)
- if expected := tc.expectedBuildConfig; !proto.Equal(expected, actualBuildConfig) {
- t.Errorf("Build config mismatch.\n"+
- "Expected build config: %#v\n"+
- "Actual build config: %#v", prototext.Format(expected), prototext.Format(actualBuildConfig))
- }
+ actual := buildConfig(config)
+ assertEquals(t, "ForceUseGoma", *tc.expectedBuildConfig.ForceUseGoma, *actual.ForceUseGoma)
+ assertEquals(t, "UseGoma", *tc.expectedBuildConfig.UseGoma, *actual.UseGoma)
+ assertEquals(t, "UseRbe", *tc.expectedBuildConfig.UseRbe, *actual.UseRbe)
+ assertEquals(t, "NinjaWeightListSource", *tc.expectedBuildConfig.NinjaWeightListSource, *actual.NinjaWeightListSource)
})
}
}
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index e0b2c08..16a3db8 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -137,6 +137,12 @@
}
}
if ctx.Metrics != nil {
+ // Also include TARGET_RELEASE in the metrics. Do this first
+ // so that it gets overwritten if dumpvars ever spits it out.
+ if release, found := os.LookupEnv("TARGET_RELEASE"); found {
+ ctx.Metrics.SetMetadataMetrics(
+ map[string]string{"TARGET_RELEASE": release})
+ }
ctx.Metrics.SetMetadataMetrics(ret)
}
@@ -166,7 +172,7 @@
"SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE",
}
-func Banner(make_vars map[string]string) string {
+func Banner(config Config, make_vars map[string]string) string {
b := &bytes.Buffer{}
fmt.Fprintln(b, "============================================")
@@ -175,6 +181,7 @@
fmt.Fprintf(b, "%s=%s\n", name, make_vars[name])
}
}
+ fmt.Fprintf(b, "SOONG_ONLY=%t\n", config.soongOnlyRequested)
fmt.Fprint(b, "============================================")
return b.String()
@@ -240,6 +247,8 @@
// `true` will relegate missing outputs to warnings.
"BUILD_BROKEN_MISSING_OUTPUTS",
+ "PRODUCT_SOONG_ONLY",
+
// Not used, but useful to be in the soong.log
"TARGET_BUILD_TYPE",
"HOST_ARCH",
@@ -281,13 +290,8 @@
ctx.Fatalln("Error dumping make vars:", err)
}
- env := config.Environment()
- // Print the banner like make does
- if !env.IsEnvTrue("ANDROID_QUIET_BUILD") {
- fmt.Fprintln(ctx.Writer, Banner(makeVars))
- }
-
// Populate the environment
+ env := config.Environment()
for _, name := range exportEnvVars {
if makeVars[name] == "" {
env.Unset(name)
@@ -308,4 +312,17 @@
config.SetBuildBrokenNinjaUsesEnvVars(strings.Fields(makeVars["BUILD_BROKEN_NINJA_USES_ENV_VARS"]))
config.SetSourceRootDirs(strings.Fields(makeVars["PRODUCT_SOURCE_ROOT_DIRS"]))
config.SetBuildBrokenMissingOutputs(makeVars["BUILD_BROKEN_MISSING_OUTPUTS"] == "true")
+
+ if !config.skipKatiControlledByFlags {
+ if makeVars["PRODUCT_SOONG_ONLY"] == "true" {
+ config.soongOnlyRequested = true
+ config.skipKati = true
+ config.skipKatiNinja = true
+ }
+ }
+
+ // Print the banner like make did
+ if !env.IsEnvTrue("ANDROID_QUIET_BUILD") {
+ fmt.Fprintln(ctx.Writer, Banner(config, makeVars))
+ }
}
diff --git a/ui/build/finder.go b/ui/build/finder.go
index da7f255..783b488 100644
--- a/ui/build/finder.go
+++ b/ui/build/finder.go
@@ -128,7 +128,7 @@
// Stop searching a subdirectory recursively after finding an Android.mk.
androidMks := f.FindFirstNamedAt(".", "Android.mk")
- androidMks = ignoreNdkAndroidMks(androidMks)
+ androidMks = ignoreSomeAndroidMks(androidMks)
blockAndroidMks(ctx, androidMks)
err := dumpListToFile(ctx, config, androidMks, filepath.Join(dumpDir, "Android.mk.list"))
if err != nil {
diff --git a/ui/build/ninja.go b/ui/build/ninja.go
index b0c9c07..e2a568f 100644
--- a/ui/build/ninja.go
+++ b/ui/build/ninja.go
@@ -36,10 +36,16 @@
ninjaWeightListFileName = ".ninja_weight_list"
)
+// Runs ninja with the arguments from the command line, as found in
+// config.NinjaArgs().
+func runNinjaForBuild(ctx Context, config Config) {
+ runNinja(ctx, config, config.NinjaArgs())
+}
+
// Constructs and runs the Ninja command line with a restricted set of
// environment variables. It's important to restrict the environment Ninja runs
// for hermeticity reasons, and to avoid spurious rebuilds.
-func runNinjaForBuild(ctx Context, config Config) {
+func runNinja(ctx Context, config Config, ninjaArgs []string) {
ctx.BeginTrace(metrics.PrimaryNinja, "ninja")
defer ctx.EndTrace()
@@ -76,7 +82,7 @@
//"--frontend-file", fifo,
}
default:
- // NINJA_NINJA is the default.
+ // NINJA_NINJA or NINJA_NINJAGO.
executable = config.NinjaBin()
args = []string{
"-d", "keepdepfile",
@@ -88,7 +94,7 @@
"-w", "missingdepfile=err",
}
}
- args = append(args, config.NinjaArgs()...)
+ args = append(args, ninjaArgs...)
var parallel int
if config.UseRemoteBuild() {
@@ -244,6 +250,8 @@
"RUST_LOG",
// SOONG_USE_PARTIAL_COMPILE only determines which half of the rule we execute.
+ // When it transitions true => false, we build phony target "partialcompileclean",
+ // which removes all files that could have been created while it was true.
"SOONG_USE_PARTIAL_COMPILE",
// Directory for ExecutionMetrics
@@ -351,12 +359,18 @@
}
// Constructs and runs the Ninja command line to get the inputs of a goal.
-// For now, this will always run ninja, because ninjago, n2 and siso don't have the
+// For n2 and siso, this will always run ninja, because they don't have the
// `-t inputs` command. This command will use the inputs command's -d option,
// to use the dep file iff ninja was the executor. For other executors, the
// results will be wrong.
func runNinjaInputs(ctx Context, config Config, goal string) ([]string, error) {
- executable := config.PrebuiltBuildTool("ninja")
+ var executable string
+ switch config.ninjaCommand {
+ case NINJA_N2, NINJA_SISO:
+ executable = config.PrebuiltBuildTool("ninja")
+ default:
+ executable = config.NinjaBin()
+ }
args := []string{
"-f",
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index 6c9a1eb..110ddee 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -42,7 +42,7 @@
}
// This tool is specifically disallowed and calling it will result in an
-// "executable no found" error.
+// "executable not found" error.
var Forbidden = PathConfig{
Symlink: false,
Log: true,
@@ -122,6 +122,10 @@
"ld.bfd": Forbidden,
"ld.gold": Forbidden,
"pkg-config": Forbidden,
+ "python": Forbidden,
+ "python2": Forbidden,
+ "python2.7": Forbidden,
+ "python3": Forbidden,
// These are toybox tools that only work on Linux.
"pgrep": LinuxOnlyPrebuilt,
diff --git a/ui/build/test_build.go b/ui/build/test_build.go
index 7a2fd16..87bec93 100644
--- a/ui/build/test_build.go
+++ b/ui/build/test_build.go
@@ -76,8 +76,10 @@
// treated as an source file.
dexpreoptConfigFilePath := filepath.Join(outDir, "soong", "dexpreopt.config")
- // out/build_date.txt is considered a "source file"
+ // out/build_(date|hostname|number).txt is considered a "source file"
buildDatetimeFilePath := filepath.Join(outDir, "build_date.txt")
+ buildHostnameFilePath := filepath.Join(outDir, "soong", "build_hostname.txt")
+ buildNumberFilePath := filepath.Join(outDir, "soong", "build_number.txt")
// release-config files are generated from the initial lunch or Kati phase
// before running soong and ninja.
@@ -102,6 +104,8 @@
line == extraVariablesFilePath ||
line == dexpreoptConfigFilePath ||
line == buildDatetimeFilePath ||
+ line == buildHostnameFilePath ||
+ line == buildNumberFilePath ||
strings.HasPrefix(line, releaseConfigDir) ||
buildFingerPrintFilePattern.MatchString(line) {
// Leaf node is in one of Soong's bootstrap directories, which do not have
diff --git a/ui/metrics/metrics.go b/ui/metrics/metrics.go
index 4a275a8..8d29cfc 100644
--- a/ui/metrics/metrics.go
+++ b/ui/metrics/metrics.go
@@ -161,7 +161,7 @@
}
// SetMetadataMetrics sets information about the build such as the target
-// product, host architecture and out directory.
+// product, host architecture and out directory. May be called multiple times.
func (m *Metrics) SetMetadataMetrics(metadata map[string]string) {
for k, v := range metadata {
switch k {
@@ -171,6 +171,8 @@
m.metrics.PlatformVersionCodename = proto.String(v)
case "TARGET_PRODUCT":
m.metrics.TargetProduct = proto.String(v)
+ case "TARGET_RELEASE":
+ m.metrics.TargetRelease = proto.String(v)
case "TARGET_BUILD_VARIANT":
switch v {
case "user":
diff --git a/ui/metrics/metrics_proto/metrics.pb.go b/ui/metrics/metrics_proto/metrics.pb.go
index 07918f1..1ebe911 100644
--- a/ui/metrics/metrics_proto/metrics.pb.go
+++ b/ui/metrics/metrics_proto/metrics.pb.go
@@ -427,6 +427,8 @@
ChangedEnvironmentVariable []string `protobuf:"bytes,34,rep,name=changed_environment_variable,json=changedEnvironmentVariable" json:"changed_environment_variable,omitempty"`
// Metrics related to optimized builds.
OptimizedBuildMetrics *OptimizedBuildMetrics `protobuf:"bytes,35,opt,name=optimized_build_metrics,json=optimizedBuildMetrics" json:"optimized_build_metrics,omitempty"`
+ // The target release information. e.g., trunk_staging.
+ TargetRelease *string `protobuf:"bytes,36,opt,name=target_release,json=targetRelease" json:"target_release,omitempty"`
}
// Default values for MetricsBase fields.
@@ -715,6 +717,13 @@
return nil
}
+func (x *MetricsBase) GetTargetRelease() string {
+ if x != nil && x.TargetRelease != nil {
+ return *x.TargetRelease
+ }
+ return ""
+}
+
type BuildConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -741,6 +750,9 @@
NinjaWeightListSource *BuildConfig_NinjaWeightListSource `protobuf:"varint,8,opt,name=ninja_weight_list_source,json=ninjaWeightListSource,enum=soong_build_metrics.BuildConfig_NinjaWeightListSource,def=0" json:"ninja_weight_list_source,omitempty"`
// Values of some build-affecting environment variables.
SoongEnvVars *SoongEnvVars `protobuf:"bytes,9,opt,name=soong_env_vars,json=soongEnvVars" json:"soong_env_vars,omitempty"`
+ // Whether this build uses soong-only (no kati) mode (either via environment variable,
+ // command line flag or product config.
+ SoongOnly *bool `protobuf:"varint,10,opt,name=soong_only,json=soongOnly" json:"soong_only,omitempty"`
}
// Default values for BuildConfig fields.
@@ -843,6 +855,13 @@
return nil
}
+func (x *BuildConfig) GetSoongOnly() bool {
+ if x != nil && x.SoongOnly != nil {
+ return *x.SoongOnly
+ }
+ return false
+}
+
type SoongEnvVars struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -2522,7 +2541,7 @@
var file_metrics_proto_rawDesc = []byte{
0x0a, 0x0d, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
0x13, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74,
- 0x72, 0x69, 0x63, 0x73, 0x22, 0xb0, 0x10, 0x0a, 0x0b, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
+ 0x72, 0x69, 0x63, 0x73, 0x22, 0xd7, 0x10, 0x0a, 0x0b, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
0x42, 0x61, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x64, 0x61,
0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01,
0x28, 0x03, 0x52, 0x12, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d,
@@ -2646,328 +2665,332 @@
0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6d,
0x69, 0x7a, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
0x52, 0x15, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64,
- 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x30, 0x0a, 0x0c, 0x42, 0x75, 0x69, 0x6c, 0x64,
- 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x08, 0x0a, 0x04, 0x55, 0x53, 0x45, 0x52, 0x10,
- 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x53, 0x45, 0x52, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x01,
- 0x12, 0x07, 0x0a, 0x03, 0x45, 0x4e, 0x47, 0x10, 0x02, 0x22, 0x3c, 0x0a, 0x04, 0x41, 0x72, 0x63,
- 0x68, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x07,
- 0x0a, 0x03, 0x41, 0x52, 0x4d, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x52, 0x4d, 0x36, 0x34,
- 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x58, 0x38, 0x36, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x58,
- 0x38, 0x36, 0x5f, 0x36, 0x34, 0x10, 0x04, 0x22, 0xd3, 0x04, 0x0a, 0x0b, 0x42, 0x75, 0x69, 0x6c,
- 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x5f, 0x67,
- 0x6f, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x75, 0x73, 0x65, 0x47, 0x6f,
- 0x6d, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x5f, 0x72, 0x62, 0x65, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x08, 0x52, 0x06, 0x75, 0x73, 0x65, 0x52, 0x62, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x66,
- 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x5f, 0x67, 0x6f, 0x6d, 0x61, 0x18, 0x03, 0x20,
- 0x01, 0x28, 0x08, 0x52, 0x0c, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x55, 0x73, 0x65, 0x47, 0x6f, 0x6d,
- 0x61, 0x12, 0x24, 0x0a, 0x0e, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x5f, 0x61, 0x73, 0x5f, 0x6e, 0x69,
- 0x6e, 0x6a, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x62, 0x61, 0x7a, 0x65, 0x6c,
- 0x41, 0x73, 0x4e, 0x69, 0x6e, 0x6a, 0x61, 0x12, 0x2a, 0x0a, 0x11, 0x62, 0x61, 0x7a, 0x65, 0x6c,
- 0x5f, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x05, 0x20, 0x01,
- 0x28, 0x08, 0x52, 0x0f, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x4d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75,
- 0x69, 0x6c, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x06,
- 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x12, 0x44, 0x0a,
- 0x1f, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x62,
- 0x61, 0x7a, 0x65, 0x6c, 0x5f, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64,
- 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x44, 0x69, 0x73,
- 0x61, 0x62, 0x6c, 0x65, 0x42, 0x61, 0x7a, 0x65, 0x6c, 0x4d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75,
- 0x69, 0x6c, 0x64, 0x12, 0x79, 0x0a, 0x18, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x5f, 0x77, 0x65, 0x69,
- 0x67, 0x68, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18,
- 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75,
- 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x42, 0x75, 0x69, 0x6c,
- 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4e, 0x69, 0x6e, 0x6a, 0x61, 0x57, 0x65, 0x69,
- 0x67, 0x68, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x08, 0x4e,
- 0x4f, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x44, 0x52, 0x15, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x57, 0x65,
- 0x69, 0x67, 0x68, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x47,
- 0x0a, 0x0e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x76, 0x5f, 0x76, 0x61, 0x72, 0x73,
- 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62,
- 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x53, 0x6f, 0x6f,
- 0x6e, 0x67, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x73, 0x52, 0x0c, 0x73, 0x6f, 0x6f, 0x6e, 0x67,
- 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x73, 0x22, 0x74, 0x0a, 0x15, 0x4e, 0x69, 0x6e, 0x6a, 0x61,
- 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65,
- 0x12, 0x0c, 0x0a, 0x08, 0x4e, 0x4f, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d,
- 0x0a, 0x09, 0x4e, 0x49, 0x4e, 0x4a, 0x41, 0x5f, 0x4c, 0x4f, 0x47, 0x10, 0x01, 0x12, 0x16, 0x0a,
- 0x12, 0x45, 0x56, 0x45, 0x4e, 0x4c, 0x59, 0x5f, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55,
- 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x45, 0x58, 0x54, 0x45, 0x52, 0x4e, 0x41,
- 0x4c, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x48, 0x49, 0x4e, 0x54,
- 0x5f, 0x46, 0x52, 0x4f, 0x4d, 0x5f, 0x53, 0x4f, 0x4f, 0x4e, 0x47, 0x10, 0x04, 0x22, 0x67, 0x0a,
- 0x0c, 0x53, 0x6f, 0x6f, 0x6e, 0x67, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x73, 0x12, 0x27, 0x0a,
- 0x0f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x43,
- 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x75, 0x73, 0x65, 0x5f, 0x70, 0x61,
- 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x11, 0x75, 0x73, 0x65, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x43,
- 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x22, 0xed, 0x01, 0x0a, 0x12, 0x53, 0x79, 0x73, 0x74, 0x65,
- 0x6d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x32, 0x0a,
- 0x15, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x70, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x5f,
- 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x74, 0x6f,
- 0x74, 0x61, 0x6c, 0x50, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x4d, 0x65, 0x6d, 0x6f, 0x72,
- 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63,
- 0x70, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x61, 0x76, 0x61, 0x69, 0x6c,
- 0x61, 0x62, 0x6c, 0x65, 0x43, 0x70, 0x75, 0x73, 0x12, 0x3d, 0x0a, 0x08, 0x63, 0x70, 0x75, 0x5f,
- 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x6f, 0x6f,
- 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
- 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x70, 0x75, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07,
- 0x63, 0x70, 0x75, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3d, 0x0a, 0x08, 0x6d, 0x65, 0x6d, 0x5f, 0x69,
- 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x6f, 0x6f, 0x6e,
- 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e,
- 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x4d, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x6d,
- 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x7e, 0x0a, 0x0d, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d,
- 0x43, 0x70, 0x75, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x76, 0x65, 0x6e, 0x64, 0x6f,
- 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x76, 0x65, 0x6e, 0x64,
- 0x6f, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x6e, 0x61,
- 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x4e,
- 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x70, 0x75, 0x5f, 0x63, 0x6f, 0x72, 0x65, 0x73,
- 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x63, 0x70, 0x75, 0x43, 0x6f, 0x72, 0x65, 0x73,
- 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x22, 0x6c, 0x0a, 0x0d, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d,
- 0x4d, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6d, 0x5f, 0x74,
- 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6d, 0x65, 0x6d, 0x54,
- 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x65, 0x6d, 0x5f, 0x66, 0x72, 0x65, 0x65,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x46, 0x72, 0x65, 0x65, 0x12,
- 0x23, 0x0a, 0x0d, 0x6d, 0x65, 0x6d, 0x5f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65,
- 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x65, 0x6d, 0x41, 0x76, 0x61, 0x69, 0x6c,
- 0x61, 0x62, 0x6c, 0x65, 0x22, 0xca, 0x02, 0x0a, 0x08, 0x50, 0x65, 0x72, 0x66, 0x49, 0x6e, 0x66,
- 0x6f, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
- 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74,
- 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x73, 0x74, 0x61,
- 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x6c, 0x5f, 0x74,
- 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x72, 0x65, 0x61, 0x6c, 0x54,
- 0x69, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0a, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x75, 0x73,
- 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x6d, 0x65, 0x6d,
- 0x6f, 0x72, 0x79, 0x55, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x17, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73,
- 0x73, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x66,
- 0x6f, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f,
- 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x72,
- 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66,
- 0x6f, 0x52, 0x15, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x6f,
- 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x22, 0x0a, 0x0d, 0x6e, 0x6f, 0x6e, 0x5f,
- 0x7a, 0x65, 0x72, 0x6f, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52,
- 0x0b, 0x6e, 0x6f, 0x6e, 0x5a, 0x65, 0x72, 0x6f, 0x45, 0x78, 0x69, 0x74, 0x12, 0x23, 0x0a, 0x0d,
- 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x08, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
- 0x65, 0x22, 0x61, 0x0a, 0x0c, 0x50, 0x65, 0x72, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72,
- 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52,
- 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18,
- 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75,
- 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x66,
- 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x06, 0x67, 0x72,
- 0x6f, 0x75, 0x70, 0x73, 0x22, 0x64, 0x0a, 0x10, 0x50, 0x65, 0x72, 0x66, 0x43, 0x6f, 0x75, 0x6e,
- 0x74, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x08,
- 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20,
- 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74,
- 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72,
- 0x52, 0x08, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x22, 0x37, 0x0a, 0x0b, 0x50, 0x65,
- 0x72, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
- 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a,
- 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61,
- 0x6c, 0x75, 0x65, 0x22, 0xb9, 0x03, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52,
- 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e,
- 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
- 0x28, 0x0a, 0x10, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x63,
- 0x72, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x75, 0x73, 0x65, 0x72, 0x54,
- 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x79, 0x73,
- 0x74, 0x65, 0x6d, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18,
- 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x69, 0x6d,
- 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x1c, 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x5f, 0x72,
- 0x73, 0x73, 0x5f, 0x6b, 0x62, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6d, 0x61, 0x78,
- 0x52, 0x73, 0x73, 0x4b, 0x62, 0x12, 0x2a, 0x0a, 0x11, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x5f, 0x70,
- 0x61, 0x67, 0x65, 0x5f, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04,
- 0x52, 0x0f, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x50, 0x61, 0x67, 0x65, 0x46, 0x61, 0x75, 0x6c, 0x74,
- 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f,
- 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6d, 0x61,
- 0x6a, 0x6f, 0x72, 0x50, 0x61, 0x67, 0x65, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x1e, 0x0a,
- 0x0b, 0x69, 0x6f, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x6b, 0x62, 0x18, 0x07, 0x20, 0x01,
- 0x28, 0x04, 0x52, 0x09, 0x69, 0x6f, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x4b, 0x62, 0x12, 0x20, 0x0a,
- 0x0c, 0x69, 0x6f, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x6b, 0x62, 0x18, 0x08, 0x20,
- 0x01, 0x28, 0x04, 0x52, 0x0a, 0x69, 0x6f, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x4b, 0x62, 0x12,
- 0x3c, 0x0a, 0x1a, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e,
- 0x74, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x09, 0x20,
- 0x01, 0x28, 0x04, 0x52, 0x18, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x43, 0x6f,
- 0x6e, 0x74, 0x65, 0x78, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x40, 0x0a,
- 0x1c, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e,
- 0x74, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x0a, 0x20,
- 0x01, 0x28, 0x04, 0x52, 0x1a, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79,
- 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x22,
- 0xe5, 0x01, 0x0a, 0x0e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x49, 0x6e,
- 0x66, 0x6f, 0x12, 0x5b, 0x0a, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x73, 0x79, 0x73, 0x74,
- 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2f, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67,
- 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4d,
- 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x42, 0x75,
- 0x69, 0x6c, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x3a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f,
- 0x57, 0x4e, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12,
- 0x1f, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65,
- 0x12, 0x24, 0x0a, 0x0e, 0x6e, 0x75, 0x6d, 0x5f, 0x6f, 0x66, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c,
- 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6e, 0x75, 0x6d, 0x4f, 0x66, 0x4d,
- 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x2f, 0x0a, 0x0b, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53,
- 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e,
- 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x4f, 0x4f, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x08, 0x0a,
- 0x04, 0x4d, 0x41, 0x4b, 0x45, 0x10, 0x02, 0x22, 0x6c, 0x0a, 0x1a, 0x43, 0x72, 0x69, 0x74, 0x69,
- 0x63, 0x61, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x4d, 0x65,
- 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x07, 0x6d, 0x65, 0x74,
- 0x72, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x6f, 0x6f,
- 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
- 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x42, 0x61, 0x73, 0x65, 0x52, 0x07, 0x6d, 0x65,
- 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x62, 0x0a, 0x1b, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61,
- 0x6c, 0x55, 0x73, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x73, 0x4d, 0x65, 0x74,
- 0x72, 0x69, 0x63, 0x73, 0x12, 0x43, 0x0a, 0x04, 0x63, 0x75, 0x6a, 0x73, 0x18, 0x01, 0x20, 0x03,
- 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64,
- 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61,
- 0x6c, 0x55, 0x73, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x4d, 0x65, 0x74, 0x72,
- 0x69, 0x63, 0x73, 0x52, 0x04, 0x63, 0x75, 0x6a, 0x73, 0x22, 0x94, 0x03, 0x0a, 0x11, 0x53, 0x6f,
- 0x6f, 0x6e, 0x67, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12,
- 0x18, 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d,
- 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x76, 0x61, 0x72,
- 0x69, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x76, 0x61, 0x72,
- 0x69, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61,
- 0x6c, 0x6c, 0x6f, 0x63, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04,
- 0x52, 0x0f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x43, 0x6f, 0x75, 0x6e,
- 0x74, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63,
- 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x74, 0x6f, 0x74,
- 0x61, 0x6c, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x6d,
- 0x61, 0x78, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01,
- 0x28, 0x04, 0x52, 0x0b, 0x6d, 0x61, 0x78, 0x48, 0x65, 0x61, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x12,
- 0x35, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32,
- 0x1d, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65,
- 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06,
- 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x50, 0x0a, 0x11, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f,
- 0x62, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x07, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x24, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f,
- 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69,
- 0x6c, 0x64, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75,
- 0x69, 0x6c, 0x64, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x46, 0x0a, 0x0d, 0x70, 0x65, 0x72, 0x66,
- 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32,
- 0x21, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65,
- 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65,
- 0x72, 0x73, 0x52, 0x0c, 0x70, 0x65, 0x72, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73,
- 0x22, 0xdb, 0x01, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x65,
- 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x4a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75,
- 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x45, 0x78, 0x70, 0x43,
- 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x65, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e,
- 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
- 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a,
- 0x06, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d,
- 0x69, 0x63, 0x72, 0x6f, 0x73, 0x22, 0x47, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53,
- 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x5f, 0x43, 0x4f, 0x4e, 0x46,
- 0x49, 0x47, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x10, 0x01,
- 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x4d,
- 0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x5f, 0x47, 0x43, 0x45, 0x52, 0x54, 0x10, 0x03, 0x22, 0x91,
- 0x01, 0x0a, 0x0f, 0x4d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x49, 0x6e,
- 0x66, 0x6f, 0x12, 0x3d, 0x0a, 0x1b, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x62, 0x75, 0x69, 0x6c,
- 0x64, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
- 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x18, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75,
- 0x69, 0x6c, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
- 0x73, 0x12, 0x3f, 0x0a, 0x1c, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64,
- 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
- 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x19, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75,
- 0x69, 0x6c, 0x64, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c,
- 0x65, 0x73, 0x22, 0x8a, 0x02, 0x0a, 0x10, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x50,
- 0x61, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2e, 0x0a, 0x13, 0x65, 0x6c, 0x61, 0x70, 0x73,
- 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x65, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x64, 0x54, 0x69, 0x6d,
- 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x39, 0x0a, 0x19, 0x63, 0x72, 0x69, 0x74, 0x69,
- 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69,
- 0x63, 0x72, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x63, 0x72, 0x69, 0x74,
- 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72,
- 0x6f, 0x73, 0x12, 0x41, 0x0a, 0x0d, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x70,
- 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x6f, 0x6f, 0x6e,
- 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e,
- 0x4a, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61,
- 0x6c, 0x50, 0x61, 0x74, 0x68, 0x12, 0x48, 0x0a, 0x11, 0x6c, 0x6f, 0x6e, 0x67, 0x5f, 0x72, 0x75,
- 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x6a, 0x6f, 0x62, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b,
- 0x32, 0x1c, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d,
- 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4a, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f,
- 0x6c, 0x6f, 0x6e, 0x67, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x4a, 0x6f, 0x62, 0x73, 0x22,
- 0x62, 0x0a, 0x07, 0x4a, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2e, 0x0a, 0x13, 0x65, 0x6c,
- 0x61, 0x70, 0x73, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f,
- 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x65, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x64,
- 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x6a, 0x6f,
- 0x62, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6a, 0x6f, 0x62, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
- 0x69, 0x6f, 0x6e, 0x22, 0xb9, 0x05, 0x0a, 0x15, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65,
- 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x42, 0x0a,
- 0x0d, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x66, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69,
- 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x49,
- 0x6e, 0x66, 0x6f, 0x52, 0x0c, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x50, 0x65, 0x72,
- 0x66, 0x12, 0x44, 0x0a, 0x0e, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x5f, 0x70,
- 0x65, 0x72, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6f, 0x6f, 0x6e,
- 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e,
- 0x50, 0x65, 0x72, 0x66, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67,
- 0x69, 0x6e, 0x67, 0x50, 0x65, 0x72, 0x66, 0x12, 0x68, 0x0a, 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65,
- 0x74, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43,
- 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74,
- 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x75,
- 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65,
- 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
- 0x75, 0x6c, 0x74, 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c,
- 0x74, 0x1a, 0xab, 0x03, 0x0a, 0x18, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x69,
- 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x12,
+ 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65,
+ 0x74, 0x5f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x24, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x22, 0x30,
+ 0x0a, 0x0c, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x08,
+ 0x0a, 0x04, 0x55, 0x53, 0x45, 0x52, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x53, 0x45, 0x52,
+ 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x45, 0x4e, 0x47, 0x10, 0x02,
+ 0x22, 0x3c, 0x0a, 0x04, 0x41, 0x72, 0x63, 0x68, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e,
+ 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x52, 0x4d, 0x10, 0x01, 0x12, 0x09,
+ 0x0a, 0x05, 0x41, 0x52, 0x4d, 0x36, 0x34, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x58, 0x38, 0x36,
+ 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x58, 0x38, 0x36, 0x5f, 0x36, 0x34, 0x10, 0x04, 0x22, 0xf2,
+ 0x04, 0x0a, 0x0b, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x19,
+ 0x0a, 0x08, 0x75, 0x73, 0x65, 0x5f, 0x67, 0x6f, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
+ 0x52, 0x07, 0x75, 0x73, 0x65, 0x47, 0x6f, 0x6d, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65,
+ 0x5f, 0x72, 0x62, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x75, 0x73, 0x65, 0x52,
+ 0x62, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x5f,
+ 0x67, 0x6f, 0x6d, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x66, 0x6f, 0x72, 0x63,
+ 0x65, 0x55, 0x73, 0x65, 0x47, 0x6f, 0x6d, 0x61, 0x12, 0x24, 0x0a, 0x0e, 0x62, 0x61, 0x7a, 0x65,
+ 0x6c, 0x5f, 0x61, 0x73, 0x5f, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08,
+ 0x52, 0x0c, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x41, 0x73, 0x4e, 0x69, 0x6e, 0x6a, 0x61, 0x12, 0x2a,
+ 0x0a, 0x11, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x5f, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x62, 0x75,
+ 0x69, 0x6c, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x62, 0x61, 0x7a, 0x65, 0x6c,
+ 0x4d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x61,
+ 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x74, 0x61, 0x72,
+ 0x67, 0x65, 0x74, 0x73, 0x12, 0x44, 0x0a, 0x1f, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x64, 0x69,
+ 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x5f, 0x6d, 0x69, 0x78, 0x65,
+ 0x64, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x66,
+ 0x6f, 0x72, 0x63, 0x65, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x61, 0x7a, 0x65, 0x6c,
+ 0x4d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x79, 0x0a, 0x18, 0x6e, 0x69,
+ 0x6e, 0x6a, 0x61, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f,
+ 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x73,
+ 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69,
+ 0x63, 0x73, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4e,
+ 0x69, 0x6e, 0x6a, 0x61, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6f,
+ 0x75, 0x72, 0x63, 0x65, 0x3a, 0x08, 0x4e, 0x4f, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x44, 0x52, 0x15,
+ 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x53,
+ 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x47, 0x0a, 0x0e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x65,
+ 0x6e, 0x76, 0x5f, 0x76, 0x61, 0x72, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e,
+ 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72,
+ 0x69, 0x63, 0x73, 0x2e, 0x53, 0x6f, 0x6f, 0x6e, 0x67, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x73,
+ 0x52, 0x0c, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x73, 0x12, 0x1d,
+ 0x0a, 0x0a, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x0a, 0x20, 0x01,
+ 0x28, 0x08, 0x52, 0x09, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x74, 0x0a,
+ 0x15, 0x4e, 0x69, 0x6e, 0x6a, 0x61, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x69, 0x73, 0x74,
+ 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x4e, 0x4f, 0x54, 0x5f, 0x55, 0x53,
+ 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x49, 0x4e, 0x4a, 0x41, 0x5f, 0x4c, 0x4f,
+ 0x47, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x45, 0x56, 0x45, 0x4e, 0x4c, 0x59, 0x5f, 0x44, 0x49,
+ 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x45,
+ 0x58, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x03, 0x12, 0x13,
+ 0x0a, 0x0f, 0x48, 0x49, 0x4e, 0x54, 0x5f, 0x46, 0x52, 0x4f, 0x4d, 0x5f, 0x53, 0x4f, 0x4f, 0x4e,
+ 0x47, 0x10, 0x04, 0x22, 0x67, 0x0a, 0x0c, 0x53, 0x6f, 0x6f, 0x6e, 0x67, 0x45, 0x6e, 0x76, 0x56,
+ 0x61, 0x72, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x63,
+ 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x61,
+ 0x72, 0x74, 0x69, 0x61, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x12, 0x2e, 0x0a, 0x13,
+ 0x75, 0x73, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6d, 0x70,
+ 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x75, 0x73, 0x65, 0x50, 0x61,
+ 0x72, 0x74, 0x69, 0x61, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x22, 0xed, 0x01, 0x0a,
+ 0x12, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49,
+ 0x6e, 0x66, 0x6f, 0x12, 0x32, 0x0a, 0x15, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x70, 0x68, 0x79,
+ 0x73, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x04, 0x52, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61,
+ 0x6c, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x76, 0x61, 0x69, 0x6c,
+ 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x70, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52,
+ 0x0d, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x70, 0x75, 0x73, 0x12, 0x3d,
+ 0x0a, 0x08, 0x63, 0x70, 0x75, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x22, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d,
+ 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x70, 0x75,
+ 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x63, 0x70, 0x75, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3d, 0x0a,
+ 0x08, 0x6d, 0x65, 0x6d, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x22, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65,
+ 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x4d, 0x65, 0x6d, 0x49,
+ 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x7e, 0x0a, 0x0d,
+ 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x70, 0x75, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a,
+ 0x09, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x08, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f,
+ 0x64, 0x65, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
+ 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x70, 0x75,
+ 0x5f, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x63, 0x70,
+ 0x75, 0x43, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18,
+ 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x22, 0x6c, 0x0a, 0x0d,
+ 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x4d, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a,
+ 0x09, 0x6d, 0x65, 0x6d, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
+ 0x52, 0x08, 0x6d, 0x65, 0x6d, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x65,
+ 0x6d, 0x5f, 0x66, 0x72, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x65,
+ 0x6d, 0x46, 0x72, 0x65, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x65, 0x6d, 0x5f, 0x61, 0x76, 0x61,
+ 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x65,
+ 0x6d, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x22, 0xca, 0x02, 0x0a, 0x08, 0x50,
+ 0x65, 0x72, 0x66, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
+ 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65,
+ 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
+ 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a,
+ 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x04, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09,
+ 0x72, 0x65, 0x61, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52,
+ 0x08, 0x72, 0x65, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0a, 0x6d, 0x65, 0x6d,
+ 0x6f, 0x72, 0x79, 0x5f, 0x75, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02, 0x18,
+ 0x01, 0x52, 0x09, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x17,
+ 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
+ 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e,
+ 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72,
+ 0x69, 0x63, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75,
+ 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x15, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
+ 0x65, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x22,
+ 0x0a, 0x0d, 0x6e, 0x6f, 0x6e, 0x5f, 0x7a, 0x65, 0x72, 0x6f, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x18,
+ 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6e, 0x6f, 0x6e, 0x5a, 0x65, 0x72, 0x6f, 0x45, 0x78,
+ 0x69, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73,
+ 0x61, 0x67, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72,
+ 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x61, 0x0a, 0x0c, 0x50, 0x65, 0x72, 0x66, 0x43,
+ 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x06, 0x67,
+ 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x6f,
+ 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
+ 0x73, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x47, 0x72, 0x6f,
+ 0x75, 0x70, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x22, 0x64, 0x0a, 0x10, 0x50, 0x65,
+ 0x72, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12,
0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
- 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x64, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x64,
- 0x12, 0x35, 0x0a, 0x16, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x15, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x65, 0x12, 0x44, 0x0a, 0x0e, 0x70, 0x61, 0x63, 0x6b, 0x61,
- 0x67, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x65, 0x72, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x08, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69,
+ 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x43,
+ 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x08, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73,
+ 0x22, 0x37, 0x0a, 0x0b, 0x50, 0x65, 0x72, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12,
+ 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
+ 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xb9, 0x03, 0x0a, 0x13, 0x50, 0x72,
+ 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66,
+ 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x74, 0x69,
+ 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52,
+ 0x0e, 0x75, 0x73, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12,
+ 0x2c, 0x0a, 0x12, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d,
+ 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x73, 0x79, 0x73,
+ 0x74, 0x65, 0x6d, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x1c, 0x0a,
+ 0x0a, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x73, 0x73, 0x5f, 0x6b, 0x62, 0x18, 0x04, 0x20, 0x01, 0x28,
+ 0x04, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x52, 0x73, 0x73, 0x4b, 0x62, 0x12, 0x2a, 0x0a, 0x11, 0x6d,
+ 0x69, 0x6e, 0x6f, 0x72, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73,
+ 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x50, 0x61, 0x67,
+ 0x65, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6d, 0x61, 0x6a, 0x6f, 0x72,
+ 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01,
+ 0x28, 0x04, 0x52, 0x0f, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x50, 0x61, 0x67, 0x65, 0x46, 0x61, 0x75,
+ 0x6c, 0x74, 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x69, 0x6f, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f,
+ 0x6b, 0x62, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x69, 0x6f, 0x49, 0x6e, 0x70, 0x75,
+ 0x74, 0x4b, 0x62, 0x12, 0x20, 0x0a, 0x0c, 0x69, 0x6f, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74,
+ 0x5f, 0x6b, 0x62, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x69, 0x6f, 0x4f, 0x75, 0x74,
+ 0x70, 0x75, 0x74, 0x4b, 0x62, 0x12, 0x3c, 0x0a, 0x1a, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61,
+ 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x77, 0x69, 0x74, 0x63,
+ 0x68, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x18, 0x76, 0x6f, 0x6c, 0x75, 0x6e,
+ 0x74, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63,
+ 0x68, 0x65, 0x73, 0x12, 0x40, 0x0a, 0x1c, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61,
+ 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x77, 0x69, 0x74, 0x63,
+ 0x68, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1a, 0x69, 0x6e, 0x76, 0x6f, 0x6c,
+ 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x53, 0x77, 0x69,
+ 0x74, 0x63, 0x68, 0x65, 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x0e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
+ 0x54, 0x79, 0x70, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x5b, 0x0a, 0x0c, 0x62, 0x75, 0x69, 0x6c,
+ 0x64, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2f,
+ 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74,
+ 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x49,
+ 0x6e, 0x66, 0x6f, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x3a,
+ 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x53,
+ 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f,
+ 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x6f, 0x64, 0x75,
+ 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x6e, 0x75, 0x6d, 0x5f, 0x6f, 0x66,
+ 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c,
+ 0x6e, 0x75, 0x6d, 0x4f, 0x66, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x2f, 0x0a, 0x0b,
+ 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x0b, 0x0a, 0x07, 0x55,
+ 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x4f, 0x4f, 0x4e,
+ 0x47, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x41, 0x4b, 0x45, 0x10, 0x02, 0x22, 0x6c, 0x0a,
+ 0x1a, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x4a, 0x6f, 0x75,
+ 0x72, 0x6e, 0x65, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e,
+ 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
+ 0x3a, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x20, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d,
+ 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x42, 0x61,
+ 0x73, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x62, 0x0a, 0x1b, 0x43,
+ 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72, 0x6e,
+ 0x65, 0x79, 0x73, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x43, 0x0a, 0x04, 0x63, 0x75,
+ 0x6a, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67,
+ 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x43,
+ 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72, 0x6e,
+ 0x65, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x04, 0x63, 0x75, 0x6a, 0x73, 0x22,
+ 0x94, 0x03, 0x0a, 0x11, 0x53, 0x6f, 0x6f, 0x6e, 0x67, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65,
+ 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12,
+ 0x1a, 0x0a, 0x08, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x0d, 0x52, 0x08, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x74,
+ 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x6c, 0x6c,
+ 0x6f, 0x63, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c,
+ 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
+ 0x04, 0x52, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x53, 0x69, 0x7a,
+ 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x73, 0x69,
+ 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6d, 0x61, 0x78, 0x48, 0x65, 0x61,
+ 0x70, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x35, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18,
+ 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75,
+ 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x66,
+ 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x50, 0x0a, 0x11,
+ 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x5f, 0x69, 0x6e, 0x66,
+ 0x6f, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f,
+ 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4d, 0x69,
+ 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x6d,
+ 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x46,
+ 0x0a, 0x0d, 0x70, 0x65, 0x72, 0x66, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x18,
+ 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75,
+ 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x66,
+ 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x52, 0x0c, 0x70, 0x65, 0x72, 0x66, 0x43, 0x6f,
+ 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x22, 0xdb, 0x01, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x43, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x46, 0x65, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x4a, 0x0a, 0x06, 0x73,
+ 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x73, 0x6f,
+ 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
+ 0x73, 0x2e, 0x45, 0x78, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x65, 0x74, 0x63, 0x68,
+ 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
+ 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e,
+ 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e,
+ 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x22, 0x47, 0x0a, 0x0c, 0x43,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0d, 0x0a, 0x09, 0x4e,
+ 0x4f, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f,
+ 0x4e, 0x46, 0x49, 0x47, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10,
+ 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x5f, 0x47, 0x43, 0x45,
+ 0x52, 0x54, 0x10, 0x03, 0x22, 0x91, 0x01, 0x0a, 0x0f, 0x4d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75,
+ 0x69, 0x6c, 0x64, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3d, 0x0a, 0x1b, 0x6d, 0x69, 0x78, 0x65,
+ 0x64, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f,
+ 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x18, 0x6d,
+ 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64,
+ 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x3f, 0x0a, 0x1c, 0x6d, 0x69, 0x78, 0x65, 0x64,
+ 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f,
+ 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x19, 0x6d,
+ 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65,
+ 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x8a, 0x02, 0x0a, 0x10, 0x43, 0x72, 0x69,
+ 0x74, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2e, 0x0a,
+ 0x13, 0x65, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69,
+ 0x63, 0x72, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x65, 0x6c, 0x61, 0x70,
+ 0x73, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x39, 0x0a,
+ 0x19, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x74,
+ 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04,
+ 0x52, 0x16, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x54, 0x69,
+ 0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x41, 0x0a, 0x0d, 0x63, 0x72, 0x69, 0x74,
+ 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32,
+ 0x1c, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65,
+ 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4a, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, 0x63,
+ 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x12, 0x48, 0x0a, 0x11, 0x6c,
+ 0x6f, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x6a, 0x6f, 0x62, 0x73,
+ 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62,
+ 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4a, 0x6f, 0x62,
+ 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x6c, 0x6f, 0x6e, 0x67, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e,
+ 0x67, 0x4a, 0x6f, 0x62, 0x73, 0x22, 0x62, 0x0a, 0x07, 0x4a, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f,
+ 0x12, 0x2e, 0x0a, 0x13, 0x65, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65,
+ 0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x65,
+ 0x6c, 0x61, 0x70, 0x73, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73,
+ 0x12, 0x27, 0x0a, 0x0f, 0x6a, 0x6f, 0x62, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6a, 0x6f, 0x62, 0x44, 0x65,
+ 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb9, 0x05, 0x0a, 0x15, 0x4f, 0x70,
+ 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72,
+ 0x69, 0x63, 0x73, 0x12, 0x42, 0x0a, 0x0d, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x5f,
+ 0x70, 0x65, 0x72, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6f, 0x6f,
+ 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
+ 0x2e, 0x50, 0x65, 0x72, 0x66, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, 0x61, 0x6e, 0x61, 0x6c, 0x79,
+ 0x73, 0x69, 0x73, 0x50, 0x65, 0x72, 0x66, 0x12, 0x44, 0x0a, 0x0e, 0x70, 0x61, 0x63, 0x6b, 0x61,
+ 0x67, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x65, 0x72, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x1d, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65,
0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d,
- 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x50, 0x65, 0x72, 0x66, 0x12, 0x7b, 0x0a,
- 0x0f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74,
- 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x52, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62,
- 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4f, 0x70, 0x74,
- 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69,
- 0x63, 0x73, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x4f, 0x75, 0x74, 0x70,
- 0x75, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x0e, 0x6f, 0x75, 0x74, 0x70,
- 0x75, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x1a, 0x63, 0x0a, 0x0e, 0x4f, 0x75,
- 0x74, 0x70, 0x75, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04,
- 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
- 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04,
- 0x73, 0x69, 0x7a, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64,
- 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f,
- 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x22,
- 0x83, 0x01, 0x0a, 0x10, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74,
- 0x72, 0x69, 0x63, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f,
- 0x61, 0x72, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d,
- 0x61, 0x6e, 0x64, 0x41, 0x72, 0x67, 0x73, 0x12, 0x4c, 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x6e, 0x67,
- 0x65, 0x64, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27,
- 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74,
- 0x72, 0x69, 0x63, 0x73, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x46,
- 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64,
- 0x46, 0x69, 0x6c, 0x65, 0x73, 0x22, 0xc9, 0x01, 0x0a, 0x12, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67,
- 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09,
- 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52,
- 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68,
- 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61,
- 0x6e, 0x67, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e,
- 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f,
- 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64, 0x65, 0x6c, 0x74,
- 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x65,
- 0x6c, 0x74, 0x61, 0x12, 0x36, 0x0a, 0x06, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20,
- 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c,
- 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x6f,
- 0x75, 0x6e, 0x74, 0x52, 0x06, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10,
- 0x02, 0x22, 0x8b, 0x01, 0x0a, 0x09, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12,
- 0x1c, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a,
- 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d,
- 0x52, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x6d,
- 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01,
- 0x28, 0x0d, 0x52, 0x0d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04,
- 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42,
- 0x28, 0x5a, 0x26, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67,
- 0x2f, 0x75, 0x69, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72,
- 0x69, 0x63, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x50, 0x65, 0x72, 0x66, 0x12, 0x68, 0x0a,
+ 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x03,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69,
+ 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6d,
+ 0x69, 0x7a, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
+ 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65,
+ 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x1a, 0xab, 0x03, 0x0a, 0x18, 0x54, 0x61, 0x72, 0x67,
+ 0x65, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
+ 0x73, 0x75, 0x6c, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6f, 0x70, 0x74, 0x69,
+ 0x6d, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6f, 0x70, 0x74,
+ 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x64, 0x12, 0x35, 0x0a, 0x16, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69,
+ 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x65,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x65, 0x12, 0x44, 0x0a,
+ 0x0e, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x65, 0x72, 0x66, 0x18,
+ 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75,
+ 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x66,
+ 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x50,
+ 0x65, 0x72, 0x66, 0x12, 0x7b, 0x0a, 0x0f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x61, 0x72,
+ 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x52, 0x2e, 0x73,
+ 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69,
+ 0x63, 0x73, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c,
+ 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4f,
+ 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c,
+ 0x74, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74,
+ 0x52, 0x0e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74,
+ 0x1a, 0x63, 0x0a, 0x0e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61,
+ 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e,
+ 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03,
+ 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x4d, 0x6f,
+ 0x64, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x83, 0x01, 0x0a, 0x10, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74,
+ 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f,
+ 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09,
+ 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x41, 0x72, 0x67, 0x73, 0x12, 0x4c, 0x0a,
+ 0x0d, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69,
+ 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65,
+ 0x67, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x0c, 0x63,
+ 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x22, 0xc9, 0x01, 0x0a, 0x12,
+ 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69,
+ 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,
+ 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+ 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
+ 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65,
+ 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x64,
+ 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61,
+ 0x6c, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74,
+ 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x12, 0x36, 0x0a, 0x06, 0x63, 0x6f, 0x75,
+ 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x6f, 0x6f, 0x6e,
+ 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e,
+ 0x46, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x06, 0x63, 0x6f, 0x75, 0x6e, 0x74,
+ 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x8b, 0x01, 0x0a, 0x09, 0x46, 0x69, 0x6c, 0x65,
+ 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,
+ 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,
+ 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e,
+ 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69,
+ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74,
+ 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65,
+ 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x28, 0x5a, 0x26, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x75, 0x69, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
+ 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
}
var (
diff --git a/ui/metrics/metrics_proto/metrics.proto b/ui/metrics/metrics_proto/metrics.proto
index a711ffb..7ff389a 100644
--- a/ui/metrics/metrics_proto/metrics.proto
+++ b/ui/metrics/metrics_proto/metrics.proto
@@ -140,6 +140,9 @@
// Metrics related to optimized builds.
optional OptimizedBuildMetrics optimized_build_metrics = 35;
+
+ // The target release information. e.g., trunk_staging.
+ optional string target_release = 36;
}
message BuildConfig {
@@ -180,6 +183,10 @@
// Values of some build-affecting environment variables.
optional SoongEnvVars soong_env_vars = 9;
+
+ // Whether this build uses soong-only (no kati) mode (either via environment variable,
+ // command line flag or product config.
+ optional bool soong_only = 10;
}
message SoongEnvVars {
diff --git a/ui/status/ninja.go b/ui/status/ninja.go
index 8c3ff29..73edbf6 100644
--- a/ui/status/ninja.go
+++ b/ui/status/ninja.go
@@ -46,6 +46,7 @@
forceClose: make(chan bool),
done: make(chan bool),
cancelOpen: make(chan bool),
+ running: make(map[uint32]*Action),
}
go n.run()
@@ -59,6 +60,7 @@
forceClose chan bool
done chan bool
cancelOpen chan bool
+ running map[uint32]*Action
}
const NINJA_READER_CLOSE_TIMEOUT = 5 * time.Second
@@ -68,32 +70,47 @@
// Signal the goroutine to stop if it is blocking opening the fifo.
close(n.cancelOpen)
+ closed := false
+
// Ninja should already have exited or been killed, wait 5 seconds for the FIFO to be closed and any
// remaining messages to be processed through the NinjaReader.run goroutine.
timeoutCh := time.After(NINJA_READER_CLOSE_TIMEOUT)
select {
case <-n.done:
- return
+ closed = true
case <-timeoutCh:
// Channel is not closed yet
}
- n.status.Error(fmt.Sprintf("ninja fifo didn't finish after %s", NINJA_READER_CLOSE_TIMEOUT.String()))
+ if !closed {
+ n.status.Error(fmt.Sprintf("ninja fifo didn't finish after %s", NINJA_READER_CLOSE_TIMEOUT.String()))
- // Force close the reader even if the FIFO didn't close.
- close(n.forceClose)
+ // Force close the reader even if the FIFO didn't close.
+ close(n.forceClose)
- // Wait again for the reader thread to acknowledge the close before giving up and assuming it isn't going
- // to send anything else.
- timeoutCh = time.After(NINJA_READER_CLOSE_TIMEOUT)
- select {
- case <-n.done:
- return
- case <-timeoutCh:
- // Channel is not closed yet
+ // Wait again for the reader thread to acknowledge the close before giving up and assuming it isn't going
+ // to send anything else.
+ timeoutCh = time.After(NINJA_READER_CLOSE_TIMEOUT)
+ select {
+ case <-n.done:
+ closed = true
+ case <-timeoutCh:
+ // Channel is not closed yet
+ }
}
- n.status.Verbose(fmt.Sprintf("ninja fifo didn't finish even after force closing after %s", NINJA_READER_CLOSE_TIMEOUT.String()))
+ if !closed {
+ n.status.Verbose(fmt.Sprintf("ninja fifo didn't finish even after force closing after %s", NINJA_READER_CLOSE_TIMEOUT.String()))
+ }
+
+ err := fmt.Errorf("error: action cancelled when ninja exited")
+ for _, action := range n.running {
+ n.status.FinishAction(ActionResult{
+ Action: action,
+ Output: err.Error(),
+ Error: err,
+ })
+ }
}
func (n *NinjaReader) run() {
@@ -125,8 +142,6 @@
r := bufio.NewReader(f)
- running := map[uint32]*Action{}
-
msgChan := make(chan *ninja_frontend.Status)
// Read from the ninja fifo and decode the protobuf in a goroutine so the main NinjaReader.run goroutine
@@ -213,11 +228,11 @@
ChangedInputs: msg.EdgeStarted.ChangedInputs,
}
n.status.StartAction(action)
- running[msg.EdgeStarted.GetId()] = action
+ n.running[msg.EdgeStarted.GetId()] = action
}
if msg.EdgeFinished != nil {
- if started, ok := running[msg.EdgeFinished.GetId()]; ok {
- delete(running, msg.EdgeFinished.GetId())
+ if started, ok := n.running[msg.EdgeFinished.GetId()]; ok {
+ delete(n.running, msg.EdgeFinished.GetId())
var err error
exitCode := int(msg.EdgeFinished.GetStatus())
diff --git a/vnames.json b/vnames.json
index 096260f..9e006bb 100644
--- a/vnames.json
+++ b/vnames.json
@@ -1,5 +1,17 @@
[
{
+ "pattern": "out/(.*)/srcjars.xref/frameworks/base/services/core/(.*)/android/server/am/(.*)",
+ "vname": {
+ "path": "frameworks/base/services/core/@2@/android/server/am/@3@"
+ }
+ },
+ {
+ "pattern": "out/(.*)/srcjars.xref/frameworks/base/services/core/(.*)/android/server/wm/(.*)",
+ "vname": {
+ "path": "frameworks/base/services/core/@2@/android/server/wm/@3@"
+ }
+ },
+ {
"pattern": "out/(.*)",
"vname": {
"root": "out",
diff --git a/xml/xml_test.go b/xml/xml_test.go
index 9f28315..212b0c5 100644
--- a/xml/xml_test.go
+++ b/xml/xml_test.go
@@ -71,7 +71,7 @@
{rule: "xmllint-minimal", input: "baz.xml"},
} {
t.Run(tc.schemaType, func(t *testing.T) {
- rule := result.ModuleForTests(tc.input, "android_arm64_armv8-a").Rule(tc.rule)
+ rule := result.ModuleForTests(t, tc.input, "android_arm64_armv8-a").Rule(tc.rule)
android.AssertStringEquals(t, "input", tc.input, rule.Input.String())
if tc.schemaType != "" {
android.AssertStringEquals(t, "schema", tc.schema, rule.Args[tc.schemaType])
@@ -79,6 +79,6 @@
})
}
- m := result.ModuleForTests("foo.xml", "android_arm64_armv8-a").Module().(*prebuiltEtcXml)
+ m := result.ModuleForTests(t, "foo.xml", "android_arm64_armv8-a").Module().(*prebuiltEtcXml)
android.AssertPathRelativeToTopEquals(t, "installDir", "out/target/product/test_device/system/etc", m.InstallDirPath())
}
diff --git a/zip/zip.go b/zip/zip.go
index f91a5f2..22b7704 100644
--- a/zip/zip.go
+++ b/zip/zip.go
@@ -475,13 +475,50 @@
return nil
}
+func (z *ZipWriter) moveJavaFileBasedOnPackage(mapping *pathMapping) error {
+ src := mapping.src
+ var s os.FileInfo
+ var err error
+ if z.followSymlinks {
+ s, err = z.fs.Stat(src)
+ } else {
+ s, err = z.fs.Lstat(src)
+ }
+ if err != nil {
+ if os.IsNotExist(err) && z.ignoreMissingFiles {
+ return nil
+ }
+ return err
+ }
+ if !s.Mode().IsRegular() {
+ return nil
+ }
+ r, err := z.fs.Open(src)
+ if err != nil {
+ return err
+ }
+ // rewrite the destination using the package path if it can be determined
+ pkg, err := jar.JavaPackage(r, src)
+ err2 := r.Close()
+ if err2 != nil {
+ return err2
+ }
+ if err != nil {
+ // ignore errors for now, leaving the file at in its original location in the zip
+ } else {
+ mapping.dest = filepath.Join(filepath.Join(strings.Split(pkg, ".")...), filepath.Base(src))
+ }
+ return nil
+}
+
func jarSort(mappings []pathMapping) {
sort.SliceStable(mappings, func(i int, j int) bool {
return jar.EntryNamesLess(mappings[i].dest, mappings[j].dest)
})
}
-func (z *ZipWriter) write(f io.Writer, pathMappings []pathMapping, manifest string, emulateJar, srcJar bool,
+func (z *ZipWriter) write(f io.Writer, pathMappings []pathMapping, manifest string,
+ emulateJar, srcJar bool,
parallelJobs int) error {
z.errors = make(chan error)
@@ -511,11 +548,41 @@
return errors.New("must specify --jar when specifying a manifest via -m")
}
+ // move java source files to the correct folder based on the package statement inside of them.
+ // This is done before the entry sorting so that they're still in the right order.
+ if srcJar {
+ var javaMoveErrors []error
+ var javaMoveErrorsLock sync.Mutex
+ var wg sync.WaitGroup
+ for i := range pathMappings {
+ if filepath.Ext(pathMappings[i].src) == ".java" {
+ wg.Add(1)
+ go func() {
+ err := z.moveJavaFileBasedOnPackage(&pathMappings[i])
+ if err != nil {
+ javaMoveErrorsLock.Lock()
+ javaMoveErrors = append(javaMoveErrors, err)
+ javaMoveErrorsLock.Unlock()
+ }
+ wg.Done()
+ }()
+ }
+ }
+ wg.Wait()
+ if len(javaMoveErrors) > 0 {
+ return errors.Join(javaMoveErrors...)
+ }
+ }
+
if emulateJar {
// manifest may be empty, in which case addManifest will fill in a default
pathMappings = append(pathMappings, pathMapping{jar.ManifestFile, manifest, zip.Deflate})
jarSort(pathMappings)
+ } else {
+ sort.SliceStable(pathMappings, func(i int, j int) bool {
+ return pathMappings[i].dest < pathMappings[j].dest
+ })
}
go func() {
@@ -526,7 +593,7 @@
if emulateJar && ele.dest == jar.ManifestFile {
err = z.addManifest(ele.dest, ele.src, ele.zipMethod)
} else {
- err = z.addFile(ele.dest, ele.src, ele.zipMethod, emulateJar, srcJar)
+ err = z.addFile(ele.dest, ele.src, ele.zipMethod, emulateJar)
}
if err != nil {
z.errors <- err
@@ -625,7 +692,7 @@
}
// imports (possibly with compression) <src> into the zip at sub-path <dest>
-func (z *ZipWriter) addFile(dest, src string, method uint16, emulateJar, srcJar bool) error {
+func (z *ZipWriter) addFile(dest, src string, method uint16, emulateJar bool) error {
var fileSize int64
var executable bool
@@ -699,21 +766,6 @@
return err
}
- if srcJar && filepath.Ext(src) == ".java" {
- // rewrite the destination using the package path if it can be determined
- pkg, err := jar.JavaPackage(r, src)
- if err != nil {
- // ignore errors for now, leaving the file at in its original location in the zip
- } else {
- dest = filepath.Join(filepath.Join(strings.Split(pkg, ".")...), filepath.Base(src))
- }
-
- _, err = r.Seek(0, io.SeekStart)
- if err != nil {
- return err
- }
- }
-
fileSize = s.Size()
executable = s.Mode()&0100 != 0
diff --git a/zip/zip_test.go b/zip/zip_test.go
index c64c3f4..8f100d8 100644
--- a/zip/zip_test.go
+++ b/zip/zip_test.go
@@ -159,10 +159,10 @@
compressionLevel: 9,
files: []zip.FileHeader{
+ fh("[", fileEmpty, zip.Store),
fh("a/a/a", fileA, zip.Deflate),
fh("a/a/b", fileB, zip.Deflate),
fh("c", fileC, zip.Deflate),
- fh("[", fileEmpty, zip.Store),
},
},
{
@@ -261,10 +261,10 @@
compressionLevel: 9,
files: []zip.FileHeader{
+ fh("[", fileEmpty, zip.Store),
fh("a/a/a", fileA, zip.Deflate),
fh("a/a/b", fileB, zip.Deflate),
fh("c", fileC, zip.Deflate),
- fh("[", fileEmpty, zip.Store),
},
},
{
@@ -274,10 +274,10 @@
compressionLevel: 9,
files: []zip.FileHeader{
+ fh("[", fileEmpty, zip.Store),
fh("a/a/a", fileA, zip.Deflate),
fh("a/a/b", fileB, zip.Deflate),
fh("c", fileC, zip.Deflate),
- fh("[", fileEmpty, zip.Store),
},
},
{
@@ -287,11 +287,11 @@
compressionLevel: 9,
files: []zip.FileHeader{
+ fh("@", fileC, zip.Deflate),
+ fh("[", fileEmpty, zip.Store),
fh("a/a/a", fileA, zip.Deflate),
fh("a/a/b", fileB, zip.Deflate),
- fh("@", fileC, zip.Deflate),
fh("foo'bar", fileC, zip.Deflate),
- fh("[", fileEmpty, zip.Store),
},
},
{
@@ -463,8 +463,8 @@
compressionLevel: 9,
files: []zip.FileHeader{
- fh("foo", fileA, zip.Deflate),
fh("a/a/b", fileB, zip.Deflate),
+ fh("foo", fileA, zip.Deflate),
},
},
{
@@ -477,8 +477,8 @@
compressionLevel: 9,
files: []zip.FileHeader{
- fh("prefix/foo", fileA, zip.Deflate),
fh("prefix/a/a/b", fileB, zip.Deflate),
+ fh("prefix/foo", fileA, zip.Deflate),
},
},
{
@@ -490,8 +490,8 @@
compressionLevel: 9,
files: []zip.FileHeader{
- fh("foo", fileA, zip.Deflate),
fh("a/a/b", fileB, zip.Deflate),
+ fh("foo", fileA, zip.Deflate),
},
},
{
@@ -504,8 +504,8 @@
compressionLevel: 9,
files: []zip.FileHeader{
- fh("foo/bar", fileA, zip.Deflate),
fh("b", fileB, zip.Deflate),
+ fh("foo/bar", fileA, zip.Deflate),
},
},
@@ -688,8 +688,8 @@
want := []string{
"foo/",
- "foo/wrong_package.java",
"foo/correct_package.java",
+ "foo/wrong_package.java",
"no_package.java",
"src2/",
"src2/parse_error.java",