1 // Copyright 2015 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.
5 // Build toolchain using Go 1.4.
7 // The general strategy is to copy the source files we need into
8 // a new GOPATH workspace, adjust import paths appropriately,
9 // invoke the Go 1.4 go command to build those sources,
10 // and then copy the binaries back.
19 // bootstrapDirs is a list of directories holding code that must be
20 // compiled with a Go 1.4 toolchain to produce the bootstrapTargets.
21 // All directories in this list are relative to and must be below $GOROOT/src/cmd.
22 // The list is assumed to have two kinds of entries: names without slashes,
23 // which are commands, and entries beginning with internal/, which are
24 // packages supporting the commands.
25 var bootstrapDirs = []string{
32 "compile/internal/amd64",
33 "compile/internal/arm",
34 "compile/internal/arm64",
35 "compile/internal/big",
36 "compile/internal/gc",
37 "compile/internal/ppc64",
38 "compile/internal/ssa",
39 "compile/internal/x86",
48 "link/internal/amd64",
50 "link/internal/arm64",
52 "link/internal/ppc64",
60 func bootstrapBuildTools() {
61 goroot_bootstrap := os.Getenv("GOROOT_BOOTSTRAP")
62 if goroot_bootstrap == "" {
63 goroot_bootstrap = pathf("%s/go1.4", os.Getenv("HOME"))
65 xprintf("##### Building Go toolchain using %s.\n", goroot_bootstrap)
67 mkzbootstrap(pathf("%s/src/cmd/internal/obj/zbootstrap.go", goroot))
69 // Use $GOROOT/pkg/bootstrap as the bootstrap workspace root.
70 // We use a subdirectory of $GOROOT/pkg because that's the
71 // space within $GOROOT where we store all generated objects.
72 // We could use a temporary directory outside $GOROOT instead,
73 // but it is easier to debug on failure if the files are in a known location.
74 workspace := pathf("%s/pkg/bootstrap", goroot)
76 base := pathf("%s/src/bootstrap", workspace)
79 // Copy source code into $GOROOT/pkg/bootstrap and rewrite import paths.
80 for _, dir := range bootstrapDirs {
81 src := pathf("%s/src/cmd/%s", goroot, dir)
82 dst := pathf("%s/%s", base, dir)
84 for _, name := range xreaddirfiles(src) {
85 srcFile := pathf("%s/%s", src, name)
86 text := readfile(srcFile)
87 text = bootstrapFixImports(text, srcFile)
88 writefile(text, pathf("%s/%s", dst, name), 0)
92 // Set up environment for invoking Go 1.4 go command.
93 // GOROOT points at Go 1.4 GOROOT,
94 // GOPATH points at our bootstrap workspace,
95 // GOBIN is empty, so that binaries are installed to GOPATH/bin,
96 // and GOOS, GOHOSTOS, GOARCH, and GOHOSTOS are empty,
97 // so that Go 1.4 builds whatever kind of binary it knows how to build.
98 // Restore GOROOT, GOPATH, and GOBIN when done.
99 // Don't bother with GOOS, GOHOSTOS, GOARCH, and GOHOSTARCH,
100 // because setup will take care of those when bootstrapBuildTools returns.
102 defer os.Setenv("GOROOT", os.Getenv("GOROOT"))
103 os.Setenv("GOROOT", goroot_bootstrap)
105 defer os.Setenv("GOPATH", os.Getenv("GOPATH"))
106 os.Setenv("GOPATH", workspace)
108 defer os.Setenv("GOBIN", os.Getenv("GOBIN"))
109 os.Setenv("GOBIN", "")
111 os.Setenv("GOOS", "")
112 os.Setenv("GOHOSTOS", "")
113 os.Setenv("GOARCH", "")
114 os.Setenv("GOHOSTARCH", "")
116 // Run Go 1.4 to build binaries.
117 run(workspace, ShowOutput|CheckExit, pathf("%s/bin/go", goroot_bootstrap), "install", "-v", "bootstrap/...")
119 // Copy binaries into tool binary directory.
120 for _, name := range bootstrapDirs {
121 if !strings.Contains(name, "/") {
122 copyfile(pathf("%s/%s%s", tooldir, name, exe), pathf("%s/bin/%s%s", workspace, name, exe), writeExec)
129 func bootstrapFixImports(text, srcFile string) string {
130 lines := strings.SplitAfter(text, "\n")
132 for i, line := range lines {
133 if strings.HasPrefix(line, "import (") {
137 if inBlock && strings.HasPrefix(line, ")") {
141 if strings.HasPrefix(line, `import "`) || strings.HasPrefix(line, `import . "`) ||
142 inBlock && (strings.HasPrefix(line, "\t\"") || strings.HasPrefix(line, "\t. \"")) {
143 lines[i] = strings.Replace(line, `"cmd/`, `"bootstrap/`, -1)
147 lines[0] = "// Do not edit. Bootstrap copy of " + srcFile + "\n\n//line " + srcFile + ":1\n" + lines[0]
149 return strings.Join(lines, "")