Colin Cross | 8e0c511 | 2015-01-23 14:15:10 -0800 | [diff] [blame] | 1 | // Copyright 2014 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 | |
Jamie Gennis | 1bc967e | 2014-05-27 16:34:41 -0700 | [diff] [blame] | 15 | package bootstrap |
| 16 | |
| 17 | import ( |
Colin Cross | de7afaa | 2019-01-23 13:23:00 -0800 | [diff] [blame] | 18 | "bufio" |
Jamie Gennis | 1bc967e | 2014-05-27 16:34:41 -0700 | [diff] [blame] | 19 | "flag" |
| 20 | "fmt" |
Colin Cross | de7afaa | 2019-01-23 13:23:00 -0800 | [diff] [blame] | 21 | "io" |
Jamie Gennis | 1bc967e | 2014-05-27 16:34:41 -0700 | [diff] [blame] | 22 | "io/ioutil" |
| 23 | "os" |
Jamie Gennis | c4ed709 | 2014-11-09 11:58:40 -0800 | [diff] [blame] | 24 | "path/filepath" |
Colin Cross | 5bdb4ca | 2015-04-14 17:22:19 -0700 | [diff] [blame] | 25 | "runtime" |
Colin Cross | 2ecec57 | 2016-05-17 13:56:21 -0700 | [diff] [blame] | 26 | "runtime/debug" |
Colin Cross | 63d5d4d | 2015-04-20 16:41:55 -0700 | [diff] [blame] | 27 | "runtime/pprof" |
Colin Cross | aec881d | 2016-08-05 13:59:43 -0700 | [diff] [blame] | 28 | "runtime/trace" |
Colin Cross | 5bdb4ca | 2015-04-14 17:22:19 -0700 | [diff] [blame] | 29 | |
| 30 | "github.com/google/blueprint" |
| 31 | "github.com/google/blueprint/deptools" |
Jamie Gennis | 1bc967e | 2014-05-27 16:34:41 -0700 | [diff] [blame] | 32 | ) |
| 33 | |
Lukacs T. Berki | 7ea1c16 | 2021-03-16 08:54:33 +0100 | [diff] [blame] | 34 | type Args struct { |
Lukacs T. Berki | b3b9cb6 | 2021-03-16 09:11:10 +0100 | [diff] [blame] | 35 | OutFile string |
| 36 | GlobFile string |
| 37 | DepFile string |
| 38 | DocFile string |
| 39 | Cpuprofile string |
| 40 | Memprofile string |
Lukacs T. Berki | 77ef79b | 2021-04-12 12:07:02 +0200 | [diff] [blame] | 41 | DelveListen string |
| 42 | DelvePath string |
Lukacs T. Berki | b3b9cb6 | 2021-03-16 09:11:10 +0100 | [diff] [blame] | 43 | TraceFile string |
| 44 | RunGoTests bool |
| 45 | UseValidations bool |
| 46 | NoGC bool |
| 47 | EmptyNinjaFile bool |
| 48 | BuildDir string |
| 49 | ModuleListFile string |
| 50 | NinjaBuildDir string |
| 51 | TopFile string |
| 52 | GeneratingPrimaryBuilder bool |
Lukacs T. Berki | 78df853 | 2021-04-14 10:28:54 +0200 | [diff] [blame] | 53 | |
| 54 | PrimaryBuilderInvocations []PrimaryBuilderInvocation |
Lukacs T. Berki | 7ea1c16 | 2021-03-16 08:54:33 +0100 | [diff] [blame] | 55 | } |
| 56 | |
| 57 | var ( |
Lukacs T. Berki | 98e0efb | 2021-04-14 13:47:52 +0200 | [diff] [blame] | 58 | CmdlineArgs Args |
| 59 | absSrcDir string |
Jamie Gennis | 7d5b2f8 | 2014-09-24 17:51:52 -0700 | [diff] [blame] | 60 | ) |
Jamie Gennis | 1bc967e | 2014-05-27 16:34:41 -0700 | [diff] [blame] | 61 | |
Jamie Gennis | 1bc967e | 2014-05-27 16:34:41 -0700 | [diff] [blame] | 62 | func init() { |
Lukacs T. Berki | 98e0efb | 2021-04-14 13:47:52 +0200 | [diff] [blame] | 63 | flag.StringVar(&CmdlineArgs.OutFile, "o", "build.ninja", "the Ninja file to output") |
| 64 | flag.StringVar(&CmdlineArgs.GlobFile, "globFile", "build-globs.ninja", "the Ninja file of globs to output") |
| 65 | flag.StringVar(&CmdlineArgs.BuildDir, "b", ".", "the build output directory") |
| 66 | flag.StringVar(&CmdlineArgs.NinjaBuildDir, "n", "", "the ninja builddir directory") |
| 67 | flag.StringVar(&CmdlineArgs.DepFile, "d", "", "the dependency file to output") |
| 68 | flag.StringVar(&CmdlineArgs.DocFile, "docs", "", "build documentation file to output") |
| 69 | flag.StringVar(&CmdlineArgs.Cpuprofile, "cpuprofile", "", "write cpu profile to file") |
| 70 | flag.StringVar(&CmdlineArgs.TraceFile, "trace", "", "write trace to file") |
| 71 | flag.StringVar(&CmdlineArgs.Memprofile, "memprofile", "", "write memory profile to file") |
| 72 | flag.BoolVar(&CmdlineArgs.NoGC, "nogc", false, "turn off GC for debugging") |
| 73 | flag.BoolVar(&CmdlineArgs.RunGoTests, "t", false, "build and run go tests during bootstrap") |
| 74 | flag.BoolVar(&CmdlineArgs.UseValidations, "use-validations", false, "use validations to depend on go tests") |
| 75 | flag.StringVar(&CmdlineArgs.ModuleListFile, "l", "", "file that lists filepaths to parse") |
| 76 | flag.BoolVar(&CmdlineArgs.EmptyNinjaFile, "empty-ninja-file", false, "write out a 0-byte ninja file") |
Jamie Gennis | 1bc967e | 2014-05-27 16:34:41 -0700 | [diff] [blame] | 77 | } |
| 78 | |
Lukacs T. Berki | f4d43ac | 2021-04-15 15:05:26 +0200 | [diff] [blame] | 79 | func Main(ctx *blueprint.Context, config interface{}, generatingPrimaryBuilder bool) { |
Jamie Gennis | 1bc967e | 2014-05-27 16:34:41 -0700 | [diff] [blame] | 80 | if !flag.Parsed() { |
| 81 | flag.Parse() |
| 82 | } |
| 83 | |
Lukacs T. Berki | 7ea1c16 | 2021-03-16 08:54:33 +0100 | [diff] [blame] | 84 | if flag.NArg() != 1 { |
| 85 | fatalf("no Blueprints file specified") |
| 86 | } |
| 87 | |
Lukacs T. Berki | 98e0efb | 2021-04-14 13:47:52 +0200 | [diff] [blame] | 88 | CmdlineArgs.TopFile = flag.Arg(0) |
| 89 | CmdlineArgs.GeneratingPrimaryBuilder = generatingPrimaryBuilder |
Lukacs T. Berki | f4d43ac | 2021-04-15 15:05:26 +0200 | [diff] [blame] | 90 | ninjaDeps := RunBlueprint(CmdlineArgs, ctx, config) |
| 91 | err := deptools.WriteDepFile(CmdlineArgs.DepFile, CmdlineArgs.OutFile, ninjaDeps) |
Lukacs T. Berki | 98e0efb | 2021-04-14 13:47:52 +0200 | [diff] [blame] | 92 | if err != nil { |
| 93 | fatalf("Cannot write depfile '%s': %s", CmdlineArgs.DepFile, err) |
| 94 | } |
Lukacs T. Berki | 7ea1c16 | 2021-03-16 08:54:33 +0100 | [diff] [blame] | 95 | } |
| 96 | |
Lukacs T. Berki | 78df853 | 2021-04-14 10:28:54 +0200 | [diff] [blame] | 97 | func PrimaryBuilderExtraFlags(args Args, globFile, mainNinjaFile string) []string { |
Lukacs T. Berki | 77ef79b | 2021-04-12 12:07:02 +0200 | [diff] [blame] | 98 | result := make([]string, 0) |
| 99 | |
| 100 | if args.RunGoTests { |
| 101 | result = append(result, "-t") |
| 102 | } |
| 103 | |
| 104 | result = append(result, "-l", args.ModuleListFile) |
| 105 | result = append(result, "-globFile", globFile) |
| 106 | result = append(result, "-o", mainNinjaFile) |
| 107 | |
| 108 | if args.EmptyNinjaFile { |
| 109 | result = append(result, "--empty-ninja-file") |
| 110 | } |
| 111 | |
| 112 | if args.DelveListen != "" { |
| 113 | result = append(result, "--delve_listen", args.DelveListen) |
| 114 | } |
| 115 | |
| 116 | if args.DelvePath != "" { |
| 117 | result = append(result, "--delve_path", args.DelvePath) |
| 118 | } |
| 119 | |
Lukacs T. Berki | 77ef79b | 2021-04-12 12:07:02 +0200 | [diff] [blame] | 120 | return result |
| 121 | } |
| 122 | |
| 123 | func writeEmptyGlobFile(path string) { |
| 124 | err := os.MkdirAll(filepath.Dir(path), 0777) |
| 125 | if err != nil { |
| 126 | fatalf("Failed to create parent directories of empty ninja glob file '%s': %s", path, err) |
| 127 | } |
| 128 | |
| 129 | if _, err := os.Stat(path); os.IsNotExist(err) { |
| 130 | err = ioutil.WriteFile(path, nil, 0666) |
| 131 | if err != nil { |
| 132 | fatalf("Failed to create empty ninja glob file '%s': %s", path, err) |
| 133 | } |
| 134 | } |
| 135 | } |
Lukacs T. Berki | f4d43ac | 2021-04-15 15:05:26 +0200 | [diff] [blame] | 136 | |
| 137 | // Returns the list of dependencies the emitted Ninja files has. These can be |
| 138 | // written to the .d file for the output so that it is correctly rebuilt when |
| 139 | // needed in case Blueprint is itself invoked from Ninja |
| 140 | func RunBlueprint(args Args, ctx *blueprint.Context, config interface{}) []string { |
Colin Cross | 5bdb4ca | 2015-04-14 17:22:19 -0700 | [diff] [blame] | 141 | runtime.GOMAXPROCS(runtime.NumCPU()) |
| 142 | |
Lukacs T. Berki | 7ea1c16 | 2021-03-16 08:54:33 +0100 | [diff] [blame] | 143 | if args.NoGC { |
Colin Cross | 2ecec57 | 2016-05-17 13:56:21 -0700 | [diff] [blame] | 144 | debug.SetGCPercent(-1) |
| 145 | } |
| 146 | |
Colin Cross | c5fa50e | 2019-12-17 13:12:35 -0800 | [diff] [blame] | 147 | absSrcDir = ctx.SrcDir() |
| 148 | |
Lukacs T. Berki | 7ea1c16 | 2021-03-16 08:54:33 +0100 | [diff] [blame] | 149 | if args.Cpuprofile != "" { |
| 150 | f, err := os.Create(absolutePath(args.Cpuprofile)) |
Jamie Gennis | 7d5b2f8 | 2014-09-24 17:51:52 -0700 | [diff] [blame] | 151 | if err != nil { |
| 152 | fatalf("error opening cpuprofile: %s", err) |
| 153 | } |
| 154 | pprof.StartCPUProfile(f) |
| 155 | defer f.Close() |
| 156 | defer pprof.StopCPUProfile() |
| 157 | } |
| 158 | |
Lukacs T. Berki | 7ea1c16 | 2021-03-16 08:54:33 +0100 | [diff] [blame] | 159 | if args.TraceFile != "" { |
| 160 | f, err := os.Create(absolutePath(args.TraceFile)) |
Colin Cross | aec881d | 2016-08-05 13:59:43 -0700 | [diff] [blame] | 161 | if err != nil { |
| 162 | fatalf("error opening trace: %s", err) |
| 163 | } |
| 164 | trace.Start(f) |
| 165 | defer f.Close() |
| 166 | defer trace.Stop() |
| 167 | } |
| 168 | |
Lukacs T. Berki | 7ea1c16 | 2021-03-16 08:54:33 +0100 | [diff] [blame] | 169 | srcDir := filepath.Dir(args.TopFile) |
Jamie Gennis | 1bc967e | 2014-05-27 16:34:41 -0700 | [diff] [blame] | 170 | |
Lukacs T. Berki | f4d43ac | 2021-04-15 15:05:26 +0200 | [diff] [blame] | 171 | ninjaDeps := make([]string, 0) |
| 172 | |
Lukacs T. Berki | 7ea1c16 | 2021-03-16 08:54:33 +0100 | [diff] [blame] | 173 | if args.ModuleListFile != "" { |
| 174 | ctx.SetModuleListFile(args.ModuleListFile) |
Lukacs T. Berki | f4d43ac | 2021-04-15 15:05:26 +0200 | [diff] [blame] | 175 | ninjaDeps = append(ninjaDeps, args.ModuleListFile) |
Jeff Gaston | c3e2844 | 2017-08-09 15:13:12 -0700 | [diff] [blame] | 176 | } else { |
| 177 | fatalf("-l <moduleListFile> is required and must be nonempty") |
| 178 | } |
Lukacs T. Berki | 7ea1c16 | 2021-03-16 08:54:33 +0100 | [diff] [blame] | 179 | filesToParse, err := ctx.ListModulePaths(srcDir) |
Jeff Gaston | c3e2844 | 2017-08-09 15:13:12 -0700 | [diff] [blame] | 180 | if err != nil { |
| 181 | fatalf("could not enumerate files: %v\n", err.Error()) |
| 182 | } |
| 183 | |
Lukacs T. Berki | f646afb | 2021-04-15 15:46:35 +0200 | [diff] [blame] | 184 | buildDir := config.(BootstrapConfig).BuildDir() |
Dan Willemsen | cd4e0ce | 2017-07-19 22:43:30 -0700 | [diff] [blame] | 185 | |
Dan Willemsen | 91a657e | 2015-07-22 17:05:59 -0700 | [diff] [blame] | 186 | stage := StageMain |
Lukacs T. Berki | b3b9cb6 | 2021-03-16 09:11:10 +0100 | [diff] [blame] | 187 | if args.GeneratingPrimaryBuilder { |
| 188 | stage = StagePrimary |
Dan Willemsen | 30a80c3 | 2015-06-24 19:21:21 -0700 | [diff] [blame] | 189 | } |
Jamie Gennis | 1bc967e | 2014-05-27 16:34:41 -0700 | [diff] [blame] | 190 | |
Lukacs T. Berki | 77ef79b | 2021-04-12 12:07:02 +0200 | [diff] [blame] | 191 | primaryBuilderNinjaGlobFile := absolutePath(filepath.Join(args.BuildDir, bootstrapSubDir, "build-globs.ninja")) |
| 192 | mainNinjaFile := filepath.Join("$buildDir", "build.ninja") |
| 193 | |
| 194 | writeEmptyGlobFile(primaryBuilderNinjaGlobFile) |
| 195 | |
Lukacs T. Berki | 78df853 | 2021-04-14 10:28:54 +0200 | [diff] [blame] | 196 | var invocations []PrimaryBuilderInvocation |
| 197 | |
| 198 | if args.PrimaryBuilderInvocations != nil { |
| 199 | invocations = args.PrimaryBuilderInvocations |
| 200 | } else { |
| 201 | primaryBuilderArgs := PrimaryBuilderExtraFlags(args, primaryBuilderNinjaGlobFile, mainNinjaFile) |
| 202 | primaryBuilderArgs = append(primaryBuilderArgs, args.TopFile) |
| 203 | |
| 204 | invocations = []PrimaryBuilderInvocation{{ |
| 205 | Inputs: []string{args.TopFile}, |
| 206 | Outputs: []string{mainNinjaFile}, |
| 207 | Args: primaryBuilderArgs, |
| 208 | }} |
| 209 | } |
| 210 | |
Dan Willemsen | 30a80c3 | 2015-06-24 19:21:21 -0700 | [diff] [blame] | 211 | bootstrapConfig := &Config{ |
Dan Willemsen | 91a657e | 2015-07-22 17:05:59 -0700 | [diff] [blame] | 212 | stage: stage, |
Dan Willemsen | dac90d3 | 2018-10-25 22:02:10 -0700 | [diff] [blame] | 213 | |
Lukacs T. Berki | 78df853 | 2021-04-14 10:28:54 +0200 | [diff] [blame] | 214 | topLevelBlueprintsFile: args.TopFile, |
| 215 | globFile: primaryBuilderNinjaGlobFile, |
| 216 | runGoTests: args.RunGoTests, |
| 217 | useValidations: args.UseValidations, |
| 218 | primaryBuilderInvocations: invocations, |
Dan Willemsen | 30a80c3 | 2015-06-24 19:21:21 -0700 | [diff] [blame] | 219 | } |
| 220 | |
Dan Willemsen | fdeb724 | 2015-07-24 16:53:27 -0700 | [diff] [blame] | 221 | ctx.RegisterBottomUpMutator("bootstrap_plugin_deps", pluginDeps) |
Dan Willemsen | 30a80c3 | 2015-06-24 19:21:21 -0700 | [diff] [blame] | 222 | ctx.RegisterModuleType("bootstrap_go_package", newGoPackageModuleFactory(bootstrapConfig)) |
Dan Willemsen | af456ea | 2017-07-19 19:22:34 -0700 | [diff] [blame] | 223 | ctx.RegisterModuleType("bootstrap_go_binary", newGoBinaryModuleFactory(bootstrapConfig, false)) |
| 224 | ctx.RegisterModuleType("blueprint_go_binary", newGoBinaryModuleFactory(bootstrapConfig, true)) |
Dan Willemsen | 30a80c3 | 2015-06-24 19:21:21 -0700 | [diff] [blame] | 225 | ctx.RegisterSingletonType("bootstrap", newSingletonFactory(bootstrapConfig)) |
| 226 | |
Colin Cross | 2523698 | 2021-04-05 17:20:34 -0700 | [diff] [blame] | 227 | ctx.RegisterSingletonType("glob", globSingletonFactory(bootstrapConfig, ctx)) |
Colin Cross | 127d2ea | 2016-11-01 11:10:51 -0700 | [diff] [blame] | 228 | |
Lukacs T. Berki | f4d43ac | 2021-04-15 15:05:26 +0200 | [diff] [blame] | 229 | blueprintFiles, errs := ctx.ParseFileList(filepath.Dir(args.TopFile), filesToParse, config) |
Jamie Gennis | 1bc967e | 2014-05-27 16:34:41 -0700 | [diff] [blame] | 230 | if len(errs) > 0 { |
| 231 | fatalErrors(errs) |
| 232 | } |
| 233 | |
Christopher Horvath | 3159cb7 | 2014-06-26 15:34:06 -0700 | [diff] [blame] | 234 | // Add extra ninja file dependencies |
Lukacs T. Berki | f4d43ac | 2021-04-15 15:05:26 +0200 | [diff] [blame] | 235 | ninjaDeps = append(ninjaDeps, blueprintFiles...) |
Christopher Horvath | 3159cb7 | 2014-06-26 15:34:06 -0700 | [diff] [blame] | 236 | |
Colin Cross | 874a346 | 2017-07-31 17:26:06 -0700 | [diff] [blame] | 237 | extraDeps, errs := ctx.ResolveDependencies(config) |
Colin Cross | 4572edd | 2015-05-13 14:36:24 -0700 | [diff] [blame] | 238 | if len(errs) > 0 { |
| 239 | fatalErrors(errs) |
| 240 | } |
Lukacs T. Berki | f4d43ac | 2021-04-15 15:05:26 +0200 | [diff] [blame] | 241 | ninjaDeps = append(ninjaDeps, extraDeps...) |
Colin Cross | 4572edd | 2015-05-13 14:36:24 -0700 | [diff] [blame] | 242 | |
Lukacs T. Berki | 7ea1c16 | 2021-03-16 08:54:33 +0100 | [diff] [blame] | 243 | if args.DocFile != "" { |
| 244 | err := writeDocs(ctx, config, absolutePath(args.DocFile)) |
Colin Cross | 4572edd | 2015-05-13 14:36:24 -0700 | [diff] [blame] | 245 | if err != nil { |
| 246 | fatalErrors([]error{err}) |
| 247 | } |
Lukacs T. Berki | 98e0efb | 2021-04-14 13:47:52 +0200 | [diff] [blame] | 248 | return nil |
Colin Cross | 4572edd | 2015-05-13 14:36:24 -0700 | [diff] [blame] | 249 | } |
| 250 | |
Colin Cross | 28b2843 | 2017-12-11 15:03:11 -0800 | [diff] [blame] | 251 | if c, ok := config.(ConfigStopBefore); ok { |
| 252 | if c.StopBefore() == StopBeforePrepareBuildActions { |
Lukacs T. Berki | f4d43ac | 2021-04-15 15:05:26 +0200 | [diff] [blame] | 253 | return ninjaDeps |
Colin Cross | 28b2843 | 2017-12-11 15:03:11 -0800 | [diff] [blame] | 254 | } |
| 255 | } |
| 256 | |
Colin Cross | 874a346 | 2017-07-31 17:26:06 -0700 | [diff] [blame] | 257 | extraDeps, errs = ctx.PrepareBuildActions(config) |
Jamie Gennis | 1bc967e | 2014-05-27 16:34:41 -0700 | [diff] [blame] | 258 | if len(errs) > 0 { |
| 259 | fatalErrors(errs) |
| 260 | } |
Lukacs T. Berki | f4d43ac | 2021-04-15 15:05:26 +0200 | [diff] [blame] | 261 | ninjaDeps = append(ninjaDeps, extraDeps...) |
Mathias Agopian | 5b8477d | 2014-06-25 17:21:54 -0700 | [diff] [blame] | 262 | |
Chris Parsons | 5e83426 | 2020-11-05 11:17:32 -0500 | [diff] [blame] | 263 | if c, ok := config.(ConfigStopBefore); ok { |
| 264 | if c.StopBefore() == StopBeforeWriteNinja { |
Lukacs T. Berki | f4d43ac | 2021-04-15 15:05:26 +0200 | [diff] [blame] | 265 | return ninjaDeps |
Chris Parsons | 5e83426 | 2020-11-05 11:17:32 -0500 | [diff] [blame] | 266 | } |
| 267 | } |
| 268 | |
Jamie Gennis | cbc6f86 | 2014-06-05 20:00:22 -0700 | [diff] [blame] | 269 | const outFilePermissions = 0666 |
Colin Cross | 0335e09 | 2021-01-21 15:26:21 -0800 | [diff] [blame] | 270 | var out io.StringWriter |
Colin Cross | de7afaa | 2019-01-23 13:23:00 -0800 | [diff] [blame] | 271 | var f *os.File |
| 272 | var buf *bufio.Writer |
| 273 | |
Lukacs T. Berki | 7ea1c16 | 2021-03-16 08:54:33 +0100 | [diff] [blame] | 274 | if args.EmptyNinjaFile { |
| 275 | if err := ioutil.WriteFile(absolutePath(args.OutFile), []byte(nil), outFilePermissions); err != nil { |
Dan Willemsen | 6c6c103 | 2020-04-19 12:50:48 -0700 | [diff] [blame] | 276 | fatalf("error writing empty Ninja file: %s", err) |
| 277 | } |
| 278 | } |
| 279 | |
Lukacs T. Berki | 7ea1c16 | 2021-03-16 08:54:33 +0100 | [diff] [blame] | 280 | if stage != StageMain || !args.EmptyNinjaFile { |
| 281 | f, err = os.OpenFile(absolutePath(args.OutFile), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, outFilePermissions) |
Colin Cross | de7afaa | 2019-01-23 13:23:00 -0800 | [diff] [blame] | 282 | if err != nil { |
| 283 | fatalf("error opening Ninja file: %s", err) |
| 284 | } |
Colin Cross | c8b9e55 | 2021-01-21 15:28:04 -0800 | [diff] [blame] | 285 | buf = bufio.NewWriterSize(f, 16*1024*1024) |
Colin Cross | de7afaa | 2019-01-23 13:23:00 -0800 | [diff] [blame] | 286 | out = buf |
| 287 | } else { |
Colin Cross | 0335e09 | 2021-01-21 15:26:21 -0800 | [diff] [blame] | 288 | out = ioutil.Discard.(io.StringWriter) |
Colin Cross | de7afaa | 2019-01-23 13:23:00 -0800 | [diff] [blame] | 289 | } |
| 290 | |
Lukacs T. Berki | 7ea1c16 | 2021-03-16 08:54:33 +0100 | [diff] [blame] | 291 | if args.GlobFile != "" { |
Colin Cross | 2523698 | 2021-04-05 17:20:34 -0700 | [diff] [blame] | 292 | buffer, errs := generateGlobNinjaFile(bootstrapConfig, config, ctx.Globs) |
Dan Willemsen | ab223a5 | 2018-07-05 21:56:59 -0700 | [diff] [blame] | 293 | if len(errs) > 0 { |
| 294 | fatalErrors(errs) |
| 295 | } |
| 296 | |
Lukacs T. Berki | 7ea1c16 | 2021-03-16 08:54:33 +0100 | [diff] [blame] | 297 | err = ioutil.WriteFile(absolutePath(args.GlobFile), buffer, outFilePermissions) |
Dan Willemsen | ab223a5 | 2018-07-05 21:56:59 -0700 | [diff] [blame] | 298 | if err != nil { |
Lukacs T. Berki | 7ea1c16 | 2021-03-16 08:54:33 +0100 | [diff] [blame] | 299 | fatalf("error writing %s: %s", args.GlobFile, err) |
Dan Willemsen | ab223a5 | 2018-07-05 21:56:59 -0700 | [diff] [blame] | 300 | } |
| 301 | } |
| 302 | |
Colin Cross | 1cda3fd | 2020-01-16 10:32:35 -0800 | [diff] [blame] | 303 | err = ctx.WriteBuildFile(out) |
| 304 | if err != nil { |
| 305 | fatalf("error writing Ninja file contents: %s", err) |
| 306 | } |
| 307 | |
| 308 | if buf != nil { |
| 309 | err = buf.Flush() |
| 310 | if err != nil { |
| 311 | fatalf("error flushing Ninja file contents: %s", err) |
| 312 | } |
| 313 | } |
| 314 | |
| 315 | if f != nil { |
| 316 | err = f.Close() |
| 317 | if err != nil { |
| 318 | fatalf("error closing Ninja file: %s", err) |
| 319 | } |
| 320 | } |
| 321 | |
Dan Willemsen | cd4e0ce | 2017-07-19 22:43:30 -0700 | [diff] [blame] | 322 | if c, ok := config.(ConfigRemoveAbandonedFilesUnder); ok { |
Lukacs T. Berki | 7ea1c16 | 2021-03-16 08:54:33 +0100 | [diff] [blame] | 323 | under, except := c.RemoveAbandonedFilesUnder(buildDir) |
| 324 | err := removeAbandonedFilesUnder(ctx, srcDir, buildDir, under, except) |
Colin Cross | 6d529f0 | 2015-11-17 16:16:58 -0800 | [diff] [blame] | 325 | if err != nil { |
| 326 | fatalf("error removing abandoned files: %s", err) |
| 327 | } |
Jamie Gennis | af43556 | 2014-10-27 22:34:56 -0700 | [diff] [blame] | 328 | } |
Colin Cross | 2ecec57 | 2016-05-17 13:56:21 -0700 | [diff] [blame] | 329 | |
Lukacs T. Berki | 7ea1c16 | 2021-03-16 08:54:33 +0100 | [diff] [blame] | 330 | if args.Memprofile != "" { |
| 331 | f, err := os.Create(absolutePath(args.Memprofile)) |
Colin Cross | 2ecec57 | 2016-05-17 13:56:21 -0700 | [diff] [blame] | 332 | if err != nil { |
| 333 | fatalf("error opening memprofile: %s", err) |
| 334 | } |
| 335 | defer f.Close() |
| 336 | pprof.WriteHeapProfile(f) |
| 337 | } |
Lukacs T. Berki | 98e0efb | 2021-04-14 13:47:52 +0200 | [diff] [blame] | 338 | |
Lukacs T. Berki | f4d43ac | 2021-04-15 15:05:26 +0200 | [diff] [blame] | 339 | return ninjaDeps |
Jamie Gennis | 1bc967e | 2014-05-27 16:34:41 -0700 | [diff] [blame] | 340 | } |
| 341 | |
| 342 | func fatalf(format string, args ...interface{}) { |
Jamie Gennis | cbc6f86 | 2014-06-05 20:00:22 -0700 | [diff] [blame] | 343 | fmt.Printf(format, args...) |
George Kulakowski | 4904c8a | 2015-08-21 14:47:06 -0700 | [diff] [blame] | 344 | fmt.Print("\n") |
Jamie Gennis | 1bc967e | 2014-05-27 16:34:41 -0700 | [diff] [blame] | 345 | os.Exit(1) |
| 346 | } |
| 347 | |
| 348 | func fatalErrors(errs []error) { |
Colin Cross | ea59954 | 2016-01-07 11:16:48 -0800 | [diff] [blame] | 349 | red := "\x1b[31m" |
| 350 | unred := "\x1b[0m" |
| 351 | |
Jamie Gennis | 1bc967e | 2014-05-27 16:34:41 -0700 | [diff] [blame] | 352 | for _, err := range errs { |
Colin Cross | ea59954 | 2016-01-07 11:16:48 -0800 | [diff] [blame] | 353 | switch err := err.(type) { |
Colin Cross | 2c62844 | 2016-10-07 17:13:10 -0700 | [diff] [blame] | 354 | case *blueprint.BlueprintError, |
| 355 | *blueprint.ModuleError, |
| 356 | *blueprint.PropertyError: |
Colin Cross | ea59954 | 2016-01-07 11:16:48 -0800 | [diff] [blame] | 357 | fmt.Printf("%serror:%s %s\n", red, unred, err.Error()) |
Jamie Gennis | 1bc967e | 2014-05-27 16:34:41 -0700 | [diff] [blame] | 358 | default: |
Colin Cross | ea59954 | 2016-01-07 11:16:48 -0800 | [diff] [blame] | 359 | fmt.Printf("%sinternal error:%s %s\n", red, unred, err) |
Jamie Gennis | 1bc967e | 2014-05-27 16:34:41 -0700 | [diff] [blame] | 360 | } |
| 361 | } |
| 362 | os.Exit(1) |
| 363 | } |
Colin Cross | c5fa50e | 2019-12-17 13:12:35 -0800 | [diff] [blame] | 364 | |
| 365 | func absolutePath(path string) string { |
| 366 | if filepath.IsAbs(path) { |
| 367 | return path |
| 368 | } |
| 369 | return filepath.Join(absSrcDir, path) |
| 370 | } |