diff options
Diffstat (limited to 'libgo/go/cmd/go/internal/work/action.go')
-rw-r--r-- | libgo/go/cmd/go/internal/work/action.go | 71 |
1 files changed, 54 insertions, 17 deletions
diff --git a/libgo/go/cmd/go/internal/work/action.go b/libgo/go/cmd/go/internal/work/action.go index 803a6bd4611..82cf228fa44 100644 --- a/libgo/go/cmd/go/internal/work/action.go +++ b/libgo/go/cmd/go/internal/work/action.go @@ -37,7 +37,10 @@ type Builder struct { flagCache map[[2]string]bool // a cache of supported compiler flags Print func(args ...interface{}) (int, error) - ComputeStaleOnly bool // compute staleness for go list; no actual build + IsCmdList bool // running as part of go list; set p.Stale and additional fields below + NeedError bool // list needs p.Error + NeedExport bool // list needs p.Export + NeedCompiledGoFiles bool // list needs p.CompiledGoFIles objdirSeq int // counter for NewObjdir pkgSeq int @@ -80,9 +83,10 @@ type Action struct { actionID cache.ActionID // cache ID of action input buildID string // build ID of action output - needVet bool // Mode=="build": need to fill in vet config - vetCfg *vetConfig // vet config - output []byte // output redirect buffer (nil means use b.Print) + VetxOnly bool // Mode=="vet": only being called to supply info about dependencies + needVet bool // Mode=="build": need to fill in vet config + vetCfg *vetConfig // vet config + output []byte // output redirect buffer (nil means use b.Print) // Execution state. pending int // number of deps yet to complete @@ -139,6 +143,7 @@ type actionJSON struct { Priority int `json:",omitempty"` Failed bool `json:",omitempty"` Built string `json:",omitempty"` + VetxOnly bool `json:",omitempty"` } // cacheKey is the key for the action cache. @@ -178,6 +183,7 @@ func actionGraphJSON(a *Action) string { Failed: a.Failed, Priority: a.priority, Built: a.built, + VetxOnly: a.VetxOnly, } if a.Package != nil { // TODO(rsc): Make this a unique key for a.Package somehow. @@ -208,7 +214,6 @@ const ( ) func (b *Builder) Init() { - var err error b.Print = func(a ...interface{}) (int, error) { return fmt.Fprint(os.Stderr, a...) } @@ -220,10 +225,19 @@ func (b *Builder) Init() { if cfg.BuildN { b.WorkDir = "$WORK" } else { - b.WorkDir, err = ioutil.TempDir(os.Getenv("GOTMPDIR"), "go-build") + tmp, err := ioutil.TempDir(os.Getenv("GOTMPDIR"), "go-build") if err != nil { - base.Fatalf("%s", err) + base.Fatalf("go: creating work dir: %v", err) } + if !filepath.IsAbs(tmp) { + abs, err := filepath.Abs(tmp) + if err != nil { + os.RemoveAll(tmp) + base.Fatalf("go: creating work dir: %v", err) + } + tmp = abs + } + b.WorkDir = tmp if cfg.BuildX || cfg.BuildWork { fmt.Fprintf(os.Stderr, "WORK=%s\n", b.WorkDir) } @@ -322,8 +336,8 @@ func (b *Builder) AutoAction(mode, depMode BuildMode, p *load.Package) *Action { // depMode is the action (build or install) to use when building dependencies. // To turn package main into an executable, call b.Link instead. func (b *Builder) CompileAction(mode, depMode BuildMode, p *load.Package) *Action { - if mode != ModeBuild && p.Internal.Local && p.Target == "" { - // Imported via local path. No permanent target. + if mode != ModeBuild && (p.Internal.Local || p.Module != nil) && p.Target == "" { + // Imported via local path or using modules. No permanent target. mode = ModeBuild } if mode != ModeBuild && p.Name == "main" { @@ -340,8 +354,10 @@ func (b *Builder) CompileAction(mode, depMode BuildMode, p *load.Package) *Actio Objdir: b.NewObjdir(), } - for _, p1 := range p.Internal.Imports { - a.Deps = append(a.Deps, b.CompileAction(depMode, depMode, p1)) + if p.Error == nil || !p.Error.IsImportCycle { + for _, p1 := range p.Internal.Imports { + a.Deps = append(a.Deps, b.CompileAction(depMode, depMode, p1)) + } } if p.Standard { @@ -379,6 +395,12 @@ func (b *Builder) CompileAction(mode, depMode BuildMode, p *load.Package) *Actio // If the caller may be causing p to be installed, it is up to the caller // to make sure that the install depends on (runs after) vet. func (b *Builder) VetAction(mode, depMode BuildMode, p *load.Package) *Action { + a := b.vetAction(mode, depMode, p) + a.VetxOnly = false + return a +} + +func (b *Builder) vetAction(mode, depMode BuildMode, p *load.Package) *Action { // Construct vet action. a := b.cacheAction("vet", p, func() *Action { a1 := b.CompileAction(mode, depMode, p) @@ -390,19 +412,34 @@ func (b *Builder) VetAction(mode, depMode BuildMode, p *load.Package) *Action { stk.Pop() aFmt := b.CompileAction(ModeBuild, depMode, p1) + var deps []*Action + if a1.buggyInstall { + // (*Builder).vet expects deps[0] to be the package + // and deps[1] to be "fmt". If we see buggyInstall + // here then a1 is an install of a shared library, + // and the real package is a1.Deps[0]. + deps = []*Action{a1.Deps[0], aFmt, a1} + } else { + deps = []*Action{a1, aFmt} + } + for _, p1 := range load.PackageList(p.Internal.Imports) { + deps = append(deps, b.vetAction(mode, depMode, p1)) + } + a := &Action{ - Mode: "vet", - Package: p, - Deps: []*Action{a1, aFmt}, - Objdir: a1.Objdir, + Mode: "vet", + Package: p, + Deps: deps, + Objdir: a1.Objdir, + VetxOnly: true, + IgnoreFail: true, // it's OK if vet of dependencies "fails" (reports problems) } if a1.Func == nil { // Built-in packages like unsafe. return a } - a1.needVet = true + deps[0].needVet = true a.Func = (*Builder).vet - return a }) return a |