1// 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 "path/filepath" 20 "strconv" 21 "strings" 22 23 "github.com/google/blueprint/microfactory" 24 25 "android/soong/ui/metrics" 26 "android/soong/ui/status" 27) 28 29func runSoong(ctx Context, config Config) { 30 ctx.BeginTrace(metrics.RunSoong, "soong") 31 defer ctx.EndTrace() 32 33 func() { 34 ctx.BeginTrace(metrics.RunSoong, "blueprint bootstrap") 35 defer ctx.EndTrace() 36 37 cmd := Command(ctx, config, "blueprint bootstrap", "build/blueprint/bootstrap.bash", "-t") 38 cmd.Environment.Set("BLUEPRINTDIR", "./build/blueprint") 39 cmd.Environment.Set("BOOTSTRAP", "./build/blueprint/bootstrap.bash") 40 cmd.Environment.Set("BUILDDIR", config.SoongOutDir()) 41 cmd.Environment.Set("GOROOT", "./"+filepath.Join("prebuilts/go", config.HostPrebuiltTag())) 42 cmd.Environment.Set("BLUEPRINT_LIST_FILE", filepath.Join(config.FileListDir(), "Android.bp.list")) 43 cmd.Environment.Set("NINJA_BUILDDIR", config.OutDir()) 44 cmd.Environment.Set("SRCDIR", ".") 45 cmd.Environment.Set("TOPNAME", "Android.bp") 46 cmd.Sandbox = soongSandbox 47 48 cmd.RunAndPrintOrFatal() 49 }() 50 51 func() { 52 ctx.BeginTrace(metrics.RunSoong, "environment check") 53 defer ctx.EndTrace() 54 55 envFile := filepath.Join(config.SoongOutDir(), ".soong.environment") 56 envTool := filepath.Join(config.SoongOutDir(), ".bootstrap/bin/soong_env") 57 if _, err := os.Stat(envFile); err == nil { 58 if _, err := os.Stat(envTool); err == nil { 59 cmd := Command(ctx, config, "soong_env", envTool, envFile) 60 cmd.Sandbox = soongSandbox 61 62 var buf strings.Builder 63 cmd.Stdout = &buf 64 cmd.Stderr = &buf 65 if err := cmd.Run(); err != nil { 66 ctx.Verboseln("soong_env failed, forcing manifest regeneration") 67 os.Remove(envFile) 68 } 69 70 if buf.Len() > 0 { 71 ctx.Verboseln(buf.String()) 72 } 73 } else { 74 ctx.Verboseln("Missing soong_env tool, forcing manifest regeneration") 75 os.Remove(envFile) 76 } 77 } else if !os.IsNotExist(err) { 78 ctx.Fatalf("Failed to stat %f: %v", envFile, err) 79 } 80 }() 81 82 var cfg microfactory.Config 83 cfg.Map("github.com/google/blueprint", "build/blueprint") 84 85 cfg.TrimPath = absPath(ctx, ".") 86 87 func() { 88 ctx.BeginTrace(metrics.RunSoong, "minibp") 89 defer ctx.EndTrace() 90 91 minibp := filepath.Join(config.SoongOutDir(), ".minibootstrap/minibp") 92 if _, err := microfactory.Build(&cfg, minibp, "github.com/google/blueprint/bootstrap/minibp"); err != nil { 93 ctx.Fatalln("Failed to build minibp:", err) 94 } 95 }() 96 97 func() { 98 ctx.BeginTrace(metrics.RunSoong, "bpglob") 99 defer ctx.EndTrace() 100 101 bpglob := filepath.Join(config.SoongOutDir(), ".minibootstrap/bpglob") 102 if _, err := microfactory.Build(&cfg, bpglob, "github.com/google/blueprint/bootstrap/bpglob"); err != nil { 103 ctx.Fatalln("Failed to build bpglob:", err) 104 } 105 }() 106 107 ninja := func(name, file string) { 108 ctx.BeginTrace(metrics.RunSoong, name) 109 defer ctx.EndTrace() 110 111 fifo := filepath.Join(config.OutDir(), ".ninja_fifo") 112 nr := status.NewNinjaReader(ctx, ctx.Status.StartTool(), fifo) 113 defer nr.Close() 114 115 cmd := Command(ctx, config, "soong "+name, 116 config.PrebuiltBuildTool("ninja"), 117 "-d", "keepdepfile", 118 "-w", "dupbuild=err", 119 "-j", strconv.Itoa(config.Parallel()), 120 "--frontend_file", fifo, 121 "-f", filepath.Join(config.SoongOutDir(), file)) 122 cmd.Sandbox = soongSandbox 123 cmd.RunAndPrintOrFatal() 124 } 125 126 ninja("minibootstrap", ".minibootstrap/build.ninja") 127 ninja("bootstrap", ".bootstrap/build.ninja") 128} 129