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