Commit e247f465 authored by Russ Cox's avatar Russ Cox

cmd/dist: read dependencies from source files

I do not remember why we require deps.go to have a hard-coded
copy of the dependency information for cmd/go, when we can
read it from the source files instead. The answer probably involves
cmd/dist once being a C program.

In any event, stop doing that, which will eliminate the builder-only
failures in the builder-only deps test.

Change-Id: I0abd384c47401940ca08427b5be544812edcbe7f
Reviewed-on: https://go-review.googlesource.com/76021
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: default avatarDavid Crawshaw <crawshaw@golang.org>
parent 60a3c95d
......@@ -533,15 +533,35 @@ var gentab = []struct {
// installed maps from a dir name (as given to install) to a chan
// closed when the dir's package is installed.
var installed = make(map[string]chan struct{})
var installedMu sync.Mutex
// install installs the library, package, or binary associated with dir,
// which is relative to $GOROOT/src.
func install(dir string) {
if ch, ok := installed[dir]; ok {
defer close(ch)
<-startInstall(dir)
}
func startInstall(dir string) chan struct{} {
installedMu.Lock()
ch := installed[dir]
if ch == nil {
ch = make(chan struct{})
installed[dir] = ch
go runInstall(dir, ch)
}
for _, dep := range builddeps[dir] {
<-installed[dep]
installedMu.Unlock()
return ch
}
// runInstall installs the library, package, or binary associated with dir,
// which is relative to $GOROOT/src.
func runInstall(dir string, ch chan struct{}) {
if dir == "net" || dir == "os/user" || dir == "crypto/x509" {
fatalf("go_bootstrap cannot depend on cgo package %s", dir)
}
defer close(ch)
if dir == "unsafe" {
return
}
if vflag > 0 {
......@@ -660,7 +680,7 @@ func install(dir string) {
}
// For package runtime, copy some files into the work space.
if dir == "runtime" || strings.HasPrefix(dir, "runtime/internal/") {
if dir == "runtime" {
xmkdirall(pathf("%s/pkg/include", goroot))
// For use by assembly and C files.
copyfile(pathf("%s/pkg/include/textflag.h", goroot),
......@@ -700,6 +720,18 @@ func install(dir string) {
built:
}
// Make sure dependencies are installed.
var deps []string
for _, p := range gofiles {
deps = append(deps, readimports(p)...)
}
for _, dir1 := range deps {
startInstall(dir1)
}
for _, dir1 := range deps {
install(dir1)
}
if goos != gohostos || goarch != gohostarch {
// We've generated the right files; the go command can do the build.
if vflag > 1 {
......@@ -906,28 +938,21 @@ func dopack(dst, src string, extra []string) {
writefile(bdst.String(), dst, 0)
}
// builddeps records the build dependencies for the 'go bootstrap' command.
// It is a map[string][]string and generated by mkdeps.bash into deps.go.
// buildlist is the list of directories being built, sorted by name.
var buildlist = makeBuildlist()
func makeBuildlist() []string {
var all []string
for dir := range builddeps {
all = append(all, dir)
}
sort.Strings(all)
return all
}
var runtimegen = []string{
"zaexperiment.h",
"zversion.go",
}
// cleanlist is a list of packages with generated files and commands.
var cleanlist = []string{
"runtime/internal/sys",
"cmd/cgo",
"cmd/go/internal/cfg",
"go/build",
}
func clean() {
for _, name := range buildlist {
for _, name := range cleanlist {
path := pathf("%s/src/%s", goroot, name)
// Remove generated files.
for _, elem := range xreaddir(path) {
......@@ -1110,13 +1135,8 @@ func cmdbootstrap() {
timelog("build", "go_bootstrap")
xprintf("Building Go bootstrap cmd/go (go_bootstrap) using Go toolchain1.\n")
for _, dir := range buildlist {
installed[dir] = make(chan struct{})
}
for _, dir := range buildlist {
go install(dir)
}
<-installed["cmd/go"]
install("runtime") // dependency not visible in sources; also sets up textflag.h
install("cmd/go")
if vflag > 0 {
xprintf("\n")
}
......
// Code generated by mkdeps.bash; DO NOT EDIT.
package main
var builddeps = map[string][]string{
"bufio": {
"bytes", // bufio
"errors", // bufio
"io", // bufio
"unicode/utf8", // bufio
},
"bytes": {
"errors", // bytes
"internal/cpu", // bytes
"io", // bytes
"unicode", // bytes
"unicode/utf8", // bytes
},
"cmd/go": {
"cmd/go/internal/base", // cmd/go
"cmd/go/internal/bug", // cmd/go
"cmd/go/internal/cfg", // cmd/go
"cmd/go/internal/clean", // cmd/go
"cmd/go/internal/doc", // cmd/go
"cmd/go/internal/envcmd", // cmd/go
"cmd/go/internal/fix", // cmd/go
"cmd/go/internal/fmtcmd", // cmd/go
"cmd/go/internal/generate", // cmd/go
"cmd/go/internal/get", // cmd/go
"cmd/go/internal/help", // cmd/go
"cmd/go/internal/list", // cmd/go
"cmd/go/internal/run", // cmd/go
"cmd/go/internal/test", // cmd/go
"cmd/go/internal/tool", // cmd/go
"cmd/go/internal/version", // cmd/go
"cmd/go/internal/vet", // cmd/go
"cmd/go/internal/work", // cmd/go
"flag", // cmd/go
"fmt", // cmd/go
"log", // cmd/go
"os", // cmd/go
"path/filepath", // cmd/go
"runtime", // cmd/go
"strings", // cmd/go
},
"cmd/go/internal/base": {
"bytes", // cmd/go/internal/base
"cmd/go/internal/cfg", // cmd/go/internal/base
"cmd/go/internal/str", // cmd/go/internal/base
"errors", // cmd/go/internal/base
"flag", // cmd/go/internal/base
"fmt", // cmd/go/internal/base
"go/build", // cmd/go/internal/base
"go/scanner", // cmd/go/internal/base
"log", // cmd/go/internal/base
"os", // cmd/go/internal/base
"os/exec", // cmd/go/internal/base
"os/signal", // cmd/go/internal/base
"path/filepath", // cmd/go/internal/base
"runtime", // cmd/go/internal/base
"strings", // cmd/go/internal/base
"sync", // cmd/go/internal/base
"syscall", // cmd/go/internal/base
},
"cmd/go/internal/bug": {
"bytes", // cmd/go/internal/bug
"cmd/go/internal/base", // cmd/go/internal/bug
"cmd/go/internal/cfg", // cmd/go/internal/bug
"cmd/go/internal/envcmd", // cmd/go/internal/bug
"cmd/go/internal/web", // cmd/go/internal/bug
"fmt", // cmd/go/internal/bug
"io", // cmd/go/internal/bug
"io/ioutil", // cmd/go/internal/bug
"os", // cmd/go/internal/bug
"os/exec", // cmd/go/internal/bug
"path/filepath", // cmd/go/internal/bug
"regexp", // cmd/go/internal/bug
"runtime", // cmd/go/internal/bug
"strings", // cmd/go/internal/bug
},
"cmd/go/internal/cache": {
"bytes", // cmd/go/internal/cache
"cmd/go/internal/base", // cmd/go/internal/cache
"crypto/sha256", // cmd/go/internal/cache
"encoding/hex", // cmd/go/internal/cache
"errors", // cmd/go/internal/cache
"fmt", // cmd/go/internal/cache
"hash", // cmd/go/internal/cache
"io", // cmd/go/internal/cache
"io/ioutil", // cmd/go/internal/cache
"os", // cmd/go/internal/cache
"path/filepath", // cmd/go/internal/cache
"runtime", // cmd/go/internal/cache
"strconv", // cmd/go/internal/cache
"strings", // cmd/go/internal/cache
"sync", // cmd/go/internal/cache
"time", // cmd/go/internal/cache
},
"cmd/go/internal/cfg": {
"cmd/internal/objabi", // cmd/go/internal/cfg
"fmt", // cmd/go/internal/cfg
"go/build", // cmd/go/internal/cfg
"os", // cmd/go/internal/cfg
"path/filepath", // cmd/go/internal/cfg
"runtime", // cmd/go/internal/cfg
},
"cmd/go/internal/clean": {
"cmd/go/internal/base", // cmd/go/internal/clean
"cmd/go/internal/cache", // cmd/go/internal/clean
"cmd/go/internal/cfg", // cmd/go/internal/clean
"cmd/go/internal/load", // cmd/go/internal/clean
"cmd/go/internal/work", // cmd/go/internal/clean
"fmt", // cmd/go/internal/clean
"io/ioutil", // cmd/go/internal/clean
"os", // cmd/go/internal/clean
"path/filepath", // cmd/go/internal/clean
"strings", // cmd/go/internal/clean
},
"cmd/go/internal/cmdflag": {
"cmd/go/internal/base", // cmd/go/internal/cmdflag
"flag", // cmd/go/internal/cmdflag
"fmt", // cmd/go/internal/cmdflag
"os", // cmd/go/internal/cmdflag
"strconv", // cmd/go/internal/cmdflag
"strings", // cmd/go/internal/cmdflag
},
"cmd/go/internal/doc": {
"cmd/go/internal/base", // cmd/go/internal/doc
"cmd/go/internal/cfg", // cmd/go/internal/doc
},
"cmd/go/internal/envcmd": {
"cmd/go/internal/base", // cmd/go/internal/envcmd
"cmd/go/internal/cache", // cmd/go/internal/envcmd
"cmd/go/internal/cfg", // cmd/go/internal/envcmd
"cmd/go/internal/load", // cmd/go/internal/envcmd
"cmd/go/internal/work", // cmd/go/internal/envcmd
"encoding/json", // cmd/go/internal/envcmd
"fmt", // cmd/go/internal/envcmd
"os", // cmd/go/internal/envcmd
"runtime", // cmd/go/internal/envcmd
"strings", // cmd/go/internal/envcmd
},
"cmd/go/internal/fix": {
"cmd/go/internal/base", // cmd/go/internal/fix
"cmd/go/internal/cfg", // cmd/go/internal/fix
"cmd/go/internal/load", // cmd/go/internal/fix
"cmd/go/internal/str", // cmd/go/internal/fix
},
"cmd/go/internal/fmtcmd": {
"cmd/go/internal/base", // cmd/go/internal/fmtcmd
"cmd/go/internal/cfg", // cmd/go/internal/fmtcmd
"cmd/go/internal/load", // cmd/go/internal/fmtcmd
"cmd/go/internal/str", // cmd/go/internal/fmtcmd
"os", // cmd/go/internal/fmtcmd
"path/filepath", // cmd/go/internal/fmtcmd
"runtime", // cmd/go/internal/fmtcmd
"strings", // cmd/go/internal/fmtcmd
"sync", // cmd/go/internal/fmtcmd
},
"cmd/go/internal/generate": {
"bufio", // cmd/go/internal/generate
"bytes", // cmd/go/internal/generate
"cmd/go/internal/base", // cmd/go/internal/generate
"cmd/go/internal/cfg", // cmd/go/internal/generate
"cmd/go/internal/load", // cmd/go/internal/generate
"cmd/go/internal/work", // cmd/go/internal/generate
"fmt", // cmd/go/internal/generate
"io", // cmd/go/internal/generate
"log", // cmd/go/internal/generate
"os", // cmd/go/internal/generate
"os/exec", // cmd/go/internal/generate
"path/filepath", // cmd/go/internal/generate
"regexp", // cmd/go/internal/generate
"strconv", // cmd/go/internal/generate
"strings", // cmd/go/internal/generate
},
"cmd/go/internal/get": {
"bytes", // cmd/go/internal/get
"cmd/go/internal/base", // cmd/go/internal/get
"cmd/go/internal/cfg", // cmd/go/internal/get
"cmd/go/internal/load", // cmd/go/internal/get
"cmd/go/internal/str", // cmd/go/internal/get
"cmd/go/internal/web", // cmd/go/internal/get
"cmd/go/internal/work", // cmd/go/internal/get
"encoding/json", // cmd/go/internal/get
"encoding/xml", // cmd/go/internal/get
"errors", // cmd/go/internal/get
"fmt", // cmd/go/internal/get
"go/build", // cmd/go/internal/get
"internal/singleflight", // cmd/go/internal/get
"io", // cmd/go/internal/get
"log", // cmd/go/internal/get
"net/url", // cmd/go/internal/get
"os", // cmd/go/internal/get
"os/exec", // cmd/go/internal/get
"path/filepath", // cmd/go/internal/get
"regexp", // cmd/go/internal/get
"runtime", // cmd/go/internal/get
"strings", // cmd/go/internal/get
"sync", // cmd/go/internal/get
},
"cmd/go/internal/help": {
"bufio", // cmd/go/internal/help
"bytes", // cmd/go/internal/help
"cmd/go/internal/base", // cmd/go/internal/help
"fmt", // cmd/go/internal/help
"io", // cmd/go/internal/help
"os", // cmd/go/internal/help
"strings", // cmd/go/internal/help
"text/template", // cmd/go/internal/help
"unicode", // cmd/go/internal/help
"unicode/utf8", // cmd/go/internal/help
},
"cmd/go/internal/list": {
"bufio", // cmd/go/internal/list
"cmd/go/internal/base", // cmd/go/internal/list
"cmd/go/internal/cfg", // cmd/go/internal/list
"cmd/go/internal/load", // cmd/go/internal/list
"cmd/go/internal/work", // cmd/go/internal/list
"encoding/json", // cmd/go/internal/list
"go/build", // cmd/go/internal/list
"io", // cmd/go/internal/list
"os", // cmd/go/internal/list
"strings", // cmd/go/internal/list
"text/template", // cmd/go/internal/list
},
"cmd/go/internal/load": {
"cmd/go/internal/base", // cmd/go/internal/load
"cmd/go/internal/cfg", // cmd/go/internal/load
"cmd/go/internal/str", // cmd/go/internal/load
"fmt", // cmd/go/internal/load
"go/build", // cmd/go/internal/load
"go/token", // cmd/go/internal/load
"io/ioutil", // cmd/go/internal/load
"log", // cmd/go/internal/load
"os", // cmd/go/internal/load
"path", // cmd/go/internal/load
"path/filepath", // cmd/go/internal/load
"regexp", // cmd/go/internal/load
"sort", // cmd/go/internal/load
"strings", // cmd/go/internal/load
"unicode", // cmd/go/internal/load
},
"cmd/go/internal/run": {
"cmd/go/internal/base", // cmd/go/internal/run
"cmd/go/internal/cfg", // cmd/go/internal/run
"cmd/go/internal/load", // cmd/go/internal/run
"cmd/go/internal/str", // cmd/go/internal/run
"cmd/go/internal/work", // cmd/go/internal/run
"fmt", // cmd/go/internal/run
"os", // cmd/go/internal/run
"strings", // cmd/go/internal/run
},
"cmd/go/internal/str": {
"bytes", // cmd/go/internal/str
"fmt", // cmd/go/internal/str
"unicode", // cmd/go/internal/str
"unicode/utf8", // cmd/go/internal/str
},
"cmd/go/internal/test": {
"bytes", // cmd/go/internal/test
"cmd/go/internal/base", // cmd/go/internal/test
"cmd/go/internal/cache", // cmd/go/internal/test
"cmd/go/internal/cfg", // cmd/go/internal/test
"cmd/go/internal/cmdflag", // cmd/go/internal/test
"cmd/go/internal/load", // cmd/go/internal/test
"cmd/go/internal/str", // cmd/go/internal/test
"cmd/go/internal/work", // cmd/go/internal/test
"errors", // cmd/go/internal/test
"flag", // cmd/go/internal/test
"fmt", // cmd/go/internal/test
"go/ast", // cmd/go/internal/test
"go/build", // cmd/go/internal/test
"go/doc", // cmd/go/internal/test
"go/parser", // cmd/go/internal/test
"go/token", // cmd/go/internal/test
"io", // cmd/go/internal/test
"os", // cmd/go/internal/test
"os/exec", // cmd/go/internal/test
"path", // cmd/go/internal/test
"path/filepath", // cmd/go/internal/test
"regexp", // cmd/go/internal/test
"sort", // cmd/go/internal/test
"strings", // cmd/go/internal/test
"text/template", // cmd/go/internal/test
"time", // cmd/go/internal/test
"unicode", // cmd/go/internal/test
"unicode/utf8", // cmd/go/internal/test
},
"cmd/go/internal/tool": {
"cmd/go/internal/base", // cmd/go/internal/tool
"cmd/go/internal/cfg", // cmd/go/internal/tool
"fmt", // cmd/go/internal/tool
"os", // cmd/go/internal/tool
"os/exec", // cmd/go/internal/tool
"sort", // cmd/go/internal/tool
"strings", // cmd/go/internal/tool
},
"cmd/go/internal/version": {
"cmd/go/internal/base", // cmd/go/internal/version
"fmt", // cmd/go/internal/version
"runtime", // cmd/go/internal/version
},
"cmd/go/internal/vet": {
"cmd/go/internal/base", // cmd/go/internal/vet
"cmd/go/internal/cmdflag", // cmd/go/internal/vet
"cmd/go/internal/load", // cmd/go/internal/vet
"cmd/go/internal/work", // cmd/go/internal/vet
"flag", // cmd/go/internal/vet
"fmt", // cmd/go/internal/vet
"os", // cmd/go/internal/vet
"strings", // cmd/go/internal/vet
},
"cmd/go/internal/web": {
"errors", // cmd/go/internal/web
"io", // cmd/go/internal/web
},
"cmd/go/internal/work": {
"bufio", // cmd/go/internal/work
"bytes", // cmd/go/internal/work
"cmd/go/internal/base", // cmd/go/internal/work
"cmd/go/internal/cache", // cmd/go/internal/work
"cmd/go/internal/cfg", // cmd/go/internal/work
"cmd/go/internal/load", // cmd/go/internal/work
"cmd/go/internal/str", // cmd/go/internal/work
"cmd/internal/buildid", // cmd/go/internal/work
"container/heap", // cmd/go/internal/work
"crypto/sha1", // cmd/go/internal/work
"debug/elf", // cmd/go/internal/work
"encoding/json", // cmd/go/internal/work
"errors", // cmd/go/internal/work
"flag", // cmd/go/internal/work
"fmt", // cmd/go/internal/work
"go/build", // cmd/go/internal/work
"io", // cmd/go/internal/work
"io/ioutil", // cmd/go/internal/work
"log", // cmd/go/internal/work
"os", // cmd/go/internal/work
"os/exec", // cmd/go/internal/work
"path", // cmd/go/internal/work
"path/filepath", // cmd/go/internal/work
"regexp", // cmd/go/internal/work
"runtime", // cmd/go/internal/work
"strconv", // cmd/go/internal/work
"strings", // cmd/go/internal/work
"sync", // cmd/go/internal/work
},
"cmd/internal/buildid": {
"bytes", // cmd/internal/buildid
"crypto/sha256", // cmd/internal/buildid
"debug/elf", // cmd/internal/buildid
"debug/macho", // cmd/internal/buildid
"encoding/binary", // cmd/internal/buildid
"fmt", // cmd/internal/buildid
"io", // cmd/internal/buildid
"os", // cmd/internal/buildid
"strconv", // cmd/internal/buildid
},
"cmd/internal/objabi": {
"flag", // cmd/internal/objabi
"fmt", // cmd/internal/objabi
"log", // cmd/internal/objabi
"os", // cmd/internal/objabi
"path/filepath", // cmd/internal/objabi
"runtime", // cmd/internal/objabi
"strconv", // cmd/internal/objabi
"strings", // cmd/internal/objabi
},
"compress/flate": {
"bufio", // compress/flate
"fmt", // compress/flate
"io", // compress/flate
"math", // compress/flate
"math/bits", // compress/flate
"sort", // compress/flate
"strconv", // compress/flate
"sync", // compress/flate
},
"compress/zlib": {
"bufio", // compress/zlib
"compress/flate", // compress/zlib
"errors", // compress/zlib
"fmt", // compress/zlib
"hash", // compress/zlib
"hash/adler32", // compress/zlib
"io", // compress/zlib
},
"container/heap": {
"sort", // container/heap
},
"context": {
"errors", // context
"fmt", // context
"reflect", // context
"sync", // context
"time", // context
},
"crypto": {
"hash", // crypto
"io", // crypto
"strconv", // crypto
},
"crypto/sha1": {
"crypto", // crypto/sha1
"errors", // crypto/sha1
"hash", // crypto/sha1
"internal/cpu", // crypto/sha1
},
"crypto/sha256": {
"crypto", // crypto/sha256
"errors", // crypto/sha256
"hash", // crypto/sha256
"internal/cpu", // crypto/sha256
},
"debug/dwarf": {
"encoding/binary", // debug/dwarf
"errors", // debug/dwarf
"fmt", // debug/dwarf
"io", // debug/dwarf
"path", // debug/dwarf
"sort", // debug/dwarf
"strconv", // debug/dwarf
"strings", // debug/dwarf
},
"debug/elf": {
"bytes", // debug/elf
"compress/zlib", // debug/elf
"debug/dwarf", // debug/elf
"encoding/binary", // debug/elf
"errors", // debug/elf
"fmt", // debug/elf
"io", // debug/elf
"os", // debug/elf
"strconv", // debug/elf
"strings", // debug/elf
},
"debug/macho": {
"bytes", // debug/macho
"debug/dwarf", // debug/macho
"encoding/binary", // debug/macho
"fmt", // debug/macho
"io", // debug/macho
"os", // debug/macho
"strconv", // debug/macho
},
"encoding": {
"runtime", // encoding
},
"encoding/base64": {
"encoding/binary", // encoding/base64
"io", // encoding/base64
"strconv", // encoding/base64
},
"encoding/binary": {
"errors", // encoding/binary
"io", // encoding/binary
"math", // encoding/binary
"reflect", // encoding/binary
},
"encoding/hex": {
"bytes", // encoding/hex
"errors", // encoding/hex
"fmt", // encoding/hex
"io", // encoding/hex
},
"encoding/json": {
"bytes", // encoding/json
"encoding", // encoding/json
"encoding/base64", // encoding/json
"errors", // encoding/json
"fmt", // encoding/json
"io", // encoding/json
"math", // encoding/json
"reflect", // encoding/json
"runtime", // encoding/json
"sort", // encoding/json
"strconv", // encoding/json
"strings", // encoding/json
"sync", // encoding/json
"sync/atomic", // encoding/json
"unicode", // encoding/json
"unicode/utf16", // encoding/json
"unicode/utf8", // encoding/json
},
"encoding/xml": {
"bufio", // encoding/xml
"bytes", // encoding/xml
"encoding", // encoding/xml
"errors", // encoding/xml
"fmt", // encoding/xml
"io", // encoding/xml
"reflect", // encoding/xml
"strconv", // encoding/xml
"strings", // encoding/xml
"sync", // encoding/xml
"unicode", // encoding/xml
"unicode/utf8", // encoding/xml
},
"errors": {
"runtime", // errors
},
"flag": {
"errors", // flag
"fmt", // flag
"io", // flag
"os", // flag
"reflect", // flag
"sort", // flag
"strconv", // flag
"strings", // flag
"time", // flag
},
"fmt": {
"errors", // fmt
"io", // fmt
"math", // fmt
"os", // fmt
"reflect", // fmt
"strconv", // fmt
"sync", // fmt
"unicode/utf8", // fmt
},
"go/ast": {
"bytes", // go/ast
"fmt", // go/ast
"go/scanner", // go/ast
"go/token", // go/ast
"io", // go/ast
"os", // go/ast
"reflect", // go/ast
"sort", // go/ast
"strconv", // go/ast
"strings", // go/ast
"unicode", // go/ast
"unicode/utf8", // go/ast
},
"go/build": {
"bufio", // go/build
"bytes", // go/build
"errors", // go/build
"fmt", // go/build
"go/ast", // go/build
"go/doc", // go/build
"go/parser", // go/build
"go/token", // go/build
"io", // go/build
"io/ioutil", // go/build
"log", // go/build
"os", // go/build
"path", // go/build
"path/filepath", // go/build
"runtime", // go/build
"sort", // go/build
"strconv", // go/build
"strings", // go/build
"unicode", // go/build
"unicode/utf8", // go/build
},
"go/doc": {
"go/ast", // go/doc
"go/token", // go/doc
"io", // go/doc
"path", // go/doc
"regexp", // go/doc
"sort", // go/doc
"strconv", // go/doc
"strings", // go/doc
"text/template", // go/doc
"unicode", // go/doc
"unicode/utf8", // go/doc
},
"go/parser": {
"bytes", // go/parser
"errors", // go/parser
"fmt", // go/parser
"go/ast", // go/parser
"go/scanner", // go/parser
"go/token", // go/parser
"io", // go/parser
"io/ioutil", // go/parser
"os", // go/parser
"path/filepath", // go/parser
"strconv", // go/parser
"strings", // go/parser
"unicode", // go/parser
},
"go/scanner": {
"bytes", // go/scanner
"fmt", // go/scanner
"go/token", // go/scanner
"io", // go/scanner
"path/filepath", // go/scanner
"sort", // go/scanner
"strconv", // go/scanner
"unicode", // go/scanner
"unicode/utf8", // go/scanner
},
"go/token": {
"fmt", // go/token
"sort", // go/token
"strconv", // go/token
"sync", // go/token
},
"hash": {
"io", // hash
},
"hash/adler32": {
"errors", // hash/adler32
"hash", // hash/adler32
},
"internal/cpu": {
"runtime", // internal/cpu
},
"internal/poll": {
"errors", // internal/poll
"internal/race", // internal/poll
"io", // internal/poll
"runtime", // internal/poll
"sync", // internal/poll
"sync/atomic", // internal/poll
"syscall", // internal/poll
"time", // internal/poll
"unicode/utf16", // internal/poll
"unicode/utf8", // internal/poll
},
"internal/race": {
"runtime", // internal/race
},
"internal/singleflight": {
"sync", // internal/singleflight
},
"internal/syscall/windows": {
"internal/syscall/windows/sysdll", // internal/syscall/windows
"syscall", // internal/syscall/windows
},
"internal/syscall/windows/registry": {
"errors", // internal/syscall/windows/registry
"internal/syscall/windows/sysdll", // internal/syscall/windows/registry
"io", // internal/syscall/windows/registry
"syscall", // internal/syscall/windows/registry
"unicode/utf16", // internal/syscall/windows/registry
},
"internal/syscall/windows/sysdll": {
"runtime", // internal/syscall/windows/sysdll
},
"io": {
"errors", // io
"sync", // io
"sync/atomic", // io
},
"io/ioutil": {
"bytes", // io/ioutil
"io", // io/ioutil
"os", // io/ioutil
"path/filepath", // io/ioutil
"sort", // io/ioutil
"strconv", // io/ioutil
"sync", // io/ioutil
"time", // io/ioutil
},
"log": {
"fmt", // log
"io", // log
"os", // log
"runtime", // log
"sync", // log
"time", // log
},
"math": {
"internal/cpu", // math
},
"math/bits": {
"runtime", // math/bits
},
"net/url": {
"bytes", // net/url
"errors", // net/url
"fmt", // net/url
"sort", // net/url
"strconv", // net/url
"strings", // net/url
},
"os": {
"errors", // os
"internal/poll", // os
"internal/syscall/windows", // os
"io", // os
"runtime", // os
"sync", // os
"sync/atomic", // os
"syscall", // os
"time", // os
"unicode/utf16", // os
},
"os/exec": {
"bytes", // os/exec
"context", // os/exec
"errors", // os/exec
"io", // os/exec
"os", // os/exec
"path/filepath", // os/exec
"runtime", // os/exec
"strconv", // os/exec
"strings", // os/exec
"sync", // os/exec
"syscall", // os/exec
},
"os/signal": {
"os", // os/signal
"sync", // os/signal
"syscall", // os/signal
},
"path": {
"errors", // path
"strings", // path
"unicode/utf8", // path
},
"path/filepath": {
"errors", // path/filepath
"internal/syscall/windows", // path/filepath
"os", // path/filepath
"runtime", // path/filepath
"sort", // path/filepath
"strings", // path/filepath
"syscall", // path/filepath
"unicode/utf8", // path/filepath
},
"reflect": {
"math", // reflect
"runtime", // reflect
"strconv", // reflect
"sync", // reflect
"unicode", // reflect
"unicode/utf8", // reflect
},
"regexp": {
"bytes", // regexp
"io", // regexp
"regexp/syntax", // regexp
"sort", // regexp
"strconv", // regexp
"strings", // regexp
"sync", // regexp
"unicode", // regexp
"unicode/utf8", // regexp
},
"regexp/syntax": {
"bytes", // regexp/syntax
"sort", // regexp/syntax
"strconv", // regexp/syntax
"strings", // regexp/syntax
"unicode", // regexp/syntax
"unicode/utf8", // regexp/syntax
},
"runtime": {
"runtime/internal/atomic", // runtime
"runtime/internal/sys", // runtime
},
"runtime/internal/atomic": {
"runtime/internal/sys", // runtime/internal/atomic
},
"runtime/internal/sys": {},
"sort": {
"reflect", // sort
},
"strconv": {
"errors", // strconv
"math", // strconv
"unicode/utf8", // strconv
},
"strings": {
"errors", // strings
"internal/cpu", // strings
"io", // strings
"unicode", // strings
"unicode/utf8", // strings
},
"sync": {
"internal/race", // sync
"runtime", // sync
"sync/atomic", // sync
},
"sync/atomic": {
"runtime", // sync/atomic
},
"syscall": {
"errors", // syscall
"internal/race", // syscall
"internal/syscall/windows/sysdll", // syscall
"runtime", // syscall
"sync", // syscall
"sync/atomic", // syscall
"unicode/utf16", // syscall
},
"text/template": {
"bytes", // text/template
"errors", // text/template
"fmt", // text/template
"io", // text/template
"io/ioutil", // text/template
"net/url", // text/template
"path/filepath", // text/template
"reflect", // text/template
"runtime", // text/template
"sort", // text/template
"strings", // text/template
"sync", // text/template
"text/template/parse", // text/template
"unicode", // text/template
"unicode/utf8", // text/template
},
"text/template/parse": {
"bytes", // text/template/parse
"fmt", // text/template/parse
"runtime", // text/template/parse
"strconv", // text/template/parse
"strings", // text/template/parse
"unicode", // text/template/parse
"unicode/utf8", // text/template/parse
},
"time": {
"errors", // time
"internal/syscall/windows/registry", // time
"runtime", // time
"sync", // time
"syscall", // time
},
"unicode": {
"runtime", // unicode
},
"unicode/utf16": {
"runtime", // unicode/utf16
},
"unicode/utf8": {
"runtime", // unicode/utf8
},
}
// Copyright 2017 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_test
import (
"bytes"
"internal/testenv"
"io/ioutil"
"os"
"os/exec"
"strings"
"testing"
)
func TestDeps(t *testing.T) {
if testing.Short() && testenv.Builder() == "" {
t.Skip("skipping in short mode")
}
current, err := ioutil.ReadFile("deps.go")
if err != nil {
t.Fatal(err)
}
bash, err := exec.LookPath("bash")
if err != nil {
t.Skipf("skipping because bash not found: %v", err)
}
outf, err := ioutil.TempFile("", "dist-deps-test")
if err != nil {
t.Fatal(err)
}
outf.Close()
outname := outf.Name()
defer os.Remove(outname)
out, err := exec.Command(bash, "mkdeps.bash", outname).CombinedOutput()
if err != nil {
t.Fatal(err)
}
t.Logf("%s", out)
updated, err := ioutil.ReadFile(outname)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(current, updated) {
// Very simple minded diff.
t.Log("-current +generated")
clines := strings.Split(string(current), "\n")
for i, line := range clines {
clines[i] = strings.Join(strings.Fields(line), " ")
}
ulines := strings.Split(string(updated), "\n")
for i, line := range ulines {
ulines[i] = strings.Join(strings.Fields(line), " ")
}
for len(clines) > 0 {
cl := clines[0]
switch {
case len(ulines) == 0:
t.Logf("-%s", cl)
clines = clines[1:]
case cl == ulines[0]:
clines = clines[1:]
ulines = ulines[1:]
case pkg(cl) == pkg(ulines[0]):
t.Logf("-%s", cl)
t.Logf("+%s", ulines[0])
clines = clines[1:]
ulines = ulines[1:]
case pkg(cl) < pkg(ulines[0]):
t.Logf("-%s", cl)
clines = clines[1:]
default:
cp := pkg(cl)
for len(ulines) > 0 && pkg(ulines[0]) < cp {
t.Logf("+%s", ulines[0])
ulines = ulines[1:]
}
}
}
t.Error("cmd/dist/deps.go is out of date; run cmd/dist/mkdeps.bash")
}
}
// pkg returns the package of a line in deps.go.
func pkg(line string) string {
i := strings.Index(line, `"`)
if i < 0 {
return ""
}
line = line[i+1:]
i = strings.Index(line, `"`)
if i < 0 {
return ""
}
return line[:i]
}
// 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.
// This file is forked from go/build/read.go.
// (cmd/dist must not import go/build because we do not want it to be
// sensitive to the specific version of go/build present in $GOROOT_BOOTSTRAP.)
package main
import (
"bufio"
"errors"
"io"
"strconv"
"strings"
"unicode/utf8"
)
type importReader struct {
b *bufio.Reader
buf []byte
peek byte
err error
eof bool
nerr int
}
func isIdent(c byte) bool {
return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '_' || c >= utf8.RuneSelf
}
var (
errSyntax = errors.New("syntax error")
errNUL = errors.New("unexpected NUL in input")
)
// syntaxError records a syntax error, but only if an I/O error has not already been recorded.
func (r *importReader) syntaxError() {
if r.err == nil {
r.err = errSyntax
}
}
// readByte reads the next byte from the input, saves it in buf, and returns it.
// If an error occurs, readByte records the error in r.err and returns 0.
func (r *importReader) readByte() byte {
c, err := r.b.ReadByte()
if err == nil {
r.buf = append(r.buf, c)
if c == 0 {
err = errNUL
}
}
if err != nil {
if err == io.EOF {
r.eof = true
} else if r.err == nil {
r.err = err
}
c = 0
}
return c
}
// peekByte returns the next byte from the input reader but does not advance beyond it.
// If skipSpace is set, peekByte skips leading spaces and comments.
func (r *importReader) peekByte(skipSpace bool) byte {
if r.err != nil {
if r.nerr++; r.nerr > 10000 {
panic("go/build: import reader looping")
}
return 0
}
// Use r.peek as first input byte.
// Don't just return r.peek here: it might have been left by peekByte(false)
// and this might be peekByte(true).
c := r.peek
if c == 0 {
c = r.readByte()
}
for r.err == nil && !r.eof {
if skipSpace {
// For the purposes of this reader, semicolons are never necessary to
// understand the input and are treated as spaces.
switch c {
case ' ', '\f', '\t', '\r', '\n', ';':
c = r.readByte()
continue
case '/':
c = r.readByte()
if c == '/' {
for c != '\n' && r.err == nil && !r.eof {
c = r.readByte()
}
} else if c == '*' {
var c1 byte
for (c != '*' || c1 != '/') && r.err == nil {
if r.eof {
r.syntaxError()
}
c, c1 = c1, r.readByte()
}
} else {
r.syntaxError()
}
c = r.readByte()
continue
}
}
break
}
r.peek = c
return r.peek
}
// nextByte is like peekByte but advances beyond the returned byte.
func (r *importReader) nextByte(skipSpace bool) byte {
c := r.peekByte(skipSpace)
r.peek = 0
return c
}
// readKeyword reads the given keyword from the input.
// If the keyword is not present, readKeyword records a syntax error.
func (r *importReader) readKeyword(kw string) {
r.peekByte(true)
for i := 0; i < len(kw); i++ {
if r.nextByte(false) != kw[i] {
r.syntaxError()
return
}
}
if isIdent(r.peekByte(false)) {
r.syntaxError()
}
}
// readIdent reads an identifier from the input.
// If an identifier is not present, readIdent records a syntax error.
func (r *importReader) readIdent() {
c := r.peekByte(true)
if !isIdent(c) {
r.syntaxError()
return
}
for isIdent(r.peekByte(false)) {
r.peek = 0
}
}
// readString reads a quoted string literal from the input.
// If an identifier is not present, readString records a syntax error.
func (r *importReader) readString(save *[]string) {
switch r.nextByte(true) {
case '`':
start := len(r.buf) - 1
for r.err == nil {
if r.nextByte(false) == '`' {
if save != nil {
*save = append(*save, string(r.buf[start:]))
}
break
}
if r.eof {
r.syntaxError()
}
}
case '"':
start := len(r.buf) - 1
for r.err == nil {
c := r.nextByte(false)
if c == '"' {
if save != nil {
*save = append(*save, string(r.buf[start:]))
}
break
}
if r.eof || c == '\n' {
r.syntaxError()
}
if c == '\\' {
r.nextByte(false)
}
}
default:
r.syntaxError()
}
}
// readImport reads an import clause - optional identifier followed by quoted string -
// from the input.
func (r *importReader) readImport(imports *[]string) {
c := r.peekByte(true)
if c == '.' {
r.peek = 0
} else if isIdent(c) {
r.readIdent()
}
r.readString(imports)
}
// readComments is like ioutil.ReadAll, except that it only reads the leading
// block of comments in the file.
func readComments(f io.Reader) ([]byte, error) {
r := &importReader{b: bufio.NewReader(f)}
r.peekByte(true)
if r.err == nil && !r.eof {
// Didn't reach EOF, so must have found a non-space byte. Remove it.
r.buf = r.buf[:len(r.buf)-1]
}
return r.buf, r.err
}
// readimports returns the imports found in the named file.
func readimports(file string) []string {
var imports []string
r := &importReader{b: bufio.NewReader(strings.NewReader(readfile(file)))}
r.readKeyword("package")
r.readIdent()
for r.peekByte(true) == 'i' {
r.readKeyword("import")
if r.peekByte(true) == '(' {
r.nextByte(false)
for r.peekByte(true) != ')' && r.err == nil {
r.readImport(&imports)
}
r.nextByte(false)
} else {
r.readImport(&imports)
}
}
for i := range imports {
unquoted, err := strconv.Unquote(imports[i])
if err != nil {
fatalf("reading imports from %s: %v", file, err)
}
imports[i] = unquoted
}
return imports
}
#!/bin/bash
# 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.
# This script regenerates deps.go.
# The script used to do all the work, but now a Go program does.
# The script has been preserved so that people who learned to type
# ./mkdeps.bash don't have to relearn a new method.
# It's fine to run "go run mkdeps.go" directly instead.
set -e
go run mkdeps.go -- "$@"
exit 0
// Copyright 2017 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.
// This program generates deps.go.
// Run as "go run mkdeps.go" or, to redirect the output, "go run mkdeps.go x.txt".
// +build ignore
package main
import (
"bytes"
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"sort"
"strings"
)
// We need to test enough GOOS/GOARCH combinations
// to find all the package dependencies of cmd/go on all systems.
var targetList = strings.Fields(`
linux/386
linux/amd64
windows/amd64
`)
func usage() {
fmt.Fprintf(os.Stderr, "usage: mkdeps [deps.go]\n")
os.Exit(2)
}
func main() {
log.SetPrefix("mkdeps: ")
log.SetFlags(0)
flag.Usage = usage
flag.Parse()
if flag.NArg() > 1 {
usage()
}
outfile := "deps.go"
if flag.NArg() == 1 {
outfile = flag.Arg(0)
}
_, deps := importsAndDepsOf("cmd/go")
all := deps["cmd/go"]
all = append(all, "cmd/go")
imports, deps := importsAndDepsOf(all...)
// Sort topologically, then by import path.
var topo []string
walked := make(map[string]bool)
var walk func(string)
walk = func(p string) {
if walked[p] {
return
}
walked[p] = true
sort.Strings(deps[p])
for _, d := range deps[p] {
walk(d)
}
topo = append(topo, p)
}
walk("cmd/go")
// We're only going to print imports, not deps,
// in hopes of making deps.go intelligible to people
// who need to debug it or attempt to resolve merge conflicts.
// For the most part, deps is just the transitive closure of imports,
// but sometimes there are implicit deps supplied by the go command
// that are not derivable from imports.
// Find those (if any) and copy them explicitly into imports.
for _, p := range topo {
for _, dp := range deps[p] {
found := false
for _, ip := range imports[p] {
if dp == ip || inList(deps[ip], dp) {
found = true
break
}
}
if !found {
imports[p] = append(imports[p], dp)
}
}
sort.Strings(imports[p])
}
sort.Strings(all)
// Print table.
var buf bytes.Buffer
fmt.Fprintf(&buf, "// Code generated by mkdeps.bash; DO NOT EDIT.\n\n")
fmt.Fprintf(&buf, "package main\n\n")
fmt.Fprintf(&buf, "var builddeps = map[string][]string{\n")
for _, p := range all {
if p == "unsafe" { // unsafe should not be built
continue
}
// We're printing a multiline format here to make the output more
// intelligible both to people and to merge tools.
// We put the name of the parent package as a comment on every line
// to keep a merge tool from applying the diff for one package
// to the dependency list for a different package.
// The extra blank line at the start stops any attempt by gofmt at
// lining up the slice literals from different packages,
// even if they are empty slices (on a single line with the key).
fmt.Fprintf(&buf, "\n\t%q: {\n", p)
for _, d := range imports[p] {
if d != "unsafe" {
fmt.Fprintf(&buf, "\t\t%q, // %s\n", d, p)
}
}
fmt.Fprintf(&buf, "\t},\n")
}
fmt.Fprintf(&buf, "\n}\n")
// Run the installed gofmt instead of using go/format,
// because, on the off chance they disagree,
// the installed gofmt binary is by definition the correct one.
cmd := exec.Command("gofmt")
cmd.Stdin = &buf
var out bytes.Buffer
cmd.Stdout = &out
if err := cmd.Run(); err != nil {
log.Fatalf("gofmt: %v", err)
}
if err := ioutil.WriteFile(outfile, out.Bytes(), 0666); err != nil {
log.Fatal(err)
}
}
func inList(xs []string, s string) bool {
for _, x := range xs {
if x == s {
return true
}
}
return false
}
// importsAndDepsOf returns two maps, one giving the imports for each package in pkgs,
// and one giving the dependencies for each package in pkgs.
// Both the keys and the entries in the value slices are full import paths.
func importsAndDepsOf(pkgs ...string) (map[string][]string, map[string][]string) {
imports := make(map[string][]string)
deps := make(map[string][]string)
for _, target := range targetList {
args := []string{"list", "-tags", "cmd_go_bootstrap", "-f", "{{range .Imports}}import {{$.ImportPath}} {{.}}\n{{end}}{{range .Deps}}dep {{$.ImportPath}} {{.}}\n{{end}}"}
args = append(args, pkgs...)
cmd := exec.Command("go", args...)
t := strings.Split(target, "/")
cmd.Env = append(os.Environ(), "GOOS="+t[0], "GOARCH="+t[1])
var stderr bytes.Buffer
cmd.Stderr = &stderr
out, err := cmd.Output()
if err != nil && !strings.Contains(stderr.String(), "build constraints exclude all Go files") {
log.Fatalf("GOOS=%s GOARCH=%s go list: %v\n%s\n%s", t[0], t[1], err, stderr.Bytes(), out)
}
helped := false
for _, line := range strings.Split(string(out), "\n") {
f := strings.Fields(line)
if len(f) != 3 {
continue
}
if f[0] == "import" && !inList(imports[f[1]], f[2]) {
helped = true
imports[f[1]] = append(imports[f[1]], f[2])
}
if f[0] == "dep" && !inList(deps[f[1]], f[2]) {
helped = true
deps[f[1]] = append(deps[f[1]], f[2])
}
}
if !helped {
fmt.Fprintf(os.Stderr, "mkdeps: note: %s did not contribute any new dependencies\n", target)
}
}
return imports, deps
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment