Source file src/cmd/go/internal/work/action.go

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Action graph creation (planning).
     6  
     7  package work
     8  
     9  import (
    10  	"bufio"
    11  	"bytes"
    12  	"cmd/internal/cov/covcmd"
    13  	"cmd/internal/par"
    14  	"container/heap"
    15  	"context"
    16  	"debug/elf"
    17  	"encoding/json"
    18  	"fmt"
    19  	"internal/platform"
    20  	"os"
    21  	"path/filepath"
    22  	"strings"
    23  	"sync"
    24  	"time"
    25  
    26  	"cmd/go/internal/base"
    27  	"cmd/go/internal/cache"
    28  	"cmd/go/internal/cfg"
    29  	"cmd/go/internal/load"
    30  	"cmd/go/internal/str"
    31  	"cmd/go/internal/trace"
    32  	"cmd/internal/buildid"
    33  	"cmd/internal/robustio"
    34  )
    35  
    36  // A Builder holds global state about a build.
    37  // It does not hold per-package state, because we
    38  // build packages in parallel, and the builder is shared.
    39  type Builder struct {
    40  	WorkDir            string                    // the temporary work directory (ends in filepath.Separator)
    41  	actionCache        map[cacheKey]*Action      // a cache of already-constructed actions
    42  	flagCache          map[[2]string]bool        // a cache of supported compiler flags
    43  	gccCompilerIDCache map[string]cache.ActionID // cache for gccCompilerID
    44  
    45  	IsCmdList           bool // running as part of go list; set p.Stale and additional fields below
    46  	NeedError           bool // list needs p.Error
    47  	NeedExport          bool // list needs p.Export
    48  	NeedCompiledGoFiles bool // list needs p.CompiledGoFiles
    49  	AllowErrors         bool // errors don't immediately exit the program
    50  
    51  	objdirSeq int // counter for NewObjdir
    52  	pkgSeq    int
    53  
    54  	backgroundSh *Shell // Shell that per-Action Shells are derived from
    55  
    56  	exec      sync.Mutex
    57  	readySema chan bool
    58  	ready     actionQueue
    59  
    60  	id             sync.Mutex
    61  	toolIDCache    par.Cache[string, string] // tool name -> tool ID
    62  	gccToolIDCache map[string]string         // tool name -> tool ID
    63  	buildIDCache   map[string]string         // file name -> build ID
    64  }
    65  
    66  // NOTE: Much of Action would not need to be exported if not for test.
    67  // Maybe test functionality should move into this package too?
    68  
    69  // An Actor runs an action.
    70  type Actor interface {
    71  	Act(*Builder, context.Context, *Action) error
    72  }
    73  
    74  // An ActorFunc is an Actor that calls the function.
    75  type ActorFunc func(*Builder, context.Context, *Action) error
    76  
    77  func (f ActorFunc) Act(b *Builder, ctx context.Context, a *Action) error {
    78  	return f(b, ctx, a)
    79  }
    80  
    81  // An Action represents a single action in the action graph.
    82  type Action struct {
    83  	Mode       string        // description of action operation
    84  	Package    *load.Package // the package this action works on
    85  	Deps       []*Action     // actions that must happen before this one
    86  	Actor      Actor         // the action itself (nil = no-op)
    87  	IgnoreFail bool          // whether to run f even if dependencies fail
    88  	TestOutput *bytes.Buffer // test output buffer
    89  	Args       []string      // additional args for runProgram
    90  
    91  	triggers []*Action // inverse of deps
    92  
    93  	buggyInstall bool // is this a buggy install (see -linkshared)?
    94  
    95  	TryCache func(*Builder, *Action) bool // callback for cache bypass
    96  
    97  	CacheExecutable bool // Whether to cache executables produced by link steps
    98  
    99  	// Generated files, directories.
   100  	Objdir           string         // directory for intermediate objects
   101  	Target           string         // goal of the action: the created package or executable
   102  	built            string         // the actual created package or executable
   103  	cachedExecutable string         // the cached executable, if CacheExecutable was set
   104  	actionID         cache.ActionID // cache ID of action input
   105  	buildID          string         // build ID of action output
   106  
   107  	VetxOnly  bool       // Mode=="vet": only being called to supply info about dependencies
   108  	needVet   bool       // Mode=="build": need to fill in vet config
   109  	needBuild bool       // Mode=="build": need to do actual build (can be false if needVet is true)
   110  	vetCfg    *vetConfig // vet config
   111  	output    []byte     // output redirect buffer (nil means use b.Print)
   112  
   113  	sh *Shell // lazily created per-Action shell; see Builder.Shell
   114  
   115  	// Execution state.
   116  	pending      int               // number of deps yet to complete
   117  	priority     int               // relative execution priority
   118  	Failed       *Action           // set to root cause if the action failed
   119  	json         *actionJSON       // action graph information
   120  	nonGoOverlay map[string]string // map from non-.go source files to copied files in objdir. Nil if no overlay is used.
   121  	traceSpan    *trace.Span
   122  }
   123  
   124  // BuildActionID returns the action ID section of a's build ID.
   125  func (a *Action) BuildActionID() string { return actionID(a.buildID) }
   126  
   127  // BuildContentID returns the content ID section of a's build ID.
   128  func (a *Action) BuildContentID() string { return contentID(a.buildID) }
   129  
   130  // BuildID returns a's build ID.
   131  func (a *Action) BuildID() string { return a.buildID }
   132  
   133  // BuiltTarget returns the actual file that was built. This differs
   134  // from Target when the result was cached.
   135  func (a *Action) BuiltTarget() string { return a.built }
   136  
   137  // CachedExecutable returns the cached executable, if CacheExecutable
   138  // was set and the executable could be cached, and "" otherwise.
   139  func (a *Action) CachedExecutable() string { return a.cachedExecutable }
   140  
   141  // An actionQueue is a priority queue of actions.
   142  type actionQueue []*Action
   143  
   144  // Implement heap.Interface
   145  func (q *actionQueue) Len() int           { return len(*q) }
   146  func (q *actionQueue) Swap(i, j int)      { (*q)[i], (*q)[j] = (*q)[j], (*q)[i] }
   147  func (q *actionQueue) Less(i, j int) bool { return (*q)[i].priority < (*q)[j].priority }
   148  func (q *actionQueue) Push(x any)         { *q = append(*q, x.(*Action)) }
   149  func (q *actionQueue) Pop() any {
   150  	n := len(*q) - 1
   151  	x := (*q)[n]
   152  	*q = (*q)[:n]
   153  	return x
   154  }
   155  
   156  func (q *actionQueue) push(a *Action) {
   157  	if a.json != nil {
   158  		a.json.TimeReady = time.Now()
   159  	}
   160  	heap.Push(q, a)
   161  }
   162  
   163  func (q *actionQueue) pop() *Action {
   164  	return heap.Pop(q).(*Action)
   165  }
   166  
   167  type actionJSON struct {
   168  	ID         int
   169  	Mode       string
   170  	Package    string
   171  	Deps       []int     `json:",omitempty"`
   172  	IgnoreFail bool      `json:",omitempty"`
   173  	Args       []string  `json:",omitempty"`
   174  	Link       bool      `json:",omitempty"`
   175  	Objdir     string    `json:",omitempty"`
   176  	Target     string    `json:",omitempty"`
   177  	Priority   int       `json:",omitempty"`
   178  	Failed     bool      `json:",omitempty"`
   179  	Built      string    `json:",omitempty"`
   180  	VetxOnly   bool      `json:",omitempty"`
   181  	NeedVet    bool      `json:",omitempty"`
   182  	NeedBuild  bool      `json:",omitempty"`
   183  	ActionID   string    `json:",omitempty"`
   184  	BuildID    string    `json:",omitempty"`
   185  	TimeReady  time.Time `json:",omitempty"`
   186  	TimeStart  time.Time `json:",omitempty"`
   187  	TimeDone   time.Time `json:",omitempty"`
   188  
   189  	Cmd     []string      // `json:",omitempty"`
   190  	CmdReal time.Duration `json:",omitempty"`
   191  	CmdUser time.Duration `json:",omitempty"`
   192  	CmdSys  time.Duration `json:",omitempty"`
   193  }
   194  
   195  // cacheKey is the key for the action cache.
   196  type cacheKey struct {
   197  	mode string
   198  	p    *load.Package
   199  }
   200  
   201  func actionGraphJSON(a *Action) string {
   202  	var workq []*Action
   203  	var inWorkq = make(map[*Action]int)
   204  
   205  	add := func(a *Action) {
   206  		if _, ok := inWorkq[a]; ok {
   207  			return
   208  		}
   209  		inWorkq[a] = len(workq)
   210  		workq = append(workq, a)
   211  	}
   212  	add(a)
   213  
   214  	for i := 0; i < len(workq); i++ {
   215  		for _, dep := range workq[i].Deps {
   216  			add(dep)
   217  		}
   218  	}
   219  
   220  	list := make([]*actionJSON, 0, len(workq))
   221  	for id, a := range workq {
   222  		if a.json == nil {
   223  			a.json = &actionJSON{
   224  				Mode:       a.Mode,
   225  				ID:         id,
   226  				IgnoreFail: a.IgnoreFail,
   227  				Args:       a.Args,
   228  				Objdir:     a.Objdir,
   229  				Target:     a.Target,
   230  				Failed:     a.Failed != nil,
   231  				Priority:   a.priority,
   232  				Built:      a.built,
   233  				VetxOnly:   a.VetxOnly,
   234  				NeedBuild:  a.needBuild,
   235  				NeedVet:    a.needVet,
   236  			}
   237  			if a.Package != nil {
   238  				// TODO(rsc): Make this a unique key for a.Package somehow.
   239  				a.json.Package = a.Package.ImportPath
   240  			}
   241  			for _, a1 := range a.Deps {
   242  				a.json.Deps = append(a.json.Deps, inWorkq[a1])
   243  			}
   244  		}
   245  		list = append(list, a.json)
   246  	}
   247  
   248  	js, err := json.MarshalIndent(list, "", "\t")
   249  	if err != nil {
   250  		fmt.Fprintf(os.Stderr, "go: writing debug action graph: %v\n", err)
   251  		return ""
   252  	}
   253  	return string(js)
   254  }
   255  
   256  // BuildMode specifies the build mode:
   257  // are we just building things or also installing the results?
   258  type BuildMode int
   259  
   260  const (
   261  	ModeBuild BuildMode = iota
   262  	ModeInstall
   263  	ModeBuggyInstall
   264  
   265  	ModeVetOnly = 1 << 8
   266  )
   267  
   268  // NewBuilder returns a new Builder ready for use.
   269  //
   270  // If workDir is the empty string, NewBuilder creates a WorkDir if needed
   271  // and arranges for it to be removed in case of an unclean exit.
   272  // The caller must Close the builder explicitly to clean up the WorkDir
   273  // before a clean exit.
   274  func NewBuilder(workDir string) *Builder {
   275  	b := new(Builder)
   276  
   277  	b.actionCache = make(map[cacheKey]*Action)
   278  	b.gccToolIDCache = make(map[string]string)
   279  	b.buildIDCache = make(map[string]string)
   280  
   281  	printWorkDir := false
   282  	if workDir != "" {
   283  		b.WorkDir = workDir
   284  	} else if cfg.BuildN {
   285  		b.WorkDir = "$WORK"
   286  	} else {
   287  		if !buildInitStarted {
   288  			panic("internal error: NewBuilder called before BuildInit")
   289  		}
   290  		tmp, err := os.MkdirTemp(cfg.Getenv("GOTMPDIR"), "go-build")
   291  		if err != nil {
   292  			base.Fatalf("go: creating work dir: %v", err)
   293  		}
   294  		if !filepath.IsAbs(tmp) {
   295  			abs, err := filepath.Abs(tmp)
   296  			if err != nil {
   297  				os.RemoveAll(tmp)
   298  				base.Fatalf("go: creating work dir: %v", err)
   299  			}
   300  			tmp = abs
   301  		}
   302  		b.WorkDir = tmp
   303  		builderWorkDirs.Store(b, b.WorkDir)
   304  		printWorkDir = cfg.BuildX || cfg.BuildWork
   305  	}
   306  
   307  	b.backgroundSh = NewShell(b.WorkDir, nil)
   308  
   309  	if printWorkDir {
   310  		b.BackgroundShell().Printf("WORK=%s\n", b.WorkDir)
   311  	}
   312  
   313  	if err := CheckGOOSARCHPair(cfg.Goos, cfg.Goarch); err != nil {
   314  		fmt.Fprintf(os.Stderr, "go: %v\n", err)
   315  		base.SetExitStatus(2)
   316  		base.Exit()
   317  	}
   318  
   319  	for _, tag := range cfg.BuildContext.BuildTags {
   320  		if strings.Contains(tag, ",") {
   321  			fmt.Fprintf(os.Stderr, "go: -tags space-separated list contains comma\n")
   322  			base.SetExitStatus(2)
   323  			base.Exit()
   324  		}
   325  	}
   326  
   327  	return b
   328  }
   329  
   330  var builderWorkDirs sync.Map // *Builder → WorkDir
   331  
   332  func (b *Builder) Close() error {
   333  	wd, ok := builderWorkDirs.Load(b)
   334  	if !ok {
   335  		return nil
   336  	}
   337  	defer builderWorkDirs.Delete(b)
   338  
   339  	if b.WorkDir != wd.(string) {
   340  		base.Errorf("go: internal error: Builder WorkDir unexpectedly changed from %s to %s", wd, b.WorkDir)
   341  	}
   342  
   343  	if !cfg.BuildWork {
   344  		if err := robustio.RemoveAll(b.WorkDir); err != nil {
   345  			return err
   346  		}
   347  	}
   348  	b.WorkDir = ""
   349  	return nil
   350  }
   351  
   352  func closeBuilders() {
   353  	leakedBuilders := 0
   354  	builderWorkDirs.Range(func(bi, _ any) bool {
   355  		leakedBuilders++
   356  		if err := bi.(*Builder).Close(); err != nil {
   357  			base.Error(err)
   358  		}
   359  		return true
   360  	})
   361  
   362  	if leakedBuilders > 0 && base.GetExitStatus() == 0 {
   363  		fmt.Fprintf(os.Stderr, "go: internal error: Builder leaked on successful exit\n")
   364  		base.SetExitStatus(1)
   365  	}
   366  }
   367  
   368  func CheckGOOSARCHPair(goos, goarch string) error {
   369  	if !platform.BuildModeSupported(cfg.BuildContext.Compiler, "default", goos, goarch) {
   370  		return fmt.Errorf("unsupported GOOS/GOARCH pair %s/%s", goos, goarch)
   371  	}
   372  	return nil
   373  }
   374  
   375  // NewObjdir returns the name of a fresh object directory under b.WorkDir.
   376  // It is up to the caller to call b.Mkdir on the result at an appropriate time.
   377  // The result ends in a slash, so that file names in that directory
   378  // can be constructed with direct string addition.
   379  //
   380  // NewObjdir must be called only from a single goroutine at a time,
   381  // so it is safe to call during action graph construction, but it must not
   382  // be called during action graph execution.
   383  func (b *Builder) NewObjdir() string {
   384  	b.objdirSeq++
   385  	return str.WithFilePathSeparator(filepath.Join(b.WorkDir, fmt.Sprintf("b%03d", b.objdirSeq)))
   386  }
   387  
   388  // readpkglist returns the list of packages that were built into the shared library
   389  // at shlibpath. For the native toolchain this list is stored, newline separated, in
   390  // an ELF note with name "Go\x00\x00" and type 1. For GCCGO it is extracted from the
   391  // .go_export section.
   392  func readpkglist(shlibpath string) (pkgs []*load.Package) {
   393  	var stk load.ImportStack
   394  	if cfg.BuildToolchainName == "gccgo" {
   395  		f, err := elf.Open(shlibpath)
   396  		if err != nil {
   397  			base.Fatal(fmt.Errorf("failed to open shared library: %v", err))
   398  		}
   399  		defer f.Close()
   400  		sect := f.Section(".go_export")
   401  		if sect == nil {
   402  			base.Fatal(fmt.Errorf("%s: missing .go_export section", shlibpath))
   403  		}
   404  		data, err := sect.Data()
   405  		if err != nil {
   406  			base.Fatal(fmt.Errorf("%s: failed to read .go_export section: %v", shlibpath, err))
   407  		}
   408  		pkgpath := []byte("pkgpath ")
   409  		for _, line := range bytes.Split(data, []byte{'\n'}) {
   410  			if path, found := bytes.CutPrefix(line, pkgpath); found {
   411  				path = bytes.TrimSuffix(path, []byte{';'})
   412  				pkgs = append(pkgs, load.LoadPackageWithFlags(string(path), base.Cwd(), &stk, nil, 0))
   413  			}
   414  		}
   415  	} else {
   416  		pkglistbytes, err := buildid.ReadELFNote(shlibpath, "Go\x00\x00", 1)
   417  		if err != nil {
   418  			base.Fatalf("readELFNote failed: %v", err)
   419  		}
   420  		scanner := bufio.NewScanner(bytes.NewBuffer(pkglistbytes))
   421  		for scanner.Scan() {
   422  			t := scanner.Text()
   423  			pkgs = append(pkgs, load.LoadPackageWithFlags(t, base.Cwd(), &stk, nil, 0))
   424  		}
   425  	}
   426  	return
   427  }
   428  
   429  // cacheAction looks up {mode, p} in the cache and returns the resulting action.
   430  // If the cache has no such action, f() is recorded and returned.
   431  // TODO(rsc): Change the second key from *load.Package to interface{},
   432  // to make the caching in linkShared less awkward?
   433  func (b *Builder) cacheAction(mode string, p *load.Package, f func() *Action) *Action {
   434  	a := b.actionCache[cacheKey{mode, p}]
   435  	if a == nil {
   436  		a = f()
   437  		b.actionCache[cacheKey{mode, p}] = a
   438  	}
   439  	return a
   440  }
   441  
   442  // AutoAction returns the "right" action for go build or go install of p.
   443  func (b *Builder) AutoAction(mode, depMode BuildMode, p *load.Package) *Action {
   444  	if p.Name == "main" {
   445  		return b.LinkAction(mode, depMode, p)
   446  	}
   447  	return b.CompileAction(mode, depMode, p)
   448  }
   449  
   450  // buildActor implements the Actor interface for package build
   451  // actions. For most package builds this simply means invoking th
   452  // *Builder.build method; in the case of "go test -cover" for
   453  // a package with no test files, we stores some additional state
   454  // information in the build actor to help with reporting.
   455  type buildActor struct {
   456  	// name of static meta-data file fragment emitted by the cover
   457  	// tool as part of the package build action, for selected
   458  	// "go test -cover" runs.
   459  	covMetaFileName string
   460  }
   461  
   462  // newBuildActor returns a new buildActor object, setting up the
   463  // covMetaFileName field if 'genCoverMeta' flag is set.
   464  func newBuildActor(p *load.Package, genCoverMeta bool) *buildActor {
   465  	ba := &buildActor{}
   466  	if genCoverMeta {
   467  		ba.covMetaFileName = covcmd.MetaFileForPackage(p.ImportPath)
   468  	}
   469  	return ba
   470  }
   471  
   472  func (ba *buildActor) Act(b *Builder, ctx context.Context, a *Action) error {
   473  	return b.build(ctx, a)
   474  }
   475  
   476  // pgoActionID computes the action ID for a preprocess PGO action.
   477  func (b *Builder) pgoActionID(input string) cache.ActionID {
   478  	h := cache.NewHash("preprocess PGO profile " + input)
   479  
   480  	fmt.Fprintf(h, "preprocess PGO profile\n")
   481  	fmt.Fprintf(h, "preprofile %s\n", b.toolID("preprofile"))
   482  	fmt.Fprintf(h, "input %q\n", b.fileHash(input))
   483  
   484  	return h.Sum()
   485  }
   486  
   487  // pgoActor implements the Actor interface for preprocessing PGO profiles.
   488  type pgoActor struct {
   489  	// input is the path to the original pprof profile.
   490  	input string
   491  }
   492  
   493  func (p *pgoActor) Act(b *Builder, ctx context.Context, a *Action) error {
   494  	if b.useCache(a, b.pgoActionID(p.input), a.Target, !b.IsCmdList) || b.IsCmdList {
   495  		return nil
   496  	}
   497  	defer b.flushOutput(a)
   498  
   499  	sh := b.Shell(a)
   500  
   501  	if err := sh.Mkdir(a.Objdir); err != nil {
   502  		return err
   503  	}
   504  
   505  	if err := sh.run(".", p.input, nil, cfg.BuildToolexec, base.Tool("preprofile"), "-o", a.Target, "-i", p.input); err != nil {
   506  		return err
   507  	}
   508  
   509  	// N.B. Builder.build looks for the out in a.built, regardless of
   510  	// whether this came from cache.
   511  	a.built = a.Target
   512  
   513  	if !cfg.BuildN {
   514  		// Cache the output.
   515  		//
   516  		// N.B. We don't use updateBuildID here, as preprocessed PGO profiles
   517  		// do not contain a build ID. updateBuildID is typically responsible
   518  		// for adding to the cache, thus we must do so ourselves instead.
   519  
   520  		r, err := os.Open(a.Target)
   521  		if err != nil {
   522  			return fmt.Errorf("error opening target for caching: %w", err)
   523  		}
   524  
   525  		c := cache.Default()
   526  		outputID, _, err := c.Put(a.actionID, r)
   527  		r.Close()
   528  		if err != nil {
   529  			return fmt.Errorf("error adding target to cache: %w", err)
   530  		}
   531  		if cfg.BuildX {
   532  			sh.ShowCmd("", "%s # internal", joinUnambiguously(str.StringList("cp", a.Target, c.OutputFile(outputID))))
   533  		}
   534  	}
   535  
   536  	return nil
   537  }
   538  
   539  // CompileAction returns the action for compiling and possibly installing
   540  // (according to mode) the given package. The resulting action is only
   541  // for building packages (archives), never for linking executables.
   542  // depMode is the action (build or install) to use when building dependencies.
   543  // To turn package main into an executable, call b.Link instead.
   544  func (b *Builder) CompileAction(mode, depMode BuildMode, p *load.Package) *Action {
   545  	vetOnly := mode&ModeVetOnly != 0
   546  	mode &^= ModeVetOnly
   547  
   548  	if mode != ModeBuild && p.Target == "" {
   549  		// No permanent target.
   550  		mode = ModeBuild
   551  	}
   552  	if mode != ModeBuild && p.Name == "main" {
   553  		// We never install the .a file for a main package.
   554  		mode = ModeBuild
   555  	}
   556  
   557  	// Construct package build action.
   558  	a := b.cacheAction("build", p, func() *Action {
   559  		a := &Action{
   560  			Mode:    "build",
   561  			Package: p,
   562  			Actor:   newBuildActor(p, p.Internal.Cover.GenMeta),
   563  			Objdir:  b.NewObjdir(),
   564  		}
   565  
   566  		if p.Error == nil || !p.Error.IsImportCycle {
   567  			for _, p1 := range p.Internal.Imports {
   568  				a.Deps = append(a.Deps, b.CompileAction(depMode, depMode, p1))
   569  			}
   570  		}
   571  
   572  		if p.Internal.PGOProfile != "" {
   573  			pgoAction := b.cacheAction("preprocess PGO profile "+p.Internal.PGOProfile, nil, func() *Action {
   574  				a := &Action{
   575  					Mode:   "preprocess PGO profile",
   576  					Actor:  &pgoActor{input: p.Internal.PGOProfile},
   577  					Objdir: b.NewObjdir(),
   578  				}
   579  				a.Target = filepath.Join(a.Objdir, "pgo.preprofile")
   580  
   581  				return a
   582  			})
   583  			a.Deps = append(a.Deps, pgoAction)
   584  		}
   585  
   586  		if p.Standard {
   587  			switch p.ImportPath {
   588  			case "builtin", "unsafe":
   589  				// Fake packages - nothing to build.
   590  				a.Mode = "built-in package"
   591  				a.Actor = nil
   592  				return a
   593  			}
   594  
   595  			// gccgo standard library is "fake" too.
   596  			if cfg.BuildToolchainName == "gccgo" {
   597  				// the target name is needed for cgo.
   598  				a.Mode = "gccgo stdlib"
   599  				a.Target = p.Target
   600  				a.Actor = nil
   601  				return a
   602  			}
   603  		}
   604  
   605  		return a
   606  	})
   607  
   608  	// Find the build action; the cache entry may have been replaced
   609  	// by the install action during (*Builder).installAction.
   610  	buildAction := a
   611  	switch buildAction.Mode {
   612  	case "build", "built-in package", "gccgo stdlib":
   613  		// ok
   614  	case "build-install":
   615  		buildAction = a.Deps[0]
   616  	default:
   617  		panic("lost build action: " + buildAction.Mode)
   618  	}
   619  	buildAction.needBuild = buildAction.needBuild || !vetOnly
   620  
   621  	// Construct install action.
   622  	if mode == ModeInstall || mode == ModeBuggyInstall {
   623  		a = b.installAction(a, mode)
   624  	}
   625  
   626  	return a
   627  }
   628  
   629  // VetAction returns the action for running go vet on package p.
   630  // It depends on the action for compiling p.
   631  // If the caller may be causing p to be installed, it is up to the caller
   632  // to make sure that the install depends on (runs after) vet.
   633  func (b *Builder) VetAction(mode, depMode BuildMode, p *load.Package) *Action {
   634  	a := b.vetAction(mode, depMode, p)
   635  	a.VetxOnly = false
   636  	return a
   637  }
   638  
   639  func (b *Builder) vetAction(mode, depMode BuildMode, p *load.Package) *Action {
   640  	// Construct vet action.
   641  	a := b.cacheAction("vet", p, func() *Action {
   642  		a1 := b.CompileAction(mode|ModeVetOnly, depMode, p)
   643  
   644  		// vet expects to be able to import "fmt".
   645  		var stk load.ImportStack
   646  		stk.Push(load.NewImportInfo("vet", nil))
   647  		p1, err := load.LoadImportWithFlags("fmt", p.Dir, p, &stk, nil, 0)
   648  		if err != nil {
   649  			base.Fatalf("unexpected error loading fmt package from package %s: %v", p.ImportPath, err)
   650  		}
   651  		stk.Pop()
   652  		aFmt := b.CompileAction(ModeBuild, depMode, p1)
   653  
   654  		var deps []*Action
   655  		if a1.buggyInstall {
   656  			// (*Builder).vet expects deps[0] to be the package
   657  			// and deps[1] to be "fmt". If we see buggyInstall
   658  			// here then a1 is an install of a shared library,
   659  			// and the real package is a1.Deps[0].
   660  			deps = []*Action{a1.Deps[0], aFmt, a1}
   661  		} else {
   662  			deps = []*Action{a1, aFmt}
   663  		}
   664  		for _, p1 := range p.Internal.Imports {
   665  			deps = append(deps, b.vetAction(mode, depMode, p1))
   666  		}
   667  
   668  		a := &Action{
   669  			Mode:       "vet",
   670  			Package:    p,
   671  			Deps:       deps,
   672  			Objdir:     a1.Objdir,
   673  			VetxOnly:   true,
   674  			IgnoreFail: true, // it's OK if vet of dependencies "fails" (reports problems)
   675  		}
   676  		if a1.Actor == nil {
   677  			// Built-in packages like unsafe.
   678  			return a
   679  		}
   680  		deps[0].needVet = true
   681  		a.Actor = ActorFunc((*Builder).vet)
   682  		return a
   683  	})
   684  	return a
   685  }
   686  
   687  // LinkAction returns the action for linking p into an executable
   688  // and possibly installing the result (according to mode).
   689  // depMode is the action (build or install) to use when compiling dependencies.
   690  func (b *Builder) LinkAction(mode, depMode BuildMode, p *load.Package) *Action {
   691  	// Construct link action.
   692  	a := b.cacheAction("link", p, func() *Action {
   693  		a := &Action{
   694  			Mode:    "link",
   695  			Package: p,
   696  		}
   697  
   698  		a1 := b.CompileAction(ModeBuild, depMode, p)
   699  		a.Actor = ActorFunc((*Builder).link)
   700  		a.Deps = []*Action{a1}
   701  		a.Objdir = a1.Objdir
   702  
   703  		// An executable file. (This is the name of a temporary file.)
   704  		// Because we run the temporary file in 'go run' and 'go test',
   705  		// the name will show up in ps listings. If the caller has specified
   706  		// a name, use that instead of a.out. The binary is generated
   707  		// in an otherwise empty subdirectory named exe to avoid
   708  		// naming conflicts. The only possible conflict is if we were
   709  		// to create a top-level package named exe.
   710  		name := "a.out"
   711  		if p.Internal.ExeName != "" {
   712  			name = p.Internal.ExeName
   713  		} else if (cfg.Goos == "darwin" || cfg.Goos == "windows") && cfg.BuildBuildmode == "c-shared" && p.Target != "" {
   714  			// On OS X, the linker output name gets recorded in the
   715  			// shared library's LC_ID_DYLIB load command.
   716  			// The code invoking the linker knows to pass only the final
   717  			// path element. Arrange that the path element matches what
   718  			// we'll install it as; otherwise the library is only loadable as "a.out".
   719  			// On Windows, DLL file name is recorded in PE file
   720  			// export section, so do like on OS X.
   721  			_, name = filepath.Split(p.Target)
   722  		}
   723  		a.Target = a.Objdir + filepath.Join("exe", name) + cfg.ExeSuffix
   724  		a.built = a.Target
   725  		b.addTransitiveLinkDeps(a, a1, "")
   726  
   727  		// Sequence the build of the main package (a1) strictly after the build
   728  		// of all other dependencies that go into the link. It is likely to be after
   729  		// them anyway, but just make sure. This is required by the build ID-based
   730  		// shortcut in (*Builder).useCache(a1), which will call b.linkActionID(a).
   731  		// In order for that linkActionID call to compute the right action ID, all the
   732  		// dependencies of a (except a1) must have completed building and have
   733  		// recorded their build IDs.
   734  		a1.Deps = append(a1.Deps, &Action{Mode: "nop", Deps: a.Deps[1:]})
   735  		return a
   736  	})
   737  
   738  	if mode == ModeInstall || mode == ModeBuggyInstall {
   739  		a = b.installAction(a, mode)
   740  	}
   741  
   742  	return a
   743  }
   744  
   745  // installAction returns the action for installing the result of a1.
   746  func (b *Builder) installAction(a1 *Action, mode BuildMode) *Action {
   747  	// Because we overwrite the build action with the install action below,
   748  	// a1 may already be an install action fetched from the "build" cache key,
   749  	// and the caller just doesn't realize.
   750  	if strings.HasSuffix(a1.Mode, "-install") {
   751  		if a1.buggyInstall && mode == ModeInstall {
   752  			//  Congratulations! The buggy install is now a proper install.
   753  			a1.buggyInstall = false
   754  		}
   755  		return a1
   756  	}
   757  
   758  	// If there's no actual action to build a1,
   759  	// there's nothing to install either.
   760  	// This happens if a1 corresponds to reusing an already-built object.
   761  	if a1.Actor == nil {
   762  		return a1
   763  	}
   764  
   765  	p := a1.Package
   766  	return b.cacheAction(a1.Mode+"-install", p, func() *Action {
   767  		// The install deletes the temporary build result,
   768  		// so we need all other actions, both past and future,
   769  		// that attempt to depend on the build to depend instead
   770  		// on the install.
   771  
   772  		// Make a private copy of a1 (the build action),
   773  		// no longer accessible to any other rules.
   774  		buildAction := new(Action)
   775  		*buildAction = *a1
   776  
   777  		// Overwrite a1 with the install action.
   778  		// This takes care of updating past actions that
   779  		// point at a1 for the build action; now they will
   780  		// point at a1 and get the install action.
   781  		// We also leave a1 in the action cache as the result
   782  		// for "build", so that actions not yet created that
   783  		// try to depend on the build will instead depend
   784  		// on the install.
   785  		*a1 = Action{
   786  			Mode:    buildAction.Mode + "-install",
   787  			Actor:   ActorFunc(BuildInstallFunc),
   788  			Package: p,
   789  			Objdir:  buildAction.Objdir,
   790  			Deps:    []*Action{buildAction},
   791  			Target:  p.Target,
   792  			built:   p.Target,
   793  
   794  			buggyInstall: mode == ModeBuggyInstall,
   795  		}
   796  
   797  		b.addInstallHeaderAction(a1)
   798  		return a1
   799  	})
   800  }
   801  
   802  // addTransitiveLinkDeps adds to the link action a all packages
   803  // that are transitive dependencies of a1.Deps.
   804  // That is, if a is a link of package main, a1 is the compile of package main
   805  // and a1.Deps is the actions for building packages directly imported by
   806  // package main (what the compiler needs). The linker needs all packages
   807  // transitively imported by the whole program; addTransitiveLinkDeps
   808  // makes sure those are present in a.Deps.
   809  // If shlib is non-empty, then a corresponds to the build and installation of shlib,
   810  // so any rebuild of shlib should not be added as a dependency.
   811  func (b *Builder) addTransitiveLinkDeps(a, a1 *Action, shlib string) {
   812  	// Expand Deps to include all built packages, for the linker.
   813  	// Use breadth-first search to find rebuilt-for-test packages
   814  	// before the standard ones.
   815  	// TODO(rsc): Eliminate the standard ones from the action graph,
   816  	// which will require doing a little bit more rebuilding.
   817  	workq := []*Action{a1}
   818  	haveDep := map[string]bool{}
   819  	if a1.Package != nil {
   820  		haveDep[a1.Package.ImportPath] = true
   821  	}
   822  	for i := 0; i < len(workq); i++ {
   823  		a1 := workq[i]
   824  		for _, a2 := range a1.Deps {
   825  			// TODO(rsc): Find a better discriminator than the Mode strings, once the dust settles.
   826  			if a2.Package == nil || (a2.Mode != "build-install" && a2.Mode != "build") || haveDep[a2.Package.ImportPath] {
   827  				continue
   828  			}
   829  			haveDep[a2.Package.ImportPath] = true
   830  			a.Deps = append(a.Deps, a2)
   831  			if a2.Mode == "build-install" {
   832  				a2 = a2.Deps[0] // walk children of "build" action
   833  			}
   834  			workq = append(workq, a2)
   835  		}
   836  	}
   837  
   838  	// If this is go build -linkshared, then the link depends on the shared libraries
   839  	// in addition to the packages themselves. (The compile steps do not.)
   840  	if cfg.BuildLinkshared {
   841  		haveShlib := map[string]bool{shlib: true}
   842  		for _, a1 := range a.Deps {
   843  			p1 := a1.Package
   844  			if p1 == nil || p1.Shlib == "" || haveShlib[filepath.Base(p1.Shlib)] {
   845  				continue
   846  			}
   847  			haveShlib[filepath.Base(p1.Shlib)] = true
   848  			// TODO(rsc): The use of ModeInstall here is suspect, but if we only do ModeBuild,
   849  			// we'll end up building an overall library or executable that depends at runtime
   850  			// on other libraries that are out-of-date, which is clearly not good either.
   851  			// We call it ModeBuggyInstall to make clear that this is not right.
   852  			a.Deps = append(a.Deps, b.linkSharedAction(ModeBuggyInstall, ModeBuggyInstall, p1.Shlib, nil))
   853  		}
   854  	}
   855  }
   856  
   857  // addInstallHeaderAction adds an install header action to a, if needed.
   858  // The action a should be an install action as generated by either
   859  // b.CompileAction or b.LinkAction with mode=ModeInstall,
   860  // and so a.Deps[0] is the corresponding build action.
   861  func (b *Builder) addInstallHeaderAction(a *Action) {
   862  	// Install header for cgo in c-archive and c-shared modes.
   863  	p := a.Package
   864  	if p.UsesCgo() && (cfg.BuildBuildmode == "c-archive" || cfg.BuildBuildmode == "c-shared") {
   865  		hdrTarget := a.Target[:len(a.Target)-len(filepath.Ext(a.Target))] + ".h"
   866  		if cfg.BuildContext.Compiler == "gccgo" && cfg.BuildO == "" {
   867  			// For the header file, remove the "lib"
   868  			// added by go/build, so we generate pkg.h
   869  			// rather than libpkg.h.
   870  			dir, file := filepath.Split(hdrTarget)
   871  			file = strings.TrimPrefix(file, "lib")
   872  			hdrTarget = filepath.Join(dir, file)
   873  		}
   874  		ah := &Action{
   875  			Mode:    "install header",
   876  			Package: a.Package,
   877  			Deps:    []*Action{a.Deps[0]},
   878  			Actor:   ActorFunc((*Builder).installHeader),
   879  			Objdir:  a.Deps[0].Objdir,
   880  			Target:  hdrTarget,
   881  		}
   882  		a.Deps = append(a.Deps, ah)
   883  	}
   884  }
   885  
   886  // buildmodeShared takes the "go build" action a1 into the building of a shared library of a1.Deps.
   887  // That is, the input a1 represents "go build pkgs" and the result represents "go build -buildmode=shared pkgs".
   888  func (b *Builder) buildmodeShared(mode, depMode BuildMode, args []string, pkgs []*load.Package, a1 *Action) *Action {
   889  	name, err := libname(args, pkgs)
   890  	if err != nil {
   891  		base.Fatalf("%v", err)
   892  	}
   893  	return b.linkSharedAction(mode, depMode, name, a1)
   894  }
   895  
   896  // linkSharedAction takes a grouping action a1 corresponding to a list of built packages
   897  // and returns an action that links them together into a shared library with the name shlib.
   898  // If a1 is nil, shlib should be an absolute path to an existing shared library,
   899  // and then linkSharedAction reads that library to find out the package list.
   900  func (b *Builder) linkSharedAction(mode, depMode BuildMode, shlib string, a1 *Action) *Action {
   901  	fullShlib := shlib
   902  	shlib = filepath.Base(shlib)
   903  	a := b.cacheAction("build-shlib "+shlib, nil, func() *Action {
   904  		if a1 == nil {
   905  			// TODO(rsc): Need to find some other place to store config,
   906  			// not in pkg directory. See golang.org/issue/22196.
   907  			pkgs := readpkglist(fullShlib)
   908  			a1 = &Action{
   909  				Mode: "shlib packages",
   910  			}
   911  			for _, p := range pkgs {
   912  				a1.Deps = append(a1.Deps, b.CompileAction(mode, depMode, p))
   913  			}
   914  		}
   915  
   916  		// Fake package to hold ldflags.
   917  		// As usual shared libraries are a kludgy, abstraction-violating special case:
   918  		// we let them use the flags specified for the command-line arguments.
   919  		p := &load.Package{}
   920  		p.Internal.CmdlinePkg = true
   921  		p.Internal.Ldflags = load.BuildLdflags.For(p)
   922  		p.Internal.Gccgoflags = load.BuildGccgoflags.For(p)
   923  
   924  		// Add implicit dependencies to pkgs list.
   925  		// Currently buildmode=shared forces external linking mode, and
   926  		// external linking mode forces an import of runtime/cgo (and
   927  		// math on arm). So if it was not passed on the command line and
   928  		// it is not present in another shared library, add it here.
   929  		// TODO(rsc): Maybe this should only happen if "runtime" is in the original package set.
   930  		// TODO(rsc): This should probably be changed to use load.LinkerDeps(p).
   931  		// TODO(rsc): We don't add standard library imports for gccgo
   932  		// because they are all always linked in anyhow.
   933  		// Maybe load.LinkerDeps should be used and updated.
   934  		a := &Action{
   935  			Mode:    "go build -buildmode=shared",
   936  			Package: p,
   937  			Objdir:  b.NewObjdir(),
   938  			Actor:   ActorFunc((*Builder).linkShared),
   939  			Deps:    []*Action{a1},
   940  		}
   941  		a.Target = filepath.Join(a.Objdir, shlib)
   942  		if cfg.BuildToolchainName != "gccgo" {
   943  			add := func(a1 *Action, pkg string, force bool) {
   944  				for _, a2 := range a1.Deps {
   945  					if a2.Package != nil && a2.Package.ImportPath == pkg {
   946  						return
   947  					}
   948  				}
   949  				var stk load.ImportStack
   950  				p := load.LoadPackageWithFlags(pkg, base.Cwd(), &stk, nil, 0)
   951  				if p.Error != nil {
   952  					base.Fatalf("load %s: %v", pkg, p.Error)
   953  				}
   954  				// Assume that if pkg (runtime/cgo or math)
   955  				// is already accounted for in a different shared library,
   956  				// then that shared library also contains runtime,
   957  				// so that anything we do will depend on that library,
   958  				// so we don't need to include pkg in our shared library.
   959  				if force || p.Shlib == "" || filepath.Base(p.Shlib) == pkg {
   960  					a1.Deps = append(a1.Deps, b.CompileAction(depMode, depMode, p))
   961  				}
   962  			}
   963  			add(a1, "runtime/cgo", false)
   964  			if cfg.Goarch == "arm" {
   965  				add(a1, "math", false)
   966  			}
   967  
   968  			// The linker step still needs all the usual linker deps.
   969  			// (For example, the linker always opens runtime.a.)
   970  			ldDeps, err := load.LinkerDeps(nil)
   971  			if err != nil {
   972  				base.Error(err)
   973  			}
   974  			for _, dep := range ldDeps {
   975  				add(a, dep, true)
   976  			}
   977  		}
   978  		b.addTransitiveLinkDeps(a, a1, shlib)
   979  		return a
   980  	})
   981  
   982  	// Install result.
   983  	if (mode == ModeInstall || mode == ModeBuggyInstall) && a.Actor != nil {
   984  		buildAction := a
   985  
   986  		a = b.cacheAction("install-shlib "+shlib, nil, func() *Action {
   987  			// Determine the eventual install target.
   988  			// The install target is root/pkg/shlib, where root is the source root
   989  			// in which all the packages lie.
   990  			// TODO(rsc): Perhaps this cross-root check should apply to the full
   991  			// transitive package dependency list, not just the ones named
   992  			// on the command line?
   993  			pkgDir := a1.Deps[0].Package.Internal.Build.PkgTargetRoot
   994  			for _, a2 := range a1.Deps {
   995  				if dir := a2.Package.Internal.Build.PkgTargetRoot; dir != pkgDir {
   996  					base.Fatalf("installing shared library: cannot use packages %s and %s from different roots %s and %s",
   997  						a1.Deps[0].Package.ImportPath,
   998  						a2.Package.ImportPath,
   999  						pkgDir,
  1000  						dir)
  1001  				}
  1002  			}
  1003  			// TODO(rsc): Find out and explain here why gccgo is different.
  1004  			if cfg.BuildToolchainName == "gccgo" {
  1005  				pkgDir = filepath.Join(pkgDir, "shlibs")
  1006  			}
  1007  			target := filepath.Join(pkgDir, shlib)
  1008  
  1009  			a := &Action{
  1010  				Mode:   "go install -buildmode=shared",
  1011  				Objdir: buildAction.Objdir,
  1012  				Actor:  ActorFunc(BuildInstallFunc),
  1013  				Deps:   []*Action{buildAction},
  1014  				Target: target,
  1015  			}
  1016  			for _, a2 := range buildAction.Deps[0].Deps {
  1017  				p := a2.Package
  1018  				pkgTargetRoot := p.Internal.Build.PkgTargetRoot
  1019  				if pkgTargetRoot == "" {
  1020  					continue
  1021  				}
  1022  				a.Deps = append(a.Deps, &Action{
  1023  					Mode:    "shlibname",
  1024  					Package: p,
  1025  					Actor:   ActorFunc((*Builder).installShlibname),
  1026  					Target:  filepath.Join(pkgTargetRoot, p.ImportPath+".shlibname"),
  1027  					Deps:    []*Action{a.Deps[0]},
  1028  				})
  1029  			}
  1030  			return a
  1031  		})
  1032  	}
  1033  
  1034  	return a
  1035  }
  1036  

View as plain text