| Colin Cross | 5049f02 | 2015-03-18 13:28:46 -0700 | [diff] [blame] | 1 | // 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 |  | 
|  | 15 | package genrule | 
|  | 16 |  | 
|  | 17 | import ( | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 18 | "fmt" | 
| Jeff Gaston | efc1b41 | 2017-03-29 17:29:06 -0700 | [diff] [blame] | 19 | "path" | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 20 | "strings" | 
| Dan Willemsen | 3f4539b | 2016-09-28 16:19:10 -0700 | [diff] [blame] | 21 |  | 
| Colin Cross | 70b4059 | 2015-03-23 12:57:34 -0700 | [diff] [blame] | 22 | "github.com/google/blueprint" | 
| Dan Willemsen | 8eded0a | 2017-09-13 16:07:44 -0700 | [diff] [blame] | 23 | "github.com/google/blueprint/bootstrap" | 
| Colin Cross | 5049f02 | 2015-03-18 13:28:46 -0700 | [diff] [blame] | 24 |  | 
| Colin Cross | 635c3b0 | 2016-05-18 15:37:25 -0700 | [diff] [blame] | 25 | "android/soong/android" | 
| Jeff Gaston | efc1b41 | 2017-03-29 17:29:06 -0700 | [diff] [blame] | 26 | "android/soong/shared" | 
|  | 27 | "path/filepath" | 
| Colin Cross | 5049f02 | 2015-03-18 13:28:46 -0700 | [diff] [blame] | 28 | ) | 
|  | 29 |  | 
| Colin Cross | 463a90e | 2015-06-17 14:20:06 -0700 | [diff] [blame] | 30 | func init() { | 
| Colin Cross | 798bfce | 2016-10-12 14:28:16 -0700 | [diff] [blame] | 31 | android.RegisterModuleType("gensrcs", GenSrcsFactory) | 
|  | 32 | android.RegisterModuleType("genrule", GenRuleFactory) | 
| Colin Cross | 463a90e | 2015-06-17 14:20:06 -0700 | [diff] [blame] | 33 | } | 
|  | 34 |  | 
| Colin Cross | 5049f02 | 2015-03-18 13:28:46 -0700 | [diff] [blame] | 35 | var ( | 
| Colin Cross | 635c3b0 | 2016-05-18 15:37:25 -0700 | [diff] [blame] | 36 | pctx = android.NewPackageContext("android/soong/genrule") | 
| Colin Cross | 5049f02 | 2015-03-18 13:28:46 -0700 | [diff] [blame] | 37 | ) | 
|  | 38 |  | 
| Jeff Gaston | efc1b41 | 2017-03-29 17:29:06 -0700 | [diff] [blame] | 39 | func init() { | 
|  | 40 | pctx.HostBinToolVariable("sboxCmd", "sbox") | 
|  | 41 | } | 
|  | 42 |  | 
| Colin Cross | 5049f02 | 2015-03-18 13:28:46 -0700 | [diff] [blame] | 43 | type SourceFileGenerator interface { | 
| Colin Cross | 635c3b0 | 2016-05-18 15:37:25 -0700 | [diff] [blame] | 44 | GeneratedSourceFiles() android.Paths | 
| Colin Cross | 5ed99c6 | 2016-11-22 12:55:55 -0800 | [diff] [blame] | 45 | GeneratedHeaderDirs() android.Paths | 
| Colin Cross | 5049f02 | 2015-03-18 13:28:46 -0700 | [diff] [blame] | 46 | } | 
|  | 47 |  | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 48 | type HostToolProvider interface { | 
| Colin Cross | 635c3b0 | 2016-05-18 15:37:25 -0700 | [diff] [blame] | 49 | HostToolPath() android.OptionalPath | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 50 | } | 
| Colin Cross | 5049f02 | 2015-03-18 13:28:46 -0700 | [diff] [blame] | 51 |  | 
| Dan Willemsen | d6ba0d5 | 2017-09-13 15:46:47 -0700 | [diff] [blame] | 52 | type hostToolDependencyTag struct { | 
|  | 53 | blueprint.BaseDependencyTag | 
|  | 54 | } | 
|  | 55 |  | 
|  | 56 | var hostToolDepTag hostToolDependencyTag | 
|  | 57 |  | 
| Colin Cross | 7d5136f | 2015-05-11 13:39:40 -0700 | [diff] [blame] | 58 | type generatorProperties struct { | 
| Jeff Gaston | efc1b41 | 2017-03-29 17:29:06 -0700 | [diff] [blame] | 59 | // The command to run on one or more input files. Cmd supports substitution of a few variables | 
|  | 60 | // (the actual substitution is implemented in GenerateAndroidBuildActions below) | 
|  | 61 | // | 
|  | 62 | // Available variables for substitution: | 
|  | 63 | // | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 64 | // $(location): the path to the first entry in tools or tool_files | 
|  | 65 | // $(location <label>): the path to the tool or tool_file with name <label> | 
|  | 66 | // $(in): one or more input files | 
|  | 67 | // $(out): a single output file | 
| Dan Willemsen | 014de6a | 2017-05-09 23:08:55 +0000 | [diff] [blame] | 68 | // $(depfile): a file to which dependencies will be written, if the depfile property is set to true | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 69 | // $(genDir): the sandbox directory for this tool; contains $(out) | 
|  | 70 | // $$: a literal $ | 
|  | 71 | // | 
| Jeff Gaston | efc1b41 | 2017-03-29 17:29:06 -0700 | [diff] [blame] | 72 | // All files used must be declared as inputs (to ensure proper up-to-date checks). | 
|  | 73 | // Use "$(in)" directly in Cmd to ensure that all inputs used are declared. | 
| Colin Cross | 7d5136f | 2015-05-11 13:39:40 -0700 | [diff] [blame] | 74 | Cmd string | 
|  | 75 |  | 
| Colin Cross | 33bfb0a | 2016-11-21 17:23:08 -0800 | [diff] [blame] | 76 | // Enable reading a file containing dependencies in gcc format after the command completes | 
|  | 77 | Depfile bool | 
|  | 78 |  | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 79 | // name of the modules (if any) that produces the host executable.   Leave empty for | 
| Colin Cross | 7d5136f | 2015-05-11 13:39:40 -0700 | [diff] [blame] | 80 | // prebuilts or scripts that do not need a module to build them. | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 81 | Tools []string | 
| Dan Willemsen | f7f3d69 | 2016-04-20 14:54:32 -0700 | [diff] [blame] | 82 |  | 
|  | 83 | // Local file that is used as the tool | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 84 | Tool_files []string | 
| Colin Cross | 5ed99c6 | 2016-11-22 12:55:55 -0800 | [diff] [blame] | 85 |  | 
|  | 86 | // List of directories to export generated headers from | 
|  | 87 | Export_include_dirs []string | 
| Colin Cross | 708c424 | 2017-01-13 18:05:49 -0800 | [diff] [blame] | 88 |  | 
|  | 89 | // list of input files | 
|  | 90 | Srcs []string | 
| Colin Cross | 7d5136f | 2015-05-11 13:39:40 -0700 | [diff] [blame] | 91 | } | 
|  | 92 |  | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 93 | type generator struct { | 
| Colin Cross | 635c3b0 | 2016-05-18 15:37:25 -0700 | [diff] [blame] | 94 | android.ModuleBase | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 95 |  | 
| Colin Cross | 7d5136f | 2015-05-11 13:39:40 -0700 | [diff] [blame] | 96 | properties generatorProperties | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 97 |  | 
|  | 98 | tasks taskFunc | 
|  | 99 |  | 
| Colin Cross | 635c3b0 | 2016-05-18 15:37:25 -0700 | [diff] [blame] | 100 | deps android.Paths | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 101 | rule blueprint.Rule | 
|  | 102 |  | 
| Colin Cross | 5ed99c6 | 2016-11-22 12:55:55 -0800 | [diff] [blame] | 103 | exportedIncludeDirs android.Paths | 
| Dan Willemsen | b40aab6 | 2016-04-20 14:21:14 -0700 | [diff] [blame] | 104 |  | 
| Colin Cross | 635c3b0 | 2016-05-18 15:37:25 -0700 | [diff] [blame] | 105 | outputFiles android.Paths | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 106 | } | 
|  | 107 |  | 
| Colin Cross | 708c424 | 2017-01-13 18:05:49 -0800 | [diff] [blame] | 108 | type taskFunc func(ctx android.ModuleContext, srcFiles android.Paths) []generateTask | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 109 |  | 
|  | 110 | type generateTask struct { | 
| Colin Cross | 635c3b0 | 2016-05-18 15:37:25 -0700 | [diff] [blame] | 111 | in  android.Paths | 
| Dan Willemsen | 9c8681f | 2016-09-28 16:21:00 -0700 | [diff] [blame] | 112 | out android.WritablePaths | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 113 | } | 
|  | 114 |  | 
| Colin Cross | 635c3b0 | 2016-05-18 15:37:25 -0700 | [diff] [blame] | 115 | func (g *generator) GeneratedSourceFiles() android.Paths { | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 116 | return g.outputFiles | 
|  | 117 | } | 
|  | 118 |  | 
| Colin Cross | 068e0fe | 2016-12-13 15:23:47 -0800 | [diff] [blame] | 119 | func (g *generator) Srcs() android.Paths { | 
|  | 120 | return g.outputFiles | 
|  | 121 | } | 
|  | 122 |  | 
| Colin Cross | 5ed99c6 | 2016-11-22 12:55:55 -0800 | [diff] [blame] | 123 | func (g *generator) GeneratedHeaderDirs() android.Paths { | 
|  | 124 | return g.exportedIncludeDirs | 
| Dan Willemsen | b40aab6 | 2016-04-20 14:21:14 -0700 | [diff] [blame] | 125 | } | 
|  | 126 |  | 
| Colin Cross | 1e676be | 2016-10-12 14:38:15 -0700 | [diff] [blame] | 127 | func (g *generator) DepsMutator(ctx android.BottomUpMutatorContext) { | 
| Colin Cross | 708c424 | 2017-01-13 18:05:49 -0800 | [diff] [blame] | 128 | android.ExtractSourcesDeps(ctx, g.properties.Srcs) | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 129 | if g, ok := ctx.Module().(*generator); ok { | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 130 | if len(g.properties.Tools) > 0 { | 
| Dan Willemsen | 490fd49 | 2015-11-24 17:53:15 -0800 | [diff] [blame] | 131 | ctx.AddFarVariationDependencies([]blueprint.Variation{ | 
| Colin Cross | a1ad8d1 | 2016-06-01 17:09:44 -0700 | [diff] [blame] | 132 | {"arch", ctx.AConfig().BuildOsVariant}, | 
| Dan Willemsen | d6ba0d5 | 2017-09-13 15:46:47 -0700 | [diff] [blame] | 133 | }, hostToolDepTag, g.properties.Tools...) | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 134 | } | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 135 | } | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 136 | } | 
|  | 137 |  | 
| Colin Cross | 635c3b0 | 2016-05-18 15:37:25 -0700 | [diff] [blame] | 138 | func (g *generator) GenerateAndroidBuildActions(ctx android.ModuleContext) { | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 139 | if len(g.properties.Tools) == 0 && len(g.properties.Tool_files) == 0 { | 
|  | 140 | ctx.ModuleErrorf("at least one `tools` or `tool_files` is required") | 
| Dan Willemsen | f7f3d69 | 2016-04-20 14:54:32 -0700 | [diff] [blame] | 141 | return | 
|  | 142 | } | 
|  | 143 |  | 
| Colin Cross | 5ed99c6 | 2016-11-22 12:55:55 -0800 | [diff] [blame] | 144 | if len(g.properties.Export_include_dirs) > 0 { | 
|  | 145 | for _, dir := range g.properties.Export_include_dirs { | 
|  | 146 | g.exportedIncludeDirs = append(g.exportedIncludeDirs, | 
|  | 147 | android.PathForModuleGen(ctx, ctx.ModuleDir(), dir)) | 
|  | 148 | } | 
|  | 149 | } else { | 
|  | 150 | g.exportedIncludeDirs = append(g.exportedIncludeDirs, android.PathForModuleGen(ctx, "")) | 
|  | 151 | } | 
| Dan Willemsen | 3f4539b | 2016-09-28 16:19:10 -0700 | [diff] [blame] | 152 |  | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 153 | tools := map[string]android.Path{} | 
| Dan Willemsen | 3f4539b | 2016-09-28 16:19:10 -0700 | [diff] [blame] | 154 |  | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 155 | if len(g.properties.Tools) > 0 { | 
| Dan Willemsen | f7f3d69 | 2016-04-20 14:54:32 -0700 | [diff] [blame] | 156 | ctx.VisitDirectDeps(func(module blueprint.Module) { | 
| Dan Willemsen | d6ba0d5 | 2017-09-13 15:46:47 -0700 | [diff] [blame] | 157 | switch ctx.OtherModuleDependencyTag(module) { | 
|  | 158 | case android.SourceDepTag: | 
|  | 159 | // Nothing to do | 
|  | 160 | case hostToolDepTag: | 
|  | 161 | tool := ctx.OtherModuleName(module) | 
| Dan Willemsen | 8eded0a | 2017-09-13 16:07:44 -0700 | [diff] [blame] | 162 | var path android.OptionalPath | 
| Dan Willemsen | d6ba0d5 | 2017-09-13 15:46:47 -0700 | [diff] [blame] | 163 |  | 
|  | 164 | if t, ok := module.(HostToolProvider); ok { | 
| Dan Willemsen | 8eded0a | 2017-09-13 16:07:44 -0700 | [diff] [blame] | 165 | path = t.HostToolPath() | 
|  | 166 | } else if t, ok := module.(bootstrap.GoBinaryTool); ok { | 
|  | 167 | if s, err := filepath.Rel(android.PathForOutput(ctx).String(), t.InstallPath()); err == nil { | 
|  | 168 | path = android.OptionalPathForPath(android.PathForOutput(ctx, s)) | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 169 | } else { | 
| Dan Willemsen | 8eded0a | 2017-09-13 16:07:44 -0700 | [diff] [blame] | 170 | ctx.ModuleErrorf("cannot find path for %q: %v", tool, err) | 
|  | 171 | break | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 172 | } | 
| Dan Willemsen | f7f3d69 | 2016-04-20 14:54:32 -0700 | [diff] [blame] | 173 | } else { | 
| Dan Willemsen | d6ba0d5 | 2017-09-13 15:46:47 -0700 | [diff] [blame] | 174 | ctx.ModuleErrorf("%q is not a host tool provider", tool) | 
| Dan Willemsen | 8eded0a | 2017-09-13 16:07:44 -0700 | [diff] [blame] | 175 | break | 
|  | 176 | } | 
|  | 177 |  | 
|  | 178 | if path.Valid() { | 
|  | 179 | g.deps = append(g.deps, path.Path()) | 
|  | 180 | if _, exists := tools[tool]; !exists { | 
|  | 181 | tools[tool] = path.Path() | 
|  | 182 | } else { | 
|  | 183 | ctx.ModuleErrorf("multiple tools for %q, %q and %q", tool, tools[tool], path.Path().String()) | 
|  | 184 | } | 
|  | 185 | } else { | 
|  | 186 | ctx.ModuleErrorf("host tool %q missing output file", tool) | 
| Dan Willemsen | f7f3d69 | 2016-04-20 14:54:32 -0700 | [diff] [blame] | 187 | } | 
| Dan Willemsen | d6ba0d5 | 2017-09-13 15:46:47 -0700 | [diff] [blame] | 188 | default: | 
|  | 189 | ctx.ModuleErrorf("unknown dependency on %q", ctx.OtherModuleName(module)) | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 190 | } | 
| Dan Willemsen | f7f3d69 | 2016-04-20 14:54:32 -0700 | [diff] [blame] | 191 | }) | 
|  | 192 | } | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 193 |  | 
| Dan Willemsen | d6ba0d5 | 2017-09-13 15:46:47 -0700 | [diff] [blame] | 194 | if ctx.Failed() { | 
|  | 195 | return | 
|  | 196 | } | 
|  | 197 |  | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 198 | for _, tool := range g.properties.Tool_files { | 
|  | 199 | toolPath := android.PathForModuleSrc(ctx, tool) | 
|  | 200 | g.deps = append(g.deps, toolPath) | 
|  | 201 | if _, exists := tools[tool]; !exists { | 
|  | 202 | tools[tool] = toolPath | 
|  | 203 | } else { | 
|  | 204 | ctx.ModuleErrorf("multiple tools for %q, %q and %q", tool, tools[tool], toolPath.String()) | 
|  | 205 | } | 
|  | 206 | } | 
|  | 207 |  | 
| Jeff Gaston | efc1b41 | 2017-03-29 17:29:06 -0700 | [diff] [blame] | 208 | rawCommand, err := android.Expand(g.properties.Cmd, func(name string) (string, error) { | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 209 | switch name { | 
|  | 210 | case "location": | 
|  | 211 | if len(g.properties.Tools) > 0 { | 
|  | 212 | return tools[g.properties.Tools[0]].String(), nil | 
|  | 213 | } else { | 
|  | 214 | return tools[g.properties.Tool_files[0]].String(), nil | 
|  | 215 | } | 
|  | 216 | case "in": | 
|  | 217 | return "${in}", nil | 
|  | 218 | case "out": | 
| Jeff Gaston | efc1b41 | 2017-03-29 17:29:06 -0700 | [diff] [blame] | 219 | return "__SBOX_OUT_FILES__", nil | 
| Colin Cross | 33bfb0a | 2016-11-21 17:23:08 -0800 | [diff] [blame] | 220 | case "depfile": | 
|  | 221 | if !g.properties.Depfile { | 
|  | 222 | return "", fmt.Errorf("$(depfile) used without depfile property") | 
|  | 223 | } | 
|  | 224 | return "${depfile}", nil | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 225 | case "genDir": | 
| Jeff Gaston | efc1b41 | 2017-03-29 17:29:06 -0700 | [diff] [blame] | 226 | genPath := android.PathForModuleGen(ctx, "").String() | 
|  | 227 | var relativePath string | 
| Jeff Gaston | 193f2fb | 2017-06-12 15:00:12 -0700 | [diff] [blame] | 228 | var err error | 
|  | 229 | outputPath := android.PathForOutput(ctx).String() | 
|  | 230 | relativePath, err = filepath.Rel(outputPath, genPath) | 
|  | 231 | if err != nil { | 
|  | 232 | panic(err) | 
| Jeff Gaston | efc1b41 | 2017-03-29 17:29:06 -0700 | [diff] [blame] | 233 | } | 
|  | 234 | return path.Join("__SBOX_OUT_DIR__", relativePath), nil | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 235 | default: | 
|  | 236 | if strings.HasPrefix(name, "location ") { | 
|  | 237 | label := strings.TrimSpace(strings.TrimPrefix(name, "location ")) | 
|  | 238 | if tool, ok := tools[label]; ok { | 
|  | 239 | return tool.String(), nil | 
|  | 240 | } else { | 
|  | 241 | return "", fmt.Errorf("unknown location label %q", label) | 
|  | 242 | } | 
|  | 243 | } | 
|  | 244 | return "", fmt.Errorf("unknown variable '$(%s)'", name) | 
|  | 245 | } | 
|  | 246 | }) | 
|  | 247 |  | 
|  | 248 | if err != nil { | 
|  | 249 | ctx.PropertyErrorf("cmd", "%s", err.Error()) | 
| Colin Cross | 54c5dd5 | 2017-04-19 14:23:26 -0700 | [diff] [blame] | 250 | return | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 251 | } | 
|  | 252 |  | 
| Jeff Gaston | efc1b41 | 2017-03-29 17:29:06 -0700 | [diff] [blame] | 253 | // tell the sbox command which directory to use as its sandbox root | 
| Jeff Gaston | 193f2fb | 2017-06-12 15:00:12 -0700 | [diff] [blame] | 254 | buildDir := android.PathForOutput(ctx).String() | 
|  | 255 | sandboxPath := shared.TempDirForOutDir(buildDir) | 
| Jeff Gaston | efc1b41 | 2017-03-29 17:29:06 -0700 | [diff] [blame] | 256 |  | 
|  | 257 | // recall that Sprintf replaces percent sign expressions, whereas dollar signs expressions remain as written, | 
|  | 258 | // to be replaced later by ninja_strings.go | 
| Jeff Gaston | 193f2fb | 2017-06-12 15:00:12 -0700 | [diff] [blame] | 259 | sandboxCommand := fmt.Sprintf("$sboxCmd --sandbox-path %s --output-root %s -c %q $out", sandboxPath, buildDir, rawCommand) | 
| Jeff Gaston | efc1b41 | 2017-03-29 17:29:06 -0700 | [diff] [blame] | 260 |  | 
| Colin Cross | 33bfb0a | 2016-11-21 17:23:08 -0800 | [diff] [blame] | 261 | ruleParams := blueprint.RuleParams{ | 
| Jeff Gaston | efc1b41 | 2017-03-29 17:29:06 -0700 | [diff] [blame] | 262 | Command:     sandboxCommand, | 
|  | 263 | CommandDeps: []string{"$sboxCmd"}, | 
| Colin Cross | 33bfb0a | 2016-11-21 17:23:08 -0800 | [diff] [blame] | 264 | } | 
|  | 265 | var args []string | 
|  | 266 | if g.properties.Depfile { | 
|  | 267 | ruleParams.Deps = blueprint.DepsGCC | 
|  | 268 | args = append(args, "depfile") | 
|  | 269 | } | 
|  | 270 | g.rule = ctx.Rule(pctx, "generator", ruleParams, args...) | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 271 |  | 
| Colin Cross | 708c424 | 2017-01-13 18:05:49 -0800 | [diff] [blame] | 272 | srcFiles := ctx.ExpandSources(g.properties.Srcs, nil) | 
|  | 273 | for _, task := range g.tasks(ctx, srcFiles) { | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 274 | g.generateSourceFile(ctx, task) | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 275 | } | 
|  | 276 | } | 
|  | 277 |  | 
| Colin Cross | 6f080df | 2016-11-04 15:32:58 -0700 | [diff] [blame] | 278 | func (g *generator) generateSourceFile(ctx android.ModuleContext, task generateTask) { | 
| Colin Cross | 67a5c13 | 2017-05-09 13:45:28 -0700 | [diff] [blame] | 279 | desc := "generate" | 
|  | 280 | if len(task.out) == 1 { | 
|  | 281 | desc += " " + task.out[0].Base() | 
|  | 282 | } | 
|  | 283 |  | 
| Colin Cross | 33bfb0a | 2016-11-21 17:23:08 -0800 | [diff] [blame] | 284 | params := android.ModuleBuildParams{ | 
| Colin Cross | 67a5c13 | 2017-05-09 13:45:28 -0700 | [diff] [blame] | 285 | Rule:        g.rule, | 
|  | 286 | Description: "generate", | 
|  | 287 | Outputs:     task.out, | 
|  | 288 | Inputs:      task.in, | 
|  | 289 | Implicits:   g.deps, | 
| Colin Cross | 33bfb0a | 2016-11-21 17:23:08 -0800 | [diff] [blame] | 290 | } | 
|  | 291 | if g.properties.Depfile { | 
|  | 292 | depfile := android.GenPathWithExt(ctx, "", task.out[0], task.out[0].Ext()+".d") | 
|  | 293 | params.Depfile = depfile | 
|  | 294 | } | 
|  | 295 | ctx.ModuleBuild(pctx, params) | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 296 |  | 
| Dan Willemsen | 9c8681f | 2016-09-28 16:21:00 -0700 | [diff] [blame] | 297 | for _, outputFile := range task.out { | 
|  | 298 | g.outputFiles = append(g.outputFiles, outputFile) | 
|  | 299 | } | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 300 | } | 
|  | 301 |  | 
| Colin Cross | 3624285 | 2017-06-23 15:06:31 -0700 | [diff] [blame] | 302 | func generatorFactory(tasks taskFunc, props ...interface{}) android.Module { | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 303 | module := &generator{ | 
|  | 304 | tasks: tasks, | 
|  | 305 | } | 
|  | 306 |  | 
| Colin Cross | 3624285 | 2017-06-23 15:06:31 -0700 | [diff] [blame] | 307 | module.AddProperties(props...) | 
|  | 308 | module.AddProperties(&module.properties) | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 309 |  | 
| Colin Cross | 3624285 | 2017-06-23 15:06:31 -0700 | [diff] [blame] | 310 | android.InitAndroidModule(module) | 
|  | 311 |  | 
|  | 312 | return module | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 313 | } | 
|  | 314 |  | 
| Colin Cross | 3624285 | 2017-06-23 15:06:31 -0700 | [diff] [blame] | 315 | func GenSrcsFactory() android.Module { | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 316 | properties := &genSrcsProperties{} | 
|  | 317 |  | 
| Colin Cross | 708c424 | 2017-01-13 18:05:49 -0800 | [diff] [blame] | 318 | tasks := func(ctx android.ModuleContext, srcFiles android.Paths) []generateTask { | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 319 | tasks := make([]generateTask, 0, len(srcFiles)) | 
|  | 320 | for _, in := range srcFiles { | 
| Dan Willemsen | 34cc69e | 2015-09-23 15:26:20 -0700 | [diff] [blame] | 321 | tasks = append(tasks, generateTask{ | 
| Colin Cross | 635c3b0 | 2016-05-18 15:37:25 -0700 | [diff] [blame] | 322 | in:  android.Paths{in}, | 
| Dan Willemsen | 21ec490 | 2016-11-02 20:43:13 -0700 | [diff] [blame] | 323 | out: android.WritablePaths{android.GenPathWithExt(ctx, "", in, properties.Output_extension)}, | 
| Dan Willemsen | 34cc69e | 2015-09-23 15:26:20 -0700 | [diff] [blame] | 324 | }) | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 325 | } | 
|  | 326 | return tasks | 
|  | 327 | } | 
|  | 328 |  | 
|  | 329 | return generatorFactory(tasks, properties) | 
|  | 330 | } | 
|  | 331 |  | 
|  | 332 | type genSrcsProperties struct { | 
| Colin Cross | 7d5136f | 2015-05-11 13:39:40 -0700 | [diff] [blame] | 333 | // extension that will be substituted for each output file | 
| Colin Cross | 5049f02 | 2015-03-18 13:28:46 -0700 | [diff] [blame] | 334 | Output_extension string | 
|  | 335 | } | 
|  | 336 |  | 
| Colin Cross | 3624285 | 2017-06-23 15:06:31 -0700 | [diff] [blame] | 337 | func GenRuleFactory() android.Module { | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 338 | properties := &genRuleProperties{} | 
| Colin Cross | 5049f02 | 2015-03-18 13:28:46 -0700 | [diff] [blame] | 339 |  | 
| Colin Cross | 708c424 | 2017-01-13 18:05:49 -0800 | [diff] [blame] | 340 | tasks := func(ctx android.ModuleContext, srcFiles android.Paths) []generateTask { | 
| Dan Willemsen | 9c8681f | 2016-09-28 16:21:00 -0700 | [diff] [blame] | 341 | outs := make(android.WritablePaths, len(properties.Out)) | 
|  | 342 | for i, out := range properties.Out { | 
|  | 343 | outs[i] = android.PathForModuleGen(ctx, out) | 
|  | 344 | } | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 345 | return []generateTask{ | 
|  | 346 | { | 
| Colin Cross | 708c424 | 2017-01-13 18:05:49 -0800 | [diff] [blame] | 347 | in:  srcFiles, | 
| Dan Willemsen | 9c8681f | 2016-09-28 16:21:00 -0700 | [diff] [blame] | 348 | out: outs, | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 349 | }, | 
|  | 350 | } | 
| Colin Cross | 5049f02 | 2015-03-18 13:28:46 -0700 | [diff] [blame] | 351 | } | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 352 |  | 
|  | 353 | return generatorFactory(tasks, properties) | 
| Colin Cross | 5049f02 | 2015-03-18 13:28:46 -0700 | [diff] [blame] | 354 | } | 
|  | 355 |  | 
| Colin Cross | d350ecd | 2015-04-28 13:25:36 -0700 | [diff] [blame] | 356 | type genRuleProperties struct { | 
| Dan Willemsen | 9c8681f | 2016-09-28 16:21:00 -0700 | [diff] [blame] | 357 | // names of the output files that will be generated | 
|  | 358 | Out []string | 
| Colin Cross | 5049f02 | 2015-03-18 13:28:46 -0700 | [diff] [blame] | 359 | } |