// Copyright 2021 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 buildcfg provides access to the build configuration// described by the current environment. It is for use by build tools// such as cmd/go or cmd/compile and for setting up go/build's Default context.//// Note that it does NOT provide access to the build configuration used to// build the currently-running binary. For that, use runtime.GOOS etc// as well as internal/goexperiment.
package buildcfgimport ()var (GOROOT = os.Getenv("GOROOT") // cached for efficiencyGOARCH = envOr("GOARCH", defaultGOARCH)GOOS = envOr("GOOS", defaultGOOS)GO386 = envOr("GO386", DefaultGO386)GOAMD64 = goamd64()GOARM = goarm()GOARM64 = goarm64()GOMIPS = gomips()GOMIPS64 = gomips64()GOPPC64 = goppc64()GORISCV64 = goriscv64()GOWASM = gowasm()ToolTags = toolTags()GO_LDSO = defaultGO_LDSOGOFIPS140 = gofips140()Version = version)// Error is one of the errors found (if any) in the build configuration.varErrorerror// Check exits the program with a fatal error if Error is non-nil.func () {ifError != nil {fmt.Fprintf(os.Stderr, "%s: %v\n", filepath.Base(os.Args[0]), Error)os.Exit(2) }}func envOr(, string) string {if := os.Getenv(); != "" {return }return}func goamd64() int {switch := envOr("GOAMD64", DefaultGOAMD64); {case"v1":return1case"v2":return2case"v3":return3case"v4":return4 }Error = fmt.Errorf("invalid GOAMD64: must be v1, v2, v3, v4")returnint(DefaultGOAMD64[len("v")] - '0')}func gofips140() string { := envOr("GOFIPS140", DefaultGOFIPS140)switch {case"off", "latest", "inprocess", "certified":return }ifisFIPSVersion() {return }Error = fmt.Errorf("invalid GOFIPS140: must be off, latest, inprocess, certified, or v1.Y.Z")returnDefaultGOFIPS140}// isFIPSVersion reports whether v is a valid FIPS version,// of the form v1.Y.Z or v1.Y.Z-hhhhhhhh or v1.Y.Z-rcN.func isFIPSVersion( string) bool { , := strings.CutPrefix(, "v1.")if ! {returnfalse }if , = cutNum(); ! {returnfalse }if , = strings.CutPrefix(, "."); ! {returnfalse }if , = cutNum(); ! {returnfalse }if == "" {returntrue }if , = strings.CutPrefix(, "-rc"); { , = cutNum()return && == "" }if , = strings.CutPrefix(, "-"); {returnlen() == 8 }returnfalse}// cutNum skips the leading text matching [0-9]+// in s, returning the rest and whether such text was found.func cutNum( string) ( string, bool) { := 0for < len() && '0' <= [] && [] <= '9' { ++ }return [:], > 0}typeGoarmFeaturesstruct { Version int SoftFloat bool}func ( GoarmFeatures) () string { := strconv.Itoa(.Version)if .SoftFloat { += ",softfloat" } else { += ",hardfloat" }return}func goarm() ( GoarmFeatures) {const ( = ",softfloat" = ",hardfloat" ) := DefaultGOARMifGOOS == "android" && GOARCH == "arm" {// Android arm devices always support GOARM=7. = "7" } := envOr("GOARM", ) := falseifstrings.HasSuffix(, ) { .SoftFloat = true = true = [:len()-len()] }ifstrings.HasSuffix(, ) { = true = [:len()-len()] }switch {case"5": .Version = 5case"6": .Version = 6case"7": .Version = 7default:Error = fmt.Errorf("invalid GOARM: must start with 5, 6, or 7, and may optionally end in either %q or %q", , ) .Version = int([0] - '0') }// 5 defaults to softfloat. 6 and 7 default to hardfloat.if ! && .Version == 5 { .SoftFloat = true }return}typeGoarm64Featuresstruct { Version string// Large Systems Extension LSE bool// ARM v8.0 Cryptographic Extension. It includes the following features: // * FEAT_AES, which includes the AESD and AESE instructions. // * FEAT_PMULL, which includes the PMULL, PMULL2 instructions. // * FEAT_SHA1, which includes the SHA1* instructions. // * FEAT_SHA256, which includes the SHA256* instructions. Crypto bool}func ( Goarm64Features) () string { := .Versionif .LSE { += ",lse" }if .Crypto { += ",crypto" }return}func ( string) ( Goarm64Features, error) {const ( = ",lse" = ",crypto" ) .LSE = false .Crypto = false// We allow any combination of suffixes, in any orderfor {ifstrings.HasSuffix(, ) { .LSE = true = [:len()-len()]continue }ifstrings.HasSuffix(, ) { .Crypto = true = [:len()-len()]continue }break }switch {case"v8.0": .Version = case"v8.1", "v8.2", "v8.3", "v8.4", "v8.5", "v8.6", "v8.7", "v8.8", "v8.9","v9.0", "v9.1", "v9.2", "v9.3", "v9.4", "v9.5": .Version = // LSE extension is mandatory starting from 8.1 .LSE = truedefault: = fmt.Errorf("invalid GOARM64: must start with v8.{0-9} or v9.{0-5} and may optionally end in %q and/or %q", , ) .Version = DefaultGOARM64 }return}func goarm64() ( Goarm64Features) { , Error = ParseGoarm64(envOr("GOARM64", DefaultGOARM64))return}// Returns true if g supports giving ARM64 ISA// Note that this function doesn't accept / test suffixes (like ",lse" or ",crypto")func ( Goarm64Features) ( string) bool {// We only accept "v{8-9}.{0-9}. Everything else is malformed.iflen() != 4 {returnfalse } := [1] := [3]// We only accept "v{8-9}.{0-9}. Everything else is malformed.if < '8' || > '9' || < '0' || > '9' || [0] != 'v' || [2] != '.' {returnfalse } := .Version[1] := .Version[3]if == {return <= } elseif == '9' {// v9.0 diverged from v8.5. This means we should compare with g_minor increased by five.return <= +5 } else {returnfalse }}func gomips() string {switch := envOr("GOMIPS", DefaultGOMIPS); {case"hardfloat", "softfloat":return }Error = fmt.Errorf("invalid GOMIPS: must be hardfloat, softfloat")returnDefaultGOMIPS}func gomips64() string {switch := envOr("GOMIPS64", DefaultGOMIPS64); {case"hardfloat", "softfloat":return }Error = fmt.Errorf("invalid GOMIPS64: must be hardfloat, softfloat")returnDefaultGOMIPS64}func goppc64() int {switch := envOr("GOPPC64", DefaultGOPPC64); {case"power8":return8case"power9":return9case"power10":return10 }Error = fmt.Errorf("invalid GOPPC64: must be power8, power9, power10")returnint(DefaultGOPPC64[len("power")] - '0')}func goriscv64() int {switch := envOr("GORISCV64", DefaultGORISCV64); {case"rva20u64":return20case"rva22u64":return22case"rva23u64":return23 }Error = fmt.Errorf("invalid GORISCV64: must be rva20u64, rva22u64, rva23u64") := DefaultGORISCV64[len("rva"):] := strings.IndexFunc(, func( rune) bool {return < '0' || > '9' }) , := strconv.Atoi([:])return}type gowasmFeatures struct {// Legacy features, now always enabled //SatConv bool //SignExt bool}func ( gowasmFeatures) () string {var []stringreturnstrings.Join(, ",")}func gowasm() ( gowasmFeatures) {for := rangestrings.SplitSeq(envOr("GOWASM", ""), ",") {switch {case"satconv":// ignore, always enabledcase"signext":// ignore, always enabledcase"":// ignoredefault:Error = fmt.Errorf("invalid GOWASM: no such feature %q", ) } }return}func () string {returnenvOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED)}func toolTags() []string { := experimentTags() = append(, gogoarchTags()...)return}func experimentTags() []string {var []string// For each experiment that has been enabled in the toolchain, define a // build tag with the same name but prefixed by "goexperiment." which can be // used for compiling alternative files for the experiment. This allows // changes for the experiment, like extra struct fields in the runtime, // without affecting the base non-experiment code at all.for , := rangeExperiment.Enabled() { = append(, "goexperiment."+) }return}// GOGOARCH returns the name and value of the GO$GOARCH setting.// For example, if GOARCH is "amd64" it might return "GOAMD64", "v2".func () (, string) {switchGOARCH {case"386":return"GO386", GO386case"amd64":return"GOAMD64", fmt.Sprintf("v%d", GOAMD64)case"arm":return"GOARM", GOARM.String()case"arm64":return"GOARM64", GOARM64.String()case"mips", "mipsle":return"GOMIPS", GOMIPScase"mips64", "mips64le":return"GOMIPS64", GOMIPS64case"ppc64", "ppc64le":return"GOPPC64", fmt.Sprintf("power%d", GOPPC64)case"riscv64":return"GORISCV64", fmt.Sprintf("rva%du64", GORISCV64)case"wasm":return"GOWASM", GOWASM.String() }return"", ""}func gogoarchTags() []string {switchGOARCH {case"386":return []string{GOARCH + "." + GO386}case"amd64":var []stringfor := 1; <= GOAMD64; ++ { = append(, fmt.Sprintf("%s.v%d", GOARCH, )) }returncase"arm":var []stringfor := 5; <= GOARM.Version; ++ { = append(, fmt.Sprintf("%s.%d", GOARCH, )) }returncase"arm64":var []string := int(GOARM64.Version[1] - '0') := int(GOARM64.Version[3] - '0')for := 0; <= ; ++ { = append(, fmt.Sprintf("%s.v%d.%d", GOARCH, , )) }// ARM64 v9.x also includes support of v8.x+5 (i.e. v9.1 includes v8.(1+5) = v8.6).if == 9 {for := 0; <= +5 && <= 9; ++ { = append(, fmt.Sprintf("%s.v%d.%d", GOARCH, 8, )) } }returncase"mips", "mipsle":return []string{GOARCH + "." + GOMIPS}case"mips64", "mips64le":return []string{GOARCH + "." + GOMIPS64}case"ppc64", "ppc64le":var []stringfor := 8; <= GOPPC64; ++ { = append(, fmt.Sprintf("%s.power%d", GOARCH, )) }returncase"riscv64": := []string{GOARCH + "." + "rva20u64"}ifGORISCV64 >= 22 { = append(, GOARCH+"."+"rva22u64") }ifGORISCV64 >= 23 { = append(, GOARCH+"."+"rva23u64") }returncase"wasm":var []string// SatConv is always enabled = append(, GOARCH+".satconv")// SignExt is always enabled = append(, GOARCH+".signext")return }returnnil}
The pages are generated with Goldsv0.8.3-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.