Loading android/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ bootstrap_go_package { "metrics.go", "module.go", "module_context.go", "module_info_json.go", "mutator.go", "namespace.go", "neverallow.go", Loading android/androidmk.go +75 −24 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import ( "reflect" "runtime" "sort" "strconv" "strings" "github.com/google/blueprint" Loading Loading @@ -626,6 +627,10 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint a.SetPath("LOCAL_SOONG_LICENSE_METADATA", licenseMetadata.LicenseMetadataPath) } if _, ok := SingletonModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok { a.SetBool("LOCAL_SOONG_MODULE_INFO_JSON", true) } extraCtx := &androidMkExtraEntriesContext{ ctx: ctx, mod: mod, Loading @@ -643,14 +648,14 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint } } func (a *AndroidMkEntries) 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 *AndroidMkEntries) write(w io.Writer) { if a.Disabled { return } if !a.OutputFile.Valid() { if a.disabled() { return } Loading Loading @@ -696,7 +701,9 @@ func (c *androidMkSingleton) GenerateBuildActions(ctx SingletonContext) { return } err := translateAndroidMk(ctx, absolutePath(transMk.String()), androidMkModulesList) moduleInfoJSON := PathForOutput(ctx, "module-info"+String(ctx.Config().productVariables.Make_suffix)+".json") err := translateAndroidMk(ctx, absolutePath(transMk.String()), moduleInfoJSON, androidMkModulesList) if err != nil { ctx.Errorf(err.Error()) } Loading @@ -707,14 +714,16 @@ func (c *androidMkSingleton) GenerateBuildActions(ctx SingletonContext) { }) } func translateAndroidMk(ctx SingletonContext, absMkFile string, mods []blueprint.Module) error { func translateAndroidMk(ctx SingletonContext, absMkFile string, moduleInfoJSONPath WritablePath, mods []blueprint.Module) error { buf := &bytes.Buffer{} var moduleInfoJSONs []*ModuleInfoJSON fmt.Fprintln(buf, "LOCAL_MODULE_MAKEFILE := $(lastword $(MAKEFILE_LIST))") typeStats := make(map[string]int) for _, mod := range mods { err := translateAndroidMkModule(ctx, buf, mod) err := translateAndroidMkModule(ctx, buf, &moduleInfoJSONs, mod) if err != nil { os.Remove(absMkFile) return err Loading @@ -736,10 +745,36 @@ func translateAndroidMk(ctx SingletonContext, absMkFile string, mods []blueprint fmt.Fprintf(buf, "STATS.SOONG_MODULE_TYPE.%s := %d\n", mod_type, typeStats[mod_type]) } return pathtools.WriteFileIfChanged(absMkFile, buf.Bytes(), 0666) err := pathtools.WriteFileIfChanged(absMkFile, buf.Bytes(), 0666) if err != nil { return err } return writeModuleInfoJSON(ctx, moduleInfoJSONs, moduleInfoJSONPath) } func translateAndroidMkModule(ctx SingletonContext, w io.Writer, mod blueprint.Module) error { func writeModuleInfoJSON(ctx SingletonContext, moduleInfoJSONs []*ModuleInfoJSON, moduleInfoJSONPath WritablePath) error { moduleInfoJSONBuf := &strings.Builder{} moduleInfoJSONBuf.WriteString("[") for i, moduleInfoJSON := range moduleInfoJSONs { if i != 0 { moduleInfoJSONBuf.WriteString(",\n") } moduleInfoJSONBuf.WriteString("{") moduleInfoJSONBuf.WriteString(strconv.Quote(moduleInfoJSON.core.RegisterName)) moduleInfoJSONBuf.WriteString(":") err := encodeModuleInfoJSON(moduleInfoJSONBuf, moduleInfoJSON) moduleInfoJSONBuf.WriteString("}") if err != nil { return err } } moduleInfoJSONBuf.WriteString("]") WriteFileRule(ctx, moduleInfoJSONPath, moduleInfoJSONBuf.String()) return nil } func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, mod blueprint.Module) error { defer func() { if r := recover(); r != nil { panic(fmt.Errorf("%s in translateAndroidMkModule for module %s variant %s", Loading @@ -748,17 +783,23 @@ func translateAndroidMkModule(ctx SingletonContext, w io.Writer, mod blueprint.M }() // Additional cases here require review for correct license propagation to make. var err error switch x := mod.(type) { case AndroidMkDataProvider: return translateAndroidModule(ctx, w, mod, x) err = translateAndroidModule(ctx, w, moduleInfoJSONs, mod, x) case bootstrap.GoBinaryTool: return translateGoBinaryModule(ctx, w, mod, x) err = translateGoBinaryModule(ctx, w, mod, x) case AndroidMkEntriesProvider: return translateAndroidMkEntriesModule(ctx, w, mod, x) err = translateAndroidMkEntriesModule(ctx, w, moduleInfoJSONs, mod, x) default: // Not exported to make so no make variables to set. return nil } if err != nil { return err } return err } // A simple, special Android.mk entry output func to make it possible to build blueprint tools using Loading Loading @@ -801,8 +842,8 @@ func (data *AndroidMkData) fillInData(ctx fillInEntriesContext, mod blueprint.Mo // A support func for the deprecated AndroidMkDataProvider interface. Use AndroidMkEntryProvider // instead. func translateAndroidModule(ctx SingletonContext, w io.Writer, mod blueprint.Module, provider AndroidMkDataProvider) error { func translateAndroidModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, mod blueprint.Module, provider AndroidMkDataProvider) error { amod := mod.(Module).base() if shouldSkipAndroidMkProcessing(amod) { Loading Loading @@ -865,17 +906,19 @@ func translateAndroidModule(ctx SingletonContext, w io.Writer, mod blueprint.Mod WriteAndroidMkData(w, data) } if !data.Entries.disabled() { if moduleInfoJSON, ok := SingletonModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok { *moduleInfoJSONs = append(*moduleInfoJSONs, moduleInfoJSON) } } return nil } // A support func for the deprecated AndroidMkDataProvider interface. Use AndroidMkEntryProvider // instead. func WriteAndroidMkData(w io.Writer, data AndroidMkData) { if data.Disabled { return } if !data.OutputFile.Valid() { if data.Entries.disabled() { return } Loading @@ -890,18 +933,26 @@ func WriteAndroidMkData(w io.Writer, data AndroidMkData) { fmt.Fprintln(w, "include "+data.Include) } func translateAndroidMkEntriesModule(ctx SingletonContext, w io.Writer, mod blueprint.Module, provider AndroidMkEntriesProvider) error { func translateAndroidMkEntriesModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, mod blueprint.Module, provider AndroidMkEntriesProvider) error { if shouldSkipAndroidMkProcessing(mod.(Module).base()) { return nil } entriesList := provider.AndroidMkEntries() // Any new or special cases here need review to verify correct propagation of license information. for _, entries := range provider.AndroidMkEntries() { for _, entries := range entriesList { entries.fillInEntries(ctx, mod) entries.write(w) } if len(entriesList) > 0 && !entriesList[0].disabled() { if moduleInfoJSON, ok := SingletonModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok { *moduleInfoJSONs = append(*moduleInfoJSONs, moduleInfoJSON) } } return nil } Loading android/module.go +84 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import ( "net/url" "path/filepath" "reflect" "slices" "sort" "strings" Loading Loading @@ -876,6 +877,10 @@ type ModuleBase struct { // The path to the generated license metadata file for the module. licenseMetadataFile WritablePath // moduleInfoJSON can be filled out by GenerateAndroidBuildActions to write a JSON file that will // be included in the final module-info.json produced by Make. moduleInfoJSON *ModuleInfoJSON } func (m *ModuleBase) AddJSONData(d *map[string]interface{}) { Loading Loading @@ -1771,11 +1776,90 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) buildLicenseMetadata(ctx, m.licenseMetadataFile) if m.moduleInfoJSON != nil { var installed InstallPaths installed = append(installed, m.katiInstalls.InstallPaths()...) installed = append(installed, m.katiSymlinks.InstallPaths()...) installed = append(installed, m.katiInitRcInstalls.InstallPaths()...) installed = append(installed, m.katiVintfInstalls.InstallPaths()...) installedStrings := installed.Strings() var targetRequired, hostRequired []string if ctx.Host() { targetRequired = m.commonProperties.Target_required } else { hostRequired = m.commonProperties.Host_required } var data []string for _, d := range m.testData { data = append(data, d.ToRelativeInstallPath()) } if m.moduleInfoJSON.Uninstallable { installedStrings = nil if len(m.moduleInfoJSON.CompatibilitySuites) == 1 && m.moduleInfoJSON.CompatibilitySuites[0] == "null-suite" { m.moduleInfoJSON.CompatibilitySuites = nil m.moduleInfoJSON.TestConfig = nil m.moduleInfoJSON.AutoTestConfig = nil data = nil } } m.moduleInfoJSON.core = CoreModuleInfoJSON{ RegisterName: m.moduleInfoRegisterName(ctx, m.moduleInfoJSON.SubName), Path: []string{ctx.ModuleDir()}, Installed: installedStrings, ModuleName: m.BaseModuleName() + m.moduleInfoJSON.SubName, SupportedVariants: []string{m.moduleInfoVariant(ctx)}, TargetDependencies: targetRequired, HostDependencies: hostRequired, Data: data, } SetProvider(ctx, ModuleInfoJSONProvider, m.moduleInfoJSON) } m.buildParams = ctx.buildParams m.ruleParams = ctx.ruleParams m.variables = ctx.variables } func (m *ModuleBase) moduleInfoRegisterName(ctx ModuleContext, subName string) string { name := m.BaseModuleName() prefix := "" if ctx.Host() { if ctx.Os() != ctx.Config().BuildOS { prefix = "host_cross_" } } suffix := "" arches := slices.Clone(ctx.Config().Targets[ctx.Os()]) arches = slices.DeleteFunc(arches, func(target Target) bool { return target.NativeBridge != ctx.Target().NativeBridge }) if len(arches) > 0 && ctx.Arch().ArchType != arches[0].Arch.ArchType { if ctx.Arch().ArchType.Multilib == "lib32" { suffix = "_32" } else { suffix = "_64" } } return prefix + name + subName + suffix } func (m *ModuleBase) moduleInfoVariant(ctx ModuleContext) string { variant := "DEVICE" if ctx.Host() { if ctx.Os() != ctx.Config().BuildOS { variant = "HOST_CROSS" } else { variant = "HOST" } } return variant } // Check the supplied dist structure to make sure that it is valid. // // property - the base property, e.g. dist or dists[1], which is combined with the Loading android/module_context.go +16 −0 Original line number Diff line number Diff line Loading @@ -210,6 +210,11 @@ type ModuleContext interface { // LicenseMetadataFile returns the path where the license metadata for this module will be // generated. LicenseMetadataFile() Path // ModuleInfoJSON returns a pointer to the ModuleInfoJSON struct that can be filled out by // GenerateAndroidBuildActions. If it is called then the struct will be written out and included in // the module-info.json generated by Make, and Make will not generate its own data for this module. ModuleInfoJSON() *ModuleInfoJSON } type moduleContext struct { Loading Loading @@ -518,6 +523,8 @@ func (m *moduleContext) installFile(installPath InstallPath, name string, srcPat if !m.skipInstall() { deps = append(deps, InstallPaths(m.module.base().installFilesDepSet.ToList())...) deps = append(deps, m.module.base().installedInitRcPaths...) deps = append(deps, m.module.base().installedVintfFragmentsPaths...) var implicitDeps, orderOnlyDeps Paths Loading Loading @@ -695,6 +702,15 @@ func (m *moduleContext) LicenseMetadataFile() Path { return m.module.base().licenseMetadataFile } func (m *moduleContext) ModuleInfoJSON() *ModuleInfoJSON { if moduleInfoJSON := m.module.base().moduleInfoJSON; moduleInfoJSON != nil { return moduleInfoJSON } moduleInfoJSON := &ModuleInfoJSON{} m.module.base().moduleInfoJSON = moduleInfoJSON return moduleInfoJSON } // Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must // be tagged with `android:"path" to support automatic source module dependency resolution. // Loading android/module_info_json.go 0 → 100644 +103 −0 Original line number Diff line number Diff line package android import ( "encoding/json" "io" "slices" "github.com/google/blueprint" ) type CoreModuleInfoJSON struct { RegisterName string `json:"-"` Path []string `json:"path,omitempty"` // $(sort $(ALL_MODULES.$(m).PATH)) Installed []string `json:"installed,omitempty"` // $(sort $(ALL_MODULES.$(m).INSTALLED)) ModuleName string `json:"module_name,omitempty"` // $(ALL_MODULES.$(m).MODULE_NAME) SupportedVariants []string `json:"supported_variants,omitempty"` // $(sort $(ALL_MODULES.$(m).SUPPORTED_VARIANTS)) HostDependencies []string `json:"host_dependencies,omitempty"` // $(sort $(ALL_MODULES.$(m).HOST_REQUIRED_FROM_TARGET)) TargetDependencies []string `json:"target_dependencies,omitempty"` // $(sort $(ALL_MODULES.$(m).TARGET_REQUIRED_FROM_HOST)) Data []string `json:"data,omitempty"` // $(sort $(ALL_MODULES.$(m).TEST_DATA)) } type ModuleInfoJSON struct { core CoreModuleInfoJSON SubName string `json:"-"` Uninstallable bool `json:"-"` Class []string `json:"class,omitempty"` // $(sort $(ALL_MODULES.$(m).CLASS)) Tags []string `json:"tags,omitempty"` // $(sort $(ALL_MODULES.$(m).TAGS)) Dependencies []string `json:"dependencies,omitempty"` // $(sort $(ALL_DEPS.$(m).ALL_DEPS)) SharedLibs []string `json:"shared_libs,omitempty"` // $(sort $(ALL_MODULES.$(m).SHARED_LIBS)) StaticLibs []string `json:"static_libs,omitempty"` // $(sort $(ALL_MODULES.$(m).STATIC_LIBS)) SystemSharedLibs []string `json:"system_shared_libs,omitempty"` // $(sort $(ALL_MODULES.$(m).SYSTEM_SHARED_LIBS)) Srcs []string `json:"srcs,omitempty"` // $(sort $(ALL_MODULES.$(m).SRCS)) SrcJars []string `json:"srcjars,omitempty"` // $(sort $(ALL_MODULES.$(m).SRCJARS)) ClassesJar []string `json:"classes_jar,omitempty"` // $(sort $(ALL_MODULES.$(m).CLASSES_JAR)) TestMainlineModules []string `json:"test_mainline_modules,omitempty"` // $(sort $(ALL_MODULES.$(m).TEST_MAINLINE_MODULES)) IsUnitTest bool `json:"is_unit_test,omitempty"` // $(ALL_MODULES.$(m).IS_UNIT_TEST) TestOptionsTags []string `json:"test_options_tags,omitempty"` // $(sort $(ALL_MODULES.$(m).TEST_OPTIONS_TAGS)) RuntimeDependencies []string `json:"runtime_dependencies,omitempty"` // $(sort $(ALL_MODULES.$(m).LOCAL_RUNTIME_LIBRARIES)) StaticDependencies []string `json:"static_dependencies,omitempty"` // $(sort $(ALL_MODULES.$(m).LOCAL_STATIC_LIBRARIES)) DataDependencies []string `json:"data_dependencies,omitempty"` // $(sort $(ALL_MODULES.$(m).TEST_DATA_BINS)) CompatibilitySuites []string `json:"compatibility_suites,omitempty"` // $(sort $(ALL_MODULES.$(m).COMPATIBILITY_SUITES)) AutoTestConfig []string `json:"auto_test_config,omitempty"` // $(ALL_MODULES.$(m).auto_test_config) TestConfig []string `json:"test_config,omitempty"` // $(strip $(ALL_MODULES.$(m).TEST_CONFIG) $(ALL_MODULES.$(m).EXTRA_TEST_CONFIGS) } //ALL_DEPS.$(LOCAL_MODULE).ALL_DEPS := $(sort \ //$(ALL_DEPS.$(LOCAL_MODULE).ALL_DEPS) \ //$(LOCAL_STATIC_LIBRARIES) \ //$(LOCAL_WHOLE_STATIC_LIBRARIES) \ //$(LOCAL_SHARED_LIBRARIES) \ //$(LOCAL_DYLIB_LIBRARIES) \ //$(LOCAL_RLIB_LIBRARIES) \ //$(LOCAL_PROC_MACRO_LIBRARIES) \ //$(LOCAL_HEADER_LIBRARIES) \ //$(LOCAL_STATIC_JAVA_LIBRARIES) \ //$(LOCAL_JAVA_LIBRARIES) \ //$(LOCAL_JNI_SHARED_LIBRARIES)) type combinedModuleInfoJSON struct { *CoreModuleInfoJSON *ModuleInfoJSON } func encodeModuleInfoJSON(w io.Writer, moduleInfoJSON *ModuleInfoJSON) error { moduleInfoJSONCopy := *moduleInfoJSON sortAndUnique := func(s *[]string) { *s = slices.Clone(*s) slices.Sort(*s) *s = slices.Compact(*s) } sortAndUnique(&moduleInfoJSONCopy.core.Path) sortAndUnique(&moduleInfoJSONCopy.core.Installed) sortAndUnique(&moduleInfoJSONCopy.core.SupportedVariants) sortAndUnique(&moduleInfoJSONCopy.core.HostDependencies) sortAndUnique(&moduleInfoJSONCopy.core.TargetDependencies) sortAndUnique(&moduleInfoJSONCopy.core.Data) sortAndUnique(&moduleInfoJSONCopy.Class) sortAndUnique(&moduleInfoJSONCopy.Tags) sortAndUnique(&moduleInfoJSONCopy.Dependencies) sortAndUnique(&moduleInfoJSONCopy.SharedLibs) sortAndUnique(&moduleInfoJSONCopy.StaticLibs) sortAndUnique(&moduleInfoJSONCopy.SystemSharedLibs) sortAndUnique(&moduleInfoJSONCopy.Srcs) sortAndUnique(&moduleInfoJSONCopy.SrcJars) sortAndUnique(&moduleInfoJSONCopy.ClassesJar) sortAndUnique(&moduleInfoJSONCopy.TestMainlineModules) sortAndUnique(&moduleInfoJSONCopy.TestOptionsTags) sortAndUnique(&moduleInfoJSONCopy.RuntimeDependencies) sortAndUnique(&moduleInfoJSONCopy.StaticDependencies) sortAndUnique(&moduleInfoJSONCopy.DataDependencies) sortAndUnique(&moduleInfoJSONCopy.CompatibilitySuites) sortAndUnique(&moduleInfoJSONCopy.AutoTestConfig) sortAndUnique(&moduleInfoJSONCopy.TestConfig) encoder := json.NewEncoder(w) return encoder.Encode(combinedModuleInfoJSON{&moduleInfoJSONCopy.core, &moduleInfoJSONCopy}) } var ModuleInfoJSONProvider = blueprint.NewProvider[*ModuleInfoJSON]() Loading
android/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ bootstrap_go_package { "metrics.go", "module.go", "module_context.go", "module_info_json.go", "mutator.go", "namespace.go", "neverallow.go", Loading
android/androidmk.go +75 −24 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import ( "reflect" "runtime" "sort" "strconv" "strings" "github.com/google/blueprint" Loading Loading @@ -626,6 +627,10 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint a.SetPath("LOCAL_SOONG_LICENSE_METADATA", licenseMetadata.LicenseMetadataPath) } if _, ok := SingletonModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok { a.SetBool("LOCAL_SOONG_MODULE_INFO_JSON", true) } extraCtx := &androidMkExtraEntriesContext{ ctx: ctx, mod: mod, Loading @@ -643,14 +648,14 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint } } func (a *AndroidMkEntries) 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 *AndroidMkEntries) write(w io.Writer) { if a.Disabled { return } if !a.OutputFile.Valid() { if a.disabled() { return } Loading Loading @@ -696,7 +701,9 @@ func (c *androidMkSingleton) GenerateBuildActions(ctx SingletonContext) { return } err := translateAndroidMk(ctx, absolutePath(transMk.String()), androidMkModulesList) moduleInfoJSON := PathForOutput(ctx, "module-info"+String(ctx.Config().productVariables.Make_suffix)+".json") err := translateAndroidMk(ctx, absolutePath(transMk.String()), moduleInfoJSON, androidMkModulesList) if err != nil { ctx.Errorf(err.Error()) } Loading @@ -707,14 +714,16 @@ func (c *androidMkSingleton) GenerateBuildActions(ctx SingletonContext) { }) } func translateAndroidMk(ctx SingletonContext, absMkFile string, mods []blueprint.Module) error { func translateAndroidMk(ctx SingletonContext, absMkFile string, moduleInfoJSONPath WritablePath, mods []blueprint.Module) error { buf := &bytes.Buffer{} var moduleInfoJSONs []*ModuleInfoJSON fmt.Fprintln(buf, "LOCAL_MODULE_MAKEFILE := $(lastword $(MAKEFILE_LIST))") typeStats := make(map[string]int) for _, mod := range mods { err := translateAndroidMkModule(ctx, buf, mod) err := translateAndroidMkModule(ctx, buf, &moduleInfoJSONs, mod) if err != nil { os.Remove(absMkFile) return err Loading @@ -736,10 +745,36 @@ func translateAndroidMk(ctx SingletonContext, absMkFile string, mods []blueprint fmt.Fprintf(buf, "STATS.SOONG_MODULE_TYPE.%s := %d\n", mod_type, typeStats[mod_type]) } return pathtools.WriteFileIfChanged(absMkFile, buf.Bytes(), 0666) err := pathtools.WriteFileIfChanged(absMkFile, buf.Bytes(), 0666) if err != nil { return err } return writeModuleInfoJSON(ctx, moduleInfoJSONs, moduleInfoJSONPath) } func translateAndroidMkModule(ctx SingletonContext, w io.Writer, mod blueprint.Module) error { func writeModuleInfoJSON(ctx SingletonContext, moduleInfoJSONs []*ModuleInfoJSON, moduleInfoJSONPath WritablePath) error { moduleInfoJSONBuf := &strings.Builder{} moduleInfoJSONBuf.WriteString("[") for i, moduleInfoJSON := range moduleInfoJSONs { if i != 0 { moduleInfoJSONBuf.WriteString(",\n") } moduleInfoJSONBuf.WriteString("{") moduleInfoJSONBuf.WriteString(strconv.Quote(moduleInfoJSON.core.RegisterName)) moduleInfoJSONBuf.WriteString(":") err := encodeModuleInfoJSON(moduleInfoJSONBuf, moduleInfoJSON) moduleInfoJSONBuf.WriteString("}") if err != nil { return err } } moduleInfoJSONBuf.WriteString("]") WriteFileRule(ctx, moduleInfoJSONPath, moduleInfoJSONBuf.String()) return nil } func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, mod blueprint.Module) error { defer func() { if r := recover(); r != nil { panic(fmt.Errorf("%s in translateAndroidMkModule for module %s variant %s", Loading @@ -748,17 +783,23 @@ func translateAndroidMkModule(ctx SingletonContext, w io.Writer, mod blueprint.M }() // Additional cases here require review for correct license propagation to make. var err error switch x := mod.(type) { case AndroidMkDataProvider: return translateAndroidModule(ctx, w, mod, x) err = translateAndroidModule(ctx, w, moduleInfoJSONs, mod, x) case bootstrap.GoBinaryTool: return translateGoBinaryModule(ctx, w, mod, x) err = translateGoBinaryModule(ctx, w, mod, x) case AndroidMkEntriesProvider: return translateAndroidMkEntriesModule(ctx, w, mod, x) err = translateAndroidMkEntriesModule(ctx, w, moduleInfoJSONs, mod, x) default: // Not exported to make so no make variables to set. return nil } if err != nil { return err } return err } // A simple, special Android.mk entry output func to make it possible to build blueprint tools using Loading Loading @@ -801,8 +842,8 @@ func (data *AndroidMkData) fillInData(ctx fillInEntriesContext, mod blueprint.Mo // A support func for the deprecated AndroidMkDataProvider interface. Use AndroidMkEntryProvider // instead. func translateAndroidModule(ctx SingletonContext, w io.Writer, mod blueprint.Module, provider AndroidMkDataProvider) error { func translateAndroidModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, mod blueprint.Module, provider AndroidMkDataProvider) error { amod := mod.(Module).base() if shouldSkipAndroidMkProcessing(amod) { Loading Loading @@ -865,17 +906,19 @@ func translateAndroidModule(ctx SingletonContext, w io.Writer, mod blueprint.Mod WriteAndroidMkData(w, data) } if !data.Entries.disabled() { if moduleInfoJSON, ok := SingletonModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok { *moduleInfoJSONs = append(*moduleInfoJSONs, moduleInfoJSON) } } return nil } // A support func for the deprecated AndroidMkDataProvider interface. Use AndroidMkEntryProvider // instead. func WriteAndroidMkData(w io.Writer, data AndroidMkData) { if data.Disabled { return } if !data.OutputFile.Valid() { if data.Entries.disabled() { return } Loading @@ -890,18 +933,26 @@ func WriteAndroidMkData(w io.Writer, data AndroidMkData) { fmt.Fprintln(w, "include "+data.Include) } func translateAndroidMkEntriesModule(ctx SingletonContext, w io.Writer, mod blueprint.Module, provider AndroidMkEntriesProvider) error { func translateAndroidMkEntriesModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, mod blueprint.Module, provider AndroidMkEntriesProvider) error { if shouldSkipAndroidMkProcessing(mod.(Module).base()) { return nil } entriesList := provider.AndroidMkEntries() // Any new or special cases here need review to verify correct propagation of license information. for _, entries := range provider.AndroidMkEntries() { for _, entries := range entriesList { entries.fillInEntries(ctx, mod) entries.write(w) } if len(entriesList) > 0 && !entriesList[0].disabled() { if moduleInfoJSON, ok := SingletonModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok { *moduleInfoJSONs = append(*moduleInfoJSONs, moduleInfoJSON) } } return nil } Loading
android/module.go +84 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import ( "net/url" "path/filepath" "reflect" "slices" "sort" "strings" Loading Loading @@ -876,6 +877,10 @@ type ModuleBase struct { // The path to the generated license metadata file for the module. licenseMetadataFile WritablePath // moduleInfoJSON can be filled out by GenerateAndroidBuildActions to write a JSON file that will // be included in the final module-info.json produced by Make. moduleInfoJSON *ModuleInfoJSON } func (m *ModuleBase) AddJSONData(d *map[string]interface{}) { Loading Loading @@ -1771,11 +1776,90 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) buildLicenseMetadata(ctx, m.licenseMetadataFile) if m.moduleInfoJSON != nil { var installed InstallPaths installed = append(installed, m.katiInstalls.InstallPaths()...) installed = append(installed, m.katiSymlinks.InstallPaths()...) installed = append(installed, m.katiInitRcInstalls.InstallPaths()...) installed = append(installed, m.katiVintfInstalls.InstallPaths()...) installedStrings := installed.Strings() var targetRequired, hostRequired []string if ctx.Host() { targetRequired = m.commonProperties.Target_required } else { hostRequired = m.commonProperties.Host_required } var data []string for _, d := range m.testData { data = append(data, d.ToRelativeInstallPath()) } if m.moduleInfoJSON.Uninstallable { installedStrings = nil if len(m.moduleInfoJSON.CompatibilitySuites) == 1 && m.moduleInfoJSON.CompatibilitySuites[0] == "null-suite" { m.moduleInfoJSON.CompatibilitySuites = nil m.moduleInfoJSON.TestConfig = nil m.moduleInfoJSON.AutoTestConfig = nil data = nil } } m.moduleInfoJSON.core = CoreModuleInfoJSON{ RegisterName: m.moduleInfoRegisterName(ctx, m.moduleInfoJSON.SubName), Path: []string{ctx.ModuleDir()}, Installed: installedStrings, ModuleName: m.BaseModuleName() + m.moduleInfoJSON.SubName, SupportedVariants: []string{m.moduleInfoVariant(ctx)}, TargetDependencies: targetRequired, HostDependencies: hostRequired, Data: data, } SetProvider(ctx, ModuleInfoJSONProvider, m.moduleInfoJSON) } m.buildParams = ctx.buildParams m.ruleParams = ctx.ruleParams m.variables = ctx.variables } func (m *ModuleBase) moduleInfoRegisterName(ctx ModuleContext, subName string) string { name := m.BaseModuleName() prefix := "" if ctx.Host() { if ctx.Os() != ctx.Config().BuildOS { prefix = "host_cross_" } } suffix := "" arches := slices.Clone(ctx.Config().Targets[ctx.Os()]) arches = slices.DeleteFunc(arches, func(target Target) bool { return target.NativeBridge != ctx.Target().NativeBridge }) if len(arches) > 0 && ctx.Arch().ArchType != arches[0].Arch.ArchType { if ctx.Arch().ArchType.Multilib == "lib32" { suffix = "_32" } else { suffix = "_64" } } return prefix + name + subName + suffix } func (m *ModuleBase) moduleInfoVariant(ctx ModuleContext) string { variant := "DEVICE" if ctx.Host() { if ctx.Os() != ctx.Config().BuildOS { variant = "HOST_CROSS" } else { variant = "HOST" } } return variant } // Check the supplied dist structure to make sure that it is valid. // // property - the base property, e.g. dist or dists[1], which is combined with the Loading
android/module_context.go +16 −0 Original line number Diff line number Diff line Loading @@ -210,6 +210,11 @@ type ModuleContext interface { // LicenseMetadataFile returns the path where the license metadata for this module will be // generated. LicenseMetadataFile() Path // ModuleInfoJSON returns a pointer to the ModuleInfoJSON struct that can be filled out by // GenerateAndroidBuildActions. If it is called then the struct will be written out and included in // the module-info.json generated by Make, and Make will not generate its own data for this module. ModuleInfoJSON() *ModuleInfoJSON } type moduleContext struct { Loading Loading @@ -518,6 +523,8 @@ func (m *moduleContext) installFile(installPath InstallPath, name string, srcPat if !m.skipInstall() { deps = append(deps, InstallPaths(m.module.base().installFilesDepSet.ToList())...) deps = append(deps, m.module.base().installedInitRcPaths...) deps = append(deps, m.module.base().installedVintfFragmentsPaths...) var implicitDeps, orderOnlyDeps Paths Loading Loading @@ -695,6 +702,15 @@ func (m *moduleContext) LicenseMetadataFile() Path { return m.module.base().licenseMetadataFile } func (m *moduleContext) ModuleInfoJSON() *ModuleInfoJSON { if moduleInfoJSON := m.module.base().moduleInfoJSON; moduleInfoJSON != nil { return moduleInfoJSON } moduleInfoJSON := &ModuleInfoJSON{} m.module.base().moduleInfoJSON = moduleInfoJSON return moduleInfoJSON } // Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must // be tagged with `android:"path" to support automatic source module dependency resolution. // Loading
android/module_info_json.go 0 → 100644 +103 −0 Original line number Diff line number Diff line package android import ( "encoding/json" "io" "slices" "github.com/google/blueprint" ) type CoreModuleInfoJSON struct { RegisterName string `json:"-"` Path []string `json:"path,omitempty"` // $(sort $(ALL_MODULES.$(m).PATH)) Installed []string `json:"installed,omitempty"` // $(sort $(ALL_MODULES.$(m).INSTALLED)) ModuleName string `json:"module_name,omitempty"` // $(ALL_MODULES.$(m).MODULE_NAME) SupportedVariants []string `json:"supported_variants,omitempty"` // $(sort $(ALL_MODULES.$(m).SUPPORTED_VARIANTS)) HostDependencies []string `json:"host_dependencies,omitempty"` // $(sort $(ALL_MODULES.$(m).HOST_REQUIRED_FROM_TARGET)) TargetDependencies []string `json:"target_dependencies,omitempty"` // $(sort $(ALL_MODULES.$(m).TARGET_REQUIRED_FROM_HOST)) Data []string `json:"data,omitempty"` // $(sort $(ALL_MODULES.$(m).TEST_DATA)) } type ModuleInfoJSON struct { core CoreModuleInfoJSON SubName string `json:"-"` Uninstallable bool `json:"-"` Class []string `json:"class,omitempty"` // $(sort $(ALL_MODULES.$(m).CLASS)) Tags []string `json:"tags,omitempty"` // $(sort $(ALL_MODULES.$(m).TAGS)) Dependencies []string `json:"dependencies,omitempty"` // $(sort $(ALL_DEPS.$(m).ALL_DEPS)) SharedLibs []string `json:"shared_libs,omitempty"` // $(sort $(ALL_MODULES.$(m).SHARED_LIBS)) StaticLibs []string `json:"static_libs,omitempty"` // $(sort $(ALL_MODULES.$(m).STATIC_LIBS)) SystemSharedLibs []string `json:"system_shared_libs,omitempty"` // $(sort $(ALL_MODULES.$(m).SYSTEM_SHARED_LIBS)) Srcs []string `json:"srcs,omitempty"` // $(sort $(ALL_MODULES.$(m).SRCS)) SrcJars []string `json:"srcjars,omitempty"` // $(sort $(ALL_MODULES.$(m).SRCJARS)) ClassesJar []string `json:"classes_jar,omitempty"` // $(sort $(ALL_MODULES.$(m).CLASSES_JAR)) TestMainlineModules []string `json:"test_mainline_modules,omitempty"` // $(sort $(ALL_MODULES.$(m).TEST_MAINLINE_MODULES)) IsUnitTest bool `json:"is_unit_test,omitempty"` // $(ALL_MODULES.$(m).IS_UNIT_TEST) TestOptionsTags []string `json:"test_options_tags,omitempty"` // $(sort $(ALL_MODULES.$(m).TEST_OPTIONS_TAGS)) RuntimeDependencies []string `json:"runtime_dependencies,omitempty"` // $(sort $(ALL_MODULES.$(m).LOCAL_RUNTIME_LIBRARIES)) StaticDependencies []string `json:"static_dependencies,omitempty"` // $(sort $(ALL_MODULES.$(m).LOCAL_STATIC_LIBRARIES)) DataDependencies []string `json:"data_dependencies,omitempty"` // $(sort $(ALL_MODULES.$(m).TEST_DATA_BINS)) CompatibilitySuites []string `json:"compatibility_suites,omitempty"` // $(sort $(ALL_MODULES.$(m).COMPATIBILITY_SUITES)) AutoTestConfig []string `json:"auto_test_config,omitempty"` // $(ALL_MODULES.$(m).auto_test_config) TestConfig []string `json:"test_config,omitempty"` // $(strip $(ALL_MODULES.$(m).TEST_CONFIG) $(ALL_MODULES.$(m).EXTRA_TEST_CONFIGS) } //ALL_DEPS.$(LOCAL_MODULE).ALL_DEPS := $(sort \ //$(ALL_DEPS.$(LOCAL_MODULE).ALL_DEPS) \ //$(LOCAL_STATIC_LIBRARIES) \ //$(LOCAL_WHOLE_STATIC_LIBRARIES) \ //$(LOCAL_SHARED_LIBRARIES) \ //$(LOCAL_DYLIB_LIBRARIES) \ //$(LOCAL_RLIB_LIBRARIES) \ //$(LOCAL_PROC_MACRO_LIBRARIES) \ //$(LOCAL_HEADER_LIBRARIES) \ //$(LOCAL_STATIC_JAVA_LIBRARIES) \ //$(LOCAL_JAVA_LIBRARIES) \ //$(LOCAL_JNI_SHARED_LIBRARIES)) type combinedModuleInfoJSON struct { *CoreModuleInfoJSON *ModuleInfoJSON } func encodeModuleInfoJSON(w io.Writer, moduleInfoJSON *ModuleInfoJSON) error { moduleInfoJSONCopy := *moduleInfoJSON sortAndUnique := func(s *[]string) { *s = slices.Clone(*s) slices.Sort(*s) *s = slices.Compact(*s) } sortAndUnique(&moduleInfoJSONCopy.core.Path) sortAndUnique(&moduleInfoJSONCopy.core.Installed) sortAndUnique(&moduleInfoJSONCopy.core.SupportedVariants) sortAndUnique(&moduleInfoJSONCopy.core.HostDependencies) sortAndUnique(&moduleInfoJSONCopy.core.TargetDependencies) sortAndUnique(&moduleInfoJSONCopy.core.Data) sortAndUnique(&moduleInfoJSONCopy.Class) sortAndUnique(&moduleInfoJSONCopy.Tags) sortAndUnique(&moduleInfoJSONCopy.Dependencies) sortAndUnique(&moduleInfoJSONCopy.SharedLibs) sortAndUnique(&moduleInfoJSONCopy.StaticLibs) sortAndUnique(&moduleInfoJSONCopy.SystemSharedLibs) sortAndUnique(&moduleInfoJSONCopy.Srcs) sortAndUnique(&moduleInfoJSONCopy.SrcJars) sortAndUnique(&moduleInfoJSONCopy.ClassesJar) sortAndUnique(&moduleInfoJSONCopy.TestMainlineModules) sortAndUnique(&moduleInfoJSONCopy.TestOptionsTags) sortAndUnique(&moduleInfoJSONCopy.RuntimeDependencies) sortAndUnique(&moduleInfoJSONCopy.StaticDependencies) sortAndUnique(&moduleInfoJSONCopy.DataDependencies) sortAndUnique(&moduleInfoJSONCopy.CompatibilitySuites) sortAndUnique(&moduleInfoJSONCopy.AutoTestConfig) sortAndUnique(&moduleInfoJSONCopy.TestConfig) encoder := json.NewEncoder(w) return encoder.Encode(combinedModuleInfoJSON{&moduleInfoJSONCopy.core, &moduleInfoJSONCopy}) } var ModuleInfoJSONProvider = blueprint.NewProvider[*ModuleInfoJSON]()