cmd/go: pass -funwind-tables when compiling C code
[official-gcc.git] / libgo / go / cmd / go / build.go
bloba62bc86c26232638f861c5fe35edecbd727ad199
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.
5 package main
7 import (
8 "bufio"
9 "bytes"
10 "container/heap"
11 "debug/elf"
12 "errors"
13 "flag"
14 "fmt"
15 "go/build"
16 "io"
17 "io/ioutil"
18 "log"
19 "os"
20 "os/exec"
21 "path"
22 "path/filepath"
23 "regexp"
24 "runtime"
25 "strconv"
26 "strings"
27 "sync"
28 "time"
31 var cmdBuild = &Command{
32 UsageLine: "build [-o output] [-i] [build flags] [packages]",
33 Short: "compile packages and dependencies",
34 Long: `
35 Build compiles the packages named by the import paths,
36 along with their dependencies, but it does not install the results.
38 If the arguments to build are a list of .go files, build treats
39 them as a list of source files specifying a single package.
41 When compiling a single main package, build writes
42 the resulting executable to an output file named after
43 the first source file ('go build ed.go rx.go' writes 'ed' or 'ed.exe')
44 or the source code directory ('go build unix/sam' writes 'sam' or 'sam.exe').
45 The '.exe' suffix is added when writing a Windows executable.
47 When compiling multiple packages or a single non-main package,
48 build compiles the packages but discards the resulting object,
49 serving only as a check that the packages can be built.
51 When compiling packages, build ignores files that end in '_test.go'.
53 The -o flag, only allowed when compiling a single package,
54 forces build to write the resulting executable or object
55 to the named output file, instead of the default behavior described
56 in the last two paragraphs.
58 The -i flag installs the packages that are dependencies of the target.
60 The build flags are shared by the build, clean, get, install, list, run,
61 and test commands:
64 force rebuilding of packages that are already up-to-date.
66 print the commands but do not run them.
67 -p n
68 the number of programs, such as build commands or
69 test binaries, that can be run in parallel.
70 The default is the number of CPUs available.
71 -race
72 enable data race detection.
73 Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
74 -msan
75 enable interoperation with memory sanitizer.
76 Supported only on linux/amd64,
77 and only with Clang/LLVM as the host C compiler.
79 print the names of packages as they are compiled.
80 -work
81 print the name of the temporary work directory and
82 do not delete it when exiting.
84 print the commands.
86 -asmflags 'flag list'
87 arguments to pass on each go tool asm invocation.
88 -buildmode mode
89 build mode to use. See 'go help buildmode' for more.
90 -compiler name
91 name of compiler to use, as in runtime.Compiler (gccgo or gc).
92 -gccgoflags 'arg list'
93 arguments to pass on each gccgo compiler/linker invocation.
94 -gcflags 'arg list'
95 arguments to pass on each go tool compile invocation.
96 -installsuffix suffix
97 a suffix to use in the name of the package installation directory,
98 in order to keep output separate from default builds.
99 If using the -race flag, the install suffix is automatically set to race
100 or, if set explicitly, has _race appended to it. Likewise for the -msan
101 flag. Using a -buildmode option that requires non-default compile flags
102 has a similar effect.
103 -ldflags 'flag list'
104 arguments to pass on each go tool link invocation.
105 -linkshared
106 link against shared libraries previously created with
107 -buildmode=shared.
108 -pkgdir dir
109 install and load all packages from dir instead of the usual locations.
110 For example, when building with a non-standard configuration,
111 use -pkgdir to keep generated packages in a separate location.
112 -tags 'tag list'
113 a list of build tags to consider satisfied during the build.
114 For more information about build tags, see the description of
115 build constraints in the documentation for the go/build package.
116 -toolexec 'cmd args'
117 a program to use to invoke toolchain programs like vet and asm.
118 For example, instead of running asm, the go command will run
119 'cmd args /path/to/asm <arguments for asm>'.
121 The list flags accept a space-separated list of strings. To embed spaces
122 in an element in the list, surround it with either single or double quotes.
124 For more about specifying packages, see 'go help packages'.
125 For more about where packages and binaries are installed,
126 run 'go help gopath'.
127 For more about calling between Go and C/C++, run 'go help c'.
129 Note: Build adheres to certain conventions such as those described
130 by 'go help gopath'. Not all projects can follow these conventions,
131 however. Installations that have their own conventions or that use
132 a separate software build system may choose to use lower-level
133 invocations such as 'go tool compile' and 'go tool link' to avoid
134 some of the overheads and design decisions of the build tool.
136 See also: go install, go get, go clean.
140 func init() {
141 // break init cycle
142 cmdBuild.Run = runBuild
143 cmdInstall.Run = runInstall
145 cmdBuild.Flag.BoolVar(&buildI, "i", false, "")
147 addBuildFlags(cmdBuild)
148 addBuildFlags(cmdInstall)
151 // Flags set by multiple commands.
152 var buildA bool // -a flag
153 var buildN bool // -n flag
154 var buildP = runtime.NumCPU() // -p flag
155 var buildV bool // -v flag
156 var buildX bool // -x flag
157 var buildI bool // -i flag
158 var buildO = cmdBuild.Flag.String("o", "", "output file")
159 var buildWork bool // -work flag
160 var buildAsmflags []string // -asmflags flag
161 var buildGcflags []string // -gcflags flag
162 var buildLdflags []string // -ldflags flag
163 var buildGccgoflags []string // -gccgoflags flag
164 var buildRace bool // -race flag
165 var buildMSan bool // -msan flag
166 var buildToolExec []string // -toolexec flag
167 var buildBuildmode string // -buildmode flag
168 var buildLinkshared bool // -linkshared flag
169 var buildPkgdir string // -pkgdir flag
171 // Require the source for go std packages
172 var reqStdPkgSrc bool
173 var buildContext = build.Default
174 var buildToolchain toolchain = noToolchain{}
175 var ldBuildmode string
177 // buildCompiler implements flag.Var.
178 // It implements Set by updating both
179 // buildToolchain and buildContext.Compiler.
180 type buildCompiler struct{}
182 func (c buildCompiler) Set(value string) error {
183 switch value {
184 case "gc":
185 buildToolchain = gcToolchain{}
186 case "gccgo":
187 buildToolchain = gccgoToolchain{}
188 default:
189 return fmt.Errorf("unknown compiler %q", value)
191 buildContext.Compiler = value
192 return nil
195 func (c buildCompiler) String() string {
196 return buildContext.Compiler
199 func init() {
200 switch build.Default.Compiler {
201 case "gc":
202 buildToolchain = gcToolchain{}
203 case "gccgo":
204 buildToolchain = gccgoToolchain{}
208 // addBuildFlags adds the flags common to the build, clean, get,
209 // install, list, run, and test commands.
210 func addBuildFlags(cmd *Command) {
211 cmd.Flag.BoolVar(&buildA, "a", false, "")
212 cmd.Flag.BoolVar(&buildN, "n", false, "")
213 cmd.Flag.IntVar(&buildP, "p", buildP, "")
214 cmd.Flag.BoolVar(&buildV, "v", false, "")
215 cmd.Flag.BoolVar(&buildX, "x", false, "")
217 cmd.Flag.Var((*stringsFlag)(&buildAsmflags), "asmflags", "")
218 cmd.Flag.Var(buildCompiler{}, "compiler", "")
219 cmd.Flag.StringVar(&buildBuildmode, "buildmode", "default", "")
220 cmd.Flag.Var((*stringsFlag)(&buildGcflags), "gcflags", "")
221 cmd.Flag.Var((*stringsFlag)(&buildGccgoflags), "gccgoflags", "")
222 cmd.Flag.StringVar(&buildContext.InstallSuffix, "installsuffix", "", "")
223 cmd.Flag.Var((*stringsFlag)(&buildLdflags), "ldflags", "")
224 cmd.Flag.BoolVar(&buildLinkshared, "linkshared", false, "")
225 cmd.Flag.StringVar(&buildPkgdir, "pkgdir", "", "")
226 cmd.Flag.BoolVar(&buildRace, "race", false, "")
227 cmd.Flag.BoolVar(&buildMSan, "msan", false, "")
228 cmd.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
229 cmd.Flag.Var((*stringsFlag)(&buildToolExec), "toolexec", "")
230 cmd.Flag.BoolVar(&buildWork, "work", false, "")
231 switch build.Default.Compiler {
232 case "gc":
233 reqStdPkgSrc = true
234 case "gccgo":
235 reqStdPkgSrc = false
239 func addBuildFlagsNX(cmd *Command) {
240 cmd.Flag.BoolVar(&buildN, "n", false, "")
241 cmd.Flag.BoolVar(&buildX, "x", false, "")
244 func isSpaceByte(c byte) bool {
245 return c == ' ' || c == '\t' || c == '\n' || c == '\r'
248 // fileExtSplit expects a filename and returns the name
249 // and ext (without the dot). If the file has no
250 // extension, ext will be empty.
251 func fileExtSplit(file string) (name, ext string) {
252 dotExt := filepath.Ext(file)
253 name = file[:len(file)-len(dotExt)]
254 if dotExt != "" {
255 ext = dotExt[1:]
257 return
260 type stringsFlag []string
262 func (v *stringsFlag) Set(s string) error {
263 var err error
264 *v, err = splitQuotedFields(s)
265 if *v == nil {
266 *v = []string{}
268 return err
271 func splitQuotedFields(s string) ([]string, error) {
272 // Split fields allowing '' or "" around elements.
273 // Quotes further inside the string do not count.
274 var f []string
275 for len(s) > 0 {
276 for len(s) > 0 && isSpaceByte(s[0]) {
277 s = s[1:]
279 if len(s) == 0 {
280 break
282 // Accepted quoted string. No unescaping inside.
283 if s[0] == '"' || s[0] == '\'' {
284 quote := s[0]
285 s = s[1:]
286 i := 0
287 for i < len(s) && s[i] != quote {
290 if i >= len(s) {
291 return nil, fmt.Errorf("unterminated %c string", quote)
293 f = append(f, s[:i])
294 s = s[i+1:]
295 continue
297 i := 0
298 for i < len(s) && !isSpaceByte(s[i]) {
301 f = append(f, s[:i])
302 s = s[i:]
304 return f, nil
307 func (v *stringsFlag) String() string {
308 return "<stringsFlag>"
311 func pkgsMain(pkgs []*Package) (res []*Package) {
312 for _, p := range pkgs {
313 if p.Name == "main" {
314 res = append(res, p)
317 return res
320 func pkgsNotMain(pkgs []*Package) (res []*Package) {
321 for _, p := range pkgs {
322 if p.Name != "main" {
323 res = append(res, p)
326 return res
329 var pkgsFilter = func(pkgs []*Package) []*Package { return pkgs }
331 func buildModeInit() {
332 _, gccgo := buildToolchain.(gccgoToolchain)
333 var codegenArg string
334 platform := goos + "/" + goarch
335 switch buildBuildmode {
336 case "archive":
337 pkgsFilter = pkgsNotMain
338 case "c-archive":
339 pkgsFilter = func(p []*Package) []*Package {
340 if len(p) != 1 || p[0].Name != "main" {
341 fatalf("-buildmode=c-archive requires exactly one main package")
343 return p
345 if gccgo {
346 codegenArg = "-fPIC"
347 } else {
348 switch platform {
349 case "darwin/arm", "darwin/arm64":
350 codegenArg = "-shared"
351 default:
352 switch goos {
353 case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
354 // Use -shared so that the result is
355 // suitable for inclusion in a PIE or
356 // shared library.
357 codegenArg = "-shared"
361 exeSuffix = ".a"
362 ldBuildmode = "c-archive"
363 case "c-shared":
364 pkgsFilter = pkgsMain
365 if gccgo {
366 codegenArg = "-fPIC"
367 } else {
368 switch platform {
369 case "linux/amd64", "linux/arm", "linux/arm64", "linux/386",
370 "android/amd64", "android/arm", "android/arm64", "android/386":
371 codegenArg = "-shared"
372 case "darwin/amd64", "darwin/386":
373 default:
374 fatalf("-buildmode=c-shared not supported on %s\n", platform)
377 ldBuildmode = "c-shared"
378 case "default":
379 switch platform {
380 case "android/arm", "android/arm64", "android/amd64", "android/386":
381 if !gccgo {
382 codegenArg = "-shared"
384 ldBuildmode = "pie"
385 case "darwin/arm", "darwin/arm64":
386 if !gccgo {
387 codegenArg = "-shared"
389 fallthrough
390 default:
391 ldBuildmode = "exe"
393 case "exe":
394 pkgsFilter = pkgsMain
395 ldBuildmode = "exe"
396 case "pie":
397 if gccgo {
398 codegenArg = "-fPIE"
399 } else {
400 switch platform {
401 case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x",
402 "android/amd64", "android/arm", "android/arm64", "android/386":
403 codegenArg = "-shared"
404 default:
405 fatalf("-buildmode=pie not supported on %s\n", platform)
408 ldBuildmode = "pie"
409 case "shared":
410 pkgsFilter = pkgsNotMain
411 if gccgo {
412 codegenArg = "-fPIC"
413 } else {
414 switch platform {
415 case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x":
416 default:
417 fatalf("-buildmode=shared not supported on %s\n", platform)
419 codegenArg = "-dynlink"
421 if *buildO != "" {
422 fatalf("-buildmode=shared and -o not supported together")
424 ldBuildmode = "shared"
425 case "plugin":
426 pkgsFilter = pkgsMain
427 if gccgo {
428 codegenArg = "-fPIC"
429 } else {
430 switch platform {
431 case "linux/amd64", "linux/arm", "linux/arm64", "linux/386",
432 "android/amd64", "android/arm", "android/arm64", "android/386":
433 default:
434 fatalf("-buildmode=plugin not supported on %s\n", platform)
436 codegenArg = "-dynlink"
438 exeSuffix = ".so"
439 ldBuildmode = "plugin"
440 default:
441 fatalf("buildmode=%s not supported", buildBuildmode)
443 if buildLinkshared {
444 if gccgo {
445 codegenArg = "-fPIC"
446 } else {
447 switch platform {
448 case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x":
449 buildAsmflags = append(buildAsmflags, "-D=GOBUILDMODE_shared=1")
450 default:
451 fatalf("-linkshared not supported on %s\n", platform)
453 codegenArg = "-dynlink"
454 // TODO(mwhudson): remove -w when that gets fixed in linker.
455 buildLdflags = append(buildLdflags, "-linkshared", "-w")
458 if codegenArg != "" {
459 if gccgo {
460 buildGccgoflags = append(buildGccgoflags, codegenArg)
461 } else {
462 buildAsmflags = append(buildAsmflags, codegenArg)
463 buildGcflags = append(buildGcflags, codegenArg)
465 // Don't alter InstallSuffix when modifying default codegen args.
466 if buildBuildmode != "default" || buildLinkshared {
467 if buildContext.InstallSuffix != "" {
468 buildContext.InstallSuffix += "_"
470 buildContext.InstallSuffix += codegenArg[1:]
475 func runBuild(cmd *Command, args []string) {
476 instrumentInit()
477 buildModeInit()
478 var b builder
479 b.init()
481 pkgs := packagesForBuild(args)
483 if len(pkgs) == 1 && pkgs[0].Name == "main" && *buildO == "" {
484 _, *buildO = path.Split(pkgs[0].ImportPath)
485 *buildO += exeSuffix
488 // Special case -o /dev/null by not writing at all.
489 if *buildO == os.DevNull {
490 *buildO = ""
493 // sanity check some often mis-used options
494 switch buildContext.Compiler {
495 case "gccgo":
496 if len(buildGcflags) != 0 {
497 fmt.Println("go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags")
499 if len(buildLdflags) != 0 {
500 fmt.Println("go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags")
502 case "gc":
503 if len(buildGccgoflags) != 0 {
504 fmt.Println("go build: when using gc toolchain, please pass compile flags using -gcflags, and linker flags using -ldflags")
508 depMode := modeBuild
509 if buildI {
510 depMode = modeInstall
513 if *buildO != "" {
514 if len(pkgs) > 1 {
515 fatalf("go build: cannot use -o with multiple packages")
516 } else if len(pkgs) == 0 {
517 fatalf("no packages to build")
519 p := pkgs[0]
520 p.target = *buildO
521 p.Stale = true // must build - not up to date
522 p.StaleReason = "build -o flag in use"
523 a := b.action(modeInstall, depMode, p)
524 b.do(a)
525 return
528 var a *action
529 if buildBuildmode == "shared" {
530 pkgs := pkgsFilter(packages(args))
531 if libName, err := libname(args, pkgs); err != nil {
532 fatalf("%s", err.Error())
533 } else {
534 a = b.libaction(libName, pkgs, modeBuild, depMode)
536 } else {
537 a = &action{}
538 for _, p := range pkgsFilter(packages(args)) {
539 a.deps = append(a.deps, b.action(modeBuild, depMode, p))
542 b.do(a)
545 var cmdInstall = &Command{
546 UsageLine: "install [build flags] [packages]",
547 Short: "compile and install packages and dependencies",
548 Long: `
549 Install compiles and installs the packages named by the import paths,
550 along with their dependencies.
552 For more about the build flags, see 'go help build'.
553 For more about specifying packages, see 'go help packages'.
555 See also: go build, go get, go clean.
559 // isMetaPackage checks if name is a reserved package name that expands to multiple packages
560 func isMetaPackage(name string) bool {
561 return name == "std" || name == "cmd" || name == "all"
564 // libname returns the filename to use for the shared library when using
565 // -buildmode=shared. The rules we use are:
566 // Use arguments for special 'meta' packages:
567 // std --> libstd.so
568 // std cmd --> libstd,cmd.so
569 // A single non-meta argument with trailing "/..." is special cased:
570 // foo/... --> libfoo.so
571 // (A relative path like "./..." expands the "." first)
572 // Use import paths for other cases, changing '/' to '-':
573 // somelib --> libsubdir-somelib.so
574 // ./ or ../ --> libsubdir-somelib.so
575 // gopkg.in/tomb.v2 -> libgopkg.in-tomb.v2.so
576 // a/... b/... ---> liba/c,b/d.so - all matching import paths
577 // Name parts are joined with ','.
578 func libname(args []string, pkgs []*Package) (string, error) {
579 var libname string
580 appendName := func(arg string) {
581 if libname == "" {
582 libname = arg
583 } else {
584 libname += "," + arg
587 var haveNonMeta bool
588 for _, arg := range args {
589 if isMetaPackage(arg) {
590 appendName(arg)
591 } else {
592 haveNonMeta = true
595 if len(libname) == 0 { // non-meta packages only. use import paths
596 if len(args) == 1 && strings.HasSuffix(args[0], "/...") {
597 // Special case of "foo/..." as mentioned above.
598 arg := strings.TrimSuffix(args[0], "/...")
599 if build.IsLocalImport(arg) {
600 cwd, _ := os.Getwd()
601 bp, _ := buildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly)
602 if bp.ImportPath != "" && bp.ImportPath != "." {
603 arg = bp.ImportPath
606 appendName(strings.Replace(arg, "/", "-", -1))
607 } else {
608 for _, pkg := range pkgs {
609 appendName(strings.Replace(pkg.ImportPath, "/", "-", -1))
612 } else if haveNonMeta { // have both meta package and a non-meta one
613 return "", errors.New("mixing of meta and non-meta packages is not allowed")
615 // TODO(mwhudson): Needs to change for platforms that use different naming
616 // conventions...
617 return "lib" + libname + ".so", nil
620 func runInstall(cmd *Command, args []string) {
621 installPackages(args, false)
624 func installPackages(args []string, forGet bool) {
625 if gobin != "" && !filepath.IsAbs(gobin) {
626 fatalf("cannot install, GOBIN must be an absolute path")
629 instrumentInit()
630 buildModeInit()
631 pkgs := pkgsFilter(packagesForBuild(args))
633 for _, p := range pkgs {
634 if p.Target == "" && (!p.Standard || p.ImportPath != "unsafe") {
635 switch {
636 case p.gobinSubdir:
637 errorf("go install: cannot install cross-compiled binaries when GOBIN is set")
638 case p.cmdline:
639 errorf("go install: no install location for .go files listed on command line (GOBIN not set)")
640 case p.ConflictDir != "":
641 errorf("go install: no install location for %s: hidden by %s", p.Dir, p.ConflictDir)
642 default:
643 errorf("go install: no install location for directory %s outside GOPATH\n"+
644 "\tFor more details see: 'go help gopath'", p.Dir)
648 exitIfErrors()
650 var b builder
651 b.init()
652 // Set the behavior for `go get` to not error on packages with test files only.
653 b.testFilesOnlyOK = forGet
654 var a *action
655 if buildBuildmode == "shared" {
656 if libName, err := libname(args, pkgs); err != nil {
657 fatalf("%s", err.Error())
658 } else {
659 a = b.libaction(libName, pkgs, modeInstall, modeInstall)
661 } else {
662 a = &action{}
663 var tools []*action
664 for _, p := range pkgs {
665 // If p is a tool, delay the installation until the end of the build.
666 // This avoids installing assemblers/compilers that are being executed
667 // by other steps in the build.
668 // cmd/cgo is handled specially in b.action, so that we can
669 // both build and use it in the same 'go install'.
670 action := b.action(modeInstall, modeInstall, p)
671 if goTools[p.ImportPath] == toTool && p.ImportPath != "cmd/cgo" {
672 a.deps = append(a.deps, action.deps...)
673 action.deps = append(action.deps, a)
674 tools = append(tools, action)
675 continue
677 a.deps = append(a.deps, action)
679 if len(tools) > 0 {
680 a = &action{
681 deps: tools,
685 b.do(a)
686 exitIfErrors()
688 // Success. If this command is 'go install' with no arguments
689 // and the current directory (the implicit argument) is a command,
690 // remove any leftover command binary from a previous 'go build'.
691 // The binary is installed; it's not needed here anymore.
692 // And worse it might be a stale copy, which you don't want to find
693 // instead of the installed one if $PATH contains dot.
694 // One way to view this behavior is that it is as if 'go install' first
695 // runs 'go build' and the moves the generated file to the install dir.
696 // See issue 9645.
697 if len(args) == 0 && len(pkgs) == 1 && pkgs[0].Name == "main" {
698 // Compute file 'go build' would have created.
699 // If it exists and is an executable file, remove it.
700 _, targ := filepath.Split(pkgs[0].ImportPath)
701 targ += exeSuffix
702 if filepath.Join(pkgs[0].Dir, targ) != pkgs[0].Target { // maybe $GOBIN is the current directory
703 fi, err := os.Stat(targ)
704 if err == nil {
705 m := fi.Mode()
706 if m.IsRegular() {
707 if m&0111 != 0 || goos == "windows" { // windows never sets executable bit
708 os.Remove(targ)
716 // Global build parameters (used during package load)
717 var (
718 goarch string
719 goos string
720 exeSuffix string
721 gopath []string
724 func init() {
725 goarch = buildContext.GOARCH
726 goos = buildContext.GOOS
728 if goos == "windows" {
729 exeSuffix = ".exe"
731 gopath = filepath.SplitList(buildContext.GOPATH)
734 // A builder holds global state about a build.
735 // It does not hold per-package state, because we
736 // build packages in parallel, and the builder is shared.
737 type builder struct {
738 work string // the temporary work directory (ends in filepath.Separator)
739 actionCache map[cacheKey]*action // a cache of already-constructed actions
740 mkdirCache map[string]bool // a cache of created directories
741 flagCache map[string]bool // a cache of supported compiler flags
742 print func(args ...interface{}) (int, error)
744 testFilesOnlyOK bool // do not error if the packages only have test files
746 output sync.Mutex
747 scriptDir string // current directory in printed script
749 exec sync.Mutex
750 readySema chan bool
751 ready actionQueue
754 // An action represents a single action in the action graph.
755 type action struct {
756 p *Package // the package this action works on
757 deps []*action // actions that must happen before this one
758 triggers []*action // inverse of deps
759 cgo *action // action for cgo binary if needed
760 args []string // additional args for runProgram
761 testOutput *bytes.Buffer // test output buffer
763 f func(*builder, *action) error // the action itself (nil = no-op)
764 ignoreFail bool // whether to run f even if dependencies fail
766 // Generated files, directories.
767 link bool // target is executable, not just package
768 pkgdir string // the -I or -L argument to use when importing this package
769 objdir string // directory for intermediate objects
770 objpkg string // the intermediate package .a file created during the action
771 target string // goal of the action: the created package or executable
773 // Execution state.
774 pending int // number of deps yet to complete
775 priority int // relative execution priority
776 failed bool // whether the action failed
779 // cacheKey is the key for the action cache.
780 type cacheKey struct {
781 mode buildMode
782 p *Package
783 shlib string
786 // buildMode specifies the build mode:
787 // are we just building things or also installing the results?
788 type buildMode int
790 const (
791 modeBuild buildMode = iota
792 modeInstall
795 var (
796 goroot = filepath.Clean(runtime.GOROOT())
797 gobin = os.Getenv("GOBIN")
798 gorootBin = filepath.Join(goroot, "bin")
799 gorootPkg = filepath.Join(goroot, "pkg")
800 gorootSrc = filepath.Join(goroot, "src")
803 func (b *builder) init() {
804 var err error
805 b.print = func(a ...interface{}) (int, error) {
806 return fmt.Fprint(os.Stderr, a...)
808 b.actionCache = make(map[cacheKey]*action)
809 b.mkdirCache = make(map[string]bool)
811 if buildN {
812 b.work = "$WORK"
813 } else {
814 b.work, err = ioutil.TempDir("", "go-build")
815 if err != nil {
816 fatalf("%s", err)
818 if buildX || buildWork {
819 fmt.Fprintf(os.Stderr, "WORK=%s\n", b.work)
821 if !buildWork {
822 workdir := b.work
823 atexit(func() { os.RemoveAll(workdir) })
828 // goFilesPackage creates a package for building a collection of Go files
829 // (typically named on the command line). The target is named p.a for
830 // package p or named after the first Go file for package main.
831 func goFilesPackage(gofiles []string) *Package {
832 // TODO: Remove this restriction.
833 for _, f := range gofiles {
834 if !strings.HasSuffix(f, ".go") {
835 fatalf("named files must be .go files")
839 var stk importStack
840 ctxt := buildContext
841 ctxt.UseAllFiles = true
843 // Synthesize fake "directory" that only shows the named files,
844 // to make it look like this is a standard package or
845 // command directory. So that local imports resolve
846 // consistently, the files must all be in the same directory.
847 var dirent []os.FileInfo
848 var dir string
849 for _, file := range gofiles {
850 fi, err := os.Stat(file)
851 if err != nil {
852 fatalf("%s", err)
854 if fi.IsDir() {
855 fatalf("%s is a directory, should be a Go file", file)
857 dir1, _ := filepath.Split(file)
858 if dir1 == "" {
859 dir1 = "./"
861 if dir == "" {
862 dir = dir1
863 } else if dir != dir1 {
864 fatalf("named files must all be in one directory; have %s and %s", dir, dir1)
866 dirent = append(dirent, fi)
868 ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil }
870 var err error
871 if dir == "" {
872 dir = cwd
874 dir, err = filepath.Abs(dir)
875 if err != nil {
876 fatalf("%s", err)
879 bp, err := ctxt.ImportDir(dir, 0)
880 pkg := new(Package)
881 pkg.local = true
882 pkg.cmdline = true
883 stk.push("main")
884 pkg.load(&stk, bp, err)
885 stk.pop()
886 pkg.localPrefix = dirToImportPath(dir)
887 pkg.ImportPath = "command-line-arguments"
888 pkg.target = ""
890 if pkg.Name == "main" {
891 _, elem := filepath.Split(gofiles[0])
892 exe := elem[:len(elem)-len(".go")] + exeSuffix
893 if *buildO == "" {
894 *buildO = exe
896 if gobin != "" {
897 pkg.target = filepath.Join(gobin, exe)
901 pkg.Target = pkg.target
902 pkg.Stale = true
903 pkg.StaleReason = "files named on command line"
905 computeStale(pkg)
906 return pkg
909 // readpkglist returns the list of packages that were built into the shared library
910 // at shlibpath. For the native toolchain this list is stored, newline separated, in
911 // an ELF note with name "Go\x00\x00" and type 1. For GCCGO it is extracted from the
912 // .go_export section.
913 func readpkglist(shlibpath string) (pkgs []*Package) {
914 var stk importStack
915 if _, gccgo := buildToolchain.(gccgoToolchain); gccgo {
916 f, _ := elf.Open(shlibpath)
917 sect := f.Section(".go_export")
918 data, _ := sect.Data()
919 scanner := bufio.NewScanner(bytes.NewBuffer(data))
920 for scanner.Scan() {
921 t := scanner.Text()
922 if strings.HasPrefix(t, "pkgpath ") {
923 t = strings.TrimPrefix(t, "pkgpath ")
924 t = strings.TrimSuffix(t, ";")
925 pkgs = append(pkgs, loadPackage(t, &stk))
928 } else {
929 pkglistbytes, err := readELFNote(shlibpath, "Go\x00\x00", 1)
930 if err != nil {
931 fatalf("readELFNote failed: %v", err)
933 scanner := bufio.NewScanner(bytes.NewBuffer(pkglistbytes))
934 for scanner.Scan() {
935 t := scanner.Text()
936 pkgs = append(pkgs, loadPackage(t, &stk))
939 return
942 // action returns the action for applying the given operation (mode) to the package.
943 // depMode is the action to use when building dependencies.
944 // action never looks for p in a shared library, but may find p's dependencies in a
945 // shared library if buildLinkshared is true.
946 func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action {
947 return b.action1(mode, depMode, p, false, "")
950 // action1 returns the action for applying the given operation (mode) to the package.
951 // depMode is the action to use when building dependencies.
952 // action1 will look for p in a shared library if lookshared is true.
953 // forShlib is the shared library that p will become part of, if any.
954 func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, lookshared bool, forShlib string) *action {
955 shlib := ""
956 if lookshared {
957 shlib = p.Shlib
959 key := cacheKey{mode, p, shlib}
961 a := b.actionCache[key]
962 if a != nil {
963 return a
965 if shlib != "" {
966 key2 := cacheKey{modeInstall, nil, shlib}
967 a = b.actionCache[key2]
968 if a != nil {
969 b.actionCache[key] = a
970 return a
972 pkgs := readpkglist(shlib)
973 a = b.libaction(filepath.Base(shlib), pkgs, modeInstall, depMode)
974 b.actionCache[key2] = a
975 b.actionCache[key] = a
976 return a
979 a = &action{p: p, pkgdir: p.build.PkgRoot}
980 if p.pkgdir != "" { // overrides p.t
981 a.pkgdir = p.pkgdir
983 b.actionCache[key] = a
985 for _, p1 := range p.imports {
986 if forShlib != "" {
987 // p is part of a shared library.
988 if p1.Shlib != "" && p1.Shlib != forShlib {
989 // p1 is explicitly part of a different shared library.
990 // Put the action for that shared library into a.deps.
991 a.deps = append(a.deps, b.action1(depMode, depMode, p1, true, p1.Shlib))
992 } else {
993 // p1 is (implicitly or not) part of this shared library.
994 // Put the action for p1 into a.deps.
995 a.deps = append(a.deps, b.action1(depMode, depMode, p1, false, forShlib))
997 } else {
998 // p is not part of a shared library.
999 // If p1 is in a shared library, put the action for that into
1000 // a.deps, otherwise put the action for p1 into a.deps.
1001 a.deps = append(a.deps, b.action1(depMode, depMode, p1, buildLinkshared, p1.Shlib))
1005 // If we are not doing a cross-build, then record the binary we'll
1006 // generate for cgo as a dependency of the build of any package
1007 // using cgo, to make sure we do not overwrite the binary while
1008 // a package is using it. If this is a cross-build, then the cgo we
1009 // are writing is not the cgo we need to use.
1010 if goos == runtime.GOOS && goarch == runtime.GOARCH && !buildRace && !buildMSan && reqStdPkgSrc {
1011 if (len(p.CgoFiles) > 0 || p.Standard && p.ImportPath == "runtime/cgo") && !buildLinkshared && buildBuildmode != "shared" {
1012 var stk importStack
1013 p1 := loadPackage("cmd/cgo", &stk)
1014 if p1.Error != nil {
1015 fatalf("load cmd/cgo: %v", p1.Error)
1017 a.cgo = b.action(depMode, depMode, p1)
1018 a.deps = append(a.deps, a.cgo)
1022 if p.Standard {
1023 switch p.ImportPath {
1024 case "builtin", "unsafe":
1025 // Fake packages - nothing to build.
1026 return a
1028 // gccgo standard library is "fake" too.
1029 if _, ok := buildToolchain.(gccgoToolchain); ok {
1030 // the target name is needed for cgo.
1031 a.target = p.target
1032 return a
1036 if !p.Stale && p.target != "" {
1037 // p.Stale==false implies that p.target is up-to-date.
1038 // Record target name for use by actions depending on this one.
1039 a.target = p.target
1040 return a
1043 if p.local && p.target == "" {
1044 // Imported via local path. No permanent target.
1045 mode = modeBuild
1047 work := p.pkgdir
1048 if work == "" {
1049 work = b.work
1051 a.objdir = filepath.Join(work, a.p.ImportPath, "_obj") + string(filepath.Separator)
1052 a.objpkg = buildToolchain.pkgpath(work, a.p)
1053 a.link = p.Name == "main"
1055 switch mode {
1056 case modeInstall:
1057 a.f = (*builder).install
1058 a.deps = []*action{b.action1(modeBuild, depMode, p, lookshared, forShlib)}
1059 a.target = a.p.target
1061 // Install header for cgo in c-archive and c-shared modes.
1062 if p.usesCgo() && (buildBuildmode == "c-archive" || buildBuildmode == "c-shared") {
1063 hdrTarget := a.target[:len(a.target)-len(filepath.Ext(a.target))] + ".h"
1064 if buildContext.Compiler == "gccgo" && *buildO == "" {
1065 // For the header file, remove the "lib"
1066 // added by go/build, so we generate pkg.h
1067 // rather than libpkg.h.
1068 dir, file := filepath.Split(hdrTarget)
1069 file = strings.TrimPrefix(file, "lib")
1070 hdrTarget = filepath.Join(dir, file)
1072 ah := &action{
1073 p: a.p,
1074 deps: []*action{a.deps[0]},
1075 f: (*builder).installHeader,
1076 pkgdir: a.pkgdir,
1077 objdir: a.objdir,
1078 target: hdrTarget,
1080 a.deps = append(a.deps, ah)
1083 case modeBuild:
1084 a.f = (*builder).build
1085 a.target = a.objpkg
1086 if a.link {
1087 // An executable file. (This is the name of a temporary file.)
1088 // Because we run the temporary file in 'go run' and 'go test',
1089 // the name will show up in ps listings. If the caller has specified
1090 // a name, use that instead of a.out. The binary is generated
1091 // in an otherwise empty subdirectory named exe to avoid
1092 // naming conflicts. The only possible conflict is if we were
1093 // to create a top-level package named exe.
1094 name := "a.out"
1095 if p.exeName != "" {
1096 name = p.exeName
1097 } else if goos == "darwin" && buildBuildmode == "c-shared" && p.target != "" {
1098 // On OS X, the linker output name gets recorded in the
1099 // shared library's LC_ID_DYLIB load command.
1100 // The code invoking the linker knows to pass only the final
1101 // path element. Arrange that the path element matches what
1102 // we'll install it as; otherwise the library is only loadable as "a.out".
1103 _, name = filepath.Split(p.target)
1105 a.target = a.objdir + filepath.Join("exe", name) + exeSuffix
1109 return a
1112 func (b *builder) libaction(libname string, pkgs []*Package, mode, depMode buildMode) *action {
1113 a := &action{}
1114 switch mode {
1115 default:
1116 fatalf("unrecognized mode %v", mode)
1118 case modeBuild:
1119 a.f = (*builder).linkShared
1120 a.target = filepath.Join(b.work, libname)
1121 for _, p := range pkgs {
1122 if p.target == "" {
1123 continue
1125 a.deps = append(a.deps, b.action(depMode, depMode, p))
1128 case modeInstall:
1129 // Currently build mode shared forces external linking mode, and
1130 // external linking mode forces an import of runtime/cgo (and
1131 // math on arm). So if it was not passed on the command line and
1132 // it is not present in another shared library, add it here.
1133 _, gccgo := buildToolchain.(gccgoToolchain)
1134 if !gccgo {
1135 seencgo := false
1136 for _, p := range pkgs {
1137 seencgo = seencgo || (p.Standard && p.ImportPath == "runtime/cgo")
1139 if !seencgo {
1140 var stk importStack
1141 p := loadPackage("runtime/cgo", &stk)
1142 if p.Error != nil {
1143 fatalf("load runtime/cgo: %v", p.Error)
1145 computeStale(p)
1146 // If runtime/cgo is in another shared library, then that's
1147 // also the shared library that contains runtime, so
1148 // something will depend on it and so runtime/cgo's staleness
1149 // will be checked when processing that library.
1150 if p.Shlib == "" || p.Shlib == libname {
1151 pkgs = append([]*Package{}, pkgs...)
1152 pkgs = append(pkgs, p)
1155 if goarch == "arm" {
1156 seenmath := false
1157 for _, p := range pkgs {
1158 seenmath = seenmath || (p.Standard && p.ImportPath == "math")
1160 if !seenmath {
1161 var stk importStack
1162 p := loadPackage("math", &stk)
1163 if p.Error != nil {
1164 fatalf("load math: %v", p.Error)
1166 computeStale(p)
1167 // If math is in another shared library, then that's
1168 // also the shared library that contains runtime, so
1169 // something will depend on it and so math's staleness
1170 // will be checked when processing that library.
1171 if p.Shlib == "" || p.Shlib == libname {
1172 pkgs = append([]*Package{}, pkgs...)
1173 pkgs = append(pkgs, p)
1179 // Figure out where the library will go.
1180 var libdir string
1181 for _, p := range pkgs {
1182 plibdir := p.build.PkgTargetRoot
1183 if gccgo {
1184 plibdir = filepath.Join(plibdir, "shlibs")
1186 if libdir == "" {
1187 libdir = plibdir
1188 } else if libdir != plibdir {
1189 fatalf("multiple roots %s & %s", libdir, plibdir)
1192 a.target = filepath.Join(libdir, libname)
1194 // Now we can check whether we need to rebuild it.
1195 stale := false
1196 var built time.Time
1197 if fi, err := os.Stat(a.target); err == nil {
1198 built = fi.ModTime()
1200 for _, p := range pkgs {
1201 if p.target == "" {
1202 continue
1204 stale = stale || p.Stale
1205 lstat, err := os.Stat(p.target)
1206 if err != nil || lstat.ModTime().After(built) {
1207 stale = true
1209 a.deps = append(a.deps, b.action1(depMode, depMode, p, false, a.target))
1212 if stale {
1213 a.f = (*builder).install
1214 buildAction := b.libaction(libname, pkgs, modeBuild, depMode)
1215 a.deps = []*action{buildAction}
1216 for _, p := range pkgs {
1217 if p.target == "" {
1218 continue
1220 shlibnameaction := &action{}
1221 shlibnameaction.f = (*builder).installShlibname
1222 shlibnameaction.target = p.target[:len(p.target)-2] + ".shlibname"
1223 a.deps = append(a.deps, shlibnameaction)
1224 shlibnameaction.deps = append(shlibnameaction.deps, buildAction)
1228 return a
1231 // actionList returns the list of actions in the dag rooted at root
1232 // as visited in a depth-first post-order traversal.
1233 func actionList(root *action) []*action {
1234 seen := map[*action]bool{}
1235 all := []*action{}
1236 var walk func(*action)
1237 walk = func(a *action) {
1238 if seen[a] {
1239 return
1241 seen[a] = true
1242 for _, a1 := range a.deps {
1243 walk(a1)
1245 all = append(all, a)
1247 walk(root)
1248 return all
1251 // allArchiveActions returns a list of the archive dependencies of root.
1252 // This is needed because if package p depends on package q that is in libr.so, the
1253 // action graph looks like p->libr.so->q and so just scanning through p's
1254 // dependencies does not find the import dir for q.
1255 func allArchiveActions(root *action) []*action {
1256 seen := map[*action]bool{}
1257 r := []*action{}
1258 var walk func(*action)
1259 walk = func(a *action) {
1260 if seen[a] {
1261 return
1263 seen[a] = true
1264 if strings.HasSuffix(a.target, ".so") || a == root {
1265 for _, a1 := range a.deps {
1266 walk(a1)
1268 } else if strings.HasSuffix(a.target, ".a") {
1269 r = append(r, a)
1272 walk(root)
1273 return r
1276 // do runs the action graph rooted at root.
1277 func (b *builder) do(root *action) {
1278 /* Commented out for gccgo, which does not have osArchSupportsCgo.
1280 if _, ok := osArchSupportsCgo[goos+"/"+goarch]; !ok && buildContext.Compiler == "gc" {
1281 fmt.Fprintf(os.Stderr, "cmd/go: unsupported GOOS/GOARCH pair %s/%s\n", goos, goarch)
1282 os.Exit(2)
1286 // Build list of all actions, assigning depth-first post-order priority.
1287 // The original implementation here was a true queue
1288 // (using a channel) but it had the effect of getting
1289 // distracted by low-level leaf actions to the detriment
1290 // of completing higher-level actions. The order of
1291 // work does not matter much to overall execution time,
1292 // but when running "go test std" it is nice to see each test
1293 // results as soon as possible. The priorities assigned
1294 // ensure that, all else being equal, the execution prefers
1295 // to do what it would have done first in a simple depth-first
1296 // dependency order traversal.
1297 all := actionList(root)
1298 for i, a := range all {
1299 a.priority = i
1302 b.readySema = make(chan bool, len(all))
1304 // Initialize per-action execution state.
1305 for _, a := range all {
1306 for _, a1 := range a.deps {
1307 a1.triggers = append(a1.triggers, a)
1309 a.pending = len(a.deps)
1310 if a.pending == 0 {
1311 b.ready.push(a)
1312 b.readySema <- true
1316 // Handle runs a single action and takes care of triggering
1317 // any actions that are runnable as a result.
1318 handle := func(a *action) {
1319 var err error
1320 if a.f != nil && (!a.failed || a.ignoreFail) {
1321 err = a.f(b, a)
1324 // The actions run in parallel but all the updates to the
1325 // shared work state are serialized through b.exec.
1326 b.exec.Lock()
1327 defer b.exec.Unlock()
1329 if err != nil {
1330 if err == errPrintedOutput {
1331 setExitStatus(2)
1332 } else if _, ok := err.(*build.NoGoError); ok && len(a.p.TestGoFiles) > 0 && b.testFilesOnlyOK {
1333 // Ignore the "no buildable Go source files" error for a package with only test files.
1334 } else {
1335 errorf("%s", err)
1337 a.failed = true
1340 for _, a0 := range a.triggers {
1341 if a.failed {
1342 a0.failed = true
1344 if a0.pending--; a0.pending == 0 {
1345 b.ready.push(a0)
1346 b.readySema <- true
1350 if a == root {
1351 close(b.readySema)
1355 var wg sync.WaitGroup
1357 // Kick off goroutines according to parallelism.
1358 // If we are using the -n flag (just printing commands)
1359 // drop the parallelism to 1, both to make the output
1360 // deterministic and because there is no real work anyway.
1361 par := buildP
1362 if buildN {
1363 par = 1
1365 for i := 0; i < par; i++ {
1366 wg.Add(1)
1367 go func() {
1368 defer wg.Done()
1369 for {
1370 select {
1371 case _, ok := <-b.readySema:
1372 if !ok {
1373 return
1375 // Receiving a value from b.readySema entitles
1376 // us to take from the ready queue.
1377 b.exec.Lock()
1378 a := b.ready.pop()
1379 b.exec.Unlock()
1380 handle(a)
1381 case <-interrupted:
1382 setExitStatus(1)
1383 return
1389 wg.Wait()
1392 // build is the action for building a single package or command.
1393 func (b *builder) build(a *action) (err error) {
1394 // Return an error for binary-only package.
1395 // We only reach this if isStale believes the binary form is
1396 // either not present or not usable.
1397 if a.p.BinaryOnly {
1398 return fmt.Errorf("missing or invalid package binary for binary-only package %s", a.p.ImportPath)
1401 // Return an error if the package has CXX files but it's not using
1402 // cgo nor SWIG, since the CXX files can only be processed by cgo
1403 // and SWIG.
1404 if len(a.p.CXXFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
1405 return fmt.Errorf("can't build package %s because it contains C++ files (%s) but it's not using cgo nor SWIG",
1406 a.p.ImportPath, strings.Join(a.p.CXXFiles, ","))
1408 // Same as above for Objective-C files
1409 if len(a.p.MFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
1410 return fmt.Errorf("can't build package %s because it contains Objective-C files (%s) but it's not using cgo nor SWIG",
1411 a.p.ImportPath, strings.Join(a.p.MFiles, ","))
1413 // Same as above for Fortran files
1414 if len(a.p.FFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
1415 return fmt.Errorf("can't build package %s because it contains Fortran files (%s) but it's not using cgo nor SWIG",
1416 a.p.ImportPath, strings.Join(a.p.FFiles, ","))
1419 defer func() {
1420 if _, ok := err.(*build.NoGoError); err != nil && err != errPrintedOutput && !(ok && b.testFilesOnlyOK && len(a.p.TestGoFiles) > 0) {
1421 err = fmt.Errorf("go build %s: %v", a.p.ImportPath, err)
1424 if buildN {
1425 // In -n mode, print a banner between packages.
1426 // The banner is five lines so that when changes to
1427 // different sections of the bootstrap script have to
1428 // be merged, the banners give patch something
1429 // to use to find its context.
1430 b.print("\n#\n# " + a.p.ImportPath + "\n#\n\n")
1433 if buildV {
1434 b.print(a.p.ImportPath + "\n")
1437 // Make build directory.
1438 obj := a.objdir
1439 if err := b.mkdir(obj); err != nil {
1440 return err
1443 // make target directory
1444 dir, _ := filepath.Split(a.target)
1445 if dir != "" {
1446 if err := b.mkdir(dir); err != nil {
1447 return err
1451 var gofiles, cgofiles, objdirCgofiles, cfiles, sfiles, cxxfiles, objects, cgoObjects, pcCFLAGS, pcLDFLAGS []string
1453 gofiles = append(gofiles, a.p.GoFiles...)
1454 cgofiles = append(cgofiles, a.p.CgoFiles...)
1455 cfiles = append(cfiles, a.p.CFiles...)
1456 sfiles = append(sfiles, a.p.SFiles...)
1457 cxxfiles = append(cxxfiles, a.p.CXXFiles...)
1459 if a.p.usesCgo() || a.p.usesSwig() {
1460 if pcCFLAGS, pcLDFLAGS, err = b.getPkgConfigFlags(a.p); err != nil {
1461 return
1465 // Run SWIG on each .swig and .swigcxx file.
1466 // Each run will generate two files, a .go file and a .c or .cxx file.
1467 // The .go file will use import "C" and is to be processed by cgo.
1468 if a.p.usesSwig() {
1469 outGo, outC, outCXX, err := b.swig(a.p, obj, pcCFLAGS)
1470 if err != nil {
1471 return err
1473 objdirCgofiles = append(objdirCgofiles, outGo...)
1474 cfiles = append(cfiles, outC...)
1475 cxxfiles = append(cxxfiles, outCXX...)
1478 // Run cgo.
1479 if a.p.usesCgo() || a.p.usesSwig() {
1480 // In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
1481 // There is one exception: runtime/cgo's job is to bridge the
1482 // cgo and non-cgo worlds, so it necessarily has files in both.
1483 // In that case gcc only gets the gcc_* files.
1484 var gccfiles []string
1485 gccfiles = append(gccfiles, cfiles...)
1486 cfiles = nil
1487 if a.p.Standard && a.p.ImportPath == "runtime/cgo" {
1488 filter := func(files, nongcc, gcc []string) ([]string, []string) {
1489 for _, f := range files {
1490 if strings.HasPrefix(f, "gcc_") {
1491 gcc = append(gcc, f)
1492 } else {
1493 nongcc = append(nongcc, f)
1496 return nongcc, gcc
1498 sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles)
1499 } else {
1500 gccfiles = append(gccfiles, sfiles...)
1501 sfiles = nil
1504 cgoExe := tool("cgo")
1505 if a.cgo != nil && a.cgo.target != "" {
1506 cgoExe = a.cgo.target
1508 outGo, outObj, err := b.cgo(a, cgoExe, obj, pcCFLAGS, pcLDFLAGS, cgofiles, objdirCgofiles, gccfiles, cxxfiles, a.p.MFiles, a.p.FFiles)
1509 if err != nil {
1510 return err
1512 if _, ok := buildToolchain.(gccgoToolchain); ok {
1513 cgoObjects = append(cgoObjects, filepath.Join(a.objdir, "_cgo_flags"))
1515 cgoObjects = append(cgoObjects, outObj...)
1516 gofiles = append(gofiles, outGo...)
1519 if len(gofiles) == 0 {
1520 return &build.NoGoError{Dir: a.p.Dir}
1523 // If we're doing coverage, preprocess the .go files and put them in the work directory
1524 if a.p.coverMode != "" {
1525 for i, file := range gofiles {
1526 var sourceFile string
1527 var coverFile string
1528 var key string
1529 if strings.HasSuffix(file, ".cgo1.go") {
1530 // cgo files have absolute paths
1531 base := filepath.Base(file)
1532 sourceFile = file
1533 coverFile = filepath.Join(obj, base)
1534 key = strings.TrimSuffix(base, ".cgo1.go") + ".go"
1535 } else {
1536 sourceFile = filepath.Join(a.p.Dir, file)
1537 coverFile = filepath.Join(obj, file)
1538 key = file
1540 cover := a.p.coverVars[key]
1541 if cover == nil || isTestFile(file) {
1542 // Not covering this file.
1543 continue
1545 if err := b.cover(a, coverFile, sourceFile, 0666, cover.Var); err != nil {
1546 return err
1548 gofiles[i] = coverFile
1552 // Prepare Go import path list.
1553 inc := b.includeArgs("-I", allArchiveActions(a))
1555 // Compile Go.
1556 ofile, out, err := buildToolchain.gc(b, a.p, a.objpkg, obj, len(sfiles) > 0, inc, gofiles)
1557 if len(out) > 0 {
1558 b.showOutput(a.p.Dir, a.p.ImportPath, b.processOutput(out))
1559 if err != nil {
1560 return errPrintedOutput
1563 if err != nil {
1564 return err
1566 if ofile != a.objpkg {
1567 objects = append(objects, ofile)
1570 // Copy .h files named for goos or goarch or goos_goarch
1571 // to names using GOOS and GOARCH.
1572 // For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
1573 _goos_goarch := "_" + goos + "_" + goarch
1574 _goos := "_" + goos
1575 _goarch := "_" + goarch
1576 for _, file := range a.p.HFiles {
1577 name, ext := fileExtSplit(file)
1578 switch {
1579 case strings.HasSuffix(name, _goos_goarch):
1580 targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext
1581 if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666, true); err != nil {
1582 return err
1584 case strings.HasSuffix(name, _goarch):
1585 targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext
1586 if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666, true); err != nil {
1587 return err
1589 case strings.HasSuffix(name, _goos):
1590 targ := file[:len(name)-len(_goos)] + "_GOOS." + ext
1591 if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666, true); err != nil {
1592 return err
1597 for _, file := range cfiles {
1598 out := file[:len(file)-len(".c")] + ".o"
1599 if err := buildToolchain.cc(b, a.p, obj, obj+out, file); err != nil {
1600 return err
1602 objects = append(objects, out)
1605 // Assemble .s files.
1606 if len(sfiles) > 0 {
1607 ofiles, err := buildToolchain.asm(b, a.p, obj, sfiles)
1608 if err != nil {
1609 return err
1611 objects = append(objects, ofiles...)
1614 // NOTE(rsc): On Windows, it is critically important that the
1615 // gcc-compiled objects (cgoObjects) be listed after the ordinary
1616 // objects in the archive. I do not know why this is.
1617 // https://golang.org/issue/2601
1618 objects = append(objects, cgoObjects...)
1620 // Add system object files.
1621 for _, syso := range a.p.SysoFiles {
1622 objects = append(objects, filepath.Join(a.p.Dir, syso))
1625 // Pack into archive in obj directory.
1626 // If the Go compiler wrote an archive, we only need to add the
1627 // object files for non-Go sources to the archive.
1628 // If the Go compiler wrote an archive and the package is entirely
1629 // Go sources, there is no pack to execute at all.
1630 if len(objects) > 0 {
1631 if err := buildToolchain.pack(b, a.p, obj, a.objpkg, objects); err != nil {
1632 return err
1636 // Link if needed.
1637 if a.link {
1638 // The compiler only cares about direct imports, but the
1639 // linker needs the whole dependency tree.
1640 all := actionList(a)
1641 all = all[:len(all)-1] // drop a
1642 if err := buildToolchain.ld(b, a, a.target, all, a.objpkg, objects); err != nil {
1643 return err
1647 return nil
1650 // pkgconfigCmd returns a pkg-config binary name
1651 // defaultPkgConfig is defined in zdefaultcc.go, written by cmd/dist.
1652 func (b *builder) pkgconfigCmd() string {
1653 return envList("PKG_CONFIG", defaultPkgConfig)[0]
1656 // splitPkgConfigOutput parses the pkg-config output into a slice of
1657 // flags. pkg-config always uses \ to escape special characters.
1658 func splitPkgConfigOutput(out []byte) []string {
1659 if len(out) == 0 {
1660 return nil
1662 var flags []string
1663 flag := make([]byte, len(out))
1664 r, w := 0, 0
1665 for r < len(out) {
1666 switch out[r] {
1667 case ' ', '\t', '\r', '\n':
1668 if w > 0 {
1669 flags = append(flags, string(flag[:w]))
1671 w = 0
1672 case '\\':
1674 fallthrough
1675 default:
1676 if r < len(out) {
1677 flag[w] = out[r]
1683 if w > 0 {
1684 flags = append(flags, string(flag[:w]))
1686 return flags
1689 // Calls pkg-config if needed and returns the cflags/ldflags needed to build the package.
1690 func (b *builder) getPkgConfigFlags(p *Package) (cflags, ldflags []string, err error) {
1691 if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
1692 var out []byte
1693 out, err = b.runOut(p.Dir, p.ImportPath, nil, b.pkgconfigCmd(), "--cflags", pkgs)
1694 if err != nil {
1695 b.showOutput(p.Dir, b.pkgconfigCmd()+" --cflags "+strings.Join(pkgs, " "), string(out))
1696 b.print(err.Error() + "\n")
1697 err = errPrintedOutput
1698 return
1700 if len(out) > 0 {
1701 cflags = splitPkgConfigOutput(out)
1703 out, err = b.runOut(p.Dir, p.ImportPath, nil, b.pkgconfigCmd(), "--libs", pkgs)
1704 if err != nil {
1705 b.showOutput(p.Dir, b.pkgconfigCmd()+" --libs "+strings.Join(pkgs, " "), string(out))
1706 b.print(err.Error() + "\n")
1707 err = errPrintedOutput
1708 return
1710 if len(out) > 0 {
1711 ldflags = strings.Fields(string(out))
1714 return
1717 func (b *builder) installShlibname(a *action) error {
1718 a1 := a.deps[0]
1719 err := ioutil.WriteFile(a.target, []byte(filepath.Base(a1.target)+"\n"), 0666)
1720 if err != nil {
1721 return err
1723 if buildX {
1724 b.showcmd("", "echo '%s' > %s # internal", filepath.Base(a1.target), a.target)
1726 return nil
1729 func (b *builder) linkShared(a *action) (err error) {
1730 allactions := actionList(a)
1731 allactions = allactions[:len(allactions)-1]
1732 return buildToolchain.ldShared(b, a.deps, a.target, allactions)
1735 // install is the action for installing a single package or executable.
1736 func (b *builder) install(a *action) (err error) {
1737 defer func() {
1738 if err != nil && err != errPrintedOutput {
1739 err = fmt.Errorf("go install %s: %v", a.p.ImportPath, err)
1742 a1 := a.deps[0]
1743 perm := os.FileMode(0666)
1744 if a1.link {
1745 switch buildBuildmode {
1746 case "c-archive", "c-shared", "plugin":
1747 default:
1748 perm = 0777
1752 // make target directory
1753 dir, _ := filepath.Split(a.target)
1754 if dir != "" {
1755 if err := b.mkdir(dir); err != nil {
1756 return err
1760 // remove object dir to keep the amount of
1761 // garbage down in a large build. On an operating system
1762 // with aggressive buffering, cleaning incrementally like
1763 // this keeps the intermediate objects from hitting the disk.
1764 if !buildWork {
1765 defer os.RemoveAll(a1.objdir)
1766 defer os.Remove(a1.target)
1769 return b.moveOrCopyFile(a, a.target, a1.target, perm, false)
1772 // includeArgs returns the -I or -L directory list for access
1773 // to the results of the list of actions.
1774 func (b *builder) includeArgs(flag string, all []*action) []string {
1775 inc := []string{}
1776 incMap := map[string]bool{
1777 b.work: true, // handled later
1778 gorootPkg: true,
1779 "": true, // ignore empty strings
1782 // Look in the temporary space for results of test-specific actions.
1783 // This is the $WORK/my/package/_test directory for the
1784 // package being built, so there are few of these.
1785 for _, a1 := range all {
1786 if a1.p == nil {
1787 continue
1789 if dir := a1.pkgdir; dir != a1.p.build.PkgRoot && !incMap[dir] {
1790 incMap[dir] = true
1791 inc = append(inc, flag, dir)
1795 // Also look in $WORK for any non-test packages that have
1796 // been built but not installed.
1797 inc = append(inc, flag, b.work)
1799 // Finally, look in the installed package directories for each action.
1800 // First add the package dirs corresponding to GOPATH entries
1801 // in the original GOPATH order.
1802 need := map[string]*build.Package{}
1803 for _, a1 := range all {
1804 if a1.p != nil && a1.pkgdir == a1.p.build.PkgRoot {
1805 need[a1.p.build.Root] = a1.p.build
1808 for _, root := range gopath {
1809 if p := need[root]; p != nil && !incMap[p.PkgRoot] {
1810 incMap[p.PkgRoot] = true
1811 inc = append(inc, flag, p.PkgTargetRoot)
1815 // Then add anything that's left.
1816 for _, a1 := range all {
1817 if a1.p == nil {
1818 continue
1820 if dir := a1.pkgdir; dir == a1.p.build.PkgRoot && !incMap[dir] {
1821 incMap[dir] = true
1822 inc = append(inc, flag, a1.p.build.PkgTargetRoot)
1826 return inc
1829 // moveOrCopyFile is like 'mv src dst' or 'cp src dst'.
1830 func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode, force bool) error {
1831 if buildN {
1832 b.showcmd("", "mv %s %s", src, dst)
1833 return nil
1836 // If we can update the mode and rename to the dst, do it.
1837 // Otherwise fall back to standard copy.
1839 // The perm argument is meant to be adjusted according to umask,
1840 // but we don't know what the umask is.
1841 // Create a dummy file to find out.
1842 // This avoids build tags and works even on systems like Plan 9
1843 // where the file mask computation incorporates other information.
1844 mode := perm
1845 f, err := os.OpenFile(filepath.Clean(dst)+"-go-tmp-umask", os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm)
1846 if err == nil {
1847 fi, err := f.Stat()
1848 if err == nil {
1849 mode = fi.Mode() & 0777
1851 name := f.Name()
1852 f.Close()
1853 os.Remove(name)
1856 if err := os.Chmod(src, mode); err == nil {
1857 if err := os.Rename(src, dst); err == nil {
1858 if buildX {
1859 b.showcmd("", "mv %s %s", src, dst)
1861 return nil
1865 return b.copyFile(a, dst, src, perm, force)
1868 // copyFile is like 'cp src dst'.
1869 func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode, force bool) error {
1870 if buildN || buildX {
1871 b.showcmd("", "cp %s %s", src, dst)
1872 if buildN {
1873 return nil
1877 sf, err := os.Open(src)
1878 if err != nil {
1879 return err
1881 defer sf.Close()
1883 // Be careful about removing/overwriting dst.
1884 // Do not remove/overwrite if dst exists and is a directory
1885 // or a non-object file.
1886 if fi, err := os.Stat(dst); err == nil {
1887 if fi.IsDir() {
1888 return fmt.Errorf("build output %q already exists and is a directory", dst)
1890 if !force && fi.Mode().IsRegular() && !isObject(dst) {
1891 return fmt.Errorf("build output %q already exists and is not an object file", dst)
1895 // On Windows, remove lingering ~ file from last attempt.
1896 if toolIsWindows {
1897 if _, err := os.Stat(dst + "~"); err == nil {
1898 os.Remove(dst + "~")
1902 mayberemovefile(dst)
1903 df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
1904 if err != nil && toolIsWindows {
1905 // Windows does not allow deletion of a binary file
1906 // while it is executing. Try to move it out of the way.
1907 // If the move fails, which is likely, we'll try again the
1908 // next time we do an install of this binary.
1909 if err := os.Rename(dst, dst+"~"); err == nil {
1910 os.Remove(dst + "~")
1912 df, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
1914 if err != nil {
1915 return err
1918 _, err = io.Copy(df, sf)
1919 df.Close()
1920 if err != nil {
1921 mayberemovefile(dst)
1922 return fmt.Errorf("copying %s to %s: %v", src, dst, err)
1924 return nil
1927 // Install the cgo export header file, if there is one.
1928 func (b *builder) installHeader(a *action) error {
1929 src := a.objdir + "_cgo_install.h"
1930 if _, err := os.Stat(src); os.IsNotExist(err) {
1931 // If the file does not exist, there are no exported
1932 // functions, and we do not install anything.
1933 return nil
1936 dir, _ := filepath.Split(a.target)
1937 if dir != "" {
1938 if err := b.mkdir(dir); err != nil {
1939 return err
1943 return b.moveOrCopyFile(a, a.target, src, 0666, true)
1946 // cover runs, in effect,
1947 // go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
1948 func (b *builder) cover(a *action, dst, src string, perm os.FileMode, varName string) error {
1949 return b.run(a.objdir, "cover "+a.p.ImportPath, nil,
1950 buildToolExec,
1951 tool("cover"),
1952 "-mode", a.p.coverMode,
1953 "-var", varName,
1954 "-o", dst,
1955 src)
1958 var objectMagic = [][]byte{
1959 {'!', '<', 'a', 'r', 'c', 'h', '>', '\n'}, // Package archive
1960 {'\x7F', 'E', 'L', 'F'}, // ELF
1961 {0xFE, 0xED, 0xFA, 0xCE}, // Mach-O big-endian 32-bit
1962 {0xFE, 0xED, 0xFA, 0xCF}, // Mach-O big-endian 64-bit
1963 {0xCE, 0xFA, 0xED, 0xFE}, // Mach-O little-endian 32-bit
1964 {0xCF, 0xFA, 0xED, 0xFE}, // Mach-O little-endian 64-bit
1965 {0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00}, // PE (Windows) as generated by 6l/8l and gcc
1966 {0x00, 0x00, 0x01, 0xEB}, // Plan 9 i386
1967 {0x00, 0x00, 0x8a, 0x97}, // Plan 9 amd64
1968 {0x00, 0x00, 0x06, 0x47}, // Plan 9 arm
1971 func isObject(s string) bool {
1972 f, err := os.Open(s)
1973 if err != nil {
1974 return false
1976 defer f.Close()
1977 buf := make([]byte, 64)
1978 io.ReadFull(f, buf)
1979 for _, magic := range objectMagic {
1980 if bytes.HasPrefix(buf, magic) {
1981 return true
1984 return false
1987 // mayberemovefile removes a file only if it is a regular file
1988 // When running as a user with sufficient privileges, we may delete
1989 // even device files, for example, which is not intended.
1990 func mayberemovefile(s string) {
1991 if fi, err := os.Lstat(s); err == nil && !fi.Mode().IsRegular() {
1992 return
1994 os.Remove(s)
1997 // fmtcmd formats a command in the manner of fmt.Sprintf but also:
1999 // If dir is non-empty and the script is not in dir right now,
2000 // fmtcmd inserts "cd dir\n" before the command.
2002 // fmtcmd replaces the value of b.work with $WORK.
2003 // fmtcmd replaces the value of goroot with $GOROOT.
2004 // fmtcmd replaces the value of b.gobin with $GOBIN.
2006 // fmtcmd replaces the name of the current directory with dot (.)
2007 // but only when it is at the beginning of a space-separated token.
2009 func (b *builder) fmtcmd(dir string, format string, args ...interface{}) string {
2010 cmd := fmt.Sprintf(format, args...)
2011 if dir != "" && dir != "/" {
2012 cmd = strings.Replace(" "+cmd, " "+dir, " .", -1)[1:]
2013 if b.scriptDir != dir {
2014 b.scriptDir = dir
2015 cmd = "cd " + dir + "\n" + cmd
2018 if b.work != "" {
2019 cmd = strings.Replace(cmd, b.work, "$WORK", -1)
2021 return cmd
2024 // showcmd prints the given command to standard output
2025 // for the implementation of -n or -x.
2026 func (b *builder) showcmd(dir string, format string, args ...interface{}) {
2027 b.output.Lock()
2028 defer b.output.Unlock()
2029 b.print(b.fmtcmd(dir, format, args...) + "\n")
2032 // showOutput prints "# desc" followed by the given output.
2033 // The output is expected to contain references to 'dir', usually
2034 // the source directory for the package that has failed to build.
2035 // showOutput rewrites mentions of dir with a relative path to dir
2036 // when the relative path is shorter. This is usually more pleasant.
2037 // For example, if fmt doesn't compile and we are in src/html,
2038 // the output is
2040 // $ go build
2041 // # fmt
2042 // ../fmt/print.go:1090: undefined: asdf
2043 // $
2045 // instead of
2047 // $ go build
2048 // # fmt
2049 // /usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
2050 // $
2052 // showOutput also replaces references to the work directory with $WORK.
2054 func (b *builder) showOutput(dir, desc, out string) {
2055 prefix := "# " + desc
2056 suffix := "\n" + out
2057 if reldir := shortPath(dir); reldir != dir {
2058 suffix = strings.Replace(suffix, " "+dir, " "+reldir, -1)
2059 suffix = strings.Replace(suffix, "\n"+dir, "\n"+reldir, -1)
2061 suffix = strings.Replace(suffix, " "+b.work, " $WORK", -1)
2063 b.output.Lock()
2064 defer b.output.Unlock()
2065 b.print(prefix, suffix)
2068 // shortPath returns an absolute or relative name for path, whatever is shorter.
2069 func shortPath(path string) string {
2070 if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) {
2071 return rel
2073 return path
2076 // relPaths returns a copy of paths with absolute paths
2077 // made relative to the current directory if they would be shorter.
2078 func relPaths(paths []string) []string {
2079 var out []string
2080 pwd, _ := os.Getwd()
2081 for _, p := range paths {
2082 rel, err := filepath.Rel(pwd, p)
2083 if err == nil && len(rel) < len(p) {
2084 p = rel
2086 out = append(out, p)
2088 return out
2091 // errPrintedOutput is a special error indicating that a command failed
2092 // but that it generated output as well, and that output has already
2093 // been printed, so there's no point showing 'exit status 1' or whatever
2094 // the wait status was. The main executor, builder.do, knows not to
2095 // print this error.
2096 var errPrintedOutput = errors.New("already printed output - no need to show error")
2098 var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.cgo1\.go:[0-9]+\]`)
2099 var cgoTypeSigRe = regexp.MustCompile(`\b_Ctype_\B`)
2101 // run runs the command given by cmdline in the directory dir.
2102 // If the command fails, run prints information about the failure
2103 // and returns a non-nil error.
2104 func (b *builder) run(dir string, desc string, env []string, cmdargs ...interface{}) error {
2105 out, err := b.runOut(dir, desc, env, cmdargs...)
2106 if len(out) > 0 {
2107 if desc == "" {
2108 desc = b.fmtcmd(dir, "%s", strings.Join(stringList(cmdargs...), " "))
2110 b.showOutput(dir, desc, b.processOutput(out))
2111 if err != nil {
2112 err = errPrintedOutput
2115 return err
2118 // processOutput prepares the output of runOut to be output to the console.
2119 func (b *builder) processOutput(out []byte) string {
2120 if out[len(out)-1] != '\n' {
2121 out = append(out, '\n')
2123 messages := string(out)
2124 // Fix up output referring to cgo-generated code to be more readable.
2125 // Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
2126 // Replace *[100]_Ctype_foo with *[100]C.foo.
2127 // If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
2128 if !buildX && cgoLine.MatchString(messages) {
2129 messages = cgoLine.ReplaceAllString(messages, "")
2130 messages = cgoTypeSigRe.ReplaceAllString(messages, "C.")
2132 return messages
2135 // runOut runs the command given by cmdline in the directory dir.
2136 // It returns the command output and any errors that occurred.
2137 func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) {
2138 cmdline := stringList(cmdargs...)
2139 if buildN || buildX {
2140 var envcmdline string
2141 for i := range env {
2142 envcmdline += env[i]
2143 envcmdline += " "
2145 envcmdline += joinUnambiguously(cmdline)
2146 b.showcmd(dir, "%s", envcmdline)
2147 if buildN {
2148 return nil, nil
2152 nbusy := 0
2153 for {
2154 var buf bytes.Buffer
2155 cmd := exec.Command(cmdline[0], cmdline[1:]...)
2156 cmd.Stdout = &buf
2157 cmd.Stderr = &buf
2158 cmd.Dir = dir
2159 cmd.Env = mergeEnvLists(env, envForDir(cmd.Dir, os.Environ()))
2160 err := cmd.Run()
2162 // cmd.Run will fail on Unix if some other process has the binary
2163 // we want to run open for writing. This can happen here because
2164 // we build and install the cgo command and then run it.
2165 // If another command was kicked off while we were writing the
2166 // cgo binary, the child process for that command may be holding
2167 // a reference to the fd, keeping us from running exec.
2169 // But, you might reasonably wonder, how can this happen?
2170 // The cgo fd, like all our fds, is close-on-exec, so that we need
2171 // not worry about other processes inheriting the fd accidentally.
2172 // The answer is that running a command is fork and exec.
2173 // A child forked while the cgo fd is open inherits that fd.
2174 // Until the child has called exec, it holds the fd open and the
2175 // kernel will not let us run cgo. Even if the child were to close
2176 // the fd explicitly, it would still be open from the time of the fork
2177 // until the time of the explicit close, and the race would remain.
2179 // On Unix systems, this results in ETXTBSY, which formats
2180 // as "text file busy". Rather than hard-code specific error cases,
2181 // we just look for that string. If this happens, sleep a little
2182 // and try again. We let this happen three times, with increasing
2183 // sleep lengths: 100+200+400 ms = 0.7 seconds.
2185 // An alternate solution might be to split the cmd.Run into
2186 // separate cmd.Start and cmd.Wait, and then use an RWLock
2187 // to make sure that copyFile only executes when no cmd.Start
2188 // call is in progress. However, cmd.Start (really syscall.forkExec)
2189 // only guarantees that when it returns, the exec is committed to
2190 // happen and succeed. It uses a close-on-exec file descriptor
2191 // itself to determine this, so we know that when cmd.Start returns,
2192 // at least one close-on-exec file descriptor has been closed.
2193 // However, we cannot be sure that all of them have been closed,
2194 // so the program might still encounter ETXTBSY even with such
2195 // an RWLock. The race window would be smaller, perhaps, but not
2196 // guaranteed to be gone.
2198 // Sleeping when we observe the race seems to be the most reliable
2199 // option we have.
2201 // https://golang.org/issue/3001
2203 if err != nil && nbusy < 3 && strings.Contains(err.Error(), "text file busy") {
2204 time.Sleep(100 * time.Millisecond << uint(nbusy))
2205 nbusy++
2206 continue
2209 // err can be something like 'exit status 1'.
2210 // Add information about what program was running.
2211 // Note that if buf.Bytes() is non-empty, the caller usually
2212 // shows buf.Bytes() and does not print err at all, so the
2213 // prefix here does not make most output any more verbose.
2214 if err != nil {
2215 err = errors.New(cmdline[0] + ": " + err.Error())
2217 return buf.Bytes(), err
2221 // joinUnambiguously prints the slice, quoting where necessary to make the
2222 // output unambiguous.
2223 // TODO: See issue 5279. The printing of commands needs a complete redo.
2224 func joinUnambiguously(a []string) string {
2225 var buf bytes.Buffer
2226 for i, s := range a {
2227 if i > 0 {
2228 buf.WriteByte(' ')
2230 q := strconv.Quote(s)
2231 if s == "" || strings.Contains(s, " ") || len(q) > len(s)+2 {
2232 buf.WriteString(q)
2233 } else {
2234 buf.WriteString(s)
2237 return buf.String()
2240 // mkdir makes the named directory.
2241 func (b *builder) mkdir(dir string) error {
2242 b.exec.Lock()
2243 defer b.exec.Unlock()
2244 // We can be a little aggressive about being
2245 // sure directories exist. Skip repeated calls.
2246 if b.mkdirCache[dir] {
2247 return nil
2249 b.mkdirCache[dir] = true
2251 if buildN || buildX {
2252 b.showcmd("", "mkdir -p %s", dir)
2253 if buildN {
2254 return nil
2258 if err := os.MkdirAll(dir, 0777); err != nil {
2259 return err
2261 return nil
2264 // mkAbs returns an absolute path corresponding to
2265 // evaluating f in the directory dir.
2266 // We always pass absolute paths of source files so that
2267 // the error messages will include the full path to a file
2268 // in need of attention.
2269 func mkAbs(dir, f string) string {
2270 // Leave absolute paths alone.
2271 // Also, during -n mode we use the pseudo-directory $WORK
2272 // instead of creating an actual work directory that won't be used.
2273 // Leave paths beginning with $WORK alone too.
2274 if filepath.IsAbs(f) || strings.HasPrefix(f, "$WORK") {
2275 return f
2277 return filepath.Join(dir, f)
2280 type toolchain interface {
2281 // gc runs the compiler in a specific directory on a set of files
2282 // and returns the name of the generated output file.
2283 gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error)
2284 // cc runs the toolchain's C compiler in a directory on a C file
2285 // to produce an output file.
2286 cc(b *builder, p *Package, objdir, ofile, cfile string) error
2287 // asm runs the assembler in a specific directory on specific files
2288 // and returns a list of named output files.
2289 asm(b *builder, p *Package, obj string, sfiles []string) ([]string, error)
2290 // pkgpath builds an appropriate path for a temporary package file.
2291 pkgpath(basedir string, p *Package) string
2292 // pack runs the archive packer in a specific directory to create
2293 // an archive from a set of object files.
2294 // typically it is run in the object directory.
2295 pack(b *builder, p *Package, objDir, afile string, ofiles []string) error
2296 // ld runs the linker to create an executable starting at mainpkg.
2297 ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error
2298 // ldShared runs the linker to create a shared library containing the pkgs built by toplevelactions
2299 ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error
2301 compiler() string
2302 linker() string
2305 type noToolchain struct{}
2307 func noCompiler() error {
2308 log.Fatalf("unknown compiler %q", buildContext.Compiler)
2309 return nil
2312 func (noToolchain) compiler() string {
2313 noCompiler()
2314 return ""
2317 func (noToolchain) linker() string {
2318 noCompiler()
2319 return ""
2322 func (noToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error) {
2323 return "", nil, noCompiler()
2326 func (noToolchain) asm(b *builder, p *Package, obj string, sfiles []string) ([]string, error) {
2327 return nil, noCompiler()
2330 func (noToolchain) pkgpath(basedir string, p *Package) string {
2331 noCompiler()
2332 return ""
2335 func (noToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
2336 return noCompiler()
2339 func (noToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error {
2340 return noCompiler()
2343 func (noToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
2344 return noCompiler()
2347 func (noToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
2348 return noCompiler()
2351 // The Go toolchain.
2352 type gcToolchain struct{}
2354 func (gcToolchain) compiler() string {
2355 return tool("compile")
2358 func (gcToolchain) linker() string {
2359 return tool("link")
2362 func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
2363 if archive != "" {
2364 ofile = archive
2365 } else {
2366 out := "_go_.o"
2367 ofile = obj + out
2370 gcargs := []string{"-p", p.ImportPath}
2371 if p.Name == "main" {
2372 gcargs[1] = "main"
2374 if p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal")) {
2375 // runtime compiles with a special gc flag to emit
2376 // additional reflect type data.
2377 gcargs = append(gcargs, "-+")
2380 // If we're giving the compiler the entire package (no C etc files), tell it that,
2381 // so that it can give good error messages about forward declarations.
2382 // Exceptions: a few standard packages have forward declarations for
2383 // pieces supplied behind-the-scenes by package runtime.
2384 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)
2385 if p.Standard {
2386 switch p.ImportPath {
2387 case "bytes", "net", "os", "runtime/pprof", "sync", "time":
2388 extFiles++
2391 if extFiles == 0 {
2392 gcargs = append(gcargs, "-complete")
2394 if buildContext.InstallSuffix != "" {
2395 gcargs = append(gcargs, "-installsuffix", buildContext.InstallSuffix)
2397 if p.buildID != "" {
2398 gcargs = append(gcargs, "-buildid", p.buildID)
2401 for _, path := range p.Imports {
2402 if i := strings.LastIndex(path, "/vendor/"); i >= 0 {
2403 gcargs = append(gcargs, "-importmap", path[i+len("/vendor/"):]+"="+path)
2404 } else if strings.HasPrefix(path, "vendor/") {
2405 gcargs = append(gcargs, "-importmap", path[len("vendor/"):]+"="+path)
2409 args := []interface{}{buildToolExec, tool("compile"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs}
2410 if ofile == archive {
2411 args = append(args, "-pack")
2413 if asmhdr {
2414 args = append(args, "-asmhdr", obj+"go_asm.h")
2416 for _, f := range gofiles {
2417 args = append(args, mkAbs(p.Dir, f))
2420 output, err = b.runOut(p.Dir, p.ImportPath, nil, args...)
2421 return ofile, output, err
2424 func (gcToolchain) asm(b *builder, p *Package, obj string, sfiles []string) ([]string, error) {
2425 // Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
2426 inc := filepath.Join(goroot, "pkg", "include")
2427 args := []interface{}{buildToolExec, tool("asm"), "-trimpath", b.work, "-I", obj, "-I", inc, "-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch, buildAsmflags}
2428 if p.ImportPath == "runtime" && goarch == "386" {
2429 for _, arg := range buildAsmflags {
2430 if arg == "-dynlink" {
2431 args = append(args, "-D=GOBUILDMODE_shared=1")
2435 var ofiles []string
2436 for _, sfile := range sfiles {
2437 ofile := obj + sfile[:len(sfile)-len(".s")] + ".o"
2438 ofiles = append(ofiles, ofile)
2439 a := append(args, "-o", ofile, mkAbs(p.Dir, sfile))
2440 if err := b.run(p.Dir, p.ImportPath, nil, a...); err != nil {
2441 return nil, err
2444 return ofiles, nil
2447 // toolVerify checks that the command line args writes the same output file
2448 // if run using newTool instead.
2449 // Unused now but kept around for future use.
2450 func toolVerify(b *builder, p *Package, newTool string, ofile string, args []interface{}) error {
2451 newArgs := make([]interface{}, len(args))
2452 copy(newArgs, args)
2453 newArgs[1] = tool(newTool)
2454 newArgs[3] = ofile + ".new" // x.6 becomes x.6.new
2455 if err := b.run(p.Dir, p.ImportPath, nil, newArgs...); err != nil {
2456 return err
2458 data1, err := ioutil.ReadFile(ofile)
2459 if err != nil {
2460 return err
2462 data2, err := ioutil.ReadFile(ofile + ".new")
2463 if err != nil {
2464 return err
2466 if !bytes.Equal(data1, data2) {
2467 return fmt.Errorf("%s and %s produced different output files:\n%s\n%s", filepath.Base(args[1].(string)), newTool, strings.Join(stringList(args...), " "), strings.Join(stringList(newArgs...), " "))
2469 os.Remove(ofile + ".new")
2470 return nil
2473 func (gcToolchain) pkgpath(basedir string, p *Package) string {
2474 end := filepath.FromSlash(p.ImportPath + ".a")
2475 return filepath.Join(basedir, end)
2478 func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
2479 var absOfiles []string
2480 for _, f := range ofiles {
2481 absOfiles = append(absOfiles, mkAbs(objDir, f))
2483 absAfile := mkAbs(objDir, afile)
2485 // The archive file should have been created by the compiler.
2486 // Since it used to not work that way, verify.
2487 if !buildN {
2488 if _, err := os.Stat(absAfile); err != nil {
2489 fatalf("os.Stat of archive file failed: %v", err)
2493 if buildN || buildX {
2494 cmdline := stringList("pack", "r", absAfile, absOfiles)
2495 b.showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline))
2497 if buildN {
2498 return nil
2500 if err := packInternal(b, absAfile, absOfiles); err != nil {
2501 b.showOutput(p.Dir, p.ImportPath, err.Error()+"\n")
2502 return errPrintedOutput
2504 return nil
2507 func packInternal(b *builder, afile string, ofiles []string) error {
2508 dst, err := os.OpenFile(afile, os.O_WRONLY|os.O_APPEND, 0)
2509 if err != nil {
2510 return err
2512 defer dst.Close() // only for error returns or panics
2513 w := bufio.NewWriter(dst)
2515 for _, ofile := range ofiles {
2516 src, err := os.Open(ofile)
2517 if err != nil {
2518 return err
2520 fi, err := src.Stat()
2521 if err != nil {
2522 src.Close()
2523 return err
2525 // Note: Not using %-16.16s format because we care
2526 // about bytes, not runes.
2527 name := fi.Name()
2528 if len(name) > 16 {
2529 name = name[:16]
2530 } else {
2531 name += strings.Repeat(" ", 16-len(name))
2533 size := fi.Size()
2534 fmt.Fprintf(w, "%s%-12d%-6d%-6d%-8o%-10d`\n",
2535 name, 0, 0, 0, 0644, size)
2536 n, err := io.Copy(w, src)
2537 src.Close()
2538 if err == nil && n < size {
2539 err = io.ErrUnexpectedEOF
2540 } else if err == nil && n > size {
2541 err = fmt.Errorf("file larger than size reported by stat")
2543 if err != nil {
2544 return fmt.Errorf("copying %s to %s: %v", ofile, afile, err)
2546 if size&1 != 0 {
2547 w.WriteByte(0)
2551 if err := w.Flush(); err != nil {
2552 return err
2554 return dst.Close()
2557 // setextld sets the appropriate linker flags for the specified compiler.
2558 func setextld(ldflags []string, compiler []string) []string {
2559 for _, f := range ldflags {
2560 if f == "-extld" || strings.HasPrefix(f, "-extld=") {
2561 // don't override -extld if supplied
2562 return ldflags
2565 ldflags = append(ldflags, "-extld="+compiler[0])
2566 if len(compiler) > 1 {
2567 extldflags := false
2568 add := strings.Join(compiler[1:], " ")
2569 for i, f := range ldflags {
2570 if f == "-extldflags" && i+1 < len(ldflags) {
2571 ldflags[i+1] = add + " " + ldflags[i+1]
2572 extldflags = true
2573 break
2574 } else if strings.HasPrefix(f, "-extldflags=") {
2575 ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
2576 extldflags = true
2577 break
2580 if !extldflags {
2581 ldflags = append(ldflags, "-extldflags="+add)
2584 return ldflags
2587 func (gcToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error {
2588 importArgs := b.includeArgs("-L", allactions)
2589 cxx := len(root.p.CXXFiles) > 0 || len(root.p.SwigCXXFiles) > 0
2590 for _, a := range allactions {
2591 if a.p != nil && (len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0) {
2592 cxx = true
2595 var ldflags []string
2596 if buildContext.InstallSuffix != "" {
2597 ldflags = append(ldflags, "-installsuffix", buildContext.InstallSuffix)
2599 if root.p.omitDWARF {
2600 ldflags = append(ldflags, "-w")
2602 if buildBuildmode == "plugin" {
2603 pluginpath := root.p.ImportPath
2604 if pluginpath == "command-line-arguments" {
2605 pluginpath = "plugin/unnamed-" + root.p.buildID
2607 ldflags = append(ldflags, "-pluginpath", pluginpath)
2610 // If the user has not specified the -extld option, then specify the
2611 // appropriate linker. In case of C++ code, use the compiler named
2612 // by the CXX environment variable or defaultCXX if CXX is not set.
2613 // Else, use the CC environment variable and defaultCC as fallback.
2614 var compiler []string
2615 if cxx {
2616 compiler = envList("CXX", defaultCXX)
2617 } else {
2618 compiler = envList("CC", defaultCC)
2620 ldflags = setextld(ldflags, compiler)
2621 ldflags = append(ldflags, "-buildmode="+ldBuildmode)
2622 if root.p.buildID != "" {
2623 ldflags = append(ldflags, "-buildid="+root.p.buildID)
2625 ldflags = append(ldflags, buildLdflags...)
2627 // On OS X when using external linking to build a shared library,
2628 // the argument passed here to -o ends up recorded in the final
2629 // shared library in the LC_ID_DYLIB load command.
2630 // To avoid putting the temporary output directory name there
2631 // (and making the resulting shared library useless),
2632 // run the link in the output directory so that -o can name
2633 // just the final path element.
2634 dir := "."
2635 if goos == "darwin" && buildBuildmode == "c-shared" {
2636 dir, out = filepath.Split(out)
2639 return b.run(dir, root.p.ImportPath, nil, buildToolExec, tool("link"), "-o", out, importArgs, ldflags, mainpkg)
2642 func (gcToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
2643 importArgs := b.includeArgs("-L", allactions)
2644 ldflags := []string{"-installsuffix", buildContext.InstallSuffix}
2645 ldflags = append(ldflags, "-buildmode=shared")
2646 ldflags = append(ldflags, buildLdflags...)
2647 cxx := false
2648 for _, a := range allactions {
2649 if a.p != nil && (len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0) {
2650 cxx = true
2653 // If the user has not specified the -extld option, then specify the
2654 // appropriate linker. In case of C++ code, use the compiler named
2655 // by the CXX environment variable or defaultCXX if CXX is not set.
2656 // Else, use the CC environment variable and defaultCC as fallback.
2657 var compiler []string
2658 if cxx {
2659 compiler = envList("CXX", defaultCXX)
2660 } else {
2661 compiler = envList("CC", defaultCC)
2663 ldflags = setextld(ldflags, compiler)
2664 for _, d := range toplevelactions {
2665 if !strings.HasSuffix(d.target, ".a") { // omit unsafe etc and actions for other shared libraries
2666 continue
2668 ldflags = append(ldflags, d.p.ImportPath+"="+d.target)
2670 return b.run(".", out, nil, buildToolExec, tool("link"), "-o", out, importArgs, ldflags)
2673 func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
2674 return fmt.Errorf("%s: C source files not supported without cgo", mkAbs(p.Dir, cfile))
2677 // The Gccgo toolchain.
2678 type gccgoToolchain struct{}
2680 var gccgoName, gccgoBin string
2682 func init() {
2683 gccgoName = os.Getenv("GCCGO")
2684 if gccgoName == "" {
2685 gccgoName = defaultGCCGO
2687 gccgoBin, _ = exec.LookPath(gccgoName)
2690 func (gccgoToolchain) compiler() string {
2691 return gccgoBin
2694 func (gccgoToolchain) linker() string {
2695 return gccgoBin
2698 func (tools gccgoToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
2699 out := "_go_.o"
2700 ofile = obj + out
2701 gcargs := []string{"-g"}
2702 gcargs = append(gcargs, b.gccArchArgs()...)
2703 gcargs = append(gcargs, "-fdebug-prefix-map="+b.work+"=/tmp/go-build")
2704 gcargs = append(gcargs, "-gno-record-gcc-switches")
2705 if pkgpath := gccgoPkgpath(p); pkgpath != "" {
2706 gcargs = append(gcargs, "-fgo-pkgpath="+pkgpath)
2708 if p.localPrefix != "" {
2709 gcargs = append(gcargs, "-fgo-relative-import-path="+p.localPrefix)
2711 savedirs := []string{}
2712 for _, incdir := range importArgs {
2713 if incdir != "-I" {
2714 savedirs = append(savedirs, incdir)
2718 for _, path := range p.Imports {
2719 // If this is a new vendor path, add it to the list of importArgs
2720 if i := strings.LastIndex(path, "/vendor/"); i >= 0 {
2721 for _, dir := range savedirs {
2722 // Check if the vendor path is already included in dir
2723 if strings.HasSuffix(dir, path[:i+len("/vendor/")]) {
2724 continue
2726 // Make sure this vendor path is not already in the list for importArgs
2727 vendorPath := dir + "/" + path[:i+len("/vendor/")]
2728 for _, imp := range importArgs {
2729 if imp == "-I" {
2730 continue
2732 // This vendorPath is already in the list
2733 if imp == vendorPath {
2734 goto nextSuffixPath
2737 // New vendorPath not yet in the importArgs list, so add it
2738 importArgs = append(importArgs, "-I", vendorPath)
2739 nextSuffixPath:
2741 } else if strings.HasPrefix(path, "vendor/") {
2742 for _, dir := range savedirs {
2743 // Make sure this vendor path is not already in the list for importArgs
2744 vendorPath := dir + "/" + path[len("/vendor"):]
2745 for _, imp := range importArgs {
2746 if imp == "-I" {
2747 continue
2749 if imp == vendorPath {
2750 goto nextPrefixPath
2753 // This vendor path is needed and not already in the list, so add it
2754 importArgs = append(importArgs, "-I", vendorPath)
2755 nextPrefixPath:
2760 args := stringList(tools.compiler(), importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags)
2761 for _, f := range gofiles {
2762 args = append(args, mkAbs(p.Dir, f))
2765 output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
2766 return ofile, output, err
2769 func (tools gccgoToolchain) asm(b *builder, p *Package, obj string, sfiles []string) ([]string, error) {
2770 var ofiles []string
2771 for _, sfile := range sfiles {
2772 ofile := obj + sfile[:len(sfile)-len(".s")] + ".o"
2773 ofiles = append(ofiles, ofile)
2774 sfile = mkAbs(p.Dir, sfile)
2775 defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
2776 if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
2777 defs = append(defs, `-D`, `GOPKGPATH=`+pkgpath)
2779 defs = tools.maybePIC(defs)
2780 defs = append(defs, b.gccArchArgs()...)
2781 err := b.run(p.Dir, p.ImportPath, nil, tools.compiler(), "-xassembler-with-cpp", "-I", obj, "-c", "-o", ofile, defs, sfile)
2782 if err != nil {
2783 return nil, err
2786 return ofiles, nil
2789 func (gccgoToolchain) pkgpath(basedir string, p *Package) string {
2790 end := filepath.FromSlash(p.ImportPath + ".a")
2791 afile := filepath.Join(basedir, end)
2792 // add "lib" to the final element
2793 return filepath.Join(filepath.Dir(afile), "lib"+filepath.Base(afile))
2796 func (gccgoToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
2797 var absOfiles []string
2798 for _, f := range ofiles {
2799 absOfiles = append(absOfiles, mkAbs(objDir, f))
2801 absAfile := mkAbs(objDir, afile)
2802 // Try with D modifier first, then without if that fails.
2803 if b.run(p.Dir, p.ImportPath, nil, "ar", "rcD", absAfile, absOfiles) != nil {
2804 return b.run(p.Dir, p.ImportPath, nil, "ar", "rc", absAfile, absOfiles)
2806 return nil
2809 func (tools gccgoToolchain) link(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string, buildmode, desc string) error {
2810 // gccgo needs explicit linking with all package dependencies,
2811 // and all LDFLAGS from cgo dependencies.
2812 apackagePathsSeen := make(map[string]bool)
2813 afiles := []string{}
2814 shlibs := []string{}
2815 ldflags := b.gccArchArgs()
2816 cgoldflags := []string{}
2817 usesCgo := false
2818 cxx := false
2819 objc := false
2820 fortran := false
2821 if root.p != nil {
2822 cxx = len(root.p.CXXFiles) > 0 || len(root.p.SwigCXXFiles) > 0
2823 objc = len(root.p.MFiles) > 0
2824 fortran = len(root.p.FFiles) > 0
2827 readCgoFlags := func(flagsFile string) error {
2828 flags, err := ioutil.ReadFile(flagsFile)
2829 if err != nil {
2830 return err
2832 const ldflagsPrefix = "_CGO_LDFLAGS="
2833 for _, line := range strings.Split(string(flags), "\n") {
2834 if strings.HasPrefix(line, ldflagsPrefix) {
2835 newFlags := strings.Fields(line[len(ldflagsPrefix):])
2836 for _, flag := range newFlags {
2837 // Every _cgo_flags file has -g and -O2 in _CGO_LDFLAGS
2838 // but they don't mean anything to the linker so filter
2839 // them out.
2840 if flag != "-g" && !strings.HasPrefix(flag, "-O") {
2841 cgoldflags = append(cgoldflags, flag)
2846 return nil
2849 readAndRemoveCgoFlags := func(archive string) (string, error) {
2850 newa, err := ioutil.TempFile(b.work, filepath.Base(archive))
2851 if err != nil {
2852 return "", err
2854 olda, err := os.Open(archive)
2855 if err != nil {
2856 return "", err
2858 _, err = io.Copy(newa, olda)
2859 if err != nil {
2860 return "", err
2862 err = olda.Close()
2863 if err != nil {
2864 return "", err
2866 err = newa.Close()
2867 if err != nil {
2868 return "", err
2871 newarchive := newa.Name()
2872 err = b.run(b.work, desc, nil, "ar", "x", newarchive, "_cgo_flags")
2873 if err != nil {
2874 return "", err
2876 err = b.run(".", desc, nil, "ar", "d", newarchive, "_cgo_flags")
2877 if err != nil {
2878 return "", err
2880 err = readCgoFlags(filepath.Join(b.work, "_cgo_flags"))
2881 if err != nil {
2882 return "", err
2884 return newarchive, nil
2887 actionsSeen := make(map[*action]bool)
2888 // Make a pre-order depth-first traversal of the action graph, taking note of
2889 // whether a shared library action has been seen on the way to an action (the
2890 // construction of the graph means that if any path to a node passes through
2891 // a shared library action, they all do).
2892 var walk func(a *action, seenShlib bool)
2893 var err error
2894 walk = func(a *action, seenShlib bool) {
2895 if actionsSeen[a] {
2896 return
2898 actionsSeen[a] = true
2899 if a.p != nil && !seenShlib {
2900 if a.p.Standard {
2901 return
2903 // We record the target of the first time we see a .a file
2904 // for a package to make sure that we prefer the 'install'
2905 // rather than the 'build' location (which may not exist any
2906 // more). We still need to traverse the dependencies of the
2907 // build action though so saying
2908 // if apackagePathsSeen[a.p.ImportPath] { return }
2909 // doesn't work.
2910 if !apackagePathsSeen[a.p.ImportPath] {
2911 apackagePathsSeen[a.p.ImportPath] = true
2912 target := a.target
2913 if len(a.p.CgoFiles) > 0 || a.p.usesSwig() {
2914 target, err = readAndRemoveCgoFlags(target)
2915 if err != nil {
2916 return
2919 afiles = append(afiles, target)
2922 if strings.HasSuffix(a.target, ".so") {
2923 shlibs = append(shlibs, a.target)
2924 seenShlib = true
2926 for _, a1 := range a.deps {
2927 walk(a1, seenShlib)
2928 if err != nil {
2929 return
2933 for _, a1 := range root.deps {
2934 walk(a1, false)
2935 if err != nil {
2936 return err
2940 for _, a := range allactions {
2941 // Gather CgoLDFLAGS, but not from standard packages.
2942 // The go tool can dig up runtime/cgo from GOROOT and
2943 // think that it should use its CgoLDFLAGS, but gccgo
2944 // doesn't use runtime/cgo.
2945 if a.p == nil {
2946 continue
2948 if !a.p.Standard {
2949 cgoldflags = append(cgoldflags, a.p.CgoLDFLAGS...)
2951 if len(a.p.CgoFiles) > 0 {
2952 usesCgo = true
2954 if a.p.usesSwig() {
2955 usesCgo = true
2957 if len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0 {
2958 cxx = true
2960 if len(a.p.MFiles) > 0 {
2961 objc = true
2963 if len(a.p.FFiles) > 0 {
2964 fortran = true
2968 for i, o := range ofiles {
2969 if filepath.Base(o) == "_cgo_flags" {
2970 readCgoFlags(o)
2971 ofiles = append(ofiles[:i], ofiles[i+1:]...)
2972 break
2976 ldflags = append(ldflags, "-Wl,--whole-archive")
2977 ldflags = append(ldflags, afiles...)
2978 ldflags = append(ldflags, "-Wl,--no-whole-archive")
2980 ldflags = append(ldflags, cgoldflags...)
2981 ldflags = append(ldflags, envList("CGO_LDFLAGS", "")...)
2982 if root.p != nil {
2983 ldflags = append(ldflags, root.p.CgoLDFLAGS...)
2986 ldflags = stringList("-Wl,-(", ldflags, "-Wl,-)")
2988 for _, shlib := range shlibs {
2989 ldflags = append(
2990 ldflags,
2991 "-L"+filepath.Dir(shlib),
2992 "-Wl,-rpath="+filepath.Dir(shlib),
2993 "-l"+strings.TrimSuffix(
2994 strings.TrimPrefix(filepath.Base(shlib), "lib"),
2995 ".so"))
2998 var realOut string
2999 switch buildmode {
3000 case "exe":
3001 if usesCgo && goos == "linux" {
3002 ldflags = append(ldflags, "-Wl,-E")
3005 case "c-archive":
3006 // Link the Go files into a single .o, and also link
3007 // in -lgolibbegin.
3009 // We need to use --whole-archive with -lgolibbegin
3010 // because it doesn't define any symbols that will
3011 // cause the contents to be pulled in; it's just
3012 // initialization code.
3014 // The user remains responsible for linking against
3015 // -lgo -lpthread -lm in the final link. We can't use
3016 // -r to pick them up because we can't combine
3017 // split-stack and non-split-stack code in a single -r
3018 // link, and libgo picks up non-split-stack code from
3019 // libffi.
3020 ldflags = append(ldflags, "-Wl,-r", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive")
3022 if b.gccSupportsNoPie() {
3023 ldflags = append(ldflags, "-no-pie")
3026 // We are creating an object file, so we don't want a build ID.
3027 ldflags = b.disableBuildID(ldflags)
3029 realOut = out
3030 out = out + ".o"
3032 case "c-shared":
3033 ldflags = append(ldflags, "-shared", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive", "-lgo", "-lgcc_s", "-lgcc", "-lc", "-lgcc")
3034 case "shared":
3035 ldflags = append(ldflags, "-zdefs", "-shared", "-nostdlib", "-lgo", "-lgcc_s", "-lgcc", "-lc")
3036 case "pie":
3037 ldflags = append(ldflags, "-pie")
3039 default:
3040 fatalf("-buildmode=%s not supported for gccgo", buildmode)
3043 switch buildmode {
3044 case "exe", "c-shared":
3045 if cxx {
3046 ldflags = append(ldflags, "-lstdc++")
3048 if objc {
3049 ldflags = append(ldflags, "-lobjc")
3051 if fortran {
3052 fc := os.Getenv("FC")
3053 if fc == "" {
3054 fc = "gfortran"
3056 // support gfortran out of the box and let others pass the correct link options
3057 // via CGO_LDFLAGS
3058 if strings.Contains(fc, "gfortran") {
3059 ldflags = append(ldflags, "-lgfortran")
3064 if err := b.run(".", desc, nil, tools.linker(), "-o", out, ofiles, ldflags, buildGccgoflags); err != nil {
3065 return err
3068 switch buildmode {
3069 case "c-archive":
3070 if err := b.run(".", desc, nil, "ar", "rc", realOut, out); err != nil {
3071 return err
3074 return nil
3077 func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error {
3078 return tools.link(b, root, out, allactions, mainpkg, ofiles, ldBuildmode, root.p.ImportPath)
3081 func (tools gccgoToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
3082 fakeRoot := &action{}
3083 fakeRoot.deps = toplevelactions
3084 return tools.link(b, fakeRoot, out, allactions, "", nil, "shared", out)
3087 func (tools gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
3088 inc := filepath.Join(goroot, "pkg", "include")
3089 cfile = mkAbs(p.Dir, cfile)
3090 defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
3091 defs = append(defs, b.gccArchArgs()...)
3092 if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
3093 defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
3095 if b.gccSupportsFlag("-fsplit-stack") {
3096 defs = append(defs, "-fsplit-stack")
3098 defs = tools.maybePIC(defs)
3099 if b.gccSupportsFlag("-fdebug-prefix-map=a=b") {
3100 defs = append(defs, "-fdebug-prefix-map="+b.work+"=/tmp/go-build")
3102 if b.gccSupportsFlag("-gno-record-gcc-switches") {
3103 defs = append(defs, "-gno-record-gcc-switches")
3105 return b.run(p.Dir, p.ImportPath, nil, envList("CC", defaultCC), "-Wall", "-g",
3106 "-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile)
3109 // maybePIC adds -fPIC to the list of arguments if needed.
3110 func (tools gccgoToolchain) maybePIC(args []string) []string {
3111 switch buildBuildmode {
3112 case "c-archive", "c-shared", "shared", "plugin":
3113 args = append(args, "-fPIC")
3115 return args
3118 func gccgoPkgpath(p *Package) string {
3119 if p.build.IsCommand() && !p.forceLibrary {
3120 return ""
3122 return p.ImportPath
3125 func gccgoCleanPkgpath(p *Package) string {
3126 clean := func(r rune) rune {
3127 switch {
3128 case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
3129 '0' <= r && r <= '9':
3130 return r
3132 return '_'
3134 return strings.Map(clean, gccgoPkgpath(p))
3137 // gcc runs the gcc C compiler to create an object from a single C file.
3138 func (b *builder) gcc(p *Package, out string, flags []string, cfile string) error {
3139 return b.ccompile(p, out, flags, cfile, b.gccCmd(p.Dir))
3142 // gxx runs the g++ C++ compiler to create an object from a single C++ file.
3143 func (b *builder) gxx(p *Package, out string, flags []string, cxxfile string) error {
3144 return b.ccompile(p, out, flags, cxxfile, b.gxxCmd(p.Dir))
3147 // gfortran runs the gfortran Fortran compiler to create an object from a single Fortran file.
3148 func (b *builder) gfortran(p *Package, out string, flags []string, ffile string) error {
3149 return b.ccompile(p, out, flags, ffile, b.gfortranCmd(p.Dir))
3152 // ccompile runs the given C or C++ compiler and creates an object from a single source file.
3153 func (b *builder) ccompile(p *Package, outfile string, flags []string, file string, compiler []string) error {
3154 file = mkAbs(p.Dir, file)
3155 desc := p.ImportPath
3156 output, err := b.runOut(p.Dir, desc, nil, compiler, flags, "-o", outfile, "-c", file)
3157 if len(output) > 0 {
3158 // On FreeBSD 11, when we pass -g to clang 3.8 it
3159 // invokes its internal assembler with -dwarf-version=2.
3160 // When it sees .section .note.GNU-stack, it warns
3161 // "DWARF2 only supports one section per compilation unit".
3162 // This warning makes no sense, since the section is empty,
3163 // but it confuses people.
3164 // We work around the problem by detecting the warning
3165 // and dropping -g and trying again.
3166 if bytes.Contains(output, []byte("DWARF2 only supports one section per compilation unit")) {
3167 newFlags := make([]string, 0, len(flags))
3168 for _, f := range flags {
3169 if !strings.HasPrefix(f, "-g") {
3170 newFlags = append(newFlags, f)
3173 if len(newFlags) < len(flags) {
3174 return b.ccompile(p, outfile, newFlags, file, compiler)
3178 b.showOutput(p.Dir, desc, b.processOutput(output))
3179 if err != nil {
3180 err = errPrintedOutput
3181 } else if os.Getenv("GO_BUILDER_NAME") != "" {
3182 return errors.New("C compiler warning promoted to error on Go builders")
3185 return err
3188 // gccld runs the gcc linker to create an executable from a set of object files.
3189 func (b *builder) gccld(p *Package, out string, flags []string, obj []string) error {
3190 var cmd []string
3191 if len(p.CXXFiles) > 0 || len(p.SwigCXXFiles) > 0 {
3192 cmd = b.gxxCmd(p.Dir)
3193 } else {
3194 cmd = b.gccCmd(p.Dir)
3196 return b.run(p.Dir, p.ImportPath, nil, cmd, "-o", out, obj, flags)
3199 // gccCmd returns a gcc command line prefix
3200 // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
3201 func (b *builder) gccCmd(objdir string) []string {
3202 return b.ccompilerCmd("CC", defaultCC, objdir)
3205 // gxxCmd returns a g++ command line prefix
3206 // defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
3207 func (b *builder) gxxCmd(objdir string) []string {
3208 return b.ccompilerCmd("CXX", defaultCXX, objdir)
3211 // gfortranCmd returns a gfortran command line prefix.
3212 func (b *builder) gfortranCmd(objdir string) []string {
3213 return b.ccompilerCmd("FC", "gfortran", objdir)
3216 // ccompilerCmd returns a command line prefix for the given environment
3217 // variable and using the default command when the variable is empty.
3218 func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
3219 // NOTE: env.go's mkEnv knows that the first three
3220 // strings returned are "gcc", "-I", objdir (and cuts them off).
3222 compiler := envList(envvar, defcmd)
3223 a := []string{compiler[0], "-I", objdir}
3224 a = append(a, compiler[1:]...)
3226 // Definitely want -fPIC but on Windows gcc complains
3227 // "-fPIC ignored for target (all code is position independent)"
3228 if goos != "windows" {
3229 a = append(a, "-fPIC")
3231 a = append(a, b.gccArchArgs()...)
3232 // gcc-4.5 and beyond require explicit "-pthread" flag
3233 // for multithreading with pthread library.
3234 if buildContext.CgoEnabled {
3235 switch goos {
3236 case "windows":
3237 a = append(a, "-mthreads")
3238 default:
3239 a = append(a, "-pthread")
3243 if strings.Contains(a[0], "clang") {
3244 // disable ASCII art in clang errors, if possible
3245 a = append(a, "-fno-caret-diagnostics")
3246 // clang is too smart about command-line arguments
3247 a = append(a, "-Qunused-arguments")
3250 // disable word wrapping in error messages
3251 a = append(a, "-fmessage-length=0")
3253 // Tell gcc not to include the work directory in object files.
3254 if b.gccSupportsFlag("-fdebug-prefix-map=a=b") {
3255 a = append(a, "-fdebug-prefix-map="+b.work+"=/tmp/go-build")
3258 // Tell gcc not to include flags in object files, which defeats the
3259 // point of -fdebug-prefix-map above.
3260 if b.gccSupportsFlag("-gno-record-gcc-switches") {
3261 a = append(a, "-gno-record-gcc-switches")
3264 // On OS X, some of the compilers behave as if -fno-common
3265 // is always set, and the Mach-O linker in 6l/8l assumes this.
3266 // See https://golang.org/issue/3253.
3267 if goos == "darwin" {
3268 a = append(a, "-fno-common")
3271 // gccgo uses the language-independent exception mechanism to
3272 // handle panics, so it always needs unwind tables.
3273 if _, ok := buildToolchain.(gccgoToolchain); ok {
3274 a = append(a, "-funwind-tables")
3277 return a
3280 // On systems with PIE (position independent executables) enabled by default,
3281 // -no-pie must be passed when doing a partial link with -Wl,-r. But -no-pie is
3282 // not supported by all compilers.
3283 func (b *builder) gccSupportsNoPie() bool {
3284 return b.gccSupportsFlag("-no-pie")
3287 // gccSupportsFlag checks to see if the compiler supports a flag.
3288 func (b *builder) gccSupportsFlag(flag string) bool {
3289 b.exec.Lock()
3290 defer b.exec.Unlock()
3291 if b, ok := b.flagCache[flag]; ok {
3292 return b
3294 if b.flagCache == nil {
3295 src := filepath.Join(b.work, "trivial.c")
3296 if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
3297 return false
3299 b.flagCache = make(map[string]bool)
3301 cmdArgs := append(envList("CC", defaultCC), flag, "-c", "trivial.c")
3302 if buildN || buildX {
3303 b.showcmd(b.work, "%s", joinUnambiguously(cmdArgs))
3304 if buildN {
3305 return false
3308 cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
3309 cmd.Dir = b.work
3310 cmd.Env = mergeEnvLists([]string{"LC_ALL=C"}, envForDir(cmd.Dir, os.Environ()))
3311 out, err := cmd.CombinedOutput()
3312 supported := err == nil && !bytes.Contains(out, []byte("unrecognized"))
3313 b.flagCache[flag] = supported
3314 return supported
3317 // gccArchArgs returns arguments to pass to gcc based on the architecture.
3318 func (b *builder) gccArchArgs() []string {
3319 switch goarch {
3320 case "386":
3321 return []string{"-m32"}
3322 case "amd64", "amd64p32":
3323 return []string{"-m64"}
3324 case "arm":
3325 return []string{"-marm"} // not thumb
3326 case "s390x":
3327 return []string{"-m64", "-march=z196"}
3328 case "mips64", "mips64le":
3329 return []string{"-mabi=64"}
3330 case "mips", "mipsle":
3331 return []string{"-mabi=32", "-march=mips32"}
3333 return nil
3336 // envList returns the value of the given environment variable broken
3337 // into fields, using the default value when the variable is empty.
3338 func envList(key, def string) []string {
3339 v := os.Getenv(key)
3340 if v == "" {
3341 v = def
3343 return strings.Fields(v)
3346 // Return the flags to use when invoking the C, C++ or Fortran compilers, or cgo.
3347 func (b *builder) cflags(p *Package) (cppflags, cflags, cxxflags, fflags, ldflags []string) {
3348 defaults := "-g -O2"
3350 cppflags = stringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS)
3351 cflags = stringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS)
3352 cxxflags = stringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS)
3353 fflags = stringList(envList("CGO_FFLAGS", defaults), p.CgoFFLAGS)
3354 ldflags = stringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS)
3355 return
3358 var cgoRe = regexp.MustCompile(`[/\\:]`)
3360 func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofiles, objdirCgofiles, gccfiles, gxxfiles, mfiles, ffiles []string) (outGo, outObj []string, err error) {
3361 p := a.p
3362 cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoFFLAGS, cgoLDFLAGS := b.cflags(p)
3363 cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...)
3364 cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...)
3365 // If we are compiling Objective-C code, then we need to link against libobjc
3366 if len(mfiles) > 0 {
3367 cgoLDFLAGS = append(cgoLDFLAGS, "-lobjc")
3370 // Likewise for Fortran, except there are many Fortran compilers.
3371 // Support gfortran out of the box and let others pass the correct link options
3372 // via CGO_LDFLAGS
3373 if len(ffiles) > 0 {
3374 fc := os.Getenv("FC")
3375 if fc == "" {
3376 fc = "gfortran"
3378 if strings.Contains(fc, "gfortran") {
3379 cgoLDFLAGS = append(cgoLDFLAGS, "-lgfortran")
3383 if buildMSan {
3384 cgoCFLAGS = append([]string{"-fsanitize=memory"}, cgoCFLAGS...)
3385 cgoLDFLAGS = append([]string{"-fsanitize=memory"}, cgoLDFLAGS...)
3388 // Allows including _cgo_export.h from .[ch] files in the package.
3389 cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", obj)
3391 // If we have cgo files in the object directory, then copy any
3392 // other cgo files into the object directory, and pass a
3393 // -srcdir option to cgo.
3394 var srcdirarg []string
3395 if len(objdirCgofiles) > 0 {
3396 for _, fn := range cgofiles {
3397 if err := b.copyFile(a, obj+filepath.Base(fn), filepath.Join(p.Dir, fn), 0666, false); err != nil {
3398 return nil, nil, err
3401 cgofiles = append(cgofiles, objdirCgofiles...)
3402 srcdirarg = []string{"-srcdir", obj}
3405 // cgo
3406 // TODO: CGO_FLAGS?
3407 gofiles := []string{obj + "_cgo_gotypes.go"}
3408 cfiles := []string{"_cgo_export.c"}
3409 for _, fn := range cgofiles {
3410 f := cgoRe.ReplaceAllString(fn[:len(fn)-2], "_")
3411 gofiles = append(gofiles, obj+f+"cgo1.go")
3412 cfiles = append(cfiles, f+"cgo2.c")
3415 // TODO: make cgo not depend on $GOARCH?
3417 cgoflags := []string{}
3418 if p.Standard && p.ImportPath == "runtime/cgo" {
3419 cgoflags = append(cgoflags, "-import_runtime_cgo=false")
3421 if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/msan" || p.ImportPath == "runtime/cgo") {
3422 cgoflags = append(cgoflags, "-import_syscall=false")
3425 // Update $CGO_LDFLAGS with p.CgoLDFLAGS.
3426 var cgoenv []string
3427 if len(cgoLDFLAGS) > 0 {
3428 flags := make([]string, len(cgoLDFLAGS))
3429 for i, f := range cgoLDFLAGS {
3430 flags[i] = strconv.Quote(f)
3432 cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
3435 if _, ok := buildToolchain.(gccgoToolchain); ok {
3436 if b.gccSupportsFlag("-fsplit-stack") {
3437 cgoCFLAGS = append(cgoCFLAGS, "-fsplit-stack")
3439 cgoflags = append(cgoflags, "-gccgo")
3440 if pkgpath := gccgoPkgpath(p); pkgpath != "" {
3441 cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
3445 switch buildBuildmode {
3446 case "c-archive", "c-shared":
3447 // Tell cgo that if there are any exported functions
3448 // it should generate a header file that C code can
3449 // #include.
3450 cgoflags = append(cgoflags, "-exportheader="+obj+"_cgo_install.h")
3453 if err := b.run(p.Dir, p.ImportPath, cgoenv, buildToolExec, cgoExe, srcdirarg, "-objdir", obj, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, cgofiles); err != nil {
3454 return nil, nil, err
3456 outGo = append(outGo, gofiles...)
3458 // gcc
3459 cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
3460 for _, cfile := range cfiles {
3461 ofile := obj + cfile[:len(cfile)-1] + "o"
3462 if err := b.gcc(p, ofile, cflags, obj+cfile); err != nil {
3463 return nil, nil, err
3465 outObj = append(outObj, ofile)
3468 for _, file := range gccfiles {
3469 base := filepath.Base(file)
3470 ofile := obj + cgoRe.ReplaceAllString(base[:len(base)-1], "_") + "o"
3471 if err := b.gcc(p, ofile, cflags, file); err != nil {
3472 return nil, nil, err
3474 outObj = append(outObj, ofile)
3477 cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
3478 for _, file := range gxxfiles {
3479 // Append .o to the file, just in case the pkg has file.c and file.cpp
3480 ofile := obj + cgoRe.ReplaceAllString(filepath.Base(file), "_") + ".o"
3481 if err := b.gxx(p, ofile, cxxflags, file); err != nil {
3482 return nil, nil, err
3484 outObj = append(outObj, ofile)
3487 for _, file := range mfiles {
3488 // Append .o to the file, just in case the pkg has file.c and file.m
3489 ofile := obj + cgoRe.ReplaceAllString(filepath.Base(file), "_") + ".o"
3490 if err := b.gcc(p, ofile, cflags, file); err != nil {
3491 return nil, nil, err
3493 outObj = append(outObj, ofile)
3496 fflags := stringList(cgoCPPFLAGS, cgoFFLAGS)
3497 for _, file := range ffiles {
3498 // Append .o to the file, just in case the pkg has file.c and file.f
3499 ofile := obj + cgoRe.ReplaceAllString(filepath.Base(file), "_") + ".o"
3500 if err := b.gfortran(p, ofile, fflags, file); err != nil {
3501 return nil, nil, err
3503 outObj = append(outObj, ofile)
3506 switch buildToolchain.(type) {
3507 case gcToolchain:
3508 importGo := obj + "_cgo_import.go"
3509 if err := b.dynimport(p, obj, importGo, cgoExe, cflags, cgoLDFLAGS, outObj); err != nil {
3510 return nil, nil, err
3512 outGo = append(outGo, importGo)
3514 ofile := obj + "_all.o"
3515 if err := b.collect(p, obj, ofile, cgoLDFLAGS, outObj); err != nil {
3516 return nil, nil, err
3518 outObj = []string{ofile}
3520 case gccgoToolchain:
3521 defunC := obj + "_cgo_defun.c"
3522 defunObj := obj + "_cgo_defun.o"
3523 if err := buildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
3524 return nil, nil, err
3526 outObj = append(outObj, defunObj)
3528 default:
3529 noCompiler()
3532 return outGo, outObj, nil
3535 // dynimport creates a Go source file named importGo containing
3536 // //go:cgo_import_dynamic directives for each symbol or library
3537 // dynamically imported by the object files outObj.
3538 func (b *builder) dynimport(p *Package, obj, importGo, cgoExe string, cflags, cgoLDFLAGS, outObj []string) error {
3539 cfile := obj + "_cgo_main.c"
3540 ofile := obj + "_cgo_main.o"
3541 if err := b.gcc(p, ofile, cflags, cfile); err != nil {
3542 return err
3545 linkobj := stringList(ofile, outObj, p.SysoFiles)
3546 dynobj := obj + "_cgo_.o"
3548 // we need to use -pie for Linux/ARM to get accurate imported sym
3549 ldflags := cgoLDFLAGS
3550 if (goarch == "arm" && goos == "linux") || goos == "android" {
3551 ldflags = append(ldflags, "-pie")
3553 if err := b.gccld(p, dynobj, ldflags, linkobj); err != nil {
3554 return err
3557 // cgo -dynimport
3558 var cgoflags []string
3559 if p.Standard && p.ImportPath == "runtime/cgo" {
3560 cgoflags = []string{"-dynlinker"} // record path to dynamic linker
3562 return b.run(p.Dir, p.ImportPath, nil, buildToolExec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags)
3565 // collect partially links the object files outObj into a single
3566 // relocatable object file named ofile.
3567 func (b *builder) collect(p *Package, obj, ofile string, cgoLDFLAGS, outObj []string) error {
3568 // When linking relocatable objects, various flags need to be
3569 // filtered out as they are inapplicable and can cause some linkers
3570 // to fail.
3571 var ldflags []string
3572 for i := 0; i < len(cgoLDFLAGS); i++ {
3573 f := cgoLDFLAGS[i]
3574 switch {
3575 // skip "-lc" or "-l somelib"
3576 case strings.HasPrefix(f, "-l"):
3577 if f == "-l" {
3580 // skip "-framework X" on Darwin
3581 case goos == "darwin" && f == "-framework":
3583 // skip "*.{dylib,so,dll,o,a}"
3584 case strings.HasSuffix(f, ".dylib"),
3585 strings.HasSuffix(f, ".so"),
3586 strings.HasSuffix(f, ".dll"),
3587 strings.HasSuffix(f, ".o"),
3588 strings.HasSuffix(f, ".a"):
3589 // Remove any -fsanitize=foo flags.
3590 // Otherwise the compiler driver thinks that we are doing final link
3591 // and links sanitizer runtime into the object file. But we are not doing
3592 // the final link, we will link the resulting object file again. And
3593 // so the program ends up with two copies of sanitizer runtime.
3594 // See issue 8788 for details.
3595 case strings.HasPrefix(f, "-fsanitize="):
3596 continue
3597 // runpath flags not applicable unless building a shared
3598 // object or executable; see issue 12115 for details. This
3599 // is necessary as Go currently does not offer a way to
3600 // specify the set of LDFLAGS that only apply to shared
3601 // objects.
3602 case strings.HasPrefix(f, "-Wl,-rpath"):
3603 if f == "-Wl,-rpath" || f == "-Wl,-rpath-link" {
3604 // Skip following argument to -rpath* too.
3607 default:
3608 ldflags = append(ldflags, f)
3612 ldflags = append(ldflags, "-Wl,-r", "-nostdlib")
3614 if b.gccSupportsNoPie() {
3615 ldflags = append(ldflags, "-no-pie")
3618 // We are creating an object file, so we don't want a build ID.
3619 ldflags = b.disableBuildID(ldflags)
3621 return b.gccld(p, ofile, ldflags, outObj)
3624 // Run SWIG on all SWIG input files.
3625 // TODO: Don't build a shared library, once SWIG emits the necessary
3626 // pragmas for external linking.
3627 func (b *builder) swig(p *Package, obj string, pcCFLAGS []string) (outGo, outC, outCXX []string, err error) {
3628 if err := b.swigVersionCheck(); err != nil {
3629 return nil, nil, nil, err
3632 intgosize, err := b.swigIntSize(obj)
3633 if err != nil {
3634 return nil, nil, nil, err
3637 for _, f := range p.SwigFiles {
3638 goFile, cFile, err := b.swigOne(p, f, obj, pcCFLAGS, false, intgosize)
3639 if err != nil {
3640 return nil, nil, nil, err
3642 if goFile != "" {
3643 outGo = append(outGo, goFile)
3645 if cFile != "" {
3646 outC = append(outC, cFile)
3649 for _, f := range p.SwigCXXFiles {
3650 goFile, cxxFile, err := b.swigOne(p, f, obj, pcCFLAGS, true, intgosize)
3651 if err != nil {
3652 return nil, nil, nil, err
3654 if goFile != "" {
3655 outGo = append(outGo, goFile)
3657 if cxxFile != "" {
3658 outCXX = append(outCXX, cxxFile)
3661 return outGo, outC, outCXX, nil
3664 // Make sure SWIG is new enough.
3665 var (
3666 swigCheckOnce sync.Once
3667 swigCheck error
3670 func (b *builder) swigDoVersionCheck() error {
3671 out, err := b.runOut("", "", nil, "swig", "-version")
3672 if err != nil {
3673 return err
3675 re := regexp.MustCompile(`[vV]ersion +([\d]+)([.][\d]+)?([.][\d]+)?`)
3676 matches := re.FindSubmatch(out)
3677 if matches == nil {
3678 // Can't find version number; hope for the best.
3679 return nil
3682 major, err := strconv.Atoi(string(matches[1]))
3683 if err != nil {
3684 // Can't find version number; hope for the best.
3685 return nil
3687 const errmsg = "must have SWIG version >= 3.0.6"
3688 if major < 3 {
3689 return errors.New(errmsg)
3691 if major > 3 {
3692 // 4.0 or later
3693 return nil
3696 // We have SWIG version 3.x.
3697 if len(matches[2]) > 0 {
3698 minor, err := strconv.Atoi(string(matches[2][1:]))
3699 if err != nil {
3700 return nil
3702 if minor > 0 {
3703 // 3.1 or later
3704 return nil
3708 // We have SWIG version 3.0.x.
3709 if len(matches[3]) > 0 {
3710 patch, err := strconv.Atoi(string(matches[3][1:]))
3711 if err != nil {
3712 return nil
3714 if patch < 6 {
3715 // Before 3.0.6.
3716 return errors.New(errmsg)
3720 return nil
3723 func (b *builder) swigVersionCheck() error {
3724 swigCheckOnce.Do(func() {
3725 swigCheck = b.swigDoVersionCheck()
3727 return swigCheck
3730 // Find the value to pass for the -intgosize option to swig.
3731 var (
3732 swigIntSizeOnce sync.Once
3733 swigIntSize string
3734 swigIntSizeError error
3737 // This code fails to build if sizeof(int) <= 32
3738 const swigIntSizeCode = `
3739 package main
3740 const i int = 1 << 32
3743 // Determine the size of int on the target system for the -intgosize option
3744 // of swig >= 2.0.9. Run only once.
3745 func (b *builder) swigDoIntSize(obj string) (intsize string, err error) {
3746 if buildN {
3747 return "$INTBITS", nil
3749 src := filepath.Join(b.work, "swig_intsize.go")
3750 if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0666); err != nil {
3751 return
3753 srcs := []string{src}
3755 p := goFilesPackage(srcs)
3757 if _, _, e := buildToolchain.gc(b, p, "", obj, false, nil, srcs); e != nil {
3758 return "32", nil
3760 return "64", nil
3763 // Determine the size of int on the target system for the -intgosize option
3764 // of swig >= 2.0.9.
3765 func (b *builder) swigIntSize(obj string) (intsize string, err error) {
3766 swigIntSizeOnce.Do(func() {
3767 swigIntSize, swigIntSizeError = b.swigDoIntSize(obj)
3769 return swigIntSize, swigIntSizeError
3772 // Run SWIG on one SWIG input file.
3773 func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outC string, err error) {
3774 cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _, _ := b.cflags(p)
3775 var cflags []string
3776 if cxx {
3777 cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS)
3778 } else {
3779 cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS)
3782 n := 5 // length of ".swig"
3783 if cxx {
3784 n = 8 // length of ".swigcxx"
3786 base := file[:len(file)-n]
3787 goFile := base + ".go"
3788 gccBase := base + "_wrap."
3789 gccExt := "c"
3790 if cxx {
3791 gccExt = "cxx"
3794 _, gccgo := buildToolchain.(gccgoToolchain)
3796 // swig
3797 args := []string{
3798 "-go",
3799 "-cgo",
3800 "-intgosize", intgosize,
3801 "-module", base,
3802 "-o", obj + gccBase + gccExt,
3803 "-outdir", obj,
3806 for _, f := range cflags {
3807 if len(f) > 3 && f[:2] == "-I" {
3808 args = append(args, f)
3812 if gccgo {
3813 args = append(args, "-gccgo")
3814 if pkgpath := gccgoPkgpath(p); pkgpath != "" {
3815 args = append(args, "-go-pkgpath", pkgpath)
3818 if cxx {
3819 args = append(args, "-c++")
3822 out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file)
3823 if err != nil {
3824 if len(out) > 0 {
3825 if bytes.Contains(out, []byte("-intgosize")) || bytes.Contains(out, []byte("-cgo")) {
3826 return "", "", errors.New("must have SWIG version >= 3.0.6")
3828 b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig error
3829 return "", "", errPrintedOutput
3831 return "", "", err
3833 if len(out) > 0 {
3834 b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig warning
3837 return goFile, obj + gccBase + gccExt, nil
3840 // disableBuildID adjusts a linker command line to avoid creating a
3841 // build ID when creating an object file rather than an executable or
3842 // shared library. Some systems, such as Ubuntu, always add
3843 // --build-id to every link, but we don't want a build ID when we are
3844 // producing an object file. On some of those system a plain -r (not
3845 // -Wl,-r) will turn off --build-id, but clang 3.0 doesn't support a
3846 // plain -r. I don't know how to turn off --build-id when using clang
3847 // other than passing a trailing --build-id=none. So that is what we
3848 // do, but only on systems likely to support it, which is to say,
3849 // systems that normally use gold or the GNU linker.
3850 func (b *builder) disableBuildID(ldflags []string) []string {
3851 switch goos {
3852 case "android", "dragonfly", "linux", "netbsd":
3853 ldflags = append(ldflags, "-Wl,--build-id=none")
3855 return ldflags
3858 // An actionQueue is a priority queue of actions.
3859 type actionQueue []*action
3861 // Implement heap.Interface
3862 func (q *actionQueue) Len() int { return len(*q) }
3863 func (q *actionQueue) Swap(i, j int) { (*q)[i], (*q)[j] = (*q)[j], (*q)[i] }
3864 func (q *actionQueue) Less(i, j int) bool { return (*q)[i].priority < (*q)[j].priority }
3865 func (q *actionQueue) Push(x interface{}) { *q = append(*q, x.(*action)) }
3866 func (q *actionQueue) Pop() interface{} {
3867 n := len(*q) - 1
3868 x := (*q)[n]
3869 *q = (*q)[:n]
3870 return x
3873 func (q *actionQueue) push(a *action) {
3874 heap.Push(q, a)
3877 func (q *actionQueue) pop() *action {
3878 return heap.Pop(q).(*action)
3881 func instrumentInit() {
3882 if !buildRace && !buildMSan {
3883 return
3885 if buildRace && buildMSan {
3886 fmt.Fprintf(os.Stderr, "go %s: may not use -race and -msan simultaneously\n", flag.Args()[0])
3887 os.Exit(2)
3889 if buildMSan && (goos != "linux" || goarch != "amd64") {
3890 fmt.Fprintf(os.Stderr, "-msan is not supported on %s/%s\n", goos, goarch)
3891 os.Exit(2)
3893 if goarch != "amd64" || goos != "linux" && goos != "freebsd" && goos != "darwin" && goos != "windows" {
3894 fmt.Fprintf(os.Stderr, "go %s: -race and -msan are only supported on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0])
3895 os.Exit(2)
3897 if !buildContext.CgoEnabled {
3898 fmt.Fprintf(os.Stderr, "go %s: -race requires cgo; enable cgo by setting CGO_ENABLED=1\n", flag.Args()[0])
3899 os.Exit(2)
3901 if buildRace {
3902 buildGcflags = append(buildGcflags, "-race")
3903 buildLdflags = append(buildLdflags, "-race")
3904 } else {
3905 buildGcflags = append(buildGcflags, "-msan")
3906 buildLdflags = append(buildLdflags, "-msan")
3908 if buildContext.InstallSuffix != "" {
3909 buildContext.InstallSuffix += "_"
3912 if buildRace {
3913 buildContext.InstallSuffix += "race"
3914 buildContext.BuildTags = append(buildContext.BuildTags, "race")
3915 } else {
3916 buildContext.InstallSuffix += "msan"
3917 buildContext.BuildTags = append(buildContext.BuildTags, "msan")