blob: b393831807465e3e13342183af518f89ad489788 [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
23 "android/soong/common"
24)
25
Colin Cross5049f022015-03-18 13:28:46 -070026var (
27 pctx = blueprint.NewPackageContext("android/soong/genrule")
28)
29
30func init() {
Colin Cross1332b002015-04-07 17:11:30 -070031 pctx.VariableConfigMethod("srcDir", common.Config.SrcDir)
Colin Crossd350ecd2015-04-28 13:25:36 -070032 pctx.VariableConfigMethod("hostBin", common.Config.HostBin)
Colin Cross5049f022015-03-18 13:28:46 -070033}
34
35type SourceFileGenerator interface {
36 GeneratedSourceFiles() []string
37}
38
Colin Crossd350ecd2015-04-28 13:25:36 -070039type HostToolProvider interface {
40 HostToolPath() string
41}
Colin Cross5049f022015-03-18 13:28:46 -070042
Colin Cross7d5136f2015-05-11 13:39:40 -070043type generatorProperties struct {
44 // command to run on one or more input files. Available variables for substitution:
45 // $in: one or more input files
46 // $out: a single output file
47 // $srcDir: the root directory of the source tree
48 // The host bin directory will be in the path
49 Cmd string
50
51 // name of the module (if any) that produces the host executable. Leave empty for
52 // prebuilts or scripts that do not need a module to build them.
53 Tool string
54}
55
Colin Crossd350ecd2015-04-28 13:25:36 -070056type generator struct {
57 common.AndroidModuleBase
58
Colin Cross7d5136f2015-05-11 13:39:40 -070059 properties generatorProperties
Colin Crossd350ecd2015-04-28 13:25:36 -070060
61 tasks taskFunc
62
63 deps []string
64 rule blueprint.Rule
65
66 outputFiles []string
67}
68
69type taskFunc func(ctx common.AndroidModuleContext) []generateTask
70
71type generateTask struct {
72 in []string
73 out string
74}
75
76func (g *generator) GeneratedSourceFiles() []string {
77 return g.outputFiles
78}
79
80func (g *generator) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
81 if g.properties.Tool != "" {
Colin Crossf9964d52015-05-11 13:38:59 -070082 ctx.AddFarVariationDependencies([]blueprint.Variation{{"hostordevice", common.Host.String()}},
83 g.properties.Tool)
Colin Crossd350ecd2015-04-28 13:25:36 -070084 }
85 return nil
86}
87
88func (g *generator) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
89 g.rule = ctx.Rule(pctx, "generator", blueprint.RuleParams{
90 Command: "PATH=$$PATH:$hostBin " + g.properties.Cmd,
91 })
92
93 ctx.VisitDirectDeps(func(module blueprint.Module) {
94 if t, ok := module.(HostToolProvider); ok {
95 p := t.HostToolPath()
96 if p != "" {
97 g.deps = append(g.deps, p)
98 } else {
99 ctx.ModuleErrorf("host tool %q missing output file", ctx.OtherModuleName(module))
100 }
101 } else {
102 ctx.ModuleErrorf("unknown dependency %q", ctx.OtherModuleName(module))
103 }
104 })
105
106 for _, task := range g.tasks(ctx) {
107 g.generateSourceFile(ctx, task)
108 }
109}
110
111func (g *generator) generateSourceFile(ctx common.AndroidModuleContext, task generateTask) {
112
113 ctx.Build(pctx, blueprint.BuildParams{
114 Rule: g.rule,
115 Inputs: task.in,
116 Implicits: g.deps,
117 Outputs: []string{task.out},
118 })
119
120 g.outputFiles = append(g.outputFiles, task.out)
121}
122
123func generatorFactory(tasks taskFunc, props ...interface{}) (blueprint.Module, []interface{}) {
124 module := &generator{
125 tasks: tasks,
126 }
127
128 props = append(props, &module.properties)
129
130 return common.InitAndroidModule(module, props...)
131}
132
133func GenSrcsFactory() (blueprint.Module, []interface{}) {
134 properties := &genSrcsProperties{}
135
136 tasks := func(ctx common.AndroidModuleContext) []generateTask {
Colin Cross8f101b42015-06-17 15:09:06 -0700137 srcFiles := ctx.ExpandSources(properties.Srcs)
Colin Crossd350ecd2015-04-28 13:25:36 -0700138 tasks := make([]generateTask, 0, len(srcFiles))
139 for _, in := range srcFiles {
140 out := pathtools.ReplaceExtension(in, properties.Output_extension)
141 out = filepath.Join(common.ModuleGenDir(ctx), out)
142 tasks = append(tasks, generateTask{[]string{in}, out})
143 }
144 return tasks
145 }
146
147 return generatorFactory(tasks, properties)
148}
149
150type genSrcsProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700151 // list of input files
Colin Cross5049f022015-03-18 13:28:46 -0700152 Srcs []string
153
Colin Cross7d5136f2015-05-11 13:39:40 -0700154 // extension that will be substituted for each output file
Colin Cross5049f022015-03-18 13:28:46 -0700155 Output_extension string
156}
157
Colin Crossd350ecd2015-04-28 13:25:36 -0700158func GenRuleFactory() (blueprint.Module, []interface{}) {
159 properties := &genRuleProperties{}
Colin Cross5049f022015-03-18 13:28:46 -0700160
Colin Crossd350ecd2015-04-28 13:25:36 -0700161 tasks := func(ctx common.AndroidModuleContext) []generateTask {
162 return []generateTask{
163 {
Colin Cross8f101b42015-06-17 15:09:06 -0700164 in: ctx.ExpandSources(properties.Srcs),
Colin Crossd350ecd2015-04-28 13:25:36 -0700165 out: filepath.Join(common.ModuleGenDir(ctx), properties.Out),
166 },
167 }
Colin Cross5049f022015-03-18 13:28:46 -0700168 }
Colin Crossd350ecd2015-04-28 13:25:36 -0700169
170 return generatorFactory(tasks, properties)
Colin Cross5049f022015-03-18 13:28:46 -0700171}
172
Colin Crossd350ecd2015-04-28 13:25:36 -0700173type genRuleProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700174 // list of input files
Colin Crossd350ecd2015-04-28 13:25:36 -0700175 Srcs []string
Colin Cross5049f022015-03-18 13:28:46 -0700176
Colin Cross7d5136f2015-05-11 13:39:40 -0700177 // name of the output file that will be generated
Colin Crossd350ecd2015-04-28 13:25:36 -0700178 Out string
Colin Cross5049f022015-03-18 13:28:46 -0700179}