github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/cmd/go/internal/cfg/cfg.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package cfg holds configuration shared by multiple parts 6 // of the go command. 7 package cfg 8 9 import ( 10 "fmt" 11 "go/build" 12 "os" 13 "path/filepath" 14 "runtime" 15 16 "cmd/internal/objabi" 17 ) 18 19 // These are general "build flags" used by build and other commands. 20 var ( 21 BuildA bool // -a flag 22 BuildBuildmode string // -buildmode flag 23 BuildContext = defaultContext() 24 BuildMod string // -mod flag 25 BuildI bool // -i flag 26 BuildLinkshared bool // -linkshared flag 27 BuildMSan bool // -msan flag 28 BuildN bool // -n flag 29 BuildO string // -o flag 30 BuildP = runtime.NumCPU() // -p flag 31 BuildPkgdir string // -pkgdir flag 32 BuildRace bool // -race flag 33 BuildToolexec []string // -toolexec flag 34 BuildToolchainName string 35 BuildToolchainCompiler func() string 36 BuildToolchainLinker func() string 37 BuildV bool // -v flag 38 BuildWork bool // -work flag 39 BuildX bool // -x flag 40 41 CmdName string // "build", "install", "list", etc. 42 43 DebugActiongraph string // -debug-actiongraph flag (undocumented, unstable) 44 ) 45 46 func defaultContext() build.Context { 47 ctxt := build.Default 48 ctxt.JoinPath = filepath.Join // back door to say "do not use go command" 49 return ctxt 50 } 51 52 func init() { 53 BuildToolchainCompiler = func() string { return "missing-compiler" } 54 BuildToolchainLinker = func() string { return "missing-linker" } 55 } 56 57 // An EnvVar is an environment variable Name=Value. 58 type EnvVar struct { 59 Name string 60 Value string 61 } 62 63 // OrigEnv is the original environment of the program at startup. 64 var OrigEnv []string 65 66 // CmdEnv is the new environment for running go tool commands. 67 // User binaries (during go test or go run) are run with OrigEnv, 68 // not CmdEnv. 69 var CmdEnv []EnvVar 70 71 // Global build parameters (used during package load) 72 var ( 73 Goarch = BuildContext.GOARCH 74 Goos = BuildContext.GOOS 75 ExeSuffix string 76 Gopath = filepath.SplitList(BuildContext.GOPATH) 77 78 // ModulesEnabled specifies whether the go command is running 79 // in module-aware mode (as opposed to GOPATH mode). 80 // It is equal to modload.Enabled, but not all packages can import modload. 81 ModulesEnabled bool 82 83 // GoModInGOPATH records whether we've found a go.mod in GOPATH/src 84 // in GO111MODULE=auto mode. In that case, we don't use modules 85 // but people might expect us to, so 'go get' warns. 86 GoModInGOPATH string 87 ) 88 89 func init() { 90 if Goos == "windows" { 91 ExeSuffix = ".exe" 92 } 93 } 94 95 var ( 96 GOROOT = findGOROOT() 97 GOBIN = os.Getenv("GOBIN") 98 GOROOTbin = filepath.Join(GOROOT, "bin") 99 GOROOTpkg = filepath.Join(GOROOT, "pkg") 100 GOROOTsrc = filepath.Join(GOROOT, "src") 101 GOROOT_FINAL = findGOROOT_FINAL() 102 103 // Used in envcmd.MkEnv and build ID computations. 104 GOARM = fmt.Sprint(objabi.GOARM) 105 GO386 = objabi.GO386 106 GOMIPS = objabi.GOMIPS 107 GOMIPS64 = objabi.GOMIPS64 108 ) 109 110 // Update build context to use our computed GOROOT. 111 func init() { 112 BuildContext.GOROOT = GOROOT 113 if runtime.Compiler != "gccgo" { 114 // Note that we must use runtime.GOOS and runtime.GOARCH here, 115 // as the tool directory does not move based on environment 116 // variables. This matches the initialization of ToolDir in 117 // go/build, except for using GOROOT rather than 118 // runtime.GOROOT. 119 build.ToolDir = filepath.Join(GOROOT, "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH) 120 } 121 } 122 123 // There is a copy of findGOROOT, isSameDir, and isGOROOT in 124 // x/tools/cmd/godoc/goroot.go. 125 // Try to keep them in sync for now. 126 127 // findGOROOT returns the GOROOT value, using either an explicitly 128 // provided environment variable, a GOROOT that contains the current 129 // os.Executable value, or else the GOROOT that the binary was built 130 // with from runtime.GOROOT(). 131 // 132 // There is a copy of this code in x/tools/cmd/godoc/goroot.go. 133 func findGOROOT() string { 134 if env := os.Getenv("GOROOT"); env != "" { 135 return filepath.Clean(env) 136 } 137 def := filepath.Clean(runtime.GOROOT()) 138 if runtime.Compiler == "gccgo" { 139 // gccgo has no real GOROOT, and it certainly doesn't 140 // depend on the executable's location. 141 return def 142 } 143 exe, err := os.Executable() 144 if err == nil { 145 exe, err = filepath.Abs(exe) 146 if err == nil { 147 if dir := filepath.Join(exe, "../.."); isGOROOT(dir) { 148 // If def (runtime.GOROOT()) and dir are the same 149 // directory, prefer the spelling used in def. 150 if isSameDir(def, dir) { 151 return def 152 } 153 return dir 154 } 155 exe, err = filepath.EvalSymlinks(exe) 156 if err == nil { 157 if dir := filepath.Join(exe, "../.."); isGOROOT(dir) { 158 if isSameDir(def, dir) { 159 return def 160 } 161 return dir 162 } 163 } 164 } 165 } 166 return def 167 } 168 169 func findGOROOT_FINAL() string { 170 def := GOROOT 171 if env := os.Getenv("GOROOT_FINAL"); env != "" { 172 def = filepath.Clean(env) 173 } 174 return def 175 } 176 177 // isSameDir reports whether dir1 and dir2 are the same directory. 178 func isSameDir(dir1, dir2 string) bool { 179 if dir1 == dir2 { 180 return true 181 } 182 info1, err1 := os.Stat(dir1) 183 info2, err2 := os.Stat(dir2) 184 return err1 == nil && err2 == nil && os.SameFile(info1, info2) 185 } 186 187 // isGOROOT reports whether path looks like a GOROOT. 188 // 189 // It does this by looking for the path/pkg/tool directory, 190 // which is necessary for useful operation of the cmd/go tool, 191 // and is not typically present in a GOPATH. 192 // 193 // There is a copy of this code in x/tools/cmd/godoc/goroot.go. 194 func isGOROOT(path string) bool { 195 stat, err := os.Stat(filepath.Join(path, "pkg", "tool")) 196 if err != nil { 197 return false 198 } 199 return stat.IsDir() 200 }