Merge "Create the filegroup to collect cert files for otatools.zip" into main
diff --git a/aconfig/all_aconfig_declarations.go b/aconfig/all_aconfig_declarations.go
index e3ef7dd..f3c68c3 100644
--- a/aconfig/all_aconfig_declarations.go
+++ b/aconfig/all_aconfig_declarations.go
@@ -95,11 +95,44 @@
})
}
+func GenerateExportedFlagCheck(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: ExportedFlagCheckRule,
+ 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)
+
+ depsFiles := android.Paths{this.finalizedFlags}
+ if checkExportedFlag, ok := ctx.Config().GetBuildFlag("RELEASE_EXPORTED_FLAG_CHECK"); ok {
+ if checkExportedFlag == "true" {
+ invalidExportedFlags := android.PathForIntermediates(ctx, "invalid_exported_flags.txt")
+ GenerateExportedFlagCheck(ctx, invalidExportedFlags, parsedFlagsFile, this.properties)
+ depsFiles = append(depsFiles, invalidExportedFlags)
+ }
+ }
+
+ ctx.Phony("all_aconfig_declarations", depsFiles...)
android.SetProvider(ctx, allAconfigDeclarationsInfoProvider, allAconfigDeclarationsInfo{
parsedFlagsFile: parsedFlagsFile,
diff --git a/aconfig/init.go b/aconfig/init.go
index b2fe5a3..d8d5470 100644
--- a/aconfig/init.go
+++ b/aconfig/init.go
@@ -77,6 +77,13 @@
"${record-finalized-flags}",
},
}, "api_signature_files", "finalized_flags_file", "parsed_flags_file")
+ ExportedFlagCheckRule = pctx.AndroidStaticRule("ExportedFlagCheckRule",
+ blueprint.RuleParams{
+ Command: `${exported-flag-check} ${parsed_flags_file} ${finalized_flags_file} ${api_signature_files} > ${out}`,
+ CommandDeps: []string{
+ "${exported-flag-check}",
+ },
+ }, "api_signature_files", "finalized_flags_file", "parsed_flags_file")
CreateStorageRule = pctx.AndroidStaticRule("aconfig_create_storage",
blueprint.RuleParams{
@@ -124,6 +131,7 @@
pctx.HostBinToolVariable("aconfig", "aconfig")
pctx.HostBinToolVariable("soong_zip", "soong_zip")
pctx.HostBinToolVariable("record-finalized-flags", "record-finalized-flags")
+ pctx.HostBinToolVariable("exported-flag-check", "exported-flag-check")
}
func RegisterBuildComponents(ctx android.RegistrationContext) {
diff --git a/android/androidmk.go b/android/androidmk.go
index 84eef62..694f5d6 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -528,6 +528,14 @@
fmt.Fprintf(&a.header, "\ninclude $(CLEAR_VARS) # type: %s, name: %s, variant: %s\n", ctx.ModuleType(mod), base.BaseModuleName(), ctx.ModuleSubDir(mod))
+ // Add the TestSuites from the provider to LOCAL_SOONG_PROVIDER_TEST_SUITES.
+ // LOCAL_SOONG_PROVIDER_TEST_SUITES will be compared against LOCAL_COMPATIBILITY_SUITES
+ // in make and enforced they're the same, to ensure we've successfully translated all
+ // LOCAL_COMPATIBILITY_SUITES usages to the provider.
+ if testSuiteInfo, ok := OtherModuleProvider(ctx, mod, TestSuiteInfoProvider); ok {
+ a.AddStrings("LOCAL_SOONG_PROVIDER_TEST_SUITES", testSuiteInfo.TestSuites...)
+ }
+
// Collect make variable assignment entries.
a.SetString("LOCAL_PATH", ctx.ModuleDir(mod))
a.SetString("LOCAL_MODULE", name+a.SubName)
@@ -1476,12 +1484,17 @@
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, commonInfo) {
- a.HeaderStrings = append(a.HeaderStrings, distString)
- }
-
+ a.HeaderStrings = append(a.HeaderStrings, a.GetDistForGoals(ctx, mod, commonInfo)...)
a.HeaderStrings = append(a.HeaderStrings, fmt.Sprintf("\ninclude $(CLEAR_VARS) # type: %s, name: %s, variant: %s", ctx.ModuleType(mod), commonInfo.BaseModuleName, ctx.ModuleSubDir(mod)))
+ // Add the TestSuites from the provider to LOCAL_SOONG_PROVIDER_TEST_SUITES.
+ // LOCAL_SOONG_PROVIDER_TEST_SUITES will be compared against LOCAL_COMPATIBILITY_SUITES
+ // in make and enforced they're the same, to ensure we've successfully translated all
+ // LOCAL_COMPATIBILITY_SUITES usages to the provider.
+ if testSuiteInfo, ok := OtherModuleProvider(ctx, mod, TestSuiteInfoProvider); ok {
+ helperInfo.AddStrings("LOCAL_SOONG_PROVIDER_TEST_SUITES", testSuiteInfo.TestSuites...)
+ }
+
// Collect make variable assignment entries.
helperInfo.SetString("LOCAL_PATH", ctx.ModuleDir(mod))
helperInfo.SetString("LOCAL_MODULE", name+a.SubName)
diff --git a/android/config.go b/android/config.go
index 9ccd099..2a4b927 100644
--- a/android/config.go
+++ b/android/config.go
@@ -200,6 +200,11 @@
return c.config.productVariables.ReleaseAconfigValueSets
}
+// If native modules should have symbols stripped by default. Default false, enabled for build tools
+func (c Config) StripByDefault() bool {
+ return proptools.Bool(c.config.productVariables.StripByDefault)
+}
+
func (c Config) ReleaseAconfigExtraReleaseConfigs() []string {
result := []string{}
if val, ok := c.config.productVariables.BuildFlags["RELEASE_ACONFIG_EXTRA_RELEASE_CONFIGS"]; ok {
diff --git a/android/module.go b/android/module.go
index 3d643f9..c6c4fd8 100644
--- a/android/module.go
+++ b/android/module.go
@@ -520,6 +520,11 @@
// names of other modules to install on target if this module is installed
Target_required []string `android:"arch_variant"`
+
+ // If this is a soong config module, this property will be set to the name of the original
+ // module type. This is used by neverallow to ensure you can't bypass a ModuleType() matcher
+ // just by creating a soong config module type.
+ Soong_config_base_module_type *string `blueprint:"mutated"`
}
type distProperties struct {
diff --git a/android/neverallow.go b/android/neverallow.go
index eca8eb3..a7bfd2d 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -412,7 +412,8 @@
continue
}
- if !n.appliesToModuleType(ctx.ModuleType()) {
+ modType := proptools.StringDefault(m.base().baseProperties.Soong_config_base_module_type, ctx.ModuleType())
+ if !n.appliesToModuleType(modType) {
continue
}
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index c74d5ff..3ccc883 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -388,6 +388,30 @@
`module type not allowed to be defined in bp file`,
},
},
+ // Test the a neverallowed module type can't be smuggled through a soong config module type
+ {
+ name: `smuggling module types through soong config modules`,
+ fs: map[string][]byte{
+ "a/b/Android.bp": []byte(`
+ soong_config_bool_variable {
+ name: "my_var",
+ }
+ soong_config_module_type {
+ name: "smuggled_prebuilt_usr_srec",
+ module_type: "prebuilt_usr_srec",
+ config_namespace: "ANDROID",
+ variables: ["my_var"],
+ properties: ["enabled"],
+ }
+ smuggled_prebuilt_usr_srec {
+ name: "foo",
+ }
+ `),
+ },
+ expectedErrors: []string{
+ `module type not allowed to be defined in bp file`,
+ },
+ },
}
var prepareForNeverAllowTest = GroupFixturePreparers(
@@ -399,6 +423,7 @@
ctx.RegisterModuleType("filesystem", newMockFilesystemModule)
ctx.RegisterModuleType("prebuilt_usr_srec", newMockPrebuiltUsrSrecModule)
}),
+ PrepareForTestWithSoongConfigModuleBuildComponents,
)
func TestNeverallow(t *testing.T) {
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 1932225..0178f76 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -607,11 +607,6 @@
if !moduleInFamily.ExportedToMake() {
continue
}
- // Skip for the top-level java_sdk_library_(_import). This has some special cases that need to be addressed first.
- // This does not run into non-determinism because PrebuiltPostDepsMutator also has the special case
- if sdkLibrary, ok := moduleInFamily.(interface{ SdkLibraryName() *string }); ok && sdkLibrary.SdkLibraryName() != nil {
- continue
- }
if p := GetEmbeddedPrebuilt(moduleInFamily); p != nil && p.properties.UsePrebuilt {
if selectedPrebuilt == nil {
selectedPrebuilt = moduleInFamily
@@ -638,26 +633,10 @@
if p := GetEmbeddedPrebuilt(m); p != nil {
bmn, _ := m.(baseModuleName)
name := bmn.BaseModuleName()
- psi := PrebuiltSelectionInfoMap{}
- ctx.VisitDirectDepsWithTag(AcDepTag, func(am Module) {
- psi, _ = OtherModuleProvider(ctx, am, PrebuiltSelectionInfoProvider)
- })
if p.properties.UsePrebuilt {
if p.properties.SourceExists {
ctx.ReplaceDependenciesIf(name, func(from blueprint.Module, tag blueprint.DependencyTag, to blueprint.Module) bool {
- if sdkLibrary, ok := m.(interface{ SdkLibraryName() *string }); ok && sdkLibrary.SdkLibraryName() != nil {
- // Do not replace deps to the top-level prebuilt java_sdk_library hook.
- // This hook has been special-cased in #isSelected to be _always_ active, even in next builds
- // for dexpreopt and hiddenapi processing.
- // If we do not special-case this here, rdeps referring to a java_sdk_library in next builds via libs
- // will get prebuilt stubs
- // TODO (b/308187268): Remove this after the apexes have been added to apex_contributions
- if psi.IsSelected(name) {
- return false
- }
- }
-
if t, ok := tag.(ReplaceSourceWithPrebuilt); ok {
return t.ReplaceSourceWithPrebuilt()
}
@@ -679,23 +658,13 @@
// java_sdk_library_import is a macro that creates
// 1. top-level "impl" library
// 2. stub libraries (suffixed with .stubs...)
-//
-// the impl of java_sdk_library_import is a "hook" for hiddenapi and dexpreopt processing. It does not have an impl jar, but acts as a shim
-// to provide the jar deapxed from the prebuilt apex
-//
-// isSelected uses `all_apex_contributions` to supersede source vs prebuilts selection of the stub libraries. It does not supersede the
-// selection of the top-level "impl" library so that this hook can work
-//
-// TODO (b/308174306) - Fix this when we need to support multiple prebuilts in main
func isSelected(psi PrebuiltSelectionInfoMap, m Module) bool {
if sdkLibrary, ok := m.(interface{ SdkLibraryName() *string }); ok && sdkLibrary.SdkLibraryName() != nil {
sln := proptools.String(sdkLibrary.SdkLibraryName())
// This is the top-level library
- // Do not supersede the existing prebuilts vs source selection mechanisms
- // TODO (b/308187268): Remove this after the apexes have been added to apex_contributions
if bmn, ok := m.(baseModuleName); ok && sln == bmn.BaseModuleName() {
- return false
+ return psi.IsSelected(m.Name())
}
// Stub library created by java_sdk_library_import
diff --git a/android/soong_config_modules.go b/android/soong_config_modules.go
index e0b1d7c..a61c9d3 100644
--- a/android/soong_config_modules.go
+++ b/android/soong_config_modules.go
@@ -506,6 +506,10 @@
conditionalProps := proptools.CloneEmptyProperties(conditionalFactoryProps)
props = append(props, conditionalProps.Interface())
+ if m, ok := module.(Module); ok {
+ m.base().baseProperties.Soong_config_base_module_type = &moduleType.BaseModuleType
+ }
+
// Regular Soong operation wraps the existing module factory with a
// conditional on Soong config variables by reading the product
// config variables from Make.
diff --git a/android/test_suites.go b/android/test_suites.go
index 39317ec..9eaf785 100644
--- a/android/test_suites.go
+++ b/android/test_suites.go
@@ -29,10 +29,7 @@
return &testSuiteFiles{}
}
-type testSuiteFiles struct {
- robolectric []Path
- ravenwood []Path
-}
+type testSuiteFiles struct{}
type TestSuiteModule interface {
Module
@@ -61,22 +58,22 @@
}
})
- t.robolectric = robolectricTestSuite(ctx, files["robolectric-tests"])
- ctx.Phony("robolectric-tests", t.robolectric...)
+ robolectricZip, robolectrictListZip := buildTestSuite(ctx, "robolectric-tests", files["robolectric-tests"])
+ ctx.Phony("robolectric-tests", robolectricZip, robolectrictListZip)
+ ctx.DistForGoal("robolectric-tests", robolectricZip, robolectrictListZip)
- t.ravenwood = ravenwoodTestSuite(ctx, files["ravenwood-tests"])
- ctx.Phony("ravenwood-tests", t.ravenwood...)
- ctx.DistForGoal("robolectric-tests", t.robolectric...)
- ctx.DistForGoal("ravenwood-tests", t.ravenwood...)
+ ravenwoodZip, ravenwoodListZip := buildTestSuite(ctx, "ravenwood-tests", files["ravenwood-tests"])
+ ctx.Phony("ravenwood-tests", ravenwoodZip, ravenwoodListZip)
+ ctx.DistForGoal("ravenwood-tests", ravenwoodZip, ravenwoodListZip)
}
-func robolectricTestSuite(ctx SingletonContext, files map[string]InstallPaths) []Path {
+func buildTestSuite(ctx SingletonContext, suiteName string, files map[string]InstallPaths) (Path, Path) {
var installedPaths InstallPaths
for _, module := range SortedKeys(files) {
installedPaths = append(installedPaths, files[module]...)
}
- outputFile := pathForPackaging(ctx, "robolectric-tests.zip")
+ outputFile := pathForPackaging(ctx, suiteName+".zip")
rule := NewRuleBuilder(pctx, ctx)
rule.Command().BuiltTool("soong_zip").
FlagWithOutput("-o ", outputFile).
@@ -85,8 +82,8 @@
FlagWithRspFileInputList("-r ", outputFile.ReplaceExtension(ctx, "rsp"), installedPaths.Paths()).
Flag("-sha256") // necessary to save cas_uploader's time
- testList := buildTestList(ctx, "robolectric-tests_list", installedPaths)
- testListZipOutputFile := pathForPackaging(ctx, "robolectric-tests_list.zip")
+ testList := buildTestList(ctx, suiteName+"_list", installedPaths)
+ testListZipOutputFile := pathForPackaging(ctx, suiteName+"_list.zip")
rule.Command().BuiltTool("soong_zip").
FlagWithOutput("-o ", testListZipOutputFile).
@@ -94,38 +91,9 @@
FlagWithInput("-f ", testList).
Flag("-sha256")
- rule.Build("robolectric_tests_zip", "robolectric-tests.zip")
+ rule.Build(strings.ReplaceAll(suiteName, "-", "_")+"_zip", suiteName+".zip")
- return []Path{outputFile, testListZipOutputFile}
-}
-
-func ravenwoodTestSuite(ctx SingletonContext, files map[string]InstallPaths) []Path {
- var installedPaths InstallPaths
- for _, module := range SortedKeys(files) {
- installedPaths = append(installedPaths, files[module]...)
- }
-
- outputFile := pathForPackaging(ctx, "ravenwood-tests.zip")
- rule := NewRuleBuilder(pctx, ctx)
- rule.Command().BuiltTool("soong_zip").
- FlagWithOutput("-o ", outputFile).
- FlagWithArg("-P ", "host/testcases").
- FlagWithArg("-C ", pathForTestCases(ctx).String()).
- FlagWithRspFileInputList("-r ", outputFile.ReplaceExtension(ctx, "rsp"), installedPaths.Paths()).
- Flag("-sha256") // necessary to save cas_uploader's time
-
- testList := buildTestList(ctx, "ravenwood-tests_list", installedPaths)
- testListZipOutputFile := pathForPackaging(ctx, "ravenwood-tests_list.zip")
-
- rule.Command().BuiltTool("soong_zip").
- FlagWithOutput("-o ", testListZipOutputFile).
- FlagWithArg("-C ", pathForPackaging(ctx).String()).
- FlagWithInput("-f ", testList).
- Flag("-sha256")
-
- rule.Build("ravenwood_tests_zip", "ravenwood-tests.zip")
-
- return []Path{outputFile, testListZipOutputFile}
+ return outputFile, testListZipOutputFile
}
func buildTestList(ctx SingletonContext, listFile string, installedPaths InstallPaths) Path {
diff --git a/android/variable.go b/android/variable.go
index 853d8ef..c59857a 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -554,6 +554,8 @@
OdmManifestFiles []string `json:",omitempty"`
UseSoongNoticeXML *bool `json:",omitempty"`
+
+ StripByDefault *bool `json:",omitempty"`
}
type PartitionQualifiedVariablesType struct {
@@ -654,6 +656,7 @@
ProductUseDynamicPartitions bool `json:",omitempty"`
ProductRetrofitDynamicPartitions bool `json:",omitempty"`
ProductBuildSuperPartition bool `json:",omitempty"`
+ BuildingSuperEmptyImage bool `json:",omitempty"`
BoardSuperPartitionSize string `json:",omitempty"`
BoardSuperPartitionMetadataDevice string `json:",omitempty"`
BoardSuperPartitionBlockDevices []string `json:",omitempty"`
diff --git a/cc/binary.go b/cc/binary.go
index 627d5e5..608251a 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -551,6 +551,10 @@
binary.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON)
}
+func (binary *binaryDecorator) testSuiteInfo(ctx ModuleContext) {
+ // not a test
+}
+
var _ overridable = (*binaryDecorator)(nil)
func init() {
diff --git a/cc/cc.go b/cc/cc.go
index 16e8df7..ae6f3b0 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -797,6 +797,8 @@
defaultDistFiles() []android.Path
moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON)
+
+ testSuiteInfo(ctx ModuleContext)
}
// specifiedDeps is a tuple struct representing dependencies of a linked binary owned by the linker.
@@ -2408,6 +2410,8 @@
name := v.ImplementationModuleName(ctx.OtherModuleName(c))
ccInfo.LinkerInfo.ImplementationModuleName = &name
}
+
+ c.linker.testSuiteInfo(ctx)
}
if c.library != nil {
ccInfo.LibraryInfo = &LibraryInfo{
diff --git a/cc/library.go b/cc/library.go
index b248224..5299771 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -1078,6 +1078,10 @@
library.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON)
}
+func (library *libraryDecorator) testSuiteInfo(ctx ModuleContext) {
+ // not a test
+}
+
func (library *libraryDecorator) linkStatic(ctx ModuleContext,
flags Flags, deps PathDeps, objs Objects) android.Path {
diff --git a/cc/object.go b/cc/object.go
index 95a8beb..ea3ed61 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -250,3 +250,7 @@
object.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON)
moduleInfoJSON.Class = []string{"STATIC_LIBRARIES"}
}
+
+func (object *objectLinker) testSuiteInfo(ctx ModuleContext) {
+ // not a test
+}
diff --git a/cc/strip.go b/cc/strip.go
index 32ea38d..42c9137 100644
--- a/cc/strip.go
+++ b/cc/strip.go
@@ -52,7 +52,7 @@
func (stripper *Stripper) NeedsStrip(actx android.ModuleContext) bool {
forceDisable := Bool(stripper.StripProperties.Strip.None)
// Strip is enabled by default for device variants.
- defaultEnable := actx.Device()
+ defaultEnable := actx.Device() || actx.Config().StripByDefault()
forceEnable := Bool(stripper.StripProperties.Strip.All) ||
Bool(stripper.StripProperties.Strip.Keep_symbols) ||
Bool(stripper.StripProperties.Strip.Keep_symbols_and_debug_frame)
diff --git a/cc/test.go b/cc/test.go
index 8b68c55..9c276b8 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -274,6 +274,12 @@
}
}
+func (test *testDecorator) testSuiteInfo(ctx ModuleContext) {
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: test.InstallerProperties.Test_suites,
+ })
+}
+
func NewTestInstaller() *baseInstaller {
return NewBaseInstaller("nativetest", "nativetest64", InstallInData)
}
@@ -342,6 +348,10 @@
}
+func (test *testBinary) testSuiteInfo(ctx ModuleContext) {
+ test.testDecorator.testSuiteInfo(ctx)
+}
+
func (test *testBinary) installerProps() []interface{} {
return append(test.baseInstaller.installerProps(), test.testDecorator.installerProps()...)
}
@@ -578,6 +588,10 @@
test.testDecorator.moduleInfoJSON(ctx, moduleInfoJSON)
}
+func (test *testLibrary) testSuiteInfo(ctx ModuleContext) {
+ test.testDecorator.testSuiteInfo(ctx)
+}
+
func (test *testLibrary) installerProps() []interface{} {
return append(test.baseInstaller.installerProps(), test.testDecorator.installerProps()...)
}
@@ -695,6 +709,12 @@
}
}
+func (benchmark *benchmarkDecorator) testSuiteInfo(ctx ModuleContext) {
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: benchmark.Properties.Test_suites,
+ })
+}
+
func NewBenchmark(hod android.HostOrDeviceSupported) *Module {
module, binary := newBinary(hod)
module.multilib = android.MultilibBoth
diff --git a/ci_tests/ci_test_package_zip.go b/ci_tests/ci_test_package_zip.go
index 451dac4..f8c4578 100644
--- a/ci_tests/ci_test_package_zip.go
+++ b/ci_tests/ci_test_package_zip.go
@@ -20,6 +20,7 @@
"strings"
"android/soong/android"
+
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -214,7 +215,13 @@
ctx.ModuleErrorf("Module %s doesn't set InstallFilesProvider", m.Name())
}
- for _, installedFile := range installedFilesInfo.InstallFiles {
+ for _, spec := range installedFilesInfo.PackagingSpecs {
+ if spec.SrcPath() == nil {
+ // Probably a symlink
+ continue
+ }
+ installedFile := spec.FullInstallPath()
+
ext := installedFile.Ext()
// there are additional installed files for some app-class modules, we only need the .apk, .odex and .vdex files in the test package
excludeInstalledFile := ext != ".apk" && ext != ".odex" && ext != ".vdex"
@@ -253,7 +260,9 @@
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)
+ // Copy srcPath instead of installedFile because some rules like target-files.zip
+ // are non-hermetic and would be affected if we built the installed files.
+ builder.Command().Text("cp").Flag("-Rf").Input(spec.SrcPath()).Output(tempOut)
builder.Temporary(tempOut)
}
}
diff --git a/filesystem/android_device.go b/filesystem/android_device.go
index 22ad7cf..45a8620 100644
--- a/filesystem/android_device.go
+++ b/filesystem/android_device.go
@@ -623,6 +623,10 @@
builder.Command().Textf("cp ").Input(info.SubImageInfo[partition].MapFile).Textf(" %s/IMAGES/", targetFilesDir.String())
}
}
+ // super_empty.img
+ if info.SuperEmptyImage != nil {
+ builder.Command().Textf("cp ").Input(info.SuperEmptyImage).Textf(" %s/IMAGES/", targetFilesDir.String())
+ }
} else {
ctx.ModuleErrorf("Super partition %s does set SuperImageProvider\n", superPartition.Name())
}
diff --git a/filesystem/super_image.go b/filesystem/super_image.go
index 5108025..8e2b532 100644
--- a/filesystem/super_image.go
+++ b/filesystem/super_image.go
@@ -80,6 +80,8 @@
}
// Whether the super image will be disted in the update package
Super_image_in_update_package *bool
+ // Whether a super_empty.img should be created
+ Create_super_empty *bool
}
type PartitionGroupsInfo struct {
@@ -118,6 +120,8 @@
SubImageInfo map[string]FilesystemInfo
DynamicPartitionsInfo android.Path
+
+ SuperEmptyImage android.Path
}
var SuperImageProvider = blueprint.NewProvider[SuperImageInfo]()
@@ -163,7 +167,7 @@
}
func (s *superImage) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- miscInfo, deps, subImageInfos := s.buildMiscInfo(ctx)
+ miscInfo, deps, subImageInfos := s.buildMiscInfo(ctx, false)
builder := android.NewRuleBuilder(pctx, ctx)
output := android.PathForModuleOut(ctx, s.installFileName())
lpMake := ctx.Config().HostToolPath(ctx, "lpmake")
@@ -176,10 +180,27 @@
Implicits(deps).
Output(output)
builder.Build("build_super_image", fmt.Sprintf("Creating super image %s", s.BaseModuleName()))
+ var superEmptyImage android.WritablePath
+ if proptools.Bool(s.properties.Create_super_empty) {
+ superEmptyImageBuilder := android.NewRuleBuilder(pctx, ctx)
+ superEmptyImage = android.PathForModuleOut(ctx, "super_empty.img")
+ superEmptyMiscInfo, superEmptyDeps, _ := s.buildMiscInfo(ctx, true)
+ if superEmptyDeps != nil {
+ ctx.ModuleErrorf("TODO: Handle additional deps when building super_empty.img")
+ }
+ superEmptyImageBuilder.Command().Textf("PATH=%s:\\$PATH", lpMakeDir).
+ BuiltTool("build_super_image").
+ Text("-v").
+ Input(superEmptyMiscInfo).
+ Implicit(lpMake).
+ Output(superEmptyImage)
+ superEmptyImageBuilder.Build("build_super_empty_image", fmt.Sprintf("Creating super empty image %s", s.BaseModuleName()))
+ }
android.SetProvider(ctx, SuperImageProvider, SuperImageInfo{
SuperImage: output,
SubImageInfo: subImageInfos,
DynamicPartitionsInfo: s.generateDynamicPartitionsInfo(ctx),
+ SuperEmptyImage: superEmptyImage,
})
ctx.SetOutputFiles([]android.Path{output}, "")
ctx.CheckbuildFile(output)
@@ -191,7 +212,7 @@
return "super.img"
}
-func (s *superImage) buildMiscInfo(ctx android.ModuleContext) (android.Path, android.Paths, map[string]FilesystemInfo) {
+func (s *superImage) buildMiscInfo(ctx android.ModuleContext, superEmpty bool) (android.Path, android.Paths, map[string]FilesystemInfo) {
var miscInfoString strings.Builder
partitionList := s.dumpDynamicPartitionInfo(ctx, &miscInfoString)
addStr := func(name string, value string) {
@@ -201,6 +222,11 @@
miscInfoString.WriteRune('\n')
}
addStr("ab_update", strconv.FormatBool(proptools.Bool(s.properties.Ab_update)))
+ if superEmpty {
+ miscInfo := android.PathForModuleOut(ctx, "misc_info_super_empty.txt")
+ android.WriteFileRule(ctx, miscInfo, miscInfoString.String())
+ return miscInfo, nil, nil
+ }
subImageInfo := make(map[string]FilesystemInfo)
var deps android.Paths
@@ -300,6 +326,9 @@
}
addStr("build_super_partition", "true")
+ if proptools.Bool(s.properties.Create_super_empty) {
+ addStr("build_super_empty_partition", "true")
+ }
addStr("use_dynamic_partitions", strconv.FormatBool(proptools.Bool(s.properties.Use_dynamic_partitions)))
if proptools.Bool(s.properties.Retrofit) {
addStr("dynamic_partition_retrofit", "true")
diff --git a/fsgen/super_img.go b/fsgen/super_img.go
index f564636..1d610f6 100644
--- a/fsgen/super_img.go
+++ b/fsgen/super_img.go
@@ -46,6 +46,7 @@
Retrofit: proptools.BoolPtr(partitionVars.ProductRetrofitDynamicPartitions),
Use_dynamic_partitions: proptools.BoolPtr(partitionVars.ProductUseDynamicPartitions),
Super_image_in_update_package: proptools.BoolPtr(partitionVars.BoardSuperImageInUpdatePackage),
+ Create_super_empty: proptools.BoolPtr(partitionVars.BuildingSuperEmptyImage),
}
if partitionVars.ProductVirtualAbOta {
superImageProps.Virtual_ab.Enable = proptools.BoolPtr(true)
diff --git a/java/app.go b/java/app.go
index f1dcf41..560129b 100644
--- a/java/app.go
+++ b/java/app.go
@@ -425,6 +425,10 @@
} else {
moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
}
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: a.appTestHelperAppProperties.Test_suites,
+ })
}
func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -1703,6 +1707,10 @@
moduleInfoJSON.AutoTestConfig = []string{"true"}
}
moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, a.testProperties.Test_mainline_modules...)
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: a.testProperties.Test_suites,
+ })
}
func testcaseRel(paths android.Paths) []string {
diff --git a/java/app_import.go b/java/app_import.go
index 37c673c..b9e91cd 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -787,6 +787,10 @@
a.updateModuleInfoJSON(ctx)
a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: a.testProperties.Test_suites,
+ })
}
func (a *AndroidTestImport) updateModuleInfoJSON(ctx android.ModuleContext) {
diff --git a/java/base.go b/java/base.go
index 19fb2bc..8453a68 100644
--- a/java/base.go
+++ b/java/base.go
@@ -888,6 +888,10 @@
// Add dependency on libraries that provide additional hidden api annotations.
ctx.AddVariationDependencies(nil, hiddenApiAnnotationsTag, j.properties.Hiddenapi_additional_annotations...)
+ // Add dependency on (soft) downstream libs from which to trace references during optimization.
+ traceRefs := j.dexProperties.Optimize.Trace_references_from.GetOrDefault(ctx, []string{})
+ ctx.AddVariationDependencies(nil, traceReferencesTag, traceRefs...)
+
// For library dependencies that are component libraries (like stubs), add the implementation
// as a dependency (dexpreopt needs to be against the implementation library, not stubs).
for _, dep := range libDeps {
diff --git a/java/dex.go b/java/dex.go
index b32d5ae..ed9c82b 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -116,6 +116,21 @@
//
// By default all classes are compiled using R8 when Optimize.Enabled is set.
Exclude *string `android:"path"`
+
+ // Optional list of downstream (Java) libraries from which to trace and preserve references
+ // when optimizing. Note that this requires that the source reference does *not* have
+ // a strict lib dependency on this target; dependencies should be on intermediate targets
+ // statically linked into this target, e.g., if A references B, and we want to trace and
+ // keep references from A when optimizing B, you would create an intermediate B.impl (
+ // containing all static code), have A depend on `B.impl` via libs, and set
+ // `trace_references_from: ["A"]` on B.
+ //
+ // Also note that these are *not* inherited across targets, they must be specified at the
+ // top-level target that is optimized.
+ //
+ // TODO(b/212737576): Handle this implicitly using bottom-up deps mutation and implicit
+ // creation of a proxy `.impl` library.
+ Trace_references_from proptools.Configurable[[]string] `android:"arch_variant"`
}
// Keep the data uncompressed. We always need uncompressed dex for execution,
@@ -458,6 +473,20 @@
flagFiles = append(flagFiles, android.PathsForModuleSrc(ctx, opt.Proguard_flags_files)...)
+ traceReferencesSources := android.Paths{}
+ ctx.VisitDirectDepsProxyWithTag(traceReferencesTag, func(m android.ModuleProxy) {
+ if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
+ traceReferencesSources = append(traceReferencesSources, dep.ImplementationJars...)
+ }
+ })
+ if len(traceReferencesSources) > 0 {
+ traceTarget := dexParams.classesJar
+ traceLibs := android.FirstUniquePaths(append(flags.bootClasspath.Paths(), flags.dexClasspath.Paths()...))
+ traceReferencesFlags := android.PathForModuleOut(ctx, "proguard", "trace_references.flags")
+ TraceReferences(ctx, traceReferencesSources, traceTarget, traceLibs, traceReferencesFlags)
+ flagFiles = append(flagFiles, traceReferencesFlags)
+ }
+
flagFiles = android.FirstUniquePaths(flagFiles)
r8Flags = append(r8Flags, android.JoinWithPrefix(flagFiles.Strings(), "-include "))
diff --git a/java/dex_test.go b/java/dex_test.go
index 66d801d..e94864b 100644
--- a/java/dex_test.go
+++ b/java/dex_test.go
@@ -866,3 +866,46 @@
})
}
}
+
+func TestTraceReferences(t *testing.T) {
+ t.Parallel()
+ bp := `
+ android_app {
+ name: "app",
+ libs: ["lib.impl"],
+ srcs: ["foo.java"],
+ platform_apis: true,
+ }
+
+ java_library {
+ name: "lib",
+ optimize: {
+ enabled: true,
+ trace_references_from: ["app"],
+ },
+ srcs: ["bar.java"],
+ static_libs: ["lib.impl"],
+ installable: true,
+ }
+
+ java_library {
+ name: "lib.impl",
+ srcs: ["baz.java"],
+ }
+ `
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ ).RunTestWithBp(t, bp)
+
+ appJar := result.ModuleForTests(t, "app", "android_common").Output("combined/app.jar").Output
+ libJar := result.ModuleForTests(t, "lib", "android_common").Output("combined/lib.jar").Output
+ libTraceRefs := result.ModuleForTests(t, "lib", "android_common").Rule("traceReferences")
+ libR8 := result.ModuleForTests(t, "lib", "android_common").Rule("r8")
+
+ android.AssertStringDoesContain(t, "expected trace reference source from app jar",
+ libTraceRefs.Args["sources"], "--source "+appJar.String())
+ android.AssertStringEquals(t, "expected trace reference target into lib jar",
+ libJar.String(), libTraceRefs.Input.String())
+ android.AssertStringDoesContain(t, "expected trace reference proguard flags in lib r8 flags",
+ libR8.Args["r8Flags"], "trace_references.flags")
+}
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index b21cfc9..e8e1cd4 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -650,6 +650,9 @@
// for now just exclude any known irrelevant dependencies that would lead to incorrect errors.
if _, ok := tag.(bootclasspathDependencyTag); ok {
return false
+ } else if tag == traceReferencesTag {
+ // Allow ordering inversion if the dependency is purely for tracing references.
+ return false
}
depIndex := jars.IndexOfJar(dep.Name())
if jarIndex < depIndex && !config.BrokenSuboptimalOrderOfSystemServerJars {
diff --git a/java/java.go b/java/java.go
index 235a27d..7f897a0 100644
--- a/java/java.go
+++ b/java/java.go
@@ -578,6 +578,7 @@
extraLintCheckTag = dependencyTag{name: "extra-lint-check", toolchain: true}
jniLibTag = dependencyTag{name: "jnilib", runtimeLinked: true}
r8LibraryJarTag = dependencyTag{name: "r8-libraryjar", runtimeLinked: true}
+ traceReferencesTag = dependencyTag{name: "trace-references"}
syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"}
javaApiContributionTag = dependencyTag{name: "java-api-contribution"}
aconfigDeclarationTag = dependencyTag{name: "aconfig-declaration"}
@@ -608,6 +609,7 @@
kotlinPluginTag,
syspropPublicStubDepTag,
instrumentationForTag,
+ traceReferencesTag,
}
)
@@ -1954,6 +1956,10 @@
ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".jar", j.outputFile)
}
}
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: j.testProperties.Test_suites,
+ })
}
func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -1970,6 +1976,10 @@
if optionalConfig.Valid() {
moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, optionalConfig.String())
}
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: j.testHelperLibraryProperties.Test_suites,
+ })
}
func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
diff --git a/python/binary.go b/python/binary.go
index feac72a..af7d30f 100644
--- a/python/binary.go
+++ b/python/binary.go
@@ -159,6 +159,10 @@
sharedLibs = append(sharedLibs, ctx.OtherModuleName(dep))
}
p.androidMkSharedLibs = sharedLibs
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: p.binaryProperties.Test_suites,
+ })
}
func (p *PythonBinaryModule) AndroidMkEntries() []android.AndroidMkEntries {
diff --git a/rust/benchmark.go b/rust/benchmark.go
index daba964..3aa2f17 100644
--- a/rust/benchmark.go
+++ b/rust/benchmark.go
@@ -146,4 +146,8 @@
} else {
moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
}
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: benchmark.Properties.Test_suites,
+ })
}
diff --git a/rust/test.go b/rust/test.go
index 9b755b4..2fed0d6 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -242,6 +242,10 @@
flags.RustFlags = append(flags.RustFlags, "-Z panic_abort_tests")
}
+ // Add a default rpath to allow tests to dlopen libraries specified in data_libs.
+ flags.GlobalLinkFlags = append(flags.GlobalLinkFlags, `-Wl,-rpath,\$$ORIGIN/lib64`)
+ flags.GlobalLinkFlags = append(flags.GlobalLinkFlags, `-Wl,-rpath,\$$ORIGIN/lib`)
+
return flags
}
@@ -316,6 +320,10 @@
} else {
moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
}
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: test.Properties.Test_suites,
+ })
}
func rustTestHostMultilib(ctx android.LoadHookContext) {
diff --git a/scripts/manifest_check.py b/scripts/manifest_check.py
index 175451e..96dc5a6 100755
--- a/scripts/manifest_check.py
+++ b/scripts/manifest_check.py
@@ -132,7 +132,7 @@
#pylint: disable=line-too-long
errmsg = ''.join([
- 'mismatch in the <uses-library> tags between the build system and the '
+ 'mismatch or misordering in the <uses-library> tags between the build system and the '
'manifest:\n',
'\t- required libraries in build system: %s[%s]%s\n' % (C_RED, ', '.join(required), C_OFF),
'\t vs. in the manifest: %s[%s]%s\n' % (C_RED, ', '.join(manifest_required), C_OFF),
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 894b17f..7041642 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -574,6 +574,10 @@
moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.testConfig.String())
}
moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.extraTestConfigs.Strings()...)
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: s.testProperties.Test_suites,
+ })
}
func addArch(archType string, paths android.Paths) []string {
diff --git a/tradefed_modules/test_module_config.go b/tradefed_modules/test_module_config.go
index 6dd48eb..2b34128 100644
--- a/tradefed_modules/test_module_config.go
+++ b/tradefed_modules/test_module_config.go
@@ -426,6 +426,10 @@
LocalCertificate: m.provider.LocalCertificate,
IsUnitTest: m.provider.IsUnitTest,
})
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: m.tradefedProperties.Test_suites,
+ })
}
var _ android.AndroidMkEntriesProvider = (*testModuleConfigHostModule)(nil)