github.com/MangoDowner/go-gm@v0.0.0-20180818020936-8baa2bd4408c/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 BuildLdflags []string // -ldflags 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 42 func init() { 43 BuildToolchainCompiler = func() string { return "missing-compiler" } 44 BuildToolchainLinker = func() string { return "missing-linker" } 45 } 46 47 // An EnvVar is an environment variable Name=Value. 48 type EnvVar struct { 49 Name string 50 Value string 51 } 52 53 // OrigEnv is the original environment of the program at startup. 54 var OrigEnv []string 55 56 // CmdEnv is the new environment for running go tool commands. 57 // User binaries (during go test or go run) are run with OrigEnv, 58 // not CmdEnv. 59 var CmdEnv []EnvVar 60 61 // Global build parameters (used during package load) 62 var ( 63 Goarch = BuildContext.GOARCH 64 Goos = BuildContext.GOOS 65 ExeSuffix string 66 Gopath = filepath.SplitList(BuildContext.GOPATH) 67 ) 68 69 func init() { 70 if Goos == "windows" { 71 ExeSuffix = ".exe" 72 } 73 } 74 75 var ( 76 GOROOT = findGOROOT() 77 GOBIN = os.Getenv("GOBIN") 78 GOROOTbin = filepath.Join(GOROOT, "bin") 79 GOROOTpkg = filepath.Join(GOROOT, "pkg") 80 GOROOTsrc = filepath.Join(GOROOT, "src") 81 82 // Used in envcmd.MkEnv and build ID computations. 83 GOARM = fmt.Sprint(objabi.GOARM) 84 GO386 = objabi.GO386 85 ) 86 87 // Update build context to use our computed GOROOT. 88 func init() { 89 BuildContext.GOROOT = GOROOT 90 // Note that we must use runtime.GOOS and runtime.GOARCH here, 91 // as the tool directory does not move based on environment variables. 92 // This matches the initialization of ToolDir in go/build, 93 // except for using GOROOT rather than runtime.GOROOT(). 94 build.ToolDir = filepath.Join(GOROOT, "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH) 95 } 96 97 func findGOROOT() string { 98 if env := os.Getenv("GOROOT"); env != "" { 99 return filepath.Clean(env) 100 } 101 exe, err := os.Executable() 102 if err == nil { 103 exe, err = filepath.Abs(exe) 104 if err == nil { 105 if dir := filepath.Join(exe, "../.."); isGOROOT(dir) { 106 return dir 107 } 108 exe, err = filepath.EvalSymlinks(exe) 109 if err == nil { 110 if dir := filepath.Join(exe, "../.."); isGOROOT(dir) { 111 return dir 112 } 113 } 114 } 115 } 116 return filepath.Clean(runtime.GOROOT()) 117 } 118 119 // isGOROOT reports whether path looks like a GOROOT. 120 // 121 // It does this by looking for the path/pkg/tool directory, 122 // which is necessary for useful operation of the cmd/go tool, 123 // and is not typically present in a GOPATH. 124 func isGOROOT(path string) bool { 125 stat, err := os.Stat(filepath.Join(path, "pkg", "tool")) 126 if err != nil { 127 return false 128 } 129 return stat.IsDir() 130 }