1// Copyright 2021 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package multitree 16 17import ( 18 "android/soong/android" 19 "fmt" 20 21 "github.com/google/blueprint" 22) 23 24var ( 25 pctx = android.NewPackageContext("android/soong/multitree") 26) 27 28func init() { 29 RegisterApiSurfaceBuildComponents(android.InitRegistrationContext) 30} 31 32var PrepareForTestWithApiSurface = android.FixtureRegisterWithContext(RegisterApiSurfaceBuildComponents) 33 34func RegisterApiSurfaceBuildComponents(ctx android.RegistrationContext) { 35 ctx.RegisterModuleType("api_surface", ApiSurfaceFactory) 36} 37 38type ApiSurface struct { 39 android.ModuleBase 40 ExportableModuleBase 41 properties apiSurfaceProperties 42 43 allOutputs android.Paths 44 taggedOutputs map[string]android.Paths 45} 46 47type apiSurfaceProperties struct { 48 Contributions []string 49} 50 51func ApiSurfaceFactory() android.Module { 52 module := &ApiSurface{} 53 module.AddProperties(&module.properties) 54 android.InitAndroidModule(module) 55 InitExportableModule(module) 56 return module 57} 58 59func (surface *ApiSurface) DepsMutator(ctx android.BottomUpMutatorContext) { 60 if surface.properties.Contributions != nil { 61 ctx.AddVariationDependencies(nil, nil, surface.properties.Contributions...) 62 } 63 64} 65func (surface *ApiSurface) GenerateAndroidBuildActions(ctx android.ModuleContext) { 66 contributionFiles := make(map[string]android.Paths) 67 var allOutputs android.Paths 68 ctx.WalkDeps(func(child, parent android.Module) bool { 69 if contribution, ok := child.(ApiContribution); ok { 70 copied := contribution.CopyFilesWithTag(ctx) 71 for tag, files := range copied { 72 contributionFiles[child.Name()+"#"+tag] = files 73 } 74 for _, paths := range copied { 75 allOutputs = append(allOutputs, paths...) 76 } 77 return false // no transitive dependencies 78 } 79 return false 80 }) 81 82 // phony target 83 ctx.Build(pctx, android.BuildParams{ 84 Rule: blueprint.Phony, 85 Output: android.PathForPhony(ctx, ctx.ModuleName()), 86 Inputs: allOutputs, 87 }) 88 89 surface.allOutputs = allOutputs 90 surface.taggedOutputs = contributionFiles 91} 92 93func (surface *ApiSurface) OutputFiles(tag string) (android.Paths, error) { 94 if tag != "" { 95 return nil, fmt.Errorf("unknown tag: %q", tag) 96 } 97 return surface.allOutputs, nil 98} 99 100func (surface *ApiSurface) TaggedOutputs() map[string]android.Paths { 101 return surface.taggedOutputs 102} 103 104func (surface *ApiSurface) Exportable() bool { 105 return true 106} 107 108var _ android.OutputFileProducer = (*ApiSurface)(nil) 109var _ Exportable = (*ApiSurface)(nil) 110 111type ApiContribution interface { 112 // copy files necessaryt to construct an API surface 113 // For C, it will be map.txt and .h files 114 // For Java, it will be api.txt 115 CopyFilesWithTag(ctx android.ModuleContext) map[string]android.Paths // output paths 116 117 // Generate Android.bp in out/ to use the exported .txt files 118 // GenerateBuildFiles(ctx ModuleContext) Paths //output paths 119} 120