blob: 83dbcb61a3b66c92858c67b373effb297bb4e3b8 [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 (
Dan Willemsendb8457c2017-05-12 16:38:17 -070018 "io/ioutil"
Dan Willemsen1e704462016-08-21 15:17:17 -070019 "os"
Dan Willemsen1e704462016-08-21 15:17:17 -070020 "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
Dan Willemsendb8457c2017-05-12 16:38:17 -070063func checkCaseSensitivity(ctx Context, config Config) {
64 outDir := config.OutDir()
65 lowerCase := filepath.Join(outDir, "casecheck.txt")
66 upperCase := filepath.Join(outDir, "CaseCheck.txt")
67 lowerData := "a"
68 upperData := "B"
69
70 err := ioutil.WriteFile(lowerCase, []byte(lowerData), 0777)
71 if err != nil {
72 ctx.Fatalln("Failed to check case sensitivity:", err)
73 }
74
75 err = ioutil.WriteFile(upperCase, []byte(upperData), 0777)
76 if err != nil {
77 ctx.Fatalln("Failed to check case sensitivity:", err)
78 }
79
80 res, err := ioutil.ReadFile(lowerCase)
81 if err != nil {
82 ctx.Fatalln("Failed to check case sensitivity:", err)
83 }
84
85 if string(res) != lowerData {
86 ctx.Println("************************************************************")
87 ctx.Println("You are building on a case-insensitive filesystem.")
88 ctx.Println("Please move your source tree to a case-sensitive filesystem.")
89 ctx.Println("************************************************************")
90 ctx.Fatalln("Case-insensitive filesystems not supported")
91 }
92}
93
Dan Willemsenf052f782017-05-18 15:29:04 -070094func help(ctx Context, config Config, what int) {
95 cmd := Command(ctx, config, "make",
96 "make", "-f", "build/core/help.mk")
97 cmd.Sandbox = makeSandbox
98 cmd.Stdout = ctx.Stdout()
99 cmd.Stderr = ctx.Stderr()
100 cmd.RunOrFatal()
Dan Willemsen02781d52017-05-12 19:28:13 -0700101}
102
Dan Willemsen1e704462016-08-21 15:17:17 -0700103// Build the tree. The 'what' argument can be used to chose which components of
104// the build to run.
105func Build(ctx Context, config Config, what int) {
106 ctx.Verboseln("Starting build with args:", config.Arguments())
107 ctx.Verboseln("Environment:", config.Environment().Environ())
108
109 if inList("help", config.Arguments()) {
Dan Willemsenf052f782017-05-18 15:29:04 -0700110 help(ctx, config, what)
Dan Willemsen1e704462016-08-21 15:17:17 -0700111 return
Dan Willemsen0b73b4b2017-05-12 19:28:13 -0700112 } else if inList("clean", config.Arguments()) || inList("clobber", config.Arguments()) {
Dan Willemsenf052f782017-05-18 15:29:04 -0700113 clean(ctx, config, what)
Dan Willemsen0b73b4b2017-05-12 19:28:13 -0700114 return
Dan Willemsen1e704462016-08-21 15:17:17 -0700115 }
116
Dan Willemsendb8457c2017-05-12 16:38:17 -0700117 // Start getting java version as early as possible
118 getJavaVersions(ctx, config)
119
Jeff Gaston3615fe82017-05-24 13:14:34 -0700120 // Make sure that no other Soong process is running with the same output directory
121 buildLock := BecomeSingletonOrFail(ctx, config)
122 defer buildLock.Unlock()
123
Dan Willemsen1e704462016-08-21 15:17:17 -0700124 SetupOutDir(ctx, config)
125
Dan Willemsendb8457c2017-05-12 16:38:17 -0700126 checkCaseSensitivity(ctx, config)
127
Dan Willemsen1e704462016-08-21 15:17:17 -0700128 if what&BuildProductConfig != 0 {
129 // Run make for product config
130 runMakeProductConfig(ctx, config)
131 }
132
Dan Willemsenf052f782017-05-18 15:29:04 -0700133 if inList("installclean", config.Arguments()) {
134 installClean(ctx, config, what)
135 ctx.Println("Deleted images and staging directories.")
136 return
137 } else if inList("dataclean", config.Arguments()) {
138 dataClean(ctx, config, what)
139 ctx.Println("Deleted data files.")
140 return
141 }
142
Dan Willemsen1e704462016-08-21 15:17:17 -0700143 if what&BuildSoong != 0 {
144 // Run Soong
145 runSoongBootstrap(ctx, config)
146 runSoong(ctx, config)
147 }
148
Dan Willemsendb8457c2017-05-12 16:38:17 -0700149 // Check the java versions we read earlier
150 checkJavaVersion(ctx, config)
151
Dan Willemsen1e704462016-08-21 15:17:17 -0700152 if what&BuildKati != 0 {
153 // Run ckati
154 runKati(ctx, config)
155 }
156
157 if what&BuildNinja != 0 {
Dan Willemsenf052f782017-05-18 15:29:04 -0700158 installCleanIfNecessary(ctx, config)
Dan Willemsen02781d52017-05-12 19:28:13 -0700159
Dan Willemsen1e704462016-08-21 15:17:17 -0700160 // Write combined ninja file
161 createCombinedBuildNinjaFile(ctx, config)
162
163 // Run ninja
164 runNinja(ctx, config)
165 }
166}