all: retire architecture letter in file names, public API

This CL removes the remaining visible uses of the "architecture letter" concept.
(They are no longer in tool names nor in source directory names.)

Because the architecture letter concept is now gone, delete GOCHAR
from "go env" output, and change go/build.ArchChar to return an
error always.

The architecture letter is still used in the compiler and linker sources
as a clumsy architecture enumeration, but that use is not visible to
Go users and can be cleaned up separately.

Change-Id: I4d97a38f372003fb610c9c5241bea440d9dbeb8d
Reviewed-on: https://go-review.googlesource.com/10289
Reviewed-by: Rob Pike <r@golang.org>
diff --git a/src/cmd/asm/internal/flags/flags.go b/src/cmd/asm/internal/flags/flags.go
index c74f269..bf5cb1e 100644
--- a/src/cmd/asm/internal/flags/flags.go
+++ b/src/cmd/asm/internal/flags/flags.go
@@ -51,7 +51,7 @@
 	os.Exit(2)
 }
 
-func Parse(theChar int) {
+func Parse() {
 	flag.Usage = Usage
 	flag.Parse()
 	if flag.NArg() != 1 {
@@ -64,6 +64,6 @@
 		if strings.HasSuffix(input, ".s") {
 			input = input[:len(input)-2]
 		}
-		*OutputFile = fmt.Sprintf("%s.%c", input, theChar)
+		*OutputFile = fmt.Sprintf("%s.o", input)
 	}
 }
diff --git a/src/cmd/asm/main.go b/src/cmd/asm/main.go
index 32bdee6..db0e28e 100644
--- a/src/cmd/asm/main.go
+++ b/src/cmd/asm/main.go
@@ -29,7 +29,7 @@
 		log.Fatalf("asm: unrecognized architecture %s", GOARCH)
 	}
 
-	flags.Parse(architecture.Thechar)
+	flags.Parse()
 
 	// Create object file, write header.
 	fd, err := os.Create(*flags.OutputFile)
diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
index f921140..3b93207 100644
--- a/src/cmd/compile/internal/gc/lex.go
+++ b/src/cmd/compile/internal/gc/lex.go
@@ -583,7 +583,7 @@
 		if obj.Access(file, 0) >= 0 {
 			return file, true
 		}
-		file = fmt.Sprintf("%s.%c", name, Thearch.Thechar)
+		file = fmt.Sprintf("%s.o", name)
 		if obj.Access(file, 0) >= 0 {
 			return file, true
 		}
@@ -605,7 +605,7 @@
 		if obj.Access(file, 0) >= 0 {
 			return file, true
 		}
-		file = fmt.Sprintf("%s/%s.%c", p.dir, name, Thearch.Thechar)
+		file = fmt.Sprintf("%s/%s.o", p.dir, name)
 		if obj.Access(file, 0) >= 0 {
 			return file, true
 		}
@@ -626,7 +626,7 @@
 		if obj.Access(file, 0) >= 0 {
 			return file, true
 		}
-		file = fmt.Sprintf("%s/pkg/%s_%s%s%s/%s.%c", goroot, goos, goarch, suffixsep, suffix, name, Thearch.Thechar)
+		file = fmt.Sprintf("%s/pkg/%s_%s%s%s/%s.o", goroot, goos, goarch, suffixsep, suffix, name)
 		if obj.Access(file, 0) >= 0 {
 			return file, true
 		}
@@ -637,7 +637,7 @@
 
 func fakeimport() {
 	importpkg = mkpkg("fake")
-	cannedimports("fake.6", "$$\n")
+	cannedimports("fake.o", "$$\n")
 }
 
 func importfile(f *Val, line int) {
@@ -679,7 +679,7 @@
 		}
 
 		importpkg = mkpkg(f.U.(string))
-		cannedimports("unsafe.6", unsafeimport)
+		cannedimports("unsafe.o", unsafeimport)
 		imported_unsafe = 1
 		return
 	}
@@ -2596,6 +2596,6 @@
 		if i := strings.LastIndex(p, "."); i >= 0 {
 			p = p[:i]
 		}
-		outfile = fmt.Sprintf("%s.%c", p, Thearch.Thechar)
+		outfile = fmt.Sprintf("%s.o", p)
 	}
 }
diff --git a/src/cmd/compile/internal/gc/mkbuiltin.go b/src/cmd/compile/internal/gc/mkbuiltin.go
index b2362a6..f4569b4 100644
--- a/src/cmd/compile/internal/gc/mkbuiltin.go
+++ b/src/cmd/compile/internal/gc/mkbuiltin.go
@@ -13,21 +13,14 @@
 import (
 	"bufio"
 	"fmt"
-	"go/build"
 	"io"
 	"log"
 	"os"
 	"os/exec"
-	"runtime"
 	"strings"
 )
 
 func main() {
-	gochar, err := build.ArchChar(runtime.GOARCH)
-	if err != nil {
-		log.Fatal(err)
-	}
-
 	f, err := os.Create("builtin.go")
 	if err != nil {
 		log.Fatal(err)
@@ -40,7 +33,7 @@
 	fmt.Fprintln(w, "package gc")
 
 	for _, name := range os.Args[1:] {
-		mkbuiltin(w, gochar, name)
+		mkbuiltin(w, name)
 	}
 
 	if err := w.Flush(); err != nil {
@@ -49,11 +42,11 @@
 }
 
 // Compile .go file, import data from .6 file, and write Go string version.
-func mkbuiltin(w io.Writer, gochar string, name string) {
-	if err := exec.Command("go", "tool", gochar+"g", "-A", "builtin/"+name+".go").Run(); err != nil {
+func mkbuiltin(w io.Writer, name string) {
+	if err := exec.Command("go", "tool", "compile", "-A", "builtin/"+name+".go").Run(); err != nil {
 		log.Fatal(err)
 	}
-	obj := fmt.Sprintf("%s.%s", name, gochar)
+	obj := "name.o"
 	defer os.Remove(obj)
 
 	r, err := os.Open(obj)
@@ -77,7 +70,7 @@
 	fmt.Fprintf(w, "\nconst %simport = \"\" +\n", name)
 
 	// sys.go claims to be in package PACKAGE to avoid
-	// conflicts during "6g sys.go".  Rename PACKAGE to $2.
+	// conflicts during "go tool compile sys.go".  Rename PACKAGE to $2.
 	replacer := strings.NewReplacer("PACKAGE", name)
 
 	// Process imports, stopping at $$ that closes them.
diff --git a/src/cmd/compile/internal/gc/obj.go b/src/cmd/compile/internal/gc/obj.go
index 2afd786..9bb334c 100644
--- a/src/cmd/compile/internal/gc/obj.go
+++ b/src/cmd/compile/internal/gc/obj.go
@@ -102,8 +102,7 @@
 			obj.Bputc(bout, 0)
 		}
 		obj.Bseek(bout, startobj-ArhdrSize, 0)
-		name := fmt.Sprintf("_go_.%c", Thearch.Thechar)
-		formathdr(arhdr[:], name, size)
+		formathdr(arhdr[:], "_go_.o", size)
 		bout.Write(arhdr[:])
 	}
 
diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go
index d6cfaf0..0cdb7d6 100644
--- a/src/cmd/dist/build.go
+++ b/src/cmd/dist/build.go
@@ -20,7 +20,6 @@
 	goarch           string
 	gobin            string
 	gohostarch       string
-	gohostchar       string
 	gohostos         string
 	goos             string
 	goarm            string
@@ -30,10 +29,8 @@
 	goextlinkenabled string
 	workdir          string
 	tooldir          string
-	gochar           string
 	oldgoos          string
 	oldgoarch        string
-	oldgochar        string
 	slash            string
 	exe              string
 	defaultcc        string
@@ -48,17 +45,13 @@
 	vflag int  // verbosity
 )
 
-// The known architecture letters.
-var gochars = "5667899"
-
 // The known architectures.
 var okgoarch = []string{
-	// same order as gochars
-	"arm",
+	"386",
 	"amd64",
 	"amd64p32",
+	"arm",
 	"arm64",
-	"386",
 	"ppc64",
 	"ppc64le",
 }
@@ -147,22 +140,18 @@
 		gohostarch = b
 	}
 
-	i := find(gohostarch, okgoarch)
-	if i < 0 {
+	if find(gohostarch, okgoarch) < 0 {
 		fatal("unknown $GOHOSTARCH %s", gohostarch)
 	}
-	gohostchar = gochars[i : i+1]
 
 	b = os.Getenv("GOARCH")
 	if b == "" {
 		b = gohostarch
 	}
 	goarch = b
-	i = find(goarch, okgoarch)
-	if i < 0 {
+	if find(goarch, okgoarch) < 0 {
 		fatal("unknown $GOARCH %s", goarch)
 	}
-	gochar = gochars[i : i+1]
 
 	b = os.Getenv("GO_EXTLINK_ENABLED")
 	if b != "" {
@@ -436,7 +425,7 @@
 	}
 
 	// If $GOBIN is set and has a Go compiler, it must be cleaned.
-	for _, char := range gochars {
+	for _, char := range "56789" {
 		if isfile(pathf("%s%s%c%s", gobin, slash, char, "g")) {
 			for _, old := range oldtool {
 				xremove(pathf("%s/%s", gobin, old))
@@ -703,11 +692,7 @@
 		b := pathf("%s/%s", workdir, filepath.Base(p))
 
 		// Change the last character of the output file (which was c or s).
-		if gohostos == "plan9" {
-			b = b[:len(b)-1] + gohostchar
-		} else {
-			b = b[:len(b)-1] + "o"
-		}
+		b = b[:len(b)-1] + "o"
 		compile = append(compile, "-o", b, p)
 		bgrun(path, compile...)
 
@@ -1035,7 +1020,6 @@
 	xprintf(format, "GOHOSTARCH", gohostarch)
 	xprintf(format, "GOHOSTOS", gohostos)
 	xprintf(format, "GOTOOLDIR", tooldir)
-	xprintf(format, "GOCHAR", gochar)
 	if goarch == "arm" {
 		xprintf(format, "GOARM", goarm)
 	}
@@ -1080,10 +1064,8 @@
 	// For the main bootstrap, building for host os/arch.
 	oldgoos = goos
 	oldgoarch = goarch
-	oldgochar = gochar
 	goos = gohostos
 	goarch = gohostarch
-	gochar = gohostchar
 	os.Setenv("GOHOSTARCH", gohostarch)
 	os.Setenv("GOHOSTOS", gohostos)
 	os.Setenv("GOARCH", goarch)
@@ -1097,37 +1079,22 @@
 	// than in a standard release like Go 1.4, so don't do this rebuild by default.
 	if false {
 		xprintf("##### Building Go toolchain using itself.\n")
-		for _, pattern := range buildorder {
-			if pattern == "cmd/go" {
+		for _, dir := range buildorder {
+			if dir == "cmd/go" {
 				break
 			}
-			dir := pattern
-			if strings.Contains(pattern, "%s") {
-				dir = fmt.Sprintf(pattern, gohostchar)
-			}
 			install(dir)
-			if oldgochar != gohostchar && strings.Contains(pattern, "%s") {
-				install(fmt.Sprintf(pattern, oldgochar))
-			}
 		}
 		xprintf("\n")
 	}
 
 	xprintf("##### Building compilers and go_bootstrap for host, %s/%s.\n", gohostos, gohostarch)
-	for _, pattern := range buildorder {
-		dir := pattern
-		if strings.Contains(pattern, "%s") {
-			dir = fmt.Sprintf(pattern, gohostchar)
-		}
+	for _, dir := range buildorder {
 		install(dir)
-		if oldgochar != gohostchar && strings.Contains(pattern, "%s") {
-			install(fmt.Sprintf(pattern, oldgochar))
-		}
 	}
 
 	goos = oldgoos
 	goarch = oldgoarch
-	gochar = oldgochar
 	os.Setenv("GOARCH", goarch)
 	os.Setenv("GOOS", goos)
 
diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go
index aa9a408..17ff7e0 100644
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -547,9 +547,6 @@
 	goarch    string
 	goos      string
 	exeSuffix string
-
-	archCharVal string
-	archCharErr error
 )
 
 func init() {
@@ -558,16 +555,6 @@
 	if goos == "windows" {
 		exeSuffix = ".exe"
 	}
-	archCharVal, archCharErr = build.ArchChar(goarch)
-}
-
-// archChar returns the architecture character.  This is only needed
-// for the gc toolchain, so only fail if we actually need it.
-func archChar() string {
-	if archCharErr != nil {
-		fatalf("%s", archCharErr)
-	}
-	return archCharVal
 }
 
 // A builder holds global state about a build.
@@ -1208,7 +1195,7 @@
 		fmt.Fprintf(os.Stderr, "%s\n", a.p.ImportPath)
 	}
 
-	if a.p.Standard && a.p.ImportPath == "runtime" && buildContext.Compiler == "gc" && archChar() != "" &&
+	if a.p.Standard && a.p.ImportPath == "runtime" && buildContext.Compiler == "gc" &&
 		(!hasString(a.p.GoFiles, "zgoos_"+buildContext.GOOS+".go") ||
 			!hasString(a.p.GoFiles, "zgoarch_"+buildContext.GOARCH+".go")) {
 		return fmt.Errorf("%s/%s must be bootstrapped using make%v", buildContext.GOOS, buildContext.GOARCH, defaultSuffix())
@@ -1371,15 +1358,8 @@
 		}
 	}
 
-	var objExt string
-	if _, ok := buildToolchain.(gccgoToolchain); ok {
-		objExt = "o"
-	} else {
-		objExt = archChar()
-	}
-
 	for _, file := range cfiles {
-		out := file[:len(file)-len(".c")] + "." + objExt
+		out := file[:len(file)-len(".c")] + ".o"
 		if err := buildToolchain.cc(b, a.p, obj, obj+out, file); err != nil {
 			return err
 		}
@@ -1388,7 +1368,7 @@
 
 	// Assemble .s files.
 	for _, file := range sfiles {
-		out := file[:len(file)-len(".s")] + "." + objExt
+		out := file[:len(file)-len(".s")] + ".o"
 		if err := buildToolchain.asm(b, a.p, obj, obj+out, file); err != nil {
 			return err
 		}
@@ -2120,7 +2100,7 @@
 	if archive != "" {
 		ofile = archive
 	} else {
-		out := "_go_." + archChar()
+		out := "_go_.o"
 		ofile = obj + out
 	}
 
@@ -2182,9 +2162,22 @@
 	}
 	// Disable checks when additional flags are passed, as the old assemblers
 	// don't implement some of them (e.g., -shared).
-	if verifyAsm && goarch != "arm64" && len(buildAsmflags) == 0 {
-		if err := toolVerify(b, p, "old"+archChar()+"a", ofile, args); err != nil {
-			return err
+	if verifyAsm && len(buildAsmflags) == 0 {
+		old := ""
+		switch goarch {
+		case "arm":
+			old = "old5a"
+		case "amd64", "amd64p32":
+			old = "old6a"
+		case "386":
+			old = "old8a"
+		case "ppc64", "ppc64le":
+			old = "old9a"
+		}
+		if old != "" {
+			if err := toolVerify(b, p, old, ofile, args); err != nil {
+				return err
+			}
 		}
 	}
 	return nil
@@ -2785,13 +2778,6 @@
 	cgoflags := []string{}
 	// TODO: make cgo not depend on $GOARCH?
 
-	var objExt string
-	if _, ok := buildToolchain.(gccgoToolchain); ok {
-		objExt = "o"
-	} else {
-		objExt = archChar()
-	}
-
 	if p.Standard && p.ImportPath == "runtime/cgo" {
 		cgoflags = append(cgoflags, "-import_runtime_cgo=false")
 	}
@@ -2836,7 +2822,7 @@
 	// cc _cgo_defun.c
 	_, gccgo := buildToolchain.(gccgoToolchain)
 	if gccgo {
-		defunObj := obj + "_cgo_defun." + objExt
+		defunObj := obj + "_cgo_defun.o"
 		if err := buildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
 			return nil, nil, err
 		}
diff --git a/src/cmd/go/env.go b/src/cmd/go/env.go
index 863eb4d..8d427b3 100644
--- a/src/cmd/go/env.go
+++ b/src/cmd/go/env.go
@@ -49,10 +49,6 @@
 		{"TERM", "dumb"},
 	}
 
-	if archCharErr == nil {
-		env = append(env, envVar{"GOCHAR", archChar()})
-	}
-
 	if goos != "plan9" {
 		cmd := b.gccCmd(".")
 		env = append(env, envVar{"CC", cmd[0]})
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
index a36cd0f..6cf0b52 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -1627,7 +1627,7 @@
 }
 
 func usage() {
-	fmt.Fprintf(os.Stderr, "usage: %cl [options] obj.%c\n", Thearch.Thechar, Thearch.Thechar)
+	fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n")
 	obj.Flagprint(2)
 	Exit(2)
 }
diff --git a/src/cmd/link/internal/ld/pobj.go b/src/cmd/link/internal/ld/pobj.go
index 8568744..5b2442805 100644
--- a/src/cmd/link/internal/ld/pobj.go
+++ b/src/cmd/link/internal/ld/pobj.go
@@ -160,10 +160,9 @@
 	}
 
 	if outfile == "" {
+		outfile = "a.out"
 		if HEADTYPE == obj.Hwindows {
-			outfile = fmt.Sprintf("%c.out.exe", Thearch.Thechar)
-		} else {
-			outfile = fmt.Sprintf("%c.out", Thearch.Thechar)
+			outfile += ".exe"
 		}
 	}
 
diff --git a/src/cmd/pack/pack_test.go b/src/cmd/pack/pack_test.go
index 9799205..cd32020 100644
--- a/src/cmd/pack/pack_test.go
+++ b/src/cmd/pack/pack_test.go
@@ -13,7 +13,6 @@
 	"os"
 	"os/exec"
 	"path/filepath"
-	"regexp"
 	"runtime"
 	"testing"
 	"time"
@@ -223,15 +222,13 @@
 		t.Fatal(err)
 	}
 
-	char := findChar(t, dir)
-
 	run := func(args ...string) string {
 		return doRun(t, dir, args...)
 	}
 
 	run("go", "build", "cmd/pack") // writes pack binary to dir
 	run("go", "tool", "compile", "hello.go")
-	run("./pack", "grc", "hello.a", "hello."+char)
+	run("./pack", "grc", "hello.a", "hello.o")
 	run("go", "tool", "link", "-o", "a.out", "hello.a")
 	out := run("./a.out")
 	if out != "hello world\n" {
@@ -297,17 +294,15 @@
 		t.Fatal(err)
 	}
 
-	char := findChar(t, dir)
-
 	run := func(args ...string) string {
 		return doRun(t, dir, args...)
 	}
 
 	run("go", "build", "cmd/pack") // writes pack binary to dir
 	run("go", "tool", "compile", "large.go")
-	run("./pack", "grc", "large.a", "large."+char)
+	run("./pack", "grc", "large.a", "large.o")
 	run("go", "tool", "compile", "-I", ".", "main.go")
-	run("go", "tool", "link", "-L", ".", "-o", "a.out", "main."+char)
+	run("go", "tool", "link", "-L", ".", "-o", "a.out", "main.o")
 	out := run("./a.out")
 	if out != "ok\n" {
 		t.Fatalf("incorrect output: %q, want %q", out, "ok\n")
@@ -325,20 +320,6 @@
 	return string(out)
 }
 
-// findChar returns the architecture character for the go command.
-func findChar(t *testing.T, dir string) string {
-	out := doRun(t, dir, "go", "env")
-	re, err := regexp.Compile(`\s*GOCHAR=['"]?(\w)['"]?`)
-	if err != nil {
-		t.Fatal(err)
-	}
-	fields := re.FindStringSubmatch(out)
-	if fields == nil {
-		t.Fatal("cannot find GOCHAR in 'go env' output:\n", out)
-	}
-	return fields[1]
-}
-
 // Fake implementation of files.
 
 var helloFile = &FakeFile{