...

Source file src/pkg/cmd/dist/main.go

     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 main
     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]   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 "darwin":
    63			// macOS 10.9 and later require clang
    64			defaultclang = true
    65		case "freebsd":
    66			// Since FreeBSD 10 gcc is no longer part of the base system.
    67			defaultclang = true
    68		case "openbsd":
    69			// The gcc available on OpenBSD armv7 is old/inadequate (for example, lacks
    70			// __sync_fetch_and_*/__sync_*_and_fetch) and will likely be removed in the
    71			// not-to-distant future - use clang instead. OpenBSD arm64 does not ship
    72			// with gcc.
    73			if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
    74				defaultclang = true
    75			}
    76		case "plan9":
    77			gohostarch = os.Getenv("objtype")
    78			if gohostarch == "" {
    79				fatalf("$objtype is unset")
    80			}
    81		case "solaris", "illumos":
    82			// Solaris and illumos systems have multi-arch userlands, and
    83			// "uname -m" reports the machine hardware name; e.g.,
    84			// "i86pc" on both 32- and 64-bit x86 systems.  Check for the
    85			// native (widest) instruction set on the running kernel:
    86			out := run("", CheckExit, "isainfo", "-n")
    87			if strings.Contains(out, "amd64") {
    88				gohostarch = "amd64"
    89			}
    90			if strings.Contains(out, "i386") {
    91				gohostarch = "386"
    92			}
    93		case "windows":
    94			exe = ".exe"
    95		}
    96	
    97		sysinit()
    98	
    99		if gohostarch == "" {
   100			// Default Unix system.
   101			out := run("", CheckExit, "uname", "-m")
   102			switch {
   103			case strings.Contains(out, "x86_64"), strings.Contains(out, "amd64"):
   104				gohostarch = "amd64"
   105			case strings.Contains(out, "86"):
   106				gohostarch = "386"
   107				if gohostos == "darwin" {
   108					// Even on 64-bit platform, some versions of macOS uname -m prints i386.
   109					// We don't support any of the OS X versions that run on 32-bit-only hardware anymore.
   110					gohostarch = "amd64"
   111				}
   112			case strings.Contains(out, "aarch64"), strings.Contains(out, "arm64"):
   113				gohostarch = "arm64"
   114			case strings.Contains(out, "arm"):
   115				gohostarch = "arm"
   116			case strings.Contains(out, "ppc64le"):
   117				gohostarch = "ppc64le"
   118			case strings.Contains(out, "ppc64"):
   119				gohostarch = "ppc64"
   120			case strings.Contains(out, "mips64"):
   121				gohostarch = "mips64"
   122				if elfIsLittleEndian(os.Args[0]) {
   123					gohostarch = "mips64le"
   124				}
   125			case strings.Contains(out, "mips"):
   126				gohostarch = "mips"
   127				if elfIsLittleEndian(os.Args[0]) {
   128					gohostarch = "mipsle"
   129				}
   130			case strings.Contains(out, "s390x"):
   131				gohostarch = "s390x"
   132			case gohostos == "darwin":
   133				if strings.Contains(run("", CheckExit, "uname", "-v"), "RELEASE_ARM64_") {
   134					gohostarch = "arm64"
   135				}
   136			default:
   137				fatalf("unknown architecture: %s", out)
   138			}
   139		}
   140	
   141		if gohostarch == "arm" || gohostarch == "mips64" || gohostarch == "mips64le" {
   142			maxbg = min(maxbg, runtime.NumCPU())
   143		}
   144		bginit()
   145	
   146		if len(os.Args) > 1 && os.Args[1] == "-check-goarm" {
   147			useVFPv1() // might fail with SIGILL
   148			println("VFPv1 OK.")
   149			useVFPv3() // might fail with SIGILL
   150			println("VFPv3 OK.")
   151			os.Exit(0)
   152		}
   153	
   154		xinit()
   155		xmain()
   156		xexit(0)
   157	}
   158	
   159	// The OS-specific main calls into the portable code here.
   160	func xmain() {
   161		if len(os.Args) < 2 {
   162			usage()
   163		}
   164		cmd := os.Args[1]
   165		os.Args = os.Args[1:] // for flag parsing during cmd
   166		flag.Usage = func() {
   167			fmt.Fprintf(os.Stderr, "usage: go tool dist %s [options]\n", cmd)
   168			flag.PrintDefaults()
   169			os.Exit(2)
   170		}
   171		if f, ok := commands[cmd]; ok {
   172			f()
   173		} else {
   174			xprintf("unknown command %s\n", cmd)
   175			usage()
   176		}
   177	}
   178	

View as plain text