oldgoarch string
oldgochar string
slash string
+ exe string
defaultcc string
defaultcflags string
defaultldflags string
ldargs = splitfields(defaultldflags)
}
- islib := strings.HasPrefix(dir, "lib") || dir == "cmd/gc"
- ispkg := !islib && !strings.HasPrefix(dir, "cmd/")
- isgo := ispkg || dir == "cmd/go" || dir == "cmd/cgo"
+ isgo := true
+ ispkg := !strings.HasPrefix(dir, "cmd/") || strings.HasPrefix(dir, "cmd/internal/")
+ islib := false
- exe := ""
- if gohostos == "windows" {
- exe = ".exe"
+ // Legacy C exceptions.
+ switch dir {
+ case "lib9", "libbio", "liblink", "cmd/gc":
+ islib = true
+ isgo = false
+ case "cmd/5a", "cmd/5g", "cmd/5l",
+ "cmd/6a", "cmd/6g", "cmd/6l",
+ "cmd/8a", "cmd/8g", "cmd/8l",
+ "cmd/9a", "cmd/9g", "cmd/9l":
+ isgo = false
}
// Start final link command line.
}
// buildorder records the order of builds for the 'go bootstrap' command.
+// The Go packages and commands must be in dependency order,
+// maintained by hand, but the order doesn't change often.
var buildorder = []string{
+ // Legacy C programs.
"lib9",
"libbio",
"liblink",
"cmd/%sa",
"cmd/%sg",
- // The dependency order here was copied from a buildscript
- // back when there were build scripts. Will have to
- // be maintained by hand, but shouldn't change very
- // often.
+ // Go libraries and programs for bootstrap.
"runtime",
"errors",
"sync/atomic",
"reflect",
"fmt",
"encoding",
+ "encoding/binary",
"encoding/json",
"flag",
"path/filepath",
"text/template",
"go/doc",
"go/build",
+ "cmd/internal/obj",
+ "cmd/internal/obj/x86",
+ "cmd/objwriter",
"cmd/go",
}
setup()
+ bootstrapBuildTools()
+
// For the main bootstrap, building for host os/arch.
oldgoos = goos
oldgoarch = goarch
os.Setenv("GOARCH", goarch)
os.Setenv("GOOS", goos)
+ // TODO(rsc): Enable when appropriate.
+ // This step is only needed if we believe that the Go compiler built from Go 1.4
+ // will produce different object files than the Go compiler built from itself.
+ // In the absence of bugs, that should not happen.
+ // And if there are bugs, they're more likely in the current development tree
+ // 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" {
+ 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") {
--- /dev/null
+// Copyright 2015 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.
+
+// Build toolchain using Go 1.4.
+//
+// The general strategy is to copy the source files we need into
+// a new GOPATH workspace, adjust import paths appropriately,
+// invoke the Go 1.4 go command to build those sources,
+// and then copy the binaries back.
+
+package main
+
+import (
+ "os"
+ "strings"
+)
+
+// bootstrapDirs is a list of directories holding code that must be
+// compiled with a Go 1.4 toolchain to produce the bootstrapTargets.
+// All directories in this list are relative to and must be below $GOROOT/src/cmd.
+// The list is assumed to have two kinds of entries: names without slashes,
+// which are commands, and entries beginning with internal/, which are
+// packages supporting the commands.
+var bootstrapDirs = []string{
+ "internal/obj",
+ "internal/obj/x86",
+ "objwriter",
+}
+
+func bootstrapBuildTools() {
+ goroot_bootstrap := os.Getenv("GOROOT_BOOTSTRAP")
+ if goroot_bootstrap == "" {
+ goroot_bootstrap = pathf("%s/go1.4", os.Getenv("HOME"))
+ }
+ xprintf("##### Building Go toolchain using %s.\n", goroot_bootstrap)
+
+ // Use $GOROOT/pkg/bootstrap as the bootstrap workspace root.
+ // We use a subdirectory of $GOROOT/pkg because that's the
+ // space within $GOROOT where we store all generated objects.
+ // We could use a temporary directory outside $GOROOT instead,
+ // but it is easier to debug on failure if the files are in a known location.
+ workspace := pathf("%s/pkg/bootstrap", goroot)
+ xremoveall(workspace)
+ base := pathf("%s/src/bootstrap", workspace)
+ xmkdirall(base)
+
+ // Copy source code into $GOROOT/pkg/bootstrap and rewrite import paths.
+ for _, dir := range bootstrapDirs {
+ src := pathf("%s/src/cmd/%s", goroot, dir)
+ dst := pathf("%s/%s", base, dir)
+ xmkdirall(dst)
+ for _, name := range xreaddirfiles(src) {
+ srcFile := pathf("%s/%s", src, name)
+ text := readfile(srcFile)
+ text = bootstrapFixImports(text, srcFile)
+ writefile(text, pathf("%s/%s", dst, name), 0)
+ }
+ }
+
+ // Set up environment for invoking Go 1.4 go command.
+ // GOROOT points at Go 1.4 GOROOT,
+ // GOPATH points at our bootstrap workspace,
+ // GOBIN is empty, so that binaries are installed to GOPATH/bin,
+ // and GOOS, GOHOSTOS, GOARCH, and GOHOSTOS are empty,
+ // so that Go 1.4 builds whatever kind of binary it knows how to build.
+ // Restore GOROOT, GOPATH, and GOBIN when done.
+ // Don't bother with GOOS, GOHOSTOS, GOARCH, and GOHOSTARCH,
+ // because setup will take care of those when bootstrapBuildTools returns.
+
+ defer os.Setenv("GOROOT", os.Getenv("GOROOT"))
+ os.Setenv("GOROOT", goroot_bootstrap)
+
+ defer os.Setenv("GOPATH", os.Getenv("GOPATH"))
+ os.Setenv("GOPATH", workspace)
+
+ defer os.Setenv("GOBIN", os.Getenv("GOBIN"))
+ os.Setenv("GOBIN", "")
+
+ os.Setenv("GOOS", "")
+ os.Setenv("GOHOSTOS", "")
+ os.Setenv("GOARCH", "")
+ os.Setenv("GOHOSTARCH", "")
+
+ // Run Go 1.4 to build binaries.
+ run(workspace, ShowOutput|CheckExit, pathf("%s/bin/go", goroot_bootstrap), "install", "-v", "bootstrap/...")
+
+ // Copy binaries into tool binary directory.
+ for _, name := range bootstrapDirs {
+ if !strings.Contains(name, "/") {
+ copyfile(pathf("%s/%s%s", tooldir, name, exe), pathf("%s/bin/%s%s", workspace, name, exe), 1)
+ }
+ }
+
+ xprintf("\n")
+}
+
+func bootstrapFixImports(text, srcFile string) string {
+ lines := strings.SplitAfter(text, "\n")
+ inBlock := false
+ for i, line := range lines {
+ if strings.HasPrefix(line, "import (") {
+ inBlock = true
+ continue
+ }
+ if inBlock && strings.HasPrefix(line, ")") {
+ inBlock = false
+ continue
+ }
+ if strings.HasPrefix(line, "import \"") || inBlock && strings.HasPrefix(line, "\t\"") {
+ lines[i] = strings.Replace(line, `"cmd/internal/`, `"bootstrap/internal/`, -1)
+ }
+ }
+
+ lines[0] = "// Do not edit. Bootstrap copy of " + srcFile + "\n\n" + lines[0]
+
+ return strings.Join(lines, "")
+}