package buildcfg
import (
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
)
var (
GOROOT = os .Getenv ("GOROOT" )
GOARCH = 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_LDSO
Version = version
)
var Error error
func Check () {
if Error != nil {
fmt .Fprintf (os .Stderr , "%s: %v\n" , filepath .Base (os .Args [0 ]), Error )
os .Exit (2 )
}
}
func envOr(key , value string ) string {
if x := os .Getenv (key ); x != "" {
return x
}
return value
}
func goamd64() int {
switch v := envOr ("GOAMD64" , defaultGOAMD64 ); v {
case "v1" :
return 1
case "v2" :
return 2
case "v3" :
return 3
case "v4" :
return 4
}
Error = fmt .Errorf ("invalid GOAMD64: must be v1, v2, v3, v4" )
return int (defaultGOAMD64 [len ("v" )] - '0' )
}
type goarmFeatures struct {
Version int
SoftFloat bool
}
func (g goarmFeatures ) String () string {
armStr := strconv .Itoa (g .Version )
if g .SoftFloat {
armStr += ",softfloat"
} else {
armStr += ",hardfloat"
}
return armStr
}
func goarm() (g goarmFeatures ) {
const (
softFloatOpt = ",softfloat"
hardFloatOpt = ",hardfloat"
)
def := defaultGOARM
if GOOS == "android" && GOARCH == "arm" {
def = "7"
}
v := envOr ("GOARM" , def )
floatSpecified := false
if strings .HasSuffix (v , softFloatOpt ) {
g .SoftFloat = true
floatSpecified = true
v = v [:len (v )-len (softFloatOpt )]
}
if strings .HasSuffix (v , hardFloatOpt ) {
floatSpecified = true
v = v [:len (v )-len (hardFloatOpt )]
}
switch v {
case "5" :
g .Version = 5
case "6" :
g .Version = 6
case "7" :
g .Version = 7
default :
Error = fmt .Errorf ("invalid GOARM: must start with 5, 6, or 7, and may optionally end in either %q or %q" , hardFloatOpt , softFloatOpt )
g .Version = int (def [0 ] - '0' )
}
if !floatSpecified && g .Version == 5 {
g .SoftFloat = true
}
return
}
type Goarm64Features struct {
Version string
LSE bool
Crypto bool
}
func (g Goarm64Features ) String () string {
arm64Str := g .Version
if g .LSE {
arm64Str += ",lse"
}
if g .Crypto {
arm64Str += ",crypto"
}
return arm64Str
}
func ParseGoarm64 (v string ) (g Goarm64Features , e error ) {
const (
lseOpt = ",lse"
cryptoOpt = ",crypto"
)
g .LSE = false
g .Crypto = false
for {
if strings .HasSuffix (v , lseOpt ) {
g .LSE = true
v = v [:len (v )-len (lseOpt )]
continue
}
if strings .HasSuffix (v , cryptoOpt ) {
g .Crypto = true
v = v [:len (v )-len (cryptoOpt )]
continue
}
break
}
switch v {
case "v8.0" :
g .Version = v
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" :
g .Version = v
g .LSE = true
default :
e = fmt .Errorf ("invalid GOARM64: must start with v8.{0-9} or v9.{0-5} and may optionally end in %q and/or %q" ,
lseOpt , cryptoOpt )
g .Version = defaultGOARM64
}
return
}
func goarm64() (g Goarm64Features ) {
g , Error = ParseGoarm64 (envOr ("GOARM64" , defaultGOARM64 ))
return
}
func (g Goarm64Features ) Supports (s string ) bool {
if len (s ) != 4 {
return false
}
major := s [1 ]
minor := s [3 ]
if major < '8' || major > '9' ||
minor < '0' || minor > '9' ||
s [0 ] != 'v' || s [2 ] != '.' {
return false
}
g_major := g .Version [1 ]
g_minor := g .Version [3 ]
if major == g_major {
return minor <= g_minor
} else if g_major == '9' {
return minor <= g_minor +5
} else {
return false
}
}
func gomips() string {
switch v := envOr ("GOMIPS" , defaultGOMIPS ); v {
case "hardfloat" , "softfloat" :
return v
}
Error = fmt .Errorf ("invalid GOMIPS: must be hardfloat, softfloat" )
return defaultGOMIPS
}
func gomips64() string {
switch v := envOr ("GOMIPS64" , defaultGOMIPS64 ); v {
case "hardfloat" , "softfloat" :
return v
}
Error = fmt .Errorf ("invalid GOMIPS64: must be hardfloat, softfloat" )
return defaultGOMIPS64
}
func goppc64() int {
switch v := envOr ("GOPPC64" , defaultGOPPC64 ); v {
case "power8" :
return 8
case "power9" :
return 9
case "power10" :
return 10
}
Error = fmt .Errorf ("invalid GOPPC64: must be power8, power9, power10" )
return int (defaultGOPPC64 [len ("power" )] - '0' )
}
func goriscv64() int {
switch v := envOr ("GORISCV64" , defaultGORISCV64 ); v {
case "rva20u64" :
return 20
case "rva22u64" :
return 22
}
Error = fmt .Errorf ("invalid GORISCV64: must be rva20u64, rva22u64" )
v := defaultGORISCV64 [len ("rva" ):]
i := strings .IndexFunc (v , func (r rune ) bool {
return r < '0' || r > '9'
})
year , _ := strconv .Atoi (v [:i ])
return year
}
type gowasmFeatures struct {
SatConv bool
SignExt bool
}
func (f gowasmFeatures ) String () string {
var flags []string
if f .SatConv {
flags = append (flags , "satconv" )
}
if f .SignExt {
flags = append (flags , "signext" )
}
return strings .Join (flags , "," )
}
func gowasm() (f gowasmFeatures ) {
for _ , opt := range strings .Split (envOr ("GOWASM" , "" ), "," ) {
switch opt {
case "satconv" :
f .SatConv = true
case "signext" :
f .SignExt = true
case "" :
default :
Error = fmt .Errorf ("invalid GOWASM: no such feature %q" , opt )
}
}
return
}
func Getgoextlinkenabled () string {
return envOr ("GO_EXTLINK_ENABLED" , defaultGO_EXTLINK_ENABLED )
}
func toolTags() []string {
tags := experimentTags ()
tags = append (tags , gogoarchTags ()...)
return tags
}
func experimentTags() []string {
var list []string
for _ , exp := range Experiment .Enabled () {
list = append (list , "goexperiment." +exp )
}
return list
}
func GOGOARCH () (name , value string ) {
switch GOARCH {
case "386" :
return "GO386" , GO386
case "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" , GOMIPS
case "mips64" , "mips64le" :
return "GOMIPS64" , GOMIPS64
case "ppc64" , "ppc64le" :
return "GOPPC64" , fmt .Sprintf ("power%d" , GOPPC64 )
case "wasm" :
return "GOWASM" , GOWASM .String ()
}
return "" , ""
}
func gogoarchTags() []string {
switch GOARCH {
case "386" :
return []string {GOARCH + "." + GO386 }
case "amd64" :
var list []string
for i := 1 ; i <= GOAMD64 ; i ++ {
list = append (list , fmt .Sprintf ("%s.v%d" , GOARCH , i ))
}
return list
case "arm" :
var list []string
for i := 5 ; i <= GOARM .Version ; i ++ {
list = append (list , fmt .Sprintf ("%s.%d" , GOARCH , i ))
}
return list
case "arm64" :
var list []string
major := int (GOARM64 .Version [1 ] - '0' )
minor := int (GOARM64 .Version [3 ] - '0' )
for i := 0 ; i <= minor ; i ++ {
list = append (list , fmt .Sprintf ("%s.v%d.%d" , GOARCH , major , i ))
}
if major == 9 {
for i := 0 ; i <= minor +5 && i <= 9 ; i ++ {
list = append (list , fmt .Sprintf ("%s.v%d.%d" , GOARCH , 8 , i ))
}
}
return list
case "mips" , "mipsle" :
return []string {GOARCH + "." + GOMIPS }
case "mips64" , "mips64le" :
return []string {GOARCH + "." + GOMIPS64 }
case "ppc64" , "ppc64le" :
var list []string
for i := 8 ; i <= GOPPC64 ; i ++ {
list = append (list , fmt .Sprintf ("%s.power%d" , GOARCH , i ))
}
return list
case "riscv64" :
list := []string {GOARCH + "." + "rva20u64" }
if GORISCV64 >= 22 {
list = append (list , GOARCH +"." +"rva22u64" )
}
return list
case "wasm" :
var list []string
if GOWASM .SatConv {
list = append (list , GOARCH +".satconv" )
}
if GOWASM .SignExt {
list = append (list , GOARCH +".signext" )
}
return list
}
return nil
}
The pages are generated with Golds v0.7.0-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 .