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