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	"io"
19	"strings"
20	"text/template"
21)
22
23func init() {
24	RegisterModuleType("filegroup", FileGroupFactory)
25}
26
27type fileGroupProperties struct {
28	// srcs lists files that will be included in this filegroup
29	Srcs []string `android:"path"`
30
31	Exclude_srcs []string `android:"path"`
32
33	// The base path to the files.  May be used by other modules to determine which portion
34	// of the path to use.  For example, when a filegroup is used as data in a cc_test rule,
35	// the base path is stripped off the path and the remaining path is used as the
36	// installation directory.
37	Path *string
38
39	// Create a make variable with the specified name that contains the list of files in the
40	// filegroup, relative to the root of the source tree.
41	Export_to_make_var *string
42}
43
44type fileGroup struct {
45	ModuleBase
46	properties fileGroupProperties
47	srcs       Paths
48}
49
50var _ SourceFileProducer = (*fileGroup)(nil)
51
52// filegroup contains a list of files that are referenced by other modules
53// properties (such as "srcs") using the syntax ":<name>". filegroup are
54// also be used to export files across package boundaries.
55func FileGroupFactory() Module {
56	module := &fileGroup{}
57	module.AddProperties(&module.properties)
58	InitAndroidModule(module)
59	return module
60}
61
62func (fg *fileGroup) GenerateAndroidBuildActions(ctx ModuleContext) {
63	fg.srcs = PathsForModuleSrcExcludes(ctx, fg.properties.Srcs, fg.properties.Exclude_srcs)
64
65	if fg.properties.Path != nil {
66		fg.srcs = PathsWithModuleSrcSubDir(ctx, fg.srcs, String(fg.properties.Path))
67	}
68}
69
70func (fg *fileGroup) Srcs() Paths {
71	return append(Paths{}, fg.srcs...)
72}
73
74var androidMkTemplate = template.Must(template.New("filegroup").Parse(`
75ifdef {{.makeVar}}
76  $(error variable {{.makeVar}} set by soong module is already set in make)
77endif
78{{.makeVar}} := {{.value}}
79.KATI_READONLY := {{.makeVar}}
80`))
81
82func (fg *fileGroup) AndroidMk() AndroidMkData {
83	return AndroidMkData{
84		Custom: func(w io.Writer, name, prefix, moduleDir string, data AndroidMkData) {
85			if makeVar := String(fg.properties.Export_to_make_var); makeVar != "" {
86				androidMkTemplate.Execute(w, map[string]string{
87					"makeVar": makeVar,
88					"value":   strings.Join(fg.srcs.Strings(), " "),
89				})
90			}
91		},
92	}
93}
94