blob: 506ff519167dc5ae022510ca7bcabe7d1c9ab71e [file] [log] [blame]
Dan Willemsen1e704462016-08-21 15:17:17 -07001// Copyright 2017 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 build
16
17import (
18 "os"
19 "os/exec"
20 "path/filepath"
21 "text/template"
22)
23
24// Ensures the out directory exists, and has the proper files to prevent kati
25// from recursing into it.
26func SetupOutDir(ctx Context, config Config) {
27 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "Android.mk"))
28 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "CleanSpec.mk"))
29 ensureEmptyFileExists(ctx, filepath.Join(config.SoongOutDir(), ".soong.in_make"))
30 // The ninja_build file is used by our buildbots to understand that the output
31 // can be parsed as ninja output.
32 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "ninja_build"))
33}
34
35var combinedBuildNinjaTemplate = template.Must(template.New("combined").Parse(`
36builddir = {{.OutDir}}
37include {{.KatiNinjaFile}}
38include {{.SoongNinjaFile}}
39build {{.CombinedNinjaFile}}: phony {{.SoongNinjaFile}}
40`))
41
42func createCombinedBuildNinjaFile(ctx Context, config Config) {
43 file, err := os.Create(config.CombinedNinjaFile())
44 if err != nil {
45 ctx.Fatalln("Failed to create combined ninja file:", err)
46 }
47 defer file.Close()
48
49 if err := combinedBuildNinjaTemplate.Execute(file, config); err != nil {
50 ctx.Fatalln("Failed to write combined ninja file:", err)
51 }
52}
53
54const (
55 BuildNone = iota
56 BuildProductConfig = 1 << iota
57 BuildSoong = 1 << iota
58 BuildKati = 1 << iota
59 BuildNinja = 1 << iota
60 BuildAll = BuildProductConfig | BuildSoong | BuildKati | BuildNinja
61)
62
63// Build the tree. The 'what' argument can be used to chose which components of
64// the build to run.
65func Build(ctx Context, config Config, what int) {
66 ctx.Verboseln("Starting build with args:", config.Arguments())
67 ctx.Verboseln("Environment:", config.Environment().Environ())
68
69 if inList("help", config.Arguments()) {
70 cmd := exec.CommandContext(ctx.Context, "make", "-f", "build/core/help.mk")
71 cmd.Env = config.Environment().Environ()
72 cmd.Stdout = ctx.Stdout()
73 cmd.Stderr = ctx.Stderr()
74 if err := cmd.Run(); err != nil {
75 ctx.Fatalln("Failed to run make:", err)
76 }
77 return
78 }
79
80 SetupOutDir(ctx, config)
81
82 if what&BuildProductConfig != 0 {
83 // Run make for product config
84 runMakeProductConfig(ctx, config)
85 }
86
87 if what&BuildSoong != 0 {
88 // Run Soong
89 runSoongBootstrap(ctx, config)
90 runSoong(ctx, config)
91 }
92
93 if what&BuildKati != 0 {
94 // Run ckati
95 runKati(ctx, config)
96 }
97
98 if what&BuildNinja != 0 {
99 // Write combined ninja file
100 createCombinedBuildNinjaFile(ctx, config)
101
102 // Run ninja
103 runNinja(ctx, config)
104 }
105}