// Copyright 2023 Google Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package android import ( "github.com/google/blueprint" ) var ( mergeAconfigFilesRule = pctx.AndroidStaticRule("mergeAconfigFilesRule", blueprint.RuleParams{ Command: `${aconfig} dump --dedup --format protobuf --out $out $flags`, CommandDeps: []string{"${aconfig}"}, }, "flags") _ = pctx.HostBinToolVariable("aconfig", "aconfig") ) // Provider published by aconfig_value_set type AconfigDeclarationsProviderData struct { Package string Container string IntermediateCacheOutputPath WritablePath IntermediateDumpOutputPath WritablePath } var AconfigDeclarationsProviderKey = blueprint.NewProvider[AconfigDeclarationsProviderData]() // This is used to collect the aconfig declarations info on the transitive closure, // the data is keyed on the container. type AconfigTransitiveDeclarationsInfo struct { AconfigFiles map[string]Paths } var AconfigTransitiveDeclarationsInfoProvider = blueprint.NewProvider[AconfigTransitiveDeclarationsInfo]() func CollectDependencyAconfigFiles(ctx ModuleContext, mergedAconfigFiles *map[string]Paths) { if *mergedAconfigFiles == nil { *mergedAconfigFiles = make(map[string]Paths) } ctx.VisitDirectDeps(func(module Module) { if dep, _ := OtherModuleProvider(ctx, module, AconfigDeclarationsProviderKey); dep.IntermediateCacheOutputPath != nil { (*mergedAconfigFiles)[dep.Container] = append((*mergedAconfigFiles)[dep.Container], dep.IntermediateCacheOutputPath) return } if dep, _ := OtherModuleProvider(ctx, module, AconfigTransitiveDeclarationsInfoProvider); len(dep.AconfigFiles) > 0 { for container, v := range dep.AconfigFiles { (*mergedAconfigFiles)[container] = append((*mergedAconfigFiles)[container], v...) } } }) for container, aconfigFiles := range *mergedAconfigFiles { (*mergedAconfigFiles)[container] = mergeAconfigFiles(ctx, aconfigFiles) } SetProvider(ctx, AconfigTransitiveDeclarationsInfoProvider, AconfigTransitiveDeclarationsInfo{ AconfigFiles: *mergedAconfigFiles, }) } func mergeAconfigFiles(ctx ModuleContext, inputs Paths) Paths { inputs = LastUniquePaths(inputs) if len(inputs) == 1 { return Paths{inputs[0]} } output := PathForModuleOut(ctx, "aconfig_merged.pb") ctx.Build(pctx, BuildParams{ Rule: mergeAconfigFilesRule, Description: "merge aconfig files", Inputs: inputs, Output: output, Args: map[string]string{ "flags": JoinWithPrefix(inputs.Strings(), "--cache "), }, }) return Paths{output} }