blob: a5a4c71f20088ac5fe615400fafa62cac7e8af06 [file] [log] [blame]
Colin Cross5049f022015-03-18 13:28:46 -07001// Copyright 2015 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 genrule
16
17import (
18 "path/filepath"
19
Colin Cross70b40592015-03-23 12:57:34 -070020 "github.com/google/blueprint"
21 "github.com/google/blueprint/pathtools"
Colin Cross5049f022015-03-18 13:28:46 -070022
Colin Cross463a90e2015-06-17 14:20:06 -070023 "android/soong"
Colin Cross5049f022015-03-18 13:28:46 -070024 "android/soong/common"
25)
26
Colin Cross463a90e2015-06-17 14:20:06 -070027func init() {
28 soong.RegisterModuleType("gensrcs", GenSrcsFactory)
29 soong.RegisterModuleType("genrule", GenRuleFactory)
30}
31
Colin Cross5049f022015-03-18 13:28:46 -070032var (
33 pctx = blueprint.NewPackageContext("android/soong/genrule")
34)
35
36func init() {
Colin Cross1332b002015-04-07 17:11:30 -070037 pctx.VariableConfigMethod("srcDir", common.Config.SrcDir)
Colin Crossd350ecd2015-04-28 13:25:36 -070038 pctx.VariableConfigMethod("hostBin", common.Config.HostBin)
Colin Cross5049f022015-03-18 13:28:46 -070039}
40
41type SourceFileGenerator interface {
42 GeneratedSourceFiles() []string
43}
44
Colin Crossd350ecd2015-04-28 13:25:36 -070045type HostToolProvider interface {
46 HostToolPath() string
47}
Colin Cross5049f022015-03-18 13:28:46 -070048
Colin Cross7d5136f2015-05-11 13:39:40 -070049type generatorProperties struct {
50 // command to run on one or more input files. Available variables for substitution:
51 // $in: one or more input files
52 // $out: a single output file
53 // $srcDir: the root directory of the source tree
54 // The host bin directory will be in the path
55 Cmd string
56
57 // name of the module (if any) that produces the host executable. Leave empty for
58 // prebuilts or scripts that do not need a module to build them.
59 Tool string
60}
61
Colin Crossd350ecd2015-04-28 13:25:36 -070062type generator struct {
63 common.AndroidModuleBase
64
Colin Cross7d5136f2015-05-11 13:39:40 -070065 properties generatorProperties
Colin Crossd350ecd2015-04-28 13:25:36 -070066
67 tasks taskFunc
68
69 deps []string
70 rule blueprint.Rule
71
72 outputFiles []string
73}
74
75type taskFunc func(ctx common.AndroidModuleContext) []generateTask
76
77type generateTask struct {
78 in []string
79 out string
80}
81
82func (g *generator) GeneratedSourceFiles() []string {
83 return g.outputFiles
84}
85
86func (g *generator) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
87 if g.properties.Tool != "" {
Colin Crossf9964d52015-05-11 13:38:59 -070088 ctx.AddFarVariationDependencies([]blueprint.Variation{{"hostordevice", common.Host.String()}},
89 g.properties.Tool)
Colin Crossd350ecd2015-04-28 13:25:36 -070090 }
91 return nil
92}
93
94func (g *generator) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
95 g.rule = ctx.Rule(pctx, "generator", blueprint.RuleParams{
96 Command: "PATH=$$PATH:$hostBin " + g.properties.Cmd,
97 })
98
99 ctx.VisitDirectDeps(func(module blueprint.Module) {
100 if t, ok := module.(HostToolProvider); ok {
101 p := t.HostToolPath()
102 if p != "" {
103 g.deps = append(g.deps, p)
104 } else {
105 ctx.ModuleErrorf("host tool %q missing output file", ctx.OtherModuleName(module))
106 }
107 } else {
108 ctx.ModuleErrorf("unknown dependency %q", ctx.OtherModuleName(module))
109 }
110 })
111
112 for _, task := range g.tasks(ctx) {
113 g.generateSourceFile(ctx, task)
114 }
115}
116
117func (g *generator) generateSourceFile(ctx common.AndroidModuleContext, task generateTask) {
118
119 ctx.Build(pctx, blueprint.BuildParams{
120 Rule: g.rule,
121 Inputs: task.in,
122 Implicits: g.deps,
123 Outputs: []string{task.out},
124 })
125
126 g.outputFiles = append(g.outputFiles, task.out)
127}
128
129func generatorFactory(tasks taskFunc, props ...interface{}) (blueprint.Module, []interface{}) {
130 module := &generator{
131 tasks: tasks,
132 }
133
134 props = append(props, &module.properties)
135
136 return common.InitAndroidModule(module, props...)
137}
138
139func GenSrcsFactory() (blueprint.Module, []interface{}) {
140 properties := &genSrcsProperties{}
141
142 tasks := func(ctx common.AndroidModuleContext) []generateTask {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700143 srcFiles := ctx.ExpandSources(properties.Srcs, nil)
Colin Crossd350ecd2015-04-28 13:25:36 -0700144 tasks := make([]generateTask, 0, len(srcFiles))
145 for _, in := range srcFiles {
146 out := pathtools.ReplaceExtension(in, properties.Output_extension)
147 out = filepath.Join(common.ModuleGenDir(ctx), out)
148 tasks = append(tasks, generateTask{[]string{in}, out})
149 }
150 return tasks
151 }
152
153 return generatorFactory(tasks, properties)
154}
155
156type genSrcsProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700157 // list of input files
Colin Cross5049f022015-03-18 13:28:46 -0700158 Srcs []string
159
Colin Cross7d5136f2015-05-11 13:39:40 -0700160 // extension that will be substituted for each output file
Colin Cross5049f022015-03-18 13:28:46 -0700161 Output_extension string
162}
163
Colin Crossd350ecd2015-04-28 13:25:36 -0700164func GenRuleFactory() (blueprint.Module, []interface{}) {
165 properties := &genRuleProperties{}
Colin Cross5049f022015-03-18 13:28:46 -0700166
Colin Crossd350ecd2015-04-28 13:25:36 -0700167 tasks := func(ctx common.AndroidModuleContext) []generateTask {
168 return []generateTask{
169 {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700170 in: ctx.ExpandSources(properties.Srcs, nil),
Colin Crossd350ecd2015-04-28 13:25:36 -0700171 out: filepath.Join(common.ModuleGenDir(ctx), properties.Out),
172 },
173 }
Colin Cross5049f022015-03-18 13:28:46 -0700174 }
Colin Crossd350ecd2015-04-28 13:25:36 -0700175
176 return generatorFactory(tasks, properties)
Colin Cross5049f022015-03-18 13:28:46 -0700177}
178
Colin Crossd350ecd2015-04-28 13:25:36 -0700179type genRuleProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700180 // list of input files
Colin Crossd350ecd2015-04-28 13:25:36 -0700181 Srcs []string
Colin Cross5049f022015-03-18 13:28:46 -0700182
Colin Cross7d5136f2015-05-11 13:39:40 -0700183 // name of the output file that will be generated
Colin Crossd350ecd2015-04-28 13:25:36 -0700184 Out string
Colin Cross5049f022015-03-18 13:28:46 -0700185}