// 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" "fmt" "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 allOutputs android.Paths 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.allOutputs = allOutputs surface.taggedOutputs = contributionFiles } func (surface *ApiSurface) OutputFiles(tag string) (android.Paths, error) { if tag != "" { return nil, fmt.Errorf("unknown tag: %q", tag) } return surface.allOutputs, nil } func (surface *ApiSurface) TaggedOutputs() map[string]android.Paths { return surface.taggedOutputs } func (surface *ApiSurface) Exportable() bool { return true } var _ android.OutputFileProducer = (*ApiSurface)(nil) 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 }