[dev.cc] cmd/go: adjust go, cgo builds & disable cc

[This CL is part of the removal of C code from package runtime.
See golang.org/s/dev.cc for an overview.]

Make gcToolchain.cc return an error (no C compiler!).

Adjust expectations of cgo, now that cgo does not write any C files
(no C compiler!).

For packages with .s files, invoke Go compiler with -asmhdr go_asm.h
so that assembly files can use it. This applies to all packages but is only
needed today by package runtime.

LGTM=r
R=r
CC=austin, golang-codereviews, iant, khr
https://golang.org/cl/171470043
diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go
index 1dd4314..5dcaa04 100644
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -813,7 +813,7 @@
 	}
 
 	if a.p.Standard && a.p.ImportPath == "runtime" && buildContext.Compiler == "gc" &&
-		!hasString(a.p.HFiles, "zasm_"+buildContext.GOOS+"_"+buildContext.GOARCH+".h") {
+		!hasString(a.p.SFiles, "zsys_"+buildContext.GOOS+"_"+buildContext.GOARCH+".s") {
 		return fmt.Errorf("%s/%s must be bootstrapped using make%v", buildContext.GOOS, buildContext.GOARCH, defaultSuffix())
 	}
 
@@ -941,7 +941,7 @@
 	inc := b.includeArgs("-I", a.deps)
 
 	// Compile Go.
-	ofile, out, err := buildToolchain.gc(b, a.p, a.objpkg, obj, inc, gofiles)
+	ofile, out, err := buildToolchain.gc(b, a.p, a.objpkg, obj, len(sfiles) > 0, inc, gofiles)
 	if len(out) > 0 {
 		b.showOutput(a.p.Dir, a.p.ImportPath, b.processOutput(out))
 		if err != nil {
@@ -1550,7 +1550,7 @@
 	// gc runs the compiler in a specific directory on a set of files
 	// and returns the name of the generated output file.
 	// The compiler runs in the directory dir.
-	gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, out []byte, err error)
+	gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error)
 	// cc runs the toolchain's C compiler in a directory on a C file
 	// to produce an output file.
 	cc(b *builder, p *Package, objdir, ofile, cfile string) error
@@ -1587,7 +1587,7 @@
 	return ""
 }
 
-func (noToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, out []byte, err error) {
+func (noToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error) {
 	return "", nil, noCompiler()
 }
 
@@ -1623,7 +1623,7 @@
 	return tool(archChar + "l")
 }
 
-func (gcToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
+func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
 	if archive != "" {
 		ofile = archive
 	} else {
@@ -1660,6 +1660,9 @@
 	if ofile == archive {
 		args = append(args, "-pack")
 	}
+	if asmhdr {
+		args = append(args, "-asmhdr", obj+"go_asm.h")
+	}
 	for _, f := range gofiles {
 		args = append(args, mkAbs(p.Dir, f))
 	}
@@ -1824,18 +1827,7 @@
 }
 
 func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
-	inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
-	cfile = mkAbs(p.Dir, cfile)
-	warn := []string{"-w"}
-	if p.usesSwig() {
-		// When using SWIG, this compiler is only used to
-		// compile the C files generated by SWIG.
-		// We don't want warnings.
-		// See issue 9065 for details.
-		warn = nil
-	}
-	args := stringList(tool(archChar+"c"), "-F", "-V", warn, "-trimpath", b.work, "-I", objdir, "-I", inc, "-o", ofile, buildCcflags, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, cfile)
-	return b.run(p.Dir, p.ImportPath, nil, args)
+	return fmt.Errorf("%s: C source files not supported without cgo", mkAbs(p.Dir, cfile))
 }
 
 // The Gccgo toolchain.
@@ -1859,7 +1851,7 @@
 	return gccgoBin
 }
 
-func (gccgoToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
+func (gccgoToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
 	out := "_go_.o"
 	ofile = obj + out
 	gcargs := []string{"-g"}
@@ -2225,11 +2217,14 @@
 	outGo = append(outGo, gofiles...)
 
 	// cc _cgo_defun.c
-	defunObj := obj + "_cgo_defun." + objExt
-	if err := buildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
-		return nil, nil, err
+	_, gccgo := buildToolchain.(gccgoToolchain)
+	if gccgo {
+		defunObj := obj + "_cgo_defun." + objExt
+		if err := buildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
+			return nil, nil, err
+		}
+		outObj = append(outObj, defunObj)
 	}
-	outObj = append(outObj, defunObj)
 
 	// gcc
 	var linkobj []string
@@ -2343,20 +2338,15 @@
 	}
 
 	// cgo -dynimport
-	importC := obj + "_cgo_import.c"
+	importGo := obj + "_cgo_import.go"
 	cgoflags = []string{}
 	if p.Standard && p.ImportPath == "runtime/cgo" {
 		cgoflags = append(cgoflags, "-dynlinker") // record path to dynamic linker
 	}
-	if err := b.run(p.Dir, p.ImportPath, nil, cgoExe, "-objdir", obj, "-dynimport", dynobj, "-dynout", importC, cgoflags); err != nil {
+	if err := b.run(p.Dir, p.ImportPath, nil, cgoExe, "-objdir", obj, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags); err != nil {
 		return nil, nil, err
 	}
-
-	// cc _cgo_import.ARCH
-	importObj := obj + "_cgo_import." + objExt
-	if err := buildToolchain.cc(b, p, obj, importObj, importC); err != nil {
-		return nil, nil, err
-	}
+	outGo = append(outGo, importGo)
 
 	ofile := obj + "_all.o"
 	var gccObjs, nonGccObjs []string
@@ -2390,7 +2380,7 @@
 	// NOTE(rsc): The importObj is a 5c/6c/8c object and on Windows
 	// must be processed before the gcc-generated objects.
 	// Put it first.  http://golang.org/issue/2601
-	outObj = stringList(importObj, nonGccObjs, ofile)
+	outObj = stringList(nonGccObjs, ofile)
 
 	return outGo, outObj, nil
 }
@@ -2526,7 +2516,7 @@
 
 	p := goFilesPackage(srcs)
 
-	if _, _, e := buildToolchain.gc(b, p, "", obj, nil, srcs); e != nil {
+	if _, _, e := buildToolchain.gc(b, p, "", obj, false, nil, srcs); e != nil {
 		return "32", nil
 	}
 	return "64", nil