summaryrefslogtreecommitdiffstats
path: root/src/cmd/dist/buildgo.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/dist/buildgo.go')
-rw-r--r--src/cmd/dist/buildgo.go162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/cmd/dist/buildgo.go b/src/cmd/dist/buildgo.go
new file mode 100644
index 0000000..884e9d7
--- /dev/null
+++ b/src/cmd/dist/buildgo.go
@@ -0,0 +1,162 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+ "sort"
+ "strings"
+)
+
+/*
+ * Helpers for building cmd/go and cmd/cgo.
+ */
+
+// generatedHeader is the string that all source files generated by dist start with.
+//
+// DO NOT CHANGE THIS STRING. If this string is changed then during
+//
+// ./make.bash
+// git checkout other-rev
+// ./make.bash
+//
+// the second make.bash will not find the files generated by the first make.bash
+// and will not clean up properly.
+const generatedHeader = "// Code generated by go tool dist; DO NOT EDIT.\n\n"
+
+// writeHeader emits the standard "generated by" header for all files generated
+// by dist.
+func writeHeader(w io.Writer) {
+ fmt.Fprint(w, generatedHeader)
+}
+
+// mkzdefaultcc writes zdefaultcc.go:
+//
+// package main
+// const defaultCC = <defaultcc>
+// const defaultCXX = <defaultcxx>
+// const defaultPkgConfig = <defaultpkgconfig>
+//
+// It is invoked to write cmd/go/internal/cfg/zdefaultcc.go
+// but we also write cmd/cgo/zdefaultcc.go
+func mkzdefaultcc(dir, file string) {
+ if strings.Contains(file, filepath.FromSlash("go/internal/cfg")) {
+ var buf strings.Builder
+ writeHeader(&buf)
+ fmt.Fprintf(&buf, "package cfg\n")
+ fmt.Fprintln(&buf)
+ fmt.Fprintf(&buf, "const DefaultPkgConfig = `%s`\n", defaultpkgconfig)
+ buf.WriteString(defaultCCFunc("DefaultCC", defaultcc))
+ buf.WriteString(defaultCCFunc("DefaultCXX", defaultcxx))
+ writefile(buf.String(), file, writeSkipSame)
+ return
+ }
+
+ var buf strings.Builder
+ writeHeader(&buf)
+ fmt.Fprintf(&buf, "package main\n")
+ fmt.Fprintln(&buf)
+ fmt.Fprintf(&buf, "const defaultPkgConfig = `%s`\n", defaultpkgconfig)
+ buf.WriteString(defaultCCFunc("defaultCC", defaultcc))
+ buf.WriteString(defaultCCFunc("defaultCXX", defaultcxx))
+ writefile(buf.String(), file, writeSkipSame)
+}
+
+func defaultCCFunc(name string, defaultcc map[string]string) string {
+ var buf strings.Builder
+
+ fmt.Fprintf(&buf, "func %s(goos, goarch string) string {\n", name)
+ fmt.Fprintf(&buf, "\tswitch goos+`/`+goarch {\n")
+ var keys []string
+ for k := range defaultcc {
+ if k != "" {
+ keys = append(keys, k)
+ }
+ }
+ sort.Strings(keys)
+ for _, k := range keys {
+ fmt.Fprintf(&buf, "\tcase %s:\n\t\treturn %s\n", quote(k), quote(defaultcc[k]))
+ }
+ fmt.Fprintf(&buf, "\t}\n")
+ if cc := defaultcc[""]; cc != "" {
+ fmt.Fprintf(&buf, "\treturn %s\n", quote(cc))
+ } else {
+ clang, gcc := "clang", "gcc"
+ if strings.HasSuffix(name, "CXX") {
+ clang, gcc = "clang++", "g++"
+ }
+ fmt.Fprintf(&buf, "\tswitch goos {\n")
+ fmt.Fprintf(&buf, "\tcase ")
+ for i, os := range clangos {
+ if i > 0 {
+ fmt.Fprintf(&buf, ", ")
+ }
+ fmt.Fprintf(&buf, "%s", quote(os))
+ }
+ fmt.Fprintf(&buf, ":\n")
+ fmt.Fprintf(&buf, "\t\treturn %s\n", quote(clang))
+ fmt.Fprintf(&buf, "\t}\n")
+ fmt.Fprintf(&buf, "\treturn %s\n", quote(gcc))
+ }
+ fmt.Fprintf(&buf, "}\n")
+
+ return buf.String()
+}
+
+// mkzcgo writes zcgo.go for the go/build package:
+//
+// package build
+// const defaultCGO_ENABLED = <CGO_ENABLED>
+//
+// It is invoked to write go/build/zcgo.go.
+func mkzcgo(dir, file string) {
+ var buf strings.Builder
+ writeHeader(&buf)
+ fmt.Fprintf(&buf, "package build\n")
+ fmt.Fprintln(&buf)
+ fmt.Fprintf(&buf, "const defaultCGO_ENABLED = %s\n", quote(os.Getenv("CGO_ENABLED")))
+
+ writefile(buf.String(), file, writeSkipSame)
+}
+
+// mktzdata src/time/tzdata/zzipdata.go:
+//
+// package tzdata
+// const zipdata = "PK..."
+func mktzdata(dir, file string) {
+ zip := readfile(filepath.Join(dir, "../../../lib/time/zoneinfo.zip"))
+
+ var buf strings.Builder
+ writeHeader(&buf)
+ fmt.Fprintf(&buf, "package tzdata\n")
+ fmt.Fprintln(&buf)
+ fmt.Fprintf(&buf, "const zipdata = %s\n", quote(zip))
+
+ writefile(buf.String(), file, writeSkipSame)
+}
+
+// quote is like strconv.Quote but simpler and has output
+// that does not depend on the exact Go bootstrap version.
+func quote(s string) string {
+ const hex = "0123456789abcdef"
+ var out strings.Builder
+ out.WriteByte('"')
+ for i := 0; i < len(s); i++ {
+ c := s[i]
+ if 0x20 <= c && c <= 0x7E && c != '"' && c != '\\' {
+ out.WriteByte(c)
+ } else {
+ out.WriteByte('\\')
+ out.WriteByte('x')
+ out.WriteByte(hex[c>>4])
+ out.WriteByte(hex[c&0xf])
+ }
+ }
+ out.WriteByte('"')
+ return out.String()
+}