1  
     2  
     3  
     4  
     5  package work
     6  
     7  import (
     8  	"bufio"
     9  	"bytes"
    10  	"fmt"
    11  	"internal/platform"
    12  	"io"
    13  	"log"
    14  	"os"
    15  	"path/filepath"
    16  	"runtime"
    17  	"strings"
    18  
    19  	"cmd/go/internal/base"
    20  	"cmd/go/internal/cfg"
    21  	"cmd/go/internal/fsys"
    22  	"cmd/go/internal/gover"
    23  	"cmd/go/internal/load"
    24  	"cmd/go/internal/str"
    25  	"cmd/internal/quoted"
    26  	"crypto/sha1"
    27  )
    28  
    29  
    30  var ToolchainVersion = runtime.Version()
    31  
    32  
    33  const trimPathGoRootFinal string = "$GOROOT"
    34  
    35  
    36  
    37  type gcToolchain struct{}
    38  
    39  func (gcToolchain) compiler() string {
    40  	return base.Tool("compile")
    41  }
    42  
    43  func (gcToolchain) linker() string {
    44  	return base.Tool("link")
    45  }
    46  
    47  func pkgPath(a *Action) string {
    48  	p := a.Package
    49  	ppath := p.ImportPath
    50  	if cfg.BuildBuildmode == "plugin" {
    51  		ppath = pluginPath(a)
    52  	} else if p.Name == "main" && !p.Internal.ForceLibrary {
    53  		ppath = "main"
    54  	}
    55  	return ppath
    56  }
    57  
    58  func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg, embedcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, output []byte, err error) {
    59  	p := a.Package
    60  	sh := b.Shell(a)
    61  	objdir := a.Objdir
    62  	if archive != "" {
    63  		ofile = archive
    64  	} else {
    65  		out := "_go_.o"
    66  		ofile = objdir + out
    67  	}
    68  
    69  	pkgpath := pkgPath(a)
    70  	defaultGcFlags := []string{"-p", pkgpath}
    71  	if p.Module != nil {
    72  		v := p.Module.GoVersion
    73  		if v == "" {
    74  			v = gover.DefaultGoModVersion
    75  		}
    76  		if allowedVersion(v) {
    77  			defaultGcFlags = append(defaultGcFlags, "-lang=go"+gover.Lang(v))
    78  		}
    79  	}
    80  	if p.Standard {
    81  		defaultGcFlags = append(defaultGcFlags, "-std")
    82  	}
    83  
    84  	
    85  	
    86  	
    87  	
    88  	extFiles := len(p.CgoFiles) + len(p.CFiles) + len(p.CXXFiles) + len(p.MFiles) + len(p.FFiles) + len(p.SFiles) + len(p.SysoFiles) + len(p.SwigFiles) + len(p.SwigCXXFiles)
    89  	if p.Standard {
    90  		switch p.ImportPath {
    91  		case "bytes", "internal/poll", "net", "os":
    92  			fallthrough
    93  		case "runtime/metrics", "runtime/pprof", "runtime/trace":
    94  			fallthrough
    95  		case "sync", "syscall", "time":
    96  			extFiles++
    97  		}
    98  	}
    99  	if extFiles == 0 {
   100  		defaultGcFlags = append(defaultGcFlags, "-complete")
   101  	}
   102  	if cfg.BuildContext.InstallSuffix != "" {
   103  		defaultGcFlags = append(defaultGcFlags, "-installsuffix", cfg.BuildContext.InstallSuffix)
   104  	}
   105  	if a.buildID != "" {
   106  		defaultGcFlags = append(defaultGcFlags, "-buildid", a.buildID)
   107  	}
   108  	if p.Internal.OmitDebug || cfg.Goos == "plan9" || cfg.Goarch == "wasm" {
   109  		defaultGcFlags = append(defaultGcFlags, "-dwarf=false")
   110  	}
   111  	if strings.HasPrefix(ToolchainVersion, "go1") && !strings.Contains(os.Args[0], "go_bootstrap") {
   112  		defaultGcFlags = append(defaultGcFlags, "-goversion", ToolchainVersion)
   113  	}
   114  	if p.Internal.Cover.Cfg != "" {
   115  		defaultGcFlags = append(defaultGcFlags, "-coveragecfg="+p.Internal.Cover.Cfg)
   116  	}
   117  	if p.Internal.PGOProfile != "" {
   118  		defaultGcFlags = append(defaultGcFlags, "-pgoprofile="+p.Internal.PGOProfile)
   119  	}
   120  	if symabis != "" {
   121  		defaultGcFlags = append(defaultGcFlags, "-symabis", symabis)
   122  	}
   123  
   124  	gcflags := str.StringList(forcedGcflags, p.Internal.Gcflags)
   125  	if p.Internal.FuzzInstrument {
   126  		gcflags = append(gcflags, fuzzInstrumentFlags()...)
   127  	}
   128  	
   129  	if c := gcBackendConcurrency(gcflags); c > 1 {
   130  		defaultGcFlags = append(defaultGcFlags, fmt.Sprintf("-c=%d", c))
   131  	}
   132  
   133  	args := []any{cfg.BuildToolexec, base.Tool("compile"), "-o", ofile, "-trimpath", a.trimpath(), defaultGcFlags, gcflags}
   134  	if p.Internal.LocalPrefix == "" {
   135  		args = append(args, "-nolocalimports")
   136  	} else {
   137  		args = append(args, "-D", p.Internal.LocalPrefix)
   138  	}
   139  	if importcfg != nil {
   140  		if err := sh.writeFile(objdir+"importcfg", importcfg); err != nil {
   141  			return "", nil, err
   142  		}
   143  		args = append(args, "-importcfg", objdir+"importcfg")
   144  	}
   145  	if embedcfg != nil {
   146  		if err := sh.writeFile(objdir+"embedcfg", embedcfg); err != nil {
   147  			return "", nil, err
   148  		}
   149  		args = append(args, "-embedcfg", objdir+"embedcfg")
   150  	}
   151  	if ofile == archive {
   152  		args = append(args, "-pack")
   153  	}
   154  	if asmhdr {
   155  		args = append(args, "-asmhdr", objdir+"go_asm.h")
   156  	}
   157  
   158  	for _, f := range gofiles {
   159  		f := mkAbs(p.Dir, f)
   160  
   161  		
   162  		
   163  		
   164  		
   165  		
   166  		
   167  		
   168  		
   169  		
   170  		
   171  		
   172  		
   173  		f, _ = fsys.OverlayPath(f)
   174  
   175  		args = append(args, f)
   176  	}
   177  
   178  	output, err = sh.runOut(base.Cwd(), nil, args...)
   179  	return ofile, output, err
   180  }
   181  
   182  
   183  func gcBackendConcurrency(gcflags []string) int {
   184  	
   185  	canDashC := concurrentGCBackendCompilationEnabledByDefault
   186  
   187  	switch e := os.Getenv("GO19CONCURRENTCOMPILATION"); e {
   188  	case "0":
   189  		canDashC = false
   190  	case "1":
   191  		canDashC = true
   192  	case "":
   193  		
   194  	default:
   195  		log.Fatalf("GO19CONCURRENTCOMPILATION must be 0, 1, or unset, got %q", e)
   196  	}
   197  
   198  	
   199  	if cfg.ExperimentErr != nil || cfg.Experiment.FieldTrack || cfg.Experiment.PreemptibleLoops {
   200  		canDashC = false
   201  	}
   202  
   203  	if !canDashC {
   204  		return 1
   205  	}
   206  
   207  	
   208  	
   209  	
   210  	
   211  	
   212  	
   213  	
   214  	
   215  	
   216  	
   217  	
   218  	
   219  	
   220  	
   221  	
   222  	
   223  	
   224  	
   225  	
   226  	
   227  	
   228  	
   229  	
   230  	c := runtime.GOMAXPROCS(0)
   231  	if cfg.BuildP == 1 {
   232  		
   233  		return c
   234  	}
   235  	
   236  	if c > 4 {
   237  		c = 4
   238  	}
   239  	return c
   240  }
   241  
   242  
   243  
   244  func (a *Action) trimpath() string {
   245  	
   246  	
   247  	
   248  
   249  	
   250  	objdir := a.Objdir
   251  	if len(objdir) > 1 && objdir[len(objdir)-1] == filepath.Separator {
   252  		objdir = objdir[:len(objdir)-1]
   253  	}
   254  	rewrite := ""
   255  
   256  	rewriteDir := a.Package.Dir
   257  	if cfg.BuildTrimpath {
   258  		importPath := a.Package.Internal.OrigImportPath
   259  		if m := a.Package.Module; m != nil && m.Version != "" {
   260  			rewriteDir = m.Path + "@" + m.Version + strings.TrimPrefix(importPath, m.Path)
   261  		} else {
   262  			rewriteDir = importPath
   263  		}
   264  		rewrite += a.Package.Dir + "=>" + rewriteDir + ";"
   265  	}
   266  
   267  	
   268  	
   269  	
   270  
   271  	cgoFiles := make(map[string]bool)
   272  	for _, f := range a.Package.CgoFiles {
   273  		cgoFiles[f] = true
   274  	}
   275  
   276  	
   277  	
   278  	
   279  	
   280  	var overlayNonGoRewrites string 
   281  	hasCgoOverlay := false
   282  	if fsys.OverlayFile != "" {
   283  		for _, filename := range a.Package.AllFiles() {
   284  			path := filename
   285  			if !filepath.IsAbs(path) {
   286  				path = filepath.Join(a.Package.Dir, path)
   287  			}
   288  			base := filepath.Base(path)
   289  			isGo := strings.HasSuffix(filename, ".go") || strings.HasSuffix(filename, ".s")
   290  			isCgo := cgoFiles[filename] || !isGo
   291  			overlayPath, isOverlay := fsys.OverlayPath(path)
   292  			if isCgo && isOverlay {
   293  				hasCgoOverlay = true
   294  			}
   295  			if !isCgo && isOverlay {
   296  				rewrite += overlayPath + "=>" + filepath.Join(rewriteDir, base) + ";"
   297  			} else if isCgo {
   298  				
   299  				if filepath.Dir(path) == a.Package.Dir {
   300  					
   301  					overlayNonGoRewrites += filepath.Join(objdir, base) + "=>" + filepath.Join(rewriteDir, base) + ";"
   302  				}
   303  			} else {
   304  				
   305  			}
   306  		}
   307  	}
   308  	if hasCgoOverlay {
   309  		rewrite += overlayNonGoRewrites
   310  	}
   311  	rewrite += objdir + "=>"
   312  
   313  	return rewrite
   314  }
   315  
   316  func asmArgs(a *Action, p *load.Package) []any {
   317  	
   318  	inc := filepath.Join(cfg.GOROOT, "pkg", "include")
   319  	pkgpath := pkgPath(a)
   320  	args := []any{cfg.BuildToolexec, base.Tool("asm"), "-p", pkgpath, "-trimpath", a.trimpath(), "-I", a.Objdir, "-I", inc, "-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch, forcedAsmflags, p.Internal.Asmflags}
   321  	if p.ImportPath == "runtime" && cfg.Goarch == "386" {
   322  		for _, arg := range forcedAsmflags {
   323  			if arg == "-dynlink" {
   324  				args = append(args, "-D=GOBUILDMODE_shared=1")
   325  			}
   326  		}
   327  	}
   328  
   329  	if cfg.Goarch == "386" {
   330  		
   331  		args = append(args, "-D", "GO386_"+cfg.GO386)
   332  	}
   333  
   334  	if cfg.Goarch == "amd64" {
   335  		
   336  		args = append(args, "-D", "GOAMD64_"+cfg.GOAMD64)
   337  	}
   338  
   339  	if cfg.Goarch == "mips" || cfg.Goarch == "mipsle" {
   340  		
   341  		args = append(args, "-D", "GOMIPS_"+cfg.GOMIPS)
   342  	}
   343  
   344  	if cfg.Goarch == "mips64" || cfg.Goarch == "mips64le" {
   345  		
   346  		args = append(args, "-D", "GOMIPS64_"+cfg.GOMIPS64)
   347  	}
   348  
   349  	if cfg.Goarch == "ppc64" || cfg.Goarch == "ppc64le" {
   350  		
   351  		
   352  		switch cfg.GOPPC64 {
   353  		case "power10":
   354  			args = append(args, "-D", "GOPPC64_power10")
   355  			fallthrough
   356  		case "power9":
   357  			args = append(args, "-D", "GOPPC64_power9")
   358  			fallthrough
   359  		default: 
   360  			args = append(args, "-D", "GOPPC64_power8")
   361  		}
   362  	}
   363  
   364  	if cfg.Goarch == "arm" {
   365  		
   366  		switch cfg.GOARM {
   367  		case "7":
   368  			args = append(args, "-D", "GOARM_7")
   369  			fallthrough
   370  		case "6":
   371  			args = append(args, "-D", "GOARM_6")
   372  			fallthrough
   373  		default:
   374  			args = append(args, "-D", "GOARM_5")
   375  		}
   376  	}
   377  
   378  	return args
   379  }
   380  
   381  func (gcToolchain) asm(b *Builder, a *Action, sfiles []string) ([]string, error) {
   382  	p := a.Package
   383  	args := asmArgs(a, p)
   384  
   385  	var ofiles []string
   386  	for _, sfile := range sfiles {
   387  		overlayPath, _ := fsys.OverlayPath(mkAbs(p.Dir, sfile))
   388  		ofile := a.Objdir + sfile[:len(sfile)-len(".s")] + ".o"
   389  		ofiles = append(ofiles, ofile)
   390  		args1 := append(args, "-o", ofile, overlayPath)
   391  		if err := b.Shell(a).run(p.Dir, p.ImportPath, nil, args1...); err != nil {
   392  			return nil, err
   393  		}
   394  	}
   395  	return ofiles, nil
   396  }
   397  
   398  func (gcToolchain) symabis(b *Builder, a *Action, sfiles []string) (string, error) {
   399  	sh := b.Shell(a)
   400  
   401  	mkSymabis := func(p *load.Package, sfiles []string, path string) error {
   402  		args := asmArgs(a, p)
   403  		args = append(args, "-gensymabis", "-o", path)
   404  		for _, sfile := range sfiles {
   405  			if p.ImportPath == "runtime/cgo" && strings.HasPrefix(sfile, "gcc_") {
   406  				continue
   407  			}
   408  			op, _ := fsys.OverlayPath(mkAbs(p.Dir, sfile))
   409  			args = append(args, op)
   410  		}
   411  
   412  		
   413  		
   414  		
   415  		if err := sh.writeFile(a.Objdir+"go_asm.h", nil); err != nil {
   416  			return err
   417  		}
   418  
   419  		return sh.run(p.Dir, p.ImportPath, nil, args...)
   420  	}
   421  
   422  	var symabis string 
   423  	p := a.Package
   424  	if len(sfiles) != 0 {
   425  		symabis = a.Objdir + "symabis"
   426  		if err := mkSymabis(p, sfiles, symabis); err != nil {
   427  			return "", err
   428  		}
   429  	}
   430  
   431  	return symabis, nil
   432  }
   433  
   434  
   435  
   436  
   437  func toolVerify(a *Action, b *Builder, p *load.Package, newTool string, ofile string, args []any) error {
   438  	newArgs := make([]any, len(args))
   439  	copy(newArgs, args)
   440  	newArgs[1] = base.Tool(newTool)
   441  	newArgs[3] = ofile + ".new" 
   442  	if err := b.Shell(a).run(p.Dir, p.ImportPath, nil, newArgs...); err != nil {
   443  		return err
   444  	}
   445  	data1, err := os.ReadFile(ofile)
   446  	if err != nil {
   447  		return err
   448  	}
   449  	data2, err := os.ReadFile(ofile + ".new")
   450  	if err != nil {
   451  		return err
   452  	}
   453  	if !bytes.Equal(data1, data2) {
   454  		return fmt.Errorf("%s and %s produced different output files:\n%s\n%s", filepath.Base(args[1].(string)), newTool, strings.Join(str.StringList(args...), " "), strings.Join(str.StringList(newArgs...), " "))
   455  	}
   456  	os.Remove(ofile + ".new")
   457  	return nil
   458  }
   459  
   460  func (gcToolchain) pack(b *Builder, a *Action, afile string, ofiles []string) error {
   461  	var absOfiles []string
   462  	for _, f := range ofiles {
   463  		absOfiles = append(absOfiles, mkAbs(a.Objdir, f))
   464  	}
   465  	absAfile := mkAbs(a.Objdir, afile)
   466  
   467  	
   468  	
   469  	if !cfg.BuildN {
   470  		if _, err := os.Stat(absAfile); err != nil {
   471  			base.Fatalf("os.Stat of archive file failed: %v", err)
   472  		}
   473  	}
   474  
   475  	p := a.Package
   476  	sh := b.Shell(a)
   477  	if cfg.BuildN || cfg.BuildX {
   478  		cmdline := str.StringList(base.Tool("pack"), "r", absAfile, absOfiles)
   479  		sh.ShowCmd(p.Dir, "%s # internal", joinUnambiguously(cmdline))
   480  	}
   481  	if cfg.BuildN {
   482  		return nil
   483  	}
   484  	if err := packInternal(absAfile, absOfiles); err != nil {
   485  		return sh.reportCmd("", "", nil, err)
   486  	}
   487  	return nil
   488  }
   489  
   490  func packInternal(afile string, ofiles []string) error {
   491  	dst, err := os.OpenFile(afile, os.O_WRONLY|os.O_APPEND, 0)
   492  	if err != nil {
   493  		return err
   494  	}
   495  	defer dst.Close() 
   496  	w := bufio.NewWriter(dst)
   497  
   498  	for _, ofile := range ofiles {
   499  		src, err := os.Open(ofile)
   500  		if err != nil {
   501  			return err
   502  		}
   503  		fi, err := src.Stat()
   504  		if err != nil {
   505  			src.Close()
   506  			return err
   507  		}
   508  		
   509  		
   510  		name := fi.Name()
   511  		if len(name) > 16 {
   512  			name = name[:16]
   513  		} else {
   514  			name += strings.Repeat(" ", 16-len(name))
   515  		}
   516  		size := fi.Size()
   517  		fmt.Fprintf(w, "%s%-12d%-6d%-6d%-8o%-10d`\n",
   518  			name, 0, 0, 0, 0644, size)
   519  		n, err := io.Copy(w, src)
   520  		src.Close()
   521  		if err == nil && n < size {
   522  			err = io.ErrUnexpectedEOF
   523  		} else if err == nil && n > size {
   524  			err = fmt.Errorf("file larger than size reported by stat")
   525  		}
   526  		if err != nil {
   527  			return fmt.Errorf("copying %s to %s: %v", ofile, afile, err)
   528  		}
   529  		if size&1 != 0 {
   530  			w.WriteByte(0)
   531  		}
   532  	}
   533  
   534  	if err := w.Flush(); err != nil {
   535  		return err
   536  	}
   537  	return dst.Close()
   538  }
   539  
   540  
   541  func setextld(ldflags []string, compiler []string) ([]string, error) {
   542  	for _, f := range ldflags {
   543  		if f == "-extld" || strings.HasPrefix(f, "-extld=") {
   544  			
   545  			return ldflags, nil
   546  		}
   547  	}
   548  	joined, err := quoted.Join(compiler)
   549  	if err != nil {
   550  		return nil, err
   551  	}
   552  	return append(ldflags, "-extld="+joined), nil
   553  }
   554  
   555  
   556  
   557  
   558  
   559  
   560  
   561  
   562  func pluginPath(a *Action) string {
   563  	p := a.Package
   564  	if p.ImportPath != "command-line-arguments" {
   565  		return p.ImportPath
   566  	}
   567  	h := sha1.New()
   568  	buildID := a.buildID
   569  	if a.Mode == "link" {
   570  		
   571  		
   572  		
   573  		
   574  		
   575  		
   576  		
   577  		
   578  		
   579  		id := strings.Split(buildID, buildIDSeparator)
   580  		buildID = id[1] + buildIDSeparator + id[1]
   581  	}
   582  	fmt.Fprintf(h, "build ID: %s\n", buildID)
   583  	for _, file := range str.StringList(p.GoFiles, p.CgoFiles, p.SFiles) {
   584  		data, err := os.ReadFile(filepath.Join(p.Dir, file))
   585  		if err != nil {
   586  			base.Fatalf("go: %s", err)
   587  		}
   588  		h.Write(data)
   589  	}
   590  	return fmt.Sprintf("plugin/unnamed-%x", h.Sum(nil))
   591  }
   592  
   593  func (gcToolchain) ld(b *Builder, root *Action, targetPath, importcfg, mainpkg string) error {
   594  	cxx := len(root.Package.CXXFiles) > 0 || len(root.Package.SwigCXXFiles) > 0
   595  	for _, a := range root.Deps {
   596  		if a.Package != nil && (len(a.Package.CXXFiles) > 0 || len(a.Package.SwigCXXFiles) > 0) {
   597  			cxx = true
   598  		}
   599  	}
   600  	var ldflags []string
   601  	if cfg.BuildContext.InstallSuffix != "" {
   602  		ldflags = append(ldflags, "-installsuffix", cfg.BuildContext.InstallSuffix)
   603  	}
   604  	if root.Package.Internal.OmitDebug {
   605  		ldflags = append(ldflags, "-s", "-w")
   606  	}
   607  	if cfg.BuildBuildmode == "plugin" {
   608  		ldflags = append(ldflags, "-pluginpath", pluginPath(root))
   609  	}
   610  
   611  	
   612  	
   613  	if root.Package.Goroot && strings.HasPrefix(root.Package.ImportPath, "cmd/") {
   614  		
   615  		
   616  		
   617  		
   618  		if !platform.MustLinkExternal(cfg.Goos, cfg.Goarch, false) {
   619  			ldflags = append(ldflags, "-X=cmd/internal/objabi.buildID="+root.buildID)
   620  		}
   621  	}
   622  
   623  	
   624  	if root.Package.DefaultGODEBUG != "" {
   625  		ldflags = append(ldflags, "-X=runtime.godebugDefault="+root.Package.DefaultGODEBUG)
   626  	}
   627  
   628  	
   629  	
   630  	
   631  	
   632  	var compiler []string
   633  	if cxx {
   634  		compiler = envList("CXX", cfg.DefaultCXX(cfg.Goos, cfg.Goarch))
   635  	} else {
   636  		compiler = envList("CC", cfg.DefaultCC(cfg.Goos, cfg.Goarch))
   637  	}
   638  	ldflags = append(ldflags, "-buildmode="+ldBuildmode)
   639  	if root.buildID != "" {
   640  		ldflags = append(ldflags, "-buildid="+root.buildID)
   641  	}
   642  	ldflags = append(ldflags, forcedLdflags...)
   643  	ldflags = append(ldflags, root.Package.Internal.Ldflags...)
   644  	ldflags, err := setextld(ldflags, compiler)
   645  	if err != nil {
   646  		return err
   647  	}
   648  
   649  	
   650  	
   651  	
   652  	
   653  	
   654  	
   655  	
   656  	
   657  	
   658  	
   659  	
   660  	dir := "."
   661  	if cfg.BuildBuildmode == "c-shared" || cfg.BuildBuildmode == "plugin" {
   662  		dir, targetPath = filepath.Split(targetPath)
   663  	}
   664  
   665  	env := []string{}
   666  	if cfg.BuildTrimpath {
   667  		env = append(env, "GOROOT_FINAL="+trimPathGoRootFinal)
   668  	}
   669  	return b.Shell(root).run(dir, root.Package.ImportPath, env, cfg.BuildToolexec, base.Tool("link"), "-o", targetPath, "-importcfg", importcfg, ldflags, mainpkg)
   670  }
   671  
   672  func (gcToolchain) ldShared(b *Builder, root *Action, toplevelactions []*Action, targetPath, importcfg string, allactions []*Action) error {
   673  	ldflags := []string{"-installsuffix", cfg.BuildContext.InstallSuffix}
   674  	ldflags = append(ldflags, "-buildmode=shared")
   675  	ldflags = append(ldflags, forcedLdflags...)
   676  	ldflags = append(ldflags, root.Package.Internal.Ldflags...)
   677  	cxx := false
   678  	for _, a := range allactions {
   679  		if a.Package != nil && (len(a.Package.CXXFiles) > 0 || len(a.Package.SwigCXXFiles) > 0) {
   680  			cxx = true
   681  		}
   682  	}
   683  	
   684  	
   685  	
   686  	
   687  	var compiler []string
   688  	if cxx {
   689  		compiler = envList("CXX", cfg.DefaultCXX(cfg.Goos, cfg.Goarch))
   690  	} else {
   691  		compiler = envList("CC", cfg.DefaultCC(cfg.Goos, cfg.Goarch))
   692  	}
   693  	ldflags, err := setextld(ldflags, compiler)
   694  	if err != nil {
   695  		return err
   696  	}
   697  	for _, d := range toplevelactions {
   698  		if !strings.HasSuffix(d.Target, ".a") { 
   699  			continue
   700  		}
   701  		ldflags = append(ldflags, d.Package.ImportPath+"="+d.Target)
   702  	}
   703  	return b.Shell(root).run(".", targetPath, nil, cfg.BuildToolexec, base.Tool("link"), "-o", targetPath, "-importcfg", importcfg, ldflags)
   704  }
   705  
   706  func (gcToolchain) cc(b *Builder, a *Action, ofile, cfile string) error {
   707  	return fmt.Errorf("%s: C source files not supported without cgo", mkAbs(a.Package.Dir, cfile))
   708  }
   709  
View as plain text