Commit a918864c authored by Russ Cox's avatar Russ Cox

cmd/go: split out cmd/go/internal/cfg

This is one CL in a long sequence of changes to break up the
go command from one package into a plausible group of packages.

This sequence is concerned only with moving code, not changing
or cleaning up code. There will still be more cleanup after this sequence.

The entire sequence will be submitted together: it is not a goal
for the tree to build at every step.

For #18653.

Change-Id: Icb3f168ade91e7da5fcab89ac75b768daefff359
Reviewed-on: https://go-review.googlesource.com/36191Reviewed-by: default avatarDavid Crawshaw <crawshaw@golang.org>
parent 762eb408
...@@ -6,6 +6,7 @@ package main ...@@ -6,6 +6,7 @@ package main
import ( import (
"bytes" "bytes"
"cmd/go/internal/cfg"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
...@@ -28,7 +29,7 @@ The report includes useful system information. ...@@ -28,7 +29,7 @@ The report includes useful system information.
} }
func init() { func init() {
cmdBug.Flag.BoolVar(&buildV, "v", false, "") cmdBug.Flag.BoolVar(&cfg.BuildV, "v", false, "")
} }
func runBug(cmd *Command, args []string) { func runBug(cmd *Command, args []string) {
...@@ -38,13 +39,13 @@ func runBug(cmd *Command, args []string) { ...@@ -38,13 +39,13 @@ func runBug(cmd *Command, args []string) {
fmt.Fprint(&buf, "#### System details\n\n") fmt.Fprint(&buf, "#### System details\n\n")
fmt.Fprintln(&buf, "```") fmt.Fprintln(&buf, "```")
fmt.Fprintf(&buf, "go version %s %s/%s\n", runtime.Version(), runtime.GOOS, runtime.GOARCH) fmt.Fprintf(&buf, "go version %s %s/%s\n", runtime.Version(), runtime.GOOS, runtime.GOARCH)
env := newEnv env := cfg.NewEnv
env = append(env, extraEnvVars()...) env = append(env, extraEnvVars()...)
for _, e := range env { for _, e := range env {
// Hide the TERM environment variable from "go bug". // Hide the TERM environment variable from "go bug".
// See issue #18128 // See issue #18128
if e.name != "TERM" { if e.Name != "TERM" {
fmt.Fprintf(&buf, "%s=\"%s\"\n", e.name, e.value) fmt.Fprintf(&buf, "%s=\"%s\"\n", e.Name, e.Value)
} }
} }
printGoDetails(&buf) printGoDetails(&buf)
...@@ -97,7 +98,7 @@ func printOSDetails(w io.Writer) { ...@@ -97,7 +98,7 @@ func printOSDetails(w io.Writer) {
if err == nil { if err == nil {
fmt.Fprintf(w, "/etc/release: %s\n", out) fmt.Fprintf(w, "/etc/release: %s\n", out)
} else { } else {
if buildV { if cfg.BuildV {
fmt.Printf("failed to read /etc/release: %v\n", err) fmt.Printf("failed to read /etc/release: %v\n", err)
} }
} }
...@@ -114,7 +115,7 @@ func printCDetails(w io.Writer) { ...@@ -114,7 +115,7 @@ func printCDetails(w io.Writer) {
// Print up to the first newline. // Print up to the first newline.
fmt.Fprintf(w, "gdb --version: %s\n", firstLine(out)) fmt.Fprintf(w, "gdb --version: %s\n", firstLine(out))
} else { } else {
if buildV { if cfg.BuildV {
fmt.Printf("failed to run gdb --version: %v\n", err) fmt.Printf("failed to run gdb --version: %v\n", err)
} }
} }
...@@ -123,7 +124,7 @@ func printCDetails(w io.Writer) { ...@@ -123,7 +124,7 @@ func printCDetails(w io.Writer) {
func inspectGoVersion(w io.Writer) { func inspectGoVersion(w io.Writer) {
data, err := httpGET("https://golang.org/VERSION?m=text") data, err := httpGET("https://golang.org/VERSION?m=text")
if err != nil { if err != nil {
if buildV { if cfg.BuildV {
fmt.Printf("failed to read from golang.org/VERSION: %v\n", err) fmt.Printf("failed to read from golang.org/VERSION: %v\n", err)
} }
return return
...@@ -150,7 +151,7 @@ func printCmdOut(w io.Writer, prefix, path string, args ...string) { ...@@ -150,7 +151,7 @@ func printCmdOut(w io.Writer, prefix, path string, args ...string) {
cmd := exec.Command(path, args...) cmd := exec.Command(path, args...)
out, err := cmd.Output() out, err := cmd.Output()
if err != nil { if err != nil {
if buildV { if cfg.BuildV {
fmt.Printf("%s %s: %v\n", path, strings.Join(args, " "), err) fmt.Printf("%s %s: %v\n", path, strings.Join(args, " "), err)
} }
return return
......
...@@ -7,7 +7,6 @@ package main ...@@ -7,7 +7,6 @@ package main
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"cmd/go/internal/str"
"container/heap" "container/heap"
"debug/elf" "debug/elf"
"errors" "errors"
...@@ -27,6 +26,9 @@ import ( ...@@ -27,6 +26,9 @@ import (
"strings" "strings"
"sync" "sync"
"time" "time"
"cmd/go/internal/cfg"
"cmd/go/internal/str"
) )
var cmdBuild = &Command{ var cmdBuild = &Command{
...@@ -143,38 +145,21 @@ func init() { ...@@ -143,38 +145,21 @@ func init() {
cmdBuild.Run = runBuild cmdBuild.Run = runBuild
cmdInstall.Run = runInstall cmdInstall.Run = runInstall
cmdBuild.Flag.BoolVar(&buildI, "i", false, "") cmdBuild.Flag.BoolVar(&cfg.BuildI, "i", false, "")
cmdBuild.Flag.StringVar(&buildO, "o", "", "output file") cmdBuild.Flag.StringVar(&cfg.BuildO, "o", "", "output file")
addBuildFlags(cmdBuild) addBuildFlags(cmdBuild)
addBuildFlags(cmdInstall) addBuildFlags(cmdInstall)
} }
// Flags set by multiple commands. // Note that flags consulted by other parts of the code
var buildA bool // -a flag // (for example, buildV) are in cmd/go/internal/cfg.
var buildN bool // -n flag
var buildP = runtime.NumCPU() // -p flag var buildAsmflags []string // -asmflags flag
var buildV bool // -v flag var buildGcflags []string // -gcflags flag
var buildX bool // -x flag var buildGccgoflags []string // -gccgoflags flag
var buildI bool // -i flag
var buildO string // -o flag
var buildWork bool // -work flag
var buildAsmflags []string // -asmflags flag
var buildGcflags []string // -gcflags flag
var buildLdflags []string // -ldflags flag
var buildGccgoflags []string // -gccgoflags flag
var buildRace bool // -race flag
var buildMSan bool // -msan flag
var buildToolExec []string // -toolexec flag
var buildBuildmode string // -buildmode flag
var buildLinkshared bool // -linkshared flag
var buildPkgdir string // -pkgdir flag
var buildContext = build.Default
var buildToolchain toolchain = noToolchain{} var buildToolchain toolchain = noToolchain{}
var buildToolchainName string
var buildToolchainCompiler string
var buildToolchainLinker string
var ldBuildmode string var ldBuildmode string
// buildCompiler implements flag.Var. // buildCompiler implements flag.Var.
...@@ -191,15 +176,15 @@ func (c buildCompiler) Set(value string) error { ...@@ -191,15 +176,15 @@ func (c buildCompiler) Set(value string) error {
default: default:
return fmt.Errorf("unknown compiler %q", value) return fmt.Errorf("unknown compiler %q", value)
} }
buildToolchainName = value cfg.BuildToolchainName = value
buildToolchainCompiler = buildToolchain.compiler() cfg.BuildToolchainCompiler = buildToolchain.compiler()
buildToolchainLinker = buildToolchain.linker() cfg.BuildToolchainLinker = buildToolchain.linker()
buildContext.Compiler = value cfg.BuildContext.Compiler = value
return nil return nil
} }
func (c buildCompiler) String() string { func (c buildCompiler) String() string {
return buildContext.Compiler return cfg.BuildContext.Compiler
} }
func init() { func init() {
...@@ -212,31 +197,31 @@ func init() { ...@@ -212,31 +197,31 @@ func init() {
// addBuildFlags adds the flags common to the build, clean, get, // addBuildFlags adds the flags common to the build, clean, get,
// install, list, run, and test commands. // install, list, run, and test commands.
func addBuildFlags(cmd *Command) { func addBuildFlags(cmd *Command) {
cmd.Flag.BoolVar(&buildA, "a", false, "") cmd.Flag.BoolVar(&cfg.BuildA, "a", false, "")
cmd.Flag.BoolVar(&buildN, "n", false, "") cmd.Flag.BoolVar(&cfg.BuildN, "n", false, "")
cmd.Flag.IntVar(&buildP, "p", buildP, "") cmd.Flag.IntVar(&cfg.BuildP, "p", cfg.BuildP, "")
cmd.Flag.BoolVar(&buildV, "v", false, "") cmd.Flag.BoolVar(&cfg.BuildV, "v", false, "")
cmd.Flag.BoolVar(&buildX, "x", false, "") cmd.Flag.BoolVar(&cfg.BuildX, "x", false, "")
cmd.Flag.Var((*stringsFlag)(&buildAsmflags), "asmflags", "") cmd.Flag.Var((*stringsFlag)(&buildAsmflags), "asmflags", "")
cmd.Flag.Var(buildCompiler{}, "compiler", "") cmd.Flag.Var(buildCompiler{}, "compiler", "")
cmd.Flag.StringVar(&buildBuildmode, "buildmode", "default", "") cmd.Flag.StringVar(&cfg.BuildBuildmode, "buildmode", "default", "")
cmd.Flag.Var((*stringsFlag)(&buildGcflags), "gcflags", "") cmd.Flag.Var((*stringsFlag)(&buildGcflags), "gcflags", "")
cmd.Flag.Var((*stringsFlag)(&buildGccgoflags), "gccgoflags", "") cmd.Flag.Var((*stringsFlag)(&buildGccgoflags), "gccgoflags", "")
cmd.Flag.StringVar(&buildContext.InstallSuffix, "installsuffix", "", "") cmd.Flag.StringVar(&cfg.BuildContext.InstallSuffix, "installsuffix", "", "")
cmd.Flag.Var((*stringsFlag)(&buildLdflags), "ldflags", "") cmd.Flag.Var((*stringsFlag)(&cfg.BuildLdflags), "ldflags", "")
cmd.Flag.BoolVar(&buildLinkshared, "linkshared", false, "") cmd.Flag.BoolVar(&cfg.BuildLinkshared, "linkshared", false, "")
cmd.Flag.StringVar(&buildPkgdir, "pkgdir", "", "") cmd.Flag.StringVar(&cfg.BuildPkgdir, "pkgdir", "", "")
cmd.Flag.BoolVar(&buildRace, "race", false, "") cmd.Flag.BoolVar(&cfg.BuildRace, "race", false, "")
cmd.Flag.BoolVar(&buildMSan, "msan", false, "") cmd.Flag.BoolVar(&cfg.BuildMSan, "msan", false, "")
cmd.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "") cmd.Flag.Var((*stringsFlag)(&cfg.BuildContext.BuildTags), "tags", "")
cmd.Flag.Var((*stringsFlag)(&buildToolExec), "toolexec", "") cmd.Flag.Var((*stringsFlag)(&cfg.BuildToolexec), "toolexec", "")
cmd.Flag.BoolVar(&buildWork, "work", false, "") cmd.Flag.BoolVar(&cfg.BuildWork, "work", false, "")
} }
func addBuildFlagsNX(cmd *Command) { func addBuildFlagsNX(cmd *Command) {
cmd.Flag.BoolVar(&buildN, "n", false, "") cmd.Flag.BoolVar(&cfg.BuildN, "n", false, "")
cmd.Flag.BoolVar(&buildX, "x", false, "") cmd.Flag.BoolVar(&cfg.BuildX, "x", false, "")
} }
func isSpaceByte(c byte) bool { func isSpaceByte(c byte) bool {
...@@ -327,10 +312,10 @@ func pkgsNotMain(pkgs []*Package) (res []*Package) { ...@@ -327,10 +312,10 @@ func pkgsNotMain(pkgs []*Package) (res []*Package) {
var pkgsFilter = func(pkgs []*Package) []*Package { return pkgs } var pkgsFilter = func(pkgs []*Package) []*Package { return pkgs }
func buildModeInit() { func buildModeInit() {
gccgo := buildToolchainName == "gccgo" gccgo := cfg.BuildToolchainName == "gccgo"
var codegenArg string var codegenArg string
platform := goos + "/" + goarch platform := cfg.Goos + "/" + cfg.Goarch
switch buildBuildmode { switch cfg.BuildBuildmode {
case "archive": case "archive":
pkgsFilter = pkgsNotMain pkgsFilter = pkgsNotMain
case "c-archive": case "c-archive":
...@@ -344,7 +329,7 @@ func buildModeInit() { ...@@ -344,7 +329,7 @@ func buildModeInit() {
case "darwin/arm", "darwin/arm64": case "darwin/arm", "darwin/arm64":
codegenArg = "-shared" codegenArg = "-shared"
default: default:
switch goos { switch cfg.Goos {
case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris": case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
// Use -shared so that the result is // Use -shared so that the result is
// suitable for inclusion in a PIE or // suitable for inclusion in a PIE or
...@@ -352,7 +337,7 @@ func buildModeInit() { ...@@ -352,7 +337,7 @@ func buildModeInit() {
codegenArg = "-shared" codegenArg = "-shared"
} }
} }
exeSuffix = ".a" cfg.ExeSuffix = ".a"
ldBuildmode = "c-archive" ldBuildmode = "c-archive"
case "c-shared": case "c-shared":
pkgsFilter = pkgsMain pkgsFilter = pkgsMain
...@@ -408,7 +393,7 @@ func buildModeInit() { ...@@ -408,7 +393,7 @@ func buildModeInit() {
} }
codegenArg = "-dynlink" codegenArg = "-dynlink"
} }
if buildO != "" { if cfg.BuildO != "" {
fatalf("-buildmode=shared and -o not supported together") fatalf("-buildmode=shared and -o not supported together")
} }
ldBuildmode = "shared" ldBuildmode = "shared"
...@@ -425,12 +410,12 @@ func buildModeInit() { ...@@ -425,12 +410,12 @@ func buildModeInit() {
} }
codegenArg = "-dynlink" codegenArg = "-dynlink"
} }
exeSuffix = ".so" cfg.ExeSuffix = ".so"
ldBuildmode = "plugin" ldBuildmode = "plugin"
default: default:
fatalf("buildmode=%s not supported", buildBuildmode) fatalf("buildmode=%s not supported", cfg.BuildBuildmode)
} }
if buildLinkshared { if cfg.BuildLinkshared {
if gccgo { if gccgo {
codegenArg = "-fPIC" codegenArg = "-fPIC"
} else { } else {
...@@ -442,7 +427,7 @@ func buildModeInit() { ...@@ -442,7 +427,7 @@ func buildModeInit() {
} }
codegenArg = "-dynlink" codegenArg = "-dynlink"
// TODO(mwhudson): remove -w when that gets fixed in linker. // TODO(mwhudson): remove -w when that gets fixed in linker.
buildLdflags = append(buildLdflags, "-linkshared", "-w") cfg.BuildLdflags = append(cfg.BuildLdflags, "-linkshared", "-w")
} }
} }
if codegenArg != "" { if codegenArg != "" {
...@@ -453,11 +438,11 @@ func buildModeInit() { ...@@ -453,11 +438,11 @@ func buildModeInit() {
buildGcflags = append(buildGcflags, codegenArg) buildGcflags = append(buildGcflags, codegenArg)
} }
// Don't alter InstallSuffix when modifying default codegen args. // Don't alter InstallSuffix when modifying default codegen args.
if buildBuildmode != "default" || buildLinkshared { if cfg.BuildBuildmode != "default" || cfg.BuildLinkshared {
if buildContext.InstallSuffix != "" { if cfg.BuildContext.InstallSuffix != "" {
buildContext.InstallSuffix += "_" cfg.BuildContext.InstallSuffix += "_"
} }
buildContext.InstallSuffix += codegenArg[1:] cfg.BuildContext.InstallSuffix += codegenArg[1:]
} }
} }
} }
...@@ -470,23 +455,23 @@ func runBuild(cmd *Command, args []string) { ...@@ -470,23 +455,23 @@ func runBuild(cmd *Command, args []string) {
pkgs := packagesForBuild(args) pkgs := packagesForBuild(args)
if len(pkgs) == 1 && pkgs[0].Name == "main" && buildO == "" { if len(pkgs) == 1 && pkgs[0].Name == "main" && cfg.BuildO == "" {
_, buildO = path.Split(pkgs[0].ImportPath) _, cfg.BuildO = path.Split(pkgs[0].ImportPath)
buildO += exeSuffix cfg.BuildO += cfg.ExeSuffix
} }
// Special case -o /dev/null by not writing at all. // Special case -o /dev/null by not writing at all.
if buildO == os.DevNull { if cfg.BuildO == os.DevNull {
buildO = "" cfg.BuildO = ""
} }
// sanity check some often mis-used options // sanity check some often mis-used options
switch buildContext.Compiler { switch cfg.BuildContext.Compiler {
case "gccgo": case "gccgo":
if len(buildGcflags) != 0 { if len(buildGcflags) != 0 {
fmt.Println("go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags") fmt.Println("go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags")
} }
if len(buildLdflags) != 0 { if len(cfg.BuildLdflags) != 0 {
fmt.Println("go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags") fmt.Println("go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags")
} }
case "gc": case "gc":
...@@ -496,18 +481,18 @@ func runBuild(cmd *Command, args []string) { ...@@ -496,18 +481,18 @@ func runBuild(cmd *Command, args []string) {
} }
depMode := modeBuild depMode := modeBuild
if buildI { if cfg.BuildI {
depMode = modeInstall depMode = modeInstall
} }
if buildO != "" { if cfg.BuildO != "" {
if len(pkgs) > 1 { if len(pkgs) > 1 {
fatalf("go build: cannot use -o with multiple packages") fatalf("go build: cannot use -o with multiple packages")
} else if len(pkgs) == 0 { } else if len(pkgs) == 0 {
fatalf("no packages to build") fatalf("no packages to build")
} }
p := pkgs[0] p := pkgs[0]
p.target = buildO p.target = cfg.BuildO
p.Stale = true // must build - not up to date p.Stale = true // must build - not up to date
p.StaleReason = "build -o flag in use" p.StaleReason = "build -o flag in use"
a := b.action(modeInstall, depMode, p) a := b.action(modeInstall, depMode, p)
...@@ -516,7 +501,7 @@ func runBuild(cmd *Command, args []string) { ...@@ -516,7 +501,7 @@ func runBuild(cmd *Command, args []string) {
} }
var a *action var a *action
if buildBuildmode == "shared" { if cfg.BuildBuildmode == "shared" {
pkgs := pkgsFilter(packages(args)) pkgs := pkgsFilter(packages(args))
if libName, err := libname(args, pkgs); err != nil { if libName, err := libname(args, pkgs); err != nil {
fatalf("%s", err.Error()) fatalf("%s", err.Error())
...@@ -588,7 +573,7 @@ func libname(args []string, pkgs []*Package) (string, error) { ...@@ -588,7 +573,7 @@ func libname(args []string, pkgs []*Package) (string, error) {
arg := strings.TrimSuffix(args[0], "/...") arg := strings.TrimSuffix(args[0], "/...")
if build.IsLocalImport(arg) { if build.IsLocalImport(arg) {
cwd, _ := os.Getwd() cwd, _ := os.Getwd()
bp, _ := buildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly) bp, _ := cfg.BuildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly)
if bp.ImportPath != "" && bp.ImportPath != "." { if bp.ImportPath != "" && bp.ImportPath != "." {
arg = bp.ImportPath arg = bp.ImportPath
} }
...@@ -642,7 +627,7 @@ func installPackages(args []string, forGet bool) { ...@@ -642,7 +627,7 @@ func installPackages(args []string, forGet bool) {
// Set the behavior for `go get` to not error on packages with test files only. // Set the behavior for `go get` to not error on packages with test files only.
b.testFilesOnlyOK = forGet b.testFilesOnlyOK = forGet
var a *action var a *action
if buildBuildmode == "shared" { if cfg.BuildBuildmode == "shared" {
if libName, err := libname(args, pkgs); err != nil { if libName, err := libname(args, pkgs); err != nil {
fatalf("%s", err.Error()) fatalf("%s", err.Error())
} else { } else {
...@@ -688,13 +673,13 @@ func installPackages(args []string, forGet bool) { ...@@ -688,13 +673,13 @@ func installPackages(args []string, forGet bool) {
// Compute file 'go build' would have created. // Compute file 'go build' would have created.
// If it exists and is an executable file, remove it. // If it exists and is an executable file, remove it.
_, targ := filepath.Split(pkgs[0].ImportPath) _, targ := filepath.Split(pkgs[0].ImportPath)
targ += exeSuffix targ += cfg.ExeSuffix
if filepath.Join(pkgs[0].Dir, targ) != pkgs[0].Target { // maybe $GOBIN is the current directory if filepath.Join(pkgs[0].Dir, targ) != pkgs[0].Target { // maybe $GOBIN is the current directory
fi, err := os.Stat(targ) fi, err := os.Stat(targ)
if err == nil { if err == nil {
m := fi.Mode() m := fi.Mode()
if m.IsRegular() { if m.IsRegular() {
if m&0111 != 0 || goos == "windows" { // windows never sets executable bit if m&0111 != 0 || cfg.Goos == "windows" { // windows never sets executable bit
os.Remove(targ) os.Remove(targ)
} }
} }
...@@ -703,22 +688,14 @@ func installPackages(args []string, forGet bool) { ...@@ -703,22 +688,14 @@ func installPackages(args []string, forGet bool) {
} }
} }
// Global build parameters (used during package load)
var (
goarch string
goos string
exeSuffix string
gopath []string
)
func init() { func init() {
goarch = buildContext.GOARCH cfg.Goarch = cfg.BuildContext.GOARCH
goos = buildContext.GOOS cfg.Goos = cfg.BuildContext.GOOS
if goos == "windows" { if cfg.Goos == "windows" {
exeSuffix = ".exe" cfg.ExeSuffix = ".exe"
} }
gopath = filepath.SplitList(buildContext.GOPATH) cfg.Gopath = filepath.SplitList(cfg.BuildContext.GOPATH)
} }
// A builder holds global state about a build. // A builder holds global state about a build.
...@@ -798,17 +775,17 @@ func (b *builder) init() { ...@@ -798,17 +775,17 @@ func (b *builder) init() {
b.actionCache = make(map[cacheKey]*action) b.actionCache = make(map[cacheKey]*action)
b.mkdirCache = make(map[string]bool) b.mkdirCache = make(map[string]bool)
if buildN { if cfg.BuildN {
b.work = "$WORK" b.work = "$WORK"
} else { } else {
b.work, err = ioutil.TempDir("", "go-build") b.work, err = ioutil.TempDir("", "go-build")
if err != nil { if err != nil {
fatalf("%s", err) fatalf("%s", err)
} }
if buildX || buildWork { if cfg.BuildX || cfg.BuildWork {
fmt.Fprintf(os.Stderr, "WORK=%s\n", b.work) fmt.Fprintf(os.Stderr, "WORK=%s\n", b.work)
} }
if !buildWork { if !cfg.BuildWork {
workdir := b.work workdir := b.work
atexit(func() { os.RemoveAll(workdir) }) atexit(func() { os.RemoveAll(workdir) })
} }
...@@ -827,7 +804,7 @@ func goFilesPackage(gofiles []string) *Package { ...@@ -827,7 +804,7 @@ func goFilesPackage(gofiles []string) *Package {
} }
var stk importStack var stk importStack
ctxt := buildContext ctxt := cfg.BuildContext
ctxt.UseAllFiles = true ctxt.UseAllFiles = true
// Synthesize fake "directory" that only shows the named files, // Synthesize fake "directory" that only shows the named files,
...@@ -879,9 +856,9 @@ func goFilesPackage(gofiles []string) *Package { ...@@ -879,9 +856,9 @@ func goFilesPackage(gofiles []string) *Package {
if pkg.Name == "main" { if pkg.Name == "main" {
_, elem := filepath.Split(gofiles[0]) _, elem := filepath.Split(gofiles[0])
exe := elem[:len(elem)-len(".go")] + exeSuffix exe := elem[:len(elem)-len(".go")] + cfg.ExeSuffix
if buildO == "" { if cfg.BuildO == "" {
buildO = exe cfg.BuildO = exe
} }
if gobin != "" { if gobin != "" {
pkg.target = filepath.Join(gobin, exe) pkg.target = filepath.Join(gobin, exe)
...@@ -902,7 +879,7 @@ func goFilesPackage(gofiles []string) *Package { ...@@ -902,7 +879,7 @@ func goFilesPackage(gofiles []string) *Package {
// .go_export section. // .go_export section.
func readpkglist(shlibpath string) (pkgs []*Package) { func readpkglist(shlibpath string) (pkgs []*Package) {
var stk importStack var stk importStack
if buildToolchainName == "gccgo" { if cfg.BuildToolchainName == "gccgo" {
f, _ := elf.Open(shlibpath) f, _ := elf.Open(shlibpath)
sect := f.Section(".go_export") sect := f.Section(".go_export")
data, _ := sect.Data() data, _ := sect.Data()
...@@ -988,7 +965,7 @@ func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, looksha ...@@ -988,7 +965,7 @@ func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, looksha
// p is not part of a shared library. // p is not part of a shared library.
// If p1 is in a shared library, put the action for that into // If p1 is in a shared library, put the action for that into
// a.deps, otherwise put the action for p1 into a.deps. // a.deps, otherwise put the action for p1 into a.deps.
a.deps = append(a.deps, b.action1(depMode, depMode, p1, buildLinkshared, p1.Shlib)) a.deps = append(a.deps, b.action1(depMode, depMode, p1, cfg.BuildLinkshared, p1.Shlib))
} }
} }
...@@ -997,8 +974,8 @@ func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, looksha ...@@ -997,8 +974,8 @@ func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, looksha
// using cgo, to make sure we do not overwrite the binary while // using cgo, to make sure we do not overwrite the binary while
// a package is using it. If this is a cross-build, then the cgo we // a package is using it. If this is a cross-build, then the cgo we
// are writing is not the cgo we need to use. // are writing is not the cgo we need to use.
if goos == runtime.GOOS && goarch == runtime.GOARCH && !buildRace && !buildMSan { if cfg.Goos == runtime.GOOS && cfg.Goarch == runtime.GOARCH && !cfg.BuildRace && !cfg.BuildMSan {
if (len(p.CgoFiles) > 0 || p.Standard && p.ImportPath == "runtime/cgo") && !buildLinkshared && buildBuildmode != "shared" { if (len(p.CgoFiles) > 0 || p.Standard && p.ImportPath == "runtime/cgo") && !cfg.BuildLinkshared && cfg.BuildBuildmode != "shared" {
var stk importStack var stk importStack
p1 := loadPackage("cmd/cgo", &stk) p1 := loadPackage("cmd/cgo", &stk)
if p1.Error != nil { if p1.Error != nil {
...@@ -1016,7 +993,7 @@ func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, looksha ...@@ -1016,7 +993,7 @@ func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, looksha
return a return a
} }
// gccgo standard library is "fake" too. // gccgo standard library is "fake" too.
if buildToolchainName == "gccgo" { if cfg.BuildToolchainName == "gccgo" {
// the target name is needed for cgo. // the target name is needed for cgo.
a.target = p.target a.target = p.target
return a return a
...@@ -1049,9 +1026,9 @@ func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, looksha ...@@ -1049,9 +1026,9 @@ func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, looksha
a.target = a.p.target a.target = a.p.target
// Install header for cgo in c-archive and c-shared modes. // Install header for cgo in c-archive and c-shared modes.
if p.usesCgo() && (buildBuildmode == "c-archive" || buildBuildmode == "c-shared") { if p.usesCgo() && (cfg.BuildBuildmode == "c-archive" || cfg.BuildBuildmode == "c-shared") {
hdrTarget := a.target[:len(a.target)-len(filepath.Ext(a.target))] + ".h" hdrTarget := a.target[:len(a.target)-len(filepath.Ext(a.target))] + ".h"
if buildContext.Compiler == "gccgo" { if cfg.BuildContext.Compiler == "gccgo" {
// For the header file, remove the "lib" // For the header file, remove the "lib"
// added by go/build, so we generate pkg.h // added by go/build, so we generate pkg.h
// rather than libpkg.h. // rather than libpkg.h.
...@@ -1084,7 +1061,7 @@ func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, looksha ...@@ -1084,7 +1061,7 @@ func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, looksha
name := "a.out" name := "a.out"
if p.exeName != "" { if p.exeName != "" {
name = p.exeName name = p.exeName
} else if goos == "darwin" && buildBuildmode == "c-shared" && p.target != "" { } else if cfg.Goos == "darwin" && cfg.BuildBuildmode == "c-shared" && p.target != "" {
// On OS X, the linker output name gets recorded in the // On OS X, the linker output name gets recorded in the
// shared library's LC_ID_DYLIB load command. // shared library's LC_ID_DYLIB load command.
// The code invoking the linker knows to pass only the final // The code invoking the linker knows to pass only the final
...@@ -1092,7 +1069,7 @@ func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, looksha ...@@ -1092,7 +1069,7 @@ func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, looksha
// we'll install it as; otherwise the library is only loadable as "a.out". // we'll install it as; otherwise the library is only loadable as "a.out".
_, name = filepath.Split(p.target) _, name = filepath.Split(p.target)
} }
a.target = a.objdir + filepath.Join("exe", name) + exeSuffix a.target = a.objdir + filepath.Join("exe", name) + cfg.ExeSuffix
} }
} }
...@@ -1120,7 +1097,7 @@ func (b *builder) libaction(libname string, pkgs []*Package, mode, depMode build ...@@ -1120,7 +1097,7 @@ func (b *builder) libaction(libname string, pkgs []*Package, mode, depMode build
// external linking mode forces an import of runtime/cgo (and // external linking mode forces an import of runtime/cgo (and
// math on arm). So if it was not passed on the command line and // math on arm). So if it was not passed on the command line and
// it is not present in another shared library, add it here. // it is not present in another shared library, add it here.
gccgo := buildToolchainName == "gccgo" gccgo := cfg.BuildToolchainName == "gccgo"
if !gccgo { if !gccgo {
seencgo := false seencgo := false
for _, p := range pkgs { for _, p := range pkgs {
...@@ -1142,7 +1119,7 @@ func (b *builder) libaction(libname string, pkgs []*Package, mode, depMode build ...@@ -1142,7 +1119,7 @@ func (b *builder) libaction(libname string, pkgs []*Package, mode, depMode build
pkgs = append(pkgs, p) pkgs = append(pkgs, p)
} }
} }
if goarch == "arm" { if cfg.Goarch == "arm" {
seenmath := false seenmath := false
for _, p := range pkgs { for _, p := range pkgs {
seenmath = seenmath || (p.Standard && p.ImportPath == "math") seenmath = seenmath || (p.Standard && p.ImportPath == "math")
...@@ -1265,8 +1242,8 @@ func allArchiveActions(root *action) []*action { ...@@ -1265,8 +1242,8 @@ func allArchiveActions(root *action) []*action {
// do runs the action graph rooted at root. // do runs the action graph rooted at root.
func (b *builder) do(root *action) { func (b *builder) do(root *action) {
if _, ok := osArchSupportsCgo[goos+"/"+goarch]; !ok && buildContext.Compiler == "gc" { if _, ok := osArchSupportsCgo[cfg.Goos+"/"+cfg.Goarch]; !ok && cfg.BuildContext.Compiler == "gc" {
fmt.Fprintf(os.Stderr, "cmd/go: unsupported GOOS/GOARCH pair %s/%s\n", goos, goarch) fmt.Fprintf(os.Stderr, "cmd/go: unsupported GOOS/GOARCH pair %s/%s\n", cfg.Goos, cfg.Goarch)
os.Exit(2) os.Exit(2)
} }
...@@ -1345,8 +1322,8 @@ func (b *builder) do(root *action) { ...@@ -1345,8 +1322,8 @@ func (b *builder) do(root *action) {
// If we are using the -n flag (just printing commands) // If we are using the -n flag (just printing commands)
// drop the parallelism to 1, both to make the output // drop the parallelism to 1, both to make the output
// deterministic and because there is no real work anyway. // deterministic and because there is no real work anyway.
par := buildP par := cfg.BuildP
if buildN { if cfg.BuildN {
par = 1 par = 1
} }
for i := 0; i < par; i++ { for i := 0; i < par; i++ {
...@@ -1408,7 +1385,7 @@ func (b *builder) build(a *action) (err error) { ...@@ -1408,7 +1385,7 @@ func (b *builder) build(a *action) (err error) {
err = fmt.Errorf("go build %s: %v", a.p.ImportPath, err) err = fmt.Errorf("go build %s: %v", a.p.ImportPath, err)
} }
}() }()
if buildN { if cfg.BuildN {
// In -n mode, print a banner between packages. // In -n mode, print a banner between packages.
// The banner is five lines so that when changes to // The banner is five lines so that when changes to
// different sections of the bootstrap script have to // different sections of the bootstrap script have to
...@@ -1417,7 +1394,7 @@ func (b *builder) build(a *action) (err error) { ...@@ -1417,7 +1394,7 @@ func (b *builder) build(a *action) (err error) {
b.print("\n#\n# " + a.p.ImportPath + "\n#\n\n") b.print("\n#\n# " + a.p.ImportPath + "\n#\n\n")
} }
if buildV { if cfg.BuildV {
b.print(a.p.ImportPath + "\n") b.print(a.p.ImportPath + "\n")
} }
...@@ -1496,7 +1473,7 @@ func (b *builder) build(a *action) (err error) { ...@@ -1496,7 +1473,7 @@ func (b *builder) build(a *action) (err error) {
if err != nil { if err != nil {
return err return err
} }
if buildToolchainName == "gccgo" { if cfg.BuildToolchainName == "gccgo" {
cgoObjects = append(cgoObjects, filepath.Join(a.objdir, "_cgo_flags")) cgoObjects = append(cgoObjects, filepath.Join(a.objdir, "_cgo_flags"))
} }
cgoObjects = append(cgoObjects, outObj...) cgoObjects = append(cgoObjects, outObj...)
...@@ -1557,9 +1534,9 @@ func (b *builder) build(a *action) (err error) { ...@@ -1557,9 +1534,9 @@ func (b *builder) build(a *action) (err error) {
// Copy .h files named for goos or goarch or goos_goarch // Copy .h files named for goos or goarch or goos_goarch
// to names using GOOS and GOARCH. // to names using GOOS and GOARCH.
// For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h. // For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
_goos_goarch := "_" + goos + "_" + goarch _goos_goarch := "_" + cfg.Goos + "_" + cfg.Goarch
_goos := "_" + goos _goos := "_" + cfg.Goos
_goarch := "_" + goarch _goarch := "_" + cfg.Goarch
for _, file := range a.p.HFiles { for _, file := range a.p.HFiles {
name, ext := fileExtSplit(file) name, ext := fileExtSplit(file)
switch { switch {
...@@ -1707,7 +1684,7 @@ func (b *builder) installShlibname(a *action) error { ...@@ -1707,7 +1684,7 @@ func (b *builder) installShlibname(a *action) error {
if err != nil { if err != nil {
return err return err
} }
if buildX { if cfg.BuildX {
b.showcmd("", "echo '%s' > %s # internal", filepath.Base(a1.target), a.target) b.showcmd("", "echo '%s' > %s # internal", filepath.Base(a1.target), a.target)
} }
return nil return nil
...@@ -1729,7 +1706,7 @@ func (b *builder) install(a *action) (err error) { ...@@ -1729,7 +1706,7 @@ func (b *builder) install(a *action) (err error) {
a1 := a.deps[0] a1 := a.deps[0]
perm := os.FileMode(0666) perm := os.FileMode(0666)
if a1.link { if a1.link {
switch buildBuildmode { switch cfg.BuildBuildmode {
case "c-archive", "c-shared", "plugin": case "c-archive", "c-shared", "plugin":
default: default:
perm = 0777 perm = 0777
...@@ -1748,7 +1725,7 @@ func (b *builder) install(a *action) (err error) { ...@@ -1748,7 +1725,7 @@ func (b *builder) install(a *action) (err error) {
// garbage down in a large build. On an operating system // garbage down in a large build. On an operating system
// with aggressive buffering, cleaning incrementally like // with aggressive buffering, cleaning incrementally like
// this keeps the intermediate objects from hitting the disk. // this keeps the intermediate objects from hitting the disk.
if !buildWork { if !cfg.BuildWork {
defer os.RemoveAll(a1.objdir) defer os.RemoveAll(a1.objdir)
defer os.Remove(a1.target) defer os.Remove(a1.target)
} }
...@@ -1792,7 +1769,7 @@ func (b *builder) includeArgs(flag string, all []*action) []string { ...@@ -1792,7 +1769,7 @@ func (b *builder) includeArgs(flag string, all []*action) []string {
need[a1.p.build.Root] = a1.p.build need[a1.p.build.Root] = a1.p.build
} }
} }
for _, root := range gopath { for _, root := range cfg.Gopath {
if p := need[root]; p != nil && !incMap[p.PkgRoot] { if p := need[root]; p != nil && !incMap[p.PkgRoot] {
incMap[p.PkgRoot] = true incMap[p.PkgRoot] = true
inc = append(inc, flag, p.PkgTargetRoot) inc = append(inc, flag, p.PkgTargetRoot)
...@@ -1815,7 +1792,7 @@ func (b *builder) includeArgs(flag string, all []*action) []string { ...@@ -1815,7 +1792,7 @@ func (b *builder) includeArgs(flag string, all []*action) []string {
// moveOrCopyFile is like 'mv src dst' or 'cp src dst'. // moveOrCopyFile is like 'mv src dst' or 'cp src dst'.
func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode, force bool) error { func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode, force bool) error {
if buildN { if cfg.BuildN {
b.showcmd("", "mv %s %s", src, dst) b.showcmd("", "mv %s %s", src, dst)
return nil return nil
} }
...@@ -1842,7 +1819,7 @@ func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode, f ...@@ -1842,7 +1819,7 @@ func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode, f
if err := os.Chmod(src, mode); err == nil { if err := os.Chmod(src, mode); err == nil {
if err := os.Rename(src, dst); err == nil { if err := os.Rename(src, dst); err == nil {
if buildX { if cfg.BuildX {
b.showcmd("", "mv %s %s", src, dst) b.showcmd("", "mv %s %s", src, dst)
} }
return nil return nil
...@@ -1854,9 +1831,9 @@ func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode, f ...@@ -1854,9 +1831,9 @@ func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode, f
// copyFile is like 'cp src dst'. // copyFile is like 'cp src dst'.
func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode, force bool) error { func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode, force bool) error {
if buildN || buildX { if cfg.BuildN || cfg.BuildX {
b.showcmd("", "cp %s %s", src, dst) b.showcmd("", "cp %s %s", src, dst)
if buildN { if cfg.BuildN {
return nil return nil
} }
} }
...@@ -1934,7 +1911,7 @@ func (b *builder) installHeader(a *action) error { ...@@ -1934,7 +1911,7 @@ func (b *builder) installHeader(a *action) error {
// go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go // go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
func (b *builder) cover(a *action, dst, src string, perm os.FileMode, varName string) error { func (b *builder) cover(a *action, dst, src string, perm os.FileMode, varName string) error {
return b.run(a.objdir, "cover "+a.p.ImportPath, nil, return b.run(a.objdir, "cover "+a.p.ImportPath, nil,
buildToolExec, cfg.BuildToolexec,
tool("cover"), tool("cover"),
"-mode", a.p.coverMode, "-mode", a.p.coverMode,
"-var", varName, "-var", varName,
...@@ -2112,7 +2089,7 @@ func (b *builder) processOutput(out []byte) string { ...@@ -2112,7 +2089,7 @@ func (b *builder) processOutput(out []byte) string {
// Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19. // Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
// Replace *[100]_Ctype_foo with *[100]C.foo. // Replace *[100]_Ctype_foo with *[100]C.foo.
// If we're using -x, assume we're debugging and want the full dump, so disable the rewrite. // If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
if !buildX && cgoLine.MatchString(messages) { if !cfg.BuildX && cgoLine.MatchString(messages) {
messages = cgoLine.ReplaceAllString(messages, "") messages = cgoLine.ReplaceAllString(messages, "")
messages = cgoTypeSigRe.ReplaceAllString(messages, "C.") messages = cgoTypeSigRe.ReplaceAllString(messages, "C.")
} }
...@@ -2123,7 +2100,7 @@ func (b *builder) processOutput(out []byte) string { ...@@ -2123,7 +2100,7 @@ func (b *builder) processOutput(out []byte) string {
// It returns the command output and any errors that occurred. // It returns the command output and any errors that occurred.
func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) { func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) {
cmdline := str.StringList(cmdargs...) cmdline := str.StringList(cmdargs...)
if buildN || buildX { if cfg.BuildN || cfg.BuildX {
var envcmdline string var envcmdline string
for i := range env { for i := range env {
envcmdline += env[i] envcmdline += env[i]
...@@ -2131,7 +2108,7 @@ func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...inter ...@@ -2131,7 +2108,7 @@ func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...inter
} }
envcmdline += joinUnambiguously(cmdline) envcmdline += joinUnambiguously(cmdline)
b.showcmd(dir, "%s", envcmdline) b.showcmd(dir, "%s", envcmdline)
if buildN { if cfg.BuildN {
return nil, nil return nil, nil
} }
} }
...@@ -2235,9 +2212,9 @@ func (b *builder) mkdir(dir string) error { ...@@ -2235,9 +2212,9 @@ func (b *builder) mkdir(dir string) error {
} }
b.mkdirCache[dir] = true b.mkdirCache[dir] = true
if buildN || buildX { if cfg.BuildN || cfg.BuildX {
b.showcmd("", "mkdir -p %s", dir) b.showcmd("", "mkdir -p %s", dir)
if buildN { if cfg.BuildN {
return nil return nil
} }
} }
...@@ -2292,7 +2269,7 @@ type toolchain interface { ...@@ -2292,7 +2269,7 @@ type toolchain interface {
type noToolchain struct{} type noToolchain struct{}
func noCompiler() error { func noCompiler() error {
log.Fatalf("unknown compiler %q", buildContext.Compiler) log.Fatalf("unknown compiler %q", cfg.BuildContext.Compiler)
return nil return nil
} }
...@@ -2378,8 +2355,8 @@ func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, ...@@ -2378,8 +2355,8 @@ func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool,
if extFiles == 0 { if extFiles == 0 {
gcargs = append(gcargs, "-complete") gcargs = append(gcargs, "-complete")
} }
if buildContext.InstallSuffix != "" { if cfg.BuildContext.InstallSuffix != "" {
gcargs = append(gcargs, "-installsuffix", buildContext.InstallSuffix) gcargs = append(gcargs, "-installsuffix", cfg.BuildContext.InstallSuffix)
} }
if p.buildID != "" { if p.buildID != "" {
gcargs = append(gcargs, "-buildid", p.buildID) gcargs = append(gcargs, "-buildid", p.buildID)
...@@ -2393,7 +2370,7 @@ func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, ...@@ -2393,7 +2370,7 @@ func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool,
} }
} }
args := []interface{}{buildToolExec, tool("compile"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs} args := []interface{}{cfg.BuildToolexec, tool("compile"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs}
if ofile == archive { if ofile == archive {
args = append(args, "-pack") args = append(args, "-pack")
} }
...@@ -2411,8 +2388,8 @@ func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, ...@@ -2411,8 +2388,8 @@ func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool,
func (gcToolchain) asm(b *builder, p *Package, obj string, sfiles []string) ([]string, error) { func (gcToolchain) asm(b *builder, p *Package, obj string, sfiles []string) ([]string, error) {
// Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files. // Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
inc := filepath.Join(goroot, "pkg", "include") inc := filepath.Join(goroot, "pkg", "include")
args := []interface{}{buildToolExec, tool("asm"), "-trimpath", b.work, "-I", obj, "-I", inc, "-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch, buildAsmflags} args := []interface{}{cfg.BuildToolexec, tool("asm"), "-trimpath", b.work, "-I", obj, "-I", inc, "-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch, buildAsmflags}
if p.ImportPath == "runtime" && goarch == "386" { if p.ImportPath == "runtime" && cfg.Goarch == "386" {
for _, arg := range buildAsmflags { for _, arg := range buildAsmflags {
if arg == "-dynlink" { if arg == "-dynlink" {
args = append(args, "-D=GOBUILDMODE_shared=1") args = append(args, "-D=GOBUILDMODE_shared=1")
...@@ -2471,17 +2448,17 @@ func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []s ...@@ -2471,17 +2448,17 @@ func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []s
// The archive file should have been created by the compiler. // The archive file should have been created by the compiler.
// Since it used to not work that way, verify. // Since it used to not work that way, verify.
if !buildN { if !cfg.BuildN {
if _, err := os.Stat(absAfile); err != nil { if _, err := os.Stat(absAfile); err != nil {
fatalf("os.Stat of archive file failed: %v", err) fatalf("os.Stat of archive file failed: %v", err)
} }
} }
if buildN || buildX { if cfg.BuildN || cfg.BuildX {
cmdline := str.StringList("pack", "r", absAfile, absOfiles) cmdline := str.StringList("pack", "r", absAfile, absOfiles)
b.showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline)) b.showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline))
} }
if buildN { if cfg.BuildN {
return nil return nil
} }
if err := packInternal(b, absAfile, absOfiles); err != nil { if err := packInternal(b, absAfile, absOfiles); err != nil {
...@@ -2580,13 +2557,13 @@ func (gcToolchain) ld(b *builder, root *action, out string, allactions []*action ...@@ -2580,13 +2557,13 @@ func (gcToolchain) ld(b *builder, root *action, out string, allactions []*action
} }
} }
var ldflags []string var ldflags []string
if buildContext.InstallSuffix != "" { if cfg.BuildContext.InstallSuffix != "" {
ldflags = append(ldflags, "-installsuffix", buildContext.InstallSuffix) ldflags = append(ldflags, "-installsuffix", cfg.BuildContext.InstallSuffix)
} }
if root.p.omitDWARF { if root.p.omitDWARF {
ldflags = append(ldflags, "-w") ldflags = append(ldflags, "-w")
} }
if buildBuildmode == "plugin" { if cfg.BuildBuildmode == "plugin" {
pluginpath := root.p.ImportPath pluginpath := root.p.ImportPath
if pluginpath == "command-line-arguments" { if pluginpath == "command-line-arguments" {
pluginpath = "plugin/unnamed-" + root.p.buildID pluginpath = "plugin/unnamed-" + root.p.buildID
...@@ -2609,7 +2586,7 @@ func (gcToolchain) ld(b *builder, root *action, out string, allactions []*action ...@@ -2609,7 +2586,7 @@ func (gcToolchain) ld(b *builder, root *action, out string, allactions []*action
if root.p.buildID != "" { if root.p.buildID != "" {
ldflags = append(ldflags, "-buildid="+root.p.buildID) ldflags = append(ldflags, "-buildid="+root.p.buildID)
} }
ldflags = append(ldflags, buildLdflags...) ldflags = append(ldflags, cfg.BuildLdflags...)
// On OS X when using external linking to build a shared library, // On OS X when using external linking to build a shared library,
// the argument passed here to -o ends up recorded in the final // the argument passed here to -o ends up recorded in the final
...@@ -2619,18 +2596,18 @@ func (gcToolchain) ld(b *builder, root *action, out string, allactions []*action ...@@ -2619,18 +2596,18 @@ func (gcToolchain) ld(b *builder, root *action, out string, allactions []*action
// run the link in the output directory so that -o can name // run the link in the output directory so that -o can name
// just the final path element. // just the final path element.
dir := "." dir := "."
if goos == "darwin" && buildBuildmode == "c-shared" { if cfg.Goos == "darwin" && cfg.BuildBuildmode == "c-shared" {
dir, out = filepath.Split(out) dir, out = filepath.Split(out)
} }
return b.run(dir, root.p.ImportPath, nil, buildToolExec, tool("link"), "-o", out, importArgs, ldflags, mainpkg) return b.run(dir, root.p.ImportPath, nil, cfg.BuildToolexec, tool("link"), "-o", out, importArgs, ldflags, mainpkg)
} }
func (gcToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error { func (gcToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
importArgs := b.includeArgs("-L", allactions) importArgs := b.includeArgs("-L", allactions)
ldflags := []string{"-installsuffix", buildContext.InstallSuffix} ldflags := []string{"-installsuffix", cfg.BuildContext.InstallSuffix}
ldflags = append(ldflags, "-buildmode=shared") ldflags = append(ldflags, "-buildmode=shared")
ldflags = append(ldflags, buildLdflags...) ldflags = append(ldflags, cfg.BuildLdflags...)
cxx := false cxx := false
for _, a := range allactions { for _, a := range allactions {
if a.p != nil && (len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0) { if a.p != nil && (len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0) {
...@@ -2654,7 +2631,7 @@ func (gcToolchain) ldShared(b *builder, toplevelactions []*action, out string, a ...@@ -2654,7 +2631,7 @@ func (gcToolchain) ldShared(b *builder, toplevelactions []*action, out string, a
} }
ldflags = append(ldflags, d.p.ImportPath+"="+d.target) ldflags = append(ldflags, d.p.ImportPath+"="+d.target)
} }
return b.run(".", out, nil, buildToolExec, tool("link"), "-o", out, importArgs, ldflags) return b.run(".", out, nil, cfg.BuildToolexec, tool("link"), "-o", out, importArgs, ldflags)
} }
func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error { func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
...@@ -2708,7 +2685,7 @@ func (tools gccgoToolchain) asm(b *builder, p *Package, obj string, sfiles []str ...@@ -2708,7 +2685,7 @@ func (tools gccgoToolchain) asm(b *builder, p *Package, obj string, sfiles []str
ofile := obj + sfile[:len(sfile)-len(".s")] + ".o" ofile := obj + sfile[:len(sfile)-len(".s")] + ".o"
ofiles = append(ofiles, ofile) ofiles = append(ofiles, ofile)
sfile = mkAbs(p.Dir, sfile) sfile = mkAbs(p.Dir, sfile)
defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch} defs := []string{"-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch}
if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" { if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
defs = append(defs, `-D`, `GOPKGPATH=`+pkgpath) defs = append(defs, `-D`, `GOPKGPATH=`+pkgpath)
} }
...@@ -2929,7 +2906,7 @@ func (tools gccgoToolchain) link(b *builder, root *action, out string, allaction ...@@ -2929,7 +2906,7 @@ func (tools gccgoToolchain) link(b *builder, root *action, out string, allaction
var realOut string var realOut string
switch buildmode { switch buildmode {
case "exe": case "exe":
if usesCgo && goos == "linux" { if usesCgo && cfg.Goos == "linux" {
ldflags = append(ldflags, "-Wl,-E") ldflags = append(ldflags, "-Wl,-E")
} }
...@@ -3016,12 +2993,12 @@ func (tools gccgoToolchain) ldShared(b *builder, toplevelactions []*action, out ...@@ -3016,12 +2993,12 @@ func (tools gccgoToolchain) ldShared(b *builder, toplevelactions []*action, out
func (tools gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error { func (tools gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
inc := filepath.Join(goroot, "pkg", "include") inc := filepath.Join(goroot, "pkg", "include")
cfile = mkAbs(p.Dir, cfile) cfile = mkAbs(p.Dir, cfile)
defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch} defs := []string{"-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch}
defs = append(defs, b.gccArchArgs()...) defs = append(defs, b.gccArchArgs()...)
if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" { if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`) defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
} }
switch goarch { switch cfg.Goarch {
case "386", "amd64": case "386", "amd64":
defs = append(defs, "-fsplit-stack") defs = append(defs, "-fsplit-stack")
} }
...@@ -3032,7 +3009,7 @@ func (tools gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile stri ...@@ -3032,7 +3009,7 @@ func (tools gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile stri
// maybePIC adds -fPIC to the list of arguments if needed. // maybePIC adds -fPIC to the list of arguments if needed.
func (tools gccgoToolchain) maybePIC(args []string) []string { func (tools gccgoToolchain) maybePIC(args []string) []string {
switch buildBuildmode { switch cfg.BuildBuildmode {
case "c-shared", "shared", "plugin": case "c-shared", "shared", "plugin":
args = append(args, "-fPIC") args = append(args, "-fPIC")
} }
...@@ -3129,14 +3106,14 @@ func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string { ...@@ -3129,14 +3106,14 @@ func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
// Definitely want -fPIC but on Windows gcc complains // Definitely want -fPIC but on Windows gcc complains
// "-fPIC ignored for target (all code is position independent)" // "-fPIC ignored for target (all code is position independent)"
if goos != "windows" { if cfg.Goos != "windows" {
a = append(a, "-fPIC") a = append(a, "-fPIC")
} }
a = append(a, b.gccArchArgs()...) a = append(a, b.gccArchArgs()...)
// gcc-4.5 and beyond require explicit "-pthread" flag // gcc-4.5 and beyond require explicit "-pthread" flag
// for multithreading with pthread library. // for multithreading with pthread library.
if buildContext.CgoEnabled { if cfg.BuildContext.CgoEnabled {
switch goos { switch cfg.Goos {
case "windows": case "windows":
a = append(a, "-mthreads") a = append(a, "-mthreads")
default: default:
...@@ -3168,7 +3145,7 @@ func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string { ...@@ -3168,7 +3145,7 @@ func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
// On OS X, some of the compilers behave as if -fno-common // On OS X, some of the compilers behave as if -fno-common
// is always set, and the Mach-O linker in 6l/8l assumes this. // is always set, and the Mach-O linker in 6l/8l assumes this.
// See https://golang.org/issue/3253. // See https://golang.org/issue/3253.
if goos == "darwin" { if cfg.Goos == "darwin" {
a = append(a, "-fno-common") a = append(a, "-fno-common")
} }
...@@ -3197,9 +3174,9 @@ func (b *builder) gccSupportsFlag(flag string) bool { ...@@ -3197,9 +3174,9 @@ func (b *builder) gccSupportsFlag(flag string) bool {
b.flagCache = make(map[string]bool) b.flagCache = make(map[string]bool)
} }
cmdArgs := append(envList("CC", defaultCC), flag, "-c", "trivial.c") cmdArgs := append(envList("CC", defaultCC), flag, "-c", "trivial.c")
if buildN || buildX { if cfg.BuildN || cfg.BuildX {
b.showcmd(b.work, "%s", joinUnambiguously(cmdArgs)) b.showcmd(b.work, "%s", joinUnambiguously(cmdArgs))
if buildN { if cfg.BuildN {
return false return false
} }
} }
...@@ -3214,7 +3191,7 @@ func (b *builder) gccSupportsFlag(flag string) bool { ...@@ -3214,7 +3191,7 @@ func (b *builder) gccSupportsFlag(flag string) bool {
// gccArchArgs returns arguments to pass to gcc based on the architecture. // gccArchArgs returns arguments to pass to gcc based on the architecture.
func (b *builder) gccArchArgs() []string { func (b *builder) gccArchArgs() []string {
switch goarch { switch cfg.Goarch {
case "386": case "386":
return []string{"-m32"} return []string{"-m32"}
case "amd64", "amd64p32": case "amd64", "amd64p32":
...@@ -3278,7 +3255,7 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil ...@@ -3278,7 +3255,7 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil
} }
} }
if buildMSan { if cfg.BuildMSan {
cgoCFLAGS = append([]string{"-fsanitize=memory"}, cgoCFLAGS...) cgoCFLAGS = append([]string{"-fsanitize=memory"}, cgoCFLAGS...)
cgoLDFLAGS = append([]string{"-fsanitize=memory"}, cgoLDFLAGS...) cgoLDFLAGS = append([]string{"-fsanitize=memory"}, cgoLDFLAGS...)
} }
...@@ -3330,8 +3307,8 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil ...@@ -3330,8 +3307,8 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil
cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")} cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
} }
if buildToolchainName == "gccgo" { if cfg.BuildToolchainName == "gccgo" {
switch goarch { switch cfg.Goarch {
case "386", "amd64": case "386", "amd64":
cgoCFLAGS = append(cgoCFLAGS, "-fsplit-stack") cgoCFLAGS = append(cgoCFLAGS, "-fsplit-stack")
} }
...@@ -3341,7 +3318,7 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil ...@@ -3341,7 +3318,7 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil
} }
} }
switch buildBuildmode { switch cfg.BuildBuildmode {
case "c-archive", "c-shared": case "c-archive", "c-shared":
// Tell cgo that if there are any exported functions // Tell cgo that if there are any exported functions
// it should generate a header file that C code can // it should generate a header file that C code can
...@@ -3349,7 +3326,7 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil ...@@ -3349,7 +3326,7 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil
cgoflags = append(cgoflags, "-exportheader="+obj+"_cgo_install.h") cgoflags = append(cgoflags, "-exportheader="+obj+"_cgo_install.h")
} }
if err := b.run(p.Dir, p.ImportPath, cgoenv, buildToolExec, cgoExe, srcdirarg, "-objdir", obj, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, cgofiles); err != nil { if err := b.run(p.Dir, p.ImportPath, cgoenv, cfg.BuildToolexec, cgoExe, srcdirarg, "-objdir", obj, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, cgofiles); err != nil {
return nil, nil, err return nil, nil, err
} }
outGo = append(outGo, gofiles...) outGo = append(outGo, gofiles...)
...@@ -3402,7 +3379,7 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil ...@@ -3402,7 +3379,7 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil
outObj = append(outObj, ofile) outObj = append(outObj, ofile)
} }
switch buildToolchainName { switch cfg.BuildToolchainName {
case "gc": case "gc":
importGo := obj + "_cgo_import.go" importGo := obj + "_cgo_import.go"
if err := b.dynimport(p, obj, importGo, cgoExe, cflags, cgoLDFLAGS, outObj); err != nil { if err := b.dynimport(p, obj, importGo, cgoExe, cflags, cgoLDFLAGS, outObj); err != nil {
...@@ -3446,7 +3423,7 @@ func (b *builder) dynimport(p *Package, obj, importGo, cgoExe string, cflags, cg ...@@ -3446,7 +3423,7 @@ func (b *builder) dynimport(p *Package, obj, importGo, cgoExe string, cflags, cg
// we need to use -pie for Linux/ARM to get accurate imported sym // we need to use -pie for Linux/ARM to get accurate imported sym
ldflags := cgoLDFLAGS ldflags := cgoLDFLAGS
if (goarch == "arm" && goos == "linux") || goos == "android" { if (cfg.Goarch == "arm" && cfg.Goos == "linux") || cfg.Goos == "android" {
ldflags = append(ldflags, "-pie") ldflags = append(ldflags, "-pie")
} }
if err := b.gccld(p, dynobj, ldflags, linkobj); err != nil { if err := b.gccld(p, dynobj, ldflags, linkobj); err != nil {
...@@ -3458,7 +3435,7 @@ func (b *builder) dynimport(p *Package, obj, importGo, cgoExe string, cflags, cg ...@@ -3458,7 +3435,7 @@ func (b *builder) dynimport(p *Package, obj, importGo, cgoExe string, cflags, cg
if p.Standard && p.ImportPath == "runtime/cgo" { if p.Standard && p.ImportPath == "runtime/cgo" {
cgoflags = []string{"-dynlinker"} // record path to dynamic linker cgoflags = []string{"-dynlinker"} // record path to dynamic linker
} }
return b.run(p.Dir, p.ImportPath, nil, buildToolExec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags) return b.run(p.Dir, p.ImportPath, nil, cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags)
} }
// collect partially links the object files outObj into a single // collect partially links the object files outObj into a single
...@@ -3477,7 +3454,7 @@ func (b *builder) collect(p *Package, obj, ofile string, cgoLDFLAGS, outObj []st ...@@ -3477,7 +3454,7 @@ func (b *builder) collect(p *Package, obj, ofile string, cgoLDFLAGS, outObj []st
i++ i++
} }
// skip "-framework X" on Darwin // skip "-framework X" on Darwin
case goos == "darwin" && f == "-framework": case cfg.Goos == "darwin" && f == "-framework":
i++ i++
// skip "*.{dylib,so,dll,o,a}" // skip "*.{dylib,so,dll,o,a}"
case strings.HasSuffix(f, ".dylib"), case strings.HasSuffix(f, ".dylib"),
...@@ -3642,7 +3619,7 @@ const i int = 1 << 32 ...@@ -3642,7 +3619,7 @@ const i int = 1 << 32
// Determine the size of int on the target system for the -intgosize option // Determine the size of int on the target system for the -intgosize option
// of swig >= 2.0.9. Run only once. // of swig >= 2.0.9. Run only once.
func (b *builder) swigDoIntSize(obj string) (intsize string, err error) { func (b *builder) swigDoIntSize(obj string) (intsize string, err error) {
if buildN { if cfg.BuildN {
return "$INTBITS", nil return "$INTBITS", nil
} }
src := filepath.Join(b.work, "swig_intsize.go") src := filepath.Join(b.work, "swig_intsize.go")
...@@ -3690,7 +3667,7 @@ func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx b ...@@ -3690,7 +3667,7 @@ func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx b
gccExt = "cxx" gccExt = "cxx"
} }
gccgo := buildToolchainName == "gccgo" gccgo := cfg.BuildToolchainName == "gccgo"
// swig // swig
args := []string{ args := []string{
...@@ -3747,7 +3724,7 @@ func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx b ...@@ -3747,7 +3724,7 @@ func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx b
// do, but only on systems likely to support it, which is to say, // do, but only on systems likely to support it, which is to say,
// systems that normally use gold or the GNU linker. // systems that normally use gold or the GNU linker.
func (b *builder) disableBuildID(ldflags []string) []string { func (b *builder) disableBuildID(ldflags []string) []string {
switch goos { switch cfg.Goos {
case "android", "dragonfly", "linux", "netbsd": case "android", "dragonfly", "linux", "netbsd":
ldflags = append(ldflags, "-Wl,--build-id=none") ldflags = append(ldflags, "-Wl,--build-id=none")
} }
...@@ -3778,41 +3755,41 @@ func (q *actionQueue) pop() *action { ...@@ -3778,41 +3755,41 @@ func (q *actionQueue) pop() *action {
} }
func instrumentInit() { func instrumentInit() {
if !buildRace && !buildMSan { if !cfg.BuildRace && !cfg.BuildMSan {
return return
} }
if buildRace && buildMSan { if cfg.BuildRace && cfg.BuildMSan {
fmt.Fprintf(os.Stderr, "go %s: may not use -race and -msan simultaneously\n", flag.Args()[0]) fmt.Fprintf(os.Stderr, "go %s: may not use -race and -msan simultaneously\n", flag.Args()[0])
os.Exit(2) os.Exit(2)
} }
if buildMSan && (goos != "linux" || goarch != "amd64") { if cfg.BuildMSan && (cfg.Goos != "linux" || cfg.Goarch != "amd64") {
fmt.Fprintf(os.Stderr, "-msan is not supported on %s/%s\n", goos, goarch) fmt.Fprintf(os.Stderr, "-msan is not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
os.Exit(2) os.Exit(2)
} }
if goarch != "amd64" || goos != "linux" && goos != "freebsd" && goos != "darwin" && goos != "windows" { if cfg.Goarch != "amd64" || cfg.Goos != "linux" && cfg.Goos != "freebsd" && cfg.Goos != "darwin" && cfg.Goos != "windows" {
fmt.Fprintf(os.Stderr, "go %s: -race and -msan are only supported on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0]) fmt.Fprintf(os.Stderr, "go %s: -race and -msan are only supported on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0])
os.Exit(2) os.Exit(2)
} }
if !buildContext.CgoEnabled { if !cfg.BuildContext.CgoEnabled {
fmt.Fprintf(os.Stderr, "go %s: -race requires cgo; enable cgo by setting CGO_ENABLED=1\n", flag.Args()[0]) fmt.Fprintf(os.Stderr, "go %s: -race requires cgo; enable cgo by setting CGO_ENABLED=1\n", flag.Args()[0])
os.Exit(2) os.Exit(2)
} }
if buildRace { if cfg.BuildRace {
buildGcflags = append(buildGcflags, "-race") buildGcflags = append(buildGcflags, "-race")
buildLdflags = append(buildLdflags, "-race") cfg.BuildLdflags = append(cfg.BuildLdflags, "-race")
} else { } else {
buildGcflags = append(buildGcflags, "-msan") buildGcflags = append(buildGcflags, "-msan")
buildLdflags = append(buildLdflags, "-msan") cfg.BuildLdflags = append(cfg.BuildLdflags, "-msan")
} }
if buildContext.InstallSuffix != "" { if cfg.BuildContext.InstallSuffix != "" {
buildContext.InstallSuffix += "_" cfg.BuildContext.InstallSuffix += "_"
} }
if buildRace { if cfg.BuildRace {
buildContext.InstallSuffix += "race" cfg.BuildContext.InstallSuffix += "race"
buildContext.BuildTags = append(buildContext.BuildTags, "race") cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, "race")
} else { } else {
buildContext.InstallSuffix += "msan" cfg.BuildContext.InstallSuffix += "msan"
buildContext.BuildTags = append(buildContext.BuildTags, "msan") cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, "msan")
} }
} }
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package main package main
import ( import (
"cmd/go/internal/cfg"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
...@@ -172,7 +173,7 @@ func clean(p *Package) { ...@@ -172,7 +173,7 @@ func clean(p *Package) {
} }
} }
if buildN || buildX { if cfg.BuildN || cfg.BuildX {
b.showcmd(p.Dir, "rm -f %s", strings.Join(allRemove, " ")) b.showcmd(p.Dir, "rm -f %s", strings.Join(allRemove, " "))
} }
...@@ -185,9 +186,9 @@ func clean(p *Package) { ...@@ -185,9 +186,9 @@ func clean(p *Package) {
if dir.IsDir() { if dir.IsDir() {
// TODO: Remove once Makefiles are forgotten. // TODO: Remove once Makefiles are forgotten.
if cleanDir[name] { if cleanDir[name] {
if buildN || buildX { if cfg.BuildN || cfg.BuildX {
b.showcmd(p.Dir, "rm -r %s", name) b.showcmd(p.Dir, "rm -r %s", name)
if buildN { if cfg.BuildN {
continue continue
} }
} }
...@@ -198,7 +199,7 @@ func clean(p *Package) { ...@@ -198,7 +199,7 @@ func clean(p *Package) {
continue continue
} }
if buildN { if cfg.BuildN {
continue continue
} }
...@@ -208,10 +209,10 @@ func clean(p *Package) { ...@@ -208,10 +209,10 @@ func clean(p *Package) {
} }
if cleanI && p.target != "" { if cleanI && p.target != "" {
if buildN || buildX { if cfg.BuildN || cfg.BuildX {
b.showcmd("", "rm -f %s", p.target) b.showcmd("", "rm -f %s", p.target)
} }
if !buildN { if !cfg.BuildN {
removeFile(p.target) removeFile(p.target)
} }
} }
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
package main package main
import "cmd/go/internal/cfg"
var cmdDoc = &Command{ var cmdDoc = &Command{
Run: runDoc, Run: runDoc,
UsageLine: "doc [-u] [-c] [package|[package.]symbol[.method]]", UsageLine: "doc [-u] [-c] [package|[package.]symbol[.method]]",
...@@ -114,5 +116,5 @@ Flags: ...@@ -114,5 +116,5 @@ Flags:
} }
func runDoc(cmd *Command, args []string) { func runDoc(cmd *Command, args []string) {
run(buildToolExec, tool("doc"), args) run(cfg.BuildToolexec, tool("doc"), args)
} }
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package main package main
import ( import (
"cmd/go/internal/cfg"
"fmt" "fmt"
"os" "os"
"runtime" "runtime"
...@@ -25,22 +26,18 @@ each named variable on its own line. ...@@ -25,22 +26,18 @@ each named variable on its own line.
`, `,
} }
type envVar struct { func mkEnv() []cfg.EnvVar {
name, value string
}
func mkEnv() []envVar {
var b builder var b builder
b.init() b.init()
env := []envVar{ env := []cfg.EnvVar{
{"GOARCH", goarch}, {"GOARCH", cfg.Goarch},
{"GOBIN", gobin}, {"GOBIN", gobin},
{"GOEXE", exeSuffix}, {"GOEXE", cfg.ExeSuffix},
{"GOHOSTARCH", runtime.GOARCH}, {"GOHOSTARCH", runtime.GOARCH},
{"GOHOSTOS", runtime.GOOS}, {"GOHOSTOS", runtime.GOOS},
{"GOOS", goos}, {"GOOS", cfg.Goos},
{"GOPATH", buildContext.GOPATH}, {"GOPATH", cfg.BuildContext.GOPATH},
{"GORACE", os.Getenv("GORACE")}, {"GORACE", os.Getenv("GORACE")},
{"GOROOT", goroot}, {"GOROOT", goroot},
{"GOTOOLDIR", toolDir}, {"GOTOOLDIR", toolDir},
...@@ -50,48 +47,48 @@ func mkEnv() []envVar { ...@@ -50,48 +47,48 @@ func mkEnv() []envVar {
} }
if gccgoBin != "" { if gccgoBin != "" {
env = append(env, envVar{"GCCGO", gccgoBin}) env = append(env, cfg.EnvVar{"GCCGO", gccgoBin})
} else { } else {
env = append(env, envVar{"GCCGO", gccgoName}) env = append(env, cfg.EnvVar{"GCCGO", gccgoName})
} }
switch goarch { switch cfg.Goarch {
case "arm": case "arm":
env = append(env, envVar{"GOARM", os.Getenv("GOARM")}) env = append(env, cfg.EnvVar{"GOARM", os.Getenv("GOARM")})
case "386": case "386":
env = append(env, envVar{"GO386", os.Getenv("GO386")}) env = append(env, cfg.EnvVar{"GO386", os.Getenv("GO386")})
} }
cmd := b.gccCmd(".") cmd := b.gccCmd(".")
env = append(env, envVar{"CC", cmd[0]}) env = append(env, cfg.EnvVar{"CC", cmd[0]})
env = append(env, envVar{"GOGCCFLAGS", strings.Join(cmd[3:], " ")}) env = append(env, cfg.EnvVar{"GOGCCFLAGS", strings.Join(cmd[3:], " ")})
cmd = b.gxxCmd(".") cmd = b.gxxCmd(".")
env = append(env, envVar{"CXX", cmd[0]}) env = append(env, cfg.EnvVar{"CXX", cmd[0]})
if buildContext.CgoEnabled { if cfg.BuildContext.CgoEnabled {
env = append(env, envVar{"CGO_ENABLED", "1"}) env = append(env, cfg.EnvVar{"CGO_ENABLED", "1"})
} else { } else {
env = append(env, envVar{"CGO_ENABLED", "0"}) env = append(env, cfg.EnvVar{"CGO_ENABLED", "0"})
} }
return env return env
} }
func findEnv(env []envVar, name string) string { func findEnv(env []cfg.EnvVar, name string) string {
for _, e := range env { for _, e := range env {
if e.name == name { if e.Name == name {
return e.value return e.Value
} }
} }
return "" return ""
} }
// extraEnvVars returns environment variables that should not leak into child processes. // extraEnvVars returns environment variables that should not leak into child processes.
func extraEnvVars() []envVar { func extraEnvVars() []cfg.EnvVar {
var b builder var b builder
b.init() b.init()
cppflags, cflags, cxxflags, fflags, ldflags := b.cflags(&Package{}) cppflags, cflags, cxxflags, fflags, ldflags := b.cflags(&Package{})
return []envVar{ return []cfg.EnvVar{
{"PKG_CONFIG", b.pkgconfigCmd()}, {"PKG_CONFIG", b.pkgconfigCmd()},
{"CGO_CFLAGS", strings.Join(cflags, " ")}, {"CGO_CFLAGS", strings.Join(cflags, " ")},
{"CGO_CPPFLAGS", strings.Join(cppflags, " ")}, {"CGO_CPPFLAGS", strings.Join(cppflags, " ")},
...@@ -102,7 +99,7 @@ func extraEnvVars() []envVar { ...@@ -102,7 +99,7 @@ func extraEnvVars() []envVar {
} }
func runEnv(cmd *Command, args []string) { func runEnv(cmd *Command, args []string) {
env := newEnv env := cfg.NewEnv
env = append(env, extraEnvVars()...) env = append(env, extraEnvVars()...)
if len(args) > 0 { if len(args) > 0 {
for _, name := range args { for _, name := range args {
...@@ -112,16 +109,16 @@ func runEnv(cmd *Command, args []string) { ...@@ -112,16 +109,16 @@ func runEnv(cmd *Command, args []string) {
} }
for _, e := range env { for _, e := range env {
if e.name != "TERM" { if e.Name != "TERM" {
switch runtime.GOOS { switch runtime.GOOS {
default: default:
fmt.Printf("%s=\"%s\"\n", e.name, e.value) fmt.Printf("%s=\"%s\"\n", e.Name, e.Value)
case "plan9": case "plan9":
if strings.IndexByte(e.value, '\x00') < 0 { if strings.IndexByte(e.Value, '\x00') < 0 {
fmt.Printf("%s='%s'\n", e.name, strings.Replace(e.value, "'", "''", -1)) fmt.Printf("%s='%s'\n", e.Name, strings.Replace(e.Value, "'", "''", -1))
} else { } else {
v := strings.Split(e.value, "\x00") v := strings.Split(e.Value, "\x00")
fmt.Printf("%s=(", e.name) fmt.Printf("%s=(", e.Name)
for x, s := range v { for x, s := range v {
if x > 0 { if x > 0 {
fmt.Printf(" ") fmt.Printf(" ")
...@@ -131,7 +128,7 @@ func runEnv(cmd *Command, args []string) { ...@@ -131,7 +128,7 @@ func runEnv(cmd *Command, args []string) {
fmt.Printf(")\n") fmt.Printf(")\n")
} }
case "windows": case "windows":
fmt.Printf("set %s=%s\n", e.name, e.value) fmt.Printf("set %s=%s\n", e.Name, e.Value)
} }
} }
} }
......
...@@ -4,7 +4,10 @@ ...@@ -4,7 +4,10 @@
package main package main
import "cmd/go/internal/str" import (
"cmd/go/internal/cfg"
"cmd/go/internal/str"
)
var cmdFix = &Command{ var cmdFix = &Command{
Run: runFix, Run: runFix,
...@@ -27,6 +30,6 @@ func runFix(cmd *Command, args []string) { ...@@ -27,6 +30,6 @@ func runFix(cmd *Command, args []string) {
// Use pkg.gofiles instead of pkg.Dir so that // Use pkg.gofiles instead of pkg.Dir so that
// the command only applies to this package, // the command only applies to this package,
// not to packages in subdirectories. // not to packages in subdirectories.
run(str.StringList(buildToolExec, tool("fix"), relPaths(pkg.allgofiles))) run(str.StringList(cfg.BuildToolexec, tool("fix"), relPaths(pkg.allgofiles)))
} }
} }
...@@ -7,6 +7,7 @@ package main ...@@ -7,6 +7,7 @@ package main
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"cmd/go/internal/cfg"
"fmt" "fmt"
"io" "io"
"log" "log"
...@@ -200,7 +201,7 @@ func (g *Generator) run() (ok bool) { ...@@ -200,7 +201,7 @@ func (g *Generator) run() (ok bool) {
}() }()
g.dir, g.file = filepath.Split(g.path) g.dir, g.file = filepath.Split(g.path)
g.dir = filepath.Clean(g.dir) // No final separator please. g.dir = filepath.Clean(g.dir) // No final separator please.
if buildV { if cfg.BuildV {
fmt.Fprintf(os.Stderr, "%s\n", shortPath(g.path)) fmt.Fprintf(os.Stderr, "%s\n", shortPath(g.path))
} }
...@@ -255,10 +256,10 @@ func (g *Generator) run() (ok bool) { ...@@ -255,10 +256,10 @@ func (g *Generator) run() (ok bool) {
continue continue
} }
// Run the command line. // Run the command line.
if buildN || buildX { if cfg.BuildN || cfg.BuildX {
fmt.Fprintf(os.Stderr, "%s\n", strings.Join(words, " ")) fmt.Fprintf(os.Stderr, "%s\n", strings.Join(words, " "))
} }
if buildN { if cfg.BuildN {
continue continue
} }
g.exec(words) g.exec(words)
...@@ -277,8 +278,8 @@ func isGoGenerate(buf []byte) bool { ...@@ -277,8 +278,8 @@ func isGoGenerate(buf []byte) bool {
// single go:generate command. // single go:generate command.
func (g *Generator) setEnv() { func (g *Generator) setEnv() {
g.env = []string{ g.env = []string{
"GOARCH=" + buildContext.GOARCH, "GOARCH=" + cfg.BuildContext.GOARCH,
"GOOS=" + buildContext.GOOS, "GOOS=" + cfg.BuildContext.GOOS,
"GOFILE=" + g.file, "GOFILE=" + g.file,
"GOLINE=" + strconv.Itoa(g.lineNum), "GOLINE=" + strconv.Itoa(g.lineNum),
"GOPACKAGE=" + g.pkg, "GOPACKAGE=" + g.pkg,
...@@ -393,7 +394,7 @@ func (g *Generator) exec(words []string) { ...@@ -393,7 +394,7 @@ func (g *Generator) exec(words []string) {
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
// Run the command in the package directory. // Run the command in the package directory.
cmd.Dir = g.dir cmd.Dir = g.dir
cmd.Env = mergeEnvLists(g.env, origEnv) cmd.Env = mergeEnvLists(g.env, cfg.OrigEnv)
err := cmd.Run() err := cmd.Run()
if err != nil { if err != nil {
g.errorf("running %q: %s", words[0], err) g.errorf("running %q: %s", words[0], err)
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package main package main
import ( import (
"cmd/go/internal/cfg"
"cmd/go/internal/str" "cmd/go/internal/str"
"fmt" "fmt"
"go/build" "go/build"
...@@ -303,7 +304,7 @@ func download(arg string, parent *Package, stk *importStack, mode int) { ...@@ -303,7 +304,7 @@ func download(arg string, parent *Package, stk *importStack, mode int) {
// due to wildcard expansion. // due to wildcard expansion.
for _, p := range pkgs { for _, p := range pkgs {
if *getFix { if *getFix {
run(buildToolExec, str.StringList(tool("fix"), relPaths(p.allgofiles))) run(cfg.BuildToolexec, str.StringList(tool("fix"), relPaths(p.allgofiles)))
// The imports might have changed, so reload again. // The imports might have changed, so reload again.
p = reloadPackage(arg, stk) p = reloadPackage(arg, stk)
...@@ -424,7 +425,7 @@ func downloadPackage(p *Package) error { ...@@ -424,7 +425,7 @@ func downloadPackage(p *Package) error {
if p.build.SrcRoot == "" { if p.build.SrcRoot == "" {
// Package not found. Put in first directory of $GOPATH. // Package not found. Put in first directory of $GOPATH.
list := filepath.SplitList(buildContext.GOPATH) list := filepath.SplitList(cfg.BuildContext.GOPATH)
if len(list) == 0 { if len(list) == 0 {
return fmt.Errorf("cannot download, $GOPATH not set. For more details see: 'go help gopath'") return fmt.Errorf("cannot download, $GOPATH not set. For more details see: 'go help gopath'")
} }
...@@ -446,7 +447,7 @@ func downloadPackage(p *Package) error { ...@@ -446,7 +447,7 @@ func downloadPackage(p *Package) error {
} }
downloadRootCache[root] = true downloadRootCache[root] = true
if buildV { if cfg.BuildV {
fmt.Fprintf(os.Stderr, "%s (download)\n", rootPath) fmt.Fprintf(os.Stderr, "%s (download)\n", rootPath)
} }
...@@ -473,7 +474,7 @@ func downloadPackage(p *Package) error { ...@@ -473,7 +474,7 @@ func downloadPackage(p *Package) error {
if err = os.MkdirAll(parent, 0777); err != nil { if err = os.MkdirAll(parent, 0777); err != nil {
return err return err
} }
if buildV && !gopathExisted && p.build.Root == buildContext.GOPATH { if cfg.BuildV && !gopathExisted && p.build.Root == cfg.BuildContext.GOPATH {
fmt.Fprintf(os.Stderr, "created GOPATH=%s; see 'go help gopath'\n", p.build.Root) fmt.Fprintf(os.Stderr, "created GOPATH=%s; see 'go help gopath'\n", p.build.Root)
} }
...@@ -487,7 +488,7 @@ func downloadPackage(p *Package) error { ...@@ -487,7 +488,7 @@ func downloadPackage(p *Package) error {
} }
} }
if buildN { if cfg.BuildN {
// Do not show tag sync in -n; it's noise more than anything, // Do not show tag sync in -n; it's noise more than anything,
// and since we're not running commands, no tag will be found. // and since we're not running commands, no tag will be found.
// But avoid printing nothing. // But avoid printing nothing.
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
package main package main
import ( import (
"cmd/go/internal/cfg"
"cmd/internal/browser" "cmd/internal/browser"
"crypto/tls" "crypto/tls"
"fmt" "fmt"
...@@ -79,7 +80,7 @@ func httpsOrHTTP(importPath string, security securityMode) (urlStr string, body ...@@ -79,7 +80,7 @@ func httpsOrHTTP(importPath string, security securityMode) (urlStr string, body
} }
u.RawQuery = "go-get=1" u.RawQuery = "go-get=1"
urlStr = u.String() urlStr = u.String()
if buildV { if cfg.BuildV {
log.Printf("Fetching %s", urlStr) log.Printf("Fetching %s", urlStr)
} }
if security == insecure && scheme == "https" { // fail earlier if security == insecure && scheme == "https" { // fail earlier
...@@ -96,7 +97,7 @@ func httpsOrHTTP(importPath string, security securityMode) (urlStr string, body ...@@ -96,7 +97,7 @@ func httpsOrHTTP(importPath string, security securityMode) (urlStr string, body
} }
urlStr, res, err := fetch("https") urlStr, res, err := fetch("https")
if err != nil { if err != nil {
if buildV { if cfg.BuildV {
log.Printf("https fetch failed: %v", err) log.Printf("https fetch failed: %v", err)
} }
if security == insecure { if security == insecure {
...@@ -110,7 +111,7 @@ func httpsOrHTTP(importPath string, security securityMode) (urlStr string, body ...@@ -110,7 +111,7 @@ func httpsOrHTTP(importPath string, security securityMode) (urlStr string, body
} }
// Note: accepting a non-200 OK here, so people can serve a // Note: accepting a non-200 OK here, so people can serve a
// meta import in their http 404 page. // meta import in their http 404 page.
if buildV { if cfg.BuildV {
log.Printf("Parsing meta tags from %s (status code %d)", urlStr, res.StatusCode) log.Printf("Parsing meta tags from %s (status code %d)", urlStr, res.StatusCode)
} }
return urlStr, res.Body, nil return urlStr, res.Body, nil
......
// 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 cfg holds configuration shared by multiple parts
// of the go command.
package cfg
import (
"go/build"
"runtime"
)
// These are general "build flags" used by build and other commands.
var (
BuildA bool // -a flag
BuildBuildmode string // -buildmode flag
BuildContext = build.Default
BuildI bool // -i flag
BuildLdflags []string // -ldflags flag
BuildLinkshared bool // -linkshared flag
BuildMSan bool // -msan flag
BuildN bool // -n flag
BuildO string // -o flag
BuildP = runtime.NumCPU() // -p flag
BuildPkgdir string // -pkgdir flag
BuildRace bool // -race flag
BuildToolexec []string // -toolexec flag
BuildToolchainName string
BuildToolchainCompiler string
BuildToolchainLinker string
BuildV bool // -v flag
BuildWork bool // -work flag
BuildX bool // -x flag
)
// The test coverage mode affects package loading. Sigh.
var TestCoverMode string // -covermode flag
// An EnvVar is an environment variable Name=Value.
type EnvVar struct {
Name string
Value string
}
// OrigEnv is the original environment of the program at startup.
var OrigEnv []string
// NewEnv is the new environment for running commands.
var NewEnv []EnvVar
// Global build parameters (used during package load)
var (
Goarch string
Goos string
ExeSuffix string
Gopath []string
)
...@@ -6,6 +6,7 @@ package main ...@@ -6,6 +6,7 @@ package main
import ( import (
"bufio" "bufio"
"cmd/go/internal/cfg"
"encoding/json" "encoding/json"
"io" "io"
"os" "os"
...@@ -165,7 +166,7 @@ func runList(cmd *Command, args []string) { ...@@ -165,7 +166,7 @@ func runList(cmd *Command, args []string) {
var cachedCtxt *Context var cachedCtxt *Context
context := func() *Context { context := func() *Context {
if cachedCtxt == nil { if cachedCtxt == nil {
cachedCtxt = newContext(&buildContext) cachedCtxt = newContext(&cfg.BuildContext)
} }
return cachedCtxt return cachedCtxt
} }
......
...@@ -7,6 +7,7 @@ package main ...@@ -7,6 +7,7 @@ package main
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"cmd/go/internal/cfg"
"cmd/go/internal/str" "cmd/go/internal/str"
"flag" "flag"
"fmt" "fmt"
...@@ -119,9 +120,6 @@ func setExitStatus(n int) { ...@@ -119,9 +120,6 @@ func setExitStatus(n int) {
exitMu.Unlock() exitMu.Unlock()
} }
var origEnv []string
var newEnv []envVar
func main() { func main() {
_ = go11tag _ = go11tag
flag.Usage = usage flag.Usage = usage
...@@ -141,7 +139,7 @@ func main() { ...@@ -141,7 +139,7 @@ func main() {
// Diagnose common mistake: GOPATH==GOROOT. // Diagnose common mistake: GOPATH==GOROOT.
// This setting is equivalent to not setting GOPATH at all, // This setting is equivalent to not setting GOPATH at all,
// which is not what most people want when they do it. // which is not what most people want when they do it.
if gopath := buildContext.GOPATH; gopath == runtime.GOROOT() { if gopath := cfg.BuildContext.GOPATH; gopath == runtime.GOROOT() {
fmt.Fprintf(os.Stderr, "warning: GOPATH set to GOROOT (%s) has no effect\n", gopath) fmt.Fprintf(os.Stderr, "warning: GOPATH set to GOROOT (%s) has no effect\n", gopath)
} else { } else {
for _, p := range filepath.SplitList(gopath) { for _, p := range filepath.SplitList(gopath) {
...@@ -169,11 +167,11 @@ func main() { ...@@ -169,11 +167,11 @@ func main() {
// the same default computation of these as we do, // the same default computation of these as we do,
// but in practice there might be skew // but in practice there might be skew
// This makes sure we all agree. // This makes sure we all agree.
origEnv = os.Environ() cfg.OrigEnv = os.Environ()
newEnv = mkEnv() cfg.NewEnv = mkEnv()
for _, env := range newEnv { for _, env := range cfg.NewEnv {
if os.Getenv(env.name) != env.value { if os.Getenv(env.Name) != env.Value {
os.Setenv(env.name, env.value) os.Setenv(env.Name, env.Value)
} }
} }
...@@ -455,9 +453,9 @@ func exitIfErrors() { ...@@ -455,9 +453,9 @@ func exitIfErrors() {
func run(cmdargs ...interface{}) { func run(cmdargs ...interface{}) {
cmdline := str.StringList(cmdargs...) cmdline := str.StringList(cmdargs...)
if buildN || buildX { if cfg.BuildN || cfg.BuildX {
fmt.Printf("%s\n", strings.Join(cmdline, " ")) fmt.Printf("%s\n", strings.Join(cmdline, " "))
if buildN { if cfg.BuildN {
return return
} }
} }
...@@ -602,12 +600,12 @@ func matchPackages(pattern string) []string { ...@@ -602,12 +600,12 @@ func matchPackages(pattern string) []string {
have := map[string]bool{ have := map[string]bool{
"builtin": true, // ignore pseudo-package that exists only for documentation "builtin": true, // ignore pseudo-package that exists only for documentation
} }
if !buildContext.CgoEnabled { if !cfg.BuildContext.CgoEnabled {
have["runtime/cgo"] = true // ignore during walk have["runtime/cgo"] = true // ignore during walk
} }
var pkgs []string var pkgs []string
for _, src := range buildContext.SrcDirs() { for _, src := range cfg.BuildContext.SrcDirs() {
if (pattern == "std" || pattern == "cmd") && src != gorootSrc { if (pattern == "std" || pattern == "cmd") && src != gorootSrc {
continue continue
} }
...@@ -643,7 +641,7 @@ func matchPackages(pattern string) []string { ...@@ -643,7 +641,7 @@ func matchPackages(pattern string) []string {
if !match(name) { if !match(name) {
return nil return nil
} }
_, err = buildContext.ImportDir(path, 0) _, err = cfg.BuildContext.ImportDir(path, 0)
if err != nil { if err != nil {
if _, noGo := err.(*build.NoGoError); noGo { if _, noGo := err.(*build.NoGoError); noGo {
return nil return nil
...@@ -720,7 +718,7 @@ func matchPackagesInFS(pattern string) []string { ...@@ -720,7 +718,7 @@ func matchPackagesInFS(pattern string) []string {
// as not matching the pattern. Go 1.5 and earlier skipped, but that // as not matching the pattern. Go 1.5 and earlier skipped, but that
// behavior means people miss serious mistakes. // behavior means people miss serious mistakes.
// See golang.org/issue/11407. // See golang.org/issue/11407.
if p, err := buildContext.ImportDir(path, 0); err != nil && (p == nil || len(p.InvalidGoFiles) == 0) { if p, err := cfg.BuildContext.ImportDir(path, 0); err != nil && (p == nil || len(p.InvalidGoFiles) == 0) {
if _, noGo := err.(*build.NoGoError); !noGo { if _, noGo := err.(*build.NoGoError); !noGo {
log.Print(err) log.Print(err)
} }
......
...@@ -6,6 +6,7 @@ package main ...@@ -6,6 +6,7 @@ package main
import ( import (
"bytes" "bytes"
"cmd/go/internal/cfg"
"cmd/go/internal/str" "cmd/go/internal/str"
"crypto/sha1" "crypto/sha1"
"errors" "errors"
...@@ -143,11 +144,11 @@ type CoverVar struct { ...@@ -143,11 +144,11 @@ type CoverVar struct {
func (p *Package) copyBuild(pp *build.Package) { func (p *Package) copyBuild(pp *build.Package) {
p.build = pp p.build = pp
if pp.PkgTargetRoot != "" && buildPkgdir != "" { if pp.PkgTargetRoot != "" && cfg.BuildPkgdir != "" {
old := pp.PkgTargetRoot old := pp.PkgTargetRoot
pp.PkgRoot = buildPkgdir pp.PkgRoot = cfg.BuildPkgdir
pp.PkgTargetRoot = buildPkgdir pp.PkgTargetRoot = cfg.BuildPkgdir
pp.PkgObj = filepath.Join(buildPkgdir, strings.TrimPrefix(pp.PkgObj, old)) pp.PkgObj = filepath.Join(cfg.BuildPkgdir, strings.TrimPrefix(pp.PkgObj, old))
} }
p.Dir = pp.Dir p.Dir = pp.Dir
...@@ -364,7 +365,7 @@ func loadImport(path, srcDir string, parent *Package, stk *importStack, importPo ...@@ -364,7 +365,7 @@ func loadImport(path, srcDir string, parent *Package, stk *importStack, importPo
// Not vendoring, or we already found the vendored path. // Not vendoring, or we already found the vendored path.
buildMode |= build.IgnoreVendor buildMode |= build.IgnoreVendor
} }
bp, err := buildContext.Import(path, srcDir, buildMode) bp, err := cfg.BuildContext.Import(path, srcDir, buildMode)
bp.ImportPath = importPath bp.ImportPath = importPath
if gobin != "" { if gobin != "" {
bp.BinDir = gobin bp.BinDir = gobin
...@@ -587,7 +588,7 @@ func disallowInternal(srcDir string, p *Package, stk *importStack) *Package { ...@@ -587,7 +588,7 @@ func disallowInternal(srcDir string, p *Package, stk *importStack) *Package {
} }
// We can't check standard packages with gccgo. // We can't check standard packages with gccgo.
if buildContext.Compiler == "gccgo" && p.Standard { if cfg.BuildContext.Compiler == "gccgo" && p.Standard {
return p return p
} }
...@@ -846,7 +847,7 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package ...@@ -846,7 +847,7 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
useBindir := p.Name == "main" useBindir := p.Name == "main"
if !p.Standard { if !p.Standard {
switch buildBuildmode { switch cfg.BuildBuildmode {
case "c-archive", "c-shared", "plugin": case "c-archive", "c-shared", "plugin":
useBindir = false useBindir = false
} }
...@@ -861,8 +862,8 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package ...@@ -861,8 +862,8 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
return p return p
} }
_, elem := filepath.Split(p.Dir) _, elem := filepath.Split(p.Dir)
full := buildContext.GOOS + "_" + buildContext.GOARCH + "/" + elem full := cfg.BuildContext.GOOS + "_" + cfg.BuildContext.GOARCH + "/" + elem
if buildContext.GOOS != toolGOOS || buildContext.GOARCH != toolGOARCH { if cfg.BuildContext.GOOS != toolGOOS || cfg.BuildContext.GOARCH != toolGOARCH {
// Install cross-compiled binaries to subdirectories of bin. // Install cross-compiled binaries to subdirectories of bin.
elem = full elem = full
} }
...@@ -880,7 +881,7 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package ...@@ -880,7 +881,7 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
// Override all the usual logic and force it into the tool directory. // Override all the usual logic and force it into the tool directory.
p.target = filepath.Join(gorootPkg, "tool", full) p.target = filepath.Join(gorootPkg, "tool", full)
} }
if p.target != "" && buildContext.GOOS == "windows" { if p.target != "" && cfg.BuildContext.GOOS == "windows" {
p.target += ".exe" p.target += ".exe"
} }
} else if p.local { } else if p.local {
...@@ -889,12 +890,12 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package ...@@ -889,12 +890,12 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
p.target = "" p.target = ""
} else { } else {
p.target = p.build.PkgObj p.target = p.build.PkgObj
if buildLinkshared { if cfg.BuildLinkshared {
shlibnamefile := p.target[:len(p.target)-2] + ".shlibname" shlibnamefile := p.target[:len(p.target)-2] + ".shlibname"
shlib, err := ioutil.ReadFile(shlibnamefile) shlib, err := ioutil.ReadFile(shlibnamefile)
if err == nil { if err == nil {
libname := strings.TrimSpace(string(shlib)) libname := strings.TrimSpace(string(shlib))
if buildContext.Compiler == "gccgo" { if cfg.BuildContext.Compiler == "gccgo" {
p.Shlib = filepath.Join(p.build.PkgTargetRoot, "shlibs", libname) p.Shlib = filepath.Join(p.build.PkgTargetRoot, "shlibs", libname)
} else { } else {
p.Shlib = filepath.Join(p.build.PkgTargetRoot, libname) p.Shlib = filepath.Join(p.build.PkgTargetRoot, libname)
...@@ -918,23 +919,23 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package ...@@ -918,23 +919,23 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
importPaths = append(importPaths, "syscall") importPaths = append(importPaths, "syscall")
} }
if buildContext.CgoEnabled && p.Name == "main" && !p.Goroot { if cfg.BuildContext.CgoEnabled && p.Name == "main" && !p.Goroot {
// Currently build modes c-shared, pie (on systems that do not // Currently build modes c-shared, pie (on systems that do not
// support PIE with internal linking mode), plugin, and // support PIE with internal linking mode), plugin, and
// -linkshared force external linking mode, as of course does // -linkshared force external linking mode, as of course does
// -ldflags=-linkmode=external. External linking mode forces // -ldflags=-linkmode=external. External linking mode forces
// an import of runtime/cgo. // an import of runtime/cgo.
pieCgo := buildBuildmode == "pie" && (buildContext.GOOS != "linux" || buildContext.GOARCH != "amd64") pieCgo := cfg.BuildBuildmode == "pie" && (cfg.BuildContext.GOOS != "linux" || cfg.BuildContext.GOARCH != "amd64")
linkmodeExternal := false linkmodeExternal := false
for i, a := range buildLdflags { for i, a := range cfg.BuildLdflags {
if a == "-linkmode=external" { if a == "-linkmode=external" {
linkmodeExternal = true linkmodeExternal = true
} }
if a == "-linkmode" && i+1 < len(buildLdflags) && buildLdflags[i+1] == "external" { if a == "-linkmode" && i+1 < len(cfg.BuildLdflags) && cfg.BuildLdflags[i+1] == "external" {
linkmodeExternal = true linkmodeExternal = true
} }
} }
if buildBuildmode == "c-shared" || buildBuildmode == "plugin" || pieCgo || buildLinkshared || linkmodeExternal { if cfg.BuildBuildmode == "c-shared" || cfg.BuildBuildmode == "plugin" || pieCgo || cfg.BuildLinkshared || linkmodeExternal {
importPaths = append(importPaths, "runtime/cgo") importPaths = append(importPaths, "runtime/cgo")
} }
} }
...@@ -945,19 +946,19 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package ...@@ -945,19 +946,19 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
importPaths = append(importPaths, "runtime") importPaths = append(importPaths, "runtime")
// When race detection enabled everything depends on runtime/race. // When race detection enabled everything depends on runtime/race.
// Exclude certain packages to avoid circular dependencies. // Exclude certain packages to avoid circular dependencies.
if buildRace && (!p.Standard || !raceExclude[p.ImportPath]) { if cfg.BuildRace && (!p.Standard || !raceExclude[p.ImportPath]) {
importPaths = append(importPaths, "runtime/race") importPaths = append(importPaths, "runtime/race")
} }
// MSan uses runtime/msan. // MSan uses runtime/msan.
if buildMSan && (!p.Standard || !raceExclude[p.ImportPath]) { if cfg.BuildMSan && (!p.Standard || !raceExclude[p.ImportPath]) {
importPaths = append(importPaths, "runtime/msan") importPaths = append(importPaths, "runtime/msan")
} }
// On ARM with GOARM=5, everything depends on math for the link. // On ARM with GOARM=5, everything depends on math for the link.
if p.Name == "main" && goarch == "arm" { if p.Name == "main" && cfg.Goarch == "arm" {
importPaths = append(importPaths, "math") importPaths = append(importPaths, "math")
} }
// In coverage atomic mode everything depends on sync/atomic. // In coverage atomic mode everything depends on sync/atomic.
if testCoverMode == "atomic" && (!p.Standard || (p.ImportPath != "runtime/cgo" && p.ImportPath != "runtime/race" && p.ImportPath != "sync/atomic")) { if cfg.TestCoverMode == "atomic" && (!p.Standard || (p.ImportPath != "runtime/cgo" && p.ImportPath != "runtime/race" && p.ImportPath != "sync/atomic")) {
importPaths = append(importPaths, "sync/atomic") importPaths = append(importPaths, "sync/atomic")
} }
} }
...@@ -1082,14 +1083,14 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package ...@@ -1082,14 +1083,14 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
} }
// unsafe is a fake package. // unsafe is a fake package.
if p.Standard && (p.ImportPath == "unsafe" || buildContext.Compiler == "gccgo") { if p.Standard && (p.ImportPath == "unsafe" || cfg.BuildContext.Compiler == "gccgo") {
p.target = "" p.target = ""
} }
p.Target = p.target p.Target = p.target
// If cgo is not enabled, ignore cgo supporting sources // If cgo is not enabled, ignore cgo supporting sources
// just as we ignore go files containing import "C". // just as we ignore go files containing import "C".
if !buildContext.CgoEnabled { if !cfg.BuildContext.CgoEnabled {
p.CFiles = nil p.CFiles = nil
p.CXXFiles = nil p.CXXFiles = nil
p.MFiles = nil p.MFiles = nil
...@@ -1102,7 +1103,7 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package ...@@ -1102,7 +1103,7 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
} }
// The gc toolchain only permits C source files with cgo. // The gc toolchain only permits C source files with cgo.
if len(p.CFiles) > 0 && !p.usesCgo() && !p.usesSwig() && buildContext.Compiler == "gc" { if len(p.CFiles) > 0 && !p.usesCgo() && !p.usesSwig() && cfg.BuildContext.Compiler == "gc" {
p.Error = &PackageError{ p.Error = &PackageError{
ImportStack: stk.copy(), ImportStack: stk.copy(),
Err: fmt.Sprintf("C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CFiles, " ")), Err: fmt.Sprintf("C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CFiles, " ")),
...@@ -1445,7 +1446,7 @@ var isGoRelease = strings.HasPrefix(runtime.Version(), "go1") ...@@ -1445,7 +1446,7 @@ var isGoRelease = strings.HasPrefix(runtime.Version(), "go1")
// isStale reports whether package p needs to be rebuilt, // isStale reports whether package p needs to be rebuilt,
// along with the reason why. // along with the reason why.
func isStale(p *Package) (bool, string) { func isStale(p *Package) (bool, string) {
if p.Standard && (p.ImportPath == "unsafe" || buildContext.Compiler == "gccgo") { if p.Standard && (p.ImportPath == "unsafe" || cfg.BuildContext.Compiler == "gccgo") {
// fake, builtin package // fake, builtin package
return false, "builtin package" return false, "builtin package"
} }
...@@ -1473,7 +1474,7 @@ func isStale(p *Package) (bool, string) { ...@@ -1473,7 +1474,7 @@ func isStale(p *Package) (bool, string) {
} }
// If the -a flag is given, rebuild everything. // If the -a flag is given, rebuild everything.
if buildA { if cfg.BuildA {
return true, "build -a flag in use" return true, "build -a flag in use"
} }
...@@ -1560,10 +1561,10 @@ func isStale(p *Package) (bool, string) { ...@@ -1560,10 +1561,10 @@ func isStale(p *Package) (bool, string) {
// Excluding $GOROOT used to also fix issue 4106, but that's now // Excluding $GOROOT used to also fix issue 4106, but that's now
// taken care of above (at least when the installed Go is a released version). // taken care of above (at least when the installed Go is a released version).
if p.Root != goroot { if p.Root != goroot {
if olderThan(buildToolchainCompiler) { if olderThan(cfg.BuildToolchainCompiler) {
return true, "newer compiler" return true, "newer compiler"
} }
if p.build.IsCommand() && olderThan(buildToolchainLinker) { if p.build.IsCommand() && olderThan(cfg.BuildToolchainLinker) {
return true, "newer linker" return true, "newer linker"
} }
} }
...@@ -1643,7 +1644,7 @@ func computeBuildID(p *Package) { ...@@ -1643,7 +1644,7 @@ func computeBuildID(p *Package) {
// Include the content of runtime/internal/sys/zversion.go in the hash // Include the content of runtime/internal/sys/zversion.go in the hash
// for package runtime. This will give package runtime a // for package runtime. This will give package runtime a
// different build ID in each Go release. // different build ID in each Go release.
if p.Standard && p.ImportPath == "runtime/internal/sys" && buildContext.Compiler != "gccgo" { if p.Standard && p.ImportPath == "runtime/internal/sys" && cfg.BuildContext.Compiler != "gccgo" {
data, err := ioutil.ReadFile(filepath.Join(p.Dir, "zversion.go")) data, err := ioutil.ReadFile(filepath.Join(p.Dir, "zversion.go"))
if err != nil { if err != nil {
fatalf("go: %s", err) fatalf("go: %s", err)
...@@ -1694,7 +1695,7 @@ func loadPackage(arg string, stk *importStack) *Package { ...@@ -1694,7 +1695,7 @@ func loadPackage(arg string, stk *importStack) *Package {
stk.push(arg) stk.push(arg)
defer stk.pop() defer stk.pop()
bp, err := buildContext.ImportDir(filepath.Join(gorootSrc, arg), 0) bp, err := cfg.BuildContext.ImportDir(filepath.Join(gorootSrc, arg), 0)
bp.ImportPath = arg bp.ImportPath = arg
bp.Goroot = true bp.Goroot = true
bp.BinDir = gorootBin bp.BinDir = gorootBin
...@@ -1722,7 +1723,7 @@ func loadPackage(arg string, stk *importStack) *Package { ...@@ -1722,7 +1723,7 @@ func loadPackage(arg string, stk *importStack) *Package {
// referring to io/ioutil rather than a hypothetical import of // referring to io/ioutil rather than a hypothetical import of
// "./ioutil". // "./ioutil".
if build.IsLocalImport(arg) { if build.IsLocalImport(arg) {
bp, _ := buildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly) bp, _ := cfg.BuildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly)
if bp.ImportPath != "" && bp.ImportPath != "." { if bp.ImportPath != "" && bp.ImportPath != "." {
arg = bp.ImportPath arg = bp.ImportPath
} }
...@@ -1867,7 +1868,7 @@ var ( ...@@ -1867,7 +1868,7 @@ var (
// It only supports the gc toolchain. // It only supports the gc toolchain.
// Other toolchain maintainers should adjust this function. // Other toolchain maintainers should adjust this function.
func readBuildID(name, target string) (id string, err error) { func readBuildID(name, target string) (id string, err error) {
if buildToolchainName != "gc" { if cfg.BuildToolchainName != "gc" {
return "", errBuildIDToolchain return "", errBuildIDToolchain
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package main package main
import ( import (
"cmd/go/internal/cfg"
"cmd/go/internal/str" "cmd/go/internal/str"
"io/ioutil" "io/ioutil"
"os" "os"
...@@ -160,9 +161,9 @@ func TestSharedLibName(t *testing.T) { ...@@ -160,9 +161,9 @@ func TestSharedLibName(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
oldGopath := buildContext.GOPATH oldGopath := cfg.BuildContext.GOPATH
defer func() { defer func() {
buildContext.GOPATH = oldGopath cfg.BuildContext.GOPATH = oldGopath
os.Chdir(cwd) os.Chdir(cwd)
err := os.RemoveAll(tmpGopath) err := os.RemoveAll(tmpGopath)
if err != nil { if err != nil {
...@@ -174,7 +175,7 @@ func TestSharedLibName(t *testing.T) { ...@@ -174,7 +175,7 @@ func TestSharedLibName(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
buildContext.GOPATH = tmpGopath cfg.BuildContext.GOPATH = tmpGopath
os.Chdir(root) os.Chdir(root)
} }
computed, err := libname(data.args, data.pkgs) computed, err := libname(data.args, data.pkgs)
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package main package main
import ( import (
"cmd/go/internal/cfg"
"cmd/go/internal/str" "cmd/go/internal/str"
"fmt" "fmt"
"os" "os"
...@@ -20,10 +21,10 @@ func findExecCmd() []string { ...@@ -20,10 +21,10 @@ func findExecCmd() []string {
return execCmd return execCmd
} }
execCmd = []string{} // avoid work the second time execCmd = []string{} // avoid work the second time
if goos == runtime.GOOS && goarch == runtime.GOARCH { if cfg.Goos == runtime.GOOS && cfg.Goarch == runtime.GOARCH {
return execCmd return execCmd
} }
path, err := exec.LookPath(fmt.Sprintf("go_%s_%s_exec", goos, goarch)) path, err := exec.LookPath(fmt.Sprintf("go_%s_%s_exec", cfg.Goos, cfg.Goarch))
if err == nil { if err == nil {
execCmd = []string{path} execCmd = []string{path}
} }
...@@ -117,7 +118,7 @@ func runRun(cmd *Command, args []string) { ...@@ -117,7 +118,7 @@ func runRun(cmd *Command, args []string) {
// this case could only happen if the provided source uses cgo // this case could only happen if the provided source uses cgo
// while cgo is disabled. // while cgo is disabled.
hint := "" hint := ""
if !buildContext.CgoEnabled { if !cfg.BuildContext.CgoEnabled {
hint = " (cgo is disabled)" hint = " (cgo is disabled)"
} }
fatalf("go run: no suitable source files%s", hint) fatalf("go run: no suitable source files%s", hint)
...@@ -132,9 +133,9 @@ func runRun(cmd *Command, args []string) { ...@@ -132,9 +133,9 @@ func runRun(cmd *Command, args []string) {
// been compiled. We ignore exit status. // been compiled. We ignore exit status.
func (b *builder) runProgram(a *action) error { func (b *builder) runProgram(a *action) error {
cmdline := str.StringList(findExecCmd(), a.deps[0].target, a.args) cmdline := str.StringList(findExecCmd(), a.deps[0].target, a.args)
if buildN || buildX { if cfg.BuildN || cfg.BuildX {
b.showcmd("", "%s", strings.Join(cmdline, " ")) b.showcmd("", "%s", strings.Join(cmdline, " "))
if buildN { if cfg.BuildN {
return nil return nil
} }
} }
...@@ -149,7 +150,7 @@ func runStdin(cmdline []string) { ...@@ -149,7 +150,7 @@ func runStdin(cmdline []string) {
cmd.Stdin = os.Stdin cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
cmd.Env = origEnv cmd.Env = cfg.OrigEnv
startSigHandlers() startSigHandlers()
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {
errorf("%v", err) errorf("%v", err)
......
...@@ -6,6 +6,7 @@ package main ...@@ -6,6 +6,7 @@ package main
import ( import (
"bytes" "bytes"
"cmd/go/internal/cfg"
"cmd/go/internal/str" "cmd/go/internal/str"
"errors" "errors"
"fmt" "fmt"
...@@ -375,9 +376,9 @@ See the documentation of the testing package for more information. ...@@ -375,9 +376,9 @@ See the documentation of the testing package for more information.
} }
var ( var (
testC bool // -c flag testC bool // -c flag
testCover bool // -cover flag testCover bool // -cover flag
testCoverMode string // -covermode flag // Note: testCoverMode is cfg.TestCoverMode (-covermode)
testCoverPaths []string // -coverpkg flag testCoverPaths []string // -coverpkg flag
testCoverPkgs []*Package // -coverpkg flag testCoverPkgs []*Package // -coverpkg flag
testO string // -o flag testO string // -o flag
...@@ -444,18 +445,18 @@ func runTest(cmd *Command, args []string) { ...@@ -444,18 +445,18 @@ func runTest(cmd *Command, args []string) {
// In these cases, streaming the output produces the same result // In these cases, streaming the output produces the same result
// as not streaming, just more immediately. // as not streaming, just more immediately.
testStreamOutput = len(pkgArgs) == 0 || testBench || testStreamOutput = len(pkgArgs) == 0 || testBench ||
(testShowPass && (len(pkgs) == 1 || buildP == 1)) (testShowPass && (len(pkgs) == 1 || cfg.BuildP == 1))
// For 'go test -i -o x.test', we want to build x.test. Imply -c to make the logic easier. // For 'go test -i -o x.test', we want to build x.test. Imply -c to make the logic easier.
if buildI && testO != "" { if cfg.BuildI && testO != "" {
testC = true testC = true
} }
var b builder var b builder
b.init() b.init()
if buildI { if cfg.BuildI {
buildV = testV cfg.BuildV = testV
deps := make(map[string]bool) deps := make(map[string]bool)
for dep := range testMainDeps { for dep := range testMainDeps {
...@@ -479,7 +480,7 @@ func runTest(cmd *Command, args []string) { ...@@ -479,7 +480,7 @@ func runTest(cmd *Command, args []string) {
if deps["C"] { if deps["C"] {
delete(deps, "C") delete(deps, "C")
deps["runtime/cgo"] = true deps["runtime/cgo"] = true
if goos == runtime.GOOS && goarch == runtime.GOARCH && !buildRace && !buildMSan { if cfg.Goos == runtime.GOOS && cfg.Goarch == runtime.GOARCH && !cfg.BuildRace && !cfg.BuildMSan {
deps["cmd/cgo"] = true deps["cmd/cgo"] = true
} }
} }
...@@ -535,7 +536,7 @@ func runTest(cmd *Command, args []string) { ...@@ -535,7 +536,7 @@ func runTest(cmd *Command, args []string) {
p.Stale = true // rebuild p.Stale = true // rebuild
p.StaleReason = "rebuild for coverage" p.StaleReason = "rebuild for coverage"
p.fake = true // do not warn about rebuild p.fake = true // do not warn about rebuild
p.coverMode = testCoverMode p.coverMode = cfg.TestCoverMode
var coverFiles []string var coverFiles []string
coverFiles = append(coverFiles, p.GoFiles...) coverFiles = append(coverFiles, p.GoFiles...)
coverFiles = append(coverFiles, p.CgoFiles...) coverFiles = append(coverFiles, p.CgoFiles...)
...@@ -625,10 +626,10 @@ func runTest(cmd *Command, args []string) { ...@@ -625,10 +626,10 @@ func runTest(cmd *Command, args []string) {
args = " " + args args = " " + args
} }
extraOpts := "" extraOpts := ""
if buildRace { if cfg.BuildRace {
extraOpts = "-race " extraOpts = "-race "
} }
if buildMSan { if cfg.BuildMSan {
extraOpts = "-msan " extraOpts = "-msan "
} }
fmt.Fprintf(os.Stderr, "installing these packages with 'go test %s-i%s' will speed future tests.\n\n", extraOpts, args) fmt.Fprintf(os.Stderr, "installing these packages with 'go test %s-i%s' will speed future tests.\n\n", extraOpts, args)
...@@ -775,7 +776,7 @@ func builderTest(b *builder, p *Package) (buildAction, runAction, printAction *a ...@@ -775,7 +776,7 @@ func builderTest(b *builder, p *Package) (buildAction, runAction, printAction *a
ptest.build.ImportPos = m ptest.build.ImportPos = m
if localCover { if localCover {
ptest.coverMode = testCoverMode ptest.coverMode = cfg.TestCoverMode
var coverFiles []string var coverFiles []string
coverFiles = append(coverFiles, ptest.GoFiles...) coverFiles = append(coverFiles, ptest.GoFiles...)
coverFiles = append(coverFiles, ptest.CgoFiles...) coverFiles = append(coverFiles, ptest.CgoFiles...)
...@@ -884,10 +885,10 @@ func builderTest(b *builder, p *Package) (buildAction, runAction, printAction *a ...@@ -884,10 +885,10 @@ func builderTest(b *builder, p *Package) (buildAction, runAction, printAction *a
recompileForTest(pmain, p, ptest, testDir) recompileForTest(pmain, p, ptest, testDir)
} }
if buildContext.GOOS == "darwin" { if cfg.BuildContext.GOOS == "darwin" {
if buildContext.GOARCH == "arm" || buildContext.GOARCH == "arm64" { if cfg.BuildContext.GOARCH == "arm" || cfg.BuildContext.GOARCH == "arm64" {
t.IsIOS = true t.IsIOS = true
t.NeedOS = true t.NeedCgo = true
} }
} }
if t.TestMain == nil { if t.TestMain == nil {
...@@ -900,7 +901,7 @@ func builderTest(b *builder, p *Package) (buildAction, runAction, printAction *a ...@@ -900,7 +901,7 @@ func builderTest(b *builder, p *Package) (buildAction, runAction, printAction *a
} }
} }
if !buildN { if !cfg.BuildN {
// writeTestmain writes _testmain.go. This must happen after recompileForTest, // writeTestmain writes _testmain.go. This must happen after recompileForTest,
// because recompileForTest modifies XXX. // because recompileForTest modifies XXX.
if err := writeTestmain(filepath.Join(testDir, "_testmain.go"), t); err != nil { if err := writeTestmain(filepath.Join(testDir, "_testmain.go"), t); err != nil {
...@@ -928,8 +929,8 @@ func builderTest(b *builder, p *Package) (buildAction, runAction, printAction *a ...@@ -928,8 +929,8 @@ func builderTest(b *builder, p *Package) (buildAction, runAction, printAction *a
a := b.action(modeBuild, modeBuild, pmain) a := b.action(modeBuild, modeBuild, pmain)
a.objdir = testDir + string(filepath.Separator) a.objdir = testDir + string(filepath.Separator)
a.objpkg = filepath.Join(testDir, "main.a") a.objpkg = filepath.Join(testDir, "main.a")
a.target = filepath.Join(testDir, testBinary) + exeSuffix a.target = filepath.Join(testDir, testBinary) + cfg.ExeSuffix
if goos == "windows" { if cfg.Goos == "windows" {
// There are many reserved words on Windows that, // There are many reserved words on Windows that,
// if used in the name of an executable, cause Windows // if used in the name of an executable, cause Windows
// to try to ask for extra permissions. // to try to ask for extra permissions.
...@@ -954,7 +955,7 @@ func builderTest(b *builder, p *Package) (buildAction, runAction, printAction *a ...@@ -954,7 +955,7 @@ func builderTest(b *builder, p *Package) (buildAction, runAction, printAction *a
// we could just do this always on Windows. // we could just do this always on Windows.
for _, bad := range windowsBadWords { for _, bad := range windowsBadWords {
if strings.Contains(testBinary, bad) { if strings.Contains(testBinary, bad) {
a.target = filepath.Join(testDir, "test.test") + exeSuffix a.target = filepath.Join(testDir, "test.test") + cfg.ExeSuffix
break break
} }
} }
...@@ -963,7 +964,7 @@ func builderTest(b *builder, p *Package) (buildAction, runAction, printAction *a ...@@ -963,7 +964,7 @@ func builderTest(b *builder, p *Package) (buildAction, runAction, printAction *a
if testC || testNeedBinary { if testC || testNeedBinary {
// -c or profiling flag: create action to copy binary to ./test.out. // -c or profiling flag: create action to copy binary to ./test.out.
target := filepath.Join(cwd, testBinary+exeSuffix) target := filepath.Join(cwd, testBinary+cfg.ExeSuffix)
if testO != "" { if testO != "" {
target = testO target = testO
if !filepath.IsAbs(target) { if !filepath.IsAbs(target) {
...@@ -1098,9 +1099,9 @@ func builderRunTest(b *builder, a *action) error { ...@@ -1098,9 +1099,9 @@ func builderRunTest(b *builder, a *action) error {
args := str.StringList(findExecCmd(), a.deps[0].target, testArgs) args := str.StringList(findExecCmd(), a.deps[0].target, testArgs)
a.testOutput = new(bytes.Buffer) a.testOutput = new(bytes.Buffer)
if buildN || buildX { if cfg.BuildN || cfg.BuildX {
b.showcmd("", "%s", strings.Join(args, " ")) b.showcmd("", "%s", strings.Join(args, " "))
if buildN { if cfg.BuildN {
return nil return nil
} }
} }
...@@ -1115,7 +1116,7 @@ func builderRunTest(b *builder, a *action) error { ...@@ -1115,7 +1116,7 @@ func builderRunTest(b *builder, a *action) error {
cmd := exec.Command(args[0], args[1:]...) cmd := exec.Command(args[0], args[1:]...)
cmd.Dir = a.p.Dir cmd.Dir = a.p.Dir
cmd.Env = envForDir(cmd.Dir, origEnv) cmd.Env = envForDir(cmd.Dir, cfg.OrigEnv)
var buf bytes.Buffer var buf bytes.Buffer
if testStreamOutput { if testStreamOutput {
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
...@@ -1227,7 +1228,7 @@ func coveragePercentage(out []byte) string { ...@@ -1227,7 +1228,7 @@ func coveragePercentage(out []byte) string {
// builderCleanTest is the action for cleaning up after a test. // builderCleanTest is the action for cleaning up after a test.
func builderCleanTest(b *builder, a *action) error { func builderCleanTest(b *builder, a *action) error {
if buildWork { if cfg.BuildWork {
return nil return nil
} }
run := a.deps[0] run := a.deps[0]
...@@ -1345,7 +1346,7 @@ type testFuncs struct { ...@@ -1345,7 +1346,7 @@ type testFuncs struct {
} }
func (t *testFuncs) CoverMode() string { func (t *testFuncs) CoverMode() string {
return testCoverMode return cfg.TestCoverMode
} }
func (t *testFuncs) CoverEnabled() bool { func (t *testFuncs) CoverEnabled() bool {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package main package main
import ( import (
"cmd/go/internal/cfg"
"flag" "flag"
"fmt" "fmt"
"os" "os"
...@@ -31,7 +32,7 @@ type testFlagSpec struct { ...@@ -31,7 +32,7 @@ type testFlagSpec struct {
var testFlagDefn = []*testFlagSpec{ var testFlagDefn = []*testFlagSpec{
// local. // local.
{name: "c", boolVar: &testC}, {name: "c", boolVar: &testC},
{name: "i", boolVar: &buildI}, {name: "i", boolVar: &cfg.BuildI},
{name: "o"}, {name: "o"},
{name: "cover", boolVar: &testCover}, {name: "cover", boolVar: &testCover},
{name: "covermode"}, {name: "covermode"},
...@@ -169,7 +170,7 @@ func testFlags(args []string) (packageNames, passToTest []string) { ...@@ -169,7 +170,7 @@ func testFlags(args []string) (packageNames, passToTest []string) {
case "covermode": case "covermode":
switch value { switch value {
case "set", "count", "atomic": case "set", "count", "atomic":
testCoverMode = value cfg.TestCoverMode = value
default: default:
fatalf("invalid flag argument for -covermode: %q", value) fatalf("invalid flag argument for -covermode: %q", value)
} }
...@@ -186,11 +187,11 @@ func testFlags(args []string) (packageNames, passToTest []string) { ...@@ -186,11 +187,11 @@ func testFlags(args []string) (packageNames, passToTest []string) {
} }
} }
if testCoverMode == "" { if cfg.TestCoverMode == "" {
testCoverMode = "set" cfg.TestCoverMode = "set"
if buildRace { if cfg.BuildRace {
// Default coverage mode is atomic when -race is set. // Default coverage mode is atomic when -race is set.
testCoverMode = "atomic" cfg.TestCoverMode = "atomic"
} }
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package main package main
import ( import (
"cmd/go/internal/cfg"
"fmt" "fmt"
"go/build" "go/build"
"os" "os"
...@@ -50,7 +51,7 @@ func tool(toolName string) string { ...@@ -50,7 +51,7 @@ func tool(toolName string) string {
if toolIsWindows { if toolIsWindows {
toolPath += toolWindowsExtension toolPath += toolWindowsExtension
} }
if len(buildToolExec) > 0 { if len(cfg.BuildToolexec) > 0 {
return toolPath return toolPath
} }
// Give a nice message if there is no tool with that name. // Give a nice message if there is no tool with that name.
...@@ -115,7 +116,7 @@ func runTool(cmd *Command, args []string) { ...@@ -115,7 +116,7 @@ func runTool(cmd *Command, args []string) {
// or we're printing command lines too (-x mode). // or we're printing command lines too (-x mode).
// Assume if command exited cleanly (even with non-zero status) // Assume if command exited cleanly (even with non-zero status)
// it printed any messages it wanted to print. // it printed any messages it wanted to print.
if e, ok := err.(*exec.ExitError); !ok || !e.Exited() || buildX { if e, ok := err.(*exec.ExitError); !ok || !e.Exited() || cfg.BuildX {
fmt.Fprintf(os.Stderr, "go tool %s: %s\n", toolName, err) fmt.Fprintf(os.Stderr, "go tool %s: %s\n", toolName, err)
} }
setExitStatus(1) setExitStatus(1)
......
...@@ -6,6 +6,7 @@ package main ...@@ -6,6 +6,7 @@ package main
import ( import (
"bytes" "bytes"
"cmd/go/internal/cfg"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
...@@ -373,7 +374,7 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool) ...@@ -373,7 +374,7 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool)
cmd := exec.Command(v.cmd, args...) cmd := exec.Command(v.cmd, args...)
cmd.Dir = dir cmd.Dir = dir
cmd.Env = envForDir(cmd.Dir, os.Environ()) cmd.Env = envForDir(cmd.Dir, os.Environ())
if buildX { if cfg.BuildX {
fmt.Printf("cd %s\n", dir) fmt.Printf("cd %s\n", dir)
fmt.Printf("%s %s\n", v.cmd, strings.Join(args, " ")) fmt.Printf("%s %s\n", v.cmd, strings.Join(args, " "))
} }
...@@ -383,7 +384,7 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool) ...@@ -383,7 +384,7 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool)
err = cmd.Run() err = cmd.Run()
out := buf.Bytes() out := buf.Bytes()
if err != nil { if err != nil {
if verbose || buildV { if verbose || cfg.BuildV {
fmt.Fprintf(os.Stderr, "# cd %s; %s %s\n", dir, v.cmd, strings.Join(args, " ")) fmt.Fprintf(os.Stderr, "# cd %s; %s %s\n", dir, v.cmd, strings.Join(args, " "))
os.Stderr.Write(out) os.Stderr.Write(out)
} }
...@@ -687,7 +688,7 @@ func repoRootForImportDynamic(importPath string, security securityMode) (*repoRo ...@@ -687,7 +688,7 @@ func repoRootForImportDynamic(importPath string, security securityMode) (*repoRo
} }
return nil, fmt.Errorf("parse %s: no go-import meta tags (%s)", urlStr, err) return nil, fmt.Errorf("parse %s: no go-import meta tags (%s)", urlStr, err)
} }
if buildV { if cfg.BuildV {
log.Printf("get %q: found meta tag %#v at %s", importPath, mmi, urlStr) log.Printf("get %q: found meta tag %#v at %s", importPath, mmi, urlStr)
} }
// If the import was "uni.edu/bob/project", which said the // If the import was "uni.edu/bob/project", which said the
...@@ -697,7 +698,7 @@ func repoRootForImportDynamic(importPath string, security securityMode) (*repoRo ...@@ -697,7 +698,7 @@ func repoRootForImportDynamic(importPath string, security securityMode) (*repoRo
// non-evil student). Instead, first verify the root and see // non-evil student). Instead, first verify the root and see
// if it matches Bob's claim. // if it matches Bob's claim.
if mmi.Prefix != importPath { if mmi.Prefix != importPath {
if buildV { if cfg.BuildV {
log.Printf("get %q: verifying non-authoritative meta tag", importPath) log.Printf("get %q: verifying non-authoritative meta tag", importPath)
} }
urlStr0 := urlStr urlStr0 := urlStr
......
...@@ -7,6 +7,7 @@ package main ...@@ -7,6 +7,7 @@ package main
import ( import (
"path/filepath" "path/filepath"
"cmd/go/internal/cfg"
"cmd/go/internal/str" "cmd/go/internal/str"
) )
...@@ -52,5 +53,5 @@ func runVetFiles(p *Package, files []string) { ...@@ -52,5 +53,5 @@ func runVetFiles(p *Package, files []string) {
for i := range files { for i := range files {
files[i] = filepath.Join(p.Dir, files[i]) files[i] = filepath.Join(p.Dir, files[i])
} }
run(buildToolExec, tool("vet"), relPaths(files)) run(cfg.BuildToolexec, tool("vet"), relPaths(files))
} }
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