// 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.
+// Build toolchain using Go bootstrap version.
//
// 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,
+// invoke the Go bootstrap toolchains go command to build those sources,
// and then copy the binaries back.
package main
"fmt"
"os"
"path/filepath"
- "runtime"
+ "regexp"
"strings"
)
// bootstrapDirs is a list of directories holding code that must be
-// compiled with a Go 1.4 toolchain to produce the bootstrapTargets.
+// compiled with the Go bootstrap toolchain to produce the bootstrapTargets.
// All directories in this list are relative to and must be below $GOROOT/src.
//
-// The list has have two kinds of entries: names beginning with cmd/ with
+// The list has two kinds of entries: names beginning with cmd/ with
// no other slashes, which are commands, and other paths, which are packages
// supporting the commands. Packages in the standard library can be listed
-// if a newer copy needs to be substituted for the Go 1.4 copy when used
-// by the command packages.
+// if a newer copy needs to be substituted for the Go bootstrap copy when used
+// by the command packages. Paths ending with /... automatically
+// include all packages within subdirectories as well.
// These will be imported during bootstrap as bootstrap/name, like bootstrap/math/big.
var bootstrapDirs = []string{
+ "cmp",
"cmd/asm",
- "cmd/asm/internal/arch",
- "cmd/asm/internal/asm",
- "cmd/asm/internal/flags",
- "cmd/asm/internal/lex",
+ "cmd/asm/internal/...",
"cmd/cgo",
"cmd/compile",
- "cmd/compile/internal/amd64",
- "cmd/compile/internal/base",
- "cmd/compile/internal/arm",
- "cmd/compile/internal/arm64",
- "cmd/compile/internal/gc",
- "cmd/compile/internal/ir",
- "cmd/compile/internal/logopt",
- "cmd/compile/internal/mips",
- "cmd/compile/internal/mips64",
- "cmd/compile/internal/ppc64",
- "cmd/compile/internal/riscv64",
- "cmd/compile/internal/s390x",
- "cmd/compile/internal/ssa",
- "cmd/compile/internal/syntax",
- "cmd/compile/internal/types",
- "cmd/compile/internal/x86",
- "cmd/compile/internal/wasm",
+ "cmd/compile/internal/...",
+ "cmd/internal/archive",
"cmd/internal/bio",
"cmd/internal/codesign",
- "cmd/internal/gcprog",
"cmd/internal/dwarf",
"cmd/internal/edit",
+ "cmd/internal/gcprog",
"cmd/internal/goobj",
+ "cmd/internal/notsha256",
+ "cmd/internal/obj/...",
"cmd/internal/objabi",
- "cmd/internal/obj",
- "cmd/internal/obj/arm",
- "cmd/internal/obj/arm64",
- "cmd/internal/obj/mips",
- "cmd/internal/obj/ppc64",
- "cmd/internal/obj/riscv",
- "cmd/internal/obj/s390x",
- "cmd/internal/obj/x86",
- "cmd/internal/obj/wasm",
"cmd/internal/pkgpath",
+ "cmd/internal/quoted",
"cmd/internal/src",
"cmd/internal/sys",
"cmd/link",
- "cmd/link/internal/amd64",
- "cmd/compile/internal/base",
- "cmd/link/internal/arm",
- "cmd/link/internal/arm64",
- "cmd/link/internal/benchmark",
- "cmd/link/internal/ld",
- "cmd/link/internal/loadelf",
- "cmd/link/internal/loader",
- "cmd/link/internal/loadmacho",
- "cmd/link/internal/loadpe",
- "cmd/link/internal/loadxcoff",
- "cmd/link/internal/mips",
- "cmd/link/internal/mips64",
- "cmd/link/internal/ppc64",
- "cmd/link/internal/riscv64",
- "cmd/link/internal/s390x",
- "cmd/link/internal/sym",
- "cmd/link/internal/x86",
+ "cmd/link/internal/...",
"compress/flate",
"compress/zlib",
- "cmd/link/internal/wasm",
"container/heap",
"debug/dwarf",
"debug/elf",
"debug/macho",
"debug/pe",
+ "go/build/constraint",
"go/constant",
+ "go/version",
+ "internal/abi",
+ "internal/coverage",
+ "cmd/internal/cov/covcmd",
+ "internal/bisect",
+ "internal/buildcfg",
+ "internal/goarch",
+ "internal/godebugs",
+ "internal/goexperiment",
+ "internal/goroot",
+ "internal/gover",
"internal/goversion",
+ // internal/lazyregexp is provided by Go 1.17, which permits it to
+ // be imported by other packages in this list, but is not provided
+ // by the Go 1.17 version of gccgo. It's on this list only to
+ // support gccgo, and can be removed if we require gccgo 14 or later.
+ "internal/lazyregexp",
+ "internal/pkgbits",
+ "internal/platform",
+ "internal/profile",
"internal/race",
+ "internal/saferio",
+ "internal/syscall/unix",
+ "internal/types/errors",
"internal/unsafeheader",
"internal/xcoff",
- "math/big",
+ "internal/zstd",
"math/bits",
"sort",
- "strconv",
}
// File prefixes that are ignored by go/build anyway, and cause
var ignorePrefixes = []string{
".",
"_",
+ "#",
}
-// File suffixes that use build tags introduced since Go 1.4.
+// File suffixes that use build tags introduced since Go 1.17.
// These must not be copied into the bootstrap build directory.
// Also ignore test files.
var ignoreSuffixes = []string{
- "_arm64.s",
- "_arm64.go",
- "_riscv64.s",
- "_riscv64.go",
- "_wasm.s",
- "_wasm.go",
"_test.s",
+ "_test.go",
+ // Skip PGO profile. No need to build toolchain1 compiler
+ // with PGO. And as it is not a text file the import path
+ // rewrite will break it.
+ ".pgo",
+}
+
+var tryDirs = []string{
+ "sdk/go1.17",
+ "go1.17",
}
func bootstrapBuildTools() {
goroot_bootstrap := os.Getenv("GOROOT_BOOTSTRAP")
if goroot_bootstrap == "" {
- goroot_bootstrap = pathf("%s/go1.4", os.Getenv("HOME"))
+ home := os.Getenv("HOME")
+ goroot_bootstrap = pathf("%s/go1.4", home)
+ for _, d := range tryDirs {
+ if p := pathf("%s/%s", home, d); isdir(p) {
+ goroot_bootstrap = p
+ }
+ }
}
xprintf("Building Go toolchain1 using %s.\n", goroot_bootstrap)
- mkzbootstrap(pathf("%s/src/cmd/internal/objabi/zbootstrap.go", goroot))
+ mkbuildcfg(pathf("%s/src/internal/buildcfg/zbootstrap.go", goroot))
+ mkobjabi(pathf("%s/src/cmd/internal/objabi/zbootstrap.go", goroot))
// Use $GOROOT/pkg/bootstrap as the bootstrap workspace root.
// We use a subdirectory of $GOROOT/pkg because that's the
xmkdirall(base)
// Copy source code into $GOROOT/pkg/bootstrap and rewrite import paths.
- writefile("module bootstrap\n", pathf("%s/%s", base, "go.mod"), 0)
+ writefile("module bootstrap\ngo 1.20\n", pathf("%s/%s", base, "go.mod"), 0)
for _, dir := range bootstrapDirs {
- src := pathf("%s/src/%s", goroot, dir)
- dst := pathf("%s/%s", base, dir)
- xmkdirall(dst)
- if dir == "cmd/cgo" {
- // Write to src because we need the file both for bootstrap
- // and for later in the main build.
- mkzdefaultcc("", pathf("%s/zdefaultcc.go", src))
- }
- Dir:
- for _, name := range xreaddirfiles(src) {
+ recurse := strings.HasSuffix(dir, "/...")
+ dir = strings.TrimSuffix(dir, "/...")
+ filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
+ if err != nil {
+ fatalf("walking bootstrap dirs failed: %v: %v", path, err)
+ }
+
+ name := filepath.Base(path)
+ src := pathf("%s/src/%s", goroot, path)
+ dst := pathf("%s/%s", base, path)
+
+ if info.IsDir() {
+ if !recurse && path != dir || name == "testdata" {
+ return filepath.SkipDir
+ }
+
+ xmkdirall(dst)
+ if path == "cmd/cgo" {
+ // Write to src because we need the file both for bootstrap
+ // and for later in the main build.
+ mkzdefaultcc("", pathf("%s/zdefaultcc.go", src))
+ mkzdefaultcc("", pathf("%s/zdefaultcc.go", dst))
+ }
+ return nil
+ }
+
for _, pre := range ignorePrefixes {
if strings.HasPrefix(name, pre) {
- continue Dir
+ return nil
}
}
for _, suf := range ignoreSuffixes {
if strings.HasSuffix(name, suf) {
- continue Dir
+ return nil
}
}
- srcFile := pathf("%s/%s", src, name)
- dstFile := pathf("%s/%s", dst, name)
- text := bootstrapRewriteFile(srcFile)
- writefile(text, dstFile, 0)
- }
+
+ text := bootstrapRewriteFile(src)
+ writefile(text, dst, 0)
+ return nil
+ })
}
- // Set up environment for invoking Go 1.4 go command.
- // GOROOT points at Go 1.4 GOROOT,
+ // Set up environment for invoking Go bootstrap toolchains go command.
+ // GOROOT points at Go bootstrap 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.
+ // so that Go bootstrap toolchain 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.
os.Setenv("GOARCH", "")
os.Setenv("GOHOSTARCH", "")
- // Run Go 1.4 to build binaries. Use -gcflags=-l to disable inlining to
- // workaround bugs in Go 1.4's compiler. See discussion thread:
- // https://groups.google.com/d/msg/golang-dev/Ss7mCKsvk8w/Gsq7VYI0AwAJ
+ // Run Go bootstrap to build binaries.
// Use the math_big_pure_go build tag to disable the assembly in math/big
// which may contain unsupported instructions.
- // Note that if we are using Go 1.10 or later as bootstrap, the -gcflags=-l
- // only applies to the final cmd/go binary, but that's OK: if this is Go 1.10
- // or later we don't need to disable inlining to work around bugs in the Go 1.4 compiler.
+ // Use the purego build tag to disable other assembly code,
+ // such as in cmd/internal/notsha256.
cmd := []string{
pathf("%s/bin/go", goroot_bootstrap),
"install",
- "-gcflags=-l",
- "-tags=math_big_pure_go compiler_bootstrap",
+ "-tags=math_big_pure_go compiler_bootstrap purego",
}
if vflag > 0 {
cmd = append(cmd, "-v")
// isUnneededSSARewriteFile reports whether srcFile is a
// src/cmd/compile/internal/ssa/rewriteARCHNAME.go file for an
-// architecture that isn't for the current runtime.GOARCH.
+// architecture that isn't for the given GOARCH.
//
// When unneeded is true archCaps is the rewrite base filename without
// the "rewrite" prefix or ".go" suffix: AMD64, 386, ARM, ARM64, etc.
-func isUnneededSSARewriteFile(srcFile string) (archCaps string, unneeded bool) {
+func isUnneededSSARewriteFile(srcFile, goArch string) (archCaps string, unneeded bool) {
if !strings.Contains(srcFile, ssaRewriteFileSubstring) {
return "", false
}
archCaps = fileArch
fileArch = strings.ToLower(fileArch)
fileArch = strings.TrimSuffix(fileArch, "splitload")
- if fileArch == os.Getenv("GOHOSTARCH") {
- return "", false
- }
- if fileArch == strings.TrimSuffix(runtime.GOARCH, "le") {
+ fileArch = strings.TrimSuffix(fileArch, "latelower")
+ if fileArch == goArch {
return "", false
}
- if fileArch == strings.TrimSuffix(os.Getenv("GOARCH"), "le") {
+ if fileArch == strings.TrimSuffix(goArch, "le") {
return "", false
}
return archCaps, true
func bootstrapRewriteFile(srcFile string) string {
// During bootstrap, generate dummy rewrite files for
// irrelevant architectures. We only need to build a bootstrap
- // binary that works for the current runtime.GOARCH.
+ // binary that works for the current gohostarch.
// This saves 6+ seconds of bootstrap.
- if archCaps, ok := isUnneededSSARewriteFile(srcFile); ok {
- return fmt.Sprintf(`// Code generated by go tool dist; DO NOT EDIT.
-
-package ssa
+ if archCaps, ok := isUnneededSSARewriteFile(srcFile, gohostarch); ok {
+ return fmt.Sprintf(`%spackage ssa
func rewriteValue%s(v *Value) bool { panic("unused during bootstrap") }
func rewriteBlock%s(b *Block) bool { panic("unused during bootstrap") }
-`, archCaps, archCaps)
+`, generatedHeader, archCaps, archCaps)
}
return bootstrapFixImports(srcFile)
}
func bootstrapFixImports(srcFile string) string {
- lines := strings.SplitAfter(readfile(srcFile), "\n")
+ text := readfile(srcFile)
+ if !strings.Contains(srcFile, "/cmd/") && !strings.Contains(srcFile, `\cmd\`) {
+ text = regexp.MustCompile(`\bany\b`).ReplaceAllString(text, "interface{}")
+ }
+ lines := strings.SplitAfter(text, "\n")
inBlock := false
for i, line := range lines {
if strings.HasPrefix(line, "import (") {
continue
}
if strings.HasPrefix(line, `import "`) || strings.HasPrefix(line, `import . "`) ||
- inBlock && (strings.HasPrefix(line, "\t\"") || strings.HasPrefix(line, "\t. \"")) {
+ inBlock && (strings.HasPrefix(line, "\t\"") || strings.HasPrefix(line, "\t. \"") || strings.HasPrefix(line, "\texec \"") || strings.HasPrefix(line, "\trtabi \"")) {
line = strings.Replace(line, `"cmd/`, `"bootstrap/cmd/`, -1)
for _, dir := range bootstrapDirs {
if strings.HasPrefix(dir, "cmd/") {
}
}
- lines[0] = "// Code generated by go tool dist; DO NOT EDIT.\n// This is a bootstrap copy of " + srcFile + "\n\n//line " + srcFile + ":1\n" + lines[0]
+ lines[0] = generatedHeader + "// This is a bootstrap copy of " + srcFile + "\n\n//line " + srcFile + ":1\n" + lines[0]
return strings.Join(lines, "")
}