...

Source file src/pkg/cmd/go/internal/work/exec.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 execution.
     6	
     7	package work
     8	
     9	import (
    10		"bytes"
    11		"cmd/go/internal/base"
    12		"cmd/go/internal/cache"
    13		"cmd/go/internal/cfg"
    14		"cmd/go/internal/load"
    15		"cmd/go/internal/str"
    16		"encoding/json"
    17		"errors"
    18		"fmt"
    19		"internal/lazyregexp"
    20		"io"
    21		"io/ioutil"
    22		"log"
    23		"math/rand"
    24		"os"
    25		"os/exec"
    26		"path/filepath"
    27		"regexp"
    28		"runtime"
    29		"strconv"
    30		"strings"
    31		"sync"
    32		"time"
    33	)
    34	
    35	// actionList returns the list of actions in the dag rooted at root
    36	// as visited in a depth-first post-order traversal.
    37	func actionList(root *Action) []*Action {
    38		seen := map[*Action]bool{}
    39		all := []*Action{}
    40		var walk func(*Action)
    41		walk = func(a *Action) {
    42			if seen[a] {
    43				return
    44			}
    45			seen[a] = true
    46			for _, a1 := range a.Deps {
    47				walk(a1)
    48			}
    49			all = append(all, a)
    50		}
    51		walk(root)
    52		return all
    53	}
    54	
    55	// do runs the action graph rooted at root.
    56	func (b *Builder) Do(root *Action) {
    57		if c := cache.Default(); c != nil && !b.IsCmdList {
    58			// If we're doing real work, take time at the end to trim the cache.
    59			defer c.Trim()
    60		}
    61	
    62		// Build list of all actions, assigning depth-first post-order priority.
    63		// The original implementation here was a true queue
    64		// (using a channel) but it had the effect of getting
    65		// distracted by low-level leaf actions to the detriment
    66		// of completing higher-level actions. The order of
    67		// work does not matter much to overall execution time,
    68		// but when running "go test std" it is nice to see each test
    69		// results as soon as possible. The priorities assigned
    70		// ensure that, all else being equal, the execution prefers
    71		// to do what it would have done first in a simple depth-first
    72		// dependency order traversal.
    73		all := actionList(root)
    74		for i, a := range all {
    75			a.priority = i
    76		}
    77	
    78		// Write action graph, without timing information, in case we fail and exit early.
    79		writeActionGraph := func() {
    80			if file := cfg.DebugActiongraph; file != "" {
    81				if strings.HasSuffix(file, ".go") {
    82					// Do not overwrite Go source code in:
    83					//	go build -debug-actiongraph x.go
    84					base.Fatalf("go: refusing to write action graph to %v\n", file)
    85				}
    86				js := actionGraphJSON(root)
    87				if err := ioutil.WriteFile(file, []byte(js), 0666); err != nil {
    88					fmt.Fprintf(os.Stderr, "go: writing action graph: %v\n", err)
    89					base.SetExitStatus(1)
    90				}
    91			}
    92		}
    93		writeActionGraph()
    94	
    95		b.readySema = make(chan bool, len(all))
    96	
    97		// Initialize per-action execution state.
    98		for _, a := range all {
    99			for _, a1 := range a.Deps {
   100				a1.triggers = append(a1.triggers, a)
   101			}
   102			a.pending = len(a.Deps)
   103			if a.pending == 0 {
   104				b.ready.push(a)
   105				b.readySema <- true
   106			}
   107		}
   108	
   109		// Handle runs a single action and takes care of triggering
   110		// any actions that are runnable as a result.
   111		handle := func(a *Action) {
   112			if a.json != nil {
   113				a.json.TimeStart = time.Now()
   114			}
   115			var err error
   116			if a.Func != nil && (!a.Failed || a.IgnoreFail) {
   117				err = a.Func(b, a)
   118			}
   119			if a.json != nil {
   120				a.json.TimeDone = time.Now()
   121			}
   122	
   123			// The actions run in parallel but all the updates to the
   124			// shared work state are serialized through b.exec.
   125			b.exec.Lock()
   126			defer b.exec.Unlock()
   127	
   128			if err != nil {
   129				if err == errPrintedOutput {
   130					base.SetExitStatus(2)
   131				} else {
   132					base.Errorf("%s", err)
   133				}
   134				a.Failed = true
   135			}
   136	
   137			for _, a0 := range a.triggers {
   138				if a.Failed {
   139					a0.Failed = true
   140				}
   141				if a0.pending--; a0.pending == 0 {
   142					b.ready.push(a0)
   143					b.readySema <- true
   144				}
   145			}
   146	
   147			if a == root {
   148				close(b.readySema)
   149			}
   150		}
   151	
   152		var wg sync.WaitGroup
   153	
   154		// Kick off goroutines according to parallelism.
   155		// If we are using the -n flag (just printing commands)
   156		// drop the parallelism to 1, both to make the output
   157		// deterministic and because there is no real work anyway.
   158		par := cfg.BuildP
   159		if cfg.BuildN {
   160			par = 1
   161		}
   162		for i := 0; i < par; i++ {
   163			wg.Add(1)
   164			go func() {
   165				defer wg.Done()
   166				for {
   167					select {
   168					case _, ok := <-b.readySema:
   169						if !ok {
   170							return
   171						}
   172						// Receiving a value from b.readySema entitles
   173						// us to take from the ready queue.
   174						b.exec.Lock()
   175						a := b.ready.pop()
   176						b.exec.Unlock()
   177						handle(a)
   178					case <-base.Interrupted:
   179						base.SetExitStatus(1)
   180						return
   181					}
   182				}
   183			}()
   184		}
   185	
   186		wg.Wait()
   187	
   188		// Write action graph again, this time with timing information.
   189		writeActionGraph()
   190	}
   191	
   192	// buildActionID computes the action ID for a build action.
   193	func (b *Builder) buildActionID(a *Action) cache.ActionID {
   194		p := a.Package
   195		h := cache.NewHash("build " + p.ImportPath)
   196	
   197		// Configuration independent of compiler toolchain.
   198		// Note: buildmode has already been accounted for in buildGcflags
   199		// and should not be inserted explicitly. Most buildmodes use the
   200		// same compiler settings and can reuse each other's results.
   201		// If not, the reason is already recorded in buildGcflags.
   202		fmt.Fprintf(h, "compile\n")
   203		// Only include the package directory if it may affect the output.
   204		// We trim workspace paths for all packages when -trimpath is set.
   205		// The compiler hides the exact value of $GOROOT
   206		// when building things in GOROOT.
   207		// Assume b.WorkDir is being trimmed properly.
   208		if !p.Goroot && !cfg.BuildTrimpath && !strings.HasPrefix(p.Dir, b.WorkDir) {
   209			fmt.Fprintf(h, "dir %s\n", p.Dir)
   210		}
   211		fmt.Fprintf(h, "goos %s goarch %s\n", cfg.Goos, cfg.Goarch)
   212		fmt.Fprintf(h, "import %q\n", p.ImportPath)
   213		fmt.Fprintf(h, "omitdebug %v standard %v local %v prefix %q\n", p.Internal.OmitDebug, p.Standard, p.Internal.Local, p.Internal.LocalPrefix)
   214		if cfg.BuildTrimpath {
   215			fmt.Fprintln(h, "trimpath")
   216		}
   217		if p.Internal.ForceLibrary {
   218			fmt.Fprintf(h, "forcelibrary\n")
   219		}
   220		if len(p.CgoFiles)+len(p.SwigFiles) > 0 {
   221			fmt.Fprintf(h, "cgo %q\n", b.toolID("cgo"))
   222			cppflags, cflags, cxxflags, fflags, ldflags, _ := b.CFlags(p)
   223			fmt.Fprintf(h, "CC=%q %q %q %q\n", b.ccExe(), cppflags, cflags, ldflags)
   224			if len(p.CXXFiles)+len(p.SwigFiles) > 0 {
   225				fmt.Fprintf(h, "CXX=%q %q\n", b.cxxExe(), cxxflags)
   226			}
   227			if len(p.FFiles) > 0 {
   228				fmt.Fprintf(h, "FC=%q %q\n", b.fcExe(), fflags)
   229			}
   230			// TODO(rsc): Should we include the SWIG version or Fortran/GCC/G++/Objective-C compiler versions?
   231		}
   232		if p.Internal.CoverMode != "" {
   233			fmt.Fprintf(h, "cover %q %q\n", p.Internal.CoverMode, b.toolID("cover"))
   234		}
   235		fmt.Fprintf(h, "modinfo %q\n", p.Internal.BuildInfo)
   236	
   237		// Configuration specific to compiler toolchain.
   238		switch cfg.BuildToolchainName {
   239		default:
   240			base.Fatalf("buildActionID: unknown build toolchain %q", cfg.BuildToolchainName)
   241		case "gc":
   242			fmt.Fprintf(h, "compile %s %q %q\n", b.toolID("compile"), forcedGcflags, p.Internal.Gcflags)
   243			if len(p.SFiles) > 0 {
   244				fmt.Fprintf(h, "asm %q %q %q\n", b.toolID("asm"), forcedAsmflags, p.Internal.Asmflags)
   245			}
   246	
   247			// GO386, GOARM, GOMIPS, etc.
   248			key, val := cfg.GetArchEnv()
   249			fmt.Fprintf(h, "%s=%s\n", key, val)
   250	
   251			// TODO(rsc): Convince compiler team not to add more magic environment variables,
   252			// or perhaps restrict the environment variables passed to subprocesses.
   253			// Because these are clumsy, undocumented special-case hacks
   254			// for debugging the compiler, they are not settable using 'go env -w',
   255			// and so here we use os.Getenv, not cfg.Getenv.
   256			magic := []string{
   257				"GOCLOBBERDEADHASH",
   258				"GOSSAFUNC",
   259				"GO_SSA_PHI_LOC_CUTOFF",
   260				"GOSSAHASH",
   261			}
   262			for _, env := range magic {
   263				if x := os.Getenv(env); x != "" {
   264					fmt.Fprintf(h, "magic %s=%s\n", env, x)
   265				}
   266			}
   267			if os.Getenv("GOSSAHASH") != "" {
   268				for i := 0; ; i++ {
   269					env := fmt.Sprintf("GOSSAHASH%d", i)
   270					x := os.Getenv(env)
   271					if x == "" {
   272						break
   273					}
   274					fmt.Fprintf(h, "magic %s=%s\n", env, x)
   275				}
   276			}
   277			if os.Getenv("GSHS_LOGFILE") != "" {
   278				// Clumsy hack. Compiler writes to this log file,
   279				// so do not allow use of cache at all.
   280				// We will still write to the cache but it will be
   281				// essentially unfindable.
   282				fmt.Fprintf(h, "nocache %d\n", time.Now().UnixNano())
   283			}
   284	
   285		case "gccgo":
   286			id, err := b.gccgoToolID(BuildToolchain.compiler(), "go")
   287			if err != nil {
   288				base.Fatalf("%v", err)
   289			}
   290			fmt.Fprintf(h, "compile %s %q %q\n", id, forcedGccgoflags, p.Internal.Gccgoflags)
   291			fmt.Fprintf(h, "pkgpath %s\n", gccgoPkgpath(p))
   292			fmt.Fprintf(h, "ar %q\n", BuildToolchain.(gccgoToolchain).ar())
   293			if len(p.SFiles) > 0 {
   294				id, _ = b.gccgoToolID(BuildToolchain.compiler(), "assembler-with-cpp")
   295				// Ignore error; different assembler versions
   296				// are unlikely to make any difference anyhow.
   297				fmt.Fprintf(h, "asm %q\n", id)
   298			}
   299		}
   300	
   301		// Input files.
   302		inputFiles := str.StringList(
   303			p.GoFiles,
   304			p.CgoFiles,
   305			p.CFiles,
   306			p.CXXFiles,
   307			p.FFiles,
   308			p.MFiles,
   309			p.HFiles,
   310			p.SFiles,
   311			p.SysoFiles,
   312			p.SwigFiles,
   313			p.SwigCXXFiles,
   314		)
   315		for _, file := range inputFiles {
   316			fmt.Fprintf(h, "file %s %s\n", file, b.fileHash(filepath.Join(p.Dir, file)))
   317		}
   318		for _, a1 := range a.Deps {
   319			p1 := a1.Package
   320			if p1 != nil {
   321				fmt.Fprintf(h, "import %s %s\n", p1.ImportPath, contentID(a1.buildID))
   322			}
   323		}
   324	
   325		return h.Sum()
   326	}
   327	
   328	// needCgoHdr reports whether the actions triggered by this one
   329	// expect to be able to access the cgo-generated header file.
   330	func (b *Builder) needCgoHdr(a *Action) bool {
   331		// If this build triggers a header install, run cgo to get the header.
   332		if !b.IsCmdList && (a.Package.UsesCgo() || a.Package.UsesSwig()) && (cfg.BuildBuildmode == "c-archive" || cfg.BuildBuildmode == "c-shared") {
   333			for _, t1 := range a.triggers {
   334				if t1.Mode == "install header" {
   335					return true
   336				}
   337			}
   338			for _, t1 := range a.triggers {
   339				for _, t2 := range t1.triggers {
   340					if t2.Mode == "install header" {
   341						return true
   342					}
   343				}
   344			}
   345		}
   346		return false
   347	}
   348	
   349	// allowedVersion reports whether the version v is an allowed version of go
   350	// (one that we can compile).
   351	// v is known to be of the form "1.23".
   352	func allowedVersion(v string) bool {
   353		// Special case: no requirement.
   354		if v == "" {
   355			return true
   356		}
   357		// Special case "1.0" means "go1", which is OK.
   358		if v == "1.0" {
   359			return true
   360		}
   361		// Otherwise look through release tags of form "go1.23" for one that matches.
   362		for _, tag := range cfg.BuildContext.ReleaseTags {
   363			if strings.HasPrefix(tag, "go") && tag[2:] == v {
   364				return true
   365			}
   366		}
   367		return false
   368	}
   369	
   370	const (
   371		needBuild uint32 = 1 << iota
   372		needCgoHdr
   373		needVet
   374		needCompiledGoFiles
   375		needStale
   376	)
   377	
   378	// build is the action for building a single package.
   379	// Note that any new influence on this logic must be reported in b.buildActionID above as well.
   380	func (b *Builder) build(a *Action) (err error) {
   381		p := a.Package
   382	
   383		bit := func(x uint32, b bool) uint32 {
   384			if b {
   385				return x
   386			}
   387			return 0
   388		}
   389	
   390		cachedBuild := false
   391		need := bit(needBuild, !b.IsCmdList && a.needBuild || b.NeedExport) |
   392			bit(needCgoHdr, b.needCgoHdr(a)) |
   393			bit(needVet, a.needVet) |
   394			bit(needCompiledGoFiles, b.NeedCompiledGoFiles)
   395	
   396		if !p.BinaryOnly {
   397			if b.useCache(a, p, b.buildActionID(a), p.Target) {
   398				// We found the main output in the cache.
   399				// If we don't need any other outputs, we can stop.
   400				// Otherwise, we need to write files to a.Objdir (needVet, needCgoHdr).
   401				// Remember that we might have them in cache
   402				// and check again after we create a.Objdir.
   403				cachedBuild = true
   404				a.output = []byte{} // start saving output in case we miss any cache results
   405				need &^= needBuild
   406				if b.NeedExport {
   407					p.Export = a.built
   408				}
   409				if need&needCompiledGoFiles != 0 && b.loadCachedSrcFiles(a) {
   410					need &^= needCompiledGoFiles
   411				}
   412			}
   413	
   414			// Source files might be cached, even if the full action is not
   415			// (e.g., go list -compiled -find).
   416			if !cachedBuild && need&needCompiledGoFiles != 0 && b.loadCachedSrcFiles(a) {
   417				need &^= needCompiledGoFiles
   418			}
   419	
   420			if need == 0 {
   421				return nil
   422			}
   423			defer b.flushOutput(a)
   424		}
   425	
   426		defer func() {
   427			if err != nil && err != errPrintedOutput {
   428				err = fmt.Errorf("go build %s: %v", a.Package.ImportPath, err)
   429			}
   430			if err != nil && b.IsCmdList && b.NeedError && p.Error == nil {
   431				p.Error = &load.PackageError{Err: err.Error()}
   432			}
   433		}()
   434		if cfg.BuildN {
   435			// In -n mode, print a banner between packages.
   436			// The banner is five lines so that when changes to
   437			// different sections of the bootstrap script have to
   438			// be merged, the banners give patch something
   439			// to use to find its context.
   440			b.Print("\n#\n# " + a.Package.ImportPath + "\n#\n\n")
   441		}
   442	
   443		if cfg.BuildV {
   444			b.Print(a.Package.ImportPath + "\n")
   445		}
   446	
   447		if a.Package.BinaryOnly {
   448			p.Stale = true
   449			p.StaleReason = "binary-only packages are no longer supported"
   450			if b.IsCmdList {
   451				return nil
   452			}
   453			return errors.New("binary-only packages are no longer supported")
   454		}
   455	
   456		if err := b.Mkdir(a.Objdir); err != nil {
   457			return err
   458		}
   459		objdir := a.Objdir
   460	
   461		// Load cached cgo header, but only if we're skipping the main build (cachedBuild==true).
   462		if cachedBuild && need&needCgoHdr != 0 && b.loadCachedCgoHdr(a) {
   463			need &^= needCgoHdr
   464		}
   465	
   466		// Load cached vet config, but only if that's all we have left
   467		// (need == needVet, not testing just the one bit).
   468		// If we are going to do a full build anyway,
   469		// we're going to regenerate the files below anyway.
   470		if need == needVet && b.loadCachedVet(a) {
   471			need &^= needVet
   472		}
   473		if need == 0 {
   474			return nil
   475		}
   476	
   477		// make target directory
   478		dir, _ := filepath.Split(a.Target)
   479		if dir != "" {
   480			if err := b.Mkdir(dir); err != nil {
   481				return err
   482			}
   483		}
   484	
   485		gofiles := str.StringList(a.Package.GoFiles)
   486		cgofiles := str.StringList(a.Package.CgoFiles)
   487		cfiles := str.StringList(a.Package.CFiles)
   488		sfiles := str.StringList(a.Package.SFiles)
   489		cxxfiles := str.StringList(a.Package.CXXFiles)
   490		var objects, cgoObjects, pcCFLAGS, pcLDFLAGS []string
   491	
   492		if a.Package.UsesCgo() || a.Package.UsesSwig() {
   493			if pcCFLAGS, pcLDFLAGS, err = b.getPkgConfigFlags(a.Package); err != nil {
   494				return
   495			}
   496		}
   497	
   498		// Run SWIG on each .swig and .swigcxx file.
   499		// Each run will generate two files, a .go file and a .c or .cxx file.
   500		// The .go file will use import "C" and is to be processed by cgo.
   501		if a.Package.UsesSwig() {
   502			outGo, outC, outCXX, err := b.swig(a, a.Package, objdir, pcCFLAGS)
   503			if err != nil {
   504				return err
   505			}
   506			cgofiles = append(cgofiles, outGo...)
   507			cfiles = append(cfiles, outC...)
   508			cxxfiles = append(cxxfiles, outCXX...)
   509		}
   510	
   511		// If we're doing coverage, preprocess the .go files and put them in the work directory
   512		if a.Package.Internal.CoverMode != "" {
   513			for i, file := range str.StringList(gofiles, cgofiles) {
   514				var sourceFile string
   515				var coverFile string
   516				var key string
   517				if strings.HasSuffix(file, ".cgo1.go") {
   518					// cgo files have absolute paths
   519					base := filepath.Base(file)
   520					sourceFile = file
   521					coverFile = objdir + base
   522					key = strings.TrimSuffix(base, ".cgo1.go") + ".go"
   523				} else {
   524					sourceFile = filepath.Join(a.Package.Dir, file)
   525					coverFile = objdir + file
   526					key = file
   527				}
   528				coverFile = strings.TrimSuffix(coverFile, ".go") + ".cover.go"
   529				cover := a.Package.Internal.CoverVars[key]
   530				if cover == nil || base.IsTestFile(file) {
   531					// Not covering this file.
   532					continue
   533				}
   534				if err := b.cover(a, coverFile, sourceFile, cover.Var); err != nil {
   535					return err
   536				}
   537				if i < len(gofiles) {
   538					gofiles[i] = coverFile
   539				} else {
   540					cgofiles[i-len(gofiles)] = coverFile
   541				}
   542			}
   543		}
   544	
   545		// Run cgo.
   546		if a.Package.UsesCgo() || a.Package.UsesSwig() {
   547			// In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
   548			// There is one exception: runtime/cgo's job is to bridge the
   549			// cgo and non-cgo worlds, so it necessarily has files in both.
   550			// In that case gcc only gets the gcc_* files.
   551			var gccfiles []string
   552			gccfiles = append(gccfiles, cfiles...)
   553			cfiles = nil
   554			if a.Package.Standard && a.Package.ImportPath == "runtime/cgo" {
   555				filter := func(files, nongcc, gcc []string) ([]string, []string) {
   556					for _, f := range files {
   557						if strings.HasPrefix(f, "gcc_") {
   558							gcc = append(gcc, f)
   559						} else {
   560							nongcc = append(nongcc, f)
   561						}
   562					}
   563					return nongcc, gcc
   564				}
   565				sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles)
   566			} else {
   567				for _, sfile := range sfiles {
   568					data, err := ioutil.ReadFile(filepath.Join(a.Package.Dir, sfile))
   569					if err == nil {
   570						if bytes.HasPrefix(data, []byte("TEXT")) || bytes.Contains(data, []byte("\nTEXT")) ||
   571							bytes.HasPrefix(data, []byte("DATA")) || bytes.Contains(data, []byte("\nDATA")) ||
   572							bytes.HasPrefix(data, []byte("GLOBL")) || bytes.Contains(data, []byte("\nGLOBL")) {
   573							return fmt.Errorf("package using cgo has Go assembly file %s", sfile)
   574						}
   575					}
   576				}
   577				gccfiles = append(gccfiles, sfiles...)
   578				sfiles = nil
   579			}
   580	
   581			outGo, outObj, err := b.cgo(a, base.Tool("cgo"), objdir, pcCFLAGS, pcLDFLAGS, mkAbsFiles(a.Package.Dir, cgofiles), gccfiles, cxxfiles, a.Package.MFiles, a.Package.FFiles)
   582			if err != nil {
   583				return err
   584			}
   585			if cfg.BuildToolchainName == "gccgo" {
   586				cgoObjects = append(cgoObjects, a.Objdir+"_cgo_flags")
   587			}
   588			cgoObjects = append(cgoObjects, outObj...)
   589			gofiles = append(gofiles, outGo...)
   590	
   591			switch cfg.BuildBuildmode {
   592			case "c-archive", "c-shared":
   593				b.cacheCgoHdr(a)
   594			}
   595		}
   596	
   597		var srcfiles []string // .go and non-.go
   598		srcfiles = append(srcfiles, gofiles...)
   599		srcfiles = append(srcfiles, sfiles...)
   600		srcfiles = append(srcfiles, cfiles...)
   601		srcfiles = append(srcfiles, cxxfiles...)
   602		b.cacheSrcFiles(a, srcfiles)
   603	
   604		// Running cgo generated the cgo header.
   605		need &^= needCgoHdr
   606	
   607		// Sanity check only, since Package.load already checked as well.
   608		if len(gofiles) == 0 {
   609			return &load.NoGoError{Package: a.Package}
   610		}
   611	
   612		// Prepare Go vet config if needed.
   613		if need&needVet != 0 {
   614			buildVetConfig(a, srcfiles)
   615			need &^= needVet
   616		}
   617		if need&needCompiledGoFiles != 0 {
   618			if !b.loadCachedSrcFiles(a) {
   619				return fmt.Errorf("failed to cache compiled Go files")
   620			}
   621			need &^= needCompiledGoFiles
   622		}
   623		if need == 0 {
   624			// Nothing left to do.
   625			return nil
   626		}
   627	
   628		// Collect symbol ABI requirements from assembly.
   629		symabis, err := BuildToolchain.symabis(b, a, sfiles)
   630		if err != nil {
   631			return err
   632		}
   633	
   634		// Prepare Go import config.
   635		// We start it off with a comment so it can't be empty, so icfg.Bytes() below is never nil.
   636		// It should never be empty anyway, but there have been bugs in the past that resulted
   637		// in empty configs, which then unfortunately turn into "no config passed to compiler",
   638		// and the compiler falls back to looking in pkg itself, which mostly works,
   639		// except when it doesn't.
   640		var icfg bytes.Buffer
   641		fmt.Fprintf(&icfg, "# import config\n")
   642		for i, raw := range a.Package.Internal.RawImports {
   643			final := a.Package.Imports[i]
   644			if final != raw {
   645				fmt.Fprintf(&icfg, "importmap %s=%s\n", raw, final)
   646			}
   647		}
   648		for _, a1 := range a.Deps {
   649			p1 := a1.Package
   650			if p1 == nil || p1.ImportPath == "" || a1.built == "" {
   651				continue
   652			}
   653			fmt.Fprintf(&icfg, "packagefile %s=%s\n", p1.ImportPath, a1.built)
   654		}
   655	
   656		if p.Internal.BuildInfo != "" && cfg.ModulesEnabled {
   657			if err := b.writeFile(objdir+"_gomod_.go", load.ModInfoProg(p.Internal.BuildInfo)); err != nil {
   658				return err
   659			}
   660			gofiles = append(gofiles, objdir+"_gomod_.go")
   661		}
   662	
   663		// Compile Go.
   664		objpkg := objdir + "_pkg_.a"
   665		ofile, out, err := BuildToolchain.gc(b, a, objpkg, icfg.Bytes(), symabis, len(sfiles) > 0, gofiles)
   666		if len(out) > 0 {
   667			output := b.processOutput(out)
   668			if p.Module != nil && !allowedVersion(p.Module.GoVersion) {
   669				output += "note: module requires Go " + p.Module.GoVersion + "\n"
   670			}
   671			b.showOutput(a, a.Package.Dir, a.Package.Desc(), output)
   672			if err != nil {
   673				return errPrintedOutput
   674			}
   675		}
   676		if err != nil {
   677			if p.Module != nil && !allowedVersion(p.Module.GoVersion) {
   678				b.showOutput(a, a.Package.Dir, a.Package.Desc(), "note: module requires Go "+p.Module.GoVersion)
   679			}
   680			return err
   681		}
   682		if ofile != objpkg {
   683			objects = append(objects, ofile)
   684		}
   685	
   686		// Copy .h files named for goos or goarch or goos_goarch
   687		// to names using GOOS and GOARCH.
   688		// For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
   689		_goos_goarch := "_" + cfg.Goos + "_" + cfg.Goarch
   690		_goos := "_" + cfg.Goos
   691		_goarch := "_" + cfg.Goarch
   692		for _, file := range a.Package.HFiles {
   693			name, ext := fileExtSplit(file)
   694			switch {
   695			case strings.HasSuffix(name, _goos_goarch):
   696				targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext
   697				if err := b.copyFile(objdir+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil {
   698					return err
   699				}
   700			case strings.HasSuffix(name, _goarch):
   701				targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext
   702				if err := b.copyFile(objdir+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil {
   703					return err
   704				}
   705			case strings.HasSuffix(name, _goos):
   706				targ := file[:len(name)-len(_goos)] + "_GOOS." + ext
   707				if err := b.copyFile(objdir+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil {
   708					return err
   709				}
   710			}
   711		}
   712	
   713		for _, file := range cfiles {
   714			out := file[:len(file)-len(".c")] + ".o"
   715			if err := BuildToolchain.cc(b, a, objdir+out, file); err != nil {
   716				return err
   717			}
   718			objects = append(objects, out)
   719		}
   720	
   721		// Assemble .s files.
   722		if len(sfiles) > 0 {
   723			ofiles, err := BuildToolchain.asm(b, a, sfiles)
   724			if err != nil {
   725				return err
   726			}
   727			objects = append(objects, ofiles...)
   728		}
   729	
   730		// For gccgo on ELF systems, we write the build ID as an assembler file.
   731		// This lets us set the SHF_EXCLUDE flag.
   732		// This is read by readGccgoArchive in cmd/internal/buildid/buildid.go.
   733		if a.buildID != "" && cfg.BuildToolchainName == "gccgo" {
   734			switch cfg.Goos {
   735			case "aix", "android", "dragonfly", "freebsd", "illumos", "linux", "netbsd", "openbsd", "solaris":
   736				asmfile, err := b.gccgoBuildIDFile(a)
   737				if err != nil {
   738					return err
   739				}
   740				ofiles, err := BuildToolchain.asm(b, a, []string{asmfile})
   741				if err != nil {
   742					return err
   743				}
   744				objects = append(objects, ofiles...)
   745			}
   746		}
   747	
   748		// NOTE(rsc): On Windows, it is critically important that the
   749		// gcc-compiled objects (cgoObjects) be listed after the ordinary
   750		// objects in the archive. I do not know why this is.
   751		// https://golang.org/issue/2601
   752		objects = append(objects, cgoObjects...)
   753	
   754		// Add system object files.
   755		for _, syso := range a.Package.SysoFiles {
   756			objects = append(objects, filepath.Join(a.Package.Dir, syso))
   757		}
   758	
   759		// Pack into archive in objdir directory.
   760		// If the Go compiler wrote an archive, we only need to add the
   761		// object files for non-Go sources to the archive.
   762		// If the Go compiler wrote an archive and the package is entirely
   763		// Go sources, there is no pack to execute at all.
   764		if len(objects) > 0 {
   765			if err := BuildToolchain.pack(b, a, objpkg, objects); err != nil {
   766				return err
   767			}
   768		}
   769	
   770		if err := b.updateBuildID(a, objpkg, true); err != nil {
   771			return err
   772		}
   773	
   774		a.built = objpkg
   775		return nil
   776	}
   777	
   778	func (b *Builder) cacheObjdirFile(a *Action, c *cache.Cache, name string) error {
   779		f, err := os.Open(a.Objdir + name)
   780		if err != nil {
   781			return err
   782		}
   783		defer f.Close()
   784		_, _, err = c.Put(cache.Subkey(a.actionID, name), f)
   785		return err
   786	}
   787	
   788	func (b *Builder) findCachedObjdirFile(a *Action, c *cache.Cache, name string) (string, error) {
   789		file, _, err := c.GetFile(cache.Subkey(a.actionID, name))
   790		if err != nil {
   791			return "", err
   792		}
   793		return file, nil
   794	}
   795	
   796	func (b *Builder) loadCachedObjdirFile(a *Action, c *cache.Cache, name string) error {
   797		cached, err := b.findCachedObjdirFile(a, c, name)
   798		if err != nil {
   799			return err
   800		}
   801		return b.copyFile(a.Objdir+name, cached, 0666, true)
   802	}
   803	
   804	func (b *Builder) cacheCgoHdr(a *Action) {
   805		c := cache.Default()
   806		if c == nil {
   807			return
   808		}
   809		b.cacheObjdirFile(a, c, "_cgo_install.h")
   810	}
   811	
   812	func (b *Builder) loadCachedCgoHdr(a *Action) bool {
   813		c := cache.Default()
   814		if c == nil {
   815			return false
   816		}
   817		err := b.loadCachedObjdirFile(a, c, "_cgo_install.h")
   818		return err == nil
   819	}
   820	
   821	func (b *Builder) cacheSrcFiles(a *Action, srcfiles []string) {
   822		c := cache.Default()
   823		if c == nil {
   824			return
   825		}
   826		var buf bytes.Buffer
   827		for _, file := range srcfiles {
   828			if !strings.HasPrefix(file, a.Objdir) {
   829				// not generated
   830				buf.WriteString("./")
   831				buf.WriteString(file)
   832				buf.WriteString("\n")
   833				continue
   834			}
   835			name := file[len(a.Objdir):]
   836			buf.WriteString(name)
   837			buf.WriteString("\n")
   838			if err := b.cacheObjdirFile(a, c, name); err != nil {
   839				return
   840			}
   841		}
   842		c.PutBytes(cache.Subkey(a.actionID, "srcfiles"), buf.Bytes())
   843	}
   844	
   845	func (b *Builder) loadCachedVet(a *Action) bool {
   846		c := cache.Default()
   847		if c == nil {
   848			return false
   849		}
   850		list, _, err := c.GetBytes(cache.Subkey(a.actionID, "srcfiles"))
   851		if err != nil {
   852			return false
   853		}
   854		var srcfiles []string
   855		for _, name := range strings.Split(string(list), "\n") {
   856			if name == "" { // end of list
   857				continue
   858			}
   859			if strings.HasPrefix(name, "./") {
   860				srcfiles = append(srcfiles, name[2:])
   861				continue
   862			}
   863			if err := b.loadCachedObjdirFile(a, c, name); err != nil {
   864				return false
   865			}
   866			srcfiles = append(srcfiles, a.Objdir+name)
   867		}
   868		buildVetConfig(a, srcfiles)
   869		return true
   870	}
   871	
   872	func (b *Builder) loadCachedSrcFiles(a *Action) bool {
   873		c := cache.Default()
   874		if c == nil {
   875			return false
   876		}
   877		list, _, err := c.GetBytes(cache.Subkey(a.actionID, "srcfiles"))
   878		if err != nil {
   879			return false
   880		}
   881		var files []string
   882		for _, name := range strings.Split(string(list), "\n") {
   883			if name == "" { // end of list
   884				continue
   885			}
   886			if strings.HasPrefix(name, "./") {
   887				files = append(files, name[len("./"):])
   888				continue
   889			}
   890			file, err := b.findCachedObjdirFile(a, c, name)
   891			if err != nil {
   892				return false
   893			}
   894			files = append(files, file)
   895		}
   896		a.Package.CompiledGoFiles = files
   897		return true
   898	}
   899	
   900	// vetConfig is the configuration passed to vet describing a single package.
   901	type vetConfig struct {
   902		ID         string   // package ID (example: "fmt [fmt.test]")
   903		Compiler   string   // compiler name (gc, gccgo)
   904		Dir        string   // directory containing package
   905		ImportPath string   // canonical import path ("package path")
   906		GoFiles    []string // absolute paths to package source files
   907		NonGoFiles []string // absolute paths to package non-Go files
   908	
   909		ImportMap   map[string]string // map import path in source code to package path
   910		PackageFile map[string]string // map package path to .a file with export data
   911		Standard    map[string]bool   // map package path to whether it's in the standard library
   912		PackageVetx map[string]string // map package path to vetx data from earlier vet run
   913		VetxOnly    bool              // only compute vetx data; don't report detected problems
   914		VetxOutput  string            // write vetx data to this output file
   915	
   916		SucceedOnTypecheckFailure bool // awful hack; see #18395 and below
   917	}
   918	
   919	func buildVetConfig(a *Action, srcfiles []string) {
   920		// Classify files based on .go extension.
   921		// srcfiles does not include raw cgo files.
   922		var gofiles, nongofiles []string
   923		for _, name := range srcfiles {
   924			if strings.HasSuffix(name, ".go") {
   925				gofiles = append(gofiles, name)
   926			} else {
   927				nongofiles = append(nongofiles, name)
   928			}
   929		}
   930	
   931		// Pass list of absolute paths to vet,
   932		// so that vet's error messages will use absolute paths,
   933		// so that we can reformat them relative to the directory
   934		// in which the go command is invoked.
   935		vcfg := &vetConfig{
   936			ID:          a.Package.ImportPath,
   937			Compiler:    cfg.BuildToolchainName,
   938			Dir:         a.Package.Dir,
   939			GoFiles:     mkAbsFiles(a.Package.Dir, gofiles),
   940			NonGoFiles:  mkAbsFiles(a.Package.Dir, nongofiles),
   941			ImportPath:  a.Package.ImportPath,
   942			ImportMap:   make(map[string]string),
   943			PackageFile: make(map[string]string),
   944			Standard:    make(map[string]bool),
   945		}
   946		a.vetCfg = vcfg
   947		for i, raw := range a.Package.Internal.RawImports {
   948			final := a.Package.Imports[i]
   949			vcfg.ImportMap[raw] = final
   950		}
   951	
   952		// Compute the list of mapped imports in the vet config
   953		// so that we can add any missing mappings below.
   954		vcfgMapped := make(map[string]bool)
   955		for _, p := range vcfg.ImportMap {
   956			vcfgMapped[p] = true
   957		}
   958	
   959		for _, a1 := range a.Deps {
   960			p1 := a1.Package
   961			if p1 == nil || p1.ImportPath == "" {
   962				continue
   963			}
   964			// Add import mapping if needed
   965			// (for imports like "runtime/cgo" that appear only in generated code).
   966			if !vcfgMapped[p1.ImportPath] {
   967				vcfg.ImportMap[p1.ImportPath] = p1.ImportPath
   968			}
   969			if a1.built != "" {
   970				vcfg.PackageFile[p1.ImportPath] = a1.built
   971			}
   972			if p1.Standard {
   973				vcfg.Standard[p1.ImportPath] = true
   974			}
   975		}
   976	}
   977	
   978	// VetTool is the path to an alternate vet tool binary.
   979	// The caller is expected to set it (if needed) before executing any vet actions.
   980	var VetTool string
   981	
   982	// VetFlags are the default flags to pass to vet.
   983	// The caller is expected to set them before executing any vet actions.
   984	var VetFlags []string
   985	
   986	// VetExplicit records whether the vet flags were set explicitly on the command line.
   987	var VetExplicit bool
   988	
   989	func (b *Builder) vet(a *Action) error {
   990		// a.Deps[0] is the build of the package being vetted.
   991		// a.Deps[1] is the build of the "fmt" package.
   992	
   993		a.Failed = false // vet of dependency may have failed but we can still succeed
   994	
   995		if a.Deps[0].Failed {
   996			// The build of the package has failed. Skip vet check.
   997			// Vet could return export data for non-typecheck errors,
   998			// but we ignore it because the package cannot be compiled.
   999			return nil
  1000		}
  1001	
  1002		vcfg := a.Deps[0].vetCfg
  1003		if vcfg == nil {
  1004			// Vet config should only be missing if the build failed.
  1005			return fmt.Errorf("vet config not found")
  1006		}
  1007	
  1008		vcfg.VetxOnly = a.VetxOnly
  1009		vcfg.VetxOutput = a.Objdir + "vet.out"
  1010		vcfg.PackageVetx = make(map[string]string)
  1011	
  1012		h := cache.NewHash("vet " + a.Package.ImportPath)
  1013		fmt.Fprintf(h, "vet %q\n", b.toolID("vet"))
  1014	
  1015		vetFlags := VetFlags
  1016	
  1017		// In GOROOT, we enable all the vet tests during 'go test',
  1018		// not just the high-confidence subset. This gets us extra
  1019		// checking for the standard library (at some compliance cost)
  1020		// and helps us gain experience about how well the checks
  1021		// work, to help decide which should be turned on by default.
  1022		// The command-line still wins.
  1023		//
  1024		// Note that this flag change applies even when running vet as
  1025		// a dependency of vetting a package outside std.
  1026		// (Otherwise we'd have to introduce a whole separate
  1027		// space of "vet fmt as a dependency of a std top-level vet"
  1028		// versus "vet fmt as a dependency of a non-std top-level vet".)
  1029		// This is OK as long as the packages that are farther down the
  1030		// dependency tree turn on *more* analysis, as here.
  1031		// (The unsafeptr check does not write any facts for use by
  1032		// later vet runs.)
  1033		if a.Package.Goroot && !VetExplicit && VetTool == "" {
  1034			// Note that $GOROOT/src/buildall.bash
  1035			// does the same for the misc-compile trybots
  1036			// and should be updated if these flags are
  1037			// changed here.
  1038			//
  1039			// There's too much unsafe.Pointer code
  1040			// that vet doesn't like in low-level packages
  1041			// like runtime, sync, and reflect.
  1042			vetFlags = []string{"-unsafeptr=false"}
  1043		}
  1044	
  1045		// Note: We could decide that vet should compute export data for
  1046		// all analyses, in which case we don't need to include the flags here.
  1047		// But that would mean that if an analysis causes problems like
  1048		// unexpected crashes there would be no way to turn it off.
  1049		// It seems better to let the flags disable export analysis too.
  1050		fmt.Fprintf(h, "vetflags %q\n", vetFlags)
  1051	
  1052		fmt.Fprintf(h, "pkg %q\n", a.Deps[0].actionID)
  1053		for _, a1 := range a.Deps {
  1054			if a1.Mode == "vet" && a1.built != "" {
  1055				fmt.Fprintf(h, "vetout %q %s\n", a1.Package.ImportPath, b.fileHash(a1.built))
  1056				vcfg.PackageVetx[a1.Package.ImportPath] = a1.built
  1057			}
  1058		}
  1059		key := cache.ActionID(h.Sum())
  1060	
  1061		if vcfg.VetxOnly {
  1062			if c := cache.Default(); c != nil && !cfg.BuildA {
  1063				if file, _, err := c.GetFile(key); err == nil {
  1064					a.built = file
  1065					return nil
  1066				}
  1067			}
  1068		}
  1069	
  1070		js, err := json.MarshalIndent(vcfg, "", "\t")
  1071		if err != nil {
  1072			return fmt.Errorf("internal error marshaling vet config: %v", err)
  1073		}
  1074		js = append(js, '\n')
  1075		if err := b.writeFile(a.Objdir+"vet.cfg", js); err != nil {
  1076			return err
  1077		}
  1078	
  1079		env := b.cCompilerEnv()
  1080		if cfg.BuildToolchainName == "gccgo" {
  1081			env = append(env, "GCCGO="+BuildToolchain.compiler())
  1082		}
  1083	
  1084		p := a.Package
  1085		tool := VetTool
  1086		if tool == "" {
  1087			tool = base.Tool("vet")
  1088		}
  1089		runErr := b.run(a, p.Dir, p.ImportPath, env, cfg.BuildToolexec, tool, vetFlags, a.Objdir+"vet.cfg")
  1090	
  1091		// If vet wrote export data, save it for input to future vets.
  1092		if f, err := os.Open(vcfg.VetxOutput); err == nil {
  1093			a.built = vcfg.VetxOutput
  1094			if c := cache.Default(); c != nil {
  1095				c.Put(key, f)
  1096			}
  1097			f.Close()
  1098		}
  1099	
  1100		return runErr
  1101	}
  1102	
  1103	// linkActionID computes the action ID for a link action.
  1104	func (b *Builder) linkActionID(a *Action) cache.ActionID {
  1105		p := a.Package
  1106		h := cache.NewHash("link " + p.ImportPath)
  1107	
  1108		// Toolchain-independent configuration.
  1109		fmt.Fprintf(h, "link\n")
  1110		fmt.Fprintf(h, "buildmode %s goos %s goarch %s\n", cfg.BuildBuildmode, cfg.Goos, cfg.Goarch)
  1111		fmt.Fprintf(h, "import %q\n", p.ImportPath)
  1112		fmt.Fprintf(h, "omitdebug %v standard %v local %v prefix %q\n", p.Internal.OmitDebug, p.Standard, p.Internal.Local, p.Internal.LocalPrefix)
  1113		if cfg.BuildTrimpath {
  1114			fmt.Fprintln(h, "trimpath")
  1115		}
  1116	
  1117		// Toolchain-dependent configuration, shared with b.linkSharedActionID.
  1118		b.printLinkerConfig(h, p)
  1119	
  1120		// Input files.
  1121		for _, a1 := range a.Deps {
  1122			p1 := a1.Package
  1123			if p1 != nil {
  1124				if a1.built != "" || a1.buildID != "" {
  1125					buildID := a1.buildID
  1126					if buildID == "" {
  1127						buildID = b.buildID(a1.built)
  1128					}
  1129					fmt.Fprintf(h, "packagefile %s=%s\n", p1.ImportPath, contentID(buildID))
  1130				}
  1131				// Because we put package main's full action ID into the binary's build ID,
  1132				// we must also put the full action ID into the binary's action ID hash.
  1133				if p1.Name == "main" {
  1134					fmt.Fprintf(h, "packagemain %s\n", a1.buildID)
  1135				}
  1136				if p1.Shlib != "" {
  1137					fmt.Fprintf(h, "packageshlib %s=%s\n", p1.ImportPath, contentID(b.buildID(p1.Shlib)))
  1138				}
  1139			}
  1140		}
  1141	
  1142		return h.Sum()
  1143	}
  1144	
  1145	// printLinkerConfig prints the linker config into the hash h,
  1146	// as part of the computation of a linker-related action ID.
  1147	func (b *Builder) printLinkerConfig(h io.Writer, p *load.Package) {
  1148		switch cfg.BuildToolchainName {
  1149		default:
  1150			base.Fatalf("linkActionID: unknown toolchain %q", cfg.BuildToolchainName)
  1151	
  1152		case "gc":
  1153			fmt.Fprintf(h, "link %s %q %s\n", b.toolID("link"), forcedLdflags, ldBuildmode)
  1154			if p != nil {
  1155				fmt.Fprintf(h, "linkflags %q\n", p.Internal.Ldflags)
  1156			}
  1157	
  1158			// GO386, GOARM, GOMIPS, etc.
  1159			key, val := cfg.GetArchEnv()
  1160			fmt.Fprintf(h, "%s=%s\n", key, val)
  1161	
  1162			// The linker writes source file paths that say GOROOT_FINAL.
  1163			fmt.Fprintf(h, "GOROOT=%s\n", cfg.GOROOT_FINAL)
  1164	
  1165			// GO_EXTLINK_ENABLED controls whether the external linker is used.
  1166			fmt.Fprintf(h, "GO_EXTLINK_ENABLED=%s\n", cfg.Getenv("GO_EXTLINK_ENABLED"))
  1167	
  1168			// TODO(rsc): Do cgo settings and flags need to be included?
  1169			// Or external linker settings and flags?
  1170	
  1171		case "gccgo":
  1172			id, err := b.gccgoToolID(BuildToolchain.linker(), "go")
  1173			if err != nil {
  1174				base.Fatalf("%v", err)
  1175			}
  1176			fmt.Fprintf(h, "link %s %s\n", id, ldBuildmode)
  1177			// TODO(iant): Should probably include cgo flags here.
  1178		}
  1179	}
  1180	
  1181	// link is the action for linking a single command.
  1182	// Note that any new influence on this logic must be reported in b.linkActionID above as well.
  1183	func (b *Builder) link(a *Action) (err error) {
  1184		if b.useCache(a, a.Package, b.linkActionID(a), a.Package.Target) || b.IsCmdList {
  1185			return nil
  1186		}
  1187		defer b.flushOutput(a)
  1188	
  1189		if err := b.Mkdir(a.Objdir); err != nil {
  1190			return err
  1191		}
  1192	
  1193		importcfg := a.Objdir + "importcfg.link"
  1194		if err := b.writeLinkImportcfg(a, importcfg); err != nil {
  1195			return err
  1196		}
  1197	
  1198		// make target directory
  1199		dir, _ := filepath.Split(a.Target)
  1200		if dir != "" {
  1201			if err := b.Mkdir(dir); err != nil {
  1202				return err
  1203			}
  1204		}
  1205	
  1206		if err := BuildToolchain.ld(b, a, a.Target, importcfg, a.Deps[0].built); err != nil {
  1207			return err
  1208		}
  1209	
  1210		// Update the binary with the final build ID.
  1211		// But if OmitDebug is set, don't rewrite the binary, because we set OmitDebug
  1212		// on binaries that we are going to run and then delete.
  1213		// There's no point in doing work on such a binary.
  1214		// Worse, opening the binary for write here makes it
  1215		// essentially impossible to safely fork+exec due to a fundamental
  1216		// incompatibility between ETXTBSY and threads on modern Unix systems.
  1217		// See golang.org/issue/22220.
  1218		// We still call updateBuildID to update a.buildID, which is important
  1219		// for test result caching, but passing rewrite=false (final arg)
  1220		// means we don't actually rewrite the binary, nor store the
  1221		// result into the cache. That's probably a net win:
  1222		// less cache space wasted on large binaries we are not likely to
  1223		// need again. (On the other hand it does make repeated go test slower.)
  1224		// It also makes repeated go run slower, which is a win in itself:
  1225		// we don't want people to treat go run like a scripting environment.
  1226		if err := b.updateBuildID(a, a.Target, !a.Package.Internal.OmitDebug); err != nil {
  1227			return err
  1228		}
  1229	
  1230		a.built = a.Target
  1231		return nil
  1232	}
  1233	
  1234	func (b *Builder) writeLinkImportcfg(a *Action, file string) error {
  1235		// Prepare Go import cfg.
  1236		var icfg bytes.Buffer
  1237		for _, a1 := range a.Deps {
  1238			p1 := a1.Package
  1239			if p1 == nil {
  1240				continue
  1241			}
  1242			fmt.Fprintf(&icfg, "packagefile %s=%s\n", p1.ImportPath, a1.built)
  1243			if p1.Shlib != "" {
  1244				fmt.Fprintf(&icfg, "packageshlib %s=%s\n", p1.ImportPath, p1.Shlib)
  1245			}
  1246		}
  1247		return b.writeFile(file, icfg.Bytes())
  1248	}
  1249	
  1250	// PkgconfigCmd returns a pkg-config binary name
  1251	// defaultPkgConfig is defined in zdefaultcc.go, written by cmd/dist.
  1252	func (b *Builder) PkgconfigCmd() string {
  1253		return envList("PKG_CONFIG", cfg.DefaultPkgConfig)[0]
  1254	}
  1255	
  1256	// splitPkgConfigOutput parses the pkg-config output into a slice of
  1257	// flags. This implements the algorithm from pkgconf/libpkgconf/argvsplit.c.
  1258	func splitPkgConfigOutput(out []byte) ([]string, error) {
  1259		if len(out) == 0 {
  1260			return nil, nil
  1261		}
  1262		var flags []string
  1263		flag := make([]byte, 0, len(out))
  1264		escaped := false
  1265		quote := byte(0)
  1266	
  1267		for _, c := range out {
  1268			if escaped {
  1269				if quote != 0 {
  1270					switch c {
  1271					case '$', '`', '"', '\\':
  1272					default:
  1273						flag = append(flag, '\\')
  1274					}
  1275					flag = append(flag, c)
  1276				} else {
  1277					flag = append(flag, c)
  1278				}
  1279				escaped = false
  1280			} else if quote != 0 {
  1281				if c == quote {
  1282					quote = 0
  1283				} else {
  1284					switch c {
  1285					case '\\':
  1286						escaped = true
  1287					default:
  1288						flag = append(flag, c)
  1289					}
  1290				}
  1291			} else if strings.IndexByte(" \t\n\v\f\r", c) < 0 {
  1292				switch c {
  1293				case '\\':
  1294					escaped = true
  1295				case '\'', '"':
  1296					quote = c
  1297				default:
  1298					flag = append(flag, c)
  1299				}
  1300			} else if len(flag) != 0 {
  1301				flags = append(flags, string(flag))
  1302				flag = flag[:0]
  1303			}
  1304		}
  1305		if escaped {
  1306			return nil, errors.New("broken character escaping in pkgconf output ")
  1307		}
  1308		if quote != 0 {
  1309			return nil, errors.New("unterminated quoted string in pkgconf output ")
  1310		} else if len(flag) != 0 {
  1311			flags = append(flags, string(flag))
  1312		}
  1313	
  1314		return flags, nil
  1315	}
  1316	
  1317	// Calls pkg-config if needed and returns the cflags/ldflags needed to build the package.
  1318	func (b *Builder) getPkgConfigFlags(p *load.Package) (cflags, ldflags []string, err error) {
  1319		if pcargs := p.CgoPkgConfig; len(pcargs) > 0 {
  1320			// pkg-config permits arguments to appear anywhere in
  1321			// the command line. Move them all to the front, before --.
  1322			var pcflags []string
  1323			var pkgs []string
  1324			for _, pcarg := range pcargs {
  1325				if pcarg == "--" {
  1326					// We're going to add our own "--" argument.
  1327				} else if strings.HasPrefix(pcarg, "--") {
  1328					pcflags = append(pcflags, pcarg)
  1329				} else {
  1330					pkgs = append(pkgs, pcarg)
  1331				}
  1332			}
  1333			for _, pkg := range pkgs {
  1334				if !load.SafeArg(pkg) {
  1335					return nil, nil, fmt.Errorf("invalid pkg-config package name: %s", pkg)
  1336				}
  1337			}
  1338			var out []byte
  1339			out, err = b.runOut(nil, p.Dir, nil, b.PkgconfigCmd(), "--cflags", pcflags, "--", pkgs)
  1340			if err != nil {
  1341				b.showOutput(nil, p.Dir, b.PkgconfigCmd()+" --cflags "+strings.Join(pcflags, " ")+" -- "+strings.Join(pkgs, " "), string(out))
  1342				b.Print(err.Error() + "\n")
  1343				return nil, nil, errPrintedOutput
  1344			}
  1345			if len(out) > 0 {
  1346				cflags, err = splitPkgConfigOutput(out)
  1347				if err != nil {
  1348					return nil, nil, err
  1349				}
  1350				if err := checkCompilerFlags("CFLAGS", "pkg-config --cflags", cflags); err != nil {
  1351					return nil, nil, err
  1352				}
  1353			}
  1354			out, err = b.runOut(nil, p.Dir, nil, b.PkgconfigCmd(), "--libs", pcflags, "--", pkgs)
  1355			if err != nil {
  1356				b.showOutput(nil, p.Dir, b.PkgconfigCmd()+" --libs "+strings.Join(pcflags, " ")+" -- "+strings.Join(pkgs, " "), string(out))
  1357				b.Print(err.Error() + "\n")
  1358				return nil, nil, errPrintedOutput
  1359			}
  1360			if len(out) > 0 {
  1361				ldflags = strings.Fields(string(out))
  1362				if err := checkLinkerFlags("LDFLAGS", "pkg-config --libs", ldflags); err != nil {
  1363					return nil, nil, err
  1364				}
  1365			}
  1366		}
  1367	
  1368		return
  1369	}
  1370	
  1371	func (b *Builder) installShlibname(a *Action) error {
  1372		// TODO: BuildN
  1373		a1 := a.Deps[0]
  1374		err := ioutil.WriteFile(a.Target, []byte(filepath.Base(a1.Target)+"\n"), 0666)
  1375		if err != nil {
  1376			return err
  1377		}
  1378		if cfg.BuildX {
  1379			b.Showcmd("", "echo '%s' > %s # internal", filepath.Base(a1.Target), a.Target)
  1380		}
  1381		return nil
  1382	}
  1383	
  1384	func (b *Builder) linkSharedActionID(a *Action) cache.ActionID {
  1385		h := cache.NewHash("linkShared")
  1386	
  1387		// Toolchain-independent configuration.
  1388		fmt.Fprintf(h, "linkShared\n")
  1389		fmt.Fprintf(h, "goos %s goarch %s\n", cfg.Goos, cfg.Goarch)
  1390	
  1391		// Toolchain-dependent configuration, shared with b.linkActionID.
  1392		b.printLinkerConfig(h, nil)
  1393	
  1394		// Input files.
  1395		for _, a1 := range a.Deps {
  1396			p1 := a1.Package
  1397			if a1.built == "" {
  1398				continue
  1399			}
  1400			if p1 != nil {
  1401				fmt.Fprintf(h, "packagefile %s=%s\n", p1.ImportPath, contentID(b.buildID(a1.built)))
  1402				if p1.Shlib != "" {
  1403					fmt.Fprintf(h, "packageshlib %s=%s\n", p1.ImportPath, contentID(b.buildID(p1.Shlib)))
  1404				}
  1405			}
  1406		}
  1407		// Files named on command line are special.
  1408		for _, a1 := range a.Deps[0].Deps {
  1409			p1 := a1.Package
  1410			fmt.Fprintf(h, "top %s=%s\n", p1.ImportPath, contentID(b.buildID(a1.built)))
  1411		}
  1412	
  1413		return h.Sum()
  1414	}
  1415	
  1416	func (b *Builder) linkShared(a *Action) (err error) {
  1417		if b.useCache(a, nil, b.linkSharedActionID(a), a.Target) || b.IsCmdList {
  1418			return nil
  1419		}
  1420		defer b.flushOutput(a)
  1421	
  1422		if err := b.Mkdir(a.Objdir); err != nil {
  1423			return err
  1424		}
  1425	
  1426		importcfg := a.Objdir + "importcfg.link"
  1427		if err := b.writeLinkImportcfg(a, importcfg); err != nil {
  1428			return err
  1429		}
  1430	
  1431		// TODO(rsc): There is a missing updateBuildID here,
  1432		// but we have to decide where to store the build ID in these files.
  1433		a.built = a.Target
  1434		return BuildToolchain.ldShared(b, a, a.Deps[0].Deps, a.Target, importcfg, a.Deps)
  1435	}
  1436	
  1437	// BuildInstallFunc is the action for installing a single package or executable.
  1438	func BuildInstallFunc(b *Builder, a *Action) (err error) {
  1439		defer func() {
  1440			if err != nil && err != errPrintedOutput {
  1441				// a.Package == nil is possible for the go install -buildmode=shared
  1442				// action that installs libmangledname.so, which corresponds to
  1443				// a list of packages, not just one.
  1444				sep, path := "", ""
  1445				if a.Package != nil {
  1446					sep, path = " ", a.Package.ImportPath
  1447				}
  1448				err = fmt.Errorf("go %s%s%s: %v", cfg.CmdName, sep, path, err)
  1449			}
  1450		}()
  1451	
  1452		a1 := a.Deps[0]
  1453		a.buildID = a1.buildID
  1454		if a.json != nil {
  1455			a.json.BuildID = a.buildID
  1456		}
  1457	
  1458		// If we are using the eventual install target as an up-to-date
  1459		// cached copy of the thing we built, then there's no need to
  1460		// copy it into itself (and that would probably fail anyway).
  1461		// In this case a1.built == a.Target because a1.built == p.Target,
  1462		// so the built target is not in the a1.Objdir tree that b.cleanup(a1) removes.
  1463		if a1.built == a.Target {
  1464			a.built = a.Target
  1465			if !a.buggyInstall {
  1466				b.cleanup(a1)
  1467			}
  1468			// Whether we're smart enough to avoid a complete rebuild
  1469			// depends on exactly what the staleness and rebuild algorithms
  1470			// are, as well as potentially the state of the Go build cache.
  1471			// We don't really want users to be able to infer (or worse start depending on)
  1472			// those details from whether the modification time changes during
  1473			// "go install", so do a best-effort update of the file times to make it
  1474			// look like we rewrote a.Target even if we did not. Updating the mtime
  1475			// may also help other mtime-based systems that depend on our
  1476			// previous mtime updates that happened more often.
  1477			// This is still not perfect - we ignore the error result, and if the file was
  1478			// unwritable for some reason then pretending to have written it is also
  1479			// confusing - but it's probably better than not doing the mtime update.
  1480			//
  1481			// But don't do that for the special case where building an executable
  1482			// with -linkshared implicitly installs all its dependent libraries.
  1483			// We want to hide that awful detail as much as possible, so don't
  1484			// advertise it by touching the mtimes (usually the libraries are up
  1485			// to date).
  1486			if !a.buggyInstall && !b.IsCmdList {
  1487				now := time.Now()
  1488				os.Chtimes(a.Target, now, now)
  1489			}
  1490			return nil
  1491		}
  1492	
  1493		// If we're building for go list -export,
  1494		// never install anything; just keep the cache reference.
  1495		if b.IsCmdList {
  1496			a.built = a1.built
  1497			return nil
  1498		}
  1499	
  1500		if err := b.Mkdir(a.Objdir); err != nil {
  1501			return err
  1502		}
  1503	
  1504		perm := os.FileMode(0666)
  1505		if a1.Mode == "link" {
  1506			switch cfg.BuildBuildmode {
  1507			case "c-archive", "c-shared", "plugin":
  1508			default:
  1509				perm = 0777
  1510			}
  1511		}
  1512	
  1513		// make target directory
  1514		dir, _ := filepath.Split(a.Target)
  1515		if dir != "" {
  1516			if err := b.Mkdir(dir); err != nil {
  1517				return err
  1518			}
  1519		}
  1520	
  1521		if !a.buggyInstall {
  1522			defer b.cleanup(a1)
  1523		}
  1524	
  1525		return b.moveOrCopyFile(a.Target, a1.built, perm, false)
  1526	}
  1527	
  1528	// cleanup removes a's object dir to keep the amount of
  1529	// on-disk garbage down in a large build. On an operating system
  1530	// with aggressive buffering, cleaning incrementally like
  1531	// this keeps the intermediate objects from hitting the disk.
  1532	func (b *Builder) cleanup(a *Action) {
  1533		if !cfg.BuildWork {
  1534			if cfg.BuildX {
  1535				// Don't say we are removing the directory if
  1536				// we never created it.
  1537				if _, err := os.Stat(a.Objdir); err == nil || cfg.BuildN {
  1538					b.Showcmd("", "rm -r %s", a.Objdir)
  1539				}
  1540			}
  1541			os.RemoveAll(a.Objdir)
  1542		}
  1543	}
  1544	
  1545	// moveOrCopyFile is like 'mv src dst' or 'cp src dst'.
  1546	func (b *Builder) moveOrCopyFile(dst, src string, perm os.FileMode, force bool) error {
  1547		if cfg.BuildN {
  1548			b.Showcmd("", "mv %s %s", src, dst)
  1549			return nil
  1550		}
  1551	
  1552		// If we can update the mode and rename to the dst, do it.
  1553		// Otherwise fall back to standard copy.
  1554	
  1555		// If the source is in the build cache, we need to copy it.
  1556		if strings.HasPrefix(src, cache.DefaultDir()) {
  1557			return b.copyFile(dst, src, perm, force)
  1558		}
  1559	
  1560		// On Windows, always copy the file, so that we respect the NTFS
  1561		// permissions of the parent folder. https://golang.org/issue/22343.
  1562		// What matters here is not cfg.Goos (the system we are building
  1563		// for) but runtime.GOOS (the system we are building on).
  1564		if runtime.GOOS == "windows" {
  1565			return b.copyFile(dst, src, perm, force)
  1566		}
  1567	
  1568		// If the destination directory has the group sticky bit set,
  1569		// we have to copy the file to retain the correct permissions.
  1570		// https://golang.org/issue/18878
  1571		if fi, err := os.Stat(filepath.Dir(dst)); err == nil {
  1572			if fi.IsDir() && (fi.Mode()&os.ModeSetgid) != 0 {
  1573				return b.copyFile(dst, src, perm, force)
  1574			}
  1575		}
  1576	
  1577		// The perm argument is meant to be adjusted according to umask,
  1578		// but we don't know what the umask is.
  1579		// Create a dummy file to find out.
  1580		// This avoids build tags and works even on systems like Plan 9
  1581		// where the file mask computation incorporates other information.
  1582		mode := perm
  1583		f, err := os.OpenFile(filepath.Clean(dst)+"-go-tmp-umask", os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm)
  1584		if err == nil {
  1585			fi, err := f.Stat()
  1586			if err == nil {
  1587				mode = fi.Mode() & 0777
  1588			}
  1589			name := f.Name()
  1590			f.Close()
  1591			os.Remove(name)
  1592		}
  1593	
  1594		if err := os.Chmod(src, mode); err == nil {
  1595			if err := os.Rename(src, dst); err == nil {
  1596				if cfg.BuildX {
  1597					b.Showcmd("", "mv %s %s", src, dst)
  1598				}
  1599				return nil
  1600			}
  1601		}
  1602	
  1603		return b.copyFile(dst, src, perm, force)
  1604	}
  1605	
  1606	// copyFile is like 'cp src dst'.
  1607	func (b *Builder) copyFile(dst, src string, perm os.FileMode, force bool) error {
  1608		if cfg.BuildN || cfg.BuildX {
  1609			b.Showcmd("", "cp %s %s", src, dst)
  1610			if cfg.BuildN {
  1611				return nil
  1612			}
  1613		}
  1614	
  1615		sf, err := os.Open(src)
  1616		if err != nil {
  1617			return err
  1618		}
  1619		defer sf.Close()
  1620	
  1621		// Be careful about removing/overwriting dst.
  1622		// Do not remove/overwrite if dst exists and is a directory
  1623		// or a non-object file.
  1624		if fi, err := os.Stat(dst); err == nil {
  1625			if fi.IsDir() {
  1626				return fmt.Errorf("build output %q already exists and is a directory", dst)
  1627			}
  1628			if !force && fi.Mode().IsRegular() && !isObject(dst) {
  1629				return fmt.Errorf("build output %q already exists and is not an object file", dst)
  1630			}
  1631		}
  1632	
  1633		// On Windows, remove lingering ~ file from last attempt.
  1634		if base.ToolIsWindows {
  1635			if _, err := os.Stat(dst + "~"); err == nil {
  1636				os.Remove(dst + "~")
  1637			}
  1638		}
  1639	
  1640		mayberemovefile(dst)
  1641		df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
  1642		if err != nil && base.ToolIsWindows {
  1643			// Windows does not allow deletion of a binary file
  1644			// while it is executing. Try to move it out of the way.
  1645			// If the move fails, which is likely, we'll try again the
  1646			// next time we do an install of this binary.
  1647			if err := os.Rename(dst, dst+"~"); err == nil {
  1648				os.Remove(dst + "~")
  1649			}
  1650			df, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
  1651		}
  1652		if err != nil {
  1653			return err
  1654		}
  1655	
  1656		_, err = io.Copy(df, sf)
  1657		df.Close()
  1658		if err != nil {
  1659			mayberemovefile(dst)
  1660			return fmt.Errorf("copying %s to %s: %v", src, dst, err)
  1661		}
  1662		return nil
  1663	}
  1664	
  1665	// writeFile writes the text to file.
  1666	func (b *Builder) writeFile(file string, text []byte) error {
  1667		if cfg.BuildN || cfg.BuildX {
  1668			b.Showcmd("", "cat >%s << 'EOF' # internal\n%sEOF", file, text)
  1669		}
  1670		if cfg.BuildN {
  1671			return nil
  1672		}
  1673		return ioutil.WriteFile(file, text, 0666)
  1674	}
  1675	
  1676	// Install the cgo export header file, if there is one.
  1677	func (b *Builder) installHeader(a *Action) error {
  1678		src := a.Objdir + "_cgo_install.h"
  1679		if _, err := os.Stat(src); os.IsNotExist(err) {
  1680			// If the file does not exist, there are no exported
  1681			// functions, and we do not install anything.
  1682			// TODO(rsc): Once we know that caching is rebuilding
  1683			// at the right times (not missing rebuilds), here we should
  1684			// probably delete the installed header, if any.
  1685			if cfg.BuildX {
  1686				b.Showcmd("", "# %s not created", src)
  1687			}
  1688			return nil
  1689		}
  1690	
  1691		dir, _ := filepath.Split(a.Target)
  1692		if dir != "" {
  1693			if err := b.Mkdir(dir); err != nil {
  1694				return err
  1695			}
  1696		}
  1697	
  1698		return b.moveOrCopyFile(a.Target, src, 0666, true)
  1699	}
  1700	
  1701	// cover runs, in effect,
  1702	//	go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
  1703	func (b *Builder) cover(a *Action, dst, src string, varName string) error {
  1704		return b.run(a, a.Objdir, "cover "+a.Package.ImportPath, nil,
  1705			cfg.BuildToolexec,
  1706			base.Tool("cover"),
  1707			"-mode", a.Package.Internal.CoverMode,
  1708			"-var", varName,
  1709			"-o", dst,
  1710			src)
  1711	}
  1712	
  1713	var objectMagic = [][]byte{
  1714		{'!', '<', 'a', 'r', 'c', 'h', '>', '\n'}, // Package archive
  1715		{'<', 'b', 'i', 'g', 'a', 'f', '>', '\n'}, // Package AIX big archive
  1716		{'\x7F', 'E', 'L', 'F'},                   // ELF
  1717		{0xFE, 0xED, 0xFA, 0xCE},                  // Mach-O big-endian 32-bit
  1718		{0xFE, 0xED, 0xFA, 0xCF},                  // Mach-O big-endian 64-bit
  1719		{0xCE, 0xFA, 0xED, 0xFE},                  // Mach-O little-endian 32-bit
  1720		{0xCF, 0xFA, 0xED, 0xFE},                  // Mach-O little-endian 64-bit
  1721		{0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00},      // PE (Windows) as generated by 6l/8l and gcc
  1722		{0x00, 0x00, 0x01, 0xEB},                  // Plan 9 i386
  1723		{0x00, 0x00, 0x8a, 0x97},                  // Plan 9 amd64
  1724		{0x00, 0x00, 0x06, 0x47},                  // Plan 9 arm
  1725		{0x00, 0x61, 0x73, 0x6D},                  // WASM
  1726		{0x01, 0xDF},                              // XCOFF 32bit
  1727		{0x01, 0xF7},                              // XCOFF 64bit
  1728	}
  1729	
  1730	func isObject(s string) bool {
  1731		f, err := os.Open(s)
  1732		if err != nil {
  1733			return false
  1734		}
  1735		defer f.Close()
  1736		buf := make([]byte, 64)
  1737		io.ReadFull(f, buf)
  1738		for _, magic := range objectMagic {
  1739			if bytes.HasPrefix(buf, magic) {
  1740				return true
  1741			}
  1742		}
  1743		return false
  1744	}
  1745	
  1746	// mayberemovefile removes a file only if it is a regular file
  1747	// When running as a user with sufficient privileges, we may delete
  1748	// even device files, for example, which is not intended.
  1749	func mayberemovefile(s string) {
  1750		if fi, err := os.Lstat(s); err == nil && !fi.Mode().IsRegular() {
  1751			return
  1752		}
  1753		os.Remove(s)
  1754	}
  1755	
  1756	// fmtcmd formats a command in the manner of fmt.Sprintf but also:
  1757	//
  1758	//	If dir is non-empty and the script is not in dir right now,
  1759	//	fmtcmd inserts "cd dir\n" before the command.
  1760	//
  1761	//	fmtcmd replaces the value of b.WorkDir with $WORK.
  1762	//	fmtcmd replaces the value of goroot with $GOROOT.
  1763	//	fmtcmd replaces the value of b.gobin with $GOBIN.
  1764	//
  1765	//	fmtcmd replaces the name of the current directory with dot (.)
  1766	//	but only when it is at the beginning of a space-separated token.
  1767	//
  1768	func (b *Builder) fmtcmd(dir string, format string, args ...interface{}) string {
  1769		cmd := fmt.Sprintf(format, args...)
  1770		if dir != "" && dir != "/" {
  1771			dot := " ."
  1772			if dir[len(dir)-1] == filepath.Separator {
  1773				dot += string(filepath.Separator)
  1774			}
  1775			cmd = strings.ReplaceAll(" "+cmd, " "+dir, dot)[1:]
  1776			if b.scriptDir != dir {
  1777				b.scriptDir = dir
  1778				cmd = "cd " + dir + "\n" + cmd
  1779			}
  1780		}
  1781		if b.WorkDir != "" {
  1782			cmd = strings.ReplaceAll(cmd, b.WorkDir, "$WORK")
  1783		}
  1784		return cmd
  1785	}
  1786	
  1787	// showcmd prints the given command to standard output
  1788	// for the implementation of -n or -x.
  1789	func (b *Builder) Showcmd(dir string, format string, args ...interface{}) {
  1790		b.output.Lock()
  1791		defer b.output.Unlock()
  1792		b.Print(b.fmtcmd(dir, format, args...) + "\n")
  1793	}
  1794	
  1795	// showOutput prints "# desc" followed by the given output.
  1796	// The output is expected to contain references to 'dir', usually
  1797	// the source directory for the package that has failed to build.
  1798	// showOutput rewrites mentions of dir with a relative path to dir
  1799	// when the relative path is shorter. This is usually more pleasant.
  1800	// For example, if fmt doesn't compile and we are in src/html,
  1801	// the output is
  1802	//
  1803	//	$ go build
  1804	//	# fmt
  1805	//	../fmt/print.go:1090: undefined: asdf
  1806	//	$
  1807	//
  1808	// instead of
  1809	//
  1810	//	$ go build
  1811	//	# fmt
  1812	//	/usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
  1813	//	$
  1814	//
  1815	// showOutput also replaces references to the work directory with $WORK.
  1816	//
  1817	// If a is not nil and a.output is not nil, showOutput appends to that slice instead of
  1818	// printing to b.Print.
  1819	//
  1820	func (b *Builder) showOutput(a *Action, dir, desc, out string) {
  1821		prefix := "# " + desc
  1822		suffix := "\n" + out
  1823		if reldir := base.ShortPath(dir); reldir != dir {
  1824			suffix = strings.ReplaceAll(suffix, " "+dir, " "+reldir)
  1825			suffix = strings.ReplaceAll(suffix, "\n"+dir, "\n"+reldir)
  1826		}
  1827		suffix = strings.ReplaceAll(suffix, " "+b.WorkDir, " $WORK")
  1828	
  1829		if a != nil && a.output != nil {
  1830			a.output = append(a.output, prefix...)
  1831			a.output = append(a.output, suffix...)
  1832			return
  1833		}
  1834	
  1835		b.output.Lock()
  1836		defer b.output.Unlock()
  1837		b.Print(prefix, suffix)
  1838	}
  1839	
  1840	// errPrintedOutput is a special error indicating that a command failed
  1841	// but that it generated output as well, and that output has already
  1842	// been printed, so there's no point showing 'exit status 1' or whatever
  1843	// the wait status was. The main executor, builder.do, knows not to
  1844	// print this error.
  1845	var errPrintedOutput = errors.New("already printed output - no need to show error")
  1846	
  1847	var cgoLine = lazyregexp.New(`\[[^\[\]]+\.(cgo1|cover)\.go:[0-9]+(:[0-9]+)?\]`)
  1848	var cgoTypeSigRe = lazyregexp.New(`\b_C2?(type|func|var|macro)_\B`)
  1849	
  1850	// run runs the command given by cmdline in the directory dir.
  1851	// If the command fails, run prints information about the failure
  1852	// and returns a non-nil error.
  1853	func (b *Builder) run(a *Action, dir string, desc string, env []string, cmdargs ...interface{}) error {
  1854		out, err := b.runOut(a, dir, env, cmdargs...)
  1855		if len(out) > 0 {
  1856			if desc == "" {
  1857				desc = b.fmtcmd(dir, "%s", strings.Join(str.StringList(cmdargs...), " "))
  1858			}
  1859			b.showOutput(a, dir, desc, b.processOutput(out))
  1860			if err != nil {
  1861				err = errPrintedOutput
  1862			}
  1863		}
  1864		return err
  1865	}
  1866	
  1867	// processOutput prepares the output of runOut to be output to the console.
  1868	func (b *Builder) processOutput(out []byte) string {
  1869		if out[len(out)-1] != '\n' {
  1870			out = append(out, '\n')
  1871		}
  1872		messages := string(out)
  1873		// Fix up output referring to cgo-generated code to be more readable.
  1874		// Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
  1875		// Replace *[100]_Ctype_foo with *[100]C.foo.
  1876		// If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
  1877		if !cfg.BuildX && cgoLine.MatchString(messages) {
  1878			messages = cgoLine.ReplaceAllString(messages, "")
  1879			messages = cgoTypeSigRe.ReplaceAllString(messages, "C.")
  1880		}
  1881		return messages
  1882	}
  1883	
  1884	// runOut runs the command given by cmdline in the directory dir.
  1885	// It returns the command output and any errors that occurred.
  1886	// It accumulates execution time in a.
  1887	func (b *Builder) runOut(a *Action, dir string, env []string, cmdargs ...interface{}) ([]byte, error) {
  1888		cmdline := str.StringList(cmdargs...)
  1889	
  1890		for _, arg := range cmdline {
  1891			// GNU binutils commands, including gcc and gccgo, interpret an argument
  1892			// @foo anywhere in the command line (even following --) as meaning
  1893			// "read and insert arguments from the file named foo."
  1894			// Don't say anything that might be misinterpreted that way.
  1895			if strings.HasPrefix(arg, "@") {
  1896				return nil, fmt.Errorf("invalid command-line argument %s in command: %s", arg, joinUnambiguously(cmdline))
  1897			}
  1898		}
  1899	
  1900		if cfg.BuildN || cfg.BuildX {
  1901			var envcmdline string
  1902			for _, e := range env {
  1903				if j := strings.IndexByte(e, '='); j != -1 {
  1904					if strings.ContainsRune(e[j+1:], '\'') {
  1905						envcmdline += fmt.Sprintf("%s=%q", e[:j], e[j+1:])
  1906					} else {
  1907						envcmdline += fmt.Sprintf("%s='%s'", e[:j], e[j+1:])
  1908					}
  1909					envcmdline += " "
  1910				}
  1911			}
  1912			envcmdline += joinUnambiguously(cmdline)
  1913			b.Showcmd(dir, "%s", envcmdline)
  1914			if cfg.BuildN {
  1915				return nil, nil
  1916			}
  1917		}
  1918	
  1919		var buf bytes.Buffer
  1920		cmd := exec.Command(cmdline[0], cmdline[1:]...)
  1921		cmd.Stdout = &buf
  1922		cmd.Stderr = &buf
  1923		cleanup := passLongArgsInResponseFiles(cmd)
  1924		defer cleanup()
  1925		cmd.Dir = dir
  1926		cmd.Env = base.EnvForDir(cmd.Dir, os.Environ())
  1927		cmd.Env = append(cmd.Env, env...)
  1928		start := time.Now()
  1929		err := cmd.Run()
  1930		if a != nil && a.json != nil {
  1931			aj := a.json
  1932			aj.Cmd = append(aj.Cmd, joinUnambiguously(cmdline))
  1933			aj.CmdReal += time.Since(start)
  1934			if ps := cmd.ProcessState; ps != nil {
  1935				aj.CmdUser += ps.UserTime()
  1936				aj.CmdSys += ps.SystemTime()
  1937			}
  1938		}
  1939	
  1940		// err can be something like 'exit status 1'.
  1941		// Add information about what program was running.
  1942		// Note that if buf.Bytes() is non-empty, the caller usually
  1943		// shows buf.Bytes() and does not print err at all, so the
  1944		// prefix here does not make most output any more verbose.
  1945		if err != nil {
  1946			err = errors.New(cmdline[0] + ": " + err.Error())
  1947		}
  1948		return buf.Bytes(), err
  1949	}
  1950	
  1951	// joinUnambiguously prints the slice, quoting where necessary to make the
  1952	// output unambiguous.
  1953	// TODO: See issue 5279. The printing of commands needs a complete redo.
  1954	func joinUnambiguously(a []string) string {
  1955		var buf bytes.Buffer
  1956		for i, s := range a {
  1957			if i > 0 {
  1958				buf.WriteByte(' ')
  1959			}
  1960			q := strconv.Quote(s)
  1961			// A gccgo command line can contain -( and -).
  1962			// Make sure we quote them since they are special to the shell.
  1963			// The trimpath argument can also contain > (part of =>) and ;. Quote those too.
  1964			if s == "" || strings.ContainsAny(s, " ()>;") || len(q) > len(s)+2 {
  1965				buf.WriteString(q)
  1966			} else {
  1967				buf.WriteString(s)
  1968			}
  1969		}
  1970		return buf.String()
  1971	}
  1972	
  1973	// cCompilerEnv returns environment variables to set when running the
  1974	// C compiler. This is needed to disable escape codes in clang error
  1975	// messages that confuse tools like cgo.
  1976	func (b *Builder) cCompilerEnv() []string {
  1977		return []string{"TERM=dumb"}
  1978	}
  1979	
  1980	// mkdir makes the named directory.
  1981	func (b *Builder) Mkdir(dir string) error {
  1982		// Make Mkdir(a.Objdir) a no-op instead of an error when a.Objdir == "".
  1983		if dir == "" {
  1984			return nil
  1985		}
  1986	
  1987		b.exec.Lock()
  1988		defer b.exec.Unlock()
  1989		// We can be a little aggressive about being
  1990		// sure directories exist. Skip repeated calls.
  1991		if b.mkdirCache[dir] {
  1992			return nil
  1993		}
  1994		b.mkdirCache[dir] = true
  1995	
  1996		if cfg.BuildN || cfg.BuildX {
  1997			b.Showcmd("", "mkdir -p %s", dir)
  1998			if cfg.BuildN {
  1999				return nil
  2000			}
  2001		}
  2002	
  2003		if err := os.MkdirAll(dir, 0777); err != nil {
  2004			return err
  2005		}
  2006		return nil
  2007	}
  2008	
  2009	// symlink creates a symlink newname -> oldname.
  2010	func (b *Builder) Symlink(oldname, newname string) error {
  2011		// It's not an error to try to recreate an existing symlink.
  2012		if link, err := os.Readlink(newname); err == nil && link == oldname {
  2013			return nil
  2014		}
  2015	
  2016		if cfg.BuildN || cfg.BuildX {
  2017			b.Showcmd("", "ln -s %s %s", oldname, newname)
  2018			if cfg.BuildN {
  2019				return nil
  2020			}
  2021		}
  2022		return os.Symlink(oldname, newname)
  2023	}
  2024	
  2025	// mkAbs returns an absolute path corresponding to
  2026	// evaluating f in the directory dir.
  2027	// We always pass absolute paths of source files so that
  2028	// the error messages will include the full path to a file
  2029	// in need of attention.
  2030	func mkAbs(dir, f string) string {
  2031		// Leave absolute paths alone.
  2032		// Also, during -n mode we use the pseudo-directory $WORK
  2033		// instead of creating an actual work directory that won't be used.
  2034		// Leave paths beginning with $WORK alone too.
  2035		if filepath.IsAbs(f) || strings.HasPrefix(f, "$WORK") {
  2036			return f
  2037		}
  2038		return filepath.Join(dir, f)
  2039	}
  2040	
  2041	type toolchain interface {
  2042		// gc runs the compiler in a specific directory on a set of files
  2043		// and returns the name of the generated output file.
  2044		//
  2045		// TODO: This argument list is long. Consider putting it in a struct.
  2046		gc(b *Builder, a *Action, archive string, importcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, out []byte, err error)
  2047		// cc runs the toolchain's C compiler in a directory on a C file
  2048		// to produce an output file.
  2049		cc(b *Builder, a *Action, ofile, cfile string) error
  2050		// asm runs the assembler in a specific directory on specific files
  2051		// and returns a list of named output files.
  2052		asm(b *Builder, a *Action, sfiles []string) ([]string, error)
  2053		// symabis scans the symbol ABIs from sfiles and returns the
  2054		// path to the output symbol ABIs file, or "" if none.
  2055		symabis(b *Builder, a *Action, sfiles []string) (string, error)
  2056		// pack runs the archive packer in a specific directory to create
  2057		// an archive from a set of object files.
  2058		// typically it is run in the object directory.
  2059		pack(b *Builder, a *Action, afile string, ofiles []string) error
  2060		// ld runs the linker to create an executable starting at mainpkg.
  2061		ld(b *Builder, root *Action, out, importcfg, mainpkg string) error
  2062		// ldShared runs the linker to create a shared library containing the pkgs built by toplevelactions
  2063		ldShared(b *Builder, root *Action, toplevelactions []*Action, out, importcfg string, allactions []*Action) error
  2064	
  2065		compiler() string
  2066		linker() string
  2067	}
  2068	
  2069	type noToolchain struct{}
  2070	
  2071	func noCompiler() error {
  2072		log.Fatalf("unknown compiler %q", cfg.BuildContext.Compiler)
  2073		return nil
  2074	}
  2075	
  2076	func (noToolchain) compiler() string {
  2077		noCompiler()
  2078		return ""
  2079	}
  2080	
  2081	func (noToolchain) linker() string {
  2082		noCompiler()
  2083		return ""
  2084	}
  2085	
  2086	func (noToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, out []byte, err error) {
  2087		return "", nil, noCompiler()
  2088	}
  2089	
  2090	func (noToolchain) asm(b *Builder, a *Action, sfiles []string) ([]string, error) {
  2091		return nil, noCompiler()
  2092	}
  2093	
  2094	func (noToolchain) symabis(b *Builder, a *Action, sfiles []string) (string, error) {
  2095		return "", noCompiler()
  2096	}
  2097	
  2098	func (noToolchain) pack(b *Builder, a *Action, afile string, ofiles []string) error {
  2099		return noCompiler()
  2100	}
  2101	
  2102	func (noToolchain) ld(b *Builder, root *Action, out, importcfg, mainpkg string) error {
  2103		return noCompiler()
  2104	}
  2105	
  2106	func (noToolchain) ldShared(b *Builder, root *Action, toplevelactions []*Action, out, importcfg string, allactions []*Action) error {
  2107		return noCompiler()
  2108	}
  2109	
  2110	func (noToolchain) cc(b *Builder, a *Action, ofile, cfile string) error {
  2111		return noCompiler()
  2112	}
  2113	
  2114	// gcc runs the gcc C compiler to create an object from a single C file.
  2115	func (b *Builder) gcc(a *Action, p *load.Package, workdir, out string, flags []string, cfile string) error {
  2116		return b.ccompile(a, p, out, flags, cfile, b.GccCmd(p.Dir, workdir))
  2117	}
  2118	
  2119	// gxx runs the g++ C++ compiler to create an object from a single C++ file.
  2120	func (b *Builder) gxx(a *Action, p *load.Package, workdir, out string, flags []string, cxxfile string) error {
  2121		return b.ccompile(a, p, out, flags, cxxfile, b.GxxCmd(p.Dir, workdir))
  2122	}
  2123	
  2124	// gfortran runs the gfortran Fortran compiler to create an object from a single Fortran file.
  2125	func (b *Builder) gfortran(a *Action, p *load.Package, workdir, out string, flags []string, ffile string) error {
  2126		return b.ccompile(a, p, out, flags, ffile, b.gfortranCmd(p.Dir, workdir))
  2127	}
  2128	
  2129	// ccompile runs the given C or C++ compiler and creates an object from a single source file.
  2130	func (b *Builder) ccompile(a *Action, p *load.Package, outfile string, flags []string, file string, compiler []string) error {
  2131		file = mkAbs(p.Dir, file)
  2132		desc := p.ImportPath
  2133		if !filepath.IsAbs(outfile) {
  2134			outfile = filepath.Join(p.Dir, outfile)
  2135		}
  2136		output, err := b.runOut(a, filepath.Dir(file), b.cCompilerEnv(), compiler, flags, "-o", outfile, "-c", filepath.Base(file))
  2137		if len(output) > 0 {
  2138			// On FreeBSD 11, when we pass -g to clang 3.8 it
  2139			// invokes its internal assembler with -dwarf-version=2.
  2140			// When it sees .section .note.GNU-stack, it warns
  2141			// "DWARF2 only supports one section per compilation unit".
  2142			// This warning makes no sense, since the section is empty,
  2143			// but it confuses people.
  2144			// We work around the problem by detecting the warning
  2145			// and dropping -g and trying again.
  2146			if bytes.Contains(output, []byte("DWARF2 only supports one section per compilation unit")) {
  2147				newFlags := make([]string, 0, len(flags))
  2148				for _, f := range flags {
  2149					if !strings.HasPrefix(f, "-g") {
  2150						newFlags = append(newFlags, f)
  2151					}
  2152				}
  2153				if len(newFlags) < len(flags) {
  2154					return b.ccompile(a, p, outfile, newFlags, file, compiler)
  2155				}
  2156			}
  2157	
  2158			b.showOutput(a, p.Dir, desc, b.processOutput(output))
  2159			if err != nil {
  2160				err = errPrintedOutput
  2161			} else if os.Getenv("GO_BUILDER_NAME") != "" {
  2162				return errors.New("C compiler warning promoted to error on Go builders")
  2163			}
  2164		}
  2165		return err
  2166	}
  2167	
  2168	// gccld runs the gcc linker to create an executable from a set of object files.
  2169	func (b *Builder) gccld(a *Action, p *load.Package, objdir, outfile string, flags []string, objs []string) error {
  2170		var cmd []string
  2171		if len(p.CXXFiles) > 0 || len(p.SwigCXXFiles) > 0 {
  2172			cmd = b.GxxCmd(p.Dir, objdir)
  2173		} else {
  2174			cmd = b.GccCmd(p.Dir, objdir)
  2175		}
  2176	
  2177		cmdargs := []interface{}{cmd, "-o", outfile, objs, flags}
  2178		dir := p.Dir
  2179		out, err := b.runOut(a, dir, b.cCompilerEnv(), cmdargs...)
  2180		if len(out) > 0 {
  2181			// Filter out useless linker warnings caused by bugs outside Go.
  2182			// See also cmd/link/internal/ld's hostlink method.
  2183			var save [][]byte
  2184			var skipLines int
  2185			for _, line := range bytes.SplitAfter(out, []byte("\n")) {
  2186				// golang.org/issue/26073 - Apple Xcode bug
  2187				if bytes.Contains(line, []byte("ld: warning: text-based stub file")) {
  2188					continue
  2189				}
  2190	
  2191				if skipLines > 0 {
  2192					skipLines--
  2193					continue
  2194				}
  2195	
  2196				// Remove duplicate main symbol with runtime/cgo on AIX.
  2197				// With runtime/cgo, two main are available:
  2198				// One is generated by cgo tool with {return 0;}.
  2199				// The other one is the main calling runtime.rt0_go
  2200				// in runtime/cgo.
  2201				// The second can't be used by cgo programs because
  2202				// runtime.rt0_go is unknown to them.
  2203				// Therefore, we let ld remove this main version
  2204				// and used the cgo generated one.
  2205				if p.ImportPath == "runtime/cgo" && bytes.Contains(line, []byte("ld: 0711-224 WARNING: Duplicate symbol: .main")) {
  2206					skipLines = 1
  2207					continue
  2208				}
  2209	
  2210				save = append(save, line)
  2211			}
  2212			out = bytes.Join(save, nil)
  2213			if len(out) > 0 {
  2214				b.showOutput(nil, dir, p.ImportPath, b.processOutput(out))
  2215				if err != nil {
  2216					err = errPrintedOutput
  2217				}
  2218			}
  2219		}
  2220		return err
  2221	}
  2222	
  2223	// Grab these before main helpfully overwrites them.
  2224	var (
  2225		origCC  = cfg.Getenv("CC")
  2226		origCXX = cfg.Getenv("CXX")
  2227	)
  2228	
  2229	// gccCmd returns a gcc command line prefix
  2230	// defaultCC is defined in zdefaultcc.go, written by cmd/dist.
  2231	func (b *Builder) GccCmd(incdir, workdir string) []string {
  2232		return b.compilerCmd(b.ccExe(), incdir, workdir)
  2233	}
  2234	
  2235	// gxxCmd returns a g++ command line prefix
  2236	// defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
  2237	func (b *Builder) GxxCmd(incdir, workdir string) []string {
  2238		return b.compilerCmd(b.cxxExe(), incdir, workdir)
  2239	}
  2240	
  2241	// gfortranCmd returns a gfortran command line prefix.
  2242	func (b *Builder) gfortranCmd(incdir, workdir string) []string {
  2243		return b.compilerCmd(b.fcExe(), incdir, workdir)
  2244	}
  2245	
  2246	// ccExe returns the CC compiler setting without all the extra flags we add implicitly.
  2247	func (b *Builder) ccExe() []string {
  2248		return b.compilerExe(origCC, cfg.DefaultCC(cfg.Goos, cfg.Goarch))
  2249	}
  2250	
  2251	// cxxExe returns the CXX compiler setting without all the extra flags we add implicitly.
  2252	func (b *Builder) cxxExe() []string {
  2253		return b.compilerExe(origCXX, cfg.DefaultCXX(cfg.Goos, cfg.Goarch))
  2254	}
  2255	
  2256	// fcExe returns the FC compiler setting without all the extra flags we add implicitly.
  2257	func (b *Builder) fcExe() []string {
  2258		return b.compilerExe(cfg.Getenv("FC"), "gfortran")
  2259	}
  2260	
  2261	// compilerExe returns the compiler to use given an
  2262	// environment variable setting (the value not the name)
  2263	// and a default. The resulting slice is usually just the name
  2264	// of the compiler but can have additional arguments if they
  2265	// were present in the environment value.
  2266	// For example if CC="gcc -DGOPHER" then the result is ["gcc", "-DGOPHER"].
  2267	func (b *Builder) compilerExe(envValue string, def string) []string {
  2268		compiler := strings.Fields(envValue)
  2269		if len(compiler) == 0 {
  2270			compiler = []string{def}
  2271		}
  2272		return compiler
  2273	}
  2274	
  2275	// compilerCmd returns a command line prefix for the given environment
  2276	// variable and using the default command when the variable is empty.
  2277	func (b *Builder) compilerCmd(compiler []string, incdir, workdir string) []string {
  2278		// NOTE: env.go's mkEnv knows that the first three
  2279		// strings returned are "gcc", "-I", incdir (and cuts them off).
  2280		a := []string{compiler[0], "-I", incdir}
  2281		a = append(a, compiler[1:]...)
  2282	
  2283		// Definitely want -fPIC but on Windows gcc complains
  2284		// "-fPIC ignored for target (all code is position independent)"
  2285		if cfg.Goos != "windows" {
  2286			a = append(a, "-fPIC")
  2287		}
  2288		a = append(a, b.gccArchArgs()...)
  2289		// gcc-4.5 and beyond require explicit "-pthread" flag
  2290		// for multithreading with pthread library.
  2291		if cfg.BuildContext.CgoEnabled {
  2292			switch cfg.Goos {
  2293			case "windows":
  2294				a = append(a, "-mthreads")
  2295			default:
  2296				a = append(a, "-pthread")
  2297			}
  2298		}
  2299	
  2300		if cfg.Goos == "aix" {
  2301			// mcmodel=large must always be enabled to allow large TOC.
  2302			a = append(a, "-mcmodel=large")
  2303		}
  2304	
  2305		// disable ASCII art in clang errors, if possible
  2306		if b.gccSupportsFlag(compiler, "-fno-caret-diagnostics") {
  2307			a = append(a, "-fno-caret-diagnostics")
  2308		}
  2309		// clang is too smart about command-line arguments
  2310		if b.gccSupportsFlag(compiler, "-Qunused-arguments") {
  2311			a = append(a, "-Qunused-arguments")
  2312		}
  2313	
  2314		// disable word wrapping in error messages
  2315		a = append(a, "-fmessage-length=0")
  2316	
  2317		// Tell gcc not to include the work directory in object files.
  2318		if b.gccSupportsFlag(compiler, "-fdebug-prefix-map=a=b") {
  2319			if workdir == "" {
  2320				workdir = b.WorkDir
  2321			}
  2322			workdir = strings.TrimSuffix(workdir, string(filepath.Separator))
  2323			a = append(a, "-fdebug-prefix-map="+workdir+"=/tmp/go-build")
  2324		}
  2325	
  2326		// Tell gcc not to include flags in object files, which defeats the
  2327		// point of -fdebug-prefix-map above.
  2328		if b.gccSupportsFlag(compiler, "-gno-record-gcc-switches") {
  2329			a = append(a, "-gno-record-gcc-switches")
  2330		}
  2331	
  2332		// On OS X, some of the compilers behave as if -fno-common
  2333		// is always set, and the Mach-O linker in 6l/8l assumes this.
  2334		// See https://golang.org/issue/3253.
  2335		if cfg.Goos == "darwin" {
  2336			a = append(a, "-fno-common")
  2337		}
  2338	
  2339		return a
  2340	}
  2341	
  2342	// gccNoPie returns the flag to use to request non-PIE. On systems
  2343	// with PIE (position independent executables) enabled by default,
  2344	// -no-pie must be passed when doing a partial link with -Wl,-r.
  2345	// But -no-pie is not supported by all compilers, and clang spells it -nopie.
  2346	func (b *Builder) gccNoPie(linker []string) string {
  2347		if b.gccSupportsFlag(linker, "-no-pie") {
  2348			return "-no-pie"
  2349		}
  2350		if b.gccSupportsFlag(linker, "-nopie") {
  2351			return "-nopie"
  2352		}
  2353		return ""
  2354	}
  2355	
  2356	// gccSupportsFlag checks to see if the compiler supports a flag.
  2357	func (b *Builder) gccSupportsFlag(compiler []string, flag string) bool {
  2358		key := [2]string{compiler[0], flag}
  2359	
  2360		b.exec.Lock()
  2361		defer b.exec.Unlock()
  2362		if b, ok := b.flagCache[key]; ok {
  2363			return b
  2364		}
  2365		if b.flagCache == nil {
  2366			b.flagCache = make(map[[2]string]bool)
  2367		}
  2368		// We used to write an empty C file, but that gets complicated with
  2369		// go build -n. We tried using a file that does not exist, but that
  2370		// fails on systems with GCC version 4.2.1; that is the last GPLv2
  2371		// version of GCC, so some systems have frozen on it.
  2372		// Now we pass an empty file on stdin, which should work at least for
  2373		// GCC and clang.
  2374		cmdArgs := str.StringList(compiler, flag, "-c", "-x", "c", "-", "-o", os.DevNull)
  2375		if cfg.BuildN || cfg.BuildX {
  2376			b.Showcmd(b.WorkDir, "%s || true", joinUnambiguously(cmdArgs))
  2377			if cfg.BuildN {
  2378				return false
  2379			}
  2380		}
  2381		cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
  2382		cmd.Dir = b.WorkDir
  2383		cmd.Env = base.EnvForDir(cmd.Dir, os.Environ())
  2384		cmd.Env = append(cmd.Env, "LC_ALL=C")
  2385		out, _ := cmd.CombinedOutput()
  2386		// GCC says "unrecognized command line option".
  2387		// clang says "unknown argument".
  2388		// Older versions of GCC say "unrecognised debug output level".
  2389		// For -fsplit-stack GCC says "'-fsplit-stack' is not supported".
  2390		supported := !bytes.Contains(out, []byte("unrecognized")) &&
  2391			!bytes.Contains(out, []byte("unknown")) &&
  2392			!bytes.Contains(out, []byte("unrecognised")) &&
  2393			!bytes.Contains(out, []byte("is not supported"))
  2394		b.flagCache[key] = supported
  2395		return supported
  2396	}
  2397	
  2398	// gccArchArgs returns arguments to pass to gcc based on the architecture.
  2399	func (b *Builder) gccArchArgs() []string {
  2400		switch cfg.Goarch {
  2401		case "386":
  2402			return []string{"-m32"}
  2403		case "amd64", "amd64p32":
  2404			return []string{"-m64"}
  2405		case "arm":
  2406			return []string{"-marm"} // not thumb
  2407		case "s390x":
  2408			return []string{"-m64", "-march=z196"}
  2409		case "mips64", "mips64le":
  2410			return []string{"-mabi=64"}
  2411		case "mips", "mipsle":
  2412			return []string{"-mabi=32", "-march=mips32"}
  2413		case "ppc64":
  2414			if cfg.Goos == "aix" {
  2415				return []string{"-maix64"}
  2416			}
  2417		}
  2418		return nil
  2419	}
  2420	
  2421	// envList returns the value of the given environment variable broken
  2422	// into fields, using the default value when the variable is empty.
  2423	func envList(key, def string) []string {
  2424		v := cfg.Getenv(key)
  2425		if v == "" {
  2426			v = def
  2427		}
  2428		return strings.Fields(v)
  2429	}
  2430	
  2431	// CFlags returns the flags to use when invoking the C, C++ or Fortran compilers, or cgo.
  2432	func (b *Builder) CFlags(p *load.Package) (cppflags, cflags, cxxflags, fflags, ldflags []string, err error) {
  2433		defaults := "-g -O2"
  2434	
  2435		if cppflags, err = buildFlags("CPPFLAGS", "", p.CgoCPPFLAGS, checkCompilerFlags); err != nil {
  2436			return
  2437		}
  2438		if cflags, err = buildFlags("CFLAGS", defaults, p.CgoCFLAGS, checkCompilerFlags); err != nil {
  2439			return
  2440		}
  2441		if cxxflags, err = buildFlags("CXXFLAGS", defaults, p.CgoCXXFLAGS, checkCompilerFlags); err != nil {
  2442			return
  2443		}
  2444		if fflags, err = buildFlags("FFLAGS", defaults, p.CgoFFLAGS, checkCompilerFlags); err != nil {
  2445			return
  2446		}
  2447		if ldflags, err = buildFlags("LDFLAGS", defaults, p.CgoLDFLAGS, checkLinkerFlags); err != nil {
  2448			return
  2449		}
  2450	
  2451		return
  2452	}
  2453	
  2454	func buildFlags(name, defaults string, fromPackage []string, check func(string, string, []string) error) ([]string, error) {
  2455		if err := check(name, "#cgo "+name, fromPackage); err != nil {
  2456			return nil, err
  2457		}
  2458		return str.StringList(envList("CGO_"+name, defaults), fromPackage), nil
  2459	}
  2460	
  2461	var cgoRe = lazyregexp.New(`[/\\:]`)
  2462	
  2463	func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgofiles, gccfiles, gxxfiles, mfiles, ffiles []string) (outGo, outObj []string, err error) {
  2464		p := a.Package
  2465		cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoFFLAGS, cgoLDFLAGS, err := b.CFlags(p)
  2466		if err != nil {
  2467			return nil, nil, err
  2468		}
  2469	
  2470		cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...)
  2471		cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...)
  2472		// If we are compiling Objective-C code, then we need to link against libobjc
  2473		if len(mfiles) > 0 {
  2474			cgoLDFLAGS = append(cgoLDFLAGS, "-lobjc")
  2475		}
  2476	
  2477		// Likewise for Fortran, except there are many Fortran compilers.
  2478		// Support gfortran out of the box and let others pass the correct link options
  2479		// via CGO_LDFLAGS
  2480		if len(ffiles) > 0 {
  2481			fc := cfg.Getenv("FC")
  2482			if fc == "" {
  2483				fc = "gfortran"
  2484			}
  2485			if strings.Contains(fc, "gfortran") {
  2486				cgoLDFLAGS = append(cgoLDFLAGS, "-lgfortran")
  2487			}
  2488		}
  2489	
  2490		if cfg.BuildMSan {
  2491			cgoCFLAGS = append([]string{"-fsanitize=memory"}, cgoCFLAGS...)
  2492			cgoLDFLAGS = append([]string{"-fsanitize=memory"}, cgoLDFLAGS...)
  2493		}
  2494	
  2495		// Allows including _cgo_export.h from .[ch] files in the package.
  2496		cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", objdir)
  2497	
  2498		// cgo
  2499		// TODO: CGO_FLAGS?
  2500		gofiles := []string{objdir + "_cgo_gotypes.go"}
  2501		cfiles := []string{"_cgo_export.c"}
  2502		for _, fn := range cgofiles {
  2503			f := strings.TrimSuffix(filepath.Base(fn), ".go")
  2504			gofiles = append(gofiles, objdir+f+".cgo1.go")
  2505			cfiles = append(cfiles, f+".cgo2.c")
  2506		}
  2507	
  2508		// TODO: make cgo not depend on $GOARCH?
  2509	
  2510		cgoflags := []string{}
  2511		if p.Standard && p.ImportPath == "runtime/cgo" {
  2512			cgoflags = append(cgoflags, "-import_runtime_cgo=false")
  2513		}
  2514		if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/msan" || p.ImportPath == "runtime/cgo") {
  2515			cgoflags = append(cgoflags, "-import_syscall=false")
  2516		}
  2517	
  2518		// Update $CGO_LDFLAGS with p.CgoLDFLAGS.
  2519		// These flags are recorded in the generated _cgo_gotypes.go file
  2520		// using //go:cgo_ldflag directives, the compiler records them in the
  2521		// object file for the package, and then the Go linker passes them
  2522		// along to the host linker. At this point in the code, cgoLDFLAGS
  2523		// consists of the original $CGO_LDFLAGS (unchecked) and all the
  2524		// flags put together from source code (checked).
  2525		cgoenv := b.cCompilerEnv()
  2526		if len(cgoLDFLAGS) > 0 {
  2527			flags := make([]string, len(cgoLDFLAGS))
  2528			for i, f := range cgoLDFLAGS {
  2529				flags[i] = strconv.Quote(f)
  2530			}
  2531			cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
  2532		}
  2533	
  2534		if cfg.BuildToolchainName == "gccgo" {
  2535			if b.gccSupportsFlag([]string{BuildToolchain.compiler()}, "-fsplit-stack") {
  2536				cgoCFLAGS = append(cgoCFLAGS, "-fsplit-stack")
  2537			}
  2538			cgoflags = append(cgoflags, "-gccgo")
  2539			if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  2540				cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
  2541			}
  2542		}
  2543	
  2544		switch cfg.BuildBuildmode {
  2545		case "c-archive", "c-shared":
  2546			// Tell cgo that if there are any exported functions
  2547			// it should generate a header file that C code can
  2548			// #include.
  2549			cgoflags = append(cgoflags, "-exportheader="+objdir+"_cgo_install.h")
  2550		}
  2551	
  2552		if err := b.run(a, p.Dir, p.ImportPath, cgoenv, cfg.BuildToolexec, cgoExe, "-objdir", objdir, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, cgofiles); err != nil {
  2553			return nil, nil, err
  2554		}
  2555		outGo = append(outGo, gofiles...)
  2556	
  2557		// Use sequential object file names to keep them distinct
  2558		// and short enough to fit in the .a header file name slots.
  2559		// We no longer collect them all into _all.o, and we'd like
  2560		// tools to see both the .o suffix and unique names, so
  2561		// we need to make them short enough not to be truncated
  2562		// in the final archive.
  2563		oseq := 0
  2564		nextOfile := func() string {
  2565			oseq++
  2566			return objdir + fmt.Sprintf("_x%03d.o", oseq)
  2567		}
  2568	
  2569		// gcc
  2570		cflags := str.StringList(cgoCPPFLAGS, cgoCFLAGS)
  2571		for _, cfile := range cfiles {
  2572			ofile := nextOfile()
  2573			if err := b.gcc(a, p, a.Objdir, ofile, cflags, objdir+cfile); err != nil {
  2574				return nil, nil, err
  2575			}
  2576			outObj = append(outObj, ofile)
  2577		}
  2578	
  2579		for _, file := range gccfiles {
  2580			ofile := nextOfile()
  2581			if err := b.gcc(a, p, a.Objdir, ofile, cflags, file); err != nil {
  2582				return nil, nil, err
  2583			}
  2584			outObj = append(outObj, ofile)
  2585		}
  2586	
  2587		cxxflags := str.StringList(cgoCPPFLAGS, cgoCXXFLAGS)
  2588		for _, file := range gxxfiles {
  2589			ofile := nextOfile()
  2590			if err := b.gxx(a, p, a.Objdir, ofile, cxxflags, file); err != nil {
  2591				return nil, nil, err
  2592			}
  2593			outObj = append(outObj, ofile)
  2594		}
  2595	
  2596		for _, file := range mfiles {
  2597			ofile := nextOfile()
  2598			if err := b.gcc(a, p, a.Objdir, ofile, cflags, file); err != nil {
  2599				return nil, nil, err
  2600			}
  2601			outObj = append(outObj, ofile)
  2602		}
  2603	
  2604		fflags := str.StringList(cgoCPPFLAGS, cgoFFLAGS)
  2605		for _, file := range ffiles {
  2606			ofile := nextOfile()
  2607			if err := b.gfortran(a, p, a.Objdir, ofile, fflags, file); err != nil {
  2608				return nil, nil, err
  2609			}
  2610			outObj = append(outObj, ofile)
  2611		}
  2612	
  2613		switch cfg.BuildToolchainName {
  2614		case "gc":
  2615			importGo := objdir + "_cgo_import.go"
  2616			if err := b.dynimport(a, p, objdir, importGo, cgoExe, cflags, cgoLDFLAGS, outObj); err != nil {
  2617				return nil, nil, err
  2618			}
  2619			outGo = append(outGo, importGo)
  2620	
  2621		case "gccgo":
  2622			defunC := objdir + "_cgo_defun.c"
  2623			defunObj := objdir + "_cgo_defun.o"
  2624			if err := BuildToolchain.cc(b, a, defunObj, defunC); err != nil {
  2625				return nil, nil, err
  2626			}
  2627			outObj = append(outObj, defunObj)
  2628	
  2629		default:
  2630			noCompiler()
  2631		}
  2632	
  2633		return outGo, outObj, nil
  2634	}
  2635	
  2636	// dynimport creates a Go source file named importGo containing
  2637	// //go:cgo_import_dynamic directives for each symbol or library
  2638	// dynamically imported by the object files outObj.
  2639	func (b *Builder) dynimport(a *Action, p *load.Package, objdir, importGo, cgoExe string, cflags, cgoLDFLAGS, outObj []string) error {
  2640		cfile := objdir + "_cgo_main.c"
  2641		ofile := objdir + "_cgo_main.o"
  2642		if err := b.gcc(a, p, objdir, ofile, cflags, cfile); err != nil {
  2643			return err
  2644		}
  2645	
  2646		linkobj := str.StringList(ofile, outObj, p.SysoFiles)
  2647		dynobj := objdir + "_cgo_.o"
  2648	
  2649		// we need to use -pie for Linux/ARM to get accurate imported sym
  2650		ldflags := cgoLDFLAGS
  2651		if (cfg.Goarch == "arm" && cfg.Goos == "linux") || cfg.Goos == "android" {
  2652			// -static -pie doesn't make sense, and causes link errors.
  2653			// Issue 26197.
  2654			n := make([]string, 0, len(ldflags))
  2655			for _, flag := range ldflags {
  2656				if flag != "-static" {
  2657					n = append(n, flag)
  2658				}
  2659			}
  2660			ldflags = append(n, "-pie")
  2661		}
  2662		if err := b.gccld(a, p, objdir, dynobj, ldflags, linkobj); err != nil {
  2663			return err
  2664		}
  2665	
  2666		// cgo -dynimport
  2667		var cgoflags []string
  2668		if p.Standard && p.ImportPath == "runtime/cgo" {
  2669			cgoflags = []string{"-dynlinker"} // record path to dynamic linker
  2670		}
  2671		return b.run(a, p.Dir, p.ImportPath, b.cCompilerEnv(), cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags)
  2672	}
  2673	
  2674	// Run SWIG on all SWIG input files.
  2675	// TODO: Don't build a shared library, once SWIG emits the necessary
  2676	// pragmas for external linking.
  2677	func (b *Builder) swig(a *Action, p *load.Package, objdir string, pcCFLAGS []string) (outGo, outC, outCXX []string, err error) {
  2678		if err := b.swigVersionCheck(); err != nil {
  2679			return nil, nil, nil, err
  2680		}
  2681	
  2682		intgosize, err := b.swigIntSize(objdir)
  2683		if err != nil {
  2684			return nil, nil, nil, err
  2685		}
  2686	
  2687		for _, f := range p.SwigFiles {
  2688			goFile, cFile, err := b.swigOne(a, p, f, objdir, pcCFLAGS, false, intgosize)
  2689			if err != nil {
  2690				return nil, nil, nil, err
  2691			}
  2692			if goFile != "" {
  2693				outGo = append(outGo, goFile)
  2694			}
  2695			if cFile != "" {
  2696				outC = append(outC, cFile)
  2697			}
  2698		}
  2699		for _, f := range p.SwigCXXFiles {
  2700			goFile, cxxFile, err := b.swigOne(a, p, f, objdir, pcCFLAGS, true, intgosize)
  2701			if err != nil {
  2702				return nil, nil, nil, err
  2703			}
  2704			if goFile != "" {
  2705				outGo = append(outGo, goFile)
  2706			}
  2707			if cxxFile != "" {
  2708				outCXX = append(outCXX, cxxFile)
  2709			}
  2710		}
  2711		return outGo, outC, outCXX, nil
  2712	}
  2713	
  2714	// Make sure SWIG is new enough.
  2715	var (
  2716		swigCheckOnce sync.Once
  2717		swigCheck     error
  2718	)
  2719	
  2720	func (b *Builder) swigDoVersionCheck() error {
  2721		out, err := b.runOut(nil, "", nil, "swig", "-version")
  2722		if err != nil {
  2723			return err
  2724		}
  2725		re := regexp.MustCompile(`[vV]ersion +([\d]+)([.][\d]+)?([.][\d]+)?`)
  2726		matches := re.FindSubmatch(out)
  2727		if matches == nil {
  2728			// Can't find version number; hope for the best.
  2729			return nil
  2730		}
  2731	
  2732		major, err := strconv.Atoi(string(matches[1]))
  2733		if err != nil {
  2734			// Can't find version number; hope for the best.
  2735			return nil
  2736		}
  2737		const errmsg = "must have SWIG version >= 3.0.6"
  2738		if major < 3 {
  2739			return errors.New(errmsg)
  2740		}
  2741		if major > 3 {
  2742			// 4.0 or later
  2743			return nil
  2744		}
  2745	
  2746		// We have SWIG version 3.x.
  2747		if len(matches[2]) > 0 {
  2748			minor, err := strconv.Atoi(string(matches[2][1:]))
  2749			if err != nil {
  2750				return nil
  2751			}
  2752			if minor > 0 {
  2753				// 3.1 or later
  2754				return nil
  2755			}
  2756		}
  2757	
  2758		// We have SWIG version 3.0.x.
  2759		if len(matches[3]) > 0 {
  2760			patch, err := strconv.Atoi(string(matches[3][1:]))
  2761			if err != nil {
  2762				return nil
  2763			}
  2764			if patch < 6 {
  2765				// Before 3.0.6.
  2766				return errors.New(errmsg)
  2767			}
  2768		}
  2769	
  2770		return nil
  2771	}
  2772	
  2773	func (b *Builder) swigVersionCheck() error {
  2774		swigCheckOnce.Do(func() {
  2775			swigCheck = b.swigDoVersionCheck()
  2776		})
  2777		return swigCheck
  2778	}
  2779	
  2780	// Find the value to pass for the -intgosize option to swig.
  2781	var (
  2782		swigIntSizeOnce  sync.Once
  2783		swigIntSize      string
  2784		swigIntSizeError error
  2785	)
  2786	
  2787	// This code fails to build if sizeof(int) <= 32
  2788	const swigIntSizeCode = `
  2789	package main
  2790	const i int = 1 << 32
  2791	`
  2792	
  2793	// Determine the size of int on the target system for the -intgosize option
  2794	// of swig >= 2.0.9. Run only once.
  2795	func (b *Builder) swigDoIntSize(objdir string) (intsize string, err error) {
  2796		if cfg.BuildN {
  2797			return "$INTBITS", nil
  2798		}
  2799		src := filepath.Join(b.WorkDir, "swig_intsize.go")
  2800		if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0666); err != nil {
  2801			return
  2802		}
  2803		srcs := []string{src}
  2804	
  2805		p := load.GoFilesPackage(srcs)
  2806	
  2807		if _, _, e := BuildToolchain.gc(b, &Action{Mode: "swigDoIntSize", Package: p, Objdir: objdir}, "", nil, "", false, srcs); e != nil {
  2808			return "32", nil
  2809		}
  2810		return "64", nil
  2811	}
  2812	
  2813	// Determine the size of int on the target system for the -intgosize option
  2814	// of swig >= 2.0.9.
  2815	func (b *Builder) swigIntSize(objdir string) (intsize string, err error) {
  2816		swigIntSizeOnce.Do(func() {
  2817			swigIntSize, swigIntSizeError = b.swigDoIntSize(objdir)
  2818		})
  2819		return swigIntSize, swigIntSizeError
  2820	}
  2821	
  2822	// Run SWIG on one SWIG input file.
  2823	func (b *Builder) swigOne(a *Action, p *load.Package, file, objdir string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outC string, err error) {
  2824		cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _, _, err := b.CFlags(p)
  2825		if err != nil {
  2826			return "", "", err
  2827		}
  2828	
  2829		var cflags []string
  2830		if cxx {
  2831			cflags = str.StringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS)
  2832		} else {
  2833			cflags = str.StringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS)
  2834		}
  2835	
  2836		n := 5 // length of ".swig"
  2837		if cxx {
  2838			n = 8 // length of ".swigcxx"
  2839		}
  2840		base := file[:len(file)-n]
  2841		goFile := base + ".go"
  2842		gccBase := base + "_wrap."
  2843		gccExt := "c"
  2844		if cxx {
  2845			gccExt = "cxx"
  2846		}
  2847	
  2848		gccgo := cfg.BuildToolchainName == "gccgo"
  2849	
  2850		// swig
  2851		args := []string{
  2852			"-go",
  2853			"-cgo",
  2854			"-intgosize", intgosize,
  2855			"-module", base,
  2856			"-o", objdir + gccBase + gccExt,
  2857			"-outdir", objdir,
  2858		}
  2859	
  2860		for _, f := range cflags {
  2861			if len(f) > 3 && f[:2] == "-I" {
  2862				args = append(args, f)
  2863			}
  2864		}
  2865	
  2866		if gccgo {
  2867			args = append(args, "-gccgo")
  2868			if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  2869				args = append(args, "-go-pkgpath", pkgpath)
  2870			}
  2871		}
  2872		if cxx {
  2873			args = append(args, "-c++")
  2874		}
  2875	
  2876		out, err := b.runOut(a, p.Dir, nil, "swig", args, file)
  2877		if err != nil {
  2878			if len(out) > 0 {
  2879				if bytes.Contains(out, []byte("-intgosize")) || bytes.Contains(out, []byte("-cgo")) {
  2880					return "", "", errors.New("must have SWIG version >= 3.0.6")
  2881				}
  2882				b.showOutput(a, p.Dir, p.Desc(), b.processOutput(out)) // swig error
  2883				return "", "", errPrintedOutput
  2884			}
  2885			return "", "", err
  2886		}
  2887		if len(out) > 0 {
  2888			b.showOutput(a, p.Dir, p.Desc(), b.processOutput(out)) // swig warning
  2889		}
  2890	
  2891		// If the input was x.swig, the output is x.go in the objdir.
  2892		// But there might be an x.go in the original dir too, and if it
  2893		// uses cgo as well, cgo will be processing both and will
  2894		// translate both into x.cgo1.go in the objdir, overwriting one.
  2895		// Rename x.go to _x_swig.go to avoid this problem.
  2896		// We ignore files in the original dir that begin with underscore
  2897		// so _x_swig.go cannot conflict with an original file we were
  2898		// going to compile.
  2899		goFile = objdir + goFile
  2900		newGoFile := objdir + "_" + base + "_swig.go"
  2901		if err := os.Rename(goFile, newGoFile); err != nil {
  2902			return "", "", err
  2903		}
  2904		return newGoFile, objdir + gccBase + gccExt, nil
  2905	}
  2906	
  2907	// disableBuildID adjusts a linker command line to avoid creating a
  2908	// build ID when creating an object file rather than an executable or
  2909	// shared library. Some systems, such as Ubuntu, always add
  2910	// --build-id to every link, but we don't want a build ID when we are
  2911	// producing an object file. On some of those system a plain -r (not
  2912	// -Wl,-r) will turn off --build-id, but clang 3.0 doesn't support a
  2913	// plain -r. I don't know how to turn off --build-id when using clang
  2914	// other than passing a trailing --build-id=none. So that is what we
  2915	// do, but only on systems likely to support it, which is to say,
  2916	// systems that normally use gold or the GNU linker.
  2917	func (b *Builder) disableBuildID(ldflags []string) []string {
  2918		switch cfg.Goos {
  2919		case "android", "dragonfly", "linux", "netbsd":
  2920			ldflags = append(ldflags, "-Wl,--build-id=none")
  2921		}
  2922		return ldflags
  2923	}
  2924	
  2925	// mkAbsFiles converts files into a list of absolute files,
  2926	// assuming they were originally relative to dir,
  2927	// and returns that new list.
  2928	func mkAbsFiles(dir string, files []string) []string {
  2929		abs := make([]string, len(files))
  2930		for i, f := range files {
  2931			if !filepath.IsAbs(f) {
  2932				f = filepath.Join(dir, f)
  2933			}
  2934			abs[i] = f
  2935		}
  2936		return abs
  2937	}
  2938	
  2939	// passLongArgsInResponseFiles modifies cmd on Windows such that, for
  2940	// certain programs, long arguments are passed in "response files", a
  2941	// file on disk with the arguments, with one arg per line. An actual
  2942	// argument starting with '@' means that the rest of the argument is
  2943	// a filename of arguments to expand.
  2944	//
  2945	// See Issue 18468.
  2946	func passLongArgsInResponseFiles(cmd *exec.Cmd) (cleanup func()) {
  2947		cleanup = func() {} // no cleanup by default
  2948	
  2949		var argLen int
  2950		for _, arg := range cmd.Args {
  2951			argLen += len(arg)
  2952		}
  2953	
  2954		// If we're not approaching 32KB of args, just pass args normally.
  2955		// (use 30KB instead to be conservative; not sure how accounting is done)
  2956		if !useResponseFile(cmd.Path, argLen) {
  2957			return
  2958		}
  2959	
  2960		tf, err := ioutil.TempFile("", "args")
  2961		if err != nil {
  2962			log.Fatalf("error writing long arguments to response file: %v", err)
  2963		}
  2964		cleanup = func() { os.Remove(tf.Name()) }
  2965		var buf bytes.Buffer
  2966		for _, arg := range cmd.Args[1:] {
  2967			fmt.Fprintf(&buf, "%s\n", arg)
  2968		}
  2969		if _, err := tf.Write(buf.Bytes()); err != nil {
  2970			tf.Close()
  2971			cleanup()
  2972			log.Fatalf("error writing long arguments to response file: %v", err)
  2973		}
  2974		if err := tf.Close(); err != nil {
  2975			cleanup()
  2976			log.Fatalf("error writing long arguments to response file: %v", err)
  2977		}
  2978		cmd.Args = []string{cmd.Args[0], "@" + tf.Name()}
  2979		return cleanup
  2980	}
  2981	
  2982	func useResponseFile(path string, argLen int) bool {
  2983		// Unless we're on Windows, don't use response files.
  2984		if runtime.GOOS != "windows" {
  2985			return false
  2986		}
  2987	
  2988		// Unless the program uses objabi.Flagparse, which understands
  2989		// response files, don't use response files.
  2990		// TODO: do we need more commands? asm? cgo? For now, no.
  2991		prog := strings.TrimSuffix(filepath.Base(path), ".exe")
  2992		switch prog {
  2993		case "compile", "link":
  2994		default:
  2995			return false
  2996		}
  2997	
  2998		// Windows has a limit of 32 KB arguments. To be conservative and not
  2999		// worry about whether that includes spaces or not, just use 30 KB.
  3000		if argLen > (30 << 10) {
  3001			return true
  3002		}
  3003	
  3004		// On the Go build system, use response files about 10% of the
  3005		// time, just to exercise this codepath.
  3006		isBuilder := os.Getenv("GO_BUILDER_NAME") != ""
  3007		if isBuilder && rand.Intn(10) == 0 {
  3008			return true
  3009		}
  3010	
  3011		return false
  3012	}
  3013	

View as plain text