diff options
86 files changed, 900 insertions, 731 deletions
diff --git a/Android.bp b/Android.bp index 8d1280cc0..432c7fc4f 100644 --- a/Android.bp +++ b/Android.bp @@ -149,3 +149,21 @@ build_prop { relative_install_path: "etc", // system_ext/etc/build.prop visibility: ["//visibility:private"], } + +build_prop { + name: "product-build.prop", + stem: "build.prop", + product_specific: true, + product_config: ":product_config", + relative_install_path: "etc", // product/etc/build.prop + visibility: ["//visibility:private"], +} + +build_prop { + name: "odm-build.prop", + stem: "build.prop", + device_specific: true, + product_config: ":product_config", + relative_install_path: "etc", // odm/etc/build.prop + visibility: ["//visibility:private"], +} diff --git a/aconfig/aconfig_declarations.go b/aconfig/aconfig_declarations.go index 9e3d291b6..9b638e752 100644 --- a/aconfig/aconfig_declarations.go +++ b/aconfig/aconfig_declarations.go @@ -220,15 +220,10 @@ func (module *DeclarationsModule) GenerateAndroidBuildActions(ctx android.Module } func (module *DeclarationsModule) BuildActionProviderKeys() []blueprint.AnyProviderKey { - return []blueprint.AnyProviderKey{android.AconfigDeclarationsProviderKey} -} - -func (module *DeclarationsModule) PackageContextPath() string { - return pkgPath -} - -func (module *DeclarationsModule) CachedRules() []blueprint.Rule { - return []blueprint.Rule{aconfigRule, aconfigTextRule} + return []blueprint.AnyProviderKey{ + android.AconfigDeclarationsProviderKey, + android.AconfigReleaseDeclarationsProviderKey, + } } var _ blueprint.Incremental = &DeclarationsModule{} diff --git a/aconfig/aconfig_declarations_test.go b/aconfig/aconfig_declarations_test.go index 548329523..e89cd316f 100644 --- a/aconfig/aconfig_declarations_test.go +++ b/aconfig/aconfig_declarations_test.go @@ -40,7 +40,7 @@ func TestAconfigDeclarations(t *testing.T) { module := result.ModuleForTests("module_name", "").Module().(*DeclarationsModule) // Check that the provider has the right contents - depData, _ := android.SingletonModuleProvider(result, module, android.AconfigDeclarationsProviderKey) + depData, _ := android.OtherModuleProvider(result, module, android.AconfigDeclarationsProviderKey) android.AssertStringEquals(t, "package", depData.Package, "com.example.package") android.AssertStringEquals(t, "container", depData.Container, "com.android.foo") android.AssertBoolEquals(t, "exportable", depData.Exportable, true) @@ -67,7 +67,7 @@ func TestAconfigDeclarationsWithExportableUnset(t *testing.T) { result := runTest(t, android.FixtureExpectsNoErrors, bp) module := result.ModuleForTests("module_name", "").Module().(*DeclarationsModule) - depData, _ := android.SingletonModuleProvider(result, module, android.AconfigDeclarationsProviderKey) + depData, _ := android.OtherModuleProvider(result, module, android.AconfigDeclarationsProviderKey) android.AssertBoolEquals(t, "exportable", depData.Exportable, false) } @@ -205,7 +205,7 @@ func TestGenerateAndroidBuildActions(t *testing.T) { } result := fixture.RunTestWithBp(t, test.bp) module := result.ModuleForTests("module_name", "").Module().(*DeclarationsModule) - depData, _ := android.SingletonModuleProvider(result, module, android.AconfigReleaseDeclarationsProviderKey) + depData, _ := android.OtherModuleProvider(result, module, android.AconfigReleaseDeclarationsProviderKey) expectedKeys := []string{""} for _, rc := range strings.Split(test.buildFlags["RELEASE_ACONFIG_EXTRA_RELEASE_CONFIGS"], " ") { expectedKeys = append(expectedKeys, rc) diff --git a/aconfig/aconfig_value_set_test.go b/aconfig/aconfig_value_set_test.go index 7d1899926..32c31cb32 100644 --- a/aconfig/aconfig_value_set_test.go +++ b/aconfig/aconfig_value_set_test.go @@ -38,6 +38,6 @@ func TestAconfigValueSet(t *testing.T) { module := result.ModuleForTests("module_name", "").Module().(*ValueSetModule) // Check that the provider has the right contents - depData, _ := android.SingletonModuleProvider(result, module, valueSetProviderKey) + depData, _ := android.OtherModuleProvider(result, module, valueSetProviderKey) android.AssertStringEquals(t, "AvailablePackages", "blah.aconfig_values", depData.AvailablePackages["foo.package"][0].String()) } diff --git a/aconfig/aconfig_values_test.go b/aconfig/aconfig_values_test.go index 526579c40..ddbea57a8 100644 --- a/aconfig/aconfig_values_test.go +++ b/aconfig/aconfig_values_test.go @@ -33,7 +33,7 @@ func TestAconfigValues(t *testing.T) { module := result.ModuleForTests("module_name", "").Module().(*ValuesModule) // Check that the provider has the right contents - depData, _ := android.SingletonModuleProvider(result, module, valuesProviderKey) + depData, _ := android.OtherModuleProvider(result, module, valuesProviderKey) android.AssertStringEquals(t, "package", "foo.package", depData.Package) android.AssertPathsEndWith(t, "srcs", []string{"blah.aconfig_values"}, depData.Values) } diff --git a/aconfig/all_aconfig_declarations.go b/aconfig/all_aconfig_declarations.go index 0437c266f..6ad54da4a 100644 --- a/aconfig/all_aconfig_declarations.go +++ b/aconfig/all_aconfig_declarations.go @@ -15,9 +15,10 @@ package aconfig import ( - "android/soong/android" "fmt" "slices" + + "android/soong/android" ) // A singleton module that collects all of the aconfig flags declared in the @@ -55,7 +56,7 @@ func (this *allAconfigDeclarationsSingleton) GenerateBuildActions(ctx android.Si var packages = make(map[string]int) var cacheFiles android.Paths ctx.VisitAllModules(func(module android.Module) { - decl, ok := android.SingletonModuleProvider(ctx, module, android.AconfigReleaseDeclarationsProviderKey) + decl, ok := android.OtherModuleProvider(ctx, module, android.AconfigReleaseDeclarationsProviderKey) if !ok { return } diff --git a/aconfig/build_flags/all_build_flag_declarations.go b/aconfig/build_flags/all_build_flag_declarations.go index 282c9dcf8..5f0291262 100644 --- a/aconfig/build_flags/all_build_flag_declarations.go +++ b/aconfig/build_flags/all_build_flag_declarations.go @@ -38,7 +38,7 @@ func (this *allBuildFlagDeclarationsSingleton) GenerateBuildActions(ctx android. // Find all of the build_flag_declarations modules var intermediateFiles android.Paths ctx.VisitAllModules(func(module android.Module) { - decl, ok := android.SingletonModuleProvider(ctx, module, BuildFlagDeclarationsProviderKey) + decl, ok := android.OtherModuleProvider(ctx, module, BuildFlagDeclarationsProviderKey) if !ok { return } diff --git a/aconfig/exported_java_aconfig_library.go b/aconfig/exported_java_aconfig_library.go index 291938fa8..a64cac882 100644 --- a/aconfig/exported_java_aconfig_library.go +++ b/aconfig/exported_java_aconfig_library.go @@ -30,7 +30,7 @@ func (this *exportedJavaDeclarationsLibrarySingleton) GenerateBuildActions(ctx a // Find all of the aconfig_declarations modules var cacheFiles android.Paths ctx.VisitAllModules(func(module android.Module) { - decl, ok := android.SingletonModuleProvider(ctx, module, android.AconfigDeclarationsProviderKey) + decl, ok := android.OtherModuleProvider(ctx, module, android.AconfigDeclarationsProviderKey) if !ok { return } diff --git a/aconfig/init.go b/aconfig/init.go index de155ab52..5fa7e76ae 100644 --- a/aconfig/init.go +++ b/aconfig/init.go @@ -23,8 +23,7 @@ import ( ) var ( - pkgPath = "android/soong/aconfig" - pctx = android.NewPackageContext(pkgPath) + pctx = android.NewPackageContext("android/soong/aconfig") // For aconfig_declarations: Generate cache file aconfigRule = pctx.AndroidStaticRule("aconfig", @@ -111,6 +110,7 @@ func init() { pctx.HostBinToolVariable("soong_zip", "soong_zip") gob.Register(android.AconfigDeclarationsProviderData{}) + gob.Register(android.AconfigReleaseDeclarationsProviderData{}) gob.Register(android.ModuleOutPath{}) } diff --git a/aidl_library/aidl_library_test.go b/aidl_library/aidl_library_test.go index 01eab0eaf..166045635 100644 --- a/aidl_library/aidl_library_test.go +++ b/aidl_library/aidl_library_test.go @@ -15,8 +15,9 @@ package aidl_library import ( - "android/soong/android" "testing" + + "android/soong/android" ) func TestAidlLibrary(t *testing.T) { @@ -46,7 +47,7 @@ func TestAidlLibrary(t *testing.T) { ).RunTest(t).TestContext foo := ctx.ModuleForTests("foo", "").Module().(*AidlLibrary) - actualInfo, _ := android.SingletonModuleProvider(ctx, foo, AidlLibraryProvider) + actualInfo, _ := android.OtherModuleProvider(ctx, foo, AidlLibraryProvider) android.AssertArrayString( t, @@ -95,7 +96,7 @@ func TestAidlLibraryWithoutStripImportPrefix(t *testing.T) { ).RunTest(t).TestContext foo := ctx.ModuleForTests("foo", "").Module().(*AidlLibrary) - actualInfo, _ := android.SingletonModuleProvider(ctx, foo, AidlLibraryProvider) + actualInfo, _ := android.OtherModuleProvider(ctx, foo, AidlLibraryProvider) android.AssertArrayString( t, diff --git a/android/Android.bp b/android/Android.bp index 841a6af6e..96e8133bf 100644 --- a/android/Android.bp +++ b/android/Android.bp @@ -106,6 +106,7 @@ bootstrap_go_package { "updatable_modules.go", "util.go", "variable.go", + "vintf_fragment.go", "visibility.go", ], testSrcs: [ @@ -148,6 +149,7 @@ bootstrap_go_package { "test_suites_test.go", "util_test.go", "variable_test.go", + "vintf_fragment_test.go", "visibility_test.go", ], } diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go index a47e80f03..f0675dd5b 100644 --- a/android/aconfig_providers.go +++ b/android/aconfig_providers.go @@ -141,7 +141,7 @@ func aconfigUpdateAndroidBuildActions(ctx ModuleContext) { } func aconfigUpdateAndroidMkData(ctx fillInEntriesContext, mod Module, data *AndroidMkData) { - info, ok := SingletonModuleProvider(ctx, mod, AconfigPropagatingProviderKey) + info, ok := OtherModuleProvider(ctx, mod, AconfigPropagatingProviderKey) // If there is no aconfigPropagatingProvider, or there are no AconfigFiles, then we are done. if !ok || len(info.AconfigFiles) == 0 { return @@ -172,7 +172,7 @@ func aconfigUpdateAndroidMkEntries(ctx fillInEntriesContext, mod Module, entries if len(*entries) == 0 { return } - info, ok := SingletonModuleProvider(ctx, mod, AconfigPropagatingProviderKey) + info, ok := OtherModuleProvider(ctx, mod, AconfigPropagatingProviderKey) if !ok || len(info.AconfigFiles) == 0 { return } diff --git a/android/all_teams.go b/android/all_teams.go index d4bf7d0c4..e3c2e70bd 100644 --- a/android/all_teams.go +++ b/android/all_teams.go @@ -1,9 +1,10 @@ package android import ( - "android/soong/android/team_proto" "path/filepath" + "android/soong/android/team_proto" + "google.golang.org/protobuf/proto" ) @@ -93,7 +94,7 @@ func (t *allTeamsSingleton) GenerateBuildActions(ctx SingletonContext) { } testModInfo := TestModuleInformation{} - if tmi, ok := SingletonModuleProvider(ctx, module, TestOnlyProviderKey); ok { + if tmi, ok := OtherModuleProvider(ctx, module, TestOnlyProviderKey); ok { testModInfo = tmi } diff --git a/android/androidmk.go b/android/androidmk.go index 9699ce5b8..081bca92e 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -170,7 +170,7 @@ type androidMkExtraEntriesContext struct { } func (a *androidMkExtraEntriesContext) Provider(provider blueprint.AnyProviderKey) (any, bool) { - return a.ctx.moduleProvider(a.mod, provider) + return a.ctx.otherModuleProvider(a.mod, provider) } type AndroidMkExtraEntriesFunc func(ctx AndroidMkExtraEntriesContext, entries *AndroidMkEntries) @@ -497,7 +497,7 @@ type fillInEntriesContext interface { ModuleDir(module blueprint.Module) string ModuleSubDir(module blueprint.Module) string Config() Config - moduleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) + otherModuleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) ModuleType(module blueprint.Module) string OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{}) } @@ -536,13 +536,14 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint a.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(amod)) // If the install rule was generated by Soong tell Make about it. - if len(base.katiInstalls) > 0 { + info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider) + if len(info.KatiInstalls) > 0 { // Assume the primary install file is last since it probably needs to depend on any other // installed files. If that is not the case we can add a method to specify the primary // installed file. - a.SetPath("LOCAL_SOONG_INSTALLED_MODULE", base.katiInstalls[len(base.katiInstalls)-1].to) - a.SetString("LOCAL_SOONG_INSTALL_PAIRS", base.katiInstalls.BuiltInstalled()) - a.SetPaths("LOCAL_SOONG_INSTALL_SYMLINKS", base.katiSymlinks.InstallPaths().Paths()) + a.SetPath("LOCAL_SOONG_INSTALLED_MODULE", info.KatiInstalls[len(info.KatiInstalls)-1].to) + a.SetString("LOCAL_SOONG_INSTALL_PAIRS", info.KatiInstalls.BuiltInstalled()) + a.SetPaths("LOCAL_SOONG_INSTALL_SYMLINKS", info.KatiSymlinks.InstallPaths().Paths()) } else { // 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 @@ -550,8 +551,8 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint a.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", proptools.Bool(base.commonProperties.No_full_install)) } - if len(base.testData) > 0 { - a.AddStrings("LOCAL_TEST_DATA", androidMkDataPaths(base.testData)...) + if len(info.TestData) > 0 { + a.AddStrings("LOCAL_TEST_DATA", androidMkDataPaths(info.TestData)...) } if am, ok := mod.(ApexModule); ok { @@ -633,11 +634,11 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint } } - if licenseMetadata, ok := SingletonModuleProvider(ctx, mod, LicenseMetadataProvider); ok { + if licenseMetadata, ok := OtherModuleProvider(ctx, mod, LicenseMetadataProvider); ok { a.SetPath("LOCAL_SOONG_LICENSE_METADATA", licenseMetadata.LicenseMetadataPath) } - if _, ok := SingletonModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok { + if _, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok { a.SetBool("LOCAL_SOONG_MODULE_INFO_JSON", true) } @@ -861,6 +862,7 @@ func translateAndroidModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs * } data := provider.AndroidMk() + if data.Include == "" { data.Include = "$(BUILD_PREBUILT)" } @@ -907,6 +909,7 @@ func translateAndroidModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs * case "*phony.PhonyRule": // writes phony deps and acts like `.PHONY` case "*selinux.selinuxContextsModule": // license properties written case "*sysprop.syspropLibrary": // license properties written + case "*vintf.vintfCompatibilityMatrixRule": // use case like phony default: if !ctx.Config().IsEnvFalse("ANDROID_REQUIRE_LICENSES") { return fmt.Errorf("custom make rules not allowed for %q (%q) module %q", ctx.ModuleType(mod), reflect.TypeOf(mod), ctx.ModuleName(mod)) @@ -918,7 +921,7 @@ func translateAndroidModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs * } if !data.Entries.disabled() { - if moduleInfoJSON, ok := SingletonModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok { + if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok { *moduleInfoJSONs = append(*moduleInfoJSONs, moduleInfoJSON) } } @@ -960,7 +963,7 @@ func translateAndroidMkEntriesModule(ctx SingletonContext, w io.Writer, moduleIn } if len(entriesList) > 0 && !entriesList[0].disabled() { - if moduleInfoJSON, ok := SingletonModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok { + if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok { *moduleInfoJSONs = append(*moduleInfoJSONs, moduleInfoJSON) } } diff --git a/android/build_prop.go b/android/build_prop.go index d48d94d4e..13d59f9f5 100644 --- a/android/build_prop.go +++ b/android/build_prop.go @@ -56,11 +56,13 @@ func (p *buildPropModule) stem() string { } func (p *buildPropModule) propFiles(ctx ModuleContext) Paths { - partition := p.PartitionTag(ctx.DeviceConfig()) + partition := p.partition(ctx.DeviceConfig()) if partition == "system" { return ctx.Config().SystemPropFiles(ctx) } else if partition == "system_ext" { return ctx.Config().SystemExtPropFiles(ctx) + } else if partition == "product" { + return ctx.Config().ProductPropFiles(ctx) } return nil } @@ -80,6 +82,28 @@ func shouldAddBuildThumbprint(config Config) bool { return false } +// Can't use PartitionTag() because PartitionTag() returns the partition this module is actually +// installed (e.g. odm module's partition tag can be either "odm" or "vendor") +func (p *buildPropModule) partition(config DeviceConfig) string { + if p.SocSpecific() { + return "vendor" + } else if p.DeviceSpecific() { + return "odm" + } else if p.ProductSpecific() { + return "product" + } else if p.SystemExtSpecific() { + return "system_ext" + } + return "system" +} + +var validPartitions = []string{ + "system", + "system_ext", + "product", + "odm", +} + func (p *buildPropModule) GenerateAndroidBuildActions(ctx ModuleContext) { p.outputFilePath = PathForModuleOut(ctx, "build.prop").OutputPath if !ctx.Config().KatiEnabled() { @@ -88,9 +112,9 @@ func (p *buildPropModule) GenerateAndroidBuildActions(ctx ModuleContext) { return } - partition := p.PartitionTag(ctx.DeviceConfig()) - if partition != "system" && partition != "system_ext" { - ctx.PropertyErrorf("partition", "unsupported partition %q: only \"system\" and \"system_ext\" are supported", partition) + partition := p.partition(ctx.DeviceConfig()) + if !InList(partition, validPartitions) { + ctx.PropertyErrorf("partition", "unsupported partition %q: only %q are supported", partition, validPartitions) return } @@ -118,7 +142,7 @@ func (p *buildPropModule) GenerateAndroidBuildActions(ctx ModuleContext) { cmd.FlagWithInput("--platform-preview-sdk-fingerprint-file=", ApiFingerprintPath(ctx)) cmd.FlagWithInput("--product-config=", PathForModuleSrc(ctx, proptools.String(p.properties.Product_config))) cmd.FlagWithArg("--partition=", partition) - cmd.FlagForEachInput("--prop-files=", ctx.Config().SystemPropFiles(ctx)) + cmd.FlagForEachInput("--prop-files=", p.propFiles(ctx)) cmd.FlagWithOutput("--out=", p.outputFilePath) postProcessCmd := rule.Command().BuiltTool("post_process_props") diff --git a/android/compliance_metadata.go b/android/compliance_metadata.go index 6ea66541a..4c92f717d 100644 --- a/android/compliance_metadata.go +++ b/android/compliance_metadata.go @@ -160,7 +160,7 @@ var ( // buildComplianceMetadataProvider starts with the ModuleContext.ComplianceMetadataInfo() and fills in more common metadata // for different module types without accessing their private fields but through android.Module interface // and public/private fields of package android. The final metadata is stored to a module's ComplianceMetadataProvider. -func buildComplianceMetadataProvider(ctx ModuleContext, m *ModuleBase) { +func buildComplianceMetadataProvider(ctx *moduleContext, m *ModuleBase) { complianceMetadataInfo := ctx.ComplianceMetadataInfo() complianceMetadataInfo.SetStringValue(ComplianceMetadataProp.NAME, m.Name()) complianceMetadataInfo.SetStringValue(ComplianceMetadataProp.PACKAGE, ctx.ModuleDir()) @@ -186,9 +186,9 @@ func buildComplianceMetadataProvider(ctx ModuleContext, m *ModuleBase) { } var installed InstallPaths - installed = append(installed, m.module.FilesToInstall()...) - installed = append(installed, m.katiInstalls.InstallPaths()...) - installed = append(installed, m.katiSymlinks.InstallPaths()...) + installed = append(installed, ctx.installFiles...) + installed = append(installed, ctx.katiInstalls.InstallPaths()...) + installed = append(installed, ctx.katiSymlinks.InstallPaths()...) installed = append(installed, m.katiInitRcInstalls.InstallPaths()...) installed = append(installed, m.katiVintfInstalls.InstallPaths()...) complianceMetadataInfo.SetListValue(ComplianceMetadataProp.INSTALLED_FILES, FirstUniqueStrings(installed.Strings())) @@ -267,7 +267,7 @@ func (c *complianceMetadataSingleton) GenerateBuildActions(ctx SingletonContext) writerToCsv(csvWriter, metadata) return } - if provider, ok := ctx.moduleProvider(module, ComplianceMetadataProvider); ok { + if provider, ok := ctx.otherModuleProvider(module, ComplianceMetadataProvider); ok { metadataInfo := provider.(*ComplianceMetadataInfo) rowId = rowId + 1 metadata := []string{strconv.Itoa(rowId)} diff --git a/android/config.go b/android/config.go index 3b30af876..d6d76a4a0 100644 --- a/android/config.go +++ b/android/config.go @@ -2046,6 +2046,26 @@ func (c *config) SystemExtPropFiles(ctx PathContext) Paths { return PathsForSource(ctx, c.productVariables.SystemExtPropFiles) } +func (c *config) ProductPropFiles(ctx PathContext) Paths { + return PathsForSource(ctx, c.productVariables.ProductPropFiles) +} + func (c *config) EnableUffdGc() string { return String(c.productVariables.EnableUffdGc) } + +func (c *config) DeviceFrameworkCompatibilityMatrixFile() []string { + return c.productVariables.DeviceFrameworkCompatibilityMatrixFile +} + +func (c *config) DeviceProductCompatibilityMatrixFile() []string { + return c.productVariables.DeviceProductCompatibilityMatrixFile +} + +func (c *config) BoardAvbEnable() bool { + return Bool(c.productVariables.BoardAvbEnable) +} + +func (c *config) BoardAvbSystemAddHashtreeFooterArgs() []string { + return c.productVariables.BoardAvbSystemAddHashtreeFooterArgs +} diff --git a/android/container.go b/android/container.go index c4fdd9c91..05897dd6c 100644 --- a/android/container.go +++ b/android/container.go @@ -21,12 +21,22 @@ import ( "github.com/google/blueprint" ) +// ---------------------------------------------------------------------------- +// Start of the definitions of exception functions and the lookup table. +// +// Functions cannot be used as a value passed in providers, because functions are not +// hashable. As a workaround, the [exceptionHandleFuncLabel] enum values are passed using providers, +// and the corresponding functions are called from [exceptionHandleFunctionsTable] map. +// ---------------------------------------------------------------------------- + +type exceptionHandleFunc func(ModuleContext, Module, Module) bool + type StubsAvailableModule interface { IsStubsModule() bool } // Returns true if the dependency module is a stubs module -var depIsStubsModule = func(_ ModuleContext, _, dep Module) bool { +var depIsStubsModule exceptionHandleFunc = func(_ ModuleContext, _, dep Module) bool { if stubsModule, ok := dep.(StubsAvailableModule); ok { return stubsModule.IsStubsModule() } @@ -41,13 +51,76 @@ const ( checkStubs exceptionHandleFuncLabel = iota ) -// Functions cannot be used as a value passed in providers, because functions are not -// hashable. As a workaround, the exceptionHandleFunc enum values are passed using providers, -// and the corresponding functions are called from this map. -var exceptionHandleFunctionsTable = map[exceptionHandleFuncLabel]func(ModuleContext, Module, Module) bool{ +var exceptionHandleFunctionsTable = map[exceptionHandleFuncLabel]exceptionHandleFunc{ checkStubs: depIsStubsModule, } +// ---------------------------------------------------------------------------- +// Start of the definitions of container determination functions. +// +// Similar to the above section, below defines the functions used to determine +// the container of each modules. +// ---------------------------------------------------------------------------- + +type containerBoundaryFunc func(mctx ModuleContext) bool + +var vendorContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bool { + m, ok := mctx.Module().(ImageInterface) + return mctx.Module().InstallInVendor() || (ok && m.VendorVariantNeeded(mctx)) +} + +var systemContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bool { + module := mctx.Module() + + return !module.InstallInTestcases() && + !module.InstallInData() && + !module.InstallInRamdisk() && + !module.InstallInVendorRamdisk() && + !module.InstallInDebugRamdisk() && + !module.InstallInRecovery() && + !module.InstallInVendor() && + !module.InstallInOdm() && + !module.InstallInProduct() && + determineModuleKind(module.base(), mctx.blueprintBaseModuleContext()) == platformModule +} + +var productContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bool { + m, ok := mctx.Module().(ImageInterface) + return mctx.Module().InstallInProduct() || (ok && m.ProductVariantNeeded(mctx)) +} + +var apexContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bool { + _, ok := ModuleProvider(mctx, AllApexInfoProvider) + return ok +} + +var ctsContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bool { + props := mctx.Module().GetProperties() + for _, prop := range props { + val := reflect.ValueOf(prop).Elem() + if val.Kind() == reflect.Struct { + testSuites := val.FieldByName("Test_suites") + if testSuites.IsValid() && testSuites.Kind() == reflect.Slice && slices.Contains(testSuites.Interface().([]string), "cts") { + return true + } + } + } + return false +} + +// Map of [*container] to the [containerBoundaryFunc] +var containerBoundaryFunctionsTable = map[*container]containerBoundaryFunc{ + VendorContainer: vendorContainerBoundaryFunc, + SystemContainer: systemContainerBoundaryFunc, + ProductContainer: productContainerBoundaryFunc, + ApexContainer: apexContainerBoundaryFunc, + CtsContainer: ctsContainerBoundaryFunc, +} + +// ---------------------------------------------------------------------------- +// End of the definitions of container determination functions. +// ---------------------------------------------------------------------------- + type InstallableModule interface { EnforceApiContainerChecks() bool } @@ -77,6 +150,7 @@ var ( name: VendorVariation, restricted: nil, } + SystemContainer = &container{ name: "system", restricted: []restriction{ @@ -90,6 +164,7 @@ var ( }, }, } + ProductContainer = &container{ name: ProductVariation, restricted: []restriction{ @@ -102,8 +177,10 @@ var ( }, }, } + ApexContainer = initializeApexContainer() - CtsContainer = &container{ + + CtsContainer = &container{ name: "cts", restricted: []restriction{ { @@ -116,6 +193,14 @@ var ( }, }, } + + allContainers = []*container{ + VendorContainer, + SystemContainer, + ProductContainer, + ApexContainer, + CtsContainer, + } ) func initializeApexContainer() *container { @@ -155,68 +240,38 @@ func (c *ContainersInfo) BelongingContainers() []*container { return c.belongingContainers } -var ContainersInfoProvider = blueprint.NewProvider[ContainersInfo]() +func (c *ContainersInfo) ApexNames() (ret []string) { + for _, apex := range c.belongingApexes { + ret = append(ret, apex.InApexModules...) + } + slices.Sort(ret) + return ret +} -// Determines if the module can be installed in the system partition or not. -// Logic is identical to that of modulePartition(...) defined in paths.go -func installInSystemPartition(ctx ModuleContext) bool { - module := ctx.Module() - return !module.InstallInTestcases() && - !module.InstallInData() && - !module.InstallInRamdisk() && - !module.InstallInVendorRamdisk() && - !module.InstallInDebugRamdisk() && - !module.InstallInRecovery() && - !module.InstallInVendor() && - !module.InstallInOdm() && - !module.InstallInProduct() && - determineModuleKind(module.base(), ctx.blueprintBaseModuleContext()) == platformModule +// Returns true if any of the apex the module belongs to is updatable. +func (c *ContainersInfo) UpdatableApex() bool { + for _, apex := range c.belongingApexes { + if apex.Updatable { + return true + } + } + return false } +var ContainersInfoProvider = blueprint.NewProvider[ContainersInfo]() + func generateContainerInfo(ctx ModuleContext) ContainersInfo { - inSystem := installInSystemPartition(ctx) - inProduct := ctx.Module().InstallInProduct() - inVendor := ctx.Module().InstallInVendor() - inCts := false - inApex := false - - if m, ok := ctx.Module().(ImageInterface); ok { - inProduct = inProduct || m.ProductVariantNeeded(ctx) - inVendor = inVendor || m.VendorVariantNeeded(ctx) - } + var containers []*container - props := ctx.Module().GetProperties() - for _, prop := range props { - val := reflect.ValueOf(prop).Elem() - if val.Kind() == reflect.Struct { - testSuites := val.FieldByName("Test_suites") - if testSuites.IsValid() && testSuites.Kind() == reflect.Slice && slices.Contains(testSuites.Interface().([]string), "cts") { - inCts = true - } + for _, cnt := range allContainers { + if containerBoundaryFunctionsTable[cnt](ctx) { + containers = append(containers, cnt) } } var belongingApexes []ApexInfo if apexInfo, ok := ModuleProvider(ctx, AllApexInfoProvider); ok { belongingApexes = apexInfo.ApexInfos - inApex = true - } - - containers := []*container{} - if inSystem { - containers = append(containers, SystemContainer) - } - if inProduct { - containers = append(containers, ProductContainer) - } - if inVendor { - containers = append(containers, VendorContainer) - } - if inCts { - containers = append(containers, CtsContainer) - } - if inApex { - containers = append(containers, ApexContainer) } return ContainersInfo{ diff --git a/android/deapexer.go b/android/deapexer.go index 61ae64ea5..dcae3e46d 100644 --- a/android/deapexer.go +++ b/android/deapexer.go @@ -181,7 +181,11 @@ func FindDeapexerProviderForModule(ctx ModuleContext) (*DeapexerInfo, error) { // An err has been found. Do not visit further. return } - c, _ := OtherModuleProvider(ctx, m, DeapexerProvider) + c, ok := OtherModuleProvider(ctx, m, DeapexerProvider) + if !ok { + ctx.ModuleErrorf("Expected all deps with DeapexerTag to have a DeapexerProvider, but module %q did not", m.Name()) + return + } p := &c if di != nil { // If two DeapexerInfo providers have been found then check if they are diff --git a/android/license_metadata.go b/android/license_metadata.go index 8056189fc..cd697495f 100644 --- a/android/license_metadata.go +++ b/android/license_metadata.go @@ -33,7 +33,7 @@ var ( }, "args") ) -func buildLicenseMetadata(ctx ModuleContext, licenseMetadataFile WritablePath) { +func buildLicenseMetadata(ctx *moduleContext, licenseMetadataFile WritablePath) { base := ctx.Module().base() if !base.Enabled(ctx) { @@ -52,8 +52,8 @@ func buildLicenseMetadata(ctx ModuleContext, licenseMetadataFile WritablePath) { // Only pass the last installed file to isContainerFromFileExtensions so a *.zip file in test data // doesn't mark the whole module as a container. var installFiles InstallPaths - if len(base.installFiles) > 0 { - installFiles = InstallPaths{base.installFiles[len(base.installFiles)-1]} + if len(ctx.installFiles) > 0 { + installFiles = InstallPaths{ctx.installFiles[len(ctx.installFiles)-1]} } isContainer := isContainerFromFileExtensions(installFiles, outputFiles) @@ -92,7 +92,7 @@ func buildLicenseMetadata(ctx ModuleContext, licenseMetadataFile WritablePath) { allDepMetadataArgs = append(allDepMetadataArgs, info.LicenseMetadataPath.String()+depAnnotations) - if depInstallFiles := dep.base().installFiles; len(depInstallFiles) > 0 { + if depInstallFiles := OtherModuleProviderOrDefault(ctx, dep, InstallFilesProvider).InstallFiles; len(depInstallFiles) > 0 { allDepOutputFiles = append(allDepOutputFiles, depInstallFiles.Paths()...) } else if depOutputFiles, err := outputFilesForModule(ctx, dep, ""); err == nil { depOutputFiles = PathsIfNonNil(depOutputFiles...) @@ -162,7 +162,7 @@ func buildLicenseMetadata(ctx ModuleContext, licenseMetadataFile WritablePath) { // Installed files args = append(args, - JoinWithPrefix(proptools.NinjaAndShellEscapeListIncludingSpaces(base.installFiles.Strings()), "-i ")) + JoinWithPrefix(proptools.NinjaAndShellEscapeListIncludingSpaces(ctx.installFiles.Strings()), "-i ")) if isContainer { args = append(args, "--is_container") diff --git a/android/logtags.go b/android/logtags.go index d11cccf4f..7929057ff 100644 --- a/android/logtags.go +++ b/android/logtags.go @@ -42,7 +42,7 @@ func (l *logtagsSingleton) GenerateBuildActions(ctx SingletonContext) { if !module.ExportedToMake() { return } - if logtagsInfo, ok := SingletonModuleProvider(ctx, module, LogtagsProviderKey); ok { + if logtagsInfo, ok := OtherModuleProvider(ctx, module, LogtagsProviderKey); ok { allLogtags = append(allLogtags, logtagsInfo.Logtags...) } }) diff --git a/android/makevars.go b/android/makevars.go index f92f4581e..810eb3881 100644 --- a/android/makevars.go +++ b/android/makevars.go @@ -94,7 +94,7 @@ type MakeVarsContext interface { ModuleDir(module blueprint.Module) string ModuleSubDir(module blueprint.Module) string ModuleType(module blueprint.Module) string - moduleProvider(module blueprint.Module, key blueprint.AnyProviderKey) (any, bool) + otherModuleProvider(module blueprint.Module, key blueprint.AnyProviderKey) (any, bool) BlueprintFile(module blueprint.Module) string ModuleErrorf(module blueprint.Module, format string, args ...interface{}) @@ -279,10 +279,11 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) { } if m.ExportedToMake() { - katiInstalls = append(katiInstalls, m.base().katiInstalls...) + info := OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider) + katiInstalls = append(katiInstalls, info.KatiInstalls...) katiInitRcInstalls = append(katiInitRcInstalls, m.base().katiInitRcInstalls...) katiVintfManifestInstalls = append(katiVintfManifestInstalls, m.base().katiVintfInstalls...) - katiSymlinks = append(katiSymlinks, m.base().katiSymlinks...) + katiSymlinks = append(katiSymlinks, info.KatiSymlinks...) } }) diff --git a/android/module.go b/android/module.go index f9fab96a9..b625be46e 100644 --- a/android/module.go +++ b/android/module.go @@ -111,9 +111,7 @@ type Module interface { RequiredModuleNames(ctx ConfigAndErrorContext) []string HostRequiredModuleNames() []string TargetRequiredModuleNames() []string - - FilesToInstall() InstallPaths - PackagingSpecs() []PackagingSpec + VintfFragmentModuleNames(ctx ConfigAndErrorContext) []string // TransitivePackagingSpecs returns the PackagingSpecs for this module and any transitive // dependencies with dependency tags for which IsInstallDepNeeded() returns true. @@ -497,6 +495,9 @@ type commonProperties struct { // The team (defined by the owner/vendor) who owns the property. Team *string `android:"path"` + + // vintf_fragment Modules required from this module. + Vintf_fragment_modules proptools.Configurable[[]string] `android:"path"` } type distProperties struct { @@ -832,20 +833,12 @@ type ModuleBase struct { primaryLicensesProperty applicableLicensesProperty noAddressSanitizer bool - installFiles InstallPaths installFilesDepSet *DepSet[InstallPath] - checkbuildFiles Paths - packagingSpecs []PackagingSpec packagingSpecsDepSet *DepSet[PackagingSpec] - // katiInstalls tracks the install rules that were created by Soong but are being exported - // to Make to convert to ninja rules so that Make can add additional dependencies. - katiInstalls katiInstalls // katiInitRcInstalls and katiVintfInstalls track the install rules created by Soong that are // allowed to have duplicates across modules and variants. katiInitRcInstalls katiInstalls katiVintfInstalls katiInstalls - katiSymlinks katiInstalls - testData []DataPath // The files to copy to the dist as explicitly specified in the .bp file. distFiles TaggedDistFiles @@ -1028,6 +1021,7 @@ func (m *ModuleBase) baseDepsMutator(ctx BottomUpMutatorContext) { fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil if fullManifest { addRequiredDeps(ctx) + addVintfFragmentDeps(ctx) } } @@ -1105,6 +1099,16 @@ func addRequiredDeps(ctx BottomUpMutatorContext) { } } +var vintfDepTag = struct { + blueprint.BaseDependencyTag + InstallAlwaysNeededDependencyTag +}{} + +func addVintfFragmentDeps(ctx BottomUpMutatorContext) { + mod := ctx.Module() + ctx.AddDependency(mod, vintfDepTag, mod.VintfFragmentModuleNames(ctx)...) +} + // AddProperties "registers" the provided props // each value in props MUST be a pointer to a struct func (m *ModuleBase) AddProperties(props ...interface{}) { @@ -1476,14 +1480,6 @@ func isInstallDepNeeded(dep Module, tag blueprint.DependencyTag) bool { return IsInstallDepNeededTag(tag) } -func (m *ModuleBase) FilesToInstall() InstallPaths { - return m.installFiles -} - -func (m *ModuleBase) PackagingSpecs() []PackagingSpec { - return m.packagingSpecs -} - func (m *ModuleBase) TransitivePackagingSpecs() []PackagingSpec { return m.packagingSpecsDepSet.ToList() } @@ -1597,6 +1593,10 @@ func (m *ModuleBase) TargetRequiredModuleNames() []string { return m.base().commonProperties.Target_required } +func (m *ModuleBase) VintfFragmentModuleNames(ctx ConfigAndErrorContext) []string { + return m.base().commonProperties.Vintf_fragment_modules.GetOrDefault(m.ConfigurableEvaluator(ctx), nil) +} + func (m *ModuleBase) InitRc() Paths { return append(Paths{}, m.initRcPaths...) } @@ -1615,18 +1615,26 @@ func (m *ModuleBase) SetLicenseInstallMap(installMap []string) { m.licenseInstallMap = append(m.licenseInstallMap, installMap...) } -func (m *ModuleBase) generateModuleTarget(ctx ModuleContext) { +func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) { var allInstalledFiles InstallPaths var allCheckbuildFiles Paths ctx.VisitAllModuleVariants(func(module Module) { a := module.base() - allInstalledFiles = append(allInstalledFiles, a.installFiles...) + var checkBuilds Paths + if a == m { + allInstalledFiles = append(allInstalledFiles, ctx.installFiles...) + checkBuilds = ctx.checkbuildFiles + } else { + info := OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider) + allInstalledFiles = append(allInstalledFiles, info.InstallFiles...) + checkBuilds = info.CheckbuildFiles + } // 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 // for the current build target. if !ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(ctx, a) { - allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...) + allCheckbuildFiles = append(allCheckbuildFiles, checkBuilds...) } }) @@ -1763,6 +1771,19 @@ func (m *ModuleBase) archModuleContextFactory(ctx archModuleContextFactoryContex } +type InstallFilesInfo struct { + InstallFiles InstallPaths + CheckbuildFiles Paths + PackagingSpecs []PackagingSpec + // katiInstalls tracks the install rules that were created by Soong but are being exported + // to Make to convert to ninja rules so that Make can add additional dependencies. + KatiInstalls katiInstalls + KatiSymlinks katiInstalls + TestData []DataPath +} + +var InstallFilesProvider = blueprint.NewProvider[InstallFilesInfo]() + func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) { ctx := &moduleContext{ module: m.module, @@ -1921,7 +1942,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) restored := false if incrementalAnalysis && cacheKey != nil { - restored = ctx.bp.RestoreBuildActions(cacheKey, incrementalModule) + restored = ctx.bp.RestoreBuildActions(cacheKey) } if !restored { @@ -1944,12 +1965,14 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) return } - m.installFiles = append(m.installFiles, ctx.installFiles...) - m.checkbuildFiles = append(m.checkbuildFiles, ctx.checkbuildFiles...) - m.packagingSpecs = append(m.packagingSpecs, ctx.packagingSpecs...) - m.katiInstalls = append(m.katiInstalls, ctx.katiInstalls...) - m.katiSymlinks = append(m.katiSymlinks, ctx.katiSymlinks...) - m.testData = append(m.testData, ctx.testData...) + SetProvider(ctx, InstallFilesProvider, InstallFilesInfo{ + InstallFiles: ctx.installFiles, + CheckbuildFiles: ctx.checkbuildFiles, + PackagingSpecs: ctx.packagingSpecs, + KatiInstalls: ctx.katiInstalls, + KatiSymlinks: ctx.katiSymlinks, + TestData: ctx.testData, + }) } else if ctx.Config().AllowMissingDependencies() { // If the module is not enabled it will not create any build rules, nothing will call // ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled @@ -1965,15 +1988,15 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) } } - m.installFilesDepSet = NewDepSet[InstallPath](TOPOLOGICAL, m.installFiles, dependencyInstallFiles) - m.packagingSpecsDepSet = NewDepSet[PackagingSpec](TOPOLOGICAL, m.packagingSpecs, dependencyPackagingSpecs) + m.installFilesDepSet = NewDepSet[InstallPath](TOPOLOGICAL, ctx.installFiles, dependencyInstallFiles) + m.packagingSpecsDepSet = NewDepSet[PackagingSpec](TOPOLOGICAL, ctx.packagingSpecs, dependencyPackagingSpecs) buildLicenseMetadata(ctx, m.licenseMetadataFile) if m.moduleInfoJSON != nil { var installed InstallPaths - installed = append(installed, m.katiInstalls.InstallPaths()...) - installed = append(installed, m.katiSymlinks.InstallPaths()...) + installed = append(installed, ctx.katiInstalls.InstallPaths()...) + installed = append(installed, ctx.katiSymlinks.InstallPaths()...) installed = append(installed, m.katiInitRcInstalls.InstallPaths()...) installed = append(installed, m.katiVintfInstalls.InstallPaths()...) installedStrings := installed.Strings() @@ -1986,7 +2009,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) } var data []string - for _, d := range m.testData { + for _, d := range ctx.testData { data = append(data, d.ToRelativeInstallPath()) } @@ -2519,7 +2542,7 @@ func outputFilesForModuleFromProvider(ctx PathContext, module blueprint.Module, fromProperty = true } } else if cta, isCta := ctx.(*singletonContextAdaptor); isCta { - providerData, _ := cta.moduleProvider(module, OutputFilesProvider) + providerData, _ := cta.otherModuleProvider(module, OutputFilesProvider) outputFiles, _ = providerData.(OutputFilesInfo) } else { return nil, fmt.Errorf("unsupported context %q in method outputFilesForModuleFromProvider", reflect.TypeOf(ctx)) @@ -2666,7 +2689,7 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) { ctx.VisitAllModules(func(module Module) { if module.Enabled(ctx) { key := osAndCross{os: module.Target().Os, hostCross: module.Target().HostCross} - osDeps[key] = append(osDeps[key], module.base().checkbuildFiles...) + osDeps[key] = append(osDeps[key], OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider).CheckbuildFiles...) } }) diff --git a/android/module_context.go b/android/module_context.go index 253bebd3b..f619da2ba 100644 --- a/android/module_context.go +++ b/android/module_context.go @@ -231,8 +231,8 @@ type moduleContext struct { module Module phonies map[string]Paths - katiInstalls []katiInstall - katiSymlinks []katiInstall + katiInstalls katiInstalls + katiSymlinks katiInstalls testData []DataPath diff --git a/android/prebuilt.go b/android/prebuilt.go index 9c8c13093..fd5a6eaee 100644 --- a/android/prebuilt.go +++ b/android/prebuilt.go @@ -244,6 +244,8 @@ func InitPrebuiltModuleWithSrcSupplier(module PrebuiltInterface, srcsSupplier Pr p.srcsPropertyName = srcsPropertyName } +// InitPrebuiltModule is the same as InitPrebuiltModuleWithSrcSupplier, but uses the +// provided list of strings property as the source provider. func InitPrebuiltModule(module PrebuiltInterface, srcs *[]string) { if srcs == nil { panic(fmt.Errorf("srcs must not be nil")) @@ -256,6 +258,20 @@ func InitPrebuiltModule(module PrebuiltInterface, srcs *[]string) { InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, "srcs") } +// InitConfigurablePrebuiltModule is the same as InitPrebuiltModule, but uses a +// Configurable list of strings property instead of a regular list of strings. +func InitConfigurablePrebuiltModule(module PrebuiltInterface, srcs *proptools.Configurable[[]string]) { + if srcs == nil { + panic(fmt.Errorf("srcs must not be nil")) + } + + srcsSupplier := func(ctx BaseModuleContext, _ Module) []string { + return srcs.GetOrDefault(ctx, nil) + } + + InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, "srcs") +} + func InitSingleSourcePrebuiltModule(module PrebuiltInterface, srcProps interface{}, srcField string) { srcPropsValue := reflect.ValueOf(srcProps).Elem() srcStructField, _ := srcPropsValue.Type().FieldByName(srcField) diff --git a/android/provider.go b/android/provider.go index 3b9c5d2ba..5ded4cc14 100644 --- a/android/provider.go +++ b/android/provider.go @@ -14,6 +14,8 @@ var _ OtherModuleProviderContext = BaseModuleContext(nil) var _ OtherModuleProviderContext = ModuleContext(nil) var _ OtherModuleProviderContext = BottomUpMutatorContext(nil) var _ OtherModuleProviderContext = TopDownMutatorContext(nil) +var _ OtherModuleProviderContext = SingletonContext(nil) +var _ OtherModuleProviderContext = (*TestContext)(nil) // OtherModuleProvider reads the provider for the given 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 @@ -30,6 +32,11 @@ func OtherModuleProvider[K any](ctx OtherModuleProviderContext, module blueprint return value.(K), ok } +func OtherModuleProviderOrDefault[K any](ctx OtherModuleProviderContext, module blueprint.Module, provider blueprint.ProviderKey[K]) K { + value, _ := OtherModuleProvider(ctx, module, provider) + return value +} + // ModuleProviderContext is a helper interface that is a subset of ModuleContext, BottomUpMutatorContext, or // TopDownMutatorContext for use in ModuleProvider. type ModuleProviderContext interface { @@ -56,26 +63,6 @@ func ModuleProvider[K any](ctx ModuleProviderContext, provider blueprint.Provide return value.(K), ok } -type SingletonModuleProviderContext interface { - moduleProvider(blueprint.Module, blueprint.AnyProviderKey) (any, bool) -} - -var _ SingletonModuleProviderContext = SingletonContext(nil) -var _ SingletonModuleProviderContext = (*TestContext)(nil) - -// SingletonModuleProvider wraps blueprint.SingletonModuleProvider to provide a type-safe method to retrieve the value -// of the given provider from a module using a SingletonContext. If the provider has not been set the first return -// value will be the zero value of the provider's type, and the second return value will be false. If the provider has -// been set the second return value will be true. -func SingletonModuleProvider[K any](ctx SingletonModuleProviderContext, module blueprint.Module, provider blueprint.ProviderKey[K]) (K, bool) { - value, ok := ctx.moduleProvider(module, provider) - if !ok { - var k K - return k, false - } - return value.(K), ok -} - // SetProviderContext is a helper interface that is a subset of ModuleContext, BottomUpMutatorContext, or // TopDownMutatorContext for use in SetProvider. type SetProviderContext interface { diff --git a/android/singleton.go b/android/singleton.go index d364384e2..92264d2e3 100644 --- a/android/singleton.go +++ b/android/singleton.go @@ -35,7 +35,7 @@ type SingletonContext interface { // Allows generating build actions for `referer` based on the metadata for `name` deferred until the singleton context. ModuleVariantsFromName(referer Module, name string) []Module - moduleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) + otherModuleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) ModuleErrorf(module blueprint.Module, format string, args ...interface{}) Errorf(format string, args ...interface{}) @@ -279,7 +279,7 @@ func (s *singletonContextAdaptor) ModuleVariantsFromName(referer Module, name st return result } -func (s *singletonContextAdaptor) moduleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) { +func (s *singletonContextAdaptor) otherModuleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) { return s.SingletonContext.ModuleProvider(module, provider) } diff --git a/android/test_suites.go b/android/test_suites.go index ff75f26bb..936d2b651 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -47,7 +47,8 @@ func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { files[testSuite] = make(map[string]InstallPaths) } name := ctx.ModuleName(m) - files[testSuite][name] = append(files[testSuite][name], tsm.FilesToInstall()...) + files[testSuite][name] = append(files[testSuite][name], + OtherModuleProviderOrDefault(ctx, tsm, InstallFilesProvider).InstallFiles...) } } }) diff --git a/android/testing.go b/android/testing.go index e3853b844..79d0c9b41 100644 --- a/android/testing.go +++ b/android/testing.go @@ -126,6 +126,10 @@ var PrepareForTestWithMakevars = FixtureRegisterWithContext(func(ctx Registratio ctx.RegisterSingletonType("makevars", makeVarsSingletonFunc) }) +var PrepareForTestVintfFragmentModules = FixtureRegisterWithContext(func(ctx RegistrationContext) { + registerVintfFragmentComponents(ctx) +}) + // Test fixture preparer that will register most java build components. // // Singletons and mutators should only be added here if they are needed for a majority of java @@ -149,6 +153,7 @@ var PrepareForTestWithAndroidBuildComponents = GroupFixturePreparers( PrepareForTestWithPackageModule, PrepareForTestWithPrebuilts, PrepareForTestWithVisibility, + PrepareForTestVintfFragmentModules, ) // Prepares an integration test with all build components from the android package. @@ -212,7 +217,7 @@ func (ctx *TestContext) HardCodedPreArchMutators(f RegisterMutatorFunc) { ctx.PreArchMutators(f) } -func (ctx *TestContext) moduleProvider(m blueprint.Module, p blueprint.AnyProviderKey) (any, bool) { +func (ctx *TestContext) otherModuleProvider(m blueprint.Module, p blueprint.AnyProviderKey) (any, bool) { return ctx.Context.ModuleProvider(m, p) } @@ -230,7 +235,7 @@ func (ctx *TestContext) FinalDepsMutators(f RegisterMutatorFunc) { func (ctx *TestContext) OtherModuleProviderAdaptor() OtherModuleProviderContext { return NewOtherModuleProviderAdaptor(func(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) { - return ctx.moduleProvider(module, provider) + return ctx.otherModuleProvider(module, provider) }) } diff --git a/android/variable.go b/android/variable.go index c9b29f1d0..c14143748 100644 --- a/android/variable.go +++ b/android/variable.go @@ -510,8 +510,14 @@ type ProductVariables struct { SystemPropFiles []string `json:",omitempty"` SystemExtPropFiles []string `json:",omitempty"` + ProductPropFiles []string `json:",omitempty"` EnableUffdGc *string `json:",omitempty"` + + BoardAvbEnable *bool `json:",omitempty"` + BoardAvbSystemAddHashtreeFooterArgs []string `json:",omitempty"` + DeviceFrameworkCompatibilityMatrixFile []string `json:",omitempty"` + DeviceProductCompatibilityMatrixFile []string `json:",omitempty"` } type PartitionQualifiedVariablesType struct { diff --git a/android/vintf_fragment.go b/android/vintf_fragment.go new file mode 100644 index 000000000..329eac974 --- /dev/null +++ b/android/vintf_fragment.go @@ -0,0 +1,84 @@ +// 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 android + +type vintfFragmentProperties struct { + // Vintf fragment XML file. + Src string `android:"path"` +} + +type vintfFragmentModule struct { + ModuleBase + + properties vintfFragmentProperties + + installDirPath InstallPath + outputFilePath OutputPath +} + +func init() { + registerVintfFragmentComponents(InitRegistrationContext) +} + +func registerVintfFragmentComponents(ctx RegistrationContext) { + ctx.RegisterModuleType("vintf_fragment", vintfLibraryFactory) +} + +// 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.AddProperties( + &m.properties, + ) + InitAndroidArchModule(m, DeviceSupported, MultilibFirst) + + return m +} + +func (m *vintfFragmentModule) GenerateAndroidBuildActions(ctx ModuleContext) { + builder := NewRuleBuilder(pctx, ctx) + srcVintfFragment := PathForModuleSrc(ctx, m.properties.Src) + processedVintfFragment := PathForModuleOut(ctx, srcVintfFragment.Base()) + + // Process vintf fragment source file with assemble_vintf tool + builder.Command(). + Flag("VINTF_IGNORE_TARGET_FCM_VERSION=true"). + BuiltTool("assemble_vintf"). + FlagWithInput("-i ", srcVintfFragment). + FlagWithOutput("-o ", processedVintfFragment) + + builder.Build("assemble_vintf", "Process vintf fragment "+processedVintfFragment.String()) + + m.installDirPath = PathForModuleInstall(ctx, "etc", "vintf", "manifest") + m.outputFilePath = processedVintfFragment.OutputPath + + ctx.InstallFile(m.installDirPath, processedVintfFragment.Base(), processedVintfFragment) +} + +// Make this module visible to AndroidMK so it can be referenced from modules defined from Android.mk files +func (m *vintfFragmentModule) AndroidMkEntries() []AndroidMkEntries { + return []AndroidMkEntries{{ + Class: "ETC", + OutputFile: OptionalPathForPath(m.outputFilePath), + ExtraEntries: []AndroidMkExtraEntriesFunc{ + func(ctx AndroidMkExtraEntriesContext, entries *AndroidMkEntries) { + entries.SetString("LOCAL_MODULE_PATH", m.installDirPath.String()) + entries.SetString("LOCAL_INSTALLED_MODULE_STEM", m.outputFilePath.Base()) + }, + }, + }} +} diff --git a/android/vintf_fragment_test.go b/android/vintf_fragment_test.go new file mode 100644 index 000000000..8be534cf4 --- /dev/null +++ b/android/vintf_fragment_test.go @@ -0,0 +1,36 @@ +// 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 android + +import ( + "strings" + "testing" +) + +func TestVintfManifestBuildAction(t *testing.T) { + bp := ` + vintf_fragment { + name: "test_vintf_fragment", + src: "test_vintf_file", + } + ` + + testResult := PrepareForTestWithAndroidBuildComponents.RunTestWithBp(t, bp) + + vintfFragmentBuild := testResult.TestContext.ModuleForTests("test_vintf_fragment", "android_arm64_armv8-a").Rule("assemble_vintf") + if !strings.Contains(vintfFragmentBuild.RuleParams.Command, "assemble_vintf") { + t.Errorf("Vintf_manifest build command does not process with assemble_vintf : " + vintfFragmentBuild.RuleParams.Command) + } +} diff --git a/android_sdk/sdk_repo_host.go b/android_sdk/sdk_repo_host.go index 373e88306..a2486fdf5 100644 --- a/android_sdk/sdk_repo_host.go +++ b/android_sdk/sdk_repo_host.go @@ -46,6 +46,9 @@ type sdkRepoHost struct { outputBaseName string outputFile android.OptionalPath + + // TODO(b/357908583): Temp field, remove this once we support Android Mk providers + installFile android.InstallPath } type remapProperties struct { @@ -234,14 +237,18 @@ func (s *sdkRepoHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { s.outputBaseName = name s.outputFile = android.OptionalPathForPath(outputZipFile) - ctx.InstallFile(android.PathForModuleInstall(ctx, "sdk-repo"), name+".zip", outputZipFile) + installPath := android.PathForModuleInstall(ctx, "sdk-repo") + name = name + ".zip" + ctx.InstallFile(installPath, name, outputZipFile) + // TODO(b/357908583): Temp field, remove this once we support Android Mk providers + s.installFile = installPath.Join(ctx, name) } func (s *sdkRepoHost) AndroidMk() android.AndroidMkData { return android.AndroidMkData{ Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) { fmt.Fprintln(w, ".PHONY:", name, "sdk_repo", "sdk-repo-"+name) - fmt.Fprintln(w, "sdk_repo", "sdk-repo-"+name+":", strings.Join(s.FilesToInstall().Strings(), " ")) + fmt.Fprintln(w, "sdk_repo", "sdk-repo-"+name+":", s.installFile.String()) fmt.Fprintf(w, "$(call dist-for-goals,sdk_repo sdk-repo-%s,%s:%s-FILE_NAME_TAG_PLACEHOLDER.zip)\n\n", s.BaseModuleName(), s.outputFile.String(), s.outputBaseName) }, diff --git a/apex/apex.go b/apex/apex.go index fc0500aec..dd1c0b52e 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -2370,6 +2370,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.providePrebuiltInfo(ctx) a.required = a.RequiredModuleNames(ctx) + a.required = append(a.required, a.VintfFragmentModuleNames(ctx)...) a.setOutputFiles(ctx) } diff --git a/apex/apex_singleton.go b/apex/apex_singleton.go index a8d89b11e..f405cb2fe 100644 --- a/apex/apex_singleton.go +++ b/apex/apex_singleton.go @@ -88,7 +88,7 @@ func (s *apexDepsInfoSingleton) GenerateBuildActions(ctx android.SingletonContex updatableFlatLists := android.Paths{} ctx.VisitAllModules(func(module android.Module) { if binaryInfo, ok := module.(android.ApexBundleDepsInfoIntf); ok { - apexInfo, _ := android.SingletonModuleProvider(ctx, module, android.ApexInfoProvider) + apexInfo, _ := android.OtherModuleProvider(ctx, module, android.ApexInfoProvider) if path := binaryInfo.FlatListPath(); path != nil { if binaryInfo.Updatable() || apexInfo.Updatable { updatableFlatLists = append(updatableFlatLists, path) @@ -155,7 +155,7 @@ func (a *apexPrebuiltInfo) GenerateBuildActions(ctx android.SingletonContext) { prebuiltInfos := []android.PrebuiltInfo{} ctx.VisitAllModules(func(m android.Module) { - prebuiltInfo, exists := android.SingletonModuleProvider(ctx, m, android.PrebuiltInfoProvider) + prebuiltInfo, exists := android.OtherModuleProvider(ctx, m, android.PrebuiltInfoProvider) // Use prebuiltInfoProvider to filter out non apex soong modules. // Use HideFromMake to filter out the unselected variants of a specific apex. if exists && !m.IsHideFromMake() { diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go index f8c823e94..25131eec6 100644 --- a/apex/bootclasspath_fragment_test.go +++ b/apex/bootclasspath_fragment_test.go @@ -152,7 +152,7 @@ func TestBootclasspathFragments_FragmentDependency(t *testing.T) { // Check stub dex paths exported by art. artFragment := result.Module("art-bootclasspath-fragment", "android_common") - artInfo, _ := android.SingletonModuleProvider(result, artFragment, java.HiddenAPIInfoProvider) + artInfo, _ := android.OtherModuleProvider(result, artFragment, java.HiddenAPIInfoProvider) bazPublicStubs := "out/soong/.intermediates/baz.stubs.exportable/android_common/dex/baz.stubs.exportable.jar" bazSystemStubs := "out/soong/.intermediates/baz.stubs.exportable.system/android_common/dex/baz.stubs.exportable.system.jar" @@ -165,7 +165,7 @@ func TestBootclasspathFragments_FragmentDependency(t *testing.T) { // Check stub dex paths exported by other. otherFragment := result.Module("other-bootclasspath-fragment", "android_common") - otherInfo, _ := android.SingletonModuleProvider(result, otherFragment, java.HiddenAPIInfoProvider) + otherInfo, _ := android.OtherModuleProvider(result, otherFragment, java.HiddenAPIInfoProvider) fooPublicStubs := "out/soong/.intermediates/foo.stubs.exportable/android_common/dex/foo.stubs.exportable.jar" fooSystemStubs := "out/soong/.intermediates/foo.stubs.exportable.system/android_common/dex/foo.stubs.exportable.system.jar" @@ -688,7 +688,7 @@ func TestBootclasspathFragmentContentsNoName(t *testing.T) { // Make sure that the fragment provides the hidden API encoded dex jars to the APEX. fragment := result.Module("mybootclasspathfragment", "android_common_apex10000") - info, _ := android.SingletonModuleProvider(result, fragment, java.BootclasspathFragmentApexContentInfoProvider) + info, _ := android.OtherModuleProvider(result, fragment, java.BootclasspathFragmentApexContentInfoProvider) checkFragmentExportedDexJar := func(name string, expectedDexJar string) { module := result.Module(name, "android_common_apex10000") diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go index 645eebb13..920fc0c0b 100644 --- a/apex/platform_bootclasspath_test.go +++ b/apex/platform_bootclasspath_test.go @@ -154,7 +154,7 @@ func TestPlatformBootclasspath_Fragments(t *testing.T) { ).RunTest(t) pbcp := result.Module("platform-bootclasspath", "android_common") - info, _ := android.SingletonModuleProvider(result, pbcp, java.MonolithicHiddenAPIInfoProvider) + info, _ := android.OtherModuleProvider(result, pbcp, java.MonolithicHiddenAPIInfoProvider) for _, category := range java.HiddenAPIFlagFileCategories { name := category.PropertyName() @@ -236,7 +236,7 @@ func TestPlatformBootclasspath_LegacyPrebuiltFragment(t *testing.T) { ) pbcp := result.Module("myplatform-bootclasspath", "android_common") - info, _ := android.SingletonModuleProvider(result, pbcp, java.MonolithicHiddenAPIInfoProvider) + 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()) diff --git a/apex/prebuilt.go b/apex/prebuilt.go index 20a13c38b..8cdfb8974 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -516,7 +516,7 @@ type ApexFileProperties struct { // This cannot be marked as `android:"arch_variant"` because the `prebuilt_apex` is only mutated // for android_common. That is so that it will have the same arch variant as, and so be compatible // with, the source `apex` module type that it replaces. - Src *string `android:"path"` + Src proptools.Configurable[string] `android:"path,replace_instead_of_append"` Arch struct { Arm struct { Src *string `android:"path"` @@ -566,7 +566,7 @@ func (p *ApexFileProperties) prebuiltApexSelector(ctx android.BaseModuleContext, src = String(p.Arch.X86_64.Src) } if src == "" { - src = String(p.Src) + src = p.Src.GetOrDefault(ctx, "") } if src == "" { @@ -779,7 +779,7 @@ func (p *Prebuilt) ComponentDepsMutator(ctx android.BottomUpMutatorContext) { func (p *prebuiltCommon) DepsMutator(ctx android.BottomUpMutatorContext) { if p.hasExportedDeps() { // Create a dependency from the prebuilt apex (prebuilt_apex/apex_set) to the internal deapexer module - // The deapexer will return a provider that will be bubbled up to the rdeps of apexes (e.g. dex_bootjars) + // The deapexer will return a provider which will be used to determine the exported artfifacts from this prebuilt. ctx.AddDependency(ctx.Module(), android.DeapexerTag, deapexerModuleName(p.Name())) } } diff --git a/bin/dirmods b/bin/dirmods index a6d4de3be..c8976d53f 100755 --- a/bin/dirmods +++ b/bin/dirmods @@ -32,7 +32,10 @@ import modinfo def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('path') + parser.add_argument('--no-recurse', '-n', action='store_true', + help='Do not include modules defined in subdirs of path') args = parser.parse_args() + should_recurse = not args.no_recurse d = os.path.normpath(args.path) # Fix absolute path to be relative to build top @@ -43,15 +46,15 @@ def main(): if d.startswith(base): d = d[len(base):] - prefix = d + '/' + prefix = d + os.path.sep module_info = modinfo.ReadModuleInfo() results = set() for m in module_info.values(): - for path in m.get(u'path', []): - if path == d or path.startswith(prefix): - name = m.get(u'module_name') + for path in m.get('path', []): + if path == d or (should_recurse and path.startswith(prefix)): + name = m.get('module_name') if name: results.add(name) diff --git a/bloaty/bloaty.go b/bloaty/bloaty.go index b72b6d387..8ecea98b4 100644 --- a/bloaty/bloaty.go +++ b/bloaty/bloaty.go @@ -88,7 +88,7 @@ func (singleton *sizesSingleton) GenerateBuildActions(ctx android.SingletonConte if !m.ExportedToMake() { return } - filePaths, ok := android.SingletonModuleProvider(ctx, m, fileSizeMeasurerKey) + filePaths, ok := android.OtherModuleProvider(ctx, m, fileSizeMeasurerKey) if !ok { return } diff --git a/cc/builder.go b/cc/builder.go index a05a16dcb..cd535c1e8 100644 --- a/cc/builder.go +++ b/cc/builder.go @@ -22,6 +22,7 @@ import ( "fmt" "path/filepath" "runtime" + "slices" "strconv" "strings" @@ -910,6 +911,16 @@ func transformObjToDynamicBinary(ctx android.ModuleContext, "ldFlags": flags.globalLdFlags + " " + flags.localLdFlags, "crtEnd": strings.Join(crtEnd.Strings(), " "), } + + // On Windows, we always generate a PDB file + // --strip-debug is needed to also keep COFF symbols which are needed when + // we patch binaries with symbol_inject. + if ctx.Windows() { + pdb := outputFile.ReplaceExtension(ctx, "pdb") + args["ldFlags"] = args["ldFlags"] + " -Wl,--strip-debug -Wl,--pdb=" + pdb.String() + " " + implicitOutputs = append(slices.Clone(implicitOutputs), pdb) + } + if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_CXX_LINKS") { rule = ldRE args["implicitOutputs"] = strings.Join(implicitOutputs.Strings(), ",") @@ -906,19 +906,17 @@ type Module struct { logtagsPaths android.Paths WholeRustStaticlib bool + + hasAidl bool + hasLex bool + hasProto bool + hasRenderscript bool + hasSysprop bool + hasWinMsg bool + hasYacc bool } func (c *Module) AddJSONData(d *map[string]interface{}) { - var hasAidl, hasLex, hasProto, hasRenderscript, hasSysprop, hasWinMsg, hasYacc bool - if b, ok := c.compiler.(*baseCompiler); ok { - hasAidl = b.hasSrcExt(".aidl") - hasLex = b.hasSrcExt(".l") || b.hasSrcExt(".ll") - hasProto = b.hasSrcExt(".proto") - hasRenderscript = b.hasSrcExt(".rscript") || b.hasSrcExt(".fs") - hasSysprop = b.hasSrcExt(".sysprop") - hasWinMsg = b.hasSrcExt(".mc") - hasYacc = b.hasSrcExt(".y") || b.hasSrcExt(".yy") - } c.AndroidModuleBase().AddJSONData(d) (*d)["Cc"] = map[string]interface{}{ "SdkVersion": c.SdkVersion(), @@ -948,14 +946,14 @@ func (c *Module) AddJSONData(d *map[string]interface{}) { "IsVendorPublicLibrary": c.IsVendorPublicLibrary(), "ApexSdkVersion": c.apexSdkVersion, "TestFor": c.TestFor(), - "AidlSrcs": hasAidl, - "LexSrcs": hasLex, - "ProtoSrcs": hasProto, - "RenderscriptSrcs": hasRenderscript, - "SyspropSrcs": hasSysprop, - "WinMsgSrcs": hasWinMsg, - "YaccSrsc": hasYacc, - "OnlyCSrcs": !(hasAidl || hasLex || hasProto || hasRenderscript || hasSysprop || hasWinMsg || hasYacc), + "AidlSrcs": c.hasAidl, + "LexSrcs": c.hasLex, + "ProtoSrcs": c.hasProto, + "RenderscriptSrcs": c.hasRenderscript, + "SyspropSrcs": c.hasSysprop, + "WinMsgSrcs": c.hasWinMsg, + "YaccSrsc": c.hasYacc, + "OnlyCSrcs": !(c.hasAidl || c.hasLex || c.hasProto || c.hasRenderscript || c.hasSysprop || c.hasWinMsg || c.hasYacc), "OptimizeForSize": c.OptimizeForSize(), } } @@ -2086,6 +2084,16 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { buildComplianceMetadataInfo(ctx, c, deps) + if b, ok := c.compiler.(*baseCompiler); ok { + c.hasAidl = b.hasSrcExt(ctx, ".aidl") + c.hasLex = b.hasSrcExt(ctx, ".l") || b.hasSrcExt(ctx, ".ll") + c.hasProto = b.hasSrcExt(ctx, ".proto") + c.hasRenderscript = b.hasSrcExt(ctx, ".rscript") || b.hasSrcExt(ctx, ".fs") + c.hasSysprop = b.hasSrcExt(ctx, ".sysprop") + c.hasWinMsg = b.hasSrcExt(ctx, ".mc") + c.hasYacc = b.hasSrcExt(ctx, ".y") || b.hasSrcExt(ctx, ".yy") + } + c.setOutputFiles(ctx) } diff --git a/cc/cc_test.go b/cc/cc_test.go index 7372fff66..779e53d40 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -851,7 +851,7 @@ func TestStaticLibDepReordering(t *testing.T) { variant := "android_arm64_armv8-a_static" moduleA := ctx.ModuleForTests("a", variant).Module().(*Module) - staticLibInfo, _ := android.SingletonModuleProvider(ctx, moduleA, StaticLibraryInfoProvider) + staticLibInfo, _ := android.OtherModuleProvider(ctx, moduleA, StaticLibraryInfoProvider) actual := android.Paths(staticLibInfo.TransitiveStaticLibrariesForOrdering.ToList()).RelativeToTop() expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b", "d"}) @@ -887,7 +887,7 @@ func TestStaticLibDepReorderingWithShared(t *testing.T) { variant := "android_arm64_armv8-a_static" moduleA := ctx.ModuleForTests("a", variant).Module().(*Module) - staticLibInfo, _ := android.SingletonModuleProvider(ctx, moduleA, StaticLibraryInfoProvider) + staticLibInfo, _ := android.OtherModuleProvider(ctx, moduleA, StaticLibraryInfoProvider) actual := android.Paths(staticLibInfo.TransitiveStaticLibrariesForOrdering.ToList()).RelativeToTop() expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b"}) @@ -999,7 +999,7 @@ func TestLlndkLibrary(t *testing.T) { checkExportedIncludeDirs := func(module, variant string, expectedSystemDirs []string, expectedDirs ...string) { t.Helper() m := result.ModuleForTests(module, variant).Module() - f, _ := android.SingletonModuleProvider(result, m, FlagExporterInfoProvider) + f, _ := android.OtherModuleProvider(result, m, FlagExporterInfoProvider) android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]", expectedDirs, f.IncludeDirs) android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]", @@ -1027,7 +1027,7 @@ func TestLlndkLibrary(t *testing.T) { } } vendorModule := result.ModuleForTests(module, vendorVariant).Module() - vendorInfo, _ := android.SingletonModuleProvider(result, vendorModule, FlagExporterInfoProvider) + 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", android.JoinPathsWithPrefix(vendorDirs, "-I"), abiCheckFlags) @@ -2452,7 +2452,7 @@ func TestIncludeDirsExporting(t *testing.T) { checkIncludeDirs := func(t *testing.T, ctx *android.TestContext, module android.Module, checkers ...exportedChecker) { t.Helper() - exported, _ := android.SingletonModuleProvider(ctx, module, FlagExporterInfoProvider) + exported, _ := android.OtherModuleProvider(ctx, module, FlagExporterInfoProvider) name := module.Name() for _, checker := range checkers { diff --git a/cc/cmake_snapshot.go b/cc/cmake_snapshot.go index 8f3ad9639..600ac47f7 100644 --- a/cc/cmake_snapshot.go +++ b/cc/cmake_snapshot.go @@ -476,7 +476,8 @@ func (m *CmakeSnapshot) GenerateAndroidBuildActions(ctx android.ModuleContext) { var prebuiltsList android.Paths ctx.VisitDirectDepsWithTag(cmakeSnapshotPrebuiltTag, func(dep android.Module) { - for _, file := range dep.FilesToInstall() { + for _, file := range android.OtherModuleProviderOrDefault( + ctx, dep, android.InstallFilesProvider).InstallFiles { prebuiltsList = append(prebuiltsList, file) } }) diff --git a/cc/compiler.go b/cc/compiler.go index ed1053334..0e0b9a72d 100644 --- a/cc/compiler.go +++ b/cc/compiler.go @@ -37,7 +37,7 @@ type BaseCompilerProperties struct { // list of source files used to compile the C/C++ module. May be .c, .cpp, or .S files. // srcs may reference the outputs of other modules that produce source files like genrule // or filegroup using the syntax ":module". - Srcs []string `android:"path,arch_variant"` + Srcs proptools.Configurable[[]string] `android:"path,arch_variant"` // list of source files that should not be compiled with clang-tidy. Tidy_disabled_srcs []string `android:"path,arch_variant"` @@ -47,7 +47,7 @@ type BaseCompilerProperties struct { // list of source files that should not be used to build the C/C++ module. // This is most useful in the arch/multilib variants to remove non-common files - Exclude_srcs []string `android:"path,arch_variant"` + Exclude_srcs proptools.Configurable[[]string] `android:"path,arch_variant"` // list of module-specific flags that will be used for C and C++ compiles. Cflags proptools.Configurable[[]string] `android:"arch_variant"` @@ -229,7 +229,7 @@ type BaseCompilerProperties struct { } `android:"arch_variant"` // Stores the original list of source files before being cleared by library reuse - OriginalSrcs []string `blueprint:"mutated"` + OriginalSrcs proptools.Configurable[[]string] `blueprint:"mutated"` // Build and link with OpenMP Openmp *bool `android:"arch_variant"` @@ -300,7 +300,7 @@ func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps { deps.AidlLibs = append(deps.AidlLibs, compiler.Properties.Aidl.Libs...) android.ProtoDeps(ctx, &compiler.Proto) - if compiler.hasSrcExt(".proto") { + if compiler.hasSrcExt(ctx, ".proto") { deps = protoDeps(ctx, deps, &compiler.Proto, Bool(compiler.Properties.Proto.Static)) } @@ -363,7 +363,9 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps tc := ctx.toolchain() modulePath := ctx.ModuleDir() - compiler.srcsBeforeGen = android.PathsForModuleSrcExcludes(ctx, compiler.Properties.Srcs, compiler.Properties.Exclude_srcs) + srcs := compiler.Properties.Srcs.GetOrDefault(ctx, nil) + exclude_srcs := compiler.Properties.Exclude_srcs.GetOrDefault(ctx, nil) + compiler.srcsBeforeGen = android.PathsForModuleSrcExcludes(ctx, srcs, exclude_srcs) compiler.srcsBeforeGen = append(compiler.srcsBeforeGen, deps.GeneratedSources...) cflags := compiler.Properties.Cflags.GetOrDefault(ctx, nil) @@ -603,11 +605,11 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps flags.Global.CFlags = append(flags.Global.CFlags, "-DANDROID_STRICT") } - if compiler.hasSrcExt(".proto") { + if compiler.hasSrcExt(ctx, ".proto") { flags = protoFlags(ctx, flags, &compiler.Proto) } - if compiler.hasSrcExt(".y") || compiler.hasSrcExt(".yy") { + if compiler.hasSrcExt(ctx, ".y") || compiler.hasSrcExt(ctx, ".yy") { flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+android.PathForModuleGen(ctx, "yacc", ctx.ModuleDir()).String()) } @@ -617,7 +619,7 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps ctx.ModuleErrorf("aidl.libs and (aidl.include_dirs or aidl.local_include_dirs) can't be set at the same time. For aidl headers, please only use aidl.libs prop") } - if compiler.hasAidl(deps) { + if compiler.hasAidl(ctx, deps) { flags.aidlFlags = append(flags.aidlFlags, compiler.Properties.Aidl.Flags...) if len(compiler.Properties.Aidl.Local_include_dirs) > 0 { localAidlIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Aidl.Local_include_dirs) @@ -646,7 +648,7 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps } flags.aidlFlags = append(flags.aidlFlags, "--min_sdk_version="+aidlMinSdkVersion) - if compiler.hasSrcExt(".aidl") { + if compiler.hasSrcExt(ctx, ".aidl") { flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+android.PathForModuleGen(ctx, "aidl").String()) } @@ -656,16 +658,16 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps } } - if compiler.hasSrcExt(".rscript") || compiler.hasSrcExt(".fs") { + if compiler.hasSrcExt(ctx, ".rscript") || compiler.hasSrcExt(ctx, ".fs") { flags = rsFlags(ctx, flags, &compiler.Properties) } - if compiler.hasSrcExt(".sysprop") { + if compiler.hasSrcExt(ctx, ".sysprop") { flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+android.PathForModuleGen(ctx, "sysprop", "include").String()) } - if len(compiler.Properties.Srcs) > 0 { + if len(srcs) > 0 { module := ctx.ModuleDir() + "/Android.bp:" + ctx.ModuleName() if inList("-Wno-error", flags.Local.CFlags) || inList("-Wno-error", flags.Local.CppFlags) { addToModuleList(ctx, modulesUsingWnoErrorKey, module) @@ -706,18 +708,18 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps return flags } -func (compiler *baseCompiler) hasSrcExt(ext string) bool { +func (compiler *baseCompiler) hasSrcExt(ctx BaseModuleContext, ext string) bool { for _, src := range compiler.srcsBeforeGen { if src.Ext() == ext { return true } } - for _, src := range compiler.Properties.Srcs { + for _, src := range compiler.Properties.Srcs.GetOrDefault(ctx, nil) { if filepath.Ext(src) == ext { return true } } - for _, src := range compiler.Properties.OriginalSrcs { + for _, src := range compiler.Properties.OriginalSrcs.GetOrDefault(ctx, nil) { if filepath.Ext(src) == ext { return true } @@ -745,8 +747,8 @@ func ndkPathDeps(ctx ModuleContext) android.Paths { return nil } -func (compiler *baseCompiler) hasAidl(deps PathDeps) bool { - return len(deps.AidlLibraryInfos) > 0 || compiler.hasSrcExt(".aidl") +func (compiler *baseCompiler) hasAidl(ctx BaseModuleContext, deps PathDeps) bool { + return len(deps.AidlLibraryInfos) > 0 || compiler.hasSrcExt(ctx, ".aidl") } func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects { diff --git a/cc/config/global.go b/cc/config/global.go index 9e3919042..0e8fff6a0 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -275,7 +275,7 @@ var ( "-Wno-zero-as-null-pointer-constant", // http://b/68236239 "-Wno-deprecated-anon-enum-enum-conversion", // http://b/153746485 "-Wno-deprecated-enum-enum-conversion", - "-Wno-pessimizing-move", // http://b/154270751 + "-Wno-error=pessimizing-move", // http://b/154270751 // New warnings to be fixed after clang-r399163 "-Wno-non-c-typedef-for-linkage", // http://b/161304145 // New warnings to be fixed after clang-r428724 @@ -293,13 +293,6 @@ var ( "-Wno-error=invalid-offsetof", "-Wno-error=thread-safety-reference-return", - // Irrelevant on Android because _we_ don't use exceptions, but causes - // lots of build noise because libcxx/libcxxabi do. This can probably - // go away when we're on a new enough libc++, but has to be global - // until then because it causes warnings in the _callers_, not the - // project itself. - "-Wno-deprecated-dynamic-exception-spec", - // Allow using VLA CXX extension. "-Wno-vla-cxx-extension", } @@ -368,6 +361,7 @@ var ( "-Wno-unqualified-std-cast-call", "-Wno-array-parameter", "-Wno-gnu-offsetof-extensions", + "-Wno-pessimizing-move", // TODO: Enable this warning http://b/315245071 "-Wno-fortify-source", } diff --git a/cc/config/x86_windows_host.go b/cc/config/x86_windows_host.go index 1e61b01d0..ea7d3426a 100644 --- a/cc/config/x86_windows_host.go +++ b/cc/config/x86_windows_host.go @@ -43,6 +43,10 @@ var ( "-mno-ms-bitfields", "--sysroot ${WindowsGccRoot}/${WindowsGccTriple}", + + // Windows flags to generate PDB + "-g", + "-gcodeview", } windowsIncludeFlags = []string{ diff --git a/cc/fuzz.go b/cc/fuzz.go index 92f2c5e44..d9e221b16 100644 --- a/cc/fuzz.go +++ b/cc/fuzz.go @@ -373,7 +373,7 @@ func NewFuzzer(hod android.HostOrDeviceSupported) *Module { } if targetFramework == fuzz.AFL { - fuzzBin.baseCompiler.Properties.Srcs = append(fuzzBin.baseCompiler.Properties.Srcs, ":aflpp_driver", ":afl-compiler-rt") + fuzzBin.baseCompiler.Properties.Srcs.AppendSimpleValue([]string{":aflpp_driver", ":afl-compiler-rt"}) module.fuzzer.Properties.FuzzFramework = fuzz.AFL } }) diff --git a/cc/image.go b/cc/image.go index 2e52ccc63..7594a0854 100644 --- a/cc/image.go +++ b/cc/image.go @@ -465,11 +465,8 @@ func (c *Module) ExtraImageVariations(ctx android.BaseModuleContext) []string { func squashVendorSrcs(m *Module) { if lib, ok := m.compiler.(*libraryDecorator); ok { - lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs, - lib.baseCompiler.Properties.Target.Vendor.Srcs...) - - lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, - lib.baseCompiler.Properties.Target.Vendor.Exclude_srcs...) + lib.baseCompiler.Properties.Srcs.AppendSimpleValue(lib.baseCompiler.Properties.Target.Vendor.Srcs) + lib.baseCompiler.Properties.Exclude_srcs.AppendSimpleValue(lib.baseCompiler.Properties.Target.Vendor.Exclude_srcs) lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources, lib.baseCompiler.Properties.Target.Vendor.Exclude_generated_sources...) @@ -482,11 +479,8 @@ func squashVendorSrcs(m *Module) { func squashProductSrcs(m *Module) { if lib, ok := m.compiler.(*libraryDecorator); ok { - lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs, - lib.baseCompiler.Properties.Target.Product.Srcs...) - - lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, - lib.baseCompiler.Properties.Target.Product.Exclude_srcs...) + lib.baseCompiler.Properties.Srcs.AppendSimpleValue(lib.baseCompiler.Properties.Target.Product.Srcs) + lib.baseCompiler.Properties.Exclude_srcs.AppendSimpleValue(lib.baseCompiler.Properties.Target.Product.Exclude_srcs) lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources, lib.baseCompiler.Properties.Target.Product.Exclude_generated_sources...) @@ -499,11 +493,8 @@ func squashProductSrcs(m *Module) { func squashRecoverySrcs(m *Module) { if lib, ok := m.compiler.(*libraryDecorator); ok { - lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs, - lib.baseCompiler.Properties.Target.Recovery.Srcs...) - - lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, - lib.baseCompiler.Properties.Target.Recovery.Exclude_srcs...) + lib.baseCompiler.Properties.Srcs.AppendSimpleValue(lib.baseCompiler.Properties.Target.Recovery.Srcs) + lib.baseCompiler.Properties.Exclude_srcs.AppendSimpleValue(lib.baseCompiler.Properties.Target.Recovery.Exclude_srcs) lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources, lib.baseCompiler.Properties.Target.Recovery.Exclude_generated_sources...) @@ -512,13 +503,13 @@ func squashRecoverySrcs(m *Module) { func squashVendorRamdiskSrcs(m *Module) { if lib, ok := m.compiler.(*libraryDecorator); ok { - lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, lib.baseCompiler.Properties.Target.Vendor_ramdisk.Exclude_srcs...) + lib.baseCompiler.Properties.Exclude_srcs.AppendSimpleValue(lib.baseCompiler.Properties.Target.Vendor_ramdisk.Exclude_srcs) } } func squashRamdiskSrcs(m *Module) { if lib, ok := m.compiler.(*libraryDecorator); ok { - lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, lib.baseCompiler.Properties.Target.Ramdisk.Exclude_srcs...) + lib.baseCompiler.Properties.Exclude_srcs.AppendSimpleValue(lib.baseCompiler.Properties.Target.Ramdisk.Exclude_srcs) } } diff --git a/cc/library.go b/cc/library.go index 092b17779..de0070a15 100644 --- a/cc/library.go +++ b/cc/library.go @@ -142,7 +142,7 @@ type SharedProperties struct { // Use `StaticProperties` or `SharedProperties`, depending on which variant is needed. // `StaticOrSharedProperties` exists only to avoid duplication. type StaticOrSharedProperties struct { - Srcs []string `android:"path,arch_variant"` + Srcs proptools.Configurable[[]string] `android:"path,arch_variant"` Tidy_disabled_srcs []string `android:"path,arch_variant"` @@ -633,14 +633,17 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa return objs } + srcs := library.baseCompiler.Properties.Srcs.GetOrDefault(ctx, nil) + staticSrcs := library.StaticProperties.Static.Srcs.GetOrDefault(ctx, nil) + sharedSrcs := library.SharedProperties.Shared.Srcs.GetOrDefault(ctx, nil) if !library.buildShared() && !library.buildStatic() { - if len(library.baseCompiler.Properties.Srcs) > 0 { + if len(srcs) > 0 { ctx.PropertyErrorf("srcs", "cc_library_headers must not have any srcs") } - if len(library.StaticProperties.Static.Srcs) > 0 { + if len(staticSrcs) > 0 { ctx.PropertyErrorf("static.srcs", "cc_library_headers must not have any srcs") } - if len(library.SharedProperties.Shared.Srcs) > 0 { + if len(sharedSrcs) > 0 { ctx.PropertyErrorf("shared.srcs", "cc_library_headers must not have any srcs") } return Objects{} @@ -651,8 +654,8 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa for _, dir := range dirs { flags.SAbiFlags = append(flags.SAbiFlags, "-I"+dir) } - totalLength := len(library.baseCompiler.Properties.Srcs) + len(deps.GeneratedSources) + - len(library.SharedProperties.Shared.Srcs) + len(library.StaticProperties.Static.Srcs) + totalLength := len(srcs) + len(deps.GeneratedSources) + + len(sharedSrcs) + len(staticSrcs) if totalLength > 0 { flags.SAbiDump = true } @@ -662,13 +665,13 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa buildFlags := flagsToBuilderFlags(flags) if library.static() { - srcs := android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Srcs) + srcs := android.PathsForModuleSrc(ctx, staticSrcs) 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)) } else if library.shared() { - srcs := android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Srcs) + 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), @@ -1651,8 +1654,8 @@ func (library *libraryDecorator) link(ctx ModuleContext, // Optionally export aidl headers. if Bool(library.Properties.Aidl.Export_aidl_headers) { - if library.baseCompiler.hasAidl(deps) { - if library.baseCompiler.hasSrcExt(".aidl") { + if library.baseCompiler.hasAidl(ctx, deps) { + if library.baseCompiler.hasSrcExt(ctx, ".aidl") { dir := android.PathForModuleGen(ctx, "aidl") library.reexportDirs(dir) } @@ -1668,7 +1671,7 @@ func (library *libraryDecorator) link(ctx ModuleContext, // Optionally export proto headers. if Bool(library.Properties.Proto.Export_proto_headers) { - if library.baseCompiler.hasSrcExt(".proto") { + if library.baseCompiler.hasSrcExt(ctx, ".proto") { var includes android.Paths if flags.proto.CanonicalPathFromRoot { includes = append(includes, flags.proto.SubDir) @@ -1682,7 +1685,7 @@ func (library *libraryDecorator) link(ctx ModuleContext, } // If the library is sysprop_library, expose either public or internal header selectively. - if library.baseCompiler.hasSrcExt(".sysprop") { + if library.baseCompiler.hasSrcExt(ctx, ".sysprop") { dir := android.PathForModuleGen(ctx, "sysprop", "include") if library.Properties.Sysprop.Platform != nil { isOwnerPlatform := Bool(library.Properties.Sysprop.Platform) @@ -2091,7 +2094,7 @@ func reuseStaticLibrary(ctx android.BottomUpMutatorContext, shared *Module) { ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, reuseObjTag, ctx.ModuleName()) sharedCompiler.baseCompiler.Properties.OriginalSrcs = sharedCompiler.baseCompiler.Properties.Srcs - sharedCompiler.baseCompiler.Properties.Srcs = nil + sharedCompiler.baseCompiler.Properties.Srcs = proptools.NewConfigurable[[]string](nil, nil) sharedCompiler.baseCompiler.Properties.Generated_sources = nil } diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go index 57a3b3a9c..e00293143 100644 --- a/cc/ndk_headers.go +++ b/cc/ndk_headers.go @@ -18,6 +18,7 @@ import ( "path/filepath" "android/soong/android" + "github.com/google/blueprint" ) @@ -44,7 +45,7 @@ func init() { } // Returns the NDK base include path for use with sdk_version current. Usable with -I. -func getCurrentIncludePath(ctx android.ModuleContext) android.OutputPath { +func getCurrentIncludePath(ctx android.PathContext) android.OutputPath { return getNdkSysrootBase(ctx).Join(ctx, "usr/include") } @@ -73,6 +74,13 @@ type headerProperties struct { // Path to the NOTICE file associated with the headers. License *string `android:"path"` + + // Set to true if the headers installed by this module should skip + // verification. This step ensures that each header is self-contained (can + // be #included alone) and is valid C. This should not be disabled except in + // rare cases. Outside bionic and external, if you're using this option + // you've probably made a mistake. + Skip_verification *bool } type headerModule struct { @@ -309,6 +317,13 @@ type preprocessedHeadersProperties struct { // Path to the NOTICE file associated with the headers. License *string + + // Set to true if the headers installed by this module should skip + // verification. This step ensures that each header is self-contained (can + // be #included alone) and is valid C. This should not be disabled except in + // rare cases. Outside bionic and external, if you're using this option + // you've probably made a mistake. + Skip_verification *bool } type preprocessedHeadersModule struct { diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go index 3c48f6881..f571523a0 100644 --- a/cc/ndk_sysroot.go +++ b/cc/ndk_sysroot.go @@ -54,7 +54,22 @@ package cc import ( "android/soong/android" + "fmt" + "path/filepath" "strings" + + "github.com/google/blueprint" +) + +var ( + verifyCCompat = pctx.AndroidStaticRule("verifyCCompat", + blueprint.RuleParams{ + Command: "$ccCmd -x c -fsyntax-only $flags $in && touch $out", + CommandDeps: []string{"$ccCmd"}, + }, + "ccCmd", + "flags", + ) ) func init() { @@ -103,6 +118,45 @@ func getNdkABIHeadersFile(ctx android.PathContext) android.WritablePath { return android.PathForOutput(ctx, "ndk_abi_headers.txt") } +func verifyNdkHeaderIsCCompatible(ctx android.SingletonContext, + src android.Path, dest android.Path) android.Path { + sysrootInclude := getCurrentIncludePath(ctx) + baseOutputDir := android.PathForOutput(ctx, "c-compat-verification") + installRelPath, err := filepath.Rel(sysrootInclude.String(), dest.String()) + if err != nil { + ctx.Errorf("filepath.Rel(%q, %q) failed: %s", dest, sysrootInclude, err) + } + output := baseOutputDir.Join(ctx, installRelPath) + ctx.Build(pctx, android.BuildParams{ + Rule: verifyCCompat, + Description: fmt.Sprintf("Verifying C compatibility of %s", src), + Output: output, + Input: dest, + // Ensures that all the headers in the sysroot are already installed + // before testing any of the headers for C compatibility, and also that + // the check will be re-run whenever the sysroot changes. This is + // necessary because many of the NDK headers depend on other NDK + // headers, but we don't have explicit dependency tracking for that. + Implicits: []android.Path{getNdkHeadersTimestampFile(ctx)}, + Args: map[string]string{ + "ccCmd": "${config.ClangBin}/clang", + "flags": fmt.Sprintf( + // Ideally we'd check each ABI, multiple API levels, + // fortify/non-fortify, and a handful of other variations. It's + // a lot more difficult to do that though, and would eat up more + // build time. All the problems we've seen so far that this + // check would catch have been in arch-generic and + // minSdkVersion-generic code in frameworks though, so this is a + // good place to start. + "-target aarch64-linux-android%d --sysroot %s", + android.FutureApiLevel.FinalOrFutureInt(), + getNdkSysrootBase(ctx).String(), + ), + }, + }) + return output +} + func NdkSingleton() android.Singleton { return &ndkSingleton{} } @@ -143,10 +197,17 @@ func writeNdkAbiSrcFilter(ctx android.BuilderContext, type ndkSingleton struct{} +type srcDestPair struct { + src android.Path + dest android.Path +} + func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) { var staticLibInstallPaths android.Paths var headerSrcPaths android.Paths var headerInstallPaths android.Paths + var headersToVerify []srcDestPair + var headerCCompatVerificationTimestampPaths android.Paths var installPaths android.Paths var licensePaths android.Paths ctx.VisitAllModules(func(module android.Module) { @@ -157,6 +218,14 @@ func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) { if m, ok := module.(*headerModule); ok { headerSrcPaths = append(headerSrcPaths, m.srcPaths...) headerInstallPaths = append(headerInstallPaths, m.installPaths...) + if !Bool(m.properties.Skip_verification) { + for i, installPath := range m.installPaths { + headersToVerify = append(headersToVerify, srcDestPair{ + src: m.srcPaths[i], + dest: installPath, + }) + } + } installPaths = append(installPaths, m.installPaths...) licensePaths = append(licensePaths, m.licensePath) } @@ -164,6 +233,10 @@ func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) { if m, ok := module.(*versionedHeaderModule); ok { headerSrcPaths = append(headerSrcPaths, m.srcPaths...) headerInstallPaths = append(headerInstallPaths, m.installPaths...) + // Verification intentionally not done for headers that go through + // versioner. It'd be nice to have, but the only user is bionic, and + // that one module would also need to use skip_verification, so it + // wouldn't help at all. installPaths = append(installPaths, m.installPaths...) licensePaths = append(licensePaths, m.licensePath) } @@ -171,6 +244,14 @@ func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) { if m, ok := module.(*preprocessedHeadersModule); ok { headerSrcPaths = append(headerSrcPaths, m.srcPaths...) headerInstallPaths = append(headerInstallPaths, m.installPaths...) + if !Bool(m.properties.Skip_verification) { + for i, installPath := range m.installPaths { + headersToVerify = append(headersToVerify, srcDestPair{ + src: m.srcPaths[i], + dest: installPath, + }) + } + } installPaths = append(installPaths, m.installPaths...) licensePaths = append(licensePaths, m.licensePath) } @@ -223,6 +304,12 @@ func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) { Implicits: headerInstallPaths, }) + for _, srcDestPair := range headersToVerify { + headerCCompatVerificationTimestampPaths = append( + headerCCompatVerificationTimestampPaths, + verifyNdkHeaderIsCCompatible(ctx, srcDestPair.src, srcDestPair.dest)) + } + writeNdkAbiSrcFilter(ctx, headerSrcPaths, getNdkABIHeadersFile(ctx)) fullDepPaths := append(staticLibInstallPaths, getNdkBaseTimestampFile(ctx)) @@ -235,6 +322,6 @@ func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) { ctx.Build(pctx, android.BuildParams{ Rule: android.Touch, Output: getNdkFullTimestampFile(ctx), - Implicits: fullDepPaths, + Implicits: append(fullDepPaths, headerCCompatVerificationTimestampPaths...), }) } diff --git a/cc/prebuilt.go b/cc/prebuilt.go index e023a324c..fb151d8fd 100644 --- a/cc/prebuilt.go +++ b/cc/prebuilt.go @@ -48,7 +48,7 @@ type prebuiltLinkerProperties struct { Source_module_name *string // a prebuilt library or binary. Can reference a genrule module that generates an executable file. - Srcs []string `android:"path,arch_variant"` + Srcs proptools.Configurable[[]string] `android:"path,arch_variant"` Sanitized Sanitized `android:"arch_variant"` @@ -75,10 +75,6 @@ func (p *prebuiltLinker) prebuilt() *android.Prebuilt { return &p.Prebuilt } -func (p *prebuiltLinker) PrebuiltSrcs() []string { - return p.properties.Srcs -} - type prebuiltLibraryInterface interface { libraryInterface prebuiltLinkerInterface @@ -226,14 +222,14 @@ func (p *prebuiltLibraryLinker) link(ctx ModuleContext, func (p *prebuiltLibraryLinker) prebuiltSrcs(ctx android.BaseModuleContext) []string { sanitize := ctx.Module().(*Module).sanitize - srcs := p.properties.Srcs + srcs := p.properties.Srcs.GetOrDefault(ctx, nil) srcs = append(srcs, srcsForSanitizer(sanitize, p.properties.Sanitized)...) if p.static() { - srcs = append(srcs, p.libraryDecorator.StaticProperties.Static.Srcs...) + srcs = append(srcs, p.libraryDecorator.StaticProperties.Static.Srcs.GetOrDefault(ctx, nil)...) srcs = append(srcs, srcsForSanitizer(sanitize, p.libraryDecorator.StaticProperties.Static.Sanitized)...) } if p.shared() { - srcs = append(srcs, p.libraryDecorator.SharedProperties.Shared.Srcs...) + srcs = append(srcs, p.libraryDecorator.SharedProperties.Shared.Srcs.GetOrDefault(ctx, nil)...) srcs = append(srcs, srcsForSanitizer(sanitize, p.libraryDecorator.SharedProperties.Shared.Sanitized)...) } return srcs @@ -248,7 +244,7 @@ func (p *prebuiltLibraryLinker) nativeCoverage() bool { } func (p *prebuiltLibraryLinker) disablePrebuilt() { - p.properties.Srcs = nil + p.properties.Srcs = proptools.NewConfigurable[[]string](nil, nil) p.properties.Sanitized.None.Srcs = nil p.properties.Sanitized.Address.Srcs = nil p.properties.Sanitized.Hwaddress.Srcs = nil @@ -416,7 +412,7 @@ func (p *prebuiltBinaryLinker) hostToolPath() android.OptionalPath { func (p *prebuiltBinaryLinker) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path { // TODO(ccross): verify shared library dependencies - if len(p.properties.Srcs) > 0 { + if len(p.properties.Srcs.GetOrDefault(ctx, nil)) > 0 { fileName := p.getStem(ctx) + flags.Toolchain.ExecutableSuffix() in := p.Prebuilt.SingleSourcePath(ctx) outputFile := android.PathForModuleOut(ctx, fileName) @@ -500,7 +496,7 @@ func NewPrebuiltBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecor module.AddProperties(&prebuilt.properties) - android.InitPrebuiltModule(module, &prebuilt.properties.Srcs) + android.InitConfigurablePrebuiltModule(module, &prebuilt.properties.Srcs) return module, binary } diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go index 44f38e10a..80facd8f0 100644 --- a/cc/sanitize_test.go +++ b/cc/sanitize_test.go @@ -47,7 +47,7 @@ var prepareForTsanTest = android.FixtureAddFile("tsan/Android.bp", []byte(` `)) type providerInterface interface { - android.SingletonModuleProviderContext + android.OtherModuleProviderContext } // expectSharedLinkDep verifies that the from module links against the to module as a @@ -55,7 +55,7 @@ type providerInterface interface { func expectSharedLinkDep(t *testing.T, ctx providerInterface, from, to android.TestingModule) { t.Helper() fromLink := from.Description("link") - toInfo, _ := android.SingletonModuleProvider(ctx, to.Module(), SharedLibraryInfoProvider) + toInfo, _ := android.OtherModuleProvider(ctx, to.Module(), SharedLibraryInfoProvider) if g, w := fromLink.OrderOnly.Strings(), toInfo.SharedLibrary.RelativeToTop().String(); !android.InList(w, g) { t.Errorf("%s should link against %s, expected %q, got %q", @@ -68,7 +68,7 @@ func expectSharedLinkDep(t *testing.T, ctx providerInterface, from, to android.T func expectNoSharedLinkDep(t *testing.T, ctx providerInterface, from, to android.TestingModule) { t.Helper() fromLink := from.Description("link") - toInfo, _ := android.SingletonModuleProvider(ctx, to.Module(), SharedLibraryInfoProvider) + toInfo, _ := android.OtherModuleProvider(ctx, to.Module(), SharedLibraryInfoProvider) if g, w := fromLink.OrderOnly.Strings(), toInfo.SharedLibrary.RelativeToTop().String(); android.InList(w, g) { t.Errorf("%s should not link against %s, expected %q, got %q", @@ -81,7 +81,7 @@ func expectNoSharedLinkDep(t *testing.T, ctx providerInterface, from, to android func expectStaticLinkDep(t *testing.T, ctx providerInterface, from, to android.TestingModule) { t.Helper() fromLink := from.Description("link") - toInfo, _ := android.SingletonModuleProvider(ctx, to.Module(), StaticLibraryInfoProvider) + toInfo, _ := android.OtherModuleProvider(ctx, to.Module(), StaticLibraryInfoProvider) if g, w := fromLink.Implicits.Strings(), toInfo.StaticLibrary.RelativeToTop().String(); !android.InList(w, g) { t.Errorf("%s should link against %s, expected %q, got %q", @@ -95,7 +95,7 @@ func expectStaticLinkDep(t *testing.T, ctx providerInterface, from, to android.T func expectNoStaticLinkDep(t *testing.T, ctx providerInterface, from, to android.TestingModule) { t.Helper() fromLink := from.Description("link") - toInfo, _ := android.SingletonModuleProvider(ctx, to.Module(), StaticLibraryInfoProvider) + toInfo, _ := android.OtherModuleProvider(ctx, to.Module(), StaticLibraryInfoProvider) if g, w := fromLink.Implicits.Strings(), toInfo.StaticLibrary.RelativeToTop().String(); android.InList(w, g) { t.Errorf("%s should not link against %s, expected %q, got %q", diff --git a/cc/stub_library.go b/cc/stub_library.go index 47c6cb9a1..f15a60403 100644 --- a/cc/stub_library.go +++ b/cc/stub_library.go @@ -39,8 +39,9 @@ func IsStubTarget(m *Module) bool { } // Get target file name to be installed from this module -func getInstalledFileName(m *Module) string { - for _, ps := range m.PackagingSpecs() { +func getInstalledFileName(ctx android.SingletonContext, m *Module) string { + for _, ps := range android.OtherModuleProviderOrDefault( + ctx, m.Module(), android.InstallFilesProvider).PackagingSpecs { if name := ps.FileName(); name != "" { return name } @@ -53,7 +54,7 @@ func (s *stubLibraries) GenerateBuildActions(ctx android.SingletonContext) { ctx.VisitAllModules(func(module android.Module) { if m, ok := module.(*Module); ok { if IsStubTarget(m) { - if name := getInstalledFileName(m); name != "" { + if name := getInstalledFileName(ctx, m); name != "" { s.stubLibraryMap[name] = true if m.InVendor() { s.stubVendorLibraryMap[name] = true diff --git a/filesystem/system_image.go b/filesystem/system_image.go index 69d922df9..a8fd36822 100644 --- a/filesystem/system_image.go +++ b/filesystem/system_image.go @@ -61,7 +61,8 @@ func (s *systemImage) buildLinkerConfigFile(ctx android.ModuleContext, root andr deps := s.gatherFilteredPackagingSpecs(ctx) ctx.WalkDeps(func(child, parent android.Module) bool { - for _, ps := range child.PackagingSpecs() { + for _, ps := range android.OtherModuleProviderOrDefault( + ctx, child, android.InstallFilesProvider).PackagingSpecs { if _, ok := deps[ps.RelPathInPackage()]; ok { modulesInPackageByModule[child] = true modulesInPackageByName[child.Name()] = true diff --git a/java/aar_test.go b/java/aar_test.go index ebad310ab..877e2c7d6 100644 --- a/java/aar_test.go +++ b/java/aar_test.go @@ -53,7 +53,7 @@ func TestAarImportProducesJniPackages(t *testing.T) { appMod := ctx.Module(tc.name, "android_common") appTestMod := ctx.ModuleForTests(tc.name, "android_common") - info, ok := android.SingletonModuleProvider(ctx, appMod, JniPackageProvider) + info, ok := android.OtherModuleProvider(ctx, appMod, JniPackageProvider) if !ok { t.Errorf("expected android_library_import to have JniPackageProvider") } diff --git a/java/app.go b/java/app.go index 19dc8d5d1..1ebf658a1 100644 --- a/java/app.go +++ b/java/app.go @@ -1109,7 +1109,7 @@ func collectJniDeps(ctx android.ModuleContext, coverageFile: dep.CoverageOutputFile(), unstrippedFile: dep.UnstrippedOutputFile(), partition: dep.Partition(), - installPaths: dep.FilesToInstall(), + installPaths: android.OtherModuleProviderOrDefault(ctx, dep, android.InstallFilesProvider).InstallFiles, }) } else if ctx.Config().AllowMissingDependencies() { ctx.AddMissingDependencies([]string{otherName}) diff --git a/java/base.go b/java/base.go index fddf16ad6..c601cf536 100644 --- a/java/base.go +++ b/java/base.go @@ -222,6 +222,13 @@ type CommonProperties struct { // the stubs via libs, but should be set to true when the module depends on // the stubs via static libs. Is_stubs_module *bool + + // If true, enable the "Ravenizer" tool on the output jar. + // "Ravenizer" is a tool for Ravenwood tests, but it can also be enabled on other kinds + // of java targets. + Ravenizer struct { + Enabled *bool + } } // Properties that are specific to device modules. Host module factories should not add these when @@ -558,6 +565,10 @@ type Module struct { // List of soong module dependencies required to compile the current module. // This information is printed out to `Dependencies` field in module_bp_java_deps.json compileDepNames []string + + ravenizer struct { + enabled bool + } } var _ android.InstallableModule = (*Module)(nil) @@ -1116,7 +1127,6 @@ func (j *Module) addGeneratedSrcJars(path android.Path) { } func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspathJars, extraCombinedJars android.Paths) { - // Auto-propagating jarjar rules jarjarProviderData := j.collectJarJarRules(ctx) if jarjarProviderData != nil { @@ -1133,6 +1143,10 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs) + if re := proptools.Bool(j.properties.Ravenizer.Enabled); re { + j.ravenizer.enabled = re + } + deps := j.collectDeps(ctx) flags := j.collectBuilderFlags(ctx, deps) @@ -1555,6 +1569,18 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath return } + if j.ravenizer.enabled { + ravenizerInput := outputFile + ravenizerOutput := android.PathForModuleOut(ctx, "ravenizer", jarName) + ctx.Build(pctx, android.BuildParams{ + Rule: ravenizer, + Description: "ravenizer", + Input: ravenizerInput, + Output: ravenizerOutput, + }) + outputFile = ravenizerOutput + } + // Check package restrictions if necessary. if len(j.properties.Permitted_packages) > 0 { // Time stamp file created by the package check rule. @@ -2014,16 +2040,20 @@ func (j *Module) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap { // Collect information for opening IDE project files in java/jdeps.go. func (j *Module) IDEInfo(dpInfo *android.IdeInfo) { - dpInfo.Deps = append(dpInfo.Deps, j.CompilerDeps()...) - dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...) - dpInfo.SrcJars = append(dpInfo.SrcJars, j.compiledSrcJars.Strings()...) - dpInfo.Aidl_include_dirs = append(dpInfo.Aidl_include_dirs, j.deviceProperties.Aidl.Include_dirs...) + // jarjar rules will repackage the sources. To prevent misleading results, IdeInfo should contain the + // repackaged jar instead of the input sources. if j.expandJarjarRules != nil { dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String()) + dpInfo.Jars = append(dpInfo.Jars, j.headerJarFile.String()) + } else { + dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...) + dpInfo.SrcJars = append(dpInfo.SrcJars, j.compiledSrcJars.Strings()...) + dpInfo.SrcJars = append(dpInfo.SrcJars, j.annoSrcJars.Strings()...) } + dpInfo.Deps = append(dpInfo.Deps, j.CompilerDeps()...) + dpInfo.Aidl_include_dirs = append(dpInfo.Aidl_include_dirs, j.deviceProperties.Aidl.Include_dirs...) dpInfo.Static_libs = append(dpInfo.Static_libs, j.properties.Static_libs...) dpInfo.Libs = append(dpInfo.Libs, j.properties.Libs...) - dpInfo.SrcJars = append(dpInfo.SrcJars, j.annoSrcJars.Strings()...) } func (j *Module) CompilerDeps() []string { diff --git a/java/bootclasspath_fragment_test.go b/java/bootclasspath_fragment_test.go index d72417afa..60f1a50e1 100644 --- a/java/bootclasspath_fragment_test.go +++ b/java/bootclasspath_fragment_test.go @@ -273,7 +273,7 @@ func TestBootclasspathFragment_StubLibs(t *testing.T) { `) fragment := result.Module("myfragment", "android_common") - info, _ := android.SingletonModuleProvider(result, fragment, HiddenAPIInfoProvider) + info, _ := android.OtherModuleProvider(result, fragment, HiddenAPIInfoProvider) stubsJar := "out/soong/.intermediates/mystublib/android_common/dex/mystublib.jar" @@ -457,7 +457,7 @@ func TestSnapshotWithBootclasspathFragment_HiddenAPI(t *testing.T) { // Make sure that the library exports hidden API properties for use by the bootclasspath_fragment. library := result.Module("mynewlibrary", "android_common") - info, _ := android.SingletonModuleProvider(result, library, hiddenAPIPropertyInfoProvider) + info, _ := android.OtherModuleProvider(result, library, hiddenAPIPropertyInfoProvider) android.AssertArrayString(t, "split packages", []string{"sdklibrary", "newlibrary"}, info.SplitPackages) android.AssertArrayString(t, "package prefixes", []string{"newlibrary.all.mine"}, info.PackagePrefixes) android.AssertArrayString(t, "single packages", []string{"newlibrary.mine"}, info.SinglePackages) diff --git a/java/builder.go b/java/builder.go index 591523545..49207e535 100644 --- a/java/builder.go +++ b/java/builder.go @@ -258,6 +258,13 @@ var ( }, ) + ravenizer = pctx.AndroidStaticRule("ravenizer", + blueprint.RuleParams{ + Command: "rm -f $out && ${ravenizer} --in-jar $in --out-jar $out", + CommandDeps: []string{"${ravenizer}"}, + }, + ) + zipalign = pctx.AndroidStaticRule("zipalign", blueprint.RuleParams{ Command: "if ! ${config.ZipAlign} -c -p 4 $in > /dev/null; then " + @@ -307,6 +314,7 @@ func init() { pctx.Import("android/soong/java/config") pctx.HostBinToolVariable("aconfig", "aconfig") + pctx.HostBinToolVariable("ravenizer", "ravenizer") pctx.HostBinToolVariable("keep-flagged-apis", "keep-flagged-apis") } @@ -765,6 +773,16 @@ func TransformJetifier(ctx android.ModuleContext, outputFile android.WritablePat }) } +func TransformRavenizer(ctx android.ModuleContext, outputFile android.WritablePath, + inputFile android.Path) { + ctx.Build(pctx, android.BuildParams{ + Rule: ravenizer, + Description: "ravenizer", + Output: outputFile, + Input: inputFile, + }) +} + func GenerateMainClassManifest(ctx android.ModuleContext, outputFile android.WritablePath, mainClass string) { android.WriteFileRule(ctx, outputFile, "Main-Class: "+mainClass+"\n") } diff --git a/java/code_metadata_test.go b/java/code_metadata_test.go index 99b1f5226..9dc9a2262 100644 --- a/java/code_metadata_test.go +++ b/java/code_metadata_test.go @@ -29,7 +29,7 @@ func TestCodeMetadata(t *testing.T) { module := result.ModuleForTests("module-name", "") // Check that the provider has the right contents - data, _ := android.SingletonModuleProvider(result, module.Module(), soongTesting.CodeMetadataProviderKey) + data, _ := android.OtherModuleProvider(result, module.Module(), soongTesting.CodeMetadataProviderKey) if !strings.HasSuffix( data.IntermediatePath.String(), "/intermediateCodeMetadata.pb", ) { diff --git a/java/config/config.go b/java/config/config.go index 66e857c64..a50c1b42d 100644 --- a/java/config/config.go +++ b/java/config/config.go @@ -47,7 +47,7 @@ var ( "services", "android.car", "android.car7", - "android.car.builtin", + "android.car.builtin.impl", "conscrypt", "core-icu4j", "core-oj", diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 56e007bbf..a81ab8316 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -1341,7 +1341,7 @@ func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) { image := d.defaultBootImage if image != nil { - if profileInstallInfo, ok := android.SingletonModuleProvider(ctx, d, profileInstallInfoProvider); ok { + if profileInstallInfo, ok := android.OtherModuleProvider(ctx, d, profileInstallInfoProvider); ok { ctx.Strict("DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED", profileInstallInfo.profileInstalls.String()) if profileInstallInfo.profileLicenseMetadataFile.Valid() { ctx.Strict("DEXPREOPT_IMAGE_PROFILE_LICENSE_METADATA", profileInstallInfo.profileLicenseMetadataFile.String()) diff --git a/java/dexpreopt_config_testing.go b/java/dexpreopt_config_testing.go index 104829f5f..37c54b915 100644 --- a/java/dexpreopt_config_testing.go +++ b/java/dexpreopt_config_testing.go @@ -1237,7 +1237,7 @@ func nestedCheckBootImageConfig(t *testing.T, result *android.TestResult, imageC if !mutated { dexBootJarModule := result.ModuleForTests("dex_bootjars", "android_common") - profileInstallInfo, _ := android.SingletonModuleProvider(result, dexBootJarModule.Module(), profileInstallInfoProvider) + profileInstallInfo, _ := android.OtherModuleProvider(result, dexBootJarModule.Module(), profileInstallInfoProvider) assertInstallsEqual(t, "profileInstalls", expected.profileInstalls, profileInstallInfo.profileInstalls) android.AssertStringEquals(t, "profileLicenseMetadataFile", expected.profileLicenseMetadataFile, profileInstallInfo.profileLicenseMetadataFile.RelativeToTop().String()) } diff --git a/java/java_test.go b/java/java_test.go index 86bfe9fe4..477a0b385 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -1100,7 +1100,7 @@ func TestJavaImport(t *testing.T) { source := ctx.ModuleForTests("source_library", "android_common") sourceJar := source.Output("javac/source_library.jar") sourceHeaderJar := source.Output("turbine-combined/source_library.jar") - sourceJavaInfo, _ := android.SingletonModuleProvider(ctx, source.Module(), JavaInfoProvider) + sourceJavaInfo, _ := android.OtherModuleProvider(ctx, source.Module(), JavaInfoProvider) // The source library produces separate implementation and header jars android.AssertPathsRelativeToTopEquals(t, "source library implementation jar", @@ -1110,7 +1110,7 @@ func TestJavaImport(t *testing.T) { importWithNoDeps := ctx.ModuleForTests("import_with_no_deps", "android_common") importWithNoDepsJar := importWithNoDeps.Output("combined/import_with_no_deps.jar") - importWithNoDepsJavaInfo, _ := android.SingletonModuleProvider(ctx, importWithNoDeps.Module(), JavaInfoProvider) + importWithNoDepsJavaInfo, _ := android.OtherModuleProvider(ctx, importWithNoDeps.Module(), JavaInfoProvider) // An import with no deps produces a single jar used as both the header and implementation jar. android.AssertPathsRelativeToTopEquals(t, "import with no deps implementation jar", @@ -1123,7 +1123,7 @@ func TestJavaImport(t *testing.T) { importWithSourceDeps := ctx.ModuleForTests("import_with_source_deps", "android_common") importWithSourceDepsJar := importWithSourceDeps.Output("combined/import_with_source_deps.jar") importWithSourceDepsHeaderJar := importWithSourceDeps.Output("turbine-combined/import_with_source_deps.jar") - importWithSourceDepsJavaInfo, _ := android.SingletonModuleProvider(ctx, importWithSourceDeps.Module(), JavaInfoProvider) + importWithSourceDepsJavaInfo, _ := android.OtherModuleProvider(ctx, importWithSourceDeps.Module(), JavaInfoProvider) // An import with source deps produces separate header and implementation jars. android.AssertPathsRelativeToTopEquals(t, "import with source deps implementation jar", @@ -1137,7 +1137,7 @@ func TestJavaImport(t *testing.T) { importWithImportDeps := ctx.ModuleForTests("import_with_import_deps", "android_common") importWithImportDepsJar := importWithImportDeps.Output("combined/import_with_import_deps.jar") - importWithImportDepsJavaInfo, _ := android.SingletonModuleProvider(ctx, importWithImportDeps.Module(), JavaInfoProvider) + importWithImportDepsJavaInfo, _ := android.OtherModuleProvider(ctx, importWithImportDeps.Module(), JavaInfoProvider) // An import with only import deps produces a single jar used as both the header and implementation jar. android.AssertPathsRelativeToTopEquals(t, "import with import deps implementation jar", @@ -2274,7 +2274,7 @@ func TestTransitiveSrcFiles(t *testing.T) { } `) c := ctx.ModuleForTests("c", "android_common").Module() - javaInfo, _ := android.SingletonModuleProvider(ctx, c, JavaInfoProvider) + 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()) } diff --git a/java/jdeps.go b/java/jdeps.go index 340026318..e856b37ee 100644 --- a/java/jdeps.go +++ b/java/jdeps.go @@ -89,7 +89,7 @@ func (j *jdepsGeneratorSingleton) GenerateBuildActions(ctx android.SingletonCont dpInfo.Classes = append(dpInfo.Classes, data.Class) } - if dep, ok := android.SingletonModuleProvider(ctx, module, JavaInfoProvider); ok { + if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { dpInfo.Installed_paths = append(dpInfo.Installed_paths, dep.ImplementationJars.Strings()...) } dpInfo.Classes = android.FirstUniqueStrings(dpInfo.Classes) diff --git a/java/jdeps_test.go b/java/jdeps_test.go index 47bfac16c..ff54da92a 100644 --- a/java/jdeps_test.go +++ b/java/jdeps_test.go @@ -91,16 +91,23 @@ func TestCollectJavaLibraryPropertiesAddAidlIncludeDirs(t *testing.T) { } } -func TestCollectJavaLibraryPropertiesAddJarjarRules(t *testing.T) { - expected := "Jarjar_rules.txt" - module := LibraryFactory().(*Library) - module.expandJarjarRules = android.PathForTesting(expected) +func TestCollectJavaLibraryWithJarJarRules(t *testing.T) { + ctx, _ := testJava(t, + ` + java_library { + name: "javalib", + srcs: ["foo.java"], + jarjar_rules: "jarjar_rules.txt", + } + `) + module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library) dpInfo := &android.IdeInfo{} module.IDEInfo(dpInfo) - - if dpInfo.Jarjar_rules[0] != expected { - t.Errorf("Library.IDEInfo() Jarjar_rules = %v, want %v", dpInfo.Jarjar_rules[0], expected) + android.AssertBoolEquals(t, "IdeInfo.Srcs of repackaged library should be empty", true, len(dpInfo.Srcs) == 0) + android.AssertStringEquals(t, "IdeInfo.Jar_rules of repackaged library should not be empty", "jarjar_rules.txt", dpInfo.Jarjar_rules[0]) + if !android.SubstringInList(dpInfo.Jars, "soong/.intermediates/javalib/android_common/jarjar/turbine/javalib.jar") { + t.Errorf("IdeInfo.Jars of repackaged library should contain the output of jarjar-ing. All outputs: %v\n", dpInfo.Jars) } } diff --git a/java/lint.go b/java/lint.go index 2eea07d31..6782adc5f 100644 --- a/java/lint.go +++ b/java/lint.go @@ -650,7 +650,7 @@ func (l *lintSingleton) generateLintReportZips(ctx android.SingletonContext) { } if apex, ok := m.(android.ApexModule); ok && apex.NotAvailableForPlatform() { - apexInfo, _ := android.SingletonModuleProvider(ctx, m, android.ApexInfoProvider) + apexInfo, _ := android.OtherModuleProvider(ctx, m, android.ApexInfoProvider) if apexInfo.IsForPlatform() { // There are stray platform variants of modules in apexes that are not available for // the platform, and they sometimes can't be built. Don't depend on them. diff --git a/java/ravenwood.go b/java/ravenwood.go index a52f4053f..bb136cf6e 100644 --- a/java/ravenwood.go +++ b/java/ravenwood.go @@ -143,6 +143,9 @@ func (r *ravenwoodTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { HostTemplate: "${RavenwoodTestConfigTemplate}", }) + // Always enable Ravenizer for ravenwood tests. + r.Library.ravenizer.enabled = true + r.Library.GenerateAndroidBuildActions(ctx) // Start by depending on all files installed by dependencies @@ -152,7 +155,8 @@ func (r *ravenwoodTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { var runtimeJniModuleNames map[string]bool if utils := ctx.GetDirectDepsWithTag(ravenwoodUtilsTag)[0]; utils != nil { - for _, installFile := range utils.FilesToInstall() { + for _, installFile := range android.OtherModuleProviderOrDefault( + ctx, utils, android.InstallFilesProvider).InstallFiles { installDeps = append(installDeps, installFile) } jniDeps, ok := android.OtherModuleProvider(ctx, utils, ravenwoodLibgroupJniDepProvider) @@ -162,7 +166,8 @@ func (r *ravenwoodTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { } if runtime := ctx.GetDirectDepsWithTag(ravenwoodRuntimeTag)[0]; runtime != nil { - for _, installFile := range runtime.FilesToInstall() { + for _, installFile := range android.OtherModuleProviderOrDefault( + ctx, runtime, android.InstallFilesProvider).InstallFiles { installDeps = append(installDeps, installFile) } jniDeps, ok := android.OtherModuleProvider(ctx, runtime, ravenwoodLibgroupJniDepProvider) @@ -191,7 +196,8 @@ func (r *ravenwoodTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { resApkInstallPath := installPath.Join(ctx, "ravenwood-res-apks") if resApk := ctx.GetDirectDepsWithTag(ravenwoodTestResourceApkTag); len(resApk) > 0 { - for _, installFile := range resApk[0].FilesToInstall() { + for _, installFile := range android.OtherModuleProviderOrDefault( + ctx, resApk[0], android.InstallFilesProvider).InstallFiles { installResApk := ctx.InstallFile(resApkInstallPath, "ravenwood-res.apk", installFile) installDeps = append(installDeps, installResApk) } diff --git a/java/sdk.go b/java/sdk.go index 4ef4ee251..dd198ac57 100644 --- a/java/sdk.go +++ b/java/sdk.go @@ -278,7 +278,7 @@ func createFrameworkAidl(stubsModules []string, path android.WritablePath, ctx a ctx.VisitAllModules(func(module android.Module) { // Collect dex jar paths for the modules listed above. - if j, ok := android.SingletonModuleProvider(ctx, module, JavaInfoProvider); ok { + if j, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { name := ctx.ModuleName(module) if i := android.IndexList(name, stubsModules); i != -1 { stubsJars[i] = j.HeaderJars diff --git a/java/sdk_library.go b/java/sdk_library.go index a8cc1b81f..4f95a997d 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -3602,3 +3602,19 @@ func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberCo propertySet.AddProperty("doctag_files", dests) } } + +// TODO(b/358613520): This can be removed when modules are no longer allowed to depend on the top-level library. +func (s *SdkLibrary) IDEInfo(dpInfo *android.IdeInfo) { + s.Library.IDEInfo(dpInfo) + if s.implLibraryModule != nil { + dpInfo.Deps = append(dpInfo.Deps, s.implLibraryModule.Name()) + } else { + // This java_sdk_library does not have an implementation (it sets `api_only` to true). + // Examples of this are `art.module.intra.core.api` (IntraCore api surface). + // Return the "public" stubs for these. + stubPaths := s.findClosestScopePath(apiScopePublic) + if len(stubPaths.stubsHeaderPath) > 0 { + dpInfo.Jars = append(dpInfo.Jars, stubPaths.stubsHeaderPath[0].String()) + } + } +} diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go index 368eca7f2..52d4af0fd 100644 --- a/java/sdk_library_test.go +++ b/java/sdk_library_test.go @@ -130,7 +130,7 @@ func TestJavaSdkLibrary(t *testing.T) { result.ModuleForTests("foo.api.system.28", "") result.ModuleForTests("foo.api.test.28", "") - exportedComponentsInfo, _ := android.SingletonModuleProvider(result, foo.Module(), android.ExportedComponentsInfoProvider) + exportedComponentsInfo, _ := android.OtherModuleProvider(result, foo.Module(), android.ExportedComponentsInfoProvider) expectedFooExportedComponents := []string{ "foo-removed.api.combined.public.latest", "foo-removed.api.combined.system.latest", diff --git a/java/system_modules_test.go b/java/system_modules_test.go index 1a8d0b5d5..b05b0e497 100644 --- a/java/system_modules_test.go +++ b/java/system_modules_test.go @@ -25,7 +25,7 @@ func getModuleHeaderJarsAsRelativeToTopPaths(result *android.TestResult, moduleN paths := []string{} for _, moduleName := range moduleNames { module := result.Module(moduleName, "android_common") - info, _ := android.SingletonModuleProvider(result, module, JavaInfoProvider) + info, _ := android.OtherModuleProvider(result, module, JavaInfoProvider) paths = append(paths, info.HeaderJars.RelativeToTop().Strings()...) } return paths diff --git a/java/test_spec_test.go b/java/test_spec_test.go index 4144dad69..f0a5fdb4b 100644 --- a/java/test_spec_test.go +++ b/java/test_spec_test.go @@ -32,7 +32,7 @@ func TestTestSpec(t *testing.T) { module := result.ModuleForTests("module-name", "") // Check that the provider has the right contents - data, _ := android.SingletonModuleProvider(result, module.Module(), soongTesting.TestSpecProviderKey) + data, _ := android.OtherModuleProvider(result, module.Module(), soongTesting.TestSpecProviderKey) if !strings.HasSuffix( data.IntermediatePath.String(), "/intermediateTestSpecMetadata.pb", ) { diff --git a/java/testing.go b/java/testing.go index a99baf8a2..e1bf5376e 100644 --- a/java/testing.go +++ b/java/testing.go @@ -632,7 +632,7 @@ func CheckPlatformBootclasspathModules(t *testing.T, result *android.TestResult, func CheckClasspathFragmentProtoContentInfoProvider(t *testing.T, result *android.TestResult, generated bool, contents, outputFilename, installDir string) { t.Helper() p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule) - info, _ := android.SingletonModuleProvider(result, p, ClasspathFragmentProtoContentInfoProvider) + info, _ := android.OtherModuleProvider(result, p, ClasspathFragmentProtoContentInfoProvider) android.AssertBoolEquals(t, "classpath proto generated", generated, info.ClasspathFragmentProtoGenerated) android.AssertStringEquals(t, "classpath proto contents", contents, info.ClasspathFragmentProtoContents.String()) @@ -652,7 +652,7 @@ func ApexNamePairsFromModules(ctx *android.TestContext, modules []android.Module func apexNamePairFromModule(ctx *android.TestContext, module android.Module) string { name := module.Name() var apex string - apexInfo, _ := android.SingletonModuleProvider(ctx, module, android.ApexInfoProvider) + apexInfo, _ := android.OtherModuleProvider(ctx, module, android.ApexInfoProvider) if apexInfo.IsForPlatform() { apex = "platform" } else { diff --git a/kernel/prebuilt_kernel_modules_test.go b/kernel/prebuilt_kernel_modules_test.go index 90b98868e..7b818695b 100644 --- a/kernel/prebuilt_kernel_modules_test.go +++ b/kernel/prebuilt_kernel_modules_test.go @@ -49,7 +49,8 @@ func TestKernelModulesFilelist(t *testing.T) { } var actual []string - for _, ps := range ctx.ModuleForTests("foo", "android_arm64_armv8-a").Module().PackagingSpecs() { + for _, ps := range android.OtherModuleProviderOrDefault( + ctx, ctx.ModuleForTests("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 87c081431..533ec6258 100644 --- a/linkerconfig/linkerconfig.go +++ b/linkerconfig/linkerconfig.go @@ -105,7 +105,8 @@ func BuildLinkerConfig(ctx android.ModuleContext, builder *android.RuleBuilder, var provideLibs []string for _, m := range provideModules { if c, ok := m.(*cc.Module); ok && (cc.IsStubTarget(c) || c.HasLlndkStubs()) { - for _, ps := range c.PackagingSpecs() { + for _, ps := range android.OtherModuleProviderOrDefault( + ctx, c, android.InstallFilesProvider).PackagingSpecs { provideLibs = append(provideLibs, ps.FileName()) } } diff --git a/scripts/gen_build_prop.py b/scripts/gen_build_prop.py index 2bd246dc7..c08a3fd42 100644 --- a/scripts/gen_build_prop.py +++ b/scripts/gen_build_prop.py @@ -472,6 +472,8 @@ def append_additional_product_props(args): # Add the 16K developer args if it is defined for the product. props.append(f"ro.product.build.16k_page.enabled={'true' if config['Product16KDeveloperOption'] else 'false'}") + props.append(f"ro.product.page_size={16384 if config['TargetBoots16K'] else 4096}") + props.append(f"ro.build.characteristics={config['AAPTCharacteristics']}") if "AbOtaUpdater" in config and config["AbOtaUpdater"]: @@ -537,6 +539,7 @@ def build_vendor_prop(args): ] build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables) +''' def build_product_prop(args): config = args.config @@ -547,8 +550,32 @@ def build_product_prop(args): "ADDITIONAL_PRODUCT_PROPERTIES", "PRODUCT_PRODUCT_PROPERTIES", ] + + gen_common_build_props = True + + # Skip common /product properties generation if device released before R and + # has no product partition. This is the first part of the check. + if config["Shipping_api_level"] and int(config["Shipping_api_level"]) < 30: + gen_common_build_props = False + + # The second part of the check - always generate common properties for the + # devices with product partition regardless of shipping level. + if config["UsesProductImage"]: + gen_common_build_props = True + + build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables) + + if config["OemProperties"]: + print("####################################") + print("# PRODUCT_OEM_PROPERTIES") + print("####################################") + + for prop in config["OemProperties"]: + print(f"import /oem/oem.prop {prop}") + +def build_odm_prop(args): + variables = ["ADDITIONAL_ODM_PROPERTIES", "PRODUCT_ODM_PROPERTIES"] build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables) -''' def build_prop(args, gen_build_info, gen_common_build_props, variables): config = args.config @@ -570,18 +597,19 @@ def main(): args = parse_args() with contextlib.redirect_stdout(args.out): - if args.partition == "system": - build_system_prop(args) - elif args.partition == "system_ext": - build_system_ext_prop(args) - ''' - elif args.partition == "vendor": - build_vendor_prop(args) - elif args.partition == "product": - build_product_prop(args) - ''' - else: - sys.exit(f"not supported partition {args.partition}") + match args.partition: + case "system": + build_system_prop(args) + case "system_ext": + build_system_ext_prop(args) + case "odm": + build_odm_prop(args) + case "product": + build_product_prop(args) + # case "vendor": # NOT IMPLEMENTED + # build_vendor_prop(args) + case _: + sys.exit(f"not supported partition {args.partition}") if __name__ == "__main__": main() diff --git a/snapshot/Android.bp b/snapshot/Android.bp index c384f8a26..ae1869a26 100644 --- a/snapshot/Android.bp +++ b/snapshot/Android.bp @@ -14,12 +14,8 @@ bootstrap_go_package { // Source file name convention is to include _snapshot as a // file suffix for files that are generating snapshots. srcs: [ - "host_snapshot.go", "snapshot_base.go", "util.go", ], - testSrcs: [ - "host_test.go", - ], pluginFor: ["soong_build"], } diff --git a/snapshot/host_snapshot.go b/snapshot/host_snapshot.go deleted file mode 100644 index 1ecab7ddc..000000000 --- a/snapshot/host_snapshot.go +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright 2021 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package snapshot - -import ( - "encoding/json" - "fmt" - "path/filepath" - "sort" - "strings" - - "github.com/google/blueprint" - "github.com/google/blueprint/proptools" - - "android/soong/android" -) - -// -// The host_snapshot module creates a snapshot of the modules defined in -// the deps property. The modules within the deps property (host tools) -// are ones that return a valid path via HostToolPath() of the -// HostToolProvider. The created snapshot contains the binaries and any -// transitive PackagingSpecs of the included host tools, along with a JSON -// meta file. -// -// The snapshot is installed into a source tree via -// development/vendor_snapshot/update.py, the included modules are -// provided as preferred prebuilts. -// -// To determine which tools to include in the host snapshot see -// host_fake_snapshot.go. - -func init() { - registerHostBuildComponents(android.InitRegistrationContext) -} - -func registerHostBuildComponents(ctx android.RegistrationContext) { - ctx.RegisterModuleType("host_snapshot", hostSnapshotFactory) -} - -// Relative installation path -type RelativeInstallPath interface { - RelativeInstallPath() string -} - -type hostSnapshot struct { - android.ModuleBase - android.PackagingBase - - outputFile android.OutputPath - installDir android.InstallPath -} - -type ProcMacro interface { - ProcMacro() bool - CrateName() string -} - -func hostSnapshotFactory() android.Module { - module := &hostSnapshot{} - initHostToolsModule(module) - return module -} -func initHostToolsModule(module *hostSnapshot) { - android.InitPackageModule(module) - android.InitAndroidMultiTargetsArchModule(module, android.HostSupported, android.MultilibCommon) -} - -var dependencyTag = struct { - blueprint.BaseDependencyTag - android.InstallAlwaysNeededDependencyTag - android.PackagingItemAlwaysDepTag -}{} - -func (f *hostSnapshot) DepsMutator(ctx android.BottomUpMutatorContext) { - f.AddDeps(ctx, dependencyTag) -} -func (f *hostSnapshot) installFileName() string { - return f.Name() + ".zip" -} - -// Create zipfile with JSON description, notice files... for dependent modules -func (f *hostSnapshot) CreateMetaData(ctx android.ModuleContext, fileName string) android.OutputPath { - var jsonData []SnapshotJsonFlags - var metaPaths android.Paths - - installedNotices := make(map[string]bool) - metaZipFile := android.PathForModuleOut(ctx, fileName).OutputPath - - // Create JSON file based on the direct dependencies - ctx.VisitDirectDeps(func(dep android.Module) { - desc := hostJsonDesc(ctx, dep) - if desc != nil { - jsonData = append(jsonData, *desc) - } - for _, notice := range dep.EffectiveLicenseFiles() { - if _, ok := installedNotices[notice.String()]; !ok { - installedNotices[notice.String()] = true - noticeOut := android.PathForModuleOut(ctx, "NOTICE_FILES", notice.String()).OutputPath - CopyFileToOutputPathRule(pctx, ctx, notice, noticeOut) - metaPaths = append(metaPaths, noticeOut) - } - } - }) - // Sort notice paths and json data for repeatble build - sort.Slice(jsonData, func(i, j int) bool { - return (jsonData[i].ModuleName < jsonData[j].ModuleName) - }) - sort.Slice(metaPaths, func(i, j int) bool { - return (metaPaths[i].String() < metaPaths[j].String()) - }) - - marsh, err := json.Marshal(jsonData) - if err != nil { - ctx.ModuleErrorf("host snapshot json marshal failure: %#v", err) - return android.OutputPath{} - } - - jsonZipFile := android.PathForModuleOut(ctx, "host_snapshot.json").OutputPath - metaPaths = append(metaPaths, jsonZipFile) - rspFile := android.PathForModuleOut(ctx, "host_snapshot.rsp").OutputPath - android.WriteFileRule(ctx, jsonZipFile, string(marsh)) - - builder := android.NewRuleBuilder(pctx, ctx) - - builder.Command(). - BuiltTool("soong_zip"). - FlagWithArg("-C ", android.PathForModuleOut(ctx).OutputPath.String()). - FlagWithOutput("-o ", metaZipFile). - FlagWithRspFileInputList("-r ", rspFile, metaPaths) - builder.Build("zip_meta", fmt.Sprintf("zipping meta data for %s", ctx.ModuleName())) - - return metaZipFile -} - -// Create the host tool zip file -func (f *hostSnapshot) GenerateAndroidBuildActions(ctx android.ModuleContext) { - // Create a zip file for the binaries, and a zip of the meta data, then merge zips - depsZipFile := android.PathForModuleOut(ctx, f.Name()+"_deps.zip").OutputPath - modsZipFile := android.PathForModuleOut(ctx, f.Name()+"_mods.zip").OutputPath - f.outputFile = android.PathForModuleOut(ctx, f.installFileName()).OutputPath - - f.installDir = android.PathForModuleInstall(ctx) - - f.CopyDepsToZip(ctx, f.GatherPackagingSpecs(ctx), depsZipFile) - - builder := android.NewRuleBuilder(pctx, ctx) - builder.Command(). - BuiltTool("zip2zip"). - FlagWithInput("-i ", depsZipFile). - FlagWithOutput("-o ", modsZipFile). - Text("**/*:" + proptools.ShellEscape(f.installDir.String())) - - metaZipFile := f.CreateMetaData(ctx, f.Name()+"_meta.zip") - - builder.Command(). - BuiltTool("merge_zips"). - Output(f.outputFile). - Input(metaZipFile). - Input(modsZipFile) - - builder.Build("manifest", fmt.Sprintf("Adding manifest %s", f.installFileName())) - ctx.InstallFile(f.installDir, f.installFileName(), f.outputFile) - -} - -// Implements android.AndroidMkEntriesProvider -func (f *hostSnapshot) AndroidMkEntries() []android.AndroidMkEntries { - return []android.AndroidMkEntries{android.AndroidMkEntries{ - Class: "ETC", - OutputFile: android.OptionalPathForPath(f.outputFile), - DistFiles: android.MakeDefaultDistFiles(f.outputFile), - ExtraEntries: []android.AndroidMkExtraEntriesFunc{ - func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { - entries.SetString("LOCAL_MODULE_PATH", f.installDir.String()) - entries.SetString("LOCAL_INSTALLED_MODULE_STEM", f.installFileName()) - }, - }, - }} -} - -// Get host tools path and relative install string helpers -func hostToolPath(m android.Module) android.OptionalPath { - if provider, ok := m.(android.HostToolProvider); ok { - return provider.HostToolPath() - } - return android.OptionalPath{} - -} -func hostRelativePathString(m android.Module) string { - var outString string - if rel, ok := m.(RelativeInstallPath); ok { - outString = rel.RelativeInstallPath() - } - return outString -} - -// Create JSON description for given module, only create descriptions for binary modules -// and rust_proc_macro modules which provide a valid HostToolPath -func hostJsonDesc(ctx android.ConfigAndErrorContext, m android.Module) *SnapshotJsonFlags { - path := hostToolPath(m) - relPath := hostRelativePathString(m) - procMacro := false - moduleStem := filepath.Base(path.String()) - crateName := "" - - if pm, ok := m.(ProcMacro); ok && pm.ProcMacro() { - procMacro = pm.ProcMacro() - moduleStem = strings.TrimSuffix(moduleStem, filepath.Ext(moduleStem)) - crateName = pm.CrateName() - } - - if path.Valid() && path.String() != "" { - props := &SnapshotJsonFlags{ - ModuleStemName: moduleStem, - Filename: path.String(), - Required: append(m.HostRequiredModuleNames(), m.RequiredModuleNames(ctx)...), - RelativeInstallPath: relPath, - RustProcMacro: procMacro, - CrateName: crateName, - } - props.InitBaseSnapshotProps(m) - return props - } - return nil -} diff --git a/snapshot/host_test.go b/snapshot/host_test.go deleted file mode 100644 index c68fdaf88..000000000 --- a/snapshot/host_test.go +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2021 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package snapshot - -import ( - "path/filepath" - "testing" - - "android/soong/android" -) - -// host_snapshot and host-fake-snapshot test functions - -type hostTestModule struct { - android.ModuleBase - props struct { - Deps []string - } -} - -func hostTestBinOut(bin string) string { - return filepath.Join("out", "bin", bin) -} - -func (c *hostTestModule) HostToolPath() android.OptionalPath { - return (android.OptionalPathForPath(android.PathForTesting(hostTestBinOut(c.Name())))) -} - -func hostTestModuleFactory() android.Module { - m := &hostTestModule{} - m.AddProperties(&m.props) - android.InitAndroidArchModule(m, android.HostSupported, android.MultilibFirst) - return m -} -func (m *hostTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { - builtFile := android.PathForModuleOut(ctx, m.Name()) - dir := ctx.Target().Arch.ArchType.Multilib - installDir := android.PathForModuleInstall(ctx, dir) - ctx.InstallFile(installDir, m.Name(), builtFile) -} - -// Common blueprint used for testing -var hostTestBp = ` - license_kind { - name: "test_notice", - conditions: ["notice"], - } - license { - name: "host_test_license", - visibility: ["//visibility:public"], - license_kinds: [ - "test_notice" - ], - license_text: [ - "NOTICE", - ], - } - component { - name: "foo", - deps: ["bar"], - } - component { - name: "bar", - licenses: ["host_test_license"], - } - ` - -var hostTestModBp = ` - host_snapshot { - name: "test-host-snapshot", - deps: [ - "foo", - ], - } - ` - -var prepareForHostTest = android.GroupFixturePreparers( - android.PrepareForTestWithAndroidBuildComponents, - android.PrepareForTestWithLicenses, - android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { - ctx.RegisterModuleType("component", hostTestModuleFactory) - }), -) - -// Prepare for host_snapshot test -var prepareForHostModTest = android.GroupFixturePreparers( - prepareForHostTest, - android.FixtureWithRootAndroidBp(hostTestBp+hostTestModBp), - android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { - registerHostBuildComponents(ctx) - }), -) - -// Prepare for fake host snapshot test disabled -var prepareForFakeHostTest = android.GroupFixturePreparers( - prepareForHostTest, - android.FixtureWithRootAndroidBp(hostTestBp), -) - -// Validate that a hostSnapshot object is created containing zip files and JSON file -// content of zip file is not validated as this is done by PackagingSpecs -func TestHostSnapshot(t *testing.T) { - result := prepareForHostModTest.RunTest(t) - t.Helper() - ctx := result.TestContext.ModuleForTests("test-host-snapshot", result.Config.BuildOS.String()+"_common") - mod := ctx.Module().(*hostSnapshot) - if ctx.MaybeOutput("host_snapshot.json").Rule == nil { - t.Error("Manifest file not found") - } - zips := []string{"_deps.zip", "_mods.zip", ".zip"} - - for _, zip := range zips { - zFile := mod.Name() + zip - if ctx.MaybeOutput(zFile).Rule == nil { - t.Error("Zip file ", zFile, "not found") - } - - } -} diff --git a/testing/all_code_metadata.go b/testing/all_code_metadata.go index 12aa7b51f..e89b28155 100644 --- a/testing/all_code_metadata.go +++ b/testing/all_code_metadata.go @@ -21,7 +21,7 @@ func (this *allCodeMetadataSingleton) GenerateBuildActions(ctx android.Singleton ctx.VisitAllModules( func(module android.Module) { - if metadata, ok := android.SingletonModuleProvider(ctx, module, CodeMetadataProviderKey); ok { + if metadata, ok := android.OtherModuleProvider(ctx, module, CodeMetadataProviderKey); ok { intermediateMetadataPaths = append(intermediateMetadataPaths, metadata.IntermediatePath) } }, diff --git a/testing/all_test_specs.go b/testing/all_test_specs.go index b035435db..68f24d15c 100644 --- a/testing/all_test_specs.go +++ b/testing/all_test_specs.go @@ -21,7 +21,7 @@ func (this *allTestSpecsSingleton) GenerateBuildActions(ctx android.SingletonCon var intermediateMetadataPaths android.Paths ctx.VisitAllModules(func(module android.Module) { - if metadata, ok := android.SingletonModuleProvider(ctx, module, TestSpecProviderKey); ok { + if metadata, ok := android.OtherModuleProvider(ctx, module, TestSpecProviderKey); ok { intermediateMetadataPaths = append(intermediateMetadataPaths, metadata.IntermediatePath) } }) diff --git a/ui/build/ninja.go b/ui/build/ninja.go index b5e74b422..8ca62d3f1 100644 --- a/ui/build/ninja.go +++ b/ui/build/ninja.go @@ -229,6 +229,7 @@ func runNinjaForBuild(ctx Context, config Config) { "BUILD_BROKEN_INCORRECT_PARTITION_IMAGES", "SOONG_USE_N2", "RUST_BACKTRACE", + "RUST_LOG", }, config.BuildBrokenNinjaUsesEnvVars()...)...) } diff --git a/ui/build/sandbox_linux.go b/ui/build/sandbox_linux.go index c38174c69..d9ca85417 100644 --- a/ui/build/sandbox_linux.go +++ b/ui/build/sandbox_linux.go @@ -51,7 +51,6 @@ var ( const ( nsjailPath = "prebuilts/build-tools/linux-x86/bin/nsjail" abfsSrcDir = "/src" - abfsOutDir = "/src/out" ) var sandboxConfig struct { @@ -162,13 +161,37 @@ func (c *Cmd) outDirArg() string { return sandboxConfig.outDir } - return sandboxConfig.outDir + ":" + abfsOutDir + return sandboxConfig.outDir + ":" + filepath.Join(abfsSrcDir, sandboxConfig.outDir) +} + +// When configured to use ABFS, we need to allow the creation of the /src +// directory. Therefore, we cannot mount the root "/" directory as read-only. +// Instead, we individually mount the children of "/" as RO. +func (c *Cmd) readMountArgs() []string { + if !c.config.UseABFS() { + // For now, just map everything. Make most things readonly. + return []string{"-R", "/"} + } + + entries, err := os.ReadDir("/") + if err != nil { + // If we can't read "/", just use the default non-ABFS behavior. + return []string{"-R", "/"} + } + + args := make([]string, 0, 2*len(entries)) + for _, ent := range entries { + args = append(args, "-R", "/"+ent.Name()) + } + + return args } func (c *Cmd) wrapSandbox() { wd, _ := os.Getwd() - sandboxArgs := []string{ + var sandboxArgs []string + sandboxArgs = append(sandboxArgs, // The executable to run "-x", c.Path, @@ -200,10 +223,13 @@ func (c *Cmd) wrapSandbox() { "--rlimit_cpu", "soft", "--rlimit_fsize", "soft", "--rlimit_nofile", "soft", + ) - // For now, just map everything. Make most things readonly. - "-R", "/", + sandboxArgs = append(sandboxArgs, + c.readMountArgs()... + ) + sandboxArgs = append(sandboxArgs, // Mount a writable tmp dir "-B", "/tmp", @@ -219,7 +245,7 @@ func (c *Cmd) wrapSandbox() { // Only log important warnings / errors "-q", - } + ) if c.config.UseABFS() { sandboxArgs = append(sandboxArgs, "-B", "{ABFS_DIR}") } |