1// Copyright 2016 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 android 16 17import ( 18 "maps" 19 "strings" 20 21 "github.com/google/blueprint" 22 "github.com/google/blueprint/proptools" 23) 24 25func init() { 26 RegisterFilegroupBuildComponents(InitRegistrationContext) 27} 28 29var PrepareForTestWithFilegroup = FixtureRegisterWithContext(func(ctx RegistrationContext) { 30 RegisterFilegroupBuildComponents(ctx) 31}) 32 33func RegisterFilegroupBuildComponents(ctx RegistrationContext) { 34 ctx.RegisterModuleType("filegroup", FileGroupFactory) 35 ctx.RegisterModuleType("filegroup_defaults", FileGroupDefaultsFactory) 36} 37 38type fileGroupProperties struct { 39 // srcs lists files that will be included in this filegroup 40 Srcs proptools.Configurable[[]string] `android:"path"` 41 42 Exclude_srcs proptools.Configurable[[]string] `android:"path"` 43 44 // Sources the will be included in the filegroup, but any module dependencies will be added 45 // using the device os and the device's first architecture's variant. 46 Device_first_srcs proptools.Configurable[[]string] `android:"path_device_first"` 47 48 // Sources the will be included in the filegroup, but any module dependencies will be added 49 // using the device os and the common architecture's variant. 50 Device_common_srcs proptools.Configurable[[]string] `android:"path_device_common"` 51 52 // The base path to the files. May be used by other modules to determine which portion 53 // of the path to use. For example, when a filegroup is used as data in a cc_test rule, 54 // the base path is stripped off the path and the remaining path is used as the 55 // installation directory. 56 Path *string 57 58 // Create a make variable with the specified name that contains the list of files in the 59 // filegroup, relative to the root of the source tree. 60 Export_to_make_var *string 61} 62 63type fileGroup struct { 64 ModuleBase 65 DefaultableModuleBase 66 properties fileGroupProperties 67 srcs Paths 68} 69 70var _ SourceFileProducer = (*fileGroup)(nil) 71 72// filegroup contains a list of files that are referenced by other modules 73// properties (such as "srcs") using the syntax ":<name>". filegroup are 74// also be used to export files across package boundaries. 75func FileGroupFactory() Module { 76 module := &fileGroup{} 77 module.AddProperties(&module.properties) 78 InitAndroidModule(module) 79 InitDefaultableModule(module) 80 return module 81} 82 83var _ blueprint.JSONActionSupplier = (*fileGroup)(nil) 84 85func (fg *fileGroup) JSONActions() []blueprint.JSONAction { 86 ins := make([]string, 0, len(fg.srcs)) 87 outs := make([]string, 0, len(fg.srcs)) 88 for _, p := range fg.srcs { 89 ins = append(ins, p.String()) 90 outs = append(outs, p.Rel()) 91 } 92 return []blueprint.JSONAction{ 93 blueprint.JSONAction{ 94 Inputs: ins, 95 Outputs: outs, 96 }, 97 } 98} 99 100func (fg *fileGroup) GenerateAndroidBuildActions(ctx ModuleContext) { 101 srcs := PathsForModuleSrcExcludes(ctx, fg.properties.Srcs.GetOrDefault(ctx, nil), fg.properties.Exclude_srcs.GetOrDefault(ctx, nil)) 102 srcs = append(srcs, PathsForModuleSrc(ctx, fg.properties.Device_first_srcs.GetOrDefault(ctx, nil))...) 103 srcs = append(srcs, PathsForModuleSrc(ctx, fg.properties.Device_common_srcs.GetOrDefault(ctx, nil))...) 104 if fg.properties.Path != nil { 105 srcs = PathsWithModuleSrcSubDir(ctx, srcs, String(fg.properties.Path)) 106 } 107 SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcs.Strings()}) 108 109 var aconfigDeclarations []string 110 var intermediateCacheOutputPaths Paths 111 var srcjars Paths 112 modeInfos := make(map[string]ModeInfo) 113 ctx.VisitDirectDeps(func(module Module) { 114 if dep, ok := OtherModuleProvider(ctx, module, CodegenInfoProvider); ok { 115 aconfigDeclarations = append(aconfigDeclarations, dep.AconfigDeclarations...) 116 intermediateCacheOutputPaths = append(intermediateCacheOutputPaths, dep.IntermediateCacheOutputPaths...) 117 srcjars = append(srcjars, dep.Srcjars...) 118 maps.Copy(modeInfos, dep.ModeInfos) 119 } 120 }) 121 122 fg.srcs = srcs 123 SetProvider(ctx, CodegenInfoProvider, CodegenInfo{ 124 AconfigDeclarations: aconfigDeclarations, 125 IntermediateCacheOutputPaths: intermediateCacheOutputPaths, 126 Srcjars: srcjars, 127 ModeInfos: modeInfos, 128 }) 129} 130 131func (fg *fileGroup) Srcs() Paths { 132 return append(Paths{}, fg.srcs...) 133} 134 135func (fg *fileGroup) MakeVars(ctx MakeVarsModuleContext) { 136 if makeVar := String(fg.properties.Export_to_make_var); makeVar != "" { 137 ctx.StrictRaw(makeVar, strings.Join(fg.srcs.Strings(), " ")) 138 } 139} 140 141// Defaults 142type FileGroupDefaults struct { 143 ModuleBase 144 DefaultsModuleBase 145} 146 147func FileGroupDefaultsFactory() Module { 148 module := &FileGroupDefaults{} 149 module.AddProperties(&fileGroupProperties{}) 150 InitDefaultsModule(module) 151 152 return module 153} 154 155// Collect information for opening IDE project files in java/jdeps.go. 156// Copied from build/soong/genrule/genrule.go 157func (fg *fileGroup) IDEInfo(ctx BaseModuleContext, dpInfo *IdeInfo) { 158 dpInfo.Srcs = append(dpInfo.Srcs, fg.Srcs().Strings()...) 159 for _, src := range fg.properties.Srcs.GetOrDefault(ctx, nil) { 160 if mod, _ := SrcIsModuleWithTag(src); mod != "" { 161 // Register the module name without any tags in `Deps` 162 dpInfo.Deps = append(dpInfo.Deps, mod) 163 } 164 } 165} 166