blob: 3c2e331fd7b6bedbb54ae68be27905b2db8d2b93 [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 (
Colin Cross70b40592015-03-23 12:57:34 -070018 "github.com/google/blueprint"
Colin Cross5049f022015-03-18 13:28:46 -070019
Colin Cross463a90e2015-06-17 14:20:06 -070020 "android/soong"
Colin Cross5049f022015-03-18 13:28:46 -070021 "android/soong/common"
22)
23
Colin Cross463a90e2015-06-17 14:20:06 -070024func init() {
25 soong.RegisterModuleType("gensrcs", GenSrcsFactory)
26 soong.RegisterModuleType("genrule", GenRuleFactory)
Colin Cross6362e272015-10-29 15:25:03 -070027
28 common.RegisterBottomUpMutator("genrule_deps", genruleDepsMutator)
Colin Cross463a90e2015-06-17 14:20:06 -070029}
30
Colin Cross5049f022015-03-18 13:28:46 -070031var (
Dan Willemsen34cc69e2015-09-23 15:26:20 -070032 pctx = common.NewPackageContext("android/soong/genrule")
Colin Cross5049f022015-03-18 13:28:46 -070033)
34
35func init() {
Dan Willemsen34cc69e2015-09-23 15:26:20 -070036 pctx.SourcePathVariable("srcDir", "")
37 pctx.HostBinToolVariable("hostBin", "")
Colin Cross5049f022015-03-18 13:28:46 -070038}
39
40type SourceFileGenerator interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -070041 GeneratedSourceFiles() common.Paths
Dan Willemsenb40aab62016-04-20 14:21:14 -070042 GeneratedHeaderDir() common.Path
Colin Cross5049f022015-03-18 13:28:46 -070043}
44
Colin Crossd350ecd2015-04-28 13:25:36 -070045type HostToolProvider interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -070046 HostToolPath() common.OptionalPath
Colin Crossd350ecd2015-04-28 13:25:36 -070047}
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
Dan Willemsen34cc69e2015-09-23 15:26:20 -070069 deps common.Paths
Colin Crossd350ecd2015-04-28 13:25:36 -070070 rule blueprint.Rule
71
Dan Willemsenb40aab62016-04-20 14:21:14 -070072 genPath common.Path
73
Dan Willemsen34cc69e2015-09-23 15:26:20 -070074 outputFiles common.Paths
Colin Crossd350ecd2015-04-28 13:25:36 -070075}
76
77type taskFunc func(ctx common.AndroidModuleContext) []generateTask
78
79type generateTask struct {
Dan Willemsen34cc69e2015-09-23 15:26:20 -070080 in common.Paths
81 out common.ModuleGenPath
Colin Crossd350ecd2015-04-28 13:25:36 -070082}
83
Dan Willemsen34cc69e2015-09-23 15:26:20 -070084func (g *generator) GeneratedSourceFiles() common.Paths {
Colin Crossd350ecd2015-04-28 13:25:36 -070085 return g.outputFiles
86}
87
Dan Willemsenb40aab62016-04-20 14:21:14 -070088func (g *generator) GeneratedHeaderDir() common.Path {
89 return g.genPath
90}
91
Colin Cross6362e272015-10-29 15:25:03 -070092func genruleDepsMutator(ctx common.AndroidBottomUpMutatorContext) {
93 if g, ok := ctx.Module().(*generator); ok {
94 if g.properties.Tool != "" {
Dan Willemsen490fd492015-11-24 17:53:15 -080095 ctx.AddFarVariationDependencies([]blueprint.Variation{
Colin Cross1604ecf2015-12-17 16:33:43 -080096 {"host_or_device", common.Host.String()},
97 {"host_type", common.CurrentHostType().String()},
Colin Crossc99deeb2016-04-11 15:06:20 -070098 }, nil, g.properties.Tool)
Colin Cross6362e272015-10-29 15:25:03 -070099 }
Colin Crossd350ecd2015-04-28 13:25:36 -0700100 }
Colin Crossd350ecd2015-04-28 13:25:36 -0700101}
102
103func (g *generator) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
104 g.rule = ctx.Rule(pctx, "generator", blueprint.RuleParams{
105 Command: "PATH=$$PATH:$hostBin " + g.properties.Cmd,
106 })
107
108 ctx.VisitDirectDeps(func(module blueprint.Module) {
109 if t, ok := module.(HostToolProvider); ok {
110 p := t.HostToolPath()
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700111 if p.Valid() {
112 g.deps = append(g.deps, p.Path())
Colin Crossd350ecd2015-04-28 13:25:36 -0700113 } else {
114 ctx.ModuleErrorf("host tool %q missing output file", ctx.OtherModuleName(module))
115 }
116 } else {
117 ctx.ModuleErrorf("unknown dependency %q", ctx.OtherModuleName(module))
118 }
119 })
120
Dan Willemsenb40aab62016-04-20 14:21:14 -0700121 g.genPath = common.PathForModuleGen(ctx, "")
122
Colin Crossd350ecd2015-04-28 13:25:36 -0700123 for _, task := range g.tasks(ctx) {
124 g.generateSourceFile(ctx, task)
125 }
126}
127
128func (g *generator) generateSourceFile(ctx common.AndroidModuleContext, task generateTask) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700129 ctx.ModuleBuild(pctx, common.ModuleBuildParams{
Colin Crossd350ecd2015-04-28 13:25:36 -0700130 Rule: g.rule,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700131 Output: task.out,
Colin Crossd350ecd2015-04-28 13:25:36 -0700132 Inputs: task.in,
133 Implicits: g.deps,
Colin Crossd350ecd2015-04-28 13:25:36 -0700134 })
135
136 g.outputFiles = append(g.outputFiles, task.out)
137}
138
139func generatorFactory(tasks taskFunc, props ...interface{}) (blueprint.Module, []interface{}) {
140 module := &generator{
141 tasks: tasks,
142 }
143
144 props = append(props, &module.properties)
145
146 return common.InitAndroidModule(module, props...)
147}
148
149func GenSrcsFactory() (blueprint.Module, []interface{}) {
150 properties := &genSrcsProperties{}
151
152 tasks := func(ctx common.AndroidModuleContext) []generateTask {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700153 srcFiles := ctx.ExpandSources(properties.Srcs, nil)
Colin Crossd350ecd2015-04-28 13:25:36 -0700154 tasks := make([]generateTask, 0, len(srcFiles))
155 for _, in := range srcFiles {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700156 tasks = append(tasks, generateTask{
157 in: common.Paths{in},
158 out: common.GenPathWithExt(ctx, in, properties.Output_extension),
159 })
Colin Crossd350ecd2015-04-28 13:25:36 -0700160 }
161 return tasks
162 }
163
164 return generatorFactory(tasks, properties)
165}
166
167type genSrcsProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700168 // list of input files
Colin Cross5049f022015-03-18 13:28:46 -0700169 Srcs []string
170
Colin Cross7d5136f2015-05-11 13:39:40 -0700171 // extension that will be substituted for each output file
Colin Cross5049f022015-03-18 13:28:46 -0700172 Output_extension string
173}
174
Colin Crossd350ecd2015-04-28 13:25:36 -0700175func GenRuleFactory() (blueprint.Module, []interface{}) {
176 properties := &genRuleProperties{}
Colin Cross5049f022015-03-18 13:28:46 -0700177
Colin Crossd350ecd2015-04-28 13:25:36 -0700178 tasks := func(ctx common.AndroidModuleContext) []generateTask {
179 return []generateTask{
180 {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700181 in: ctx.ExpandSources(properties.Srcs, nil),
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700182 out: properties.Out,
Colin Crossd350ecd2015-04-28 13:25:36 -0700183 },
184 }
Colin Cross5049f022015-03-18 13:28:46 -0700185 }
Colin Crossd350ecd2015-04-28 13:25:36 -0700186
187 return generatorFactory(tasks, properties)
Colin Cross5049f022015-03-18 13:28:46 -0700188}
189
Colin Crossd350ecd2015-04-28 13:25:36 -0700190type genRuleProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700191 // list of input files
Colin Crossd350ecd2015-04-28 13:25:36 -0700192 Srcs []string
Colin Cross5049f022015-03-18 13:28:46 -0700193
Colin Cross7d5136f2015-05-11 13:39:40 -0700194 // name of the output file that will be generated
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700195 Out common.ModuleGenPath
Colin Cross5049f022015-03-18 13:28:46 -0700196}