github.com/goproxy0/go@v0.0.0-20171111080102-49cc0c489d2c/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 = build.Default 24 BuildI bool // -i flag 25 BuildLinkshared bool // -linkshared flag 26 BuildMSan bool // -msan flag 27 BuildN bool // -n flag 28 BuildO string // -o flag 29 BuildP = runtime.NumCPU() // -p flag 30 BuildPkgdir string // -pkgdir flag 31 BuildRace bool // -race flag 32 BuildToolexec []string // -toolexec flag 33 BuildToolchainName string 34 BuildToolchainCompiler func() string 35 BuildToolchainLinker func() string 36 BuildV bool // -v flag 37 BuildWork bool // -work flag 38 BuildX bool // -x flag 39 40 CmdName string // "build", "install", "list", etc. 41 42 DebugActiongraph string // -debug-actiongraph flag (undocumented, unstable) 43 ) 44 45 func init() { 46 BuildToolchainCompiler = func() string { return "missing-compiler" } 47 BuildToolchainLinker = func() string { return "missing-linker" } 48 } 49 50 // An EnvVar is an environment variable Name=Value. 51 type EnvVar struct { 52 Name string 53 Value string 54 } 55 56 // OrigEnv is the original environment of the program at startup. 57 var OrigEnv []string 58 59 // CmdEnv is the new environment for running go tool commands. 60 // User binaries (during go test or go run) are run with OrigEnv, 61 // not CmdEnv. 62 var CmdEnv []EnvVar 63 64 // Global build parameters (used during package load) 65 var ( 66 Goarch = BuildContext.GOARCH 67 Goos = BuildContext.GOOS 68 ExeSuffix string 69 Gopath = filepath.SplitList(BuildContext.GOPATH) 70 ) 71 72 func init() { 73 if Goos == "windows" { 74 ExeSuffix = ".exe" 75 } 76 } 77 78 var ( 79 GOROOT = findGOROOT() 80 GOBIN = os.Getenv("GOBIN") 81 GOROOTbin = filepath.Join(GOROOT, "bin") 82 GOROOTpkg = filepath.Join(GOROOT, "pkg") 83 GOROOTsrc = filepath.Join(GOROOT, "src") 84 85 // Used in envcmd.MkEnv and build ID computations. 86 GOARM = fmt.Sprint(objabi.GOARM) 87 GO386 = objabi.GO386 88 ) 89 90 // Update build context to use our computed GOROOT. 91 func init() { 92 BuildContext.GOROOT = GOROOT 93 // Note that we must use runtime.GOOS and runtime.GOARCH here, 94 // as the tool directory does not move based on environment variables. 95 // This matches the initialization of ToolDir in go/build, 96 // except for using GOROOT rather than runtime.GOROOT(). 97 build.ToolDir = filepath.Join(GOROOT, "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH) 98 } 99 100 func findGOROOT() string { 101 if env := os.Getenv("GOROOT"); env != "" { 102 return filepath.Clean(env) 103 } 104 def := filepath.Clean(runtime.GOROOT()) 105 exe, err := os.Executable() 106 if err == nil { 107 exe, err = filepath.Abs(exe) 108 if err == nil { 109 if dir := filepath.Join(exe, "../.."); isGOROOT(dir) { 110 // If def (runtime.GOROOT()) and dir are the same 111 // directory, prefer the spelling used in def. 112 if isSameDir(def, dir) { 113 return def 114 } 115 return dir 116 } 117 exe, err = filepath.EvalSymlinks(exe) 118 if err == nil { 119 if dir := filepath.Join(exe, "../.."); isGOROOT(dir) { 120 if isSameDir(def, dir) { 121 return def 122 } 123 return dir 124 } 125 } 126 } 127 } 128 return def 129 } 130 131 // isSameDir reports whether dir1 and dir2 are the same directory. 132 func isSameDir(dir1, dir2 string) bool { 133 if dir1 == dir2 { 134 return true 135 } 136 info1, err1 := os.Stat(dir1) 137 info2, err2 := os.Stat(dir2) 138 return err1 == nil && err2 == nil && os.SameFile(info1, info2) 139 } 140 141 // isGOROOT reports whether path looks like a GOROOT. 142 // 143 // It does this by looking for the path/pkg/tool directory, 144 // which is necessary for useful operation of the cmd/go tool, 145 // and is not typically present in a GOPATH. 146 func isGOROOT(path string) bool { 147 stat, err := os.Stat(filepath.Join(path, "pkg", "tool")) 148 if err != nil { 149 return false 150 } 151 return stat.IsDir() 152 }