blob: 30381e088b6f8ed1b85c1e129bb50f2909b15a62 [file] [log] [blame]
Colin Cross3f40fa42015-01-30 17:27:36 -08001// 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
15package main
16
17import (
18 "flag"
19 "fmt"
20 "os"
Colin Crossaa812d12019-06-19 13:33:24 -070021 "os/exec"
Colin Cross3f40fa42015-01-30 17:27:36 -080022 "path/filepath"
Colin Crossaa812d12019-06-19 13:33:24 -070023 "strconv"
24 "strings"
25 "syscall"
26 "time"
Colin Cross3f40fa42015-01-30 17:27:36 -080027
Colin Cross70b40592015-03-23 12:57:34 -070028 "github.com/google/blueprint/bootstrap"
Colin Cross3f40fa42015-01-30 17:27:36 -080029
Colin Cross635c3b02016-05-18 15:37:25 -070030 "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -080031)
32
Colin Crosse87040b2017-12-11 15:52:26 -080033var (
34 docFile string
35)
36
37func init() {
38 flag.StringVar(&docFile, "soong_docs", "", "build documentation file to output")
39}
40
Jeff Gaston088e29e2017-11-29 16:47:17 -080041func newNameResolver(config android.Config) *android.NameResolver {
42 namespacePathsToExport := make(map[string]bool)
43
Dan Willemsen3fb1fae2018-03-12 15:30:26 -070044 for _, namespaceName := range config.ExportedNamespaces() {
Jeff Gaston088e29e2017-11-29 16:47:17 -080045 namespacePathsToExport[namespaceName] = true
46 }
47
48 namespacePathsToExport["."] = true // always export the root namespace
49
50 exportFilter := func(namespace *android.Namespace) bool {
51 return namespacePathsToExport[namespace.Path]
52 }
53
54 return android.NewNameResolver(exportFilter)
55}
56
Colin Cross3f40fa42015-01-30 17:27:36 -080057func main() {
Colin Crossaa812d12019-06-19 13:33:24 -070058 if android.SoongDelveListen != "" {
59 if android.SoongDelvePath == "" {
60 fmt.Fprintln(os.Stderr, "SOONG_DELVE is set but failed to find dlv")
61 os.Exit(1)
62 }
63 pid := strconv.Itoa(os.Getpid())
64 cmd := []string{android.SoongDelvePath,
65 "attach", pid,
66 "--headless",
67 "-l", android.SoongDelveListen,
68 "--api-version=2",
69 "--accept-multiclient",
70 "--log",
71 }
72
73 fmt.Println("Starting", strings.Join(cmd, " "))
74 dlv := exec.Command(cmd[0], cmd[1:]...)
75 dlv.Stdout = os.Stdout
76 dlv.Stderr = os.Stderr
77 dlv.Stdin = nil
78
79 // Put dlv into its own process group so we can kill it and the child process it starts.
80 dlv.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
81
82 err := dlv.Start()
83 if err != nil {
84 // Print the error starting dlv and continue.
85 fmt.Println(err)
86 } else {
87 // Kill the process group for dlv when soong_build exits.
88 defer syscall.Kill(-dlv.Process.Pid, syscall.SIGKILL)
89 // Wait to give dlv a chance to connect and pause the process.
90 time.Sleep(time.Second)
91 }
92 }
93
Colin Cross3f40fa42015-01-30 17:27:36 -080094 flag.Parse()
95
96 // The top-level Blueprints file is passed as the first argument.
97 srcDir := filepath.Dir(flag.Arg(0))
98
Colin Cross798bfce2016-10-12 14:28:16 -070099 ctx := android.NewContext()
Colin Crosscec81712017-07-13 14:43:27 -0700100 ctx.Register()
Colin Cross3f40fa42015-01-30 17:27:36 -0800101
Colin Cross635c3b02016-05-18 15:37:25 -0700102 configuration, err := android.NewConfig(srcDir, bootstrap.BuildDir)
Colin Cross3f40fa42015-01-30 17:27:36 -0800103 if err != nil {
104 fmt.Fprintf(os.Stderr, "%s", err)
105 os.Exit(1)
106 }
107
Colin Crosse87040b2017-12-11 15:52:26 -0800108 if docFile != "" {
109 configuration.SetStopBefore(bootstrap.StopBeforePrepareBuildActions)
110 }
111
Jeff Gaston088e29e2017-11-29 16:47:17 -0800112 ctx.SetNameInterface(newNameResolver(configuration))
Colin Cross3f40fa42015-01-30 17:27:36 -0800113
Colin Cross6ff51382015-12-17 16:39:19 -0800114 ctx.SetAllowMissingDependencies(configuration.AllowMissingDependencies())
115
Colin Crossaa812d12019-06-19 13:33:24 -0700116 extraNinjaDeps := []string{configuration.ConfigFileName, configuration.ProductVariablesFileName}
117
118 // Read the SOONG_DELVE again through configuration so that there is a dependency on the environment variable
119 // and soong_build will rerun when it is set for the first time.
120 if listen := configuration.Getenv("SOONG_DELVE"); listen != "" {
121 // Add a non-existent file to the dependencies so that soong_build will rerun when the debugger is
122 // enabled even if it completed successfully.
123 extraNinjaDeps = append(extraNinjaDeps, filepath.Join(configuration.BuildDir(), "always_rerun_for_delve"))
124 }
125
126 bootstrap.Main(ctx.Context, configuration, extraNinjaDeps...)
Colin Crosse87040b2017-12-11 15:52:26 -0800127
128 if docFile != "" {
Sasha Smundakff483392019-02-07 12:10:56 -0800129 if err := writeDocs(ctx, docFile); err != nil {
Colin Cross7089c272019-01-25 22:43:35 -0800130 fmt.Fprintf(os.Stderr, "%s", err)
131 os.Exit(1)
132 }
Colin Crosse87040b2017-12-11 15:52:26 -0800133 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800134}