github.com/corona10/go@v0.0.0-20180224231303-7a218942be57/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 GOROOT_FINAL = findGOROOT_FINAL() 85 86 // Used in envcmd.MkEnv and build ID computations. 87 GOARM = fmt.Sprint(objabi.GOARM) 88 GO386 = objabi.GO386 89 GOMIPS = objabi.GOMIPS 90 ) 91 92 // Update build context to use our computed GOROOT. 93 func init() { 94 BuildContext.GOROOT = GOROOT 95 // Note that we must use runtime.GOOS and runtime.GOARCH here, 96 // as the tool directory does not move based on environment variables. 97 // This matches the initialization of ToolDir in go/build, 98 // except for using GOROOT rather than runtime.GOROOT(). 99 build.ToolDir = filepath.Join(GOROOT, "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH) 100 } 101 102 func findGOROOT() string { 103 if env := os.Getenv("GOROOT"); env != "" { 104 return filepath.Clean(env) 105 } 106 def := filepath.Clean(runtime.GOROOT()) 107 exe, err := os.Executable() 108 if err == nil { 109 exe, err = filepath.Abs(exe) 110 if err == nil { 111 if dir := filepath.Join(exe, "../.."); isGOROOT(dir) { 112 // If def (runtime.GOROOT()) and dir are the same 113 // directory, prefer the spelling used in def. 114 if isSameDir(def, dir) { 115 return def 116 } 117 return dir 118 } 119 exe, err = filepath.EvalSymlinks(exe) 120 if err == nil { 121 if dir := filepath.Join(exe, "../.."); isGOROOT(dir) { 122 if isSameDir(def, dir) { 123 return def 124 } 125 return dir 126 } 127 } 128 } 129 } 130 return def 131 } 132 133 func findGOROOT_FINAL() string { 134 def := GOROOT 135 if env := os.Getenv("GOROOT_FINAL"); env != "" { 136 def = filepath.Clean(env) 137 } 138 return def 139 } 140 141 // isSameDir reports whether dir1 and dir2 are the same directory. 142 func isSameDir(dir1, dir2 string) bool { 143 if dir1 == dir2 { 144 return true 145 } 146 info1, err1 := os.Stat(dir1) 147 info2, err2 := os.Stat(dir2) 148 return err1 == nil && err2 == nil && os.SameFile(info1, info2) 149 } 150 151 // isGOROOT reports whether path looks like a GOROOT. 152 // 153 // It does this by looking for the path/pkg/tool directory, 154 // which is necessary for useful operation of the cmd/go tool, 155 // and is not typically present in a GOPATH. 156 func isGOROOT(path string) bool { 157 stat, err := os.Stat(filepath.Join(path, "pkg", "tool")) 158 if err != nil { 159 return false 160 } 161 return stat.IsDir() 162 }