github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/dist/main.go (about) 1 // Copyright 2012 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 dist 6 7 import ( 8 "flag" 9 "fmt" 10 "os" 11 "runtime" 12 "strings" 13 ) 14 15 func usage() { 16 xprintf(`usage: go tool dist [command] 17 Commands are: 18 19 banner print installation banner 20 bootstrap rebuild everything 21 clean deletes all built files 22 env [-p] print environment (-p: include $PATH) 23 install [dir] install individual directory 24 list [-json] [-broken] list all supported platforms 25 test [-h] run Go test(s) 26 version print Go version 27 28 All commands take -v flags to emit extra information. 29 `) 30 xexit(2) 31 } 32 33 // commands records the available commands. 34 var commands = map[string]func(){ 35 "banner": cmdbanner, 36 "bootstrap": cmdbootstrap, 37 "clean": cmdclean, 38 "env": cmdenv, 39 "install": cmdinstall, 40 "list": cmdlist, 41 "test": cmdtest, 42 "version": cmdversion, 43 } 44 45 // main takes care of OS-specific startup and dispatches to xmain. 46 func main() { 47 os.Setenv("TERM", "dumb") // disable escape codes in clang errors 48 49 // provide -check-armv6k first, before checking for $GOROOT so that 50 // it is possible to run this check without having $GOROOT available. 51 if len(os.Args) > 1 && os.Args[1] == "-check-armv6k" { 52 useARMv6K() // might fail with SIGILL 53 println("ARMv6K supported.") 54 os.Exit(0) 55 } 56 57 gohostos = runtime.GOOS 58 switch gohostos { 59 case "aix": 60 // uname -m doesn't work under AIX 61 gohostarch = "ppc64" 62 case "plan9": 63 gohostarch = os.Getenv("objtype") 64 if gohostarch == "" { 65 fatalf("$objtype is unset") 66 } 67 case "solaris", "illumos": 68 // Solaris and illumos systems have multi-arch userlands, and 69 // "uname -m" reports the machine hardware name; e.g., 70 // "i86pc" on both 32- and 64-bit x86 systems. Check for the 71 // native (widest) instruction set on the running kernel: 72 out := run("", CheckExit, "isainfo", "-n") 73 if strings.Contains(out, "amd64") { 74 gohostarch = "amd64" 75 } 76 if strings.Contains(out, "i386") { 77 gohostarch = "386" 78 } 79 case "windows": 80 exe = ".exe" 81 } 82 83 sysinit() 84 85 if gohostarch == "" { 86 // Default Unix system. 87 out := run("", CheckExit, "uname", "-m") 88 outAll := run("", CheckExit, "uname", "-a") 89 switch { 90 case strings.Contains(outAll, "RELEASE_ARM64"): 91 // MacOS prints 92 // Darwin p1.local 21.1.0 Darwin Kernel Version 21.1.0: Wed Oct 13 17:33:01 PDT 2021; root:xnu-8019.41.5~1/RELEASE_ARM64_T6000 x86_64 93 // on ARM64 laptops when there is an x86 parent in the 94 // process tree. Look for the RELEASE_ARM64 to avoid being 95 // confused into building an x86 toolchain. 96 gohostarch = "arm64" 97 case strings.Contains(out, "x86_64"), strings.Contains(out, "amd64"): 98 gohostarch = "amd64" 99 case strings.Contains(out, "86"): 100 gohostarch = "386" 101 if gohostos == "darwin" { 102 // Even on 64-bit platform, some versions of macOS uname -m prints i386. 103 // We don't support any of the OS X versions that run on 32-bit-only hardware anymore. 104 gohostarch = "amd64" 105 } 106 case strings.Contains(out, "aarch64"), strings.Contains(out, "arm64"): 107 gohostarch = "arm64" 108 case strings.Contains(out, "arm"): 109 gohostarch = "arm" 110 if gohostos == "netbsd" && strings.Contains(run("", CheckExit, "uname", "-p"), "aarch64") { 111 gohostarch = "arm64" 112 } 113 case strings.Contains(out, "ppc64le"): 114 gohostarch = "ppc64le" 115 case strings.Contains(out, "ppc64"): 116 gohostarch = "ppc64" 117 case strings.Contains(out, "mips64"): 118 gohostarch = "mips64" 119 if elfIsLittleEndian(os.Args[0]) { 120 gohostarch = "mips64le" 121 } 122 case strings.Contains(out, "mips"): 123 gohostarch = "mips" 124 if elfIsLittleEndian(os.Args[0]) { 125 gohostarch = "mipsle" 126 } 127 case strings.Contains(out, "loongarch64"): 128 gohostarch = "loong64" 129 case strings.Contains(out, "riscv64"): 130 gohostarch = "riscv64" 131 case strings.Contains(out, "s390x"): 132 gohostarch = "s390x" 133 case gohostos == "darwin", gohostos == "ios": 134 if strings.Contains(run("", CheckExit, "uname", "-v"), "RELEASE_ARM64_") { 135 gohostarch = "arm64" 136 } 137 case gohostos == "freebsd": 138 if strings.Contains(run("", CheckExit, "uname", "-p"), "riscv64") { 139 gohostarch = "riscv64" 140 } 141 case gohostos == "openbsd" && strings.Contains(out, "powerpc64"): 142 gohostarch = "ppc64" 143 case gohostos == "openbsd": 144 if strings.Contains(run("", CheckExit, "uname", "-p"), "mips64") { 145 gohostarch = "mips64" 146 } 147 default: 148 fatalf("unknown architecture: %s", out) 149 } 150 } 151 152 if gohostarch == "arm" || gohostarch == "mips64" || gohostarch == "mips64le" { 153 maxbg = min(maxbg, runtime.NumCPU()) 154 } 155 // For deterministic make.bash debugging and for smallest-possible footprint, 156 // pay attention to GOMAXPROCS=1. This was a bad idea for 1.4 bootstrap, but 157 // the bootstrap version is now 1.17+ and thus this is fine. 158 if runtime.GOMAXPROCS(0) == 1 { 159 maxbg = 1 160 } 161 bginit() 162 163 if len(os.Args) > 1 && os.Args[1] == "-check-goarm" { 164 useVFPv1() // might fail with SIGILL 165 println("VFPv1 OK.") 166 useVFPv3() // might fail with SIGILL 167 println("VFPv3 OK.") 168 os.Exit(0) 169 } 170 171 xinit() 172 xmain() 173 xexit(0) 174 } 175 176 // The OS-specific main calls into the portable code here. 177 func xmain() { 178 if len(os.Args) < 2 { 179 usage() 180 } 181 cmd := os.Args[1] 182 os.Args = os.Args[1:] // for flag parsing during cmd 183 flag.Usage = func() { 184 fmt.Fprintf(os.Stderr, "usage: go tool dist %s [options]\n", cmd) 185 flag.PrintDefaults() 186 os.Exit(2) 187 } 188 if f, ok := commands[cmd]; ok { 189 f() 190 } else { 191 xprintf("unknown command %s\n", cmd) 192 usage() 193 } 194 }