From 69454c2938ea30afbd21d86c93179a14afbeab0b Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Tue, 31 Oct 2023 19:25:45 +0000 Subject: [PATCH 01/17] Improve the docs about when to use introduced. Bug: None Test: None Change-Id: I90eeb24c0fce8f17576f6e4c98e04aa2855a4e8c --- docs/map_files.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/map_files.md b/docs/map_files.md index 35e8cbbfc..c5ccdb62d 100644 --- a/docs/map_files.md +++ b/docs/map_files.md @@ -88,12 +88,17 @@ but is useful when developing APIs for an unknown future release. ### introduced -Indicates the version in which an API was first introduced. For example, -`introduced=21` specifies that the API was first added (or first made public) in -API level 21. This tag can be applied to either a version definition or an -individual symbol. If applied to a version, all symbols contained in the version -will have the tag applied. An `introduced` tag on a symbol overrides the value -set for the version, if both are defined. +Indicates the version in which an API was first introduced in the NDK. For +example, `introduced=21` specifies that the API was first added (or first made +public) in API level 21. This tag can be applied to either a version definition +or an individual symbol. If applied to a version, all symbols contained in the +version will have the tag applied. An `introduced` tag on a symbol overrides the +value set for the version, if both are defined. + +The `introduced` tag should only be used with NDK APIs. Other API surface tags +(such as `apex`) will override `introduced`. APIs that are in the NDK should +never use tags like `apex`, and APIs that are not in the NDK should never use +`introduced`. Note: The map file alone does not contain all the information needed to determine which API level an API was added in. The `first_version` property of From a89a58ac1c9f9c01a8e06d4d2cbc5b8bfa70ee63 Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Thu, 29 Aug 2024 13:00:33 +0900 Subject: [PATCH 02/17] Remove apex_available allowlist Bug: 147364041 Test: m nothing --no-skip-soong-tests Change-Id: I65ac605fe77a9e013a2c0b64adc36db414c77465 --- apex/apex.go | 70 +-------------------------------------------------- sdk/update.go | 4 --- 2 files changed, 1 insertion(+), 73 deletions(-) diff --git a/apex/apex.go b/apex/apex.go index d5776b5de..d4ce8a0c9 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -2819,7 +2819,7 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) { return false } - if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) { + if to.AvailableFor(apexName) { return true } @@ -2879,74 +2879,6 @@ func (a *apexBundle) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeI dpInfo.Deps = append(dpInfo.Deps, a.properties.ResolvedSystemserverclasspathFragments...) } -var ( - apexAvailBaseline = makeApexAvailableBaseline() - inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline) -) - -func baselineApexAvailable(apex, moduleName string) bool { - key := apex - moduleName = normalizeModuleName(moduleName) - - if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) { - return true - } - - key = android.AvailableToAnyApex - if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) { - return true - } - - return false -} - -func normalizeModuleName(moduleName string) string { - // Prebuilt modules (e.g. java_import, etc.) have "prebuilt_" prefix added by the build - // system. Trim the prefix for the check since they are confusing - moduleName = android.RemoveOptionalPrebuiltPrefix(moduleName) - if strings.HasPrefix(moduleName, "libclang_rt.") { - // This module has many arch variants that depend on the product being built. - // We don't want to list them all - moduleName = "libclang_rt" - } - if strings.HasPrefix(moduleName, "androidx.") { - // TODO(b/156996905) Set apex_available/min_sdk_version for androidx support libraries - moduleName = "androidx" - } - return moduleName -} - -// Transform the map of apex -> modules to module -> apexes. -func invertApexBaseline(m map[string][]string) map[string][]string { - r := make(map[string][]string) - for apex, modules := range m { - for _, module := range modules { - r[module] = append(r[module], apex) - } - } - return r -} - -// Retrieve the baseline of apexes to which the supplied module belongs. -func BaselineApexAvailable(moduleName string) []string { - return inverseApexAvailBaseline[normalizeModuleName(moduleName)] -} - -// This is a map from apex to modules, which overrides the apex_available setting for that -// particular module to make it available for the apex regardless of its setting. -// TODO(b/147364041): remove this -func makeApexAvailableBaseline() map[string][]string { - // The "Module separator"s below are employed to minimize merge conflicts. - m := make(map[string][]string) - // - // Module separator - // - m["com.android.runtime"] = []string{ - "libz", - } - return m -} - func init() { android.AddNeverAllowRules(createBcpPermittedPackagesRules(qBcpPackages())...) android.AddNeverAllowRules(createBcpPermittedPackagesRules(rBcpPackages())...) diff --git a/sdk/update.go b/sdk/update.go index a4b1967af..0a21e0c0c 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -22,7 +22,6 @@ import ( "sort" "strings" - "android/soong/apex" "android/soong/cc" "android/soong/java" @@ -1133,9 +1132,6 @@ func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType apexAvailable = []string{android.AvailableToPlatform} } - // Add in any baseline apex available settings. - apexAvailable = append(apexAvailable, apex.BaselineApexAvailable(member.Name())...) - // Remove duplicates and sort. apexAvailable = android.FirstUniqueStrings(apexAvailable) sort.Strings(apexAvailable) From 4e455c72b2170cb108dc5d98d28be60b6363898a Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Tue, 10 Sep 2024 21:34:35 +0000 Subject: [PATCH 03/17] Add myself as an owner of the map files doc. Bug: None Test: None Change-Id: I4ca8a28235295f1cf3c3a40ee1e61d9e36791bd3 --- docs/OWNERS | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/OWNERS diff --git a/docs/OWNERS b/docs/OWNERS new file mode 100644 index 000000000..776beca32 --- /dev/null +++ b/docs/OWNERS @@ -0,0 +1 @@ +per-file map_files.md = danalbert@google.com From 2cc42505d91aca2c9fc75b904eed69d7f4210af6 Mon Sep 17 00:00:00 2001 From: Justin Yun Date: Wed, 11 Sep 2024 14:10:20 +0900 Subject: [PATCH 04/17] Soong system image may update the $PRODUCT_OUT A target must define "USE_SOONG_DEFINED_SYSTEM_IMAGE := true" and "PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE := " to use the soong defined system image. The system image must install the files to $PRODUCT_OUT for adb sync and build verification. Instead of using 'update_product_out' property in Android.bp, copy the files only if the name of the image matches with PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE. Bug: 350599535 Bug: 365700376 Test: lunch aosp_x86_64-trunk_staging-userdebug && m && m aosp_cf_system_x86_64 Test: lunch aosp_cf_x86_64_phone_soong_system-trunk_staging-userdebug && m and adb sync on the cf device Change-Id: If8673ba2855a753a5559a588bd83068d950fd7e4 --- android/config.go | 11 +++++++++++ android/variable.go | 3 +++ filesystem/filesystem.go | 5 +---- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/android/config.go b/android/config.go index b682c2e93..368e57381 100644 --- a/android/config.go +++ b/android/config.go @@ -1663,6 +1663,17 @@ func (c *config) ApexTrimEnabled() bool { return Bool(c.productVariables.TrimmedApex) } +func (c *config) UseSoongSystemImage() bool { + return Bool(c.productVariables.UseSoongSystemImage) +} + +func (c *config) SoongDefinedSystemImage() string { + if c.UseSoongSystemImage() { + return String(c.productVariables.ProductSoongDefinedSystemImage) + } + return "" +} + func (c *config) EnforceSystemCertificate() bool { return Bool(c.productVariables.EnforceSystemCertificate) } diff --git a/android/variable.go b/android/variable.go index b238c4a5d..e0d512d3a 100644 --- a/android/variable.go +++ b/android/variable.go @@ -423,6 +423,9 @@ type ProductVariables struct { TargetFSConfigGen []string `json:",omitempty"` + UseSoongSystemImage *bool `json:",omitempty"` + ProductSoongDefinedSystemImage *string `json:",omitempty"` + EnforceProductPartitionInterface *bool `json:",omitempty"` EnforceInterPartitionJavaSdkLibrary *bool `json:",omitempty"` diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index a8f97e3b7..0b390624f 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -136,9 +136,6 @@ type filesystemProperties struct { // Install aconfig_flags.pb file for the modules installed in this partition. Gen_aconfig_flags_pb *bool - // Update the Base_dir of the $PRODUCT_OUT directory with the packaging files. - Update_product_out *bool - Fsverity fsverityProperties } @@ -335,7 +332,7 @@ func (f *filesystem) copyPackagingSpecs(ctx android.ModuleContext, builder *andr } func (f *filesystem) copyFilesToProductOut(ctx android.ModuleContext, builder *android.RuleBuilder, rebasedDir android.OutputPath) { - if !proptools.Bool(f.properties.Update_product_out) { + if f.Name() != ctx.Config().SoongDefinedSystemImage() { return } installPath := android.PathForModuleInPartitionInstall(ctx, f.partitionName()) From 037e1297d9752301a3cdaffbd79986b69de5a746 Mon Sep 17 00:00:00 2001 From: Charisee Date: Tue, 10 Sep 2024 23:57:30 +0000 Subject: [PATCH 05/17] rustc-1.81.0 Build 12349086 Test: m rust Change-Id: I036a8f459055343533c651f461cda1d71a921757 --- rust/config/global.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/config/global.go b/rust/config/global.go index 990a64331..68a74c204 100644 --- a/rust/config/global.go +++ b/rust/config/global.go @@ -24,7 +24,7 @@ import ( var ( pctx = android.NewPackageContext("android/soong/rust/config") - RustDefaultVersion = "1.80.1" + RustDefaultVersion = "1.81.0" RustDefaultBase = "prebuilts/rust/" DefaultEdition = "2021" Stdlibs = []string{ From 184209792871bd14d9c736f8bf6f7b77c236e450 Mon Sep 17 00:00:00 2001 From: mrziwang Date: Tue, 3 Sep 2024 15:12:51 -0700 Subject: [PATCH 06/17] Add framework for using provider on AndroidMKEntries In the context of incremental soong, the inter-module communication through AndroidMkEntries and AndroidMkData should be changed to through the real provider. This change adds the framework for the provider(AndroidMkInfoProvider). A module will set its AndroidMkInfoProvider, which includes what's in its AndroidMkEntries method, to be used in translateAndroidMkModule. This change also changes module type vbmeta to use AndroidMKInfoProvider. The next step is to replace the AndroidMkEntries methods of all the other module types to set the AndroidMkInfoProvider. Test: m with tests and CI Bug: 357907638 Change-Id: Icfd1363f97d31548bb78c6615e0f7076b22dcbe4 --- android/aconfig_providers.go | 14 + android/androidmk.go | 585 ++++++++++++++++++++++++++++++++++- filesystem/vbmeta.go | 24 +- 3 files changed, 601 insertions(+), 22 deletions(-) diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go index 6bfbf3776..cb88e011c 100644 --- a/android/aconfig_providers.go +++ b/android/aconfig_providers.go @@ -187,6 +187,20 @@ func aconfigUpdateAndroidMkEntries(ctx fillInEntriesContext, mod Module, entries } } +func aconfigUpdateAndroidMkInfos(ctx fillInEntriesContext, mod Module, infos *AndroidMkProviderInfo) { + info, ok := OtherModuleProvider(ctx, mod, AconfigPropagatingProviderKey) + if !ok || len(info.AconfigFiles) == 0 { + return + } + // All of the files in the module potentially depend on the aconfig flag values. + infos.PrimaryInfo.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths(mod.base(), info.AconfigFiles)) + if len(infos.ExtraInfo) > 0 { + for _, ei := range (*infos).ExtraInfo { + ei.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths(mod.base(), info.AconfigFiles)) + } + } +} + func mergeAconfigFiles(ctx ModuleContext, container string, inputs Paths, generateRule bool) Paths { inputs = SortedUniquePaths(inputs) if len(inputs) == 1 { diff --git a/android/androidmk.go b/android/androidmk.go index fc628cb34..2185e4579 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -806,15 +806,21 @@ func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs // Additional cases here require review for correct license propagation to make. var err error - switch x := mod.(type) { - case AndroidMkDataProvider: - err = translateAndroidModule(ctx, w, moduleInfoJSONs, mod, x) - case bootstrap.GoBinaryTool: - err = translateGoBinaryModule(ctx, w, mod, x) - case AndroidMkEntriesProvider: - err = translateAndroidMkEntriesModule(ctx, w, moduleInfoJSONs, mod, x) - default: - // Not exported to make so no make variables to set. + + if info, ok := ctx.otherModuleProvider(mod, AndroidMkInfoProvider); ok { + androidMkEntriesInfos := info.(*AndroidMkProviderInfo) + err = translateAndroidMkEntriesInfoModule(ctx, w, moduleInfoJSONs, mod, androidMkEntriesInfos) + } else { + switch x := mod.(type) { + case AndroidMkDataProvider: + err = translateAndroidModule(ctx, w, moduleInfoJSONs, mod, x) + case bootstrap.GoBinaryTool: + err = translateGoBinaryModule(ctx, w, mod, x) + case AndroidMkEntriesProvider: + err = translateAndroidMkEntriesModule(ctx, w, moduleInfoJSONs, mod, x) + default: + // Not exported to make so no make variables to set. + } } if err != nil { @@ -1063,3 +1069,564 @@ func AndroidMkEmitAssignList(w io.Writer, varName string, lists ...[]string) { } fmt.Fprintln(w) } + +type AndroidMkProviderInfo struct { + PrimaryInfo AndroidMkInfo + ExtraInfo []AndroidMkInfo +} + +type AndroidMkInfo struct { + // Android.mk class string, e.g. EXECUTABLES, JAVA_LIBRARIES, ETC + Class string + // Optional suffix to append to the module name. Useful when a module wants to return multiple + // AndroidMkEntries objects. For example, when a java_library returns an additional entry for + // its hostdex sub-module, this SubName field is set to "-hostdex" so that it can have a + // different name than the parent's. + SubName string + // If set, this value overrides the base module name. SubName is still appended. + OverrideName string + // Dist files to output + DistFiles TaggedDistFiles + // The output file for Kati to process and/or install. If absent, the module is skipped. + OutputFile OptionalPath + // If true, the module is skipped and does not appear on the final Android-.mk + // file. Useful when a module needs to be skipped conditionally. + Disabled bool + // The postprocessing mk file to include, e.g. $(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk + // If not set, $(BUILD_SYSTEM)/prebuilt.mk is used. + Include string + // Required modules that need to be built and included in the final build output when building + // this module. + Required []string + // Required host modules that need to be built and included in the final build output when + // building this module. + Host_required []string + // Required device modules that need to be built and included in the final build output when + // building this module. + Target_required []string + + HeaderStrings []string + FooterStrings []string + + // A map that holds the up-to-date Make variable values. Can be accessed from tests. + EntryMap map[string][]string + // A list of EntryMap keys in insertion order. This serves a few purposes: + // 1. Prevents churns. Golang map doesn't provide consistent iteration order, so without this, + // the outputted Android-*.mk file may change even though there have been no content changes. + // 2. Allows modules to refer to other variables, like LOCAL_BAR_VAR := $(LOCAL_FOO_VAR), + // without worrying about the variables being mixed up in the actual mk file. + // 3. Makes troubleshooting and spotting errors easier. + EntryOrder []string +} + +// TODO: rename it to AndroidMkEntriesProvider after AndroidMkEntriesProvider interface is gone. +var AndroidMkInfoProvider = blueprint.NewProvider[*AndroidMkProviderInfo]() + +func translateAndroidMkEntriesInfoModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, + mod blueprint.Module, providerInfo *AndroidMkProviderInfo) error { + if shouldSkipAndroidMkProcessing(ctx, mod.(Module).base()) { + return nil + } + + // Deep copy the provider info since we need to modify the info later + info := deepCopyAndroidMkProviderInfo(providerInfo) + + aconfigUpdateAndroidMkInfos(ctx, mod.(Module), &info) + + // Any new or special cases here need review to verify correct propagation of license information. + info.PrimaryInfo.fillInEntries(ctx, mod) + info.PrimaryInfo.write(w) + if len(info.ExtraInfo) > 0 { + for _, ei := range info.ExtraInfo { + ei.fillInEntries(ctx, mod) + ei.write(w) + } + } + + if !info.PrimaryInfo.disabled() { + if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok { + *moduleInfoJSONs = append(*moduleInfoJSONs, moduleInfoJSON) + } + } + + return nil +} + +// Utility funcs to manipulate Android.mk variable entries. + +// SetString sets a Make variable with the given name to the given value. +func (a *AndroidMkInfo) SetString(name, value string) { + if _, ok := a.EntryMap[name]; !ok { + a.EntryOrder = append(a.EntryOrder, name) + } + a.EntryMap[name] = []string{value} +} + +// SetPath sets a Make variable with the given name to the given path string. +func (a *AndroidMkInfo) SetPath(name string, path Path) { + if _, ok := a.EntryMap[name]; !ok { + a.EntryOrder = append(a.EntryOrder, name) + } + a.EntryMap[name] = []string{path.String()} +} + +// SetOptionalPath sets a Make variable with the given name to the given path string if it is valid. +// It is a no-op if the given path is invalid. +func (a *AndroidMkInfo) SetOptionalPath(name string, path OptionalPath) { + if path.Valid() { + a.SetPath(name, path.Path()) + } +} + +// AddPath appends the given path string to a Make variable with the given name. +func (a *AndroidMkInfo) AddPath(name string, path Path) { + if _, ok := a.EntryMap[name]; !ok { + a.EntryOrder = append(a.EntryOrder, name) + } + a.EntryMap[name] = append(a.EntryMap[name], path.String()) +} + +// AddOptionalPath appends the given path string to a Make variable with the given name if it is +// valid. It is a no-op if the given path is invalid. +func (a *AndroidMkInfo) AddOptionalPath(name string, path OptionalPath) { + if path.Valid() { + a.AddPath(name, path.Path()) + } +} + +// SetPaths sets a Make variable with the given name to a slice of the given path strings. +func (a *AndroidMkInfo) SetPaths(name string, paths Paths) { + if _, ok := a.EntryMap[name]; !ok { + a.EntryOrder = append(a.EntryOrder, name) + } + a.EntryMap[name] = paths.Strings() +} + +// SetOptionalPaths sets a Make variable with the given name to a slice of the given path strings +// only if there are a non-zero amount of paths. +func (a *AndroidMkInfo) SetOptionalPaths(name string, paths Paths) { + if len(paths) > 0 { + a.SetPaths(name, paths) + } +} + +// AddPaths appends the given path strings to a Make variable with the given name. +func (a *AndroidMkInfo) AddPaths(name string, paths Paths) { + if _, ok := a.EntryMap[name]; !ok { + a.EntryOrder = append(a.EntryOrder, name) + } + a.EntryMap[name] = append(a.EntryMap[name], paths.Strings()...) +} + +// SetBoolIfTrue sets a Make variable with the given name to true if the given flag is true. +// It is a no-op if the given flag is false. +func (a *AndroidMkInfo) SetBoolIfTrue(name string, flag bool) { + if flag { + if _, ok := a.EntryMap[name]; !ok { + a.EntryOrder = append(a.EntryOrder, name) + } + a.EntryMap[name] = []string{"true"} + } +} + +// SetBool sets a Make variable with the given name to if the given bool flag value. +func (a *AndroidMkInfo) SetBool(name string, flag bool) { + if _, ok := a.EntryMap[name]; !ok { + a.EntryOrder = append(a.EntryOrder, name) + } + if flag { + a.EntryMap[name] = []string{"true"} + } else { + a.EntryMap[name] = []string{"false"} + } +} + +// AddStrings appends the given strings to a Make variable with the given name. +func (a *AndroidMkInfo) AddStrings(name string, value ...string) { + if len(value) == 0 { + return + } + if _, ok := a.EntryMap[name]; !ok { + a.EntryOrder = append(a.EntryOrder, name) + } + a.EntryMap[name] = append(a.EntryMap[name], value...) +} + +// AddCompatibilityTestSuites adds the supplied test suites to the EntryMap, with special handling +// for partial MTS and MCTS test suites. +func (a *AndroidMkInfo) AddCompatibilityTestSuites(suites ...string) { + // M(C)TS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}. + // To reduce repetition, if we find a partial M(C)TS test suite without an full M(C)TS test suite, + // we add the full test suite to our list. + if PrefixInList(suites, "mts-") && !InList("mts", suites) { + suites = append(suites, "mts") + } + if PrefixInList(suites, "mcts-") && !InList("mcts", suites) { + suites = append(suites, "mcts") + } + a.AddStrings("LOCAL_COMPATIBILITY_SUITE", suites...) +} + +func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) { + helperInfo := AndroidMkInfo{ + EntryMap: make(map[string][]string), + } + + amod := mod.(Module) + base := amod.base() + name := base.BaseModuleName() + if a.OverrideName != "" { + name = a.OverrideName + } + + if a.Include == "" { + a.Include = "$(BUILD_PREBUILT)" + } + a.Required = append(a.Required, amod.RequiredModuleNames(ctx)...) + a.Required = append(a.Required, amod.VintfFragmentModuleNames(ctx)...) + a.Host_required = append(a.Host_required, amod.HostRequiredModuleNames()...) + a.Target_required = append(a.Target_required, amod.TargetRequiredModuleNames()...) + + for _, distString := range a.GetDistForGoals(ctx, mod) { + a.HeaderStrings = append(a.HeaderStrings, distString) + } + + a.HeaderStrings = append(a.HeaderStrings, fmt.Sprintf("\ninclude $(CLEAR_VARS) # type: %s, name: %s, variant: %s\n", ctx.ModuleType(mod), base.BaseModuleName(), ctx.ModuleSubDir(mod))) + + // Collect make variable assignment entries. + helperInfo.SetString("LOCAL_PATH", ctx.ModuleDir(mod)) + helperInfo.SetString("LOCAL_MODULE", name+a.SubName) + helperInfo.SetString("LOCAL_MODULE_CLASS", a.Class) + helperInfo.SetString("LOCAL_PREBUILT_MODULE_FILE", a.OutputFile.String()) + helperInfo.AddStrings("LOCAL_REQUIRED_MODULES", a.Required...) + helperInfo.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...) + helperInfo.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...) + helperInfo.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(amod)) + + // If the install rule was generated by Soong tell Make about it. + 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. + helperInfo.SetPath("LOCAL_SOONG_INSTALLED_MODULE", info.KatiInstalls[len(info.KatiInstalls)-1].to) + helperInfo.SetString("LOCAL_SOONG_INSTALL_PAIRS", info.KatiInstalls.BuiltInstalled()) + helperInfo.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 + // install rule there. + helperInfo.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", proptools.Bool(base.commonProperties.No_full_install)) + } + + if len(info.TestData) > 0 { + helperInfo.AddStrings("LOCAL_TEST_DATA", androidMkDataPaths(info.TestData)...) + } + + if am, ok := mod.(ApexModule); ok { + helperInfo.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", am.NotAvailableForPlatform()) + } + + archStr := base.Arch().ArchType.String() + host := false + switch base.Os().Class { + case Host: + if base.Target().HostCross { + // Make cannot identify LOCAL_MODULE_HOST_CROSS_ARCH:= common. + if base.Arch().ArchType != Common { + helperInfo.SetString("LOCAL_MODULE_HOST_CROSS_ARCH", archStr) + } + } else { + // Make cannot identify LOCAL_MODULE_HOST_ARCH:= common. + if base.Arch().ArchType != Common { + helperInfo.SetString("LOCAL_MODULE_HOST_ARCH", archStr) + } + } + host = true + case Device: + // Make cannot identify LOCAL_MODULE_TARGET_ARCH:= common. + if base.Arch().ArchType != Common { + if base.Target().NativeBridge { + hostArchStr := base.Target().NativeBridgeHostArchName + if hostArchStr != "" { + helperInfo.SetString("LOCAL_MODULE_TARGET_ARCH", hostArchStr) + } + } else { + helperInfo.SetString("LOCAL_MODULE_TARGET_ARCH", archStr) + } + } + + if !base.InVendorRamdisk() { + helperInfo.AddPaths("LOCAL_FULL_INIT_RC", info.InitRcPaths) + } + if len(info.VintfFragmentsPaths) > 0 { + helperInfo.AddPaths("LOCAL_FULL_VINTF_FRAGMENTS", info.VintfFragmentsPaths) + } + helperInfo.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", Bool(base.commonProperties.Proprietary)) + if Bool(base.commonProperties.Vendor) || Bool(base.commonProperties.Soc_specific) { + helperInfo.SetString("LOCAL_VENDOR_MODULE", "true") + } + helperInfo.SetBoolIfTrue("LOCAL_ODM_MODULE", Bool(base.commonProperties.Device_specific)) + helperInfo.SetBoolIfTrue("LOCAL_PRODUCT_MODULE", Bool(base.commonProperties.Product_specific)) + helperInfo.SetBoolIfTrue("LOCAL_SYSTEM_EXT_MODULE", Bool(base.commonProperties.System_ext_specific)) + if base.commonProperties.Owner != nil { + helperInfo.SetString("LOCAL_MODULE_OWNER", *base.commonProperties.Owner) + } + } + + if host { + makeOs := base.Os().String() + if base.Os() == Linux || base.Os() == LinuxBionic || base.Os() == LinuxMusl { + makeOs = "linux" + } + helperInfo.SetString("LOCAL_MODULE_HOST_OS", makeOs) + helperInfo.SetString("LOCAL_IS_HOST_MODULE", "true") + } + + prefix := "" + if base.ArchSpecific() { + switch base.Os().Class { + case Host: + if base.Target().HostCross { + prefix = "HOST_CROSS_" + } else { + prefix = "HOST_" + } + case Device: + prefix = "TARGET_" + + } + + if base.Arch().ArchType != ctx.Config().Targets[base.Os()][0].Arch.ArchType { + prefix = "2ND_" + prefix + } + } + + if licenseMetadata, ok := OtherModuleProvider(ctx, mod, LicenseMetadataProvider); ok { + helperInfo.SetPath("LOCAL_SOONG_LICENSE_METADATA", licenseMetadata.LicenseMetadataPath) + } + + if _, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok { + helperInfo.SetBool("LOCAL_SOONG_MODULE_INFO_JSON", true) + } + + a.mergeEntries(&helperInfo) + + // Write to footer. + a.FooterStrings = append([]string{"include " + a.Include}, a.FooterStrings...) +} + +// This method merges the entries to helperInfo, then replaces a's EntryMap and +// EntryOrder with helperInfo's +func (a *AndroidMkInfo) mergeEntries(helperInfo *AndroidMkInfo) { + for _, extraEntry := range a.EntryOrder { + if v, ok := helperInfo.EntryMap[extraEntry]; ok { + v = append(v, a.EntryMap[extraEntry]...) + } else { + helperInfo.EntryMap[extraEntry] = a.EntryMap[extraEntry] + helperInfo.EntryOrder = append(helperInfo.EntryOrder, extraEntry) + } + } + a.EntryOrder = helperInfo.EntryOrder + a.EntryMap = helperInfo.EntryMap +} + +func (a *AndroidMkInfo) disabled() bool { + return a.Disabled || !a.OutputFile.Valid() +} + +// write flushes the AndroidMkEntries's in-struct data populated by AndroidMkEntries into the +// given Writer object. +func (a *AndroidMkInfo) write(w io.Writer) { + if a.disabled() { + return + } + + combinedHeaderString := strings.Join(a.HeaderStrings, "\n") + combinedFooterString := strings.Join(a.FooterStrings, "\n") + w.Write([]byte(combinedHeaderString)) + for _, name := range a.EntryOrder { + AndroidMkEmitAssignList(w, name, a.EntryMap[name]) + } + w.Write([]byte(combinedFooterString)) +} + +// Compute the list of Make strings to declare phony goals and dist-for-goals +// calls from the module's dist and dists properties. +func (a *AndroidMkInfo) GetDistForGoals(ctx fillInEntriesContext, mod blueprint.Module) []string { + distContributions := a.getDistContributions(ctx, mod) + if distContributions == nil { + return nil + } + + return generateDistContributionsForMake(distContributions) +} + +// Compute the contributions that the module makes to the dist. +func (a *AndroidMkInfo) getDistContributions(ctx fillInEntriesContext, mod blueprint.Module) *distContributions { + amod := mod.(Module).base() + name := amod.BaseModuleName() + + // Collate the set of associated tag/paths available for copying to the dist. + // Start with an empty (nil) set. + var availableTaggedDists TaggedDistFiles + + // Then merge in any that are provided explicitly by the module. + if a.DistFiles != nil { + // Merge the DistFiles into the set. + availableTaggedDists = availableTaggedDists.merge(a.DistFiles) + } + + // If no paths have been provided for the DefaultDistTag and the output file is + // valid then add that as the default dist path. + if _, ok := availableTaggedDists[DefaultDistTag]; !ok && a.OutputFile.Valid() { + availableTaggedDists = availableTaggedDists.addPathsForTag(DefaultDistTag, a.OutputFile.Path()) + } + + info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider) + // If the distFiles created by GenerateTaggedDistFiles contains paths for the + // DefaultDistTag then that takes priority so delete any existing paths. + if _, ok := info.DistFiles[DefaultDistTag]; ok { + delete(availableTaggedDists, DefaultDistTag) + } + + // Finally, merge the distFiles created by GenerateTaggedDistFiles. + availableTaggedDists = availableTaggedDists.merge(info.DistFiles) + + if len(availableTaggedDists) == 0 { + // Nothing dist-able for this module. + return nil + } + + // Collate the contributions this module makes to the dist. + distContributions := &distContributions{} + + if !exemptFromRequiredApplicableLicensesProperty(mod.(Module)) { + distContributions.licenseMetadataFile = info.LicenseMetadataFile + } + + // Iterate over this module's dist structs, merged from the dist and dists properties. + for _, dist := range amod.Dists() { + // Get the list of goals this dist should be enabled for. e.g. sdk, droidcore + goals := strings.Join(dist.Targets, " ") + + // Get the tag representing the output files to be dist'd. e.g. ".jar", ".proguard_map" + var tag string + if dist.Tag == nil { + // If the dist struct does not specify a tag, use the default output files tag. + tag = DefaultDistTag + } else { + tag = *dist.Tag + } + + // Get the paths of the output files to be dist'd, represented by the tag. + // Can be an empty list. + tagPaths := availableTaggedDists[tag] + if len(tagPaths) == 0 { + // Nothing to dist for this tag, continue to the next dist. + continue + } + + if len(tagPaths) > 1 && (dist.Dest != nil || dist.Suffix != nil) { + errorMessage := "%s: Cannot apply dest/suffix for more than one dist " + + "file for %q goals tag %q in module %s. The list of dist files, " + + "which should have a single element, is:\n%s" + panic(fmt.Errorf(errorMessage, mod, goals, tag, name, tagPaths)) + } + + copiesForGoals := distContributions.getCopiesForGoals(goals) + + // Iterate over each path adding a copy instruction to copiesForGoals + for _, path := range tagPaths { + // It's possible that the Path is nil from errant modules. Be defensive here. + if path == nil { + tagName := "default" // for error message readability + if dist.Tag != nil { + tagName = *dist.Tag + } + panic(fmt.Errorf("Dist file should not be nil for the %s tag in %s", tagName, name)) + } + + dest := filepath.Base(path.String()) + + if dist.Dest != nil { + var err error + if dest, err = validateSafePath(*dist.Dest); err != nil { + // This was checked in ModuleBase.GenerateBuildActions + panic(err) + } + } + + ext := filepath.Ext(dest) + suffix := "" + if dist.Suffix != nil { + suffix = *dist.Suffix + } + + productString := "" + if dist.Append_artifact_with_product != nil && *dist.Append_artifact_with_product { + productString = fmt.Sprintf("_%s", ctx.Config().DeviceProduct()) + } + + if suffix != "" || productString != "" { + dest = strings.TrimSuffix(dest, ext) + suffix + productString + ext + } + + if dist.Dir != nil { + var err error + if dest, err = validateSafePath(*dist.Dir, dest); err != nil { + // This was checked in ModuleBase.GenerateBuildActions + panic(err) + } + } + + copiesForGoals.addCopyInstruction(path, dest) + } + } + + return distContributions +} + +func deepCopyAndroidMkProviderInfo(providerInfo *AndroidMkProviderInfo) AndroidMkProviderInfo { + info := AndroidMkProviderInfo{ + PrimaryInfo: deepCopyAndroidMkInfo(&providerInfo.PrimaryInfo), + } + if len(providerInfo.ExtraInfo) > 0 { + for _, i := range providerInfo.ExtraInfo { + info.ExtraInfo = append(info.ExtraInfo, deepCopyAndroidMkInfo(&i)) + } + } + return info +} + +func deepCopyAndroidMkInfo(mkinfo *AndroidMkInfo) AndroidMkInfo { + info := AndroidMkInfo{ + Class: mkinfo.Class, + SubName: mkinfo.SubName, + OverrideName: mkinfo.OverrideName, + // There is no modification on DistFiles or OutputFile, so no need to + // make their deep copy. + DistFiles: mkinfo.DistFiles, + OutputFile: mkinfo.OutputFile, + Disabled: mkinfo.Disabled, + Include: mkinfo.Include, + Required: deepCopyStringSlice(mkinfo.Required), + Host_required: deepCopyStringSlice(mkinfo.Host_required), + Target_required: deepCopyStringSlice(mkinfo.Target_required), + HeaderStrings: deepCopyStringSlice(mkinfo.HeaderStrings), + FooterStrings: deepCopyStringSlice(mkinfo.FooterStrings), + EntryOrder: deepCopyStringSlice(mkinfo.EntryOrder), + } + info.EntryMap = make(map[string][]string) + for k, v := range mkinfo.EntryMap { + info.EntryMap[k] = deepCopyStringSlice(v) + } + + return info +} + +func deepCopyStringSlice(original []string) []string { + result := make([]string, len(original)) + copy(result, original) + return result +} diff --git a/filesystem/vbmeta.go b/filesystem/vbmeta.go index 3a9a64daa..1d647965a 100644 --- a/filesystem/vbmeta.go +++ b/filesystem/vbmeta.go @@ -213,6 +213,7 @@ func (v *vbmeta) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.InstallFile(v.installDir, v.installFileName(), v.output) ctx.SetOutputFiles([]android.Path{v.output}, "") + android.SetProvider(ctx, android.AndroidMkInfoProvider, v.prepareAndroidMKProviderInfo()) } // Returns the embedded shell command that prints the rollback index @@ -265,20 +266,17 @@ func (v *vbmeta) extractPublicKeys(ctx android.ModuleContext) map[string]android return result } -var _ android.AndroidMkEntriesProvider = (*vbmeta)(nil) - -// Implements android.AndroidMkEntriesProvider -func (v *vbmeta) AndroidMkEntries() []android.AndroidMkEntries { - return []android.AndroidMkEntries{android.AndroidMkEntries{ - Class: "ETC", - OutputFile: android.OptionalPathForPath(v.output), - ExtraEntries: []android.AndroidMkExtraEntriesFunc{ - func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { - entries.SetString("LOCAL_MODULE_PATH", v.installDir.String()) - entries.SetString("LOCAL_INSTALLED_MODULE_STEM", v.installFileName()) - }, +func (v *vbmeta) prepareAndroidMKProviderInfo() *android.AndroidMkProviderInfo { + providerData := android.AndroidMkProviderInfo{ + PrimaryInfo: android.AndroidMkInfo{ + Class: "ETC", + OutputFile: android.OptionalPathForPath(v.output), + EntryMap: make(map[string][]string), }, - }} + } + providerData.PrimaryInfo.SetString("LOCAL_MODULE_PATH", v.installDir.String()) + providerData.PrimaryInfo.SetString("LOCAL_INSTALLED_MODULE_STEM", v.installFileName()) + return &providerData } var _ Filesystem = (*vbmeta)(nil) From e8a8783154dc31f3e09e3bb98a8b11233358097d Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Wed, 11 Sep 2024 11:35:46 -0700 Subject: [PATCH 07/17] Rename ConfigAndErrorContext to ConfigurableEvaluatorContext I'm going to be adding some methods to this interface, give it a name based on how it's going to be used, not based on what methods it contains. Bug: 323382414 Test: m nothing --no-skip-soong-tests Change-Id: I9bba04ba756c4dbe00625e2d04af81e78a11cae9 --- android/androidmk.go | 4 ++-- android/module.go | 20 ++++++++++---------- android/module_context.go | 4 ++-- android/sdk.go | 2 +- android/testing.go | 2 +- cc/cc.go | 4 ++-- cc/library.go | 2 +- cc/linker.go | 2 +- cc/object.go | 2 +- fuzz/fuzz_common.go | 2 +- java/boot_jars.go | 2 +- 11 files changed, 23 insertions(+), 23 deletions(-) diff --git a/android/androidmk.go b/android/androidmk.go index fc628cb34..98f8bb111 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -983,11 +983,11 @@ func translateAndroidMkEntriesModule(ctx SingletonContext, w io.Writer, moduleIn return nil } -func ShouldSkipAndroidMkProcessing(ctx ConfigAndErrorContext, module Module) bool { +func ShouldSkipAndroidMkProcessing(ctx ConfigurableEvaluatorContext, module Module) bool { return shouldSkipAndroidMkProcessing(ctx, module.base()) } -func shouldSkipAndroidMkProcessing(ctx ConfigAndErrorContext, module *ModuleBase) bool { +func shouldSkipAndroidMkProcessing(ctx ConfigurableEvaluatorContext, module *ModuleBase) bool { if !module.commonProperties.NamespaceExportedToMake { // TODO(jeffrygaston) do we want to validate that there are no modules being // exported to Kati that depend on this module? diff --git a/android/module.go b/android/module.go index 009b0dfb6..47fdc238b 100644 --- a/android/module.go +++ b/android/module.go @@ -58,7 +58,7 @@ type Module interface { base() *ModuleBase Disable() - Enabled(ctx ConfigAndErrorContext) bool + Enabled(ctx ConfigurableEvaluatorContext) bool Target() Target MultiTargets() []Target @@ -109,12 +109,12 @@ type Module interface { // Get information about the properties that can contain visibility rules. visibilityProperties() []visibilityProperty - RequiredModuleNames(ctx ConfigAndErrorContext) []string + RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string HostRequiredModuleNames() []string TargetRequiredModuleNames() []string - VintfFragmentModuleNames(ctx ConfigAndErrorContext) []string + VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string - ConfigurableEvaluator(ctx ConfigAndErrorContext) proptools.ConfigurableEvaluator + ConfigurableEvaluator(ctx ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator } // Qualified id for a module @@ -1339,7 +1339,7 @@ func (m *ModuleBase) PartitionTag(config DeviceConfig) string { return partition } -func (m *ModuleBase) Enabled(ctx ConfigAndErrorContext) bool { +func (m *ModuleBase) Enabled(ctx ConfigurableEvaluatorContext) bool { if m.commonProperties.ForcedDisabled { return false } @@ -1536,7 +1536,7 @@ func (m *ModuleBase) InRecovery() bool { return m.base().commonProperties.ImageVariation == RecoveryVariation } -func (m *ModuleBase) RequiredModuleNames(ctx ConfigAndErrorContext) []string { +func (m *ModuleBase) RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string { return m.base().commonProperties.Required.GetOrDefault(m.ConfigurableEvaluator(ctx), nil) } @@ -1548,7 +1548,7 @@ func (m *ModuleBase) TargetRequiredModuleNames() []string { return m.base().commonProperties.Target_required } -func (m *ModuleBase) VintfFragmentModuleNames(ctx ConfigAndErrorContext) []string { +func (m *ModuleBase) VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string { return m.base().commonProperties.Vintf_fragment_modules.GetOrDefault(m.ConfigurableEvaluator(ctx), nil) } @@ -2204,17 +2204,17 @@ func (m *ModuleBase) IsNativeBridgeSupported() bool { return proptools.Bool(m.commonProperties.Native_bridge_supported) } -type ConfigAndErrorContext interface { +type ConfigurableEvaluatorContext interface { Config() Config OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{}) } type configurationEvalutor struct { - ctx ConfigAndErrorContext + ctx ConfigurableEvaluatorContext m Module } -func (m *ModuleBase) ConfigurableEvaluator(ctx ConfigAndErrorContext) proptools.ConfigurableEvaluator { +func (m *ModuleBase) ConfigurableEvaluator(ctx ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator { return configurationEvalutor{ ctx: ctx, m: m.module, diff --git a/android/module_context.go b/android/module_context.go index 3889e40e8..54fe0be17 100644 --- a/android/module_context.go +++ b/android/module_context.go @@ -194,7 +194,7 @@ type ModuleContext interface { InstallInVendor() bool InstallForceOS() (*OsType, *ArchType) - RequiredModuleNames(ctx ConfigAndErrorContext) []string + RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string HostRequiredModuleNames() []string TargetRequiredModuleNames() []string @@ -855,7 +855,7 @@ func (m *moduleContext) ExpandOptionalSource(srcFile *string, _ string) Optional return OptionalPath{} } -func (m *moduleContext) RequiredModuleNames(ctx ConfigAndErrorContext) []string { +func (m *moduleContext) RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string { return m.module.RequiredModuleNames(ctx) } diff --git a/android/sdk.go b/android/sdk.go index d3f04a4f9..fb1ac24d4 100644 --- a/android/sdk.go +++ b/android/sdk.go @@ -813,7 +813,7 @@ type SdkMemberProperties interface { // SdkMemberContext provides access to information common to a specific member. type SdkMemberContext interface { - ConfigAndErrorContext + ConfigurableEvaluatorContext // SdkModuleContext returns the module context of the sdk common os variant which is creating the // snapshot. diff --git a/android/testing.go b/android/testing.go index 816707d63..42cd1ebbe 100644 --- a/android/testing.go +++ b/android/testing.go @@ -1326,7 +1326,7 @@ func (ctx *panickingConfigAndErrorContext) Config() Config { return ctx.ctx.Config() } -func PanickingConfigAndErrorContext(ctx *TestContext) ConfigAndErrorContext { +func PanickingConfigAndErrorContext(ctx *TestContext) ConfigurableEvaluatorContext { return &panickingConfigAndErrorContext{ ctx: ctx, } diff --git a/cc/cc.go b/cc/cc.go index b53473765..5b3647ee4 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -613,7 +613,7 @@ type linker interface { coverageOutputFilePath() android.OptionalPath // Get the deps that have been explicitly specified in the properties. - linkerSpecifiedDeps(ctx android.ConfigAndErrorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps + linkerSpecifiedDeps(ctx android.ConfigurableEvaluatorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) } @@ -970,7 +970,7 @@ func (c *Module) HiddenFromMake() bool { return c.Properties.HideFromMake } -func (c *Module) RequiredModuleNames(ctx android.ConfigAndErrorContext) []string { +func (c *Module) RequiredModuleNames(ctx android.ConfigurableEvaluatorContext) []string { required := android.CopyOf(c.ModuleBase.RequiredModuleNames(ctx)) if c.ImageVariation().Variation == android.CoreVariation { required = append(required, c.Properties.Target.Platform.Required...) diff --git a/cc/library.go b/cc/library.go index 03f7174c6..0a8fb247e 100644 --- a/cc/library.go +++ b/cc/library.go @@ -919,7 +919,7 @@ func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { return deps } -func (library *libraryDecorator) linkerSpecifiedDeps(ctx android.ConfigAndErrorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps { +func (library *libraryDecorator) linkerSpecifiedDeps(ctx android.ConfigurableEvaluatorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps { specifiedDeps = library.baseLinker.linkerSpecifiedDeps(ctx, module, specifiedDeps) var properties StaticOrSharedProperties if library.static() { diff --git a/cc/linker.go b/cc/linker.go index 00568177f..1efacade8 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -645,7 +645,7 @@ func (linker *baseLinker) link(ctx ModuleContext, panic(fmt.Errorf("baseLinker doesn't know how to link")) } -func (linker *baseLinker) linkerSpecifiedDeps(ctx android.ConfigAndErrorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps { +func (linker *baseLinker) linkerSpecifiedDeps(ctx android.ConfigurableEvaluatorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps { eval := module.ConfigurableEvaluator(ctx) specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, linker.Properties.Shared_libs.GetOrDefault(eval, nil)...) diff --git a/cc/object.go b/cc/object.go index a4f4c8408..c89520ab7 100644 --- a/cc/object.go +++ b/cc/object.go @@ -203,7 +203,7 @@ func (object *objectLinker) link(ctx ModuleContext, return outputFile } -func (object *objectLinker) linkerSpecifiedDeps(ctx android.ConfigAndErrorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps { +func (object *objectLinker) linkerSpecifiedDeps(ctx android.ConfigurableEvaluatorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps { eval := module.ConfigurableEvaluator(ctx) specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, object.Properties.Shared_libs.GetOrDefault(eval, nil)...) diff --git a/fuzz/fuzz_common.go b/fuzz/fuzz_common.go index 306d65e29..a0598376b 100644 --- a/fuzz/fuzz_common.go +++ b/fuzz/fuzz_common.go @@ -449,7 +449,7 @@ func IsValidFrameworkForModule(targetFramework Framework, lang Lang, moduleFrame } } -func IsValid(ctx android.ConfigAndErrorContext, fuzzModule FuzzModule) bool { +func IsValid(ctx android.ConfigurableEvaluatorContext, fuzzModule FuzzModule) bool { // Discard ramdisk + vendor_ramdisk + recovery modules, they're duplicates of // fuzz targets we're going to package anyway. if !fuzzModule.Enabled(ctx) || fuzzModule.InRamdisk() || fuzzModule.InVendorRamdisk() || fuzzModule.InRecovery() { diff --git a/java/boot_jars.go b/java/boot_jars.go index 6223dede8..3c3bd550c 100644 --- a/java/boot_jars.go +++ b/java/boot_jars.go @@ -21,7 +21,7 @@ import ( // isActiveModule returns true if the given module should be considered for boot // jars, i.e. if it's enabled and the preferred one in case of source and // prebuilt alternatives. -func isActiveModule(ctx android.ConfigAndErrorContext, module android.Module) bool { +func isActiveModule(ctx android.ConfigurableEvaluatorContext, module android.Module) bool { if !module.Enabled(ctx) { return false } From ff66518da284851c0cd6ef911ef06fa8e9840aa2 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Wed, 11 Sep 2024 18:48:44 +0000 Subject: [PATCH 08/17] Delete multitree api imports code The mutltiree workflow has not been in use for a while. This CL cleans up the code that was added to support multitree. Details - Delete cc_api_library, cc_api_headers, cc_api_variant module types. These module types contain build rules for prebuilt stub .so and .h files - Update the DepsMutator of cc.Module to not create a dependency on a sibling cc_api_* module if it exists. e.g. do not create a dependency on libfoo.apiimports if libfoo is listed in `shared_libs`. - Remove cc_api_library from the stub/impl selection logic for cc modules Test: m nothing --no-skip-soong-tests Test: presbumits Change-Id: Ie194157fb3bbc630f384cdd9b694b0fba6786ded --- apex/Android.bp | 1 - apex/apex.go | 5 - apex/apex_test.go | 217 ----------------- cc/Android.bp | 2 - cc/androidmk.go | 29 --- cc/cc.go | 121 +-------- cc/library.go | 3 +- cc/library_stub.go | 512 --------------------------------------- cc/sdk.go | 12 - cc/testing.go | 4 - multitree/Android.bp | 20 -- multitree/api_imports.go | 102 -------- multitree/api_surface.go | 109 --------- multitree/export.go | 66 ----- multitree/import.go | 96 -------- multitree/metadata.go | 74 ------ rust/rust.go | 59 +---- 17 files changed, 6 insertions(+), 1426 deletions(-) delete mode 100644 cc/library_stub.go delete mode 100644 multitree/Android.bp delete mode 100644 multitree/api_imports.go delete mode 100644 multitree/api_surface.go delete mode 100644 multitree/export.go delete mode 100644 multitree/import.go delete mode 100644 multitree/metadata.go diff --git a/apex/Android.bp b/apex/Android.bp index 17fdfc36a..ef2f75570 100644 --- a/apex/Android.bp +++ b/apex/Android.bp @@ -15,7 +15,6 @@ bootstrap_go_package { "soong-cc", "soong-filesystem", "soong-java", - "soong-multitree", "soong-provenance", "soong-python", "soong-rust", diff --git a/apex/apex.go b/apex/apex.go index 1f4a99b55..8a03240a1 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -32,7 +32,6 @@ import ( prebuilt_etc "android/soong/etc" "android/soong/filesystem" "android/soong/java" - "android/soong/multitree" "android/soong/rust" "android/soong/sh" ) @@ -438,7 +437,6 @@ type apexBundle struct { android.ModuleBase android.DefaultableModuleBase android.OverridableModuleBase - multitree.ExportableModuleBase // Properties properties apexBundleProperties @@ -1406,8 +1404,6 @@ func (a *apexBundle) DepIsInSameApex(_ android.BaseModuleContext, _ android.Modu return true } -var _ multitree.Exportable = (*apexBundle)(nil) - func (a *apexBundle) Exportable() bool { return true } @@ -2540,7 +2536,6 @@ func newApexBundle() *apexBundle { android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) android.InitDefaultableModule(module) android.InitOverridableModule(module, &module.overridableProperties.Overrides) - multitree.InitExportableModule(module) return module } diff --git a/apex/apex_test.go b/apex/apex_test.go index 685cb3743..2b9772821 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -10274,208 +10274,6 @@ func TestUpdatableApexEnforcesAppUpdatability(t *testing.T) { } } -func TestApexBuildsAgainstApiSurfaceStubLibraries(t *testing.T) { - bp := ` - apex { - name: "myapex", - key: "myapex.key", - native_shared_libs: ["libbaz"], - binaries: ["binfoo"], - min_sdk_version: "29", - } - apex_key { - name: "myapex.key", - } - cc_binary { - name: "binfoo", - shared_libs: ["libbar", "libbaz", "libqux",], - apex_available: ["myapex"], - min_sdk_version: "29", - recovery_available: false, - } - cc_library { - name: "libbar", - srcs: ["libbar.cc"], - stubs: { - symbol_file: "libbar.map.txt", - versions: [ - "29", - ], - }, - } - cc_library { - name: "libbaz", - srcs: ["libbaz.cc"], - apex_available: ["myapex"], - min_sdk_version: "29", - stubs: { - symbol_file: "libbaz.map.txt", - versions: [ - "29", - ], - }, - } - cc_api_library { - name: "libbar", - src: "libbar_stub.so", - min_sdk_version: "29", - variants: ["apex.29"], - } - cc_api_variant { - name: "libbar", - variant: "apex", - version: "29", - src: "libbar_apex_29.so", - } - cc_api_library { - name: "libbaz", - src: "libbaz_stub.so", - min_sdk_version: "29", - variants: ["apex.29"], - } - cc_api_variant { - name: "libbaz", - variant: "apex", - version: "29", - src: "libbaz_apex_29.so", - } - cc_api_library { - name: "libqux", - src: "libqux_stub.so", - min_sdk_version: "29", - variants: ["apex.29"], - } - cc_api_variant { - name: "libqux", - variant: "apex", - version: "29", - src: "libqux_apex_29.so", - } - api_imports { - name: "api_imports", - apex_shared_libs: [ - "libbar", - "libbaz", - "libqux", - ], - } - ` - result := testApex(t, bp) - - hasDep := func(m android.Module, wantDep android.Module) bool { - t.Helper() - var found bool - result.VisitDirectDeps(m, func(dep blueprint.Module) { - if dep == wantDep { - found = true - } - }) - return found - } - - // Library defines stubs and cc_api_library should be used with cc_api_library - binfooApexVariant := result.ModuleForTests("binfoo", "android_arm64_armv8-a_apex29").Module() - libbarCoreVariant := result.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module() - libbarApiImportCoreVariant := result.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module() - - android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries", true, hasDep(binfooApexVariant, libbarApiImportCoreVariant)) - android.AssertBoolEquals(t, "apex variant should link against original library if exists", true, hasDep(binfooApexVariant, libbarCoreVariant)) - - binFooCFlags := result.ModuleForTests("binfoo", "android_arm64_armv8-a_apex29").Rule("ld").Args["libFlags"] - android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libbar.apex.29.apiimport.so") - android.AssertStringDoesNotContain(t, "binfoo should not link against cc_api_library itself", binFooCFlags, "libbar.apiimport.so") - android.AssertStringDoesNotContain(t, "binfoo should not link against original definition", binFooCFlags, "libbar.so") - - // Library defined in the same APEX should be linked with original definition instead of cc_api_library - libbazApexVariant := result.ModuleForTests("libbaz", "android_arm64_armv8-a_shared_apex29").Module() - libbazApiImportCoreVariant := result.ModuleForTests("libbaz.apiimport", "android_arm64_armv8-a_shared").Module() - android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries even from same APEX", true, hasDep(binfooApexVariant, libbazApiImportCoreVariant)) - android.AssertBoolEquals(t, "apex variant should link against original library if exists", true, hasDep(binfooApexVariant, libbazApexVariant)) - - android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libbaz.so") - android.AssertStringDoesNotContain(t, "binfoo should not link against cc_api_library itself", binFooCFlags, "libbaz.apiimport.so") - android.AssertStringDoesNotContain(t, "binfoo should not link against original definition", binFooCFlags, "libbaz.apex.29.apiimport.so") - - // cc_api_library defined without original library should be linked with cc_api_library - libquxApiImportApexVariant := result.ModuleForTests("libqux.apiimport", "android_arm64_armv8-a_shared").Module() - android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries even original library definition does not exist", true, hasDep(binfooApexVariant, libquxApiImportApexVariant)) - android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libqux.apex.29.apiimport.so") -} - -func TestPlatformBinaryBuildsAgainstApiSurfaceStubLibraries(t *testing.T) { - bp := ` - apex { - name: "myapex", - key: "myapex.key", - native_shared_libs: ["libbar"], - min_sdk_version: "29", - } - apex_key { - name: "myapex.key", - } - cc_binary { - name: "binfoo", - shared_libs: ["libbar"], - recovery_available: false, - } - cc_library { - name: "libbar", - srcs: ["libbar.cc"], - apex_available: ["myapex"], - min_sdk_version: "29", - stubs: { - symbol_file: "libbar.map.txt", - versions: [ - "29", - ], - }, - } - cc_api_library { - name: "libbar", - src: "libbar_stub.so", - variants: ["apex.29"], - } - cc_api_variant { - name: "libbar", - variant: "apex", - version: "29", - src: "libbar_apex_29.so", - } - api_imports { - name: "api_imports", - apex_shared_libs: [ - "libbar", - ], - } - ` - - result := testApex(t, bp) - - hasDep := func(m android.Module, wantDep android.Module) bool { - t.Helper() - var found bool - result.VisitDirectDeps(m, func(dep blueprint.Module) { - if dep == wantDep { - found = true - } - }) - return found - } - - // Library defines stubs and cc_api_library should be used with cc_api_library - binfooApexVariant := result.ModuleForTests("binfoo", "android_arm64_armv8-a").Module() - libbarCoreVariant := result.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module() - libbarApiImportCoreVariant := result.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module() - - android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries", true, hasDep(binfooApexVariant, libbarApiImportCoreVariant)) - android.AssertBoolEquals(t, "apex variant should link against original library if exists", true, hasDep(binfooApexVariant, libbarCoreVariant)) - - binFooCFlags := result.ModuleForTests("binfoo", "android_arm64_armv8-a").Rule("ld").Args["libFlags"] - android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libbar.apex.29.apiimport.so") - android.AssertStringDoesNotContain(t, "binfoo should not link against cc_api_library itself", binFooCFlags, "libbar.apiimport.so") - android.AssertStringDoesNotContain(t, "binfoo should not link against original definition", binFooCFlags, "libbar.so") -} - func TestTrimmedApex(t *testing.T) { bp := ` apex { @@ -10514,21 +10312,6 @@ func TestTrimmedApex(t *testing.T) { apex_available: ["myapex","mydcla"], min_sdk_version: "29", } - cc_api_library { - name: "libc", - src: "libc.so", - min_sdk_version: "29", - recovery_available: true, - vendor_available: true, - product_available: true, - } - api_imports { - name: "api_imports", - shared_libs: [ - "libc", - ], - header_libs: [], - } ` ctx := testApex(t, bp) module := ctx.ModuleForTests("myapex", "android_common_myapex") diff --git a/cc/Android.bp b/cc/Android.bp index e68e4a398..29526143f 100644 --- a/cc/Android.bp +++ b/cc/Android.bp @@ -16,7 +16,6 @@ bootstrap_go_package { "soong-etc", "soong-fuzz", "soong-genrule", - "soong-multitree", "soong-testing", "soong-tradefed", ], @@ -65,7 +64,6 @@ bootstrap_go_package { "library.go", "library_headers.go", "library_sdk_member.go", - "library_stub.go", "native_bridge_sdk_trait.go", "object.go", "test.go", diff --git a/cc/androidmk.go b/cc/androidmk.go index cecaae23a..6966f7692 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -21,7 +21,6 @@ import ( "strings" "android/soong/android" - "android/soong/multitree" ) var ( @@ -479,34 +478,6 @@ func (p *prebuiltBinaryLinker) AndroidMkEntries(ctx AndroidMkContext, entries *a androidMkWritePrebuiltOptions(p.baseLinker, entries) } -func (a *apiLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) { - entries.Class = "SHARED_LIBRARIES" - entries.SubName += multitree.GetApiImportSuffix() - - entries.ExtraEntries = append(entries.ExtraEntries, func(_ android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { - a.libraryDecorator.androidMkWriteExportedFlags(entries) - src := *a.properties.Src - path, file := filepath.Split(src) - stem, suffix, ext := android.SplitFileExt(file) - entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext) - entries.SetString("LOCAL_MODULE_SUFFIX", suffix) - entries.SetString("LOCAL_MODULE_STEM", stem) - entries.SetString("LOCAL_MODULE_PATH", path) - entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true) - entries.SetString("LOCAL_SOONG_TOC", a.toc().String()) - }) -} - -func (a *apiHeadersDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) { - entries.Class = "HEADER_LIBRARIES" - entries.SubName += multitree.GetApiImportSuffix() - - entries.ExtraEntries = append(entries.ExtraEntries, func(_ android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { - a.libraryDecorator.androidMkWriteExportedFlags(entries) - entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true) - }) -} - func androidMkWritePrebuiltOptions(linker *baseLinker, entries *android.AndroidMkEntries) { allow := linker.Properties.Allow_undefined_symbols if allow != nil { diff --git a/cc/cc.go b/cc/cc.go index b53473765..dd0e581f8 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -34,7 +34,6 @@ import ( "android/soong/cc/config" "android/soong/fuzz" "android/soong/genrule" - "android/soong/multitree" ) func init() { @@ -2361,24 +2360,6 @@ func AddSharedLibDependenciesWithVersions(ctx android.BottomUpMutatorContext, mo } } -func GetApiImports(c LinkableInterface, actx android.BottomUpMutatorContext) multitree.ApiImportInfo { - apiImportInfo := multitree.ApiImportInfo{} - - if c.Device() { - var apiImportModule []blueprint.Module - if actx.OtherModuleExists("api_imports") { - apiImportModule = actx.AddDependency(c, nil, "api_imports") - if len(apiImportModule) > 0 && apiImportModule[0] != nil { - apiInfo, _ := android.OtherModuleProvider(actx, apiImportModule[0], multitree.ApiImportsProvider) - apiImportInfo = apiInfo - android.SetProvider(actx, multitree.ApiImportsProvider, apiInfo) - } - } - } - - return apiImportInfo -} - func GetReplaceModuleName(lib string, replaceMap map[string]string) string { if snapshot, ok := replaceMap[lib]; ok { return snapshot @@ -2448,11 +2429,6 @@ func (c *Module) shouldUseApiSurface() bool { // NDK Variant return true } - - if c.isImportedApiLibrary() { - // API Library should depend on API headers - return true - } } return false @@ -2472,19 +2448,10 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { ctx.ctx = ctx deps := c.deps(ctx) - apiImportInfo := GetApiImports(c, actx) apiNdkLibs := []string{} apiLateNdkLibs := []string{} - if c.shouldUseApiSurface() { - deps.SharedLibs, apiNdkLibs = rewriteLibsForApiImports(c, deps.SharedLibs, apiImportInfo.SharedLibs, ctx.Config()) - deps.LateSharedLibs, apiLateNdkLibs = rewriteLibsForApiImports(c, deps.LateSharedLibs, apiImportInfo.SharedLibs, ctx.Config()) - deps.SystemSharedLibs, _ = rewriteLibsForApiImports(c, deps.SystemSharedLibs, apiImportInfo.SharedLibs, ctx.Config()) - deps.ReexportHeaderLibHeaders, _ = rewriteLibsForApiImports(c, deps.ReexportHeaderLibHeaders, apiImportInfo.SharedLibs, ctx.Config()) - deps.ReexportSharedLibHeaders, _ = rewriteLibsForApiImports(c, deps.ReexportSharedLibHeaders, apiImportInfo.SharedLibs, ctx.Config()) - } - c.Properties.AndroidMkSystemSharedLibs = deps.SystemSharedLibs variantNdkLibs := []string{} @@ -2501,11 +2468,6 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { depTag.reexportFlags = true } - // Check header lib replacement from API surface first, and then check again with VSDK - if c.shouldUseApiSurface() { - lib = GetReplaceModuleName(lib, apiImportInfo.HeaderLibs) - } - if c.isNDKStubLibrary() { variationExists := actx.OtherModuleDependencyVariantExists(nil, lib) if variationExists { @@ -2515,7 +2477,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { // any variants. actx.AddFarVariationDependencies([]blueprint.Variation{}, depTag, lib) } - } else if c.IsStubs() && !c.isImportedApiLibrary() { + } else if c.IsStubs() { actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation()), depTag, lib) } else { @@ -2591,22 +2553,12 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { } name, version := StubsLibNameAndVersion(lib) - if apiLibraryName, ok := apiImportInfo.SharedLibs[name]; ok && !ctx.OtherModuleExists(name) { - name = apiLibraryName - } sharedLibNames = append(sharedLibNames, name) variations := []blueprint.Variation{ {Mutator: "link", Variation: "shared"}, } - - if _, ok := apiImportInfo.ApexSharedLibs[name]; !ok || ctx.OtherModuleExists(name) { - AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, name, version, false) - } - - if apiLibraryName, ok := apiImportInfo.ApexSharedLibs[name]; ok { - AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, apiLibraryName, version, false) - } + AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, name, version, false) } for _, lib := range deps.LateStaticLibs { @@ -2701,7 +2653,6 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { ) } - updateImportedLibraryDependency(ctx) } func BeginMutator(ctx android.BottomUpMutatorContext) { @@ -2730,10 +2681,6 @@ func checkLinkType(ctx android.BaseModuleContext, from LinkableInterface, to Lin return } - // TODO(b/244244438) : Remove this once all variants are implemented - if ccFrom, ok := from.(*Module); ok && ccFrom.isImportedApiLibrary() { - return - } if from.SdkVersion() == "" { // Platform code can link to anything return @@ -2756,10 +2703,6 @@ func checkLinkType(ctx android.BaseModuleContext, from LinkableInterface, to Lin // the NDK. return } - if c.isImportedApiLibrary() { - // Imported library from the API surface is a stub library built against interface definition. - return - } } if strings.HasPrefix(ctx.ModuleName(), "libclang_rt.") && to.Module().Name() == "libc++" { @@ -2935,47 +2878,6 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { skipModuleList := map[string]bool{} - var apiImportInfo multitree.ApiImportInfo - hasApiImportInfo := false - - ctx.VisitDirectDeps(func(dep android.Module) { - if dep.Name() == "api_imports" { - apiImportInfo, _ = android.OtherModuleProvider(ctx, dep, multitree.ApiImportsProvider) - hasApiImportInfo = true - } - }) - - if hasApiImportInfo { - targetStubModuleList := map[string]string{} - targetOrigModuleList := map[string]string{} - - // Search for dependency which both original module and API imported library with APEX stub exists - ctx.VisitDirectDeps(func(dep android.Module) { - depName := ctx.OtherModuleName(dep) - if apiLibrary, ok := apiImportInfo.ApexSharedLibs[depName]; ok { - targetStubModuleList[apiLibrary] = depName - } - }) - ctx.VisitDirectDeps(func(dep android.Module) { - depName := ctx.OtherModuleName(dep) - if origLibrary, ok := targetStubModuleList[depName]; ok { - targetOrigModuleList[origLibrary] = depName - } - }) - - // Decide which library should be used between original and API imported library - ctx.VisitDirectDeps(func(dep android.Module) { - depName := ctx.OtherModuleName(dep) - if apiLibrary, ok := targetOrigModuleList[depName]; ok { - if ShouldUseStubForApex(ctx, dep) { - skipModuleList[depName] = true - } else { - skipModuleList[apiLibrary] = true - } - } - }) - } - ctx.VisitDirectDeps(func(dep android.Module) { depName := ctx.OtherModuleName(dep) depTag := ctx.OtherModuleDependencyTag(dep) @@ -3404,17 +3306,7 @@ func ShouldUseStubForApex(ctx android.ModuleContext, dep android.Module) bool { // bootstrap modules, always link to non-stub variant isNotInPlatform := dep.(android.ApexModule).NotInPlatform() - isApexImportedApiLibrary := false - - if cc, ok := dep.(*Module); ok { - if apiLibrary, ok := cc.linker.(*apiLibraryDecorator); ok { - if apiLibrary.hasApexStubs() { - isApexImportedApiLibrary = true - } - } - } - - useStubs = (isNotInPlatform || isApexImportedApiLibrary) && !bootstrap + useStubs = isNotInPlatform && !bootstrap if useStubs { // Another exception: if this module is a test for an APEX, then @@ -3439,7 +3331,7 @@ func ShouldUseStubForApex(ctx android.ModuleContext, dep android.Module) bool { // only partially overlapping apex_available. For that test_for // modules would need to be split into APEX variants and resolved // separately for each APEX they have access to. - if !isApexImportedApiLibrary && android.AvailableToSameApexes(thisModule, dep.(android.ApexModule)) { + if android.AvailableToSameApexes(thisModule, dep.(android.ApexModule)) { useStubs = false } } @@ -4023,11 +3915,6 @@ func (c *Module) IsSdkVariant() bool { return c.Properties.IsSdkVariant } -func (c *Module) isImportedApiLibrary() bool { - _, ok := c.linker.(*apiLibraryDecorator) - return ok -} - func kytheExtractAllFactory() android.Singleton { return &kytheExtractAllSingleton{} } diff --git a/cc/library.go b/cc/library.go index 03f7174c6..ebc4c5f11 100644 --- a/cc/library.go +++ b/cc/library.go @@ -2350,9 +2350,8 @@ func (versionTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, varia if library := moduleLibraryInterface(ctx.Module()); library != nil && canBeVersionVariant(m) { isLLNDK := m.IsLlndk() isVendorPublicLibrary := m.IsVendorPublicLibrary() - isImportedApiLibrary := m.isImportedApiLibrary() - if variation != "" || isLLNDK || isVendorPublicLibrary || isImportedApiLibrary { + if variation != "" || isLLNDK || isVendorPublicLibrary { // A stubs or LLNDK stubs variant. if m.sanitize != nil { m.sanitize.Properties.ForceDisable = true diff --git a/cc/library_stub.go b/cc/library_stub.go deleted file mode 100644 index 636782581..000000000 --- a/cc/library_stub.go +++ /dev/null @@ -1,512 +0,0 @@ -// Copyright 2021 Google Inc. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cc - -import ( - "regexp" - "strings" - - "android/soong/android" - "android/soong/multitree" - - "github.com/google/blueprint/proptools" -) - -var ( - ndkVariantRegex = regexp.MustCompile("ndk\\.([a-zA-Z0-9]+)") - stubVariantRegex = regexp.MustCompile("apex\\.([a-zA-Z0-9]+)") -) - -func init() { - RegisterLibraryStubBuildComponents(android.InitRegistrationContext) -} - -func RegisterLibraryStubBuildComponents(ctx android.RegistrationContext) { - ctx.RegisterModuleType("cc_api_library", CcApiLibraryFactory) - ctx.RegisterModuleType("cc_api_headers", CcApiHeadersFactory) - ctx.RegisterModuleType("cc_api_variant", CcApiVariantFactory) -} - -func updateImportedLibraryDependency(ctx android.BottomUpMutatorContext) { - m, ok := ctx.Module().(*Module) - if !ok { - return - } - - apiLibrary, ok := m.linker.(*apiLibraryDecorator) - if !ok { - return - } - - if m.InVendorOrProduct() && apiLibrary.hasLLNDKStubs() { - // Add LLNDK variant dependency - if inList("llndk", apiLibrary.properties.Variants) { - variantName := BuildApiVariantName(m.BaseModuleName(), "llndk", "") - ctx.AddDependency(m, nil, variantName) - } - } else if m.IsSdkVariant() { - // Add NDK variant dependencies - targetVariant := "ndk." + m.StubsVersion() - if inList(targetVariant, apiLibrary.properties.Variants) { - variantName := BuildApiVariantName(m.BaseModuleName(), targetVariant, "") - ctx.AddDependency(m, nil, variantName) - } - } else if m.IsStubs() { - targetVariant := "apex." + m.StubsVersion() - if inList(targetVariant, apiLibrary.properties.Variants) { - variantName := BuildApiVariantName(m.BaseModuleName(), targetVariant, "") - ctx.AddDependency(m, nil, variantName) - } - } -} - -// 'cc_api_library' is a module type which is from the exported API surface -// with C shared library type. The module will replace original module, and -// offer a link to the module that generates shared library object from the -// map file. -type apiLibraryProperties struct { - Src *string `android:"arch_variant"` - Variants []string -} - -type apiLibraryDecorator struct { - *libraryDecorator - properties apiLibraryProperties -} - -func CcApiLibraryFactory() android.Module { - module, decorator := NewLibrary(android.DeviceSupported) - apiLibraryDecorator := &apiLibraryDecorator{ - libraryDecorator: decorator, - } - apiLibraryDecorator.BuildOnlyShared() - - module.stl = nil - module.sanitize = nil - decorator.disableStripping() - - module.compiler = nil - module.linker = apiLibraryDecorator - module.installer = nil - module.library = apiLibraryDecorator - module.AddProperties(&module.Properties, &apiLibraryDecorator.properties) - - // Prevent default system libs (libc, libm, and libdl) from being linked - if apiLibraryDecorator.baseLinker.Properties.System_shared_libs == nil { - apiLibraryDecorator.baseLinker.Properties.System_shared_libs = []string{} - } - - apiLibraryDecorator.baseLinker.Properties.No_libcrt = BoolPtr(true) - apiLibraryDecorator.baseLinker.Properties.Nocrt = BoolPtr(true) - - module.Init() - - return module -} - -func (d *apiLibraryDecorator) Name(basename string) string { - return basename + multitree.GetApiImportSuffix() -} - -// Export include dirs without checking for existence. -// The directories are not guaranteed to exist during Soong analysis. -func (d *apiLibraryDecorator) exportIncludes(ctx ModuleContext) { - exporterProps := d.flagExporter.Properties - for _, dir := range exporterProps.Export_include_dirs.GetOrDefault(ctx, nil) { - d.dirs = append(d.dirs, android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), dir)) - } - // system headers - for _, dir := range exporterProps.Export_system_include_dirs { - d.systemDirs = append(d.systemDirs, android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), dir)) - } -} - -func (d *apiLibraryDecorator) linkerInit(ctx BaseModuleContext) { - d.baseLinker.linkerInit(ctx) - - if d.hasNDKStubs() { - // Set SDK version of module as current - ctx.Module().(*Module).Properties.Sdk_version = StringPtr("current") - - // Add NDK stub as NDK known libs - name := ctx.ModuleName() - - ndkKnownLibsLock.Lock() - ndkKnownLibs := getNDKKnownLibs(ctx.Config()) - if !inList(name, *ndkKnownLibs) { - *ndkKnownLibs = append(*ndkKnownLibs, name) - } - ndkKnownLibsLock.Unlock() - } -} - -func (d *apiLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objects Objects) android.Path { - m, _ := ctx.Module().(*Module) - - var in android.Path - - // src might not exist during the beginning of soong analysis in Multi-tree - if src := String(d.properties.Src); src != "" { - in = android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), src) - } - - libName := m.BaseModuleName() + multitree.GetApiImportSuffix() - - load_cc_variant := func(apiVariantModule string) { - var mod android.Module - - ctx.VisitDirectDeps(func(depMod android.Module) { - if depMod.Name() == apiVariantModule { - mod = depMod - libName = apiVariantModule - } - }) - - if mod != nil { - variantMod, ok := mod.(*CcApiVariant) - if ok { - in = variantMod.Src() - - // Copy LLDNK properties to cc_api_library module - exportIncludeDirs := append(d.libraryDecorator.flagExporter.Properties.Export_include_dirs.GetOrDefault(ctx, nil), - variantMod.exportProperties.Export_include_dirs...) - d.libraryDecorator.flagExporter.Properties.Export_include_dirs = proptools.NewConfigurable[[]string]( - nil, - []proptools.ConfigurableCase[[]string]{ - proptools.NewConfigurableCase[[]string](nil, &exportIncludeDirs), - }, - ) - - // Export headers as system include dirs if specified. Mostly for libc - if Bool(variantMod.exportProperties.Export_headers_as_system) { - d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs = append( - d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs, - d.libraryDecorator.flagExporter.Properties.Export_include_dirs.GetOrDefault(ctx, nil)...) - d.libraryDecorator.flagExporter.Properties.Export_include_dirs = proptools.NewConfigurable[[]string](nil, nil) - } - } - } - } - - if m.InVendorOrProduct() && d.hasLLNDKStubs() { - // LLNDK variant - load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "llndk", "")) - } else if m.IsSdkVariant() { - // NDK Variant - load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "ndk", m.StubsVersion())) - } else if m.IsStubs() { - // APEX Variant - load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "apex", m.StubsVersion())) - } - - // Flags reexported from dependencies. (e.g. vndk_prebuilt_shared) - d.exportIncludes(ctx) - d.libraryDecorator.reexportDirs(deps.ReexportedDirs...) - d.libraryDecorator.reexportSystemDirs(deps.ReexportedSystemDirs...) - d.libraryDecorator.reexportFlags(deps.ReexportedFlags...) - d.libraryDecorator.reexportDeps(deps.ReexportedDeps...) - d.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...) - - if in == nil { - ctx.PropertyErrorf("src", "Unable to locate source property") - return nil - } - - // Make the _compilation_ of rdeps have an order-only dep on cc_api_library.src (an .so file) - // The .so file itself has an order-only dependency on the headers contributed by this library. - // Creating this dependency ensures that the headers are assembled before compilation of rdeps begins. - d.libraryDecorator.reexportDeps(in) - d.libraryDecorator.flagExporter.setProvider(ctx) - - d.unstrippedOutputFile = in - libName += flags.Toolchain.ShlibSuffix() - - tocFile := android.PathForModuleOut(ctx, libName+".toc") - d.tocFile = android.OptionalPathForPath(tocFile) - TransformSharedObjectToToc(ctx, in, tocFile) - - outputFile := android.PathForModuleOut(ctx, libName) - - // TODO(b/270485584) This copies with a new name, just to avoid conflict with prebuilts. - // We can just use original input if there is any way to avoid name conflict without copy. - ctx.Build(pctx, android.BuildParams{ - Rule: android.Cp, - Description: "API surface imported library", - Input: in, - Output: outputFile, - Args: map[string]string{ - "cpFlags": "-L", - }, - }) - - android.SetProvider(ctx, SharedLibraryInfoProvider, SharedLibraryInfo{ - SharedLibrary: outputFile, - Target: ctx.Target(), - - TableOfContents: d.tocFile, - }) - - d.shareStubs(ctx) - - return outputFile -} - -// Share additional information about stub libraries with provider -func (d *apiLibraryDecorator) shareStubs(ctx ModuleContext) { - stubs := ctx.GetDirectDepsWithTag(stubImplDepTag) - if len(stubs) > 0 { - var stubsInfo []SharedStubLibrary - for _, stub := range stubs { - stubInfo, _ := android.OtherModuleProvider(ctx, stub, SharedLibraryInfoProvider) - flagInfo, _ := android.OtherModuleProvider(ctx, stub, FlagExporterInfoProvider) - stubsInfo = append(stubsInfo, SharedStubLibrary{ - Version: moduleLibraryInterface(stub).stubsVersion(), - SharedLibraryInfo: stubInfo, - FlagExporterInfo: flagInfo, - }) - } - android.SetProvider(ctx, SharedLibraryStubsProvider, SharedLibraryStubsInfo{ - SharedStubLibraries: stubsInfo, - - IsLLNDK: ctx.IsLlndk(), - }) - } -} - -func (d *apiLibraryDecorator) availableFor(what string) bool { - // Stub from API surface should be available for any APEX. - return true -} - -func (d *apiLibraryDecorator) hasApexStubs() bool { - for _, variant := range d.properties.Variants { - if strings.HasPrefix(variant, "apex") { - return true - } - } - return false -} - -func (d *apiLibraryDecorator) hasStubsVariants() bool { - return d.hasApexStubs() -} - -func (d *apiLibraryDecorator) stubsVersions(ctx android.BaseModuleContext) []string { - m, ok := ctx.Module().(*Module) - - if !ok { - return nil - } - - // TODO(b/244244438) Create more version information for NDK and APEX variations - // NDK variants - if m.IsSdkVariant() { - // TODO(b/249193999) Do not check if module has NDK stubs once all NDK cc_api_library contains ndk variant of cc_api_variant. - if d.hasNDKStubs() { - return d.getNdkVersions() - } - } - - if d.hasLLNDKStubs() && m.InVendorOrProduct() { - // LLNDK libraries only need a single stubs variant. - return []string{android.FutureApiLevel.String()} - } - - stubsVersions := d.getStubVersions() - - if len(stubsVersions) != 0 { - return stubsVersions - } - - if m.MinSdkVersion() == "" { - return nil - } - - firstVersion, err := nativeApiLevelFromUser(ctx, - m.MinSdkVersion()) - - if err != nil { - return nil - } - - return ndkLibraryVersions(ctx, firstVersion) -} - -func (d *apiLibraryDecorator) hasLLNDKStubs() bool { - return inList("llndk", d.properties.Variants) -} - -func (d *apiLibraryDecorator) hasNDKStubs() bool { - for _, variant := range d.properties.Variants { - if ndkVariantRegex.MatchString(variant) { - return true - } - } - return false -} - -func (d *apiLibraryDecorator) getNdkVersions() []string { - ndkVersions := []string{} - - for _, variant := range d.properties.Variants { - if match := ndkVariantRegex.FindStringSubmatch(variant); len(match) == 2 { - ndkVersions = append(ndkVersions, match[1]) - } - } - - return ndkVersions -} - -func (d *apiLibraryDecorator) getStubVersions() []string { - stubVersions := []string{} - - for _, variant := range d.properties.Variants { - if match := stubVariantRegex.FindStringSubmatch(variant); len(match) == 2 { - stubVersions = append(stubVersions, match[1]) - } - } - - return stubVersions -} - -// 'cc_api_headers' is similar with 'cc_api_library', but which replaces -// header libraries. The module will replace any dependencies to existing -// original header libraries. -type apiHeadersDecorator struct { - *libraryDecorator -} - -func CcApiHeadersFactory() android.Module { - module, decorator := NewLibrary(android.DeviceSupported) - apiHeadersDecorator := &apiHeadersDecorator{ - libraryDecorator: decorator, - } - apiHeadersDecorator.HeaderOnly() - - module.stl = nil - module.sanitize = nil - decorator.disableStripping() - - module.compiler = nil - module.linker = apiHeadersDecorator - module.installer = nil - - // Prevent default system libs (libc, libm, and libdl) from being linked - if apiHeadersDecorator.baseLinker.Properties.System_shared_libs == nil { - apiHeadersDecorator.baseLinker.Properties.System_shared_libs = []string{} - } - - apiHeadersDecorator.baseLinker.Properties.No_libcrt = BoolPtr(true) - apiHeadersDecorator.baseLinker.Properties.Nocrt = BoolPtr(true) - - module.Init() - - return module -} - -func (d *apiHeadersDecorator) Name(basename string) string { - return basename + multitree.GetApiImportSuffix() -} - -func (d *apiHeadersDecorator) availableFor(what string) bool { - // Stub from API surface should be available for any APEX. - return true -} - -type ccApiexportProperties struct { - Src *string `android:"arch_variant"` - Variant *string - Version *string -} - -type variantExporterProperties struct { - // Header directory to export - Export_include_dirs []string `android:"arch_variant"` - - // Export all headers as system include - Export_headers_as_system *bool -} - -type CcApiVariant struct { - android.ModuleBase - - properties ccApiexportProperties - exportProperties variantExporterProperties - - src android.Path -} - -var _ android.Module = (*CcApiVariant)(nil) -var _ android.ImageInterface = (*CcApiVariant)(nil) - -func CcApiVariantFactory() android.Module { - module := &CcApiVariant{} - - module.AddProperties(&module.properties) - module.AddProperties(&module.exportProperties) - - android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibBoth) - return module -} - -func (v *CcApiVariant) GenerateAndroidBuildActions(ctx android.ModuleContext) { - // No need to build - - if String(v.properties.Src) == "" { - ctx.PropertyErrorf("src", "src is a required property") - } - - // Skip the existence check of the stub prebuilt file. - // The file is not guaranteed to exist during Soong analysis. - // Build orchestrator will be responsible for creating a connected ninja graph. - v.src = android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), String(v.properties.Src)) -} - -func (v *CcApiVariant) Name() string { - version := String(v.properties.Version) - return BuildApiVariantName(v.BaseModuleName(), *v.properties.Variant, version) -} - -func (v *CcApiVariant) Src() android.Path { - return v.src -} - -func BuildApiVariantName(baseName string, variant string, version string) string { - names := []string{baseName, variant} - if version != "" { - names = append(names, version) - } - - return strings.Join(names[:], ".") + multitree.GetApiImportSuffix() -} - -// Implement ImageInterface to generate image variants -func (v *CcApiVariant) ImageMutatorBegin(ctx android.BaseModuleContext) {} -func (v *CcApiVariant) VendorVariantNeeded(ctx android.BaseModuleContext) bool { - return String(v.properties.Variant) == "llndk" -} -func (v *CcApiVariant) ProductVariantNeeded(ctx android.BaseModuleContext) bool { - return String(v.properties.Variant) == "llndk" -} -func (v *CcApiVariant) CoreVariantNeeded(ctx android.BaseModuleContext) bool { - return inList(String(v.properties.Variant), []string{"ndk", "apex"}) -} -func (v *CcApiVariant) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false } -func (v *CcApiVariant) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false } -func (v *CcApiVariant) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false } -func (v *CcApiVariant) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool { return false } -func (v *CcApiVariant) ExtraImageVariations(ctx android.BaseModuleContext) []string { return nil } -func (v *CcApiVariant) SetImageVariation(ctx android.BaseModuleContext, variation string) { -} diff --git a/cc/sdk.go b/cc/sdk.go index dc1261d68..5dd44d8b8 100644 --- a/cc/sdk.go +++ b/cc/sdk.go @@ -51,13 +51,6 @@ func (sdkTransitionMutator) Split(ctx android.BaseModuleContext) []string { return []string{""} } } - case *CcApiVariant: - ccApiVariant, _ := ctx.Module().(*CcApiVariant) - if String(ccApiVariant.properties.Variant) == "ndk" { - return []string{"sdk"} - } else { - return []string{""} - } } return []string{""} @@ -84,11 +77,6 @@ func (sdkTransitionMutator) IncomingTransition(ctx android.IncomingTransitionCon return incomingVariation } } - case *CcApiVariant: - ccApiVariant, _ := ctx.Module().(*CcApiVariant) - if String(ccApiVariant.properties.Variant) == "ndk" { - return "sdk" - } } if ctx.IsAddingDependency() { diff --git a/cc/testing.go b/cc/testing.go index 159f86c60..14a6b7a6a 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -20,7 +20,6 @@ import ( "android/soong/android" "android/soong/genrule" - "android/soong/multitree" ) func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) { @@ -29,9 +28,6 @@ func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) { RegisterBinaryBuildComponents(ctx) RegisterLibraryBuildComponents(ctx) RegisterLibraryHeadersBuildComponents(ctx) - RegisterLibraryStubBuildComponents(ctx) - - multitree.RegisterApiImportsModule(ctx) ctx.RegisterModuleType("prebuilt_build_tool", android.NewPrebuiltBuildTool) ctx.RegisterModuleType("cc_benchmark", BenchmarkFactory) diff --git a/multitree/Android.bp b/multitree/Android.bp deleted file mode 100644 index 78c49627b..000000000 --- a/multitree/Android.bp +++ /dev/null @@ -1,20 +0,0 @@ -package { - default_applicable_licenses: ["Android-Apache-2.0"], -} - -bootstrap_go_package { - name: "soong-multitree", - pkgPath: "android/soong/multitree", - deps: [ - "blueprint", - "soong-android", - ], - srcs: [ - "api_imports.go", - "api_surface.go", - "export.go", - "metadata.go", - "import.go", - ], - pluginFor: ["soong_build"], -} diff --git a/multitree/api_imports.go b/multitree/api_imports.go deleted file mode 100644 index 51b9e07a5..000000000 --- a/multitree/api_imports.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2022 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 multitree - -import ( - "android/soong/android" - "strings" - - "github.com/google/blueprint" -) - -var ( - apiImportNameSuffix = ".apiimport" -) - -func init() { - RegisterApiImportsModule(android.InitRegistrationContext) - android.RegisterMakeVarsProvider(pctx, makeVarsProvider) -} - -func RegisterApiImportsModule(ctx android.RegistrationContext) { - ctx.RegisterModuleType("api_imports", apiImportsFactory) -} - -type ApiImports struct { - android.ModuleBase - properties apiImportsProperties -} - -type apiImportsProperties struct { - Shared_libs []string // List of C shared libraries from API surfaces - Header_libs []string // List of C header libraries from API surfaces - Apex_shared_libs []string // List of C shared libraries with APEX stubs -} - -// 'api_imports' is a module which describes modules available from API surfaces. -// This module is required to get the list of all imported API modules, because -// it is discouraged to loop and fetch all modules from its type information. The -// only module with name 'api_imports' will be used from the build. -func apiImportsFactory() android.Module { - module := &ApiImports{} - module.AddProperties(&module.properties) - android.InitAndroidModule(module) - return module -} - -func (imports *ApiImports) GenerateAndroidBuildActions(ctx android.ModuleContext) { - // ApiImport module does not generate any build actions -} - -type ApiImportInfo struct { - SharedLibs, HeaderLibs, ApexSharedLibs map[string]string -} - -var ApiImportsProvider = blueprint.NewMutatorProvider[ApiImportInfo]("deps") - -// Store module lists into ApiImportInfo and share it over mutator provider. -func (imports *ApiImports) DepsMutator(ctx android.BottomUpMutatorContext) { - generateNameMapWithSuffix := func(names []string) map[string]string { - moduleNameMap := make(map[string]string) - for _, name := range names { - moduleNameMap[name] = name + apiImportNameSuffix - } - - return moduleNameMap - } - - sharedLibs := generateNameMapWithSuffix(imports.properties.Shared_libs) - headerLibs := generateNameMapWithSuffix(imports.properties.Header_libs) - apexSharedLibs := generateNameMapWithSuffix(imports.properties.Apex_shared_libs) - - android.SetProvider(ctx, ApiImportsProvider, ApiImportInfo{ - SharedLibs: sharedLibs, - HeaderLibs: headerLibs, - ApexSharedLibs: apexSharedLibs, - }) -} - -func GetApiImportSuffix() string { - return apiImportNameSuffix -} - -func makeVarsProvider(ctx android.MakeVarsContext) { - ctx.VisitAllModules(func(m android.Module) { - if i, ok := m.(*ApiImports); ok { - ctx.Strict("API_IMPORTED_SHARED_LIBRARIES", strings.Join(i.properties.Shared_libs, " ")) - ctx.Strict("API_IMPORTED_HEADER_LIBRARIES", strings.Join(i.properties.Header_libs, " ")) - } - }) -} diff --git a/multitree/api_surface.go b/multitree/api_surface.go deleted file mode 100644 index 0f605d84a..000000000 --- a/multitree/api_surface.go +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2021 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 multitree - -import ( - "android/soong/android" - "github.com/google/blueprint" -) - -var ( - pctx = android.NewPackageContext("android/soong/multitree") -) - -func init() { - RegisterApiSurfaceBuildComponents(android.InitRegistrationContext) -} - -var PrepareForTestWithApiSurface = android.FixtureRegisterWithContext(RegisterApiSurfaceBuildComponents) - -func RegisterApiSurfaceBuildComponents(ctx android.RegistrationContext) { - ctx.RegisterModuleType("api_surface", ApiSurfaceFactory) -} - -type ApiSurface struct { - android.ModuleBase - ExportableModuleBase - properties apiSurfaceProperties - - taggedOutputs map[string]android.Paths -} - -type apiSurfaceProperties struct { - Contributions []string -} - -func ApiSurfaceFactory() android.Module { - module := &ApiSurface{} - module.AddProperties(&module.properties) - android.InitAndroidModule(module) - InitExportableModule(module) - return module -} - -func (surface *ApiSurface) DepsMutator(ctx android.BottomUpMutatorContext) { - if surface.properties.Contributions != nil { - ctx.AddVariationDependencies(nil, nil, surface.properties.Contributions...) - } - -} -func (surface *ApiSurface) GenerateAndroidBuildActions(ctx android.ModuleContext) { - contributionFiles := make(map[string]android.Paths) - var allOutputs android.Paths - ctx.WalkDeps(func(child, parent android.Module) bool { - if contribution, ok := child.(ApiContribution); ok { - copied := contribution.CopyFilesWithTag(ctx) - for tag, files := range copied { - contributionFiles[child.Name()+"#"+tag] = files - } - for _, paths := range copied { - allOutputs = append(allOutputs, paths...) - } - return false // no transitive dependencies - } - return false - }) - - // phony target - ctx.Build(pctx, android.BuildParams{ - Rule: blueprint.Phony, - Output: android.PathForPhony(ctx, ctx.ModuleName()), - Inputs: allOutputs, - }) - - surface.taggedOutputs = contributionFiles - - ctx.SetOutputFiles(allOutputs, "") -} - -func (surface *ApiSurface) TaggedOutputs() map[string]android.Paths { - return surface.taggedOutputs -} - -func (surface *ApiSurface) Exportable() bool { - return true -} - -var _ Exportable = (*ApiSurface)(nil) - -type ApiContribution interface { - // copy files necessaryt to construct an API surface - // For C, it will be map.txt and .h files - // For Java, it will be api.txt - CopyFilesWithTag(ctx android.ModuleContext) map[string]android.Paths // output paths - - // Generate Android.bp in out/ to use the exported .txt files - // GenerateBuildFiles(ctx ModuleContext) Paths //output paths -} diff --git a/multitree/export.go b/multitree/export.go deleted file mode 100644 index 8be8f7058..000000000 --- a/multitree/export.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2022 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 multitree - -import ( - "android/soong/android" - - "github.com/google/blueprint/proptools" -) - -type moduleExportProperty struct { - // True if the module is exported to the other components in a multi-tree. - // Any components in the multi-tree can import this module to use. - Export *bool -} - -type ExportableModuleBase struct { - properties moduleExportProperty -} - -type Exportable interface { - // Properties for the exporable module. - exportableModuleProps() *moduleExportProperty - - // Check if this module can be exported. - // If this returns false, the module will not be exported regardless of the 'export' value. - Exportable() bool - - // Returns 'true' if this module has 'export: true' - // This module will not be exported if it returns 'false' to 'Exportable()' interface even if - // it has 'export: true'. - IsExported() bool - - // Map from tags to outputs. - // Each module can tag their outputs for convenience. - TaggedOutputs() map[string]android.Paths -} - -type ExportableModule interface { - android.Module - Exportable -} - -func InitExportableModule(module ExportableModule) { - module.AddProperties(module.exportableModuleProps()) -} - -func (m *ExportableModuleBase) exportableModuleProps() *moduleExportProperty { - return &m.properties -} - -func (m *ExportableModuleBase) IsExported() bool { - return proptools.Bool(m.properties.Export) -} diff --git a/multitree/import.go b/multitree/import.go deleted file mode 100644 index 1e5c421bc..000000000 --- a/multitree/import.go +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2022 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 multitree - -import ( - "android/soong/android" -) - -var ( - nameSuffix = ".imported" -) - -type MultitreeImportedModuleInterface interface { - GetMultitreeImportedModuleName() string -} - -func init() { - android.RegisterModuleType("imported_filegroup", importedFileGroupFactory) - - android.PreArchMutators(RegisterMultitreePreArchMutators) -} - -type importedFileGroupProperties struct { - // Imported modules from the other components in a multi-tree - Imported []string -} - -type importedFileGroup struct { - android.ModuleBase - - properties importedFileGroupProperties - srcs android.Paths -} - -func (ifg *importedFileGroup) Name() string { - return ifg.BaseModuleName() + nameSuffix -} - -func importedFileGroupFactory() android.Module { - module := &importedFileGroup{} - module.AddProperties(&module.properties) - - android.InitAndroidModule(module) - return module -} - -var _ MultitreeImportedModuleInterface = (*importedFileGroup)(nil) - -func (ifg *importedFileGroup) GetMultitreeImportedModuleName() string { - // The base module name of the imported filegroup is used as the imported module name - return ifg.BaseModuleName() -} - -var _ android.SourceFileProducer = (*importedFileGroup)(nil) - -func (ifg *importedFileGroup) Srcs() android.Paths { - return ifg.srcs -} - -func (ifg *importedFileGroup) GenerateAndroidBuildActions(ctx android.ModuleContext) { - // srcs from this module must not be used. Adding a dot path to avoid the empty - // source failure. Still soong returns error when a module wants to build against - // this source, which is intended. - ifg.srcs = android.PathsForModuleSrc(ctx, []string{"."}) -} - -func RegisterMultitreePreArchMutators(ctx android.RegisterMutatorsContext) { - ctx.BottomUp("multitree_imported_rename", MultitreeImportedRenameMutator).Parallel() -} - -func MultitreeImportedRenameMutator(ctx android.BottomUpMutatorContext) { - if m, ok := ctx.Module().(MultitreeImportedModuleInterface); ok { - name := m.GetMultitreeImportedModuleName() - if !ctx.OtherModuleExists(name) { - // Provide an empty filegroup not to break the build while updating the metadata. - // In other cases, soong will report an error to guide users to run 'm update-meta' - // first. - if !ctx.Config().TargetMultitreeUpdateMeta() { - ctx.ModuleErrorf("\"%s\" filegroup must be imported.\nRun 'm update-meta' first to import the filegroup.", name) - } - ctx.Rename(name) - } - } -} diff --git a/multitree/metadata.go b/multitree/metadata.go deleted file mode 100644 index 0eb0efc95..000000000 --- a/multitree/metadata.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2022 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 multitree - -import ( - "android/soong/android" - "encoding/json" -) - -func init() { - android.RegisterParallelSingletonType("update-meta", UpdateMetaSingleton) -} - -func UpdateMetaSingleton() android.Singleton { - return &updateMetaSingleton{} -} - -type jsonImported struct { - FileGroups map[string][]string `json:",omitempty"` -} - -type metadataJsonFlags struct { - Imported jsonImported `json:",omitempty"` - Exported map[string][]string `json:",omitempty"` -} - -type updateMetaSingleton struct { - importedModules []string - generatedMetadataFile android.OutputPath -} - -func (s *updateMetaSingleton) GenerateBuildActions(ctx android.SingletonContext) { - metadata := metadataJsonFlags{ - Imported: jsonImported{ - FileGroups: make(map[string][]string), - }, - Exported: make(map[string][]string), - } - ctx.VisitAllModules(func(module android.Module) { - if ifg, ok := module.(*importedFileGroup); ok { - metadata.Imported.FileGroups[ifg.BaseModuleName()] = ifg.properties.Imported - } - if e, ok := module.(ExportableModule); ok { - if e.IsExported() && e.Exportable() { - for tag, files := range e.TaggedOutputs() { - // TODO(b/219846705): refactor this to a dictionary - metadata.Exported[e.Name()+":"+tag] = append(metadata.Exported[e.Name()+":"+tag], files.Strings()...) - } - } - } - }) - jsonStr, err := json.Marshal(metadata) - if err != nil { - ctx.Errorf(err.Error()) - } - s.generatedMetadataFile = android.PathForOutput(ctx, "multitree", "metadata.json") - android.WriteFileRule(ctx, s.generatedMetadataFile, string(jsonStr)) -} - -func (s *updateMetaSingleton) MakeVars(ctx android.MakeVarsContext) { - ctx.Strict("MULTITREE_METADATA", s.generatedMetadataFile.String()) -} diff --git a/rust/rust.go b/rust/rust.go index 240c22178..50f822b53 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -29,7 +29,6 @@ import ( "android/soong/cc" cc_config "android/soong/cc/config" "android/soong/fuzz" - "android/soong/multitree" "android/soong/rust/config" ) @@ -1218,47 +1217,6 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { skipModuleList := map[string]bool{} - var apiImportInfo multitree.ApiImportInfo - hasApiImportInfo := false - - ctx.VisitDirectDeps(func(dep android.Module) { - if dep.Name() == "api_imports" { - apiImportInfo, _ = android.OtherModuleProvider(ctx, dep, multitree.ApiImportsProvider) - hasApiImportInfo = true - } - }) - - if hasApiImportInfo { - targetStubModuleList := map[string]string{} - targetOrigModuleList := map[string]string{} - - // Search for dependency which both original module and API imported library with APEX stub exists - ctx.VisitDirectDeps(func(dep android.Module) { - depName := ctx.OtherModuleName(dep) - if apiLibrary, ok := apiImportInfo.ApexSharedLibs[depName]; ok { - targetStubModuleList[apiLibrary] = depName - } - }) - ctx.VisitDirectDeps(func(dep android.Module) { - depName := ctx.OtherModuleName(dep) - if origLibrary, ok := targetStubModuleList[depName]; ok { - targetOrigModuleList[origLibrary] = depName - } - }) - - // Decide which library should be used between original and API imported library - ctx.VisitDirectDeps(func(dep android.Module) { - depName := ctx.OtherModuleName(dep) - if apiLibrary, ok := targetOrigModuleList[depName]; ok { - if cc.ShouldUseStubForApex(ctx, dep) { - skipModuleList[depName] = true - } else { - skipModuleList[apiLibrary] = true - } - } - }) - } - var transitiveAndroidMkSharedLibs []*android.DepSet[string] var directAndroidMkSharedLibs []string @@ -1609,13 +1567,6 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { deps := mod.deps(ctx) var commonDepVariations []blueprint.Variation - apiImportInfo := cc.GetApiImports(mod, actx) - if mod.usePublicApi() || mod.useVendorApi() { - for idx, lib := range deps.SharedLibs { - deps.SharedLibs[idx] = cc.GetReplaceModuleName(lib, apiImportInfo.SharedLibs) - } - } - if ctx.Os() == android.Android { deps.SharedLibs, _ = cc.FilterNdkLibs(mod, ctx.Config(), deps.SharedLibs) } @@ -1708,15 +1659,7 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { variations := []blueprint.Variation{ {Mutator: "link", Variation: "shared"}, } - // For core variant, add a dep on the implementation (if it exists) and its .apiimport (if it exists) - // GenerateAndroidBuildActions will pick the correct impl/stub based on the api_domain boundary - if _, ok := apiImportInfo.ApexSharedLibs[name]; !ok || ctx.OtherModuleExists(name) { - cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, name, version, false) - } - - if apiLibraryName, ok := apiImportInfo.ApexSharedLibs[name]; ok { - cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, apiLibraryName, version, false) - } + cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, name, version, false) } for _, lib := range deps.WholeStaticLibs { From 7df32b1f695f4aca27fe8d41d904a4281b75dbc2 Mon Sep 17 00:00:00 2001 From: Wei Li Date: Wed, 11 Sep 2024 19:36:41 +0000 Subject: [PATCH 09/17] Add directories below to Android.mk denylist: device/common/ device/google_car/ vendor/google_contexthub/ vendor/google_data/ vendor/google_elmyra/ vendor/google_mhl/ vendor/google_pdk/ vendor/google_testing/ vendor/partner_testing/ vendor/partner_tools/ vendor/pdk/ Bug: 318428689 Test: CIs Change-Id: I2242c84aaea844ed19bafd20a68c506c99859fea --- ui/build/androidmk_denylist.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ui/build/androidmk_denylist.go b/ui/build/androidmk_denylist.go index 2bad5a88f..2ec897273 100644 --- a/ui/build/androidmk_denylist.go +++ b/ui/build/androidmk_denylist.go @@ -25,6 +25,8 @@ var androidmk_denylist []string = []string{ "dalvik/", "developers/", "development/", + "device/common/", + "device/google_car/", "device/sample/", "frameworks/", // Do not block other directories in kernel/, see b/319658303. @@ -41,6 +43,15 @@ var androidmk_denylist []string = []string{ "trusty/", // Add back toolchain/ once defensive Android.mk files are removed //"toolchain/", + "vendor/google_contexthub/", + "vendor/google_data/", + "vendor/google_elmyra/", + "vendor/google_mhl/", + "vendor/google_pdk/", + "vendor/google_testing/", + "vendor/partner_testing/", + "vendor/partner_tools/", + "vendor/pdk/", } func blockAndroidMks(ctx Context, androidMks []string) { From cebc5db94652020b62c1d8bee3c6633ab39773bc Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Wed, 11 Sep 2024 20:21:38 +0000 Subject: [PATCH 10/17] Remove `prebuilt_visibility` from `sdk` This property was introduced for inter module dependencies in the prebuilt module sdk. https://r.android.com/3252814 changed the visibilty of all prebuilts in module sdk to //visibility:public. This property is a noop now, and can be removed. Test: go test ./sdk Bug: 365111645 Change-Id: I186a201895fc2b33a65bbedae8a8326e087feb2b --- sdk/sdk.go | 16 ---------------- sdk/sdk_test.go | 15 --------------- 2 files changed, 31 deletions(-) diff --git a/sdk/sdk.go b/sdk/sdk.go index 2fb3a3f30..aa82abbb4 100644 --- a/sdk/sdk.go +++ b/sdk/sdk.go @@ -84,20 +84,6 @@ type sdkProperties struct { // True if this is a module_exports (or module_exports_snapshot) module type. Module_exports bool `blueprint:"mutated"` - - // The additional visibility to add to the prebuilt modules to allow them to - // reference each other. - // - // This can only be used to widen the visibility of the members: - // - // * Specifying //visibility:public here will make all members visible and - // essentially ignore their own visibility. - // * Specifying //visibility:private here is an error. - // * Specifying any other rule here will add it to the members visibility and - // be output to the member prebuilt in the snapshot. Duplicates will be - // dropped. Adding a rule to members that have //visibility:private will - // cause the //visibility:private to be discarded. - Prebuilt_visibility []string } // sdk defines an SDK which is a logical group of modules (e.g. native libs, headers, java libs, etc.) @@ -130,8 +116,6 @@ func newSdkModule(moduleExports bool) *sdk { s.AddProperties(&s.properties, s.dynamicMemberTypeListProperties, &traitsWrapper) - // Make sure that the prebuilt visibility property is verified for errors. - android.AddVisibilityProperty(s, "prebuilt_visibility", &s.properties.Prebuilt_visibility) android.InitCommonOSAndroidMultiTargetsArchModule(s, android.HostAndDeviceSupported, android.MultilibCommon) android.InitDefaultableModule(s) android.AddLoadHook(s, func(ctx android.LoadHookContext) { diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go index 416dce62c..2532a2581 100644 --- a/sdk/sdk_test.go +++ b/sdk/sdk_test.go @@ -53,9 +53,6 @@ func TestSnapshotVisibility(t *testing.T) { // generated sdk_snapshot. ":__subpackages__", ], - prebuilt_visibility: [ - "//prebuilts/mysdk", - ], java_header_libs: [ "myjavalib", "mypublicjavalib", @@ -162,18 +159,6 @@ java_import { `)) } -func TestPrebuiltVisibilityProperty_IsValidated(t *testing.T) { - testSdkError(t, `prebuilt_visibility: cannot mix "//visibility:private" with any other visibility rules`, ` - sdk { - name: "mysdk", - prebuilt_visibility: [ - "//foo", - "//visibility:private", - ], - } -`) -} - func TestSdkInstall(t *testing.T) { sdk := ` sdk { From 1028d5a53f003d497d9e850780f7d0c28729b343 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Mon, 19 Aug 2024 21:45:48 +0000 Subject: [PATCH 11/17] Create .kzip files for kotlin translation units This CL creates the build rules to invoke the standalone kotlin extractor and create .kzip files for each kotlin translation unit. These will be indexed by the internal g3 kotlin indexers Implementation details - Create a `kotlinKytheExtract` static rule. Its inputs will be source .kt/.srcjar files and other verbatim args passed to kotlinc. The extrator will serialize this information into a .kzip file. The .kzip file should contain the necessary information to "replay" the compilation - Create a xref_kotlin phony rule to build all .kzip files corresponding to kotlin translation units. This implementation has one limitation. Since the kotlin indexers "replay" the compilation using its own version of kotlinc-jvm, there might be indexing issues caused by kotlinc version skew between android builds and indexing builds. `-kotlin-home` can likely solve that, but this CL defers that for now. Bug: 265428637 Test: Built the phony `xref_kotlin`, and ran the indexer locally using go/kythe-git-local-run#indexing-to-local-xrefs-server Change-Id: Ifb370f2df8aa46f71df3fe1ae7d7aa5da773cc8b --- java/base.go | 5 +++-- java/config/config.go | 1 + java/java.go | 10 +++++++++ java/kotlin.go | 50 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/java/base.go b/java/base.go index a63533127..30485d0ca 100644 --- a/java/base.go +++ b/java/base.go @@ -538,7 +538,8 @@ type Module struct { linter // list of the xref extraction files - kytheFiles android.Paths + kytheFiles android.Paths + kytheKotlinFiles android.Paths hideApexVariantFromMake bool @@ -1372,7 +1373,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName) kotlinHeaderJar := android.PathForModuleOut(ctx, "kotlin_headers", jarName) - kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags) + j.kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags) if ctx.Failed() { return } diff --git a/java/config/config.go b/java/config/config.go index a50c1b42d..ca712827f 100644 --- a/java/config/config.go +++ b/java/config/config.go @@ -144,6 +144,7 @@ func init() { pctx.SourcePathVariable("JmodCmd", "${JavaToolchain}/jmod") pctx.SourcePathVariable("JrtFsJar", "${JavaHome}/lib/jrt-fs.jar") pctx.SourcePathVariable("JavaKytheExtractorJar", "prebuilts/build-tools/common/framework/javac_extractor.jar") + pctx.SourcePathVariable("KotlinKytheExtractor", "prebuilts/build-tools/${hostPrebuiltTag}/bin/kotlinc_extractor") pctx.SourcePathVariable("Ziptime", "prebuilts/build-tools/${hostPrebuiltTag}/bin/ziptime") pctx.SourcePathVariable("ResourceProcessorBusyBox", "prebuilts/bazel/common/android_tools/android_tools/all_android_tools_deploy.jar") diff --git a/java/java.go b/java/java.go index 797a90dfc..99f44374f 100644 --- a/java/java.go +++ b/java/java.go @@ -356,12 +356,17 @@ type UsesLibraryDependency interface { // TODO(jungjw): Move this to kythe.go once it's created. type xref interface { XrefJavaFiles() android.Paths + XrefKotlinFiles() android.Paths } func (j *Module) XrefJavaFiles() android.Paths { return j.kytheFiles } +func (j *Module) XrefKotlinFiles() android.Paths { + return j.kytheKotlinFiles +} + func (d dependencyTag) PropagateAconfigValidation() bool { return d.static } @@ -3304,15 +3309,20 @@ type kytheExtractJavaSingleton struct { func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonContext) { var xrefTargets android.Paths + var xrefKotlinTargets android.Paths ctx.VisitAllModules(func(module android.Module) { if javaModule, ok := module.(xref); ok { xrefTargets = append(xrefTargets, javaModule.XrefJavaFiles()...) + xrefKotlinTargets = append(xrefKotlinTargets, javaModule.XrefKotlinFiles()...) } }) // TODO(asmundak): perhaps emit a rule to output a warning if there were no xrefTargets if len(xrefTargets) > 0 { ctx.Phony("xref_java", xrefTargets...) } + if len(xrefKotlinTargets) > 0 { + ctx.Phony("xref_kotlin", xrefKotlinTargets...) + } } var Bool = proptools.Bool diff --git a/java/kotlin.go b/java/kotlin.go index c28bc3f54..79781a06d 100644 --- a/java/kotlin.go +++ b/java/kotlin.go @@ -64,6 +64,29 @@ var kotlinc = pctx.AndroidRemoteStaticRule("kotlinc", android.RemoteRuleSupports "kotlincFlags", "classpath", "srcJars", "commonSrcFilesArg", "srcJarDir", "classesDir", "headerClassesDir", "headerJar", "kotlinJvmTarget", "kotlinBuildFile", "emptyDir", "name") +var kotlinKytheExtract = pctx.AndroidStaticRule("kotlinKythe", + // TODO (b/265428637): To prevent kotlinc version skew between android builds and internal kotlin indexers (g3), consider embedding the kotlinc used by android into the kzip file. + // This has an impact on .kzip sizes, so defer that for now. + blueprint.RuleParams{ + Command: `rm -rf "$srcJarDir" && mkdir -p "$srcJarDir" && ` + + `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" -f "*.kt" $srcJars && ` + + `${config.KotlinKytheExtractor} -corpus ${kytheCorpus} --srcs @$out.rsp --srcs @"$srcJarDir/list" $commonSrcFilesList --cp @$classpath -o $out --kotlin_out $outJar ` + + // wrap the additional kotlin args. + // Skip Xbuild file, pass the cp explicitly. + // Skip header jars, those should not have an effect on kythe results. + ` --args '${config.KotlincGlobalFlags} ` + + ` ${config.KotlincSuppressJDK9Warnings} ${config.JavacHeapFlags} ` + + ` $kotlincFlags -jvm-target $kotlinJvmTarget'`, + CommandDeps: []string{ + "${config.KotlinKytheExtractor}", + "${config.ZipSyncCmd}", + }, + Rspfile: "$out.rsp", + RspfileContent: "$in", + }, + "classpath", "kotlincFlags", "commonSrcFilesList", "kotlinJvmTarget", "outJar", "srcJars", "srcJarDir", +) + func kotlinCommonSrcsList(ctx android.ModuleContext, commonSrcFiles android.Paths) android.OptionalPath { if len(commonSrcFiles) > 0 { // The list of common_srcs may be too long to put on the command line, but @@ -81,7 +104,7 @@ func kotlinCommonSrcsList(ctx android.ModuleContext, commonSrcFiles android.Path } // kotlinCompile takes .java and .kt sources and srcJars, and compiles the .kt sources into a classes jar in outputFile. -func kotlinCompile(ctx android.ModuleContext, outputFile, headerOutputFile android.WritablePath, +func (j *Module) kotlinCompile(ctx android.ModuleContext, outputFile, headerOutputFile android.WritablePath, srcFiles, commonSrcFiles, srcJars android.Paths, flags javaBuilderFlags) { @@ -127,6 +150,31 @@ func kotlinCompile(ctx android.ModuleContext, outputFile, headerOutputFile andro "name": kotlinName, }, }) + + // Emit kythe xref rule + if (ctx.Config().EmitXrefRules()) && ctx.Module() == ctx.PrimaryModule() { + extractionFile := outputFile.ReplaceExtension(ctx, "kzip") + args := map[string]string{ + "classpath": classpathRspFile.String(), + "kotlincFlags": flags.kotlincFlags, + "kotlinJvmTarget": flags.javaVersion.StringForKotlinc(), + "outJar": outputFile.String(), + "srcJars": strings.Join(srcJars.Strings(), " "), + "srcJarDir": android.PathForModuleOut(ctx, "kotlinc", "srcJars.xref").String(), + } + if commonSrcsList.Valid() { + args["commonSrcFilesList"] = "--srcs @" + commonSrcsList.String() + } + ctx.Build(pctx, android.BuildParams{ + Rule: kotlinKytheExtract, + Description: "kotlinKythe", + Output: extractionFile, + Inputs: srcFiles, + Implicits: deps, + Args: args, + }) + j.kytheKotlinFiles = append(j.kytheKotlinFiles, extractionFile) + } } var kaptStubs = pctx.AndroidRemoteStaticRule("kaptStubs", android.RemoteRuleSupports{Goma: true}, From 600afbe381409e77654f73672491492f4c2aeecd Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Wed, 4 Sep 2024 23:49:27 +0000 Subject: [PATCH 12/17] Add kotlin kzips to build_kzip.bash Test: Built the phony xref_kotlin target locally Bug: 265428637 Change-Id: Ib5d6679f17ea45beea8302bc2257e1e4bd0ed7eb --- build_kzip.bash | 1 + 1 file changed, 1 insertion(+) diff --git a/build_kzip.bash b/build_kzip.bash index 4c42048dd..850aedaf0 100755 --- a/build_kzip.bash +++ b/build_kzip.bash @@ -40,6 +40,7 @@ kzip_targets=( merge_zips xref_cxx xref_java + xref_kotlin # TODO: b/286390153 - reenable rust # xref_rust ) From 4e2bf9fb2d3ede98da38a6574a17a6ec2d6bb84e Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Wed, 11 Sep 2024 13:26:20 -0700 Subject: [PATCH 13/17] Add HasMutatorFinished To enforce that selects are only evaluated after a certain point in a followup cl. Bug: 323382414 Test: m nothing --no-skip-soong-tests Change-Id: Ib215fedb904aa2e5f4d65cfd26a23f527eb4983e --- android/androidmk.go | 1 + android/base_module_context.go | 8 ++++++++ android/paths.go | 1 + android/sdk.go | 2 -- android/singleton.go | 8 ++++++++ android/testing.go | 4 ++++ cc/binary_sdk_member.go | 2 +- cc/library_sdk_member.go | 2 +- sdk/update.go | 8 -------- 9 files changed, 24 insertions(+), 12 deletions(-) diff --git a/android/androidmk.go b/android/androidmk.go index 98f8bb111..c175bec7d 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -502,6 +502,7 @@ type fillInEntriesContext interface { otherModuleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) ModuleType(module blueprint.Module) string OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{}) + HasMutatorFinished(mutatorName string) bool } func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) { diff --git a/android/base_module_context.go b/android/base_module_context.go index 550600052..bb8137720 100644 --- a/android/base_module_context.go +++ b/android/base_module_context.go @@ -220,6 +220,10 @@ type BaseModuleContext interface { // EvaluateConfiguration makes ModuleContext a valid proptools.ConfigurableEvaluator, so this context // can be used to evaluate the final value of Configurable properties. EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue + + // HasMutatorFinished returns true if the given mutator has finished running. + // It will panic if given an invalid mutator name. + HasMutatorFinished(mutatorName string) bool } type baseModuleContext struct { @@ -270,6 +274,10 @@ func (b *baseModuleContext) setProvider(provider blueprint.AnyProviderKey, value b.bp.SetProvider(provider, value) } +func (b *baseModuleContext) HasMutatorFinished(mutatorName string) bool { + return b.bp.HasMutatorFinished(mutatorName) +} + func (b *baseModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module { return b.bp.GetDirectDepWithTag(name, tag) } diff --git a/android/paths.go b/android/paths.go index e45795989..6322f7566 100644 --- a/android/paths.go +++ b/android/paths.go @@ -94,6 +94,7 @@ type ModuleWithDepsPathContext interface { EarlyModulePathContext VisitDirectDepsBlueprint(visit func(blueprint.Module)) OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag + HasMutatorFinished(mutatorName string) bool } // ModuleMissingDepsPathContext is a subset of *ModuleContext methods required by diff --git a/android/sdk.go b/android/sdk.go index fb1ac24d4..ab9a91ccb 100644 --- a/android/sdk.go +++ b/android/sdk.go @@ -813,8 +813,6 @@ type SdkMemberProperties interface { // SdkMemberContext provides access to information common to a specific member. type SdkMemberContext interface { - ConfigurableEvaluatorContext - // SdkModuleContext returns the module context of the sdk common os variant which is creating the // snapshot. // diff --git a/android/singleton.go b/android/singleton.go index 8542bd9e6..913bf6a56 100644 --- a/android/singleton.go +++ b/android/singleton.go @@ -90,6 +90,10 @@ type SingletonContext interface { // OtherModulePropertyErrorf reports an error on the line number of the given property of the given module OtherModulePropertyErrorf(module Module, property string, format string, args ...interface{}) + + // HasMutatorFinished returns true if the given mutator has finished running. + // It will panic if given an invalid mutator name. + HasMutatorFinished(mutatorName string) bool } type singletonAdaptor struct { @@ -286,3 +290,7 @@ func (s *singletonContextAdaptor) otherModuleProvider(module blueprint.Module, p func (s *singletonContextAdaptor) OtherModulePropertyErrorf(module Module, property string, format string, args ...interface{}) { s.blueprintSingletonContext().OtherModulePropertyErrorf(module, property, format, args...) } + +func (s *singletonContextAdaptor) HasMutatorFinished(mutatorName string) bool { + return s.blueprintSingletonContext().HasMutatorFinished(mutatorName) +} diff --git a/android/testing.go b/android/testing.go index 42cd1ebbe..1ee6e4cdb 100644 --- a/android/testing.go +++ b/android/testing.go @@ -1326,6 +1326,10 @@ func (ctx *panickingConfigAndErrorContext) Config() Config { return ctx.ctx.Config() } +func (ctx *panickingConfigAndErrorContext) HasMutatorFinished(mutatorName string) bool { + return ctx.ctx.HasMutatorFinished(mutatorName) +} + func PanickingConfigAndErrorContext(ctx *TestContext) ConfigurableEvaluatorContext { return &panickingConfigAndErrorContext{ ctx: ctx, diff --git a/cc/binary_sdk_member.go b/cc/binary_sdk_member.go index 8a7ea8845..4063714ab 100644 --- a/cc/binary_sdk_member.go +++ b/cc/binary_sdk_member.go @@ -132,7 +132,7 @@ func (p *nativeBinaryInfoProperties) PopulateFromVariant(ctx android.SdkMemberCo if ccModule.linker != nil { specifiedDeps := specifiedDeps{} - specifiedDeps = ccModule.linker.linkerSpecifiedDeps(ctx, ccModule, specifiedDeps) + specifiedDeps = ccModule.linker.linkerSpecifiedDeps(ctx.SdkModuleContext(), ccModule, specifiedDeps) p.SharedLibs = specifiedDeps.sharedLibs p.SystemSharedLibs = specifiedDeps.systemSharedLibs diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go index 053c46069..af3658d58 100644 --- a/cc/library_sdk_member.go +++ b/cc/library_sdk_member.go @@ -543,7 +543,7 @@ func (p *nativeLibInfoProperties) PopulateFromVariant(ctx android.SdkMemberConte p.ExportedFlags = exportedInfo.Flags if ccModule.linker != nil { specifiedDeps := specifiedDeps{} - specifiedDeps = ccModule.linker.linkerSpecifiedDeps(ctx, ccModule, specifiedDeps) + specifiedDeps = ccModule.linker.linkerSpecifiedDeps(ctx.SdkModuleContext(), ccModule, specifiedDeps) if lib := ccModule.library; lib != nil { if !lib.hasStubsVariants() { diff --git a/sdk/update.go b/sdk/update.go index 93bb861e9..ec87a75d9 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -1993,14 +1993,6 @@ func (m *memberContext) IsTargetBuildBeforeTiramisu() bool { return m.builder.targetBuildRelease.EarlierThan(buildReleaseT) } -func (m *memberContext) Config() android.Config { - return m.sdkMemberContext.Config() -} - -func (m *memberContext) OtherModulePropertyErrorf(module android.Module, property string, fmt string, args ...interface{}) { - m.sdkMemberContext.OtherModulePropertyErrorf(module, property, fmt, args) -} - var _ android.SdkMemberContext = (*memberContext)(nil) func (s *sdk) createMemberSnapshot(ctx *memberContext, member *sdkMember, bpModule *bpModule) { From 2261a82dbd9599fc1a7091fffea6931fbb5c4963 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Thu, 12 Sep 2024 00:01:54 +0000 Subject: [PATCH 14/17] Remove unused property naming_scheme in java_sdk_library The property was introduced as an interim solution, and is currently unused. Test: m nothing --no-skip-soong-tests Bug: 366071058 Change-Id: I57abdb64fabdb34fbbd1190851bc528dbb88c7f8 --- java/java_test.go | 2 +- java/sdk_library.go | 80 ++++------------------------------------ java/sdk_library_test.go | 2 +- sdk/java_sdk_test.go | 55 --------------------------- 4 files changed, 9 insertions(+), 130 deletions(-) diff --git a/java/java_test.go b/java/java_test.go index e4e6bca9c..c13db3e30 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -2674,7 +2674,7 @@ func TestDisableFromTextStubForCoverageBuild(t *testing.T) { android.AssertBoolEquals(t, "stub module expected to depend on from-source stub", true, CheckModuleHasDependency(t, result.TestContext, apiScopePublic.stubsLibraryModuleName("foo"), "android_common", - apiScopePublic.sourceStubLibraryModuleName("foo"))) + apiScopePublic.sourceStubsLibraryModuleName("foo"))) android.AssertBoolEquals(t, "stub module expected to not depend on from-text stub", false, CheckModuleHasDependency(t, result.TestContext, diff --git a/java/sdk_library.go b/java/sdk_library.go index b7aa4e56d..725aaed9b 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -248,7 +248,7 @@ func (scope *apiScope) apiLibraryModuleName(baseName string) string { return scope.stubsLibraryModuleName(baseName) + ".from-text" } -func (scope *apiScope) sourceStubLibraryModuleName(baseName string) string { +func (scope *apiScope) sourceStubsLibraryModuleName(baseName string) string { return scope.stubsLibraryModuleName(baseName) + ".from-source" } @@ -830,16 +830,6 @@ func (paths *scopePaths) extractLatestRemovedApiPath(ctx android.ModuleContext, } type commonToSdkLibraryAndImportProperties struct { - // The naming scheme to use for the components that this module creates. - // - // If not specified then it defaults to "default". - // - // This is a temporary mechanism to simplify conversion from separate modules for each - // component that follow a different naming pattern to the default one. - // - // TODO(b/155480189) - Remove once naming inconsistencies have been resolved. - Naming_scheme *string - // Specifies whether this module can be used as an Android shared library; defaults // to true. // @@ -915,8 +905,6 @@ type commonToSdkLibraryAndImport struct { scopePaths map[*apiScope]*scopePaths - namingScheme sdkLibraryComponentNamingScheme - commonSdkLibraryProperties commonToSdkLibraryAndImportProperties // Paths to commonSdkLibraryProperties.Doctag_files @@ -944,15 +932,6 @@ func (c *commonToSdkLibraryAndImport) initCommon(module commonSdkLibraryAndImpor } func (c *commonToSdkLibraryAndImport) initCommonAfterDefaultsApplied(ctx android.DefaultableHookContext) bool { - schemeProperty := proptools.StringDefault(c.commonSdkLibraryProperties.Naming_scheme, "default") - switch schemeProperty { - case "default": - c.namingScheme = &defaultNamingScheme{} - default: - ctx.PropertyErrorf("naming_scheme", "expected 'default' but was %q", schemeProperty) - return false - } - namePtr := proptools.StringPtr(c.module.RootLibraryName()) c.sdkLibraryComponentProperties.SdkLibraryName = namePtr @@ -995,41 +974,41 @@ func (c *commonToSdkLibraryAndImport) xmlPermissionsModuleName() string { // Name of the java_library module that compiles the stubs source. func (c *commonToSdkLibraryAndImport) stubsLibraryModuleName(apiScope *apiScope) string { baseName := c.module.RootLibraryName() - return c.namingScheme.stubsLibraryModuleName(apiScope, baseName) + return apiScope.stubsLibraryModuleName(baseName) } // Name of the java_library module that compiles the exportable stubs source. func (c *commonToSdkLibraryAndImport) exportableStubsLibraryModuleName(apiScope *apiScope) string { baseName := c.module.RootLibraryName() - return c.namingScheme.exportableStubsLibraryModuleName(apiScope, baseName) + return apiScope.exportableStubsLibraryModuleName(baseName) } // Name of the droidstubs module that generates the stubs source and may also // generate/check the API. func (c *commonToSdkLibraryAndImport) stubsSourceModuleName(apiScope *apiScope) string { baseName := c.module.RootLibraryName() - return c.namingScheme.stubsSourceModuleName(apiScope, baseName) + return apiScope.stubsSourceModuleName(baseName) } // Name of the java_api_library module that generates the from-text stubs source // and compiles to a jar file. func (c *commonToSdkLibraryAndImport) apiLibraryModuleName(apiScope *apiScope) string { baseName := c.module.RootLibraryName() - return c.namingScheme.apiLibraryModuleName(apiScope, baseName) + return apiScope.apiLibraryModuleName(baseName) } // Name of the java_library module that compiles the stubs // generated from source Java files. func (c *commonToSdkLibraryAndImport) sourceStubsLibraryModuleName(apiScope *apiScope) string { baseName := c.module.RootLibraryName() - return c.namingScheme.sourceStubsLibraryModuleName(apiScope, baseName) + return apiScope.sourceStubsLibraryModuleName(baseName) } // Name of the java_library module that compiles the exportable stubs // generated from source Java files. func (c *commonToSdkLibraryAndImport) exportableSourceStubsLibraryModuleName(apiScope *apiScope) string { baseName := c.module.RootLibraryName() - return c.namingScheme.exportableSourceStubsLibraryModuleName(apiScope, baseName) + return apiScope.exportableSourceStubsLibraryModuleName(baseName) } // The component names for different outputs of the java_sdk_library. @@ -2395,50 +2374,6 @@ func (module *SdkLibrary) defaultsToStubs() bool { return proptools.Bool(module.sdkLibraryProperties.Default_to_stubs) } -// Defines how to name the individual component modules the sdk library creates. -type sdkLibraryComponentNamingScheme interface { - stubsLibraryModuleName(scope *apiScope, baseName string) string - - stubsSourceModuleName(scope *apiScope, baseName string) string - - apiLibraryModuleName(scope *apiScope, baseName string) string - - sourceStubsLibraryModuleName(scope *apiScope, baseName string) string - - exportableStubsLibraryModuleName(scope *apiScope, baseName string) string - - exportableSourceStubsLibraryModuleName(scope *apiScope, baseName string) string -} - -type defaultNamingScheme struct { -} - -func (s *defaultNamingScheme) stubsLibraryModuleName(scope *apiScope, baseName string) string { - return scope.stubsLibraryModuleName(baseName) -} - -func (s *defaultNamingScheme) stubsSourceModuleName(scope *apiScope, baseName string) string { - return scope.stubsSourceModuleName(baseName) -} - -func (s *defaultNamingScheme) apiLibraryModuleName(scope *apiScope, baseName string) string { - return scope.apiLibraryModuleName(baseName) -} - -func (s *defaultNamingScheme) sourceStubsLibraryModuleName(scope *apiScope, baseName string) string { - return scope.sourceStubLibraryModuleName(baseName) -} - -func (s *defaultNamingScheme) exportableStubsLibraryModuleName(scope *apiScope, baseName string) string { - return scope.exportableStubsLibraryModuleName(baseName) -} - -func (s *defaultNamingScheme) exportableSourceStubsLibraryModuleName(scope *apiScope, baseName string) string { - return scope.exportableSourceStubsLibraryModuleName(baseName) -} - -var _ sdkLibraryComponentNamingScheme = (*defaultNamingScheme)(nil) - func moduleStubLinkType(j *Module) (stub bool, ret sdkLinkType) { kind := android.ToSdkKind(proptools.String(j.properties.Stub_contributing_api)) switch kind { @@ -3510,7 +3445,6 @@ func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMembe } } - s.Naming_scheme = sdk.commonSdkLibraryProperties.Naming_scheme s.Shared_library = proptools.BoolPtr(sdk.sharedLibrary()) s.Compile_dex = sdk.dexProperties.Compile_dex s.Doctag_paths = sdk.doctagPaths diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go index bb6331506..31fbc5a58 100644 --- a/java/sdk_library_test.go +++ b/java/sdk_library_test.go @@ -422,7 +422,7 @@ func TestJavaSdkLibrary_StubOrImplOnlyLibs(t *testing.T) { for _, expectation := range expectations { verify("sdklib.impl", expectation.lib, expectation.on_impl_classpath, expectation.in_impl_combined) - stubName := apiScopePublic.sourceStubLibraryModuleName("sdklib") + stubName := apiScopePublic.sourceStubsLibraryModuleName("sdklib") verify(stubName, expectation.lib, expectation.on_stub_classpath, expectation.in_stub_combined) } } diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go index 0fb5c70d2..09a7c9e8c 100644 --- a/sdk/java_sdk_test.go +++ b/sdk/java_sdk_test.go @@ -1703,61 +1703,6 @@ java_sdk_library_import { ) } -func TestSnapshotWithJavaSdkLibrary_NamingScheme(t *testing.T) { - result := android.GroupFixturePreparers(prepareForSdkTestWithJavaSdkLibrary).RunTestWithBp(t, ` - sdk { - name: "mysdk", - java_sdk_libs: ["myjavalib"], - } - - java_sdk_library { - name: "myjavalib", - apex_available: ["//apex_available:anyapex"], - srcs: ["Test.java"], - sdk_version: "current", - naming_scheme: "default", - public: { - enabled: true, - }, - } - `) - - CheckSnapshot(t, result, "mysdk", "", - checkAndroidBpContents(` -// This is auto-generated. DO NOT EDIT. - -apex_contributions_defaults { - name: "mysdk.contributions", - contents: ["prebuilt_myjavalib"], -} - -java_sdk_library_import { - name: "myjavalib", - prefer: false, - visibility: ["//visibility:public"], - apex_available: ["//apex_available:anyapex"], - naming_scheme: "default", - shared_library: true, - public: { - jars: ["sdk_library/public/myjavalib-stubs.jar"], - stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], - current_api: "sdk_library/public/myjavalib.txt", - removed_api: "sdk_library/public/myjavalib-removed.txt", - sdk_version: "current", - }, -} -`), - checkAllCopyRules(` -.intermediates/myjavalib.stubs.exportable/android_common/combined/myjavalib.stubs.exportable.jar -> sdk_library/public/myjavalib-stubs.jar -.intermediates/myjavalib.stubs.source/android_common/exportable/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib.txt -.intermediates/myjavalib.stubs.source/android_common/exportable/myjavalib.stubs.source_removed.txt -> sdk_library/public/myjavalib-removed.txt -`), - checkMergeZips( - ".intermediates/mysdk/common_os/tmp/sdk_library/public/myjavalib_stub_sources.zip", - ), - ) -} - func TestSnapshotWithJavaSdkLibrary_DoctagFiles(t *testing.T) { result := android.GroupFixturePreparers( prepareForSdkTestWithJavaSdkLibrary, From 6e0280d795d1b26803aebd00b7991d8eaf661b0f Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Wed, 11 Sep 2024 23:51:35 +0000 Subject: [PATCH 15/17] Introduce a util method PrettyConcat The method can be used when printing string list in a well-formated way in user-facing messages. This will be used in a follow up change. Test: m nothing --no-skip-soong-tests Change-Id: I77e3445a5333f82067dd8f1bb6ad892c69754ece --- android/util.go | 35 ++++++++++++++++++++++++++++++++ android/util_test.go | 48 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/android/util.go b/android/util.go index 3c0af2f38..2d269b724 100644 --- a/android/util.go +++ b/android/util.go @@ -177,6 +177,41 @@ func setFromList[T comparable](l []T) map[T]bool { return m } +// PrettyConcat returns the formatted concatenated string suitable for displaying user-facing +// messages. +func PrettyConcat(list []string, quote bool, lastSep string) string { + if len(list) == 0 { + return "" + } + + quoteStr := func(v string) string { + if !quote { + return v + } + return fmt.Sprintf("%q", v) + } + + if len(list) == 1 { + return quoteStr(list[0]) + } + + var sb strings.Builder + for i, val := range list { + if i > 0 { + sb.WriteString(", ") + } + if i == len(list)-1 { + sb.WriteString(lastSep) + if lastSep != "" { + sb.WriteString(" ") + } + } + sb.WriteString(quoteStr(val)) + } + + return sb.String() +} + // ListSetDifference checks if the two lists contain the same elements. It returns // a boolean which is true if there is a difference, and then returns lists of elements // that are in l1 but not l2, and l2 but not l1. diff --git a/android/util_test.go b/android/util_test.go index 6537d69b9..b76ffcfea 100644 --- a/android/util_test.go +++ b/android/util_test.go @@ -867,3 +867,51 @@ func TestHasIntersection(t *testing.T) { }) } } + +var prettyConcatTestCases = []struct { + name string + list []string + quote bool + lastSeparator string + expected string +}{ + { + name: "empty", + list: []string{}, + quote: false, + lastSeparator: "and", + expected: ``, + }, + { + name: "single", + list: []string{"a"}, + quote: true, + lastSeparator: "and", + expected: `"a"`, + }, + { + name: "with separator", + list: []string{"a", "b", "c"}, + quote: true, + lastSeparator: "or", + expected: `"a", "b", or "c"`, + }, + { + name: "without separator", + list: []string{"a", "b", "c"}, + quote: false, + lastSeparator: "", + expected: `a, b, c`, + }, +} + +func TestPrettyConcat(t *testing.T) { + for _, testCase := range prettyConcatTestCases { + t.Run(testCase.name, func(t *testing.T) { + concatString := PrettyConcat(testCase.list, testCase.quote, testCase.lastSeparator) + if !reflect.DeepEqual(concatString, testCase.expected) { + t.Errorf("expected %#v, got %#v", testCase.expected, concatString) + } + }) + } +} From 1496fb167548823625efd5e67ba6e3fd098ec1b9 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 9 Sep 2024 16:44:10 -0700 Subject: [PATCH 16/17] Wrap blueprint_go_binary and bootstrap_go_package into android.Modules Depending on a blueprint_go_binary from a Soong module requires hacks that allow Soong to support both blueprint.Module and android.Module. Wrap the blueprint Go module types with ones that implement android.Module, and delete all the related hacks. Bug: 319288033 Test: m checkbuild Flag: EXEMPT refactor Change-Id: I9b62b450de09bd10288333fbc66aa71c867ae0b3 --- android/androidmk.go | 20 ------- android/arch.go | 50 ++-------------- android/module_context.go | 6 +- android/mutator.go | 4 +- android/paths.go | 12 ---- genrule/genrule.go | 6 -- golang/Android.bp | 22 +++++++ golang/golang.go | 122 ++++++++++++++++++++++++++++++++++++++ golang/golang_test.go | 51 ++++++++++++++++ 9 files changed, 205 insertions(+), 88 deletions(-) create mode 100644 golang/Android.bp create mode 100644 golang/golang.go create mode 100644 golang/golang_test.go diff --git a/android/androidmk.go b/android/androidmk.go index 5fb0cd167..cac2cfe47 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -34,7 +34,6 @@ import ( "strings" "github.com/google/blueprint" - "github.com/google/blueprint/bootstrap" "github.com/google/blueprint/pathtools" "github.com/google/blueprint/proptools" ) @@ -815,8 +814,6 @@ func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs switch x := mod.(type) { case AndroidMkDataProvider: err = translateAndroidModule(ctx, w, moduleInfoJSONs, mod, x) - case bootstrap.GoBinaryTool: - err = translateGoBinaryModule(ctx, w, mod, x) case AndroidMkEntriesProvider: err = translateAndroidMkEntriesModule(ctx, w, moduleInfoJSONs, mod, x) default: @@ -831,23 +828,6 @@ func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs return err } -// A simple, special Android.mk entry output func to make it possible to build blueprint tools using -// m by making them phony targets. -func translateGoBinaryModule(ctx SingletonContext, w io.Writer, mod blueprint.Module, - goBinary bootstrap.GoBinaryTool) error { - - name := ctx.ModuleName(mod) - fmt.Fprintln(w, ".PHONY:", name) - fmt.Fprintln(w, name+":", goBinary.InstallPath()) - fmt.Fprintln(w, "") - // Assuming no rules in make include go binaries in distributables. - // If the assumption is wrong, make will fail to build without the necessary .meta_lic and .meta_module files. - // In that case, add the targets and rules here to build a .meta_lic file for `name` and a .meta_module for - // `goBinary.InstallPath()` pointing to the `name`.meta_lic file. - - return nil -} - func (data *AndroidMkData) fillInData(ctx fillInEntriesContext, mod blueprint.Module) { // Get the preamble content through AndroidMkEntries logic. data.Entries = AndroidMkEntries{ diff --git a/android/arch.go b/android/arch.go index 6d896e5fc..a7868bac4 100644 --- a/android/arch.go +++ b/android/arch.go @@ -23,7 +23,6 @@ import ( "strings" "github.com/google/blueprint" - "github.com/google/blueprint/bootstrap" "github.com/google/blueprint/proptools" ) @@ -397,33 +396,8 @@ func (target Target) Variations() []blueprint.Variation { // device_supported and host_supported properties to determine which OsTypes are enabled for this // module, then searches through the Targets to determine which have enabled Targets for this // module. -func osMutator(bpctx blueprint.BottomUpMutatorContext) { - var module Module - var ok bool - if module, ok = bpctx.Module().(Module); !ok { - // The module is not a Soong module, it is a Blueprint module. - if bootstrap.IsBootstrapModule(bpctx.Module()) { - // Bootstrap Go modules are always the build OS or linux bionic. - config := bpctx.Config().(Config) - osNames := []string{config.BuildOSTarget.OsVariation()} - for _, hostCrossTarget := range config.Targets[LinuxBionic] { - if hostCrossTarget.Arch.ArchType == config.BuildOSTarget.Arch.ArchType { - osNames = append(osNames, hostCrossTarget.OsVariation()) - } - } - osNames = FirstUniqueStrings(osNames) - bpctx.CreateVariations(osNames...) - } - return - } - - // Bootstrap Go module support above requires this mutator to be a - // blueprint.BottomUpMutatorContext because android.BottomUpMutatorContext - // filters out non-Soong modules. Now that we've handled them, create a - // normal android.BottomUpMutatorContext. - mctx := bottomUpMutatorContextFactory(bpctx, module, false) - defer bottomUpMutatorContextPool.Put(mctx) - +func osMutator(mctx BottomUpMutatorContext) { + module := mctx.Module() base := module.base() // Nothing to do for modules that are not architecture specific (e.g. a genrule). @@ -553,24 +527,8 @@ var DarwinUniversalVariantTag = archDepTag{name: "darwin universal binary"} // // Modules can be initialized with InitAndroidMultiTargetsArchModule, in which case they will be split by OsClass, // but will have a common Target that is expected to handle all other selected Targets via ctx.MultiTargets(). -func archMutator(bpctx blueprint.BottomUpMutatorContext) { - var module Module - var ok bool - if module, ok = bpctx.Module().(Module); !ok { - if bootstrap.IsBootstrapModule(bpctx.Module()) { - // Bootstrap Go modules are always the build architecture. - bpctx.CreateVariations(bpctx.Config().(Config).BuildOSTarget.ArchVariation()) - } - return - } - - // Bootstrap Go module support above requires this mutator to be a - // blueprint.BottomUpMutatorContext because android.BottomUpMutatorContext - // filters out non-Soong modules. Now that we've handled them, create a - // normal android.BottomUpMutatorContext. - mctx := bottomUpMutatorContextFactory(bpctx, module, false) - defer bottomUpMutatorContextPool.Put(mctx) - +func archMutator(mctx BottomUpMutatorContext) { + module := mctx.Module() base := module.base() if !base.ArchSpecific() { diff --git a/android/module_context.go b/android/module_context.go index 54fe0be17..2bf2a8f00 100644 --- a/android/module_context.go +++ b/android/module_context.go @@ -85,7 +85,9 @@ type ModuleBuildParams BuildParams type ModuleContext interface { BaseModuleContext - blueprintModuleContext() blueprint.ModuleContext + // BlueprintModuleContext returns the blueprint.ModuleContext that the ModuleContext wraps. It may only be + // used by the golang module types that need to call into the bootstrap module types. + BlueprintModuleContext() blueprint.ModuleContext // Deprecated: use ModuleContext.Build instead. ModuleBuild(pctx PackageContext, params ModuleBuildParams) @@ -779,7 +781,7 @@ func (m *moduleContext) UncheckedModule() { m.uncheckedModule = true } -func (m *moduleContext) blueprintModuleContext() blueprint.ModuleContext { +func (m *moduleContext) BlueprintModuleContext() blueprint.ModuleContext { return m.bp } diff --git a/android/mutator.go b/android/mutator.go index 38fb857dd..2ef4d7fef 100644 --- a/android/mutator.go +++ b/android/mutator.go @@ -148,9 +148,9 @@ var preArch = []RegisterMutatorFunc{ } func registerArchMutator(ctx RegisterMutatorsContext) { - ctx.BottomUpBlueprint("os", osMutator).Parallel() + ctx.BottomUp("os", osMutator).Parallel() ctx.Transition("image", &imageTransitionMutator{}) - ctx.BottomUpBlueprint("arch", archMutator).Parallel() + ctx.BottomUp("arch", archMutator).Parallel() } var preDeps = []RegisterMutatorFunc{ diff --git a/android/paths.go b/android/paths.go index 6322f7566..0a4f89187 100644 --- a/android/paths.go +++ b/android/paths.go @@ -27,7 +27,6 @@ import ( "strings" "github.com/google/blueprint" - "github.com/google/blueprint/bootstrap" "github.com/google/blueprint/pathtools" ) @@ -555,13 +554,6 @@ func (p OutputPaths) Strings() []string { return ret } -// PathForGoBinary returns the path to the installed location of a bootstrap_go_binary module. -func PathForGoBinary(ctx PathContext, goBinary bootstrap.GoBinaryTool) Path { - goBinaryInstallDir := pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "bin") - rel := Rel(ctx, goBinaryInstallDir.String(), goBinary.InstallPath()) - return goBinaryInstallDir.Join(ctx, rel) -} - // Expands Paths to a SourceFileProducer or OutputFileProducer module dependency referenced via ":name" or ":name{.tag}" syntax. // If the dependency is not found, a missingErrorDependency is returned. // If the module dependency is not a SourceFileProducer or OutputFileProducer, appropriate errors will be returned. @@ -573,10 +565,6 @@ func getPathsFromModuleDep(ctx ModuleWithDepsPathContext, path, moduleName, tag if aModule, ok := module.(Module); ok && !aModule.Enabled(ctx) { return nil, missingDependencyError{[]string{moduleName}} } - if goBinary, ok := module.(bootstrap.GoBinaryTool); ok && tag == "" { - goBinaryPath := PathForGoBinary(ctx, goBinary) - return Paths{goBinaryPath}, nil - } outputFiles, err := outputFilesForModule(ctx, module, tag) if outputFiles != nil && err == nil { return outputFiles, nil diff --git a/genrule/genrule.go b/genrule/genrule.go index fd72d3c15..a48038bac 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -25,7 +25,6 @@ import ( "strings" "github.com/google/blueprint" - "github.com/google/blueprint/bootstrap" "github.com/google/blueprint/proptools" "android/soong/android" @@ -365,11 +364,6 @@ func (g *Module) generateCommonBuildActions(ctx android.ModuleContext) { tools = append(tools, path.Path()) addLocationLabel(tag.label, toolLocation{android.Paths{path.Path()}}) } - case bootstrap.GoBinaryTool: - // A GoBinaryTool provides the install path to a tool, which will be copied. - p := android.PathForGoBinary(ctx, t) - tools = append(tools, p) - addLocationLabel(tag.label, toolLocation{android.Paths{p}}) default: ctx.ModuleErrorf("%q is not a host tool provider", tool) return diff --git a/golang/Android.bp b/golang/Android.bp new file mode 100644 index 000000000..3eae94fa2 --- /dev/null +++ b/golang/Android.bp @@ -0,0 +1,22 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +bootstrap_go_package { + name: "soong-golang", + pkgPath: "android/soong/golang", + deps: [ + "blueprint", + "blueprint-pathtools", + "blueprint-bootstrap", + "soong", + "soong-android", + ], + srcs: [ + "golang.go", + ], + testSrcs: [ + "golang_test.go", + ], + pluginFor: ["soong_build"], +} diff --git a/golang/golang.go b/golang/golang.go new file mode 100644 index 000000000..ede2150dc --- /dev/null +++ b/golang/golang.go @@ -0,0 +1,122 @@ +// 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 golang wraps the blueprint blueprint_go_binary and bootstrap_go_binary module types in versions +// that implement android.Module that are used when building in Soong. This simplifies the code in Soong +// so it can always assume modules are an android.Module. +// The original blueprint blueprint_go_binary and bootstrap_go_binary module types are still used during +// bootstrapping, so the Android.bp entries for these module types must be compatible with both the +// original blueprint module types and these wrapped module types. +package golang + +import ( + "android/soong/android" + "github.com/google/blueprint" + "github.com/google/blueprint/bootstrap" +) + +func init() { + // Wrap the blueprint Go module types with Soong ones that interoperate with the rest of the Soong modules. + bootstrap.GoModuleTypesAreWrapped() + RegisterGoModuleTypes(android.InitRegistrationContext) +} + +func RegisterGoModuleTypes(ctx android.RegistrationContext) { + ctx.RegisterModuleType("bootstrap_go_package", goPackageModuleFactory) + ctx.RegisterModuleType("blueprint_go_binary", goBinaryModuleFactory) +} + +// A GoPackage is a module for building Go packages. +type GoPackage struct { + android.ModuleBase + bootstrap.GoPackage +} + +func goPackageModuleFactory() android.Module { + module := &GoPackage{} + module.AddProperties(module.Properties()...) + android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst) + return module +} + +func (g *GoPackage) GenerateBuildActions(ctx blueprint.ModuleContext) { + // The embedded ModuleBase and bootstrap.GoPackage each implement GenerateBuildActions, + // the delegation has to be implemented manually to disambiguate. Call ModuleBase's + // GenerateBuildActions, which will call GenerateAndroidBuildActions, which will call + // bootstrap.GoPackage.GenerateBuildActions. + g.ModuleBase.GenerateBuildActions(ctx) +} + +func (g *GoPackage) GenerateAndroidBuildActions(ctx android.ModuleContext) { + g.GoPackage.GenerateBuildActions(ctx.BlueprintModuleContext()) +} + +// A GoBinary is a module for building executable binaries from Go sources. +type GoBinary struct { + android.ModuleBase + bootstrap.GoBinary + + outputFile android.Path +} + +func goBinaryModuleFactory() android.Module { + module := &GoBinary{} + module.AddProperties(module.Properties()...) + android.InitAndroidArchModule(module, android.HostSupportedNoCross, android.MultilibFirst) + return module +} + +func (g *GoBinary) GenerateBuildActions(ctx blueprint.ModuleContext) { + // The embedded ModuleBase and bootstrap.GoBinary each implement GenerateBuildActions, + // the delegation has to be implemented manually to disambiguate. Call ModuleBase's + // GenerateBuildActions, which will call GenerateAndroidBuildActions, which will call + // bootstrap.GoBinary.GenerateBuildActions. + g.ModuleBase.GenerateBuildActions(ctx) +} + +func (g *GoBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) { + // Install the file in Soong instead of blueprint so that Soong knows about the install rules. + g.GoBinary.SetSkipInstall() + + // Run the build actions from the wrapped blueprint bootstrap module. + g.GoBinary.GenerateBuildActions(ctx.BlueprintModuleContext()) + + // Translate the bootstrap module's string path into a Path + outputFile := android.PathForArbitraryOutput(ctx, android.Rel(ctx, ctx.Config().OutDir(), g.IntermediateFile())).WithoutRel() + g.outputFile = outputFile + + installPath := ctx.InstallFile(android.PathForModuleInstall(ctx, "bin"), ctx.ModuleName(), outputFile) + + if !ctx.Config().KatiEnabled() || g.ExportedToMake() { + // Modules in an unexported namespace have no install rule, only add modules in the exported namespaces + // to the blueprint_tools phony rules. + ctx.Phony("blueprint_tools", installPath) + } + + ctx.SetOutputFiles(android.Paths{outputFile}, "") +} + +func (g *GoBinary) HostToolPath() android.OptionalPath { + return android.OptionalPathForPath(g.outputFile) +} + +func (g *GoBinary) AndroidMkEntries() []android.AndroidMkEntries { + return []android.AndroidMkEntries{ + { + Class: "EXECUTABLES", + OutputFile: android.OptionalPathForPath(g.outputFile), + Include: "$(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk", + }, + } +} diff --git a/golang/golang_test.go b/golang/golang_test.go new file mode 100644 index 000000000..b51214402 --- /dev/null +++ b/golang/golang_test.go @@ -0,0 +1,51 @@ +// 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 golang + +import ( + "android/soong/android" + "github.com/google/blueprint/bootstrap" + "path/filepath" + "testing" +) + +func TestGolang(t *testing.T) { + bp := ` + bootstrap_go_package { + name: "gopkg", + pkgPath: "test/pkg", + } + + blueprint_go_binary { + name: "gobin", + deps: ["gopkg"], + } + ` + + result := android.GroupFixturePreparers( + android.PrepareForTestWithArchMutator, + android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { + RegisterGoModuleTypes(ctx) + ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { + ctx.BottomUpBlueprint("bootstrap_deps", bootstrap.BootstrapDeps) + }) + }), + ).RunTestWithBp(t, bp) + + bin := result.ModuleForTests("gobin", result.Config.BuildOSTarget.String()) + + expected := filepath.Join("out/soong/host", result.Config.PrebuiltOS(), "bin/go/gobin/obj/gobin") + android.AssertPathsRelativeToTopEquals(t, "output files", []string{expected}, bin.OutputFiles(result.TestContext, t, "")) +} From d9108d2d343117278ca647f8abe3e40fccb7119d Mon Sep 17 00:00:00 2001 From: Yaowen Mei Date: Thu, 29 Aug 2024 16:56:32 +0000 Subject: [PATCH 17/17] Fix a bug in the log directory cleanup logic. This CL fix the bug that shouldCleanupRBELogsDir() never return true. The way how shouldCleanupRBELogsDir() use to work is it will return true only if `RBE_proxy_log_dir` flag is not set. But CI build always got this flag from gcl file, and developer build always got this flag set from ui/build/rbe.go (http://shortn/_K604iWNYkd). So there is never a case this shouldCleanupRBELogsDir() return true. That is to say, we never clean up RBELogsDir by ourselves. The reason why this is not a concern is that soong will automatically delete the out/soong/.temp folder every time when user run `m` or `lunch`, and the default RBELogsDir use to be `out/soong/.temp/rbe`. So soong is helping us to clean the logs before. Previously, I merged this CL: https://r.android.com/3192211 to support running `lunch` in two terminals. In that CL, I moved the auto created RBELogsDir one level up to `out/soong/rbe`. This is causing a problem because RBELogsDir never get cleaned. This CL will fix the shouldCleanupRBELogsDir() method, after this merged in, 1) if a user didn't set the `RBE_proxy_log_dir` flag, the logs in `out/soong/rbe` will be cleaned each time when running `m`, but `lunch` will not touch `out/soong/rbe`, so we still support running `lunch` in different terminals. 2) If user set `RBE_proxy_log_dir` flag to anything rather than `out/song/rbe`, the directory will not be cleaned by running `m`; 3) we have updated our doc everywhere that `out/soong/rbe` is re-client's default log dir, so I think it should be expected if user set `RBE_proxy_log_dir=out/soong/rbe`, then the logs will be deleted when next time `m` invoked, same as if they set `RBE_proxy_log_dir=out/soong/.temp/rbe` before. Test: abtd run is green: http://shortn/_KqTvQelstP, local build with multiply lunch is not affected, and running m after a build can clean the out/soong/rbe directory. Bug: 362798954 Change-Id: I38a7ad650fc59ad06716c5be7de6ecc61ead8eef --- ui/build/config.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ui/build/config.go b/ui/build/config.go index f02222e1a..d72c8fa01 100644 --- a/ui/build/config.go +++ b/ui/build/config.go @@ -1375,8 +1375,10 @@ func (c *configImpl) shouldCleanupRBELogsDir() bool { // Perform a log directory cleanup only when the log directory // is auto created by the build rather than user-specified. for _, f := range []string{"RBE_proxy_log_dir", "FLAG_output_dir"} { - if _, ok := c.environ.Get(f); ok { - return false + if v, ok := c.environ.Get(f); ok { + if v != c.rbeTmpDir() { + return false + } } } return true