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	// The base path to the files.  May be used by other modules to determine which portion
45	// of the path to use.  For example, when a filegroup is used as data in a cc_test rule,
46	// the base path is stripped off the path and the remaining path is used as the
47	// installation directory.
48	Path *string
49
50	// Create a make variable with the specified name that contains the list of files in the
51	// filegroup, relative to the root of the source tree.
52	Export_to_make_var *string
53}
54
55type fileGroup struct {
56	ModuleBase
57	DefaultableModuleBase
58	properties fileGroupProperties
59	srcs       Paths
60}
61
62var _ SourceFileProducer = (*fileGroup)(nil)
63
64// filegroup contains a list of files that are referenced by other modules
65// properties (such as "srcs") using the syntax ":<name>". filegroup are
66// also be used to export files across package boundaries.
67func FileGroupFactory() Module {
68	module := &fileGroup{}
69	module.AddProperties(&module.properties)
70	InitAndroidModule(module)
71	InitDefaultableModule(module)
72	return module
73}
74
75var _ blueprint.JSONActionSupplier = (*fileGroup)(nil)
76
77func (fg *fileGroup) JSONActions() []blueprint.JSONAction {
78	ins := make([]string, 0, len(fg.srcs))
79	outs := make([]string, 0, len(fg.srcs))
80	for _, p := range fg.srcs {
81		ins = append(ins, p.String())
82		outs = append(outs, p.Rel())
83	}
84	return []blueprint.JSONAction{
85		blueprint.JSONAction{
86			Inputs:  ins,
87			Outputs: outs,
88		},
89	}
90}
91
92func (fg *fileGroup) GenerateAndroidBuildActions(ctx ModuleContext) {
93	fg.srcs = PathsForModuleSrcExcludes(ctx, fg.properties.Srcs.GetOrDefault(ctx, nil), fg.properties.Exclude_srcs.GetOrDefault(ctx, nil))
94	if fg.properties.Path != nil {
95		fg.srcs = PathsWithModuleSrcSubDir(ctx, fg.srcs, String(fg.properties.Path))
96	}
97	SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: fg.srcs.Strings()})
98
99	var aconfigDeclarations []string
100	var intermediateCacheOutputPaths Paths
101	var srcjars Paths
102	modeInfos := make(map[string]ModeInfo)
103	ctx.VisitDirectDeps(func(module Module) {
104		if dep, ok := OtherModuleProvider(ctx, module, CodegenInfoProvider); ok {
105			aconfigDeclarations = append(aconfigDeclarations, dep.AconfigDeclarations...)
106			intermediateCacheOutputPaths = append(intermediateCacheOutputPaths, dep.IntermediateCacheOutputPaths...)
107			srcjars = append(srcjars, dep.Srcjars...)
108			maps.Copy(modeInfos, dep.ModeInfos)
109		}
110	})
111	SetProvider(ctx, CodegenInfoProvider, CodegenInfo{
112		AconfigDeclarations:          aconfigDeclarations,
113		IntermediateCacheOutputPaths: intermediateCacheOutputPaths,
114		Srcjars:                      srcjars,
115		ModeInfos:                    modeInfos,
116	})
117}
118
119func (fg *fileGroup) Srcs() Paths {
120	return append(Paths{}, fg.srcs...)
121}
122
123func (fg *fileGroup) MakeVars(ctx MakeVarsModuleContext) {
124	if makeVar := String(fg.properties.Export_to_make_var); makeVar != "" {
125		ctx.StrictRaw(makeVar, strings.Join(fg.srcs.Strings(), " "))
126	}
127}
128
129// Defaults
130type FileGroupDefaults struct {
131	ModuleBase
132	DefaultsModuleBase
133}
134
135func FileGroupDefaultsFactory() Module {
136	module := &FileGroupDefaults{}
137	module.AddProperties(&fileGroupProperties{})
138	InitDefaultsModule(module)
139
140	return module
141}
142