/
cfg.go
155 lines (139 loc) · 4.53 KB
/
cfg.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package cfg holds configuration shared by multiple parts
// of the go command.
package cfg
import (
"fmt"
"go/build"
"os"
"path/filepath"
"runtime"
"cmd/internal/objabi"
)
// These are general "build flags" used by build and other commands.
var (
BuildA bool // -a flag
BuildBuildmode string // -buildmode flag
BuildContext = build.Default
BuildI bool // -i flag
BuildLdflags []string // -ldflags flag
BuildLinkshared bool // -linkshared flag
BuildMSan bool // -msan flag
BuildN bool // -n flag
BuildO string // -o flag
BuildP = runtime.NumCPU() // -p flag
BuildPkgdir string // -pkgdir flag
BuildRace bool // -race flag
BuildToolexec []string // -toolexec flag
BuildToolchainName string
BuildToolchainCompiler func() string
BuildToolchainLinker func() string
BuildV bool // -v flag
BuildWork bool // -work flag
BuildX bool // -x flag
)
func init() {
BuildToolchainCompiler = func() string { return "missing-compiler" }
BuildToolchainLinker = func() string { return "missing-linker" }
}
// An EnvVar is an environment variable Name=Value.
type EnvVar struct {
Name string
Value string
}
// OrigEnv is the original environment of the program at startup.
var OrigEnv []string
// CmdEnv is the new environment for running go tool commands.
// User binaries (during go test or go run) are run with OrigEnv,
// not CmdEnv.
var CmdEnv []EnvVar
// Global build parameters (used during package load)
var (
Goarch = BuildContext.GOARCH
Goos = BuildContext.GOOS
ExeSuffix string
Gopath = filepath.SplitList(BuildContext.GOPATH)
)
func init() {
if Goos == "windows" {
ExeSuffix = ".exe"
}
}
var (
GOROOT = findGOROOT()
GOBIN = os.Getenv("GOBIN")
GOROOTbin = filepath.Join(GOROOT, "bin")
GOROOTpkg = filepath.Join(GOROOT, "pkg")
GOROOTsrc = filepath.Join(GOROOT, "src")
// Used in envcmd.MkEnv and build ID computations.
GOARM = fmt.Sprint(objabi.GOARM)
GO386 = objabi.GO386
)
// Update build context to use our computed GOROOT.
func init() {
BuildContext.GOROOT = GOROOT
// Note that we must use runtime.GOOS and runtime.GOARCH here,
// as the tool directory does not move based on environment variables.
// This matches the initialization of ToolDir in go/build,
// except for using GOROOT rather than runtime.GOROOT().
build.ToolDir = filepath.Join(GOROOT, "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH)
}
func findGOROOT() string {
if env := os.Getenv("GOROOT"); env != "" {
return filepath.Clean(env)
}
exe, err := os.Executable()
if err == nil {
exe, err = filepath.Abs(exe)
if err == nil {
if dir := filepath.Join(exe, "../.."); isGOROOT(dir) {
return dir
}
exe, err = filepath.EvalSymlinks(exe)
if err == nil {
if dir := filepath.Join(exe, "../.."); isGOROOT(dir) {
return dir
}
}
}
}
return filepath.Clean(runtime.GOROOT())
}
// isGOROOT reports whether path looks like a GOROOT.
//
// It does this by looking for the path/pkg/tool directory,
// which is necessary for useful operation of the cmd/go tool,
// and is not typically present in a GOPATH.
func isGOROOT(path string) bool {
stat, err := os.Stat(filepath.Join(path, "pkg", "tool"))
if err != nil {
return false
}
return stat.IsDir()
}
// ExternalLinkingForced reports whether external linking is being
// forced even for programs that do not use cgo.
func ExternalLinkingForced() bool {
if !BuildContext.CgoEnabled {
return false
}
// Currently build modes c-shared, pie (on systems that do not
// support PIE with internal linking mode (currently all
// systems: issue #18968)), plugin, and -linkshared force
// external linking mode, as of course does
// -ldflags=-linkmode=external. External linking mode forces
// an import of runtime/cgo.
pieCgo := BuildBuildmode == "pie"
linkmodeExternal := false
for i, a := range BuildLdflags {
if a == "-linkmode=external" {
linkmodeExternal = true
}
if a == "-linkmode" && i+1 < len(BuildLdflags) && BuildLdflags[i+1] == "external" {
linkmodeExternal = true
}
}
return BuildBuildmode == "c-shared" || BuildBuildmode == "plugin" || pieCgo || BuildLinkshared || linkmodeExternal
}