github.com/JimmyHuang454/JLS-go@v0.0.0-20230831150107-90d536585ba0/internal/buildcfg/cfg.go (about) 1 // Copyright 2021 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 buildcfg provides access to the build configuration 6 // described by the current environment. It is for use by build tools 7 // such as cmd/go or cmd/compile and for setting up go/build's Default context. 8 // 9 // Note that it does NOT provide access to the build configuration used to 10 // build the currently-running binary. For that, use runtime.GOOS etc 11 // as well as internal/goexperiment. 12 package buildcfg 13 14 import ( 15 "fmt" 16 "os" 17 "path/filepath" 18 "runtime" 19 "strings" 20 ) 21 22 var ( 23 GOROOT = runtime.GOROOT() // cached for efficiency 24 GOARCH = envOr("GOARCH", defaultGOARCH) 25 GOOS = envOr("GOOS", defaultGOOS) 26 GO386 = envOr("GO386", defaultGO386) 27 GOAMD64 = goamd64() 28 GOARM = goarm() 29 GOMIPS = gomips() 30 GOMIPS64 = gomips64() 31 GOPPC64 = goppc64() 32 GOWASM = gowasm() 33 ToolTags = toolTags() 34 GO_LDSO = defaultGO_LDSO 35 Version = version 36 ) 37 38 // Error is one of the errors found (if any) in the build configuration. 39 var Error error 40 41 // Check exits the program with a fatal error if Error is non-nil. 42 func Check() { 43 if Error != nil { 44 fmt.Fprintf(os.Stderr, "%s: %v\n", filepath.Base(os.Args[0]), Error) 45 os.Exit(2) 46 } 47 } 48 49 func envOr(key, value string) string { 50 if x := os.Getenv(key); x != "" { 51 return x 52 } 53 return value 54 } 55 56 func goamd64() int { 57 switch v := envOr("GOAMD64", defaultGOAMD64); v { 58 case "v1": 59 return 1 60 case "v2": 61 return 2 62 case "v3": 63 return 3 64 case "v4": 65 return 4 66 } 67 Error = fmt.Errorf("invalid GOAMD64: must be v1, v2, v3, v4") 68 return int(defaultGOAMD64[len("v")] - '0') 69 } 70 71 func goarm() int { 72 def := defaultGOARM 73 if GOOS == "android" && GOARCH == "arm" { 74 // Android arm devices always support GOARM=7. 75 def = "7" 76 } 77 switch v := envOr("GOARM", def); v { 78 case "5": 79 return 5 80 case "6": 81 return 6 82 case "7": 83 return 7 84 } 85 Error = fmt.Errorf("invalid GOARM: must be 5, 6, 7") 86 return int(def[0] - '0') 87 } 88 89 func gomips() string { 90 switch v := envOr("GOMIPS", defaultGOMIPS); v { 91 case "hardfloat", "softfloat": 92 return v 93 } 94 Error = fmt.Errorf("invalid GOMIPS: must be hardfloat, softfloat") 95 return defaultGOMIPS 96 } 97 98 func gomips64() string { 99 switch v := envOr("GOMIPS64", defaultGOMIPS64); v { 100 case "hardfloat", "softfloat": 101 return v 102 } 103 Error = fmt.Errorf("invalid GOMIPS64: must be hardfloat, softfloat") 104 return defaultGOMIPS64 105 } 106 107 func goppc64() int { 108 switch v := envOr("GOPPC64", defaultGOPPC64); v { 109 case "power8": 110 return 8 111 case "power9": 112 return 9 113 case "power10": 114 return 10 115 } 116 Error = fmt.Errorf("invalid GOPPC64: must be power8, power9, power10") 117 return int(defaultGOPPC64[len("power")] - '0') 118 } 119 120 type gowasmFeatures struct { 121 SatConv bool 122 SignExt bool 123 } 124 125 func (f gowasmFeatures) String() string { 126 var flags []string 127 if f.SatConv { 128 flags = append(flags, "satconv") 129 } 130 if f.SignExt { 131 flags = append(flags, "signext") 132 } 133 return strings.Join(flags, ",") 134 } 135 136 func gowasm() (f gowasmFeatures) { 137 for _, opt := range strings.Split(envOr("GOWASM", ""), ",") { 138 switch opt { 139 case "satconv": 140 f.SatConv = true 141 case "signext": 142 f.SignExt = true 143 case "": 144 // ignore 145 default: 146 Error = fmt.Errorf("invalid GOWASM: no such feature %q", opt) 147 } 148 } 149 return 150 } 151 152 func Getgoextlinkenabled() string { 153 return envOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED) 154 } 155 156 func toolTags() []string { 157 tags := experimentTags() 158 tags = append(tags, gogoarchTags()...) 159 return tags 160 } 161 162 func experimentTags() []string { 163 var list []string 164 // For each experiment that has been enabled in the toolchain, define a 165 // build tag with the same name but prefixed by "goexperiment." which can be 166 // used for compiling alternative files for the experiment. This allows 167 // changes for the experiment, like extra struct fields in the runtime, 168 // without affecting the base non-experiment code at all. 169 for _, exp := range Experiment.Enabled() { 170 list = append(list, "goexperiment."+exp) 171 } 172 return list 173 } 174 175 // GOGOARCH returns the name and value of the GO$GOARCH setting. 176 // For example, if GOARCH is "amd64" it might return "GOAMD64", "v2". 177 func GOGOARCH() (name, value string) { 178 switch GOARCH { 179 case "386": 180 return "GO386", GO386 181 case "amd64": 182 return "GOAMD64", fmt.Sprintf("v%d", GOAMD64) 183 case "arm": 184 return "GOARM", fmt.Sprintf("%d", GOARM) 185 case "mips", "mipsle": 186 return "GOMIPS", GOMIPS 187 case "mips64", "mips64le": 188 return "GOMIPS64", GOMIPS64 189 case "ppc64", "ppc64le": 190 return "GOPPC64", fmt.Sprintf("power%d", GOPPC64) 191 case "wasm": 192 return "GOWASM", GOWASM.String() 193 } 194 return "", "" 195 } 196 197 func gogoarchTags() []string { 198 switch GOARCH { 199 case "386": 200 return []string{GOARCH + "." + GO386} 201 case "amd64": 202 var list []string 203 for i := 1; i <= GOAMD64; i++ { 204 list = append(list, fmt.Sprintf("%s.v%d", GOARCH, i)) 205 } 206 return list 207 case "arm": 208 var list []string 209 for i := 5; i <= GOARM; i++ { 210 list = append(list, fmt.Sprintf("%s.%d", GOARCH, i)) 211 } 212 return list 213 case "mips", "mipsle": 214 return []string{GOARCH + "." + GOMIPS} 215 case "mips64", "mips64le": 216 return []string{GOARCH + "." + GOMIPS64} 217 case "ppc64", "ppc64le": 218 var list []string 219 for i := 8; i <= GOPPC64; i++ { 220 list = append(list, fmt.Sprintf("%s.power%d", GOARCH, i)) 221 } 222 return list 223 case "wasm": 224 var list []string 225 if GOWASM.SatConv { 226 list = append(list, GOARCH+".satconv") 227 } 228 if GOWASM.SignExt { 229 list = append(list, GOARCH+".signext") 230 } 231 return list 232 } 233 return nil 234 }