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.
31 var cmdBuild = &Command{
32 UsageLine: "build [-o output] [-i] [build flags] [packages]",
33 Short: "compile packages and dependencies",
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,
64 force rebuilding of packages that are already up-to-date.
66 print the commands but do not run them.
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.
72 enable data race detection.
73 Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
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.
81 print the name of the temporary work directory and
82 do not delete it when exiting.
87 arguments to pass on each go tool asm invocation.
89 build mode to use. See 'go help buildmode' for more.
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.
95 arguments to pass on each go tool compile invocation.
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.
104 arguments to pass on each go tool link invocation.
106 link against shared libraries previously created with
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.
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.
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.
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 var buildContext = build.Default
172 var buildToolchain toolchain = noToolchain{}
173 var ldBuildmode string
175 // buildCompiler implements flag.Var.
176 // It implements Set by updating both
177 // buildToolchain and buildContext.Compiler.
178 type buildCompiler struct{}
180 func (c buildCompiler) Set(value string) error {
183 buildToolchain = gcToolchain{}
185 buildToolchain = gccgoToolchain{}
187 return fmt.Errorf("unknown compiler %q", value)
189 buildContext.Compiler = value
193 func (c buildCompiler) String() string {
194 return buildContext.Compiler
198 switch build.Default.Compiler {
200 buildToolchain = gcToolchain{}
202 buildToolchain = gccgoToolchain{}
206 // addBuildFlags adds the flags common to the build, clean, get,
207 // install, list, run, and test commands.
208 func addBuildFlags(cmd *Command) {
209 cmd.Flag.BoolVar(&buildA, "a", false, "")
210 cmd.Flag.BoolVar(&buildN, "n", false, "")
211 cmd.Flag.IntVar(&buildP, "p", buildP, "")
212 cmd.Flag.BoolVar(&buildV, "v", false, "")
213 cmd.Flag.BoolVar(&buildX, "x", false, "")
215 cmd.Flag.Var((*stringsFlag)(&buildAsmflags), "asmflags", "")
216 cmd.Flag.Var(buildCompiler{}, "compiler", "")
217 cmd.Flag.StringVar(&buildBuildmode, "buildmode", "default", "")
218 cmd.Flag.Var((*stringsFlag)(&buildGcflags), "gcflags", "")
219 cmd.Flag.Var((*stringsFlag)(&buildGccgoflags), "gccgoflags", "")
220 cmd.Flag.StringVar(&buildContext.InstallSuffix, "installsuffix", "", "")
221 cmd.Flag.Var((*stringsFlag)(&buildLdflags), "ldflags", "")
222 cmd.Flag.BoolVar(&buildLinkshared, "linkshared", false, "")
223 cmd.Flag.StringVar(&buildPkgdir, "pkgdir", "", "")
224 cmd.Flag.BoolVar(&buildRace, "race", false, "")
225 cmd.Flag.BoolVar(&buildMSan, "msan", false, "")
226 cmd.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
227 cmd.Flag.Var((*stringsFlag)(&buildToolExec), "toolexec", "")
228 cmd.Flag.BoolVar(&buildWork, "work", false, "")
231 func addBuildFlagsNX(cmd *Command) {
232 cmd.Flag.BoolVar(&buildN, "n", false, "")
233 cmd.Flag.BoolVar(&buildX, "x", false, "")
236 func isSpaceByte(c byte) bool {
237 return c == ' ' || c == '\t' || c == '\n' || c == '\r'
240 // fileExtSplit expects a filename and returns the name
241 // and ext (without the dot). If the file has no
242 // extension, ext will be empty.
243 func fileExtSplit(file string) (name, ext string) {
244 dotExt := filepath.Ext(file)
245 name = file[:len(file)-len(dotExt)]
252 type stringsFlag []string
254 func (v *stringsFlag) Set(s string) error {
256 *v, err = splitQuotedFields(s)
263 func splitQuotedFields(s string) ([]string, error) {
264 // Split fields allowing '' or "" around elements.
265 // Quotes further inside the string do not count.
268 for len(s) > 0 && isSpaceByte(s[0]) {
274 // Accepted quoted string. No unescaping inside.
275 if s[0] == '"' || s[0] == '\'' {
279 for i < len(s) && s[i] != quote {
283 return nil, fmt.Errorf("unterminated %c string", quote)
290 for i < len(s) && !isSpaceByte(s[i]) {
299 func (v *stringsFlag) String() string {
300 return "<stringsFlag>"
303 func pkgsMain(pkgs []*Package) (res []*Package) {
304 for _, p := range pkgs {
305 if p.Name == "main" {
312 func pkgsNotMain(pkgs []*Package) (res []*Package) {
313 for _, p := range pkgs {
314 if p.Name != "main" {
321 var pkgsFilter = func(pkgs []*Package) []*Package { return pkgs }
323 func buildModeInit() {
324 _, gccgo := buildToolchain.(gccgoToolchain)
325 var codegenArg string
326 platform := goos + "/" + goarch
327 switch buildBuildmode {
329 pkgsFilter = pkgsNotMain
331 pkgsFilter = func(p []*Package) []*Package {
332 if len(p) != 1 || p[0].Name != "main" {
333 fatalf("-buildmode=c-archive requires exactly one main package")
339 codegenArg = "-shared"
343 ldBuildmode = "c-archive"
345 pkgsFilter = pkgsMain
350 case "linux/amd64", "linux/arm", "linux/arm64", "linux/386",
351 "android/amd64", "android/arm", "android/arm64", "android/386":
352 codegenArg = "-shared"
353 case "darwin/amd64", "darwin/386":
355 fatalf("-buildmode=c-shared not supported on %s\n", platform)
358 ldBuildmode = "c-shared"
361 case "android/arm", "android/arm64", "android/amd64", "android/386":
362 codegenArg = "-shared"
368 pkgsFilter = pkgsMain
372 fatalf("-buildmode=pie not supported by gccgo")
375 case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x",
376 "android/amd64", "android/arm", "android/arm64", "android/386":
377 codegenArg = "-shared"
379 fatalf("-buildmode=pie not supported on %s\n", platform)
384 pkgsFilter = pkgsNotMain
389 case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x":
391 fatalf("-buildmode=shared not supported on %s\n", platform)
393 codegenArg = "-dynlink"
396 fatalf("-buildmode=shared and -o not supported together")
398 ldBuildmode = "shared"
400 fatalf("buildmode=%s not supported", buildBuildmode)
407 case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x":
408 buildAsmflags = append(buildAsmflags, "-D=GOBUILDMODE_shared=1")
410 fatalf("-linkshared not supported on %s\n", platform)
412 codegenArg = "-dynlink"
413 // TODO(mwhudson): remove -w when that gets fixed in linker.
414 buildLdflags = append(buildLdflags, "-linkshared", "-w")
417 if codegenArg != "" {
419 buildGccgoflags = append(buildGccgoflags, codegenArg)
421 buildAsmflags = append(buildAsmflags, codegenArg)
422 buildGcflags = append(buildGcflags, codegenArg)
424 if buildContext.InstallSuffix != "" {
425 buildContext.InstallSuffix += "_"
427 buildContext.InstallSuffix += codegenArg[1:]
431 func runBuild(cmd *Command, args []string) {
437 pkgs := packagesForBuild(args)
439 if len(pkgs) == 1 && pkgs[0].Name == "main" && *buildO == "" {
440 _, *buildO = path.Split(pkgs[0].ImportPath)
444 // sanity check some often mis-used options
445 switch buildContext.Compiler {
447 if len(buildGcflags) != 0 {
448 fmt.Println("go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags")
450 if len(buildLdflags) != 0 {
451 fmt.Println("go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags")
454 if len(buildGccgoflags) != 0 {
455 fmt.Println("go build: when using gc toolchain, please pass compile flags using -gcflags, and linker flags using -ldflags")
461 depMode = modeInstall
466 fatalf("go build: cannot use -o with multiple packages")
467 } else if len(pkgs) == 0 {
468 fatalf("no packages to build")
472 p.Stale = true // must build - not up to date
473 p.StaleReason = "build -o flag in use"
474 a := b.action(modeInstall, depMode, p)
480 if buildBuildmode == "shared" {
481 pkgs := pkgsFilter(packages(args))
482 if libName, err := libname(args, pkgs); err != nil {
483 fatalf("%s", err.Error())
485 a = b.libaction(libName, pkgs, modeBuild, depMode)
489 for _, p := range pkgsFilter(packages(args)) {
490 a.deps = append(a.deps, b.action(modeBuild, depMode, p))
496 var cmdInstall = &Command{
497 UsageLine: "install [build flags] [packages]",
498 Short: "compile and install packages and dependencies",
500 Install compiles and installs the packages named by the import paths,
501 along with their dependencies.
503 For more about the build flags, see 'go help build'.
504 For more about specifying packages, see 'go help packages'.
506 See also: go build, go get, go clean.
510 // isMetaPackage checks if name is a reserved package name that expands to multiple packages
511 func isMetaPackage(name string) bool {
512 return name == "std" || name == "cmd" || name == "all"
515 // libname returns the filename to use for the shared library when using
516 // -buildmode=shared. The rules we use are:
517 // Use arguments for special 'meta' packages:
519 // std cmd --> libstd,cmd.so
520 // A single non-meta argument with trailing "/..." is special cased:
521 // foo/... --> libfoo.so
522 // (A relative path like "./..." expands the "." first)
523 // Use import paths for other cases, changing '/' to '-':
524 // somelib --> libsubdir-somelib.so
525 // ./ or ../ --> libsubdir-somelib.so
526 // gopkg.in/tomb.v2 -> libgopkg.in-tomb.v2.so
527 // a/... b/... ---> liba/c,b/d.so - all matching import paths
528 // Name parts are joined with ','.
529 func libname(args []string, pkgs []*Package) (string, error) {
531 appendName := func(arg string) {
539 for _, arg := range args {
540 if isMetaPackage(arg) {
546 if len(libname) == 0 { // non-meta packages only. use import paths
547 if len(args) == 1 && strings.HasSuffix(args[0], "/...") {
548 // Special case of "foo/..." as mentioned above.
549 arg := strings.TrimSuffix(args[0], "/...")
550 if build.IsLocalImport(arg) {
552 bp, _ := buildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly)
553 if bp.ImportPath != "" && bp.ImportPath != "." {
557 appendName(strings.Replace(arg, "/", "-", -1))
559 for _, pkg := range pkgs {
560 appendName(strings.Replace(pkg.ImportPath, "/", "-", -1))
563 } else if haveNonMeta { // have both meta package and a non-meta one
564 return "", errors.New("mixing of meta and non-meta packages is not allowed")
566 // TODO(mwhudson): Needs to change for platforms that use different naming
568 return "lib" + libname + ".so", nil
571 func runInstall(cmd *Command, args []string) {
572 if gobin != "" && !filepath.IsAbs(gobin) {
573 fatalf("cannot install, GOBIN must be an absolute path")
578 pkgs := pkgsFilter(packagesForBuild(args))
580 for _, p := range pkgs {
581 if p.Target == "" && (!p.Standard || p.ImportPath != "unsafe") {
584 errorf("go install: cannot install cross-compiled binaries when GOBIN is set")
586 errorf("go install: no install location for .go files listed on command line (GOBIN not set)")
587 case p.ConflictDir != "":
588 errorf("go install: no install location for %s: hidden by %s", p.Dir, p.ConflictDir)
590 errorf("go install: no install location for directory %s outside GOPATH\n"+
591 "\tFor more details see: go help gopath", p.Dir)
600 if buildBuildmode == "shared" {
601 if libName, err := libname(args, pkgs); err != nil {
602 fatalf("%s", err.Error())
604 a = b.libaction(libName, pkgs, modeInstall, modeInstall)
609 for _, p := range pkgs {
610 // If p is a tool, delay the installation until the end of the build.
611 // This avoids installing assemblers/compilers that are being executed
612 // by other steps in the build.
613 // cmd/cgo is handled specially in b.action, so that we can
614 // both build and use it in the same 'go install'.
615 action := b.action(modeInstall, modeInstall, p)
616 if goTools[p.ImportPath] == toTool && p.ImportPath != "cmd/cgo" {
617 a.deps = append(a.deps, action.deps...)
618 action.deps = append(action.deps, a)
619 tools = append(tools, action)
622 a.deps = append(a.deps, action)
633 // Success. If this command is 'go install' with no arguments
634 // and the current directory (the implicit argument) is a command,
635 // remove any leftover command binary from a previous 'go build'.
636 // The binary is installed; it's not needed here anymore.
637 // And worse it might be a stale copy, which you don't want to find
638 // instead of the installed one if $PATH contains dot.
639 // One way to view this behavior is that it is as if 'go install' first
640 // runs 'go build' and the moves the generated file to the install dir.
642 if len(args) == 0 && len(pkgs) == 1 && pkgs[0].Name == "main" {
643 // Compute file 'go build' would have created.
644 // If it exists and is an executable file, remove it.
645 _, targ := filepath.Split(pkgs[0].ImportPath)
647 if filepath.Join(pkgs[0].Dir, targ) != pkgs[0].Target { // maybe $GOBIN is the current directory
648 fi, err := os.Stat(targ)
652 if m&0111 != 0 || goos == "windows" { // windows never sets executable bit
661 // Global build parameters (used during package load)
670 goarch = buildContext.GOARCH
671 goos = buildContext.GOOS
672 if goos == "windows" {
675 gopath = filepath.SplitList(buildContext.GOPATH)
678 // A builder holds global state about a build.
679 // It does not hold per-package state, because we
680 // build packages in parallel, and the builder is shared.
681 type builder struct {
682 work string // the temporary work directory (ends in filepath.Separator)
683 actionCache map[cacheKey]*action // a cache of already-constructed actions
684 mkdirCache map[string]bool // a cache of created directories
685 flagCache map[string]bool // a cache of supported compiler flags
686 print func(args ...interface{}) (int, error)
689 scriptDir string // current directory in printed script
696 // An action represents a single action in the action graph.
698 p *Package // the package this action works on
699 deps []*action // actions that must happen before this one
700 triggers []*action // inverse of deps
701 cgo *action // action for cgo binary if needed
702 args []string // additional args for runProgram
703 testOutput *bytes.Buffer // test output buffer
705 f func(*builder, *action) error // the action itself (nil = no-op)
706 ignoreFail bool // whether to run f even if dependencies fail
708 // Generated files, directories.
709 link bool // target is executable, not just package
710 pkgdir string // the -I or -L argument to use when importing this package
711 objdir string // directory for intermediate objects
712 objpkg string // the intermediate package .a file created during the action
713 target string // goal of the action: the created package or executable
716 pending int // number of deps yet to complete
717 priority int // relative execution priority
718 failed bool // whether the action failed
721 // cacheKey is the key for the action cache.
722 type cacheKey struct {
728 // buildMode specifies the build mode:
729 // are we just building things or also installing the results?
733 modeBuild buildMode = iota
738 goroot = filepath.Clean(runtime.GOROOT())
739 gobin = os.Getenv("GOBIN")
740 gorootBin = filepath.Join(goroot, "bin")
741 gorootPkg = filepath.Join(goroot, "pkg")
742 gorootSrc = filepath.Join(goroot, "src")
745 func (b *builder) init() {
747 b.print = func(a ...interface{}) (int, error) {
748 return fmt.Fprint(os.Stderr, a...)
750 b.actionCache = make(map[cacheKey]*action)
751 b.mkdirCache = make(map[string]bool)
756 b.work, err = ioutil.TempDir("", "go-build")
760 if buildX || buildWork {
761 fmt.Fprintf(os.Stderr, "WORK=%s\n", b.work)
765 atexit(func() { os.RemoveAll(workdir) })
770 // goFilesPackage creates a package for building a collection of Go files
771 // (typically named on the command line). The target is named p.a for
772 // package p or named after the first Go file for package main.
773 func goFilesPackage(gofiles []string) *Package {
774 // TODO: Remove this restriction.
775 for _, f := range gofiles {
776 if !strings.HasSuffix(f, ".go") {
777 fatalf("named files must be .go files")
783 ctxt.UseAllFiles = true
785 // Synthesize fake "directory" that only shows the named files,
786 // to make it look like this is a standard package or
787 // command directory. So that local imports resolve
788 // consistently, the files must all be in the same directory.
789 var dirent []os.FileInfo
791 for _, file := range gofiles {
792 fi, err := os.Stat(file)
797 fatalf("%s is a directory, should be a Go file", file)
799 dir1, _ := filepath.Split(file)
805 } else if dir != dir1 {
806 fatalf("named files must all be in one directory; have %s and %s", dir, dir1)
808 dirent = append(dirent, fi)
810 ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil }
816 dir, err = filepath.Abs(dir)
821 bp, err := ctxt.ImportDir(dir, 0)
826 pkg.load(&stk, bp, err)
828 pkg.localPrefix = dirToImportPath(dir)
829 pkg.ImportPath = "command-line-arguments"
832 if pkg.Name == "main" {
833 _, elem := filepath.Split(gofiles[0])
834 exe := elem[:len(elem)-len(".go")] + exeSuffix
839 pkg.target = filepath.Join(gobin, exe)
843 pkg.Target = pkg.target
845 pkg.StaleReason = "files named on command line"
851 // readpkglist returns the list of packages that were built into the shared library
852 // at shlibpath. For the native toolchain this list is stored, newline separated, in
853 // an ELF note with name "Go\x00\x00" and type 1. For GCCGO it is extracted from the
854 // .go_export section.
855 func readpkglist(shlibpath string) (pkgs []*Package) {
857 if _, gccgo := buildToolchain.(gccgoToolchain); gccgo {
858 f, _ := elf.Open(shlibpath)
859 sect := f.Section(".go_export")
860 data, _ := sect.Data()
861 scanner := bufio.NewScanner(bytes.NewBuffer(data))
864 if strings.HasPrefix(t, "pkgpath ") {
865 t = strings.TrimPrefix(t, "pkgpath ")
866 t = strings.TrimSuffix(t, ";")
867 pkgs = append(pkgs, loadPackage(t, &stk))
871 pkglistbytes, err := readELFNote(shlibpath, "Go\x00\x00", 1)
873 fatalf("readELFNote failed: %v", err)
875 scanner := bufio.NewScanner(bytes.NewBuffer(pkglistbytes))
878 pkgs = append(pkgs, loadPackage(t, &stk))
884 // action returns the action for applying the given operation (mode) to the package.
885 // depMode is the action to use when building dependencies.
886 // action never looks for p in a shared library, but may find p's dependencies in a
887 // shared library if buildLinkshared is true.
888 func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action {
889 return b.action1(mode, depMode, p, false, "")
892 // action1 returns the action for applying the given operation (mode) to the package.
893 // depMode is the action to use when building dependencies.
894 // action1 will look for p in a shared library if lookshared is true.
895 // forShlib is the shared library that p will become part of, if any.
896 func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, lookshared bool, forShlib string) *action {
901 key := cacheKey{mode, p, shlib}
903 a := b.actionCache[key]
908 key2 := cacheKey{modeInstall, nil, shlib}
909 a = b.actionCache[key2]
911 b.actionCache[key] = a
914 pkgs := readpkglist(shlib)
915 a = b.libaction(filepath.Base(shlib), pkgs, modeInstall, depMode)
916 b.actionCache[key2] = a
917 b.actionCache[key] = a
921 a = &action{p: p, pkgdir: p.build.PkgRoot}
922 if p.pkgdir != "" { // overrides p.t
925 b.actionCache[key] = a
927 for _, p1 := range p.imports {
929 // p is part of a shared library.
930 if p1.Shlib != "" && p1.Shlib != forShlib {
931 // p1 is explicitly part of a different shared library.
932 // Put the action for that shared library into a.deps.
933 a.deps = append(a.deps, b.action1(depMode, depMode, p1, true, p1.Shlib))
935 // p1 is (implicitly or not) part of this shared library.
936 // Put the action for p1 into a.deps.
937 a.deps = append(a.deps, b.action1(depMode, depMode, p1, false, forShlib))
940 // p is not part of a shared library.
941 // If p1 is in a shared library, put the action for that into
942 // a.deps, otherwise put the action for p1 into a.deps.
943 a.deps = append(a.deps, b.action1(depMode, depMode, p1, buildLinkshared, p1.Shlib))
947 // If we are not doing a cross-build, then record the binary we'll
948 // generate for cgo as a dependency of the build of any package
949 // using cgo, to make sure we do not overwrite the binary while
950 // a package is using it. If this is a cross-build, then the cgo we
951 // are writing is not the cgo we need to use.
952 if goos == runtime.GOOS && goarch == runtime.GOARCH && !buildRace && !buildMSan {
953 if (len(p.CgoFiles) > 0 || p.Standard && p.ImportPath == "runtime/cgo") && !buildLinkshared && buildBuildmode != "shared" {
955 p1 := loadPackage("cmd/cgo", &stk)
957 fatalf("load cmd/cgo: %v", p1.Error)
959 a.cgo = b.action(depMode, depMode, p1)
960 a.deps = append(a.deps, a.cgo)
965 switch p.ImportPath {
966 case "builtin", "unsafe":
967 // Fake packages - nothing to build.
970 // gccgo standard library is "fake" too.
971 if _, ok := buildToolchain.(gccgoToolchain); ok {
972 // the target name is needed for cgo.
978 if !p.Stale && p.target != "" {
979 // p.Stale==false implies that p.target is up-to-date.
980 // Record target name for use by actions depending on this one.
985 if p.local && p.target == "" {
986 // Imported via local path. No permanent target.
993 a.objdir = filepath.Join(work, a.p.ImportPath, "_obj") + string(filepath.Separator)
994 a.objpkg = buildToolchain.pkgpath(work, a.p)
995 a.link = p.Name == "main"
999 a.f = (*builder).install
1000 a.deps = []*action{b.action1(modeBuild, depMode, p, lookshared, forShlib)}
1001 a.target = a.p.target
1003 // Install header for cgo in c-archive and c-shared modes.
1004 if p.usesCgo() && (buildBuildmode == "c-archive" || buildBuildmode == "c-shared") {
1005 hdrTarget := a.target[:len(a.target)-len(filepath.Ext(a.target))] + ".h"
1006 if buildContext.Compiler == "gccgo" {
1007 // For the header file, remove the "lib"
1008 // added by go/build, so we generate pkg.h
1009 // rather than libpkg.h.
1010 dir, file := filepath.Split(hdrTarget)
1011 file = strings.TrimPrefix(file, "lib")
1012 hdrTarget = filepath.Join(dir, file)
1016 deps: []*action{a.deps[0]},
1017 f: (*builder).installHeader,
1022 a.deps = append(a.deps, ah)
1026 a.f = (*builder).build
1029 // An executable file. (This is the name of a temporary file.)
1030 // Because we run the temporary file in 'go run' and 'go test',
1031 // the name will show up in ps listings. If the caller has specified
1032 // a name, use that instead of a.out. The binary is generated
1033 // in an otherwise empty subdirectory named exe to avoid
1034 // naming conflicts. The only possible conflict is if we were
1035 // to create a top-level package named exe.
1037 if p.exeName != "" {
1039 } else if goos == "darwin" && buildBuildmode == "c-shared" && p.target != "" {
1040 // On OS X, the linker output name gets recorded in the
1041 // shared library's LC_ID_DYLIB load command.
1042 // The code invoking the linker knows to pass only the final
1043 // path element. Arrange that the path element matches what
1044 // we'll install it as; otherwise the library is only loadable as "a.out".
1045 _, name = filepath.Split(p.target)
1047 a.target = a.objdir + filepath.Join("exe", name) + exeSuffix
1054 func (b *builder) libaction(libname string, pkgs []*Package, mode, depMode buildMode) *action {
1058 fatalf("unrecognized mode %v", mode)
1061 a.f = (*builder).linkShared
1062 a.target = filepath.Join(b.work, libname)
1063 for _, p := range pkgs {
1067 a.deps = append(a.deps, b.action(depMode, depMode, p))
1071 // Currently build mode shared forces external linking mode, and
1072 // external linking mode forces an import of runtime/cgo (and
1073 // math on arm). So if it was not passed on the command line and
1074 // it is not present in another shared library, add it here.
1075 _, gccgo := buildToolchain.(gccgoToolchain)
1078 for _, p := range pkgs {
1079 seencgo = seencgo || (p.Standard && p.ImportPath == "runtime/cgo")
1083 p := loadPackage("runtime/cgo", &stk)
1085 fatalf("load runtime/cgo: %v", p.Error)
1088 // If runtime/cgo is in another shared library, then that's
1089 // also the shared library that contains runtime, so
1090 // something will depend on it and so runtime/cgo's staleness
1091 // will be checked when processing that library.
1092 if p.Shlib == "" || p.Shlib == libname {
1093 pkgs = append([]*Package{}, pkgs...)
1094 pkgs = append(pkgs, p)
1097 if goarch == "arm" {
1099 for _, p := range pkgs {
1100 seenmath = seenmath || (p.Standard && p.ImportPath == "math")
1104 p := loadPackage("math", &stk)
1106 fatalf("load math: %v", p.Error)
1109 // If math is in another shared library, then that's
1110 // also the shared library that contains runtime, so
1111 // something will depend on it and so math's staleness
1112 // will be checked when processing that library.
1113 if p.Shlib == "" || p.Shlib == libname {
1114 pkgs = append([]*Package{}, pkgs...)
1115 pkgs = append(pkgs, p)
1121 // Figure out where the library will go.
1123 for _, p := range pkgs {
1124 plibdir := p.build.PkgTargetRoot
1126 plibdir = filepath.Join(plibdir, "shlibs")
1130 } else if libdir != plibdir {
1131 fatalf("multiple roots %s & %s", libdir, plibdir)
1134 a.target = filepath.Join(libdir, libname)
1136 // Now we can check whether we need to rebuild it.
1139 if fi, err := os.Stat(a.target); err == nil {
1140 built = fi.ModTime()
1142 for _, p := range pkgs {
1146 stale = stale || p.Stale
1147 lstat, err := os.Stat(p.target)
1148 if err != nil || lstat.ModTime().After(built) {
1151 a.deps = append(a.deps, b.action1(depMode, depMode, p, false, a.target))
1155 a.f = (*builder).install
1156 buildAction := b.libaction(libname, pkgs, modeBuild, depMode)
1157 a.deps = []*action{buildAction}
1158 for _, p := range pkgs {
1162 shlibnameaction := &action{}
1163 shlibnameaction.f = (*builder).installShlibname
1164 shlibnameaction.target = p.target[:len(p.target)-2] + ".shlibname"
1165 a.deps = append(a.deps, shlibnameaction)
1166 shlibnameaction.deps = append(shlibnameaction.deps, buildAction)
1173 // actionList returns the list of actions in the dag rooted at root
1174 // as visited in a depth-first post-order traversal.
1175 func actionList(root *action) []*action {
1176 seen := map[*action]bool{}
1178 var walk func(*action)
1179 walk = func(a *action) {
1184 for _, a1 := range a.deps {
1187 all = append(all, a)
1193 // allArchiveActions returns a list of the archive dependencies of root.
1194 // This is needed because if package p depends on package q that is in libr.so, the
1195 // action graph looks like p->libr.so->q and so just scanning through p's
1196 // dependencies does not find the import dir for q.
1197 func allArchiveActions(root *action) []*action {
1198 seen := map[*action]bool{}
1200 var walk func(*action)
1201 walk = func(a *action) {
1206 if strings.HasSuffix(a.target, ".so") || a == root {
1207 for _, a1 := range a.deps {
1210 } else if strings.HasSuffix(a.target, ".a") {
1218 // do runs the action graph rooted at root.
1219 func (b *builder) do(root *action) {
1220 // Build list of all actions, assigning depth-first post-order priority.
1221 // The original implementation here was a true queue
1222 // (using a channel) but it had the effect of getting
1223 // distracted by low-level leaf actions to the detriment
1224 // of completing higher-level actions. The order of
1225 // work does not matter much to overall execution time,
1226 // but when running "go test std" it is nice to see each test
1227 // results as soon as possible. The priorities assigned
1228 // ensure that, all else being equal, the execution prefers
1229 // to do what it would have done first in a simple depth-first
1230 // dependency order traversal.
1231 all := actionList(root)
1232 for i, a := range all {
1236 b.readySema = make(chan bool, len(all))
1238 // Initialize per-action execution state.
1239 for _, a := range all {
1240 for _, a1 := range a.deps {
1241 a1.triggers = append(a1.triggers, a)
1243 a.pending = len(a.deps)
1250 // Handle runs a single action and takes care of triggering
1251 // any actions that are runnable as a result.
1252 handle := func(a *action) {
1254 if a.f != nil && (!a.failed || a.ignoreFail) {
1258 // The actions run in parallel but all the updates to the
1259 // shared work state are serialized through b.exec.
1261 defer b.exec.Unlock()
1264 if err == errPrintedOutput {
1272 for _, a0 := range a.triggers {
1276 if a0.pending--; a0.pending == 0 {
1287 var wg sync.WaitGroup
1289 // Kick off goroutines according to parallelism.
1290 // If we are using the -n flag (just printing commands)
1291 // drop the parallelism to 1, both to make the output
1292 // deterministic and because there is no real work anyway.
1297 for i := 0; i < par; i++ {
1303 case _, ok := <-b.readySema:
1307 // Receiving a value from b.readySema entitles
1308 // us to take from the ready queue.
1324 // build is the action for building a single package or command.
1325 func (b *builder) build(a *action) (err error) {
1326 // Return an error for binary-only package.
1327 // We only reach this if isStale believes the binary form is
1328 // either not present or not usable.
1330 return fmt.Errorf("missing or invalid package binary for binary-only package %s", a.p.ImportPath)
1333 // Return an error if the package has CXX files but it's not using
1334 // cgo nor SWIG, since the CXX files can only be processed by cgo
1336 if len(a.p.CXXFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
1337 return fmt.Errorf("can't build package %s because it contains C++ files (%s) but it's not using cgo nor SWIG",
1338 a.p.ImportPath, strings.Join(a.p.CXXFiles, ","))
1340 // Same as above for Objective-C files
1341 if len(a.p.MFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
1342 return fmt.Errorf("can't build package %s because it contains Objective-C files (%s) but it's not using cgo nor SWIG",
1343 a.p.ImportPath, strings.Join(a.p.MFiles, ","))
1345 // Same as above for Fortran files
1346 if len(a.p.FFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
1347 return fmt.Errorf("can't build package %s because it contains Fortran files (%s) but it's not using cgo nor SWIG",
1348 a.p.ImportPath, strings.Join(a.p.FFiles, ","))
1352 if err != nil && err != errPrintedOutput {
1353 err = fmt.Errorf("go build %s: %v", a.p.ImportPath, err)
1357 // In -n mode, print a banner between packages.
1358 // The banner is five lines so that when changes to
1359 // different sections of the bootstrap script have to
1360 // be merged, the banners give patch something
1361 // to use to find its context.
1362 b.print("\n#\n# " + a.p.ImportPath + "\n#\n\n")
1366 b.print(a.p.ImportPath + "\n")
1369 // Make build directory.
1371 if err := b.mkdir(obj); err != nil {
1375 // make target directory
1376 dir, _ := filepath.Split(a.target)
1378 if err := b.mkdir(dir); err != nil {
1383 var gofiles, cgofiles, cfiles, sfiles, cxxfiles, objects, cgoObjects, pcCFLAGS, pcLDFLAGS []string
1385 gofiles = append(gofiles, a.p.GoFiles...)
1386 cgofiles = append(cgofiles, a.p.CgoFiles...)
1387 cfiles = append(cfiles, a.p.CFiles...)
1388 sfiles = append(sfiles, a.p.SFiles...)
1389 cxxfiles = append(cxxfiles, a.p.CXXFiles...)
1391 if a.p.usesCgo() || a.p.usesSwig() {
1392 if pcCFLAGS, pcLDFLAGS, err = b.getPkgConfigFlags(a.p); err != nil {
1397 // Run SWIG on each .swig and .swigcxx file.
1398 // Each run will generate two files, a .go file and a .c or .cxx file.
1399 // The .go file will use import "C" and is to be processed by cgo.
1401 outGo, outC, outCXX, err := b.swig(a.p, obj, pcCFLAGS)
1405 cgofiles = append(cgofiles, outGo...)
1406 cfiles = append(cfiles, outC...)
1407 cxxfiles = append(cxxfiles, outCXX...)
1411 if a.p.usesCgo() || a.p.usesSwig() {
1412 // In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
1413 // There is one exception: runtime/cgo's job is to bridge the
1414 // cgo and non-cgo worlds, so it necessarily has files in both.
1415 // In that case gcc only gets the gcc_* files.
1416 var gccfiles []string
1417 gccfiles = append(gccfiles, cfiles...)
1419 if a.p.Standard && a.p.ImportPath == "runtime/cgo" {
1420 filter := func(files, nongcc, gcc []string) ([]string, []string) {
1421 for _, f := range files {
1422 if strings.HasPrefix(f, "gcc_") {
1423 gcc = append(gcc, f)
1425 nongcc = append(nongcc, f)
1430 sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles)
1432 gccfiles = append(gccfiles, sfiles...)
1436 cgoExe := tool("cgo")
1437 if a.cgo != nil && a.cgo.target != "" {
1438 cgoExe = a.cgo.target
1440 outGo, outObj, err := b.cgo(a.p, cgoExe, obj, pcCFLAGS, pcLDFLAGS, cgofiles, gccfiles, cxxfiles, a.p.MFiles, a.p.FFiles)
1444 if _, ok := buildToolchain.(gccgoToolchain); ok {
1445 cgoObjects = append(cgoObjects, filepath.Join(a.objdir, "_cgo_flags"))
1447 cgoObjects = append(cgoObjects, outObj...)
1448 gofiles = append(gofiles, outGo...)
1451 if len(gofiles) == 0 {
1452 return &build.NoGoError{Dir: a.p.Dir}
1455 // If we're doing coverage, preprocess the .go files and put them in the work directory
1456 if a.p.coverMode != "" {
1457 for i, file := range gofiles {
1458 var sourceFile string
1459 var coverFile string
1461 if strings.HasSuffix(file, ".cgo1.go") {
1462 // cgo files have absolute paths
1463 base := filepath.Base(file)
1465 coverFile = filepath.Join(obj, base)
1466 key = strings.TrimSuffix(base, ".cgo1.go") + ".go"
1468 sourceFile = filepath.Join(a.p.Dir, file)
1469 coverFile = filepath.Join(obj, file)
1472 cover := a.p.coverVars[key]
1473 if cover == nil || isTestFile(file) {
1474 // Not covering this file.
1477 if err := b.cover(a, coverFile, sourceFile, 0666, cover.Var); err != nil {
1480 gofiles[i] = coverFile
1484 // Prepare Go import path list.
1485 inc := b.includeArgs("-I", allArchiveActions(a))
1488 ofile, out, err := buildToolchain.gc(b, a.p, a.objpkg, obj, len(sfiles) > 0, inc, gofiles)
1490 b.showOutput(a.p.Dir, a.p.ImportPath, b.processOutput(out))
1492 return errPrintedOutput
1498 if ofile != a.objpkg {
1499 objects = append(objects, ofile)
1502 // Copy .h files named for goos or goarch or goos_goarch
1503 // to names using GOOS and GOARCH.
1504 // For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
1505 _goos_goarch := "_" + goos + "_" + goarch
1507 _goarch := "_" + goarch
1508 for _, file := range a.p.HFiles {
1509 name, ext := fileExtSplit(file)
1511 case strings.HasSuffix(name, _goos_goarch):
1512 targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext
1513 if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666, true); err != nil {
1516 case strings.HasSuffix(name, _goarch):
1517 targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext
1518 if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666, true); err != nil {
1521 case strings.HasSuffix(name, _goos):
1522 targ := file[:len(name)-len(_goos)] + "_GOOS." + ext
1523 if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666, true); err != nil {
1529 for _, file := range cfiles {
1530 out := file[:len(file)-len(".c")] + ".o"
1531 if err := buildToolchain.cc(b, a.p, obj, obj+out, file); err != nil {
1534 objects = append(objects, out)
1537 // Assemble .s files.
1538 for _, file := range sfiles {
1539 out := file[:len(file)-len(".s")] + ".o"
1540 if err := buildToolchain.asm(b, a.p, obj, obj+out, file); err != nil {
1543 objects = append(objects, out)
1546 // NOTE(rsc): On Windows, it is critically important that the
1547 // gcc-compiled objects (cgoObjects) be listed after the ordinary
1548 // objects in the archive. I do not know why this is.
1549 // https://golang.org/issue/2601
1550 objects = append(objects, cgoObjects...)
1552 // Add system object files.
1553 for _, syso := range a.p.SysoFiles {
1554 objects = append(objects, filepath.Join(a.p.Dir, syso))
1557 // Pack into archive in obj directory.
1558 // If the Go compiler wrote an archive, we only need to add the
1559 // object files for non-Go sources to the archive.
1560 // If the Go compiler wrote an archive and the package is entirely
1561 // Go sources, there is no pack to execute at all.
1562 if len(objects) > 0 {
1563 if err := buildToolchain.pack(b, a.p, obj, a.objpkg, objects); err != nil {
1570 // The compiler only cares about direct imports, but the
1571 // linker needs the whole dependency tree.
1572 all := actionList(a)
1573 all = all[:len(all)-1] // drop a
1574 if err := buildToolchain.ld(b, a, a.target, all, a.objpkg, objects); err != nil {
1582 // Calls pkg-config if needed and returns the cflags/ldflags needed to build the package.
1583 func (b *builder) getPkgConfigFlags(p *Package) (cflags, ldflags []string, err error) {
1584 if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
1586 out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--cflags", pkgs)
1588 b.showOutput(p.Dir, "pkg-config --cflags "+strings.Join(pkgs, " "), string(out))
1589 b.print(err.Error() + "\n")
1590 err = errPrintedOutput
1594 cflags = strings.Fields(string(out))
1596 out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--libs", pkgs)
1598 b.showOutput(p.Dir, "pkg-config --libs "+strings.Join(pkgs, " "), string(out))
1599 b.print(err.Error() + "\n")
1600 err = errPrintedOutput
1604 ldflags = strings.Fields(string(out))
1610 func (b *builder) installShlibname(a *action) error {
1612 err := ioutil.WriteFile(a.target, []byte(filepath.Base(a1.target)+"\n"), 0666)
1617 b.showcmd("", "echo '%s' > %s # internal", filepath.Base(a1.target), a.target)
1622 func (b *builder) linkShared(a *action) (err error) {
1623 allactions := actionList(a)
1624 allactions = allactions[:len(allactions)-1]
1625 return buildToolchain.ldShared(b, a.deps, a.target, allactions)
1628 // install is the action for installing a single package or executable.
1629 func (b *builder) install(a *action) (err error) {
1631 if err != nil && err != errPrintedOutput {
1632 err = fmt.Errorf("go install %s: %v", a.p.ImportPath, err)
1636 perm := os.FileMode(0666)
1638 switch buildBuildmode {
1639 case "c-archive", "c-shared":
1645 // make target directory
1646 dir, _ := filepath.Split(a.target)
1648 if err := b.mkdir(dir); err != nil {
1653 // remove object dir to keep the amount of
1654 // garbage down in a large build. On an operating system
1655 // with aggressive buffering, cleaning incrementally like
1656 // this keeps the intermediate objects from hitting the disk.
1658 defer os.RemoveAll(a1.objdir)
1659 defer os.Remove(a1.target)
1662 return b.moveOrCopyFile(a, a.target, a1.target, perm, false)
1665 // includeArgs returns the -I or -L directory list for access
1666 // to the results of the list of actions.
1667 func (b *builder) includeArgs(flag string, all []*action) []string {
1669 incMap := map[string]bool{
1670 b.work: true, // handled later
1672 "": true, // ignore empty strings
1675 // Look in the temporary space for results of test-specific actions.
1676 // This is the $WORK/my/package/_test directory for the
1677 // package being built, so there are few of these.
1678 for _, a1 := range all {
1682 if dir := a1.pkgdir; dir != a1.p.build.PkgRoot && !incMap[dir] {
1684 inc = append(inc, flag, dir)
1688 // Also look in $WORK for any non-test packages that have
1689 // been built but not installed.
1690 inc = append(inc, flag, b.work)
1692 // Finally, look in the installed package directories for each action.
1693 // First add the package dirs corresponding to GOPATH entries
1694 // in the original GOPATH order.
1695 need := map[string]*build.Package{}
1696 for _, a1 := range all {
1697 if a1.p != nil && a1.pkgdir == a1.p.build.PkgRoot {
1698 need[a1.p.build.Root] = a1.p.build
1701 for _, root := range gopath {
1702 if p := need[root]; p != nil && !incMap[p.PkgRoot] {
1703 incMap[p.PkgRoot] = true
1704 inc = append(inc, flag, p.PkgTargetRoot)
1708 // Then add anything that's left.
1709 for _, a1 := range all {
1713 if dir := a1.pkgdir; dir == a1.p.build.PkgRoot && !incMap[dir] {
1715 inc = append(inc, flag, a1.p.build.PkgTargetRoot)
1722 // moveOrCopyFile is like 'mv src dst' or 'cp src dst'.
1723 func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode, force bool) error {
1725 b.showcmd("", "mv %s %s", src, dst)
1729 // If we can update the mode and rename to the dst, do it.
1730 // Otherwise fall back to standard copy.
1732 // The perm argument is meant to be adjusted according to umask,
1733 // but we don't know what the umask is.
1734 // Create a dummy file to find out.
1735 // This avoids build tags and works even on systems like Plan 9
1736 // where the file mask computation incorporates other information.
1738 f, err := os.OpenFile(filepath.Clean(dst)+"-go-tmp-umask", os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm)
1742 mode = fi.Mode() & 0777
1749 if err := os.Chmod(src, mode); err == nil {
1750 if err := os.Rename(src, dst); err == nil {
1752 b.showcmd("", "mv %s %s", src, dst)
1758 return b.copyFile(a, dst, src, perm, force)
1761 // copyFile is like 'cp src dst'.
1762 func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode, force bool) error {
1763 if buildN || buildX {
1764 b.showcmd("", "cp %s %s", src, dst)
1770 sf, err := os.Open(src)
1776 // Be careful about removing/overwriting dst.
1777 // Do not remove/overwrite if dst exists and is a directory
1778 // or a non-object file.
1779 if fi, err := os.Stat(dst); err == nil {
1781 return fmt.Errorf("build output %q already exists and is a directory", dst)
1783 if !force && fi.Mode().IsRegular() && !isObject(dst) {
1784 return fmt.Errorf("build output %q already exists and is not an object file", dst)
1788 // On Windows, remove lingering ~ file from last attempt.
1790 if _, err := os.Stat(dst + "~"); err == nil {
1791 os.Remove(dst + "~")
1795 mayberemovefile(dst)
1796 df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
1797 if err != nil && toolIsWindows {
1798 // Windows does not allow deletion of a binary file
1799 // while it is executing. Try to move it out of the way.
1800 // If the move fails, which is likely, we'll try again the
1801 // next time we do an install of this binary.
1802 if err := os.Rename(dst, dst+"~"); err == nil {
1803 os.Remove(dst + "~")
1805 df, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
1811 _, err = io.Copy(df, sf)
1814 mayberemovefile(dst)
1815 return fmt.Errorf("copying %s to %s: %v", src, dst, err)
1820 // Install the cgo export header file, if there is one.
1821 func (b *builder) installHeader(a *action) error {
1822 src := a.objdir + "_cgo_install.h"
1823 if _, err := os.Stat(src); os.IsNotExist(err) {
1824 // If the file does not exist, there are no exported
1825 // functions, and we do not install anything.
1829 dir, _ := filepath.Split(a.target)
1831 if err := b.mkdir(dir); err != nil {
1836 return b.moveOrCopyFile(a, a.target, src, 0666, true)
1839 // cover runs, in effect,
1840 // go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
1841 func (b *builder) cover(a *action, dst, src string, perm os.FileMode, varName string) error {
1842 return b.run(a.objdir, "cover "+a.p.ImportPath, nil,
1845 "-mode", a.p.coverMode,
1851 var objectMagic = [][]byte{
1852 {'!', '<', 'a', 'r', 'c', 'h', '>', '\n'}, // Package archive
1853 {'\x7F', 'E', 'L', 'F'}, // ELF
1854 {0xFE, 0xED, 0xFA, 0xCE}, // Mach-O big-endian 32-bit
1855 {0xFE, 0xED, 0xFA, 0xCF}, // Mach-O big-endian 64-bit
1856 {0xCE, 0xFA, 0xED, 0xFE}, // Mach-O little-endian 32-bit
1857 {0xCF, 0xFA, 0xED, 0xFE}, // Mach-O little-endian 64-bit
1858 {0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00}, // PE (Windows) as generated by 6l/8l and gcc
1859 {0x00, 0x00, 0x01, 0xEB}, // Plan 9 i386
1860 {0x00, 0x00, 0x8a, 0x97}, // Plan 9 amd64
1861 {0x00, 0x00, 0x06, 0x47}, // Plan 9 arm
1864 func isObject(s string) bool {
1865 f, err := os.Open(s)
1870 buf := make([]byte, 64)
1872 for _, magic := range objectMagic {
1873 if bytes.HasPrefix(buf, magic) {
1880 // mayberemovefile removes a file only if it is a regular file
1881 // When running as a user with sufficient privileges, we may delete
1882 // even device files, for example, which is not intended.
1883 func mayberemovefile(s string) {
1884 if fi, err := os.Lstat(s); err == nil && !fi.Mode().IsRegular() {
1890 // fmtcmd formats a command in the manner of fmt.Sprintf but also:
1892 // If dir is non-empty and the script is not in dir right now,
1893 // fmtcmd inserts "cd dir\n" before the command.
1895 // fmtcmd replaces the value of b.work with $WORK.
1896 // fmtcmd replaces the value of goroot with $GOROOT.
1897 // fmtcmd replaces the value of b.gobin with $GOBIN.
1899 // fmtcmd replaces the name of the current directory with dot (.)
1900 // but only when it is at the beginning of a space-separated token.
1902 func (b *builder) fmtcmd(dir string, format string, args ...interface{}) string {
1903 cmd := fmt.Sprintf(format, args...)
1904 if dir != "" && dir != "/" {
1905 cmd = strings.Replace(" "+cmd, " "+dir, " .", -1)[1:]
1906 if b.scriptDir != dir {
1908 cmd = "cd " + dir + "\n" + cmd
1912 cmd = strings.Replace(cmd, b.work, "$WORK", -1)
1917 // showcmd prints the given command to standard output
1918 // for the implementation of -n or -x.
1919 func (b *builder) showcmd(dir string, format string, args ...interface{}) {
1921 defer b.output.Unlock()
1922 b.print(b.fmtcmd(dir, format, args...) + "\n")
1925 // showOutput prints "# desc" followed by the given output.
1926 // The output is expected to contain references to 'dir', usually
1927 // the source directory for the package that has failed to build.
1928 // showOutput rewrites mentions of dir with a relative path to dir
1929 // when the relative path is shorter. This is usually more pleasant.
1930 // For example, if fmt doesn't compile and we are in src/html,
1935 // ../fmt/print.go:1090: undefined: asdf
1942 // /usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
1945 // showOutput also replaces references to the work directory with $WORK.
1947 func (b *builder) showOutput(dir, desc, out string) {
1948 prefix := "# " + desc
1949 suffix := "\n" + out
1950 if reldir := shortPath(dir); reldir != dir {
1951 suffix = strings.Replace(suffix, " "+dir, " "+reldir, -1)
1952 suffix = strings.Replace(suffix, "\n"+dir, "\n"+reldir, -1)
1954 suffix = strings.Replace(suffix, " "+b.work, " $WORK", -1)
1957 defer b.output.Unlock()
1958 b.print(prefix, suffix)
1961 // shortPath returns an absolute or relative name for path, whatever is shorter.
1962 func shortPath(path string) string {
1963 if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) {
1969 // relPaths returns a copy of paths with absolute paths
1970 // made relative to the current directory if they would be shorter.
1971 func relPaths(paths []string) []string {
1973 pwd, _ := os.Getwd()
1974 for _, p := range paths {
1975 rel, err := filepath.Rel(pwd, p)
1976 if err == nil && len(rel) < len(p) {
1979 out = append(out, p)
1984 // errPrintedOutput is a special error indicating that a command failed
1985 // but that it generated output as well, and that output has already
1986 // been printed, so there's no point showing 'exit status 1' or whatever
1987 // the wait status was. The main executor, builder.do, knows not to
1988 // print this error.
1989 var errPrintedOutput = errors.New("already printed output - no need to show error")
1991 var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.cgo1\.go:[0-9]+\]`)
1992 var cgoTypeSigRe = regexp.MustCompile(`\b_Ctype_\B`)
1994 // run runs the command given by cmdline in the directory dir.
1995 // If the command fails, run prints information about the failure
1996 // and returns a non-nil error.
1997 func (b *builder) run(dir string, desc string, env []string, cmdargs ...interface{}) error {
1998 out, err := b.runOut(dir, desc, env, cmdargs...)
2001 desc = b.fmtcmd(dir, "%s", strings.Join(stringList(cmdargs...), " "))
2003 b.showOutput(dir, desc, b.processOutput(out))
2005 err = errPrintedOutput
2011 // processOutput prepares the output of runOut to be output to the console.
2012 func (b *builder) processOutput(out []byte) string {
2013 if out[len(out)-1] != '\n' {
2014 out = append(out, '\n')
2016 messages := string(out)
2017 // Fix up output referring to cgo-generated code to be more readable.
2018 // Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
2019 // Replace *[100]_Ctype_foo with *[100]C.foo.
2020 // If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
2021 if !buildX && cgoLine.MatchString(messages) {
2022 messages = cgoLine.ReplaceAllString(messages, "")
2023 messages = cgoTypeSigRe.ReplaceAllString(messages, "C.")
2028 // runOut runs the command given by cmdline in the directory dir.
2029 // It returns the command output and any errors that occurred.
2030 func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) {
2031 cmdline := stringList(cmdargs...)
2032 if buildN || buildX {
2033 var envcmdline string
2034 for i := range env {
2035 envcmdline += env[i]
2038 envcmdline += joinUnambiguously(cmdline)
2039 b.showcmd(dir, "%s", envcmdline)
2047 var buf bytes.Buffer
2048 cmd := exec.Command(cmdline[0], cmdline[1:]...)
2052 cmd.Env = mergeEnvLists(env, envForDir(cmd.Dir, os.Environ()))
2055 // cmd.Run will fail on Unix if some other process has the binary
2056 // we want to run open for writing. This can happen here because
2057 // we build and install the cgo command and then run it.
2058 // If another command was kicked off while we were writing the
2059 // cgo binary, the child process for that command may be holding
2060 // a reference to the fd, keeping us from running exec.
2062 // But, you might reasonably wonder, how can this happen?
2063 // The cgo fd, like all our fds, is close-on-exec, so that we need
2064 // not worry about other processes inheriting the fd accidentally.
2065 // The answer is that running a command is fork and exec.
2066 // A child forked while the cgo fd is open inherits that fd.
2067 // Until the child has called exec, it holds the fd open and the
2068 // kernel will not let us run cgo. Even if the child were to close
2069 // the fd explicitly, it would still be open from the time of the fork
2070 // until the time of the explicit close, and the race would remain.
2072 // On Unix systems, this results in ETXTBSY, which formats
2073 // as "text file busy". Rather than hard-code specific error cases,
2074 // we just look for that string. If this happens, sleep a little
2075 // and try again. We let this happen three times, with increasing
2076 // sleep lengths: 100+200+400 ms = 0.7 seconds.
2078 // An alternate solution might be to split the cmd.Run into
2079 // separate cmd.Start and cmd.Wait, and then use an RWLock
2080 // to make sure that copyFile only executes when no cmd.Start
2081 // call is in progress. However, cmd.Start (really syscall.forkExec)
2082 // only guarantees that when it returns, the exec is committed to
2083 // happen and succeed. It uses a close-on-exec file descriptor
2084 // itself to determine this, so we know that when cmd.Start returns,
2085 // at least one close-on-exec file descriptor has been closed.
2086 // However, we cannot be sure that all of them have been closed,
2087 // so the program might still encounter ETXTBSY even with such
2088 // an RWLock. The race window would be smaller, perhaps, but not
2089 // guaranteed to be gone.
2091 // Sleeping when we observe the race seems to be the most reliable
2094 // https://golang.org/issue/3001
2096 if err != nil && nbusy < 3 && strings.Contains(err.Error(), "text file busy") {
2097 time.Sleep(100 * time.Millisecond << uint(nbusy))
2102 // err can be something like 'exit status 1'.
2103 // Add information about what program was running.
2104 // Note that if buf.Bytes() is non-empty, the caller usually
2105 // shows buf.Bytes() and does not print err at all, so the
2106 // prefix here does not make most output any more verbose.
2108 err = errors.New(cmdline[0] + ": " + err.Error())
2110 return buf.Bytes(), err
2114 // joinUnambiguously prints the slice, quoting where necessary to make the
2115 // output unambiguous.
2116 // TODO: See issue 5279. The printing of commands needs a complete redo.
2117 func joinUnambiguously(a []string) string {
2118 var buf bytes.Buffer
2119 for i, s := range a {
2123 q := strconv.Quote(s)
2124 if s == "" || strings.Contains(s, " ") || len(q) > len(s)+2 {
2133 // mkdir makes the named directory.
2134 func (b *builder) mkdir(dir string) error {
2136 defer b.exec.Unlock()
2137 // We can be a little aggressive about being
2138 // sure directories exist. Skip repeated calls.
2139 if b.mkdirCache[dir] {
2142 b.mkdirCache[dir] = true
2144 if buildN || buildX {
2145 b.showcmd("", "mkdir -p %s", dir)
2151 if err := os.MkdirAll(dir, 0777); err != nil {
2157 // mkAbs returns an absolute path corresponding to
2158 // evaluating f in the directory dir.
2159 // We always pass absolute paths of source files so that
2160 // the error messages will include the full path to a file
2161 // in need of attention.
2162 func mkAbs(dir, f string) string {
2163 // Leave absolute paths alone.
2164 // Also, during -n mode we use the pseudo-directory $WORK
2165 // instead of creating an actual work directory that won't be used.
2166 // Leave paths beginning with $WORK alone too.
2167 if filepath.IsAbs(f) || strings.HasPrefix(f, "$WORK") {
2170 return filepath.Join(dir, f)
2173 type toolchain interface {
2174 // gc runs the compiler in a specific directory on a set of files
2175 // and returns the name of the generated output file.
2176 // The compiler runs in the directory dir.
2177 gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error)
2178 // cc runs the toolchain's C compiler in a directory on a C file
2179 // to produce an output file.
2180 cc(b *builder, p *Package, objdir, ofile, cfile string) error
2181 // asm runs the assembler in a specific directory on a specific file
2182 // to generate the named output file.
2183 asm(b *builder, p *Package, obj, ofile, sfile string) error
2184 // pkgpath builds an appropriate path for a temporary package file.
2185 pkgpath(basedir string, p *Package) string
2186 // pack runs the archive packer in a specific directory to create
2187 // an archive from a set of object files.
2188 // typically it is run in the object directory.
2189 pack(b *builder, p *Package, objDir, afile string, ofiles []string) error
2190 // ld runs the linker to create an executable starting at mainpkg.
2191 ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error
2192 // ldShared runs the linker to create a shared library containing the pkgs built by toplevelactions
2193 ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error
2199 type noToolchain struct{}
2201 func noCompiler() error {
2202 log.Fatalf("unknown compiler %q", buildContext.Compiler)
2206 func (noToolchain) compiler() string {
2211 func (noToolchain) linker() string {
2216 func (noToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error) {
2217 return "", nil, noCompiler()
2220 func (noToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
2224 func (noToolchain) pkgpath(basedir string, p *Package) string {
2229 func (noToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
2233 func (noToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error {
2237 func (noToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
2241 func (noToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
2245 // The Go toolchain.
2246 type gcToolchain struct{}
2248 func (gcToolchain) compiler() string {
2249 return tool("compile")
2252 func (gcToolchain) linker() string {
2256 func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
2264 gcargs := []string{"-p", p.ImportPath}
2265 if p.Name == "main" {
2268 if p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal")) {
2269 // runtime compiles with a special gc flag to emit
2270 // additional reflect type data.
2271 gcargs = append(gcargs, "-+")
2274 // If we're giving the compiler the entire package (no C etc files), tell it that,
2275 // so that it can give good error messages about forward declarations.
2276 // Exceptions: a few standard packages have forward declarations for
2277 // pieces supplied behind-the-scenes by package runtime.
2278 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)
2280 switch p.ImportPath {
2281 case "bytes", "net", "os", "runtime/pprof", "sync", "time":
2286 gcargs = append(gcargs, "-complete")
2288 if buildContext.InstallSuffix != "" {
2289 gcargs = append(gcargs, "-installsuffix", buildContext.InstallSuffix)
2291 if p.buildID != "" {
2292 gcargs = append(gcargs, "-buildid", p.buildID)
2295 for _, path := range p.Imports {
2296 if i := strings.LastIndex(path, "/vendor/"); i >= 0 {
2297 gcargs = append(gcargs, "-importmap", path[i+len("/vendor/"):]+"="+path)
2298 } else if strings.HasPrefix(path, "vendor/") {
2299 gcargs = append(gcargs, "-importmap", path[len("vendor/"):]+"="+path)
2303 args := []interface{}{buildToolExec, tool("compile"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs}
2304 if ofile == archive {
2305 args = append(args, "-pack")
2308 args = append(args, "-asmhdr", obj+"go_asm.h")
2310 for _, f := range gofiles {
2311 args = append(args, mkAbs(p.Dir, f))
2314 output, err = b.runOut(p.Dir, p.ImportPath, nil, args...)
2315 return ofile, output, err
2318 func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
2319 // Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
2320 inc := filepath.Join(goroot, "pkg", "include")
2321 sfile = mkAbs(p.Dir, sfile)
2322 args := []interface{}{buildToolExec, tool("asm"), "-o", ofile, "-trimpath", b.work, "-I", obj, "-I", inc, "-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch, buildAsmflags, sfile}
2323 if err := b.run(p.Dir, p.ImportPath, nil, args...); err != nil {
2329 // toolVerify checks that the command line args writes the same output file
2330 // if run using newTool instead.
2331 // Unused now but kept around for future use.
2332 func toolVerify(b *builder, p *Package, newTool string, ofile string, args []interface{}) error {
2333 newArgs := make([]interface{}, len(args))
2335 newArgs[1] = tool(newTool)
2336 newArgs[3] = ofile + ".new" // x.6 becomes x.6.new
2337 if err := b.run(p.Dir, p.ImportPath, nil, newArgs...); err != nil {
2340 data1, err := ioutil.ReadFile(ofile)
2344 data2, err := ioutil.ReadFile(ofile + ".new")
2348 if !bytes.Equal(data1, data2) {
2349 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...), " "))
2351 os.Remove(ofile + ".new")
2355 func (gcToolchain) pkgpath(basedir string, p *Package) string {
2356 end := filepath.FromSlash(p.ImportPath + ".a")
2357 return filepath.Join(basedir, end)
2360 func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
2361 var absOfiles []string
2362 for _, f := range ofiles {
2363 absOfiles = append(absOfiles, mkAbs(objDir, f))
2365 absAfile := mkAbs(objDir, afile)
2367 // The archive file should have been created by the compiler.
2368 // Since it used to not work that way, verify.
2370 if _, err := os.Stat(absAfile); err != nil {
2371 fatalf("os.Stat of archive file failed: %v", err)
2375 if buildN || buildX {
2376 cmdline := stringList("pack", "r", absAfile, absOfiles)
2377 b.showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline))
2382 if err := packInternal(b, absAfile, absOfiles); err != nil {
2383 b.showOutput(p.Dir, p.ImportPath, err.Error()+"\n")
2384 return errPrintedOutput
2389 func packInternal(b *builder, afile string, ofiles []string) error {
2390 dst, err := os.OpenFile(afile, os.O_WRONLY|os.O_APPEND, 0)
2394 defer dst.Close() // only for error returns or panics
2395 w := bufio.NewWriter(dst)
2397 for _, ofile := range ofiles {
2398 src, err := os.Open(ofile)
2402 fi, err := src.Stat()
2407 // Note: Not using %-16.16s format because we care
2408 // about bytes, not runes.
2413 name += strings.Repeat(" ", 16-len(name))
2416 fmt.Fprintf(w, "%s%-12d%-6d%-6d%-8o%-10d`\n",
2417 name, 0, 0, 0, 0644, size)
2418 n, err := io.Copy(w, src)
2420 if err == nil && n < size {
2421 err = io.ErrUnexpectedEOF
2422 } else if err == nil && n > size {
2423 err = fmt.Errorf("file larger than size reported by stat")
2426 return fmt.Errorf("copying %s to %s: %v", ofile, afile, err)
2433 if err := w.Flush(); err != nil {
2439 // setextld sets the appropriate linker flags for the specified compiler.
2440 func setextld(ldflags []string, compiler []string) []string {
2441 for _, f := range ldflags {
2442 if f == "-extld" || strings.HasPrefix(f, "-extld=") {
2443 // don't override -extld if supplied
2447 ldflags = append(ldflags, "-extld="+compiler[0])
2448 if len(compiler) > 1 {
2450 add := strings.Join(compiler[1:], " ")
2451 for i, f := range ldflags {
2452 if f == "-extldflags" && i+1 < len(ldflags) {
2453 ldflags[i+1] = add + " " + ldflags[i+1]
2456 } else if strings.HasPrefix(f, "-extldflags=") {
2457 ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
2463 ldflags = append(ldflags, "-extldflags="+add)
2469 func (gcToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error {
2470 importArgs := b.includeArgs("-L", allactions)
2471 cxx := len(root.p.CXXFiles) > 0 || len(root.p.SwigCXXFiles) > 0
2472 for _, a := range allactions {
2473 if a.p != nil && (len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0) {
2477 var ldflags []string
2478 if buildContext.InstallSuffix != "" {
2479 ldflags = append(ldflags, "-installsuffix", buildContext.InstallSuffix)
2481 if root.p.omitDWARF {
2482 ldflags = append(ldflags, "-w")
2485 // If the user has not specified the -extld option, then specify the
2486 // appropriate linker. In case of C++ code, use the compiler named
2487 // by the CXX environment variable or defaultCXX if CXX is not set.
2488 // Else, use the CC environment variable and defaultCC as fallback.
2489 var compiler []string
2491 compiler = envList("CXX", defaultCXX)
2493 compiler = envList("CC", defaultCC)
2495 ldflags = setextld(ldflags, compiler)
2496 ldflags = append(ldflags, "-buildmode="+ldBuildmode)
2497 if root.p.buildID != "" {
2498 ldflags = append(ldflags, "-buildid="+root.p.buildID)
2500 ldflags = append(ldflags, buildLdflags...)
2502 // On OS X when using external linking to build a shared library,
2503 // the argument passed here to -o ends up recorded in the final
2504 // shared library in the LC_ID_DYLIB load command.
2505 // To avoid putting the temporary output directory name there
2506 // (and making the resulting shared library useless),
2507 // run the link in the output directory so that -o can name
2508 // just the final path element.
2510 if goos == "darwin" && buildBuildmode == "c-shared" {
2511 dir, out = filepath.Split(out)
2514 return b.run(dir, root.p.ImportPath, nil, buildToolExec, tool("link"), "-o", out, importArgs, ldflags, mainpkg)
2517 func (gcToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
2518 importArgs := b.includeArgs("-L", allactions)
2519 ldflags := []string{"-installsuffix", buildContext.InstallSuffix}
2520 ldflags = append(ldflags, "-buildmode=shared")
2521 ldflags = append(ldflags, buildLdflags...)
2523 for _, a := range allactions {
2524 if a.p != nil && (len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0) {
2528 // If the user has not specified the -extld option, then specify the
2529 // appropriate linker. In case of C++ code, use the compiler named
2530 // by the CXX environment variable or defaultCXX if CXX is not set.
2531 // Else, use the CC environment variable and defaultCC as fallback.
2532 var compiler []string
2534 compiler = envList("CXX", defaultCXX)
2536 compiler = envList("CC", defaultCC)
2538 ldflags = setextld(ldflags, compiler)
2539 for _, d := range toplevelactions {
2540 if !strings.HasSuffix(d.target, ".a") { // omit unsafe etc and actions for other shared libraries
2543 ldflags = append(ldflags, d.p.ImportPath+"="+d.target)
2545 return b.run(".", out, nil, buildToolExec, tool("link"), "-o", out, importArgs, ldflags)
2548 func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
2549 return fmt.Errorf("%s: C source files not supported without cgo", mkAbs(p.Dir, cfile))
2552 // The Gccgo toolchain.
2553 type gccgoToolchain struct{}
2555 var gccgoName, gccgoBin string
2558 gccgoName = os.Getenv("GCCGO")
2559 if gccgoName == "" {
2562 gccgoBin, _ = exec.LookPath(gccgoName)
2565 func (gccgoToolchain) compiler() string {
2569 func (gccgoToolchain) linker() string {
2573 func (tools gccgoToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
2576 gcargs := []string{"-g"}
2577 gcargs = append(gcargs, b.gccArchArgs()...)
2578 if pkgpath := gccgoPkgpath(p); pkgpath != "" {
2579 gcargs = append(gcargs, "-fgo-pkgpath="+pkgpath)
2581 if p.localPrefix != "" {
2582 gcargs = append(gcargs, "-fgo-relative-import-path="+p.localPrefix)
2584 args := stringList(tools.compiler(), importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags)
2585 for _, f := range gofiles {
2586 args = append(args, mkAbs(p.Dir, f))
2589 output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
2590 return ofile, output, err
2593 func (tools gccgoToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
2594 sfile = mkAbs(p.Dir, sfile)
2595 defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
2596 if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
2597 defs = append(defs, `-D`, `GOPKGPATH=`+pkgpath)
2599 defs = tools.maybePIC(defs)
2600 defs = append(defs, b.gccArchArgs()...)
2601 return b.run(p.Dir, p.ImportPath, nil, tools.compiler(), "-xassembler-with-cpp", "-I", obj, "-c", "-o", ofile, defs, sfile)
2604 func (gccgoToolchain) pkgpath(basedir string, p *Package) string {
2605 end := filepath.FromSlash(p.ImportPath + ".a")
2606 afile := filepath.Join(basedir, end)
2607 // add "lib" to the final element
2608 return filepath.Join(filepath.Dir(afile), "lib"+filepath.Base(afile))
2611 func (gccgoToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
2612 var absOfiles []string
2613 for _, f := range ofiles {
2614 absOfiles = append(absOfiles, mkAbs(objDir, f))
2616 return b.run(p.Dir, p.ImportPath, nil, "ar", "rc", mkAbs(objDir, afile), absOfiles)
2619 func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error {
2620 // gccgo needs explicit linking with all package dependencies,
2621 // and all LDFLAGS from cgo dependencies.
2622 apackagePathsSeen := make(map[string]bool)
2623 afiles := []string{}
2624 shlibs := []string{}
2625 ldflags := b.gccArchArgs()
2626 cgoldflags := []string{}
2628 cxx := len(root.p.CXXFiles) > 0 || len(root.p.SwigCXXFiles) > 0
2629 objc := len(root.p.MFiles) > 0
2630 fortran := len(root.p.FFiles) > 0
2632 readCgoFlags := func(flagsFile string) error {
2633 flags, err := ioutil.ReadFile(flagsFile)
2637 const ldflagsPrefix = "_CGO_LDFLAGS="
2638 for _, line := range strings.Split(string(flags), "\n") {
2639 if strings.HasPrefix(line, ldflagsPrefix) {
2640 newFlags := strings.Fields(line[len(ldflagsPrefix):])
2641 for _, flag := range newFlags {
2642 // Every _cgo_flags file has -g and -O2 in _CGO_LDFLAGS
2643 // but they don't mean anything to the linker so filter
2645 if flag != "-g" && !strings.HasPrefix(flag, "-O") {
2646 cgoldflags = append(cgoldflags, flag)
2654 readAndRemoveCgoFlags := func(archive string) (string, error) {
2655 newa, err := ioutil.TempFile(b.work, filepath.Base(archive))
2659 olda, err := os.Open(archive)
2663 _, err = io.Copy(newa, olda)
2676 newarchive := newa.Name()
2677 err = b.run(b.work, root.p.ImportPath, nil, "ar", "x", newarchive, "_cgo_flags")
2681 err = b.run(".", root.p.ImportPath, nil, "ar", "d", newarchive, "_cgo_flags")
2685 err = readCgoFlags(filepath.Join(b.work, "_cgo_flags"))
2689 return newarchive, nil
2692 actionsSeen := make(map[*action]bool)
2693 // Make a pre-order depth-first traversal of the action graph, taking note of
2694 // whether a shared library action has been seen on the way to an action (the
2695 // construction of the graph means that if any path to a node passes through
2696 // a shared library action, they all do).
2697 var walk func(a *action, seenShlib bool)
2699 walk = func(a *action, seenShlib bool) {
2703 actionsSeen[a] = true
2704 if a.p != nil && !seenShlib {
2708 // We record the target of the first time we see a .a file
2709 // for a package to make sure that we prefer the 'install'
2710 // rather than the 'build' location (which may not exist any
2711 // more). We still need to traverse the dependencies of the
2712 // build action though so saying
2713 // if apackagePathsSeen[a.p.ImportPath] { return }
2715 if !apackagePathsSeen[a.p.ImportPath] {
2716 apackagePathsSeen[a.p.ImportPath] = true
2718 if len(a.p.CgoFiles) > 0 {
2719 target, err = readAndRemoveCgoFlags(target)
2724 afiles = append(afiles, target)
2727 if strings.HasSuffix(a.target, ".so") {
2728 shlibs = append(shlibs, a.target)
2731 for _, a1 := range a.deps {
2738 for _, a1 := range root.deps {
2745 for _, a := range allactions {
2746 // Gather CgoLDFLAGS, but not from standard packages.
2747 // The go tool can dig up runtime/cgo from GOROOT and
2748 // think that it should use its CgoLDFLAGS, but gccgo
2749 // doesn't use runtime/cgo.
2754 cgoldflags = append(cgoldflags, a.p.CgoLDFLAGS...)
2756 if len(a.p.CgoFiles) > 0 {
2762 if len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0 {
2765 if len(a.p.MFiles) > 0 {
2768 if len(a.p.FFiles) > 0 {
2773 for i, o := range ofiles {
2774 if filepath.Base(o) == "_cgo_flags" {
2776 ofiles = append(ofiles[:i], ofiles[i+1:]...)
2781 ldflags = append(ldflags, "-Wl,--whole-archive")
2782 ldflags = append(ldflags, afiles...)
2783 ldflags = append(ldflags, "-Wl,--no-whole-archive")
2785 ldflags = append(ldflags, cgoldflags...)
2786 ldflags = append(ldflags, envList("CGO_LDFLAGS", "")...)
2787 ldflags = append(ldflags, root.p.CgoLDFLAGS...)
2789 ldflags = stringList("-Wl,-(", ldflags, "-Wl,-)")
2791 for _, shlib := range shlibs {
2794 "-L"+filepath.Dir(shlib),
2795 "-Wl,-rpath="+filepath.Dir(shlib),
2796 "-l"+strings.TrimSuffix(
2797 strings.TrimPrefix(filepath.Base(shlib), "lib"),
2802 switch ldBuildmode {
2804 if usesCgo && goos == "linux" {
2805 ldflags = append(ldflags, "-Wl,-E")
2809 // Link the Go files into a single .o, and also link
2812 // We need to use --whole-archive with -lgolibbegin
2813 // because it doesn't define any symbols that will
2814 // cause the contents to be pulled in; it's just
2815 // initialization code.
2817 // The user remains responsible for linking against
2818 // -lgo -lpthread -lm in the final link. We can't use
2819 // -r to pick them up because we can't combine
2820 // split-stack and non-split-stack code in a single -r
2821 // link, and libgo picks up non-split-stack code from
2823 ldflags = append(ldflags, "-Wl,-r", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive")
2825 if b.gccSupportsNoPie() {
2826 ldflags = append(ldflags, "-no-pie")
2829 // We are creating an object file, so we don't want a build ID.
2830 ldflags = b.disableBuildID(ldflags)
2836 ldflags = append(ldflags, "-shared", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive", "-lgo", "-lgcc_s", "-lgcc", "-lc", "-lgcc")
2839 fatalf("-buildmode=%s not supported for gccgo", ldBuildmode)
2842 switch ldBuildmode {
2843 case "exe", "c-shared":
2845 ldflags = append(ldflags, "-lstdc++")
2848 ldflags = append(ldflags, "-lobjc")
2851 fc := os.Getenv("FC")
2855 // support gfortran out of the box and let others pass the correct link options
2857 if strings.Contains(fc, "gfortran") {
2858 ldflags = append(ldflags, "-lgfortran")
2863 if err := b.run(".", root.p.ImportPath, nil, tools.linker(), "-o", out, ofiles, ldflags, buildGccgoflags); err != nil {
2867 switch ldBuildmode {
2869 if err := b.run(".", root.p.ImportPath, nil, "ar", "rc", realOut, out); err != nil {
2876 func (tools gccgoToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
2877 args := []string{"-o", out, "-shared", "-nostdlib", "-zdefs", "-Wl,--whole-archive"}
2878 for _, a := range toplevelactions {
2879 args = append(args, a.target)
2881 args = append(args, "-Wl,--no-whole-archive", "-shared", "-nostdlib", "-lgo", "-lgcc_s", "-lgcc", "-lc")
2882 shlibs := []string{}
2883 for _, a := range allactions {
2884 if strings.HasSuffix(a.target, ".so") {
2885 shlibs = append(shlibs, a.target)
2888 for _, shlib := range shlibs {
2891 "-L"+filepath.Dir(shlib),
2892 "-Wl,-rpath="+filepath.Dir(shlib),
2893 "-l"+strings.TrimSuffix(
2894 strings.TrimPrefix(filepath.Base(shlib), "lib"),
2897 return b.run(".", out, nil, tools.linker(), args, buildGccgoflags)
2900 func (tools gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
2901 inc := filepath.Join(goroot, "pkg", "include")
2902 cfile = mkAbs(p.Dir, cfile)
2903 defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
2904 defs = append(defs, b.gccArchArgs()...)
2905 if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
2906 defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
2909 case "386", "amd64":
2910 defs = append(defs, "-fsplit-stack")
2912 defs = tools.maybePIC(defs)
2913 return b.run(p.Dir, p.ImportPath, nil, envList("CC", defaultCC), "-Wall", "-g",
2914 "-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile)
2917 // maybePIC adds -fPIC to the list of arguments if needed.
2918 func (tools gccgoToolchain) maybePIC(args []string) []string {
2919 switch buildBuildmode {
2920 case "c-shared", "shared":
2921 args = append(args, "-fPIC")
2926 func gccgoPkgpath(p *Package) string {
2927 if p.build.IsCommand() && !p.forceLibrary {
2933 func gccgoCleanPkgpath(p *Package) string {
2934 clean := func(r rune) rune {
2936 case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
2937 '0' <= r && r <= '9':
2942 return strings.Map(clean, gccgoPkgpath(p))
2945 // gcc runs the gcc C compiler to create an object from a single C file.
2946 func (b *builder) gcc(p *Package, out string, flags []string, cfile string) error {
2947 return b.ccompile(p, out, flags, cfile, b.gccCmd(p.Dir))
2950 // gxx runs the g++ C++ compiler to create an object from a single C++ file.
2951 func (b *builder) gxx(p *Package, out string, flags []string, cxxfile string) error {
2952 return b.ccompile(p, out, flags, cxxfile, b.gxxCmd(p.Dir))
2955 // gfortran runs the gfortran Fortran compiler to create an object from a single Fortran file.
2956 func (b *builder) gfortran(p *Package, out string, flags []string, ffile string) error {
2957 return b.ccompile(p, out, flags, ffile, b.gfortranCmd(p.Dir))
2960 // ccompile runs the given C or C++ compiler and creates an object from a single source file.
2961 func (b *builder) ccompile(p *Package, out string, flags []string, file string, compiler []string) error {
2962 file = mkAbs(p.Dir, file)
2963 return b.run(p.Dir, p.ImportPath, nil, compiler, flags, "-o", out, "-c", file)
2966 // gccld runs the gcc linker to create an executable from a set of object files.
2967 func (b *builder) gccld(p *Package, out string, flags []string, obj []string) error {
2969 if len(p.CXXFiles) > 0 || len(p.SwigCXXFiles) > 0 {
2970 cmd = b.gxxCmd(p.Dir)
2972 cmd = b.gccCmd(p.Dir)
2974 return b.run(p.Dir, p.ImportPath, nil, cmd, "-o", out, obj, flags)
2977 // gccCmd returns a gcc command line prefix
2978 // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
2979 func (b *builder) gccCmd(objdir string) []string {
2980 return b.ccompilerCmd("CC", defaultCC, objdir)
2983 // gxxCmd returns a g++ command line prefix
2984 // defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
2985 func (b *builder) gxxCmd(objdir string) []string {
2986 return b.ccompilerCmd("CXX", defaultCXX, objdir)
2989 // gfortranCmd returns a gfortran command line prefix.
2990 func (b *builder) gfortranCmd(objdir string) []string {
2991 return b.ccompilerCmd("FC", "gfortran", objdir)
2994 // ccompilerCmd returns a command line prefix for the given environment
2995 // variable and using the default command when the variable is empty.
2996 func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
2997 // NOTE: env.go's mkEnv knows that the first three
2998 // strings returned are "gcc", "-I", objdir (and cuts them off).
3000 compiler := envList(envvar, defcmd)
3001 a := []string{compiler[0], "-I", objdir}
3002 a = append(a, compiler[1:]...)
3004 // Definitely want -fPIC but on Windows gcc complains
3005 // "-fPIC ignored for target (all code is position independent)"
3006 if goos != "windows" {
3007 a = append(a, "-fPIC")
3009 a = append(a, b.gccArchArgs()...)
3010 // gcc-4.5 and beyond require explicit "-pthread" flag
3011 // for multithreading with pthread library.
3012 if buildContext.CgoEnabled {
3015 a = append(a, "-mthreads")
3017 a = append(a, "-pthread")
3021 if strings.Contains(a[0], "clang") {
3022 // disable ASCII art in clang errors, if possible
3023 a = append(a, "-fno-caret-diagnostics")
3024 // clang is too smart about command-line arguments
3025 a = append(a, "-Qunused-arguments")
3028 // disable word wrapping in error messages
3029 a = append(a, "-fmessage-length=0")
3031 // Tell gcc not to include the work directory in object files.
3032 if b.gccSupportsFlag("-fdebug-prefix-map=a=b") {
3033 a = append(a, "-fdebug-prefix-map="+b.work+"=/tmp/go-build")
3036 // Tell gcc not to include flags in object files, which defeats the
3037 // point of -fdebug-prefix-map above.
3038 if b.gccSupportsFlag("-gno-record-gcc-switches") {
3039 a = append(a, "-gno-record-gcc-switches")
3042 // On OS X, some of the compilers behave as if -fno-common
3043 // is always set, and the Mach-O linker in 6l/8l assumes this.
3044 // See https://golang.org/issue/3253.
3045 if goos == "darwin" {
3046 a = append(a, "-fno-common")
3052 // On systems with PIE (position independent executables) enabled by default,
3053 // -no-pie must be passed when doing a partial link with -Wl,-r. But -no-pie is
3054 // not supported by all compilers.
3055 func (b *builder) gccSupportsNoPie() bool {
3056 return b.gccSupportsFlag("-no-pie")
3059 // gccSupportsFlag checks to see if the compiler supports a flag.
3060 func (b *builder) gccSupportsFlag(flag string) bool {
3062 defer b.exec.Unlock()
3063 if b, ok := b.flagCache[flag]; ok {
3066 if b.flagCache == nil {
3067 src := filepath.Join(b.work, "trivial.c")
3068 if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
3071 b.flagCache = make(map[string]bool)
3073 cmdArgs := append(envList("CC", defaultCC), flag, "-c", "trivial.c")
3074 if buildN || buildX {
3075 b.showcmd(b.work, "%s", joinUnambiguously(cmdArgs))
3080 cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
3082 cmd.Env = envForDir(cmd.Dir, os.Environ())
3083 out, err := cmd.CombinedOutput()
3084 supported := err == nil && !bytes.Contains(out, []byte("unrecognized"))
3085 b.flagCache[flag] = supported
3089 // gccArchArgs returns arguments to pass to gcc based on the architecture.
3090 func (b *builder) gccArchArgs() []string {
3093 return []string{"-m32"}
3094 case "amd64", "amd64p32":
3095 return []string{"-m64"}
3097 return []string{"-marm"} // not thumb
3099 return []string{"-m64", "-march=z196"}
3104 // envList returns the value of the given environment variable broken
3105 // into fields, using the default value when the variable is empty.
3106 func envList(key, def string) []string {
3111 return strings.Fields(v)
3114 // Return the flags to use when invoking the C, C++ or Fortran compilers, or cgo.
3115 func (b *builder) cflags(p *Package, def bool) (cppflags, cflags, cxxflags, fflags, ldflags []string) {
3121 cppflags = stringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS)
3122 cflags = stringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS)
3123 cxxflags = stringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS)
3124 fflags = stringList(envList("CGO_FFLAGS", defaults), p.CgoFFLAGS)
3125 ldflags = stringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS)
3129 var cgoRe = regexp.MustCompile(`[/\\:]`)
3131 func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofiles, gccfiles, gxxfiles, mfiles, ffiles []string) (outGo, outObj []string, err error) {
3132 cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoFFLAGS, cgoLDFLAGS := b.cflags(p, true)
3133 _, cgoexeCFLAGS, _, _, _ := b.cflags(p, false)
3134 cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...)
3135 cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...)
3136 // If we are compiling Objective-C code, then we need to link against libobjc
3137 if len(mfiles) > 0 {
3138 cgoLDFLAGS = append(cgoLDFLAGS, "-lobjc")
3141 // Likewise for Fortran, except there are many Fortran compilers.
3142 // Support gfortran out of the box and let others pass the correct link options
3144 if len(ffiles) > 0 {
3145 fc := os.Getenv("FC")
3149 if strings.Contains(fc, "gfortran") {
3150 cgoLDFLAGS = append(cgoLDFLAGS, "-lgfortran")
3154 if buildMSan && p.ImportPath != "runtime/cgo" {
3155 cgoCFLAGS = append([]string{"-fsanitize=memory"}, cgoCFLAGS...)
3156 cgoLDFLAGS = append([]string{"-fsanitize=memory"}, cgoLDFLAGS...)
3159 // Allows including _cgo_export.h from .[ch] files in the package.
3160 cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", obj)
3164 gofiles := []string{obj + "_cgo_gotypes.go"}
3165 cfiles := []string{"_cgo_main.c", "_cgo_export.c"}
3166 for _, fn := range cgofiles {
3167 f := cgoRe.ReplaceAllString(fn[:len(fn)-2], "_")
3168 gofiles = append(gofiles, obj+f+"cgo1.go")
3169 cfiles = append(cfiles, f+"cgo2.c")
3171 defunC := obj + "_cgo_defun.c"
3173 cgoflags := []string{}
3174 // TODO: make cgo not depend on $GOARCH?
3176 if p.Standard && p.ImportPath == "runtime/cgo" {
3177 cgoflags = append(cgoflags, "-import_runtime_cgo=false")
3179 if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/msan" || p.ImportPath == "runtime/cgo") {
3180 cgoflags = append(cgoflags, "-import_syscall=false")
3183 // Update $CGO_LDFLAGS with p.CgoLDFLAGS.
3185 if len(cgoLDFLAGS) > 0 {
3186 flags := make([]string, len(cgoLDFLAGS))
3187 for i, f := range cgoLDFLAGS {
3188 flags[i] = strconv.Quote(f)
3190 cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
3193 if _, ok := buildToolchain.(gccgoToolchain); ok {
3195 case "386", "amd64":
3196 cgoCFLAGS = append(cgoCFLAGS, "-fsplit-stack")
3198 cgoflags = append(cgoflags, "-gccgo")
3199 if pkgpath := gccgoPkgpath(p); pkgpath != "" {
3200 cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
3204 switch buildBuildmode {
3205 case "c-archive", "c-shared":
3206 // Tell cgo that if there are any exported functions
3207 // it should generate a header file that C code can
3209 cgoflags = append(cgoflags, "-exportheader="+obj+"_cgo_install.h")
3212 if err := b.run(p.Dir, p.ImportPath, cgoenv, buildToolExec, cgoExe, "-objdir", obj, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoexeCFLAGS, cgofiles); err != nil {
3213 return nil, nil, err
3215 outGo = append(outGo, gofiles...)
3218 _, gccgo := buildToolchain.(gccgoToolchain)
3220 defunObj := obj + "_cgo_defun.o"
3221 if err := buildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
3222 return nil, nil, err
3224 outObj = append(outObj, defunObj)
3228 var linkobj []string
3230 var bareLDFLAGS []string
3231 // When linking relocatable objects, various flags need to be
3232 // filtered out as they are inapplicable and can cause some linkers
3234 for i := 0; i < len(cgoLDFLAGS); i++ {
3237 // skip "-lc" or "-l somelib"
3238 case strings.HasPrefix(f, "-l"):
3242 // skip "-framework X" on Darwin
3243 case goos == "darwin" && f == "-framework":
3245 // skip "*.{dylib,so,dll}"
3246 case strings.HasSuffix(f, ".dylib"),
3247 strings.HasSuffix(f, ".so"),
3248 strings.HasSuffix(f, ".dll"):
3249 // Remove any -fsanitize=foo flags.
3250 // Otherwise the compiler driver thinks that we are doing final link
3251 // and links sanitizer runtime into the object file. But we are not doing
3252 // the final link, we will link the resulting object file again. And
3253 // so the program ends up with two copies of sanitizer runtime.
3254 // See issue 8788 for details.
3255 case strings.HasPrefix(f, "-fsanitize="):
3257 // runpath flags not applicable unless building a shared
3258 // object or executable; see issue 12115 for details. This
3259 // is necessary as Go currently does not offer a way to
3260 // specify the set of LDFLAGS that only apply to shared
3262 case strings.HasPrefix(f, "-Wl,-rpath"):
3263 if f == "-Wl,-rpath" || f == "-Wl,-rpath-link" {
3264 // Skip following argument to -rpath* too.
3268 bareLDFLAGS = append(bareLDFLAGS, f)
3272 var staticLibs []string
3273 if goos == "windows" {
3274 // libmingw32 and libmingwex have some inter-dependencies,
3275 // so must use linker groups.
3276 staticLibs = []string{"-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group"}
3279 cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
3280 for _, cfile := range cfiles {
3281 ofile := obj + cfile[:len(cfile)-1] + "o"
3282 if err := b.gcc(p, ofile, cflags, obj+cfile); err != nil {
3283 return nil, nil, err
3285 linkobj = append(linkobj, ofile)
3286 if !strings.HasSuffix(ofile, "_cgo_main.o") {
3287 outObj = append(outObj, ofile)
3291 for _, file := range gccfiles {
3292 ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
3293 if err := b.gcc(p, ofile, cflags, file); err != nil {
3294 return nil, nil, err
3296 linkobj = append(linkobj, ofile)
3297 outObj = append(outObj, ofile)
3300 cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
3301 for _, file := range gxxfiles {
3302 // Append .o to the file, just in case the pkg has file.c and file.cpp
3303 ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
3304 if err := b.gxx(p, ofile, cxxflags, file); err != nil {
3305 return nil, nil, err
3307 linkobj = append(linkobj, ofile)
3308 outObj = append(outObj, ofile)
3311 for _, file := range mfiles {
3312 // Append .o to the file, just in case the pkg has file.c and file.m
3313 ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
3314 if err := b.gcc(p, ofile, cflags, file); err != nil {
3315 return nil, nil, err
3317 linkobj = append(linkobj, ofile)
3318 outObj = append(outObj, ofile)
3321 fflags := stringList(cgoCPPFLAGS, cgoFFLAGS)
3322 for _, file := range ffiles {
3323 // Append .o to the file, just in case the pkg has file.c and file.f
3324 ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
3325 if err := b.gfortran(p, ofile, fflags, file); err != nil {
3326 return nil, nil, err
3328 linkobj = append(linkobj, ofile)
3329 outObj = append(outObj, ofile)
3332 linkobj = append(linkobj, p.SysoFiles...)
3333 dynobj := obj + "_cgo_.o"
3334 pie := (goarch == "arm" && goos == "linux") || goos == "android"
3335 if pie { // we need to use -pie for Linux/ARM to get accurate imported sym
3336 cgoLDFLAGS = append(cgoLDFLAGS, "-pie")
3338 if err := b.gccld(p, dynobj, cgoLDFLAGS, linkobj); err != nil {
3339 return nil, nil, err
3341 if pie { // but we don't need -pie for normal cgo programs
3342 cgoLDFLAGS = cgoLDFLAGS[0 : len(cgoLDFLAGS)-1]
3345 if _, ok := buildToolchain.(gccgoToolchain); ok {
3346 // we don't use dynimport when using gccgo.
3347 return outGo, outObj, nil
3351 importGo := obj + "_cgo_import.go"
3352 cgoflags = []string{}
3353 if p.Standard && p.ImportPath == "runtime/cgo" {
3354 cgoflags = append(cgoflags, "-dynlinker") // record path to dynamic linker
3356 if err := b.run(p.Dir, p.ImportPath, nil, buildToolExec, cgoExe, "-objdir", obj, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags); err != nil {
3357 return nil, nil, err
3359 outGo = append(outGo, importGo)
3361 ofile := obj + "_all.o"
3362 var gccObjs, nonGccObjs []string
3363 for _, f := range outObj {
3364 if strings.HasSuffix(f, ".o") {
3365 gccObjs = append(gccObjs, f)
3367 nonGccObjs = append(nonGccObjs, f)
3370 ldflags := stringList(bareLDFLAGS, "-Wl,-r", "-nostdlib", staticLibs)
3372 if b.gccSupportsNoPie() {
3373 ldflags = append(ldflags, "-no-pie")
3376 // We are creating an object file, so we don't want a build ID.
3377 ldflags = b.disableBuildID(ldflags)
3379 if err := b.gccld(p, ofile, ldflags, gccObjs); err != nil {
3380 return nil, nil, err
3383 // NOTE(rsc): The importObj is a 5c/6c/8c object and on Windows
3384 // must be processed before the gcc-generated objects.
3385 // Put it first. https://golang.org/issue/2601
3386 outObj = stringList(nonGccObjs, ofile)
3388 return outGo, outObj, nil
3391 // Run SWIG on all SWIG input files.
3392 // TODO: Don't build a shared library, once SWIG emits the necessary
3393 // pragmas for external linking.
3394 func (b *builder) swig(p *Package, obj string, pcCFLAGS []string) (outGo, outC, outCXX []string, err error) {
3395 if err := b.swigVersionCheck(); err != nil {
3396 return nil, nil, nil, err
3399 intgosize, err := b.swigIntSize(obj)
3401 return nil, nil, nil, err
3404 for _, f := range p.SwigFiles {
3405 goFile, cFile, err := b.swigOne(p, f, obj, pcCFLAGS, false, intgosize)
3407 return nil, nil, nil, err
3410 outGo = append(outGo, goFile)
3413 outC = append(outC, cFile)
3416 for _, f := range p.SwigCXXFiles {
3417 goFile, cxxFile, err := b.swigOne(p, f, obj, pcCFLAGS, true, intgosize)
3419 return nil, nil, nil, err
3422 outGo = append(outGo, goFile)
3425 outCXX = append(outCXX, cxxFile)
3428 return outGo, outC, outCXX, nil
3431 // Make sure SWIG is new enough.
3433 swigCheckOnce sync.Once
3437 func (b *builder) swigDoVersionCheck() error {
3438 out, err := b.runOut("", "", nil, "swig", "-version")
3442 re := regexp.MustCompile(`[vV]ersion +([\d]+)([.][\d]+)?([.][\d]+)?`)
3443 matches := re.FindSubmatch(out)
3445 // Can't find version number; hope for the best.
3449 major, err := strconv.Atoi(string(matches[1]))
3451 // Can't find version number; hope for the best.
3454 const errmsg = "must have SWIG version >= 3.0.6"
3456 return errors.New(errmsg)
3463 // We have SWIG version 3.x.
3464 if len(matches[2]) > 0 {
3465 minor, err := strconv.Atoi(string(matches[2][1:]))
3475 // We have SWIG version 3.0.x.
3476 if len(matches[3]) > 0 {
3477 patch, err := strconv.Atoi(string(matches[3][1:]))
3483 return errors.New(errmsg)
3490 func (b *builder) swigVersionCheck() error {
3491 swigCheckOnce.Do(func() {
3492 swigCheck = b.swigDoVersionCheck()
3497 // Find the value to pass for the -intgosize option to swig.
3499 swigIntSizeOnce sync.Once
3501 swigIntSizeError error
3504 // This code fails to build if sizeof(int) <= 32
3505 const swigIntSizeCode = `
3507 const i int = 1 << 32
3510 // Determine the size of int on the target system for the -intgosize option
3511 // of swig >= 2.0.9. Run only once.
3512 func (b *builder) swigDoIntSize(obj string) (intsize string, err error) {
3514 return "$INTBITS", nil
3516 src := filepath.Join(b.work, "swig_intsize.go")
3517 if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0666); err != nil {
3520 srcs := []string{src}
3522 p := goFilesPackage(srcs)
3524 if _, _, e := buildToolchain.gc(b, p, "", obj, false, nil, srcs); e != nil {
3530 // Determine the size of int on the target system for the -intgosize option
3531 // of swig >= 2.0.9.
3532 func (b *builder) swigIntSize(obj string) (intsize string, err error) {
3533 swigIntSizeOnce.Do(func() {
3534 swigIntSize, swigIntSizeError = b.swigDoIntSize(obj)
3536 return swigIntSize, swigIntSizeError
3539 // Run SWIG on one SWIG input file.
3540 func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outC string, err error) {
3541 cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _, _ := b.cflags(p, true)
3544 cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS)
3546 cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS)
3549 n := 5 // length of ".swig"
3551 n = 8 // length of ".swigcxx"
3553 base := file[:len(file)-n]
3554 goFile := base + ".go"
3555 gccBase := base + "_wrap."
3561 _, gccgo := buildToolchain.(gccgoToolchain)
3567 "-intgosize", intgosize,
3569 "-o", obj + gccBase + gccExt,
3573 for _, f := range cflags {
3574 if len(f) > 3 && f[:2] == "-I" {
3575 args = append(args, f)
3580 args = append(args, "-gccgo")
3581 if pkgpath := gccgoPkgpath(p); pkgpath != "" {
3582 args = append(args, "-go-pkgpath", pkgpath)
3586 args = append(args, "-c++")
3589 out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file)
3592 if bytes.Contains(out, []byte("-intgosize")) || bytes.Contains(out, []byte("-cgo")) {
3593 return "", "", errors.New("must have SWIG version >= 3.0.6")
3595 b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig error
3596 return "", "", errPrintedOutput
3601 b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig warning
3604 return obj + goFile, obj + gccBase + gccExt, nil
3607 // disableBuildID adjusts a linker command line to avoid creating a
3608 // build ID when creating an object file rather than an executable or
3609 // shared library. Some systems, such as Ubuntu, always add
3610 // --build-id to every link, but we don't want a build ID when we are
3611 // producing an object file. On some of those system a plain -r (not
3612 // -Wl,-r) will turn off --build-id, but clang 3.0 doesn't support a
3613 // plain -r. I don't know how to turn off --build-id when using clang
3614 // other than passing a trailing --build-id=none. So that is what we
3615 // do, but only on systems likely to support it, which is to say,
3616 // systems that normally use gold or the GNU linker.
3617 func (b *builder) disableBuildID(ldflags []string) []string {
3619 case "android", "dragonfly", "linux", "netbsd":
3620 ldflags = append(ldflags, "-Wl,--build-id=none")
3625 // An actionQueue is a priority queue of actions.
3626 type actionQueue []*action
3628 // Implement heap.Interface
3629 func (q *actionQueue) Len() int { return len(*q) }
3630 func (q *actionQueue) Swap(i, j int) { (*q)[i], (*q)[j] = (*q)[j], (*q)[i] }
3631 func (q *actionQueue) Less(i, j int) bool { return (*q)[i].priority < (*q)[j].priority }
3632 func (q *actionQueue) Push(x interface{}) { *q = append(*q, x.(*action)) }
3633 func (q *actionQueue) Pop() interface{} {
3640 func (q *actionQueue) push(a *action) {
3644 func (q *actionQueue) pop() *action {
3645 return heap.Pop(q).(*action)
3648 func instrumentInit() {
3649 if !buildRace && !buildMSan {
3652 if buildRace && buildMSan {
3653 fmt.Fprintf(os.Stderr, "go %s: may not use -race and -msan simultaneously", flag.Args()[0])
3656 if goarch != "amd64" || goos != "linux" && goos != "freebsd" && goos != "darwin" && goos != "windows" {
3657 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])
3660 if !buildContext.CgoEnabled {
3661 fmt.Fprintf(os.Stderr, "go %s: -race requires cgo; enable cgo by setting CGO_ENABLED=1\n", flag.Args()[0])
3665 buildGcflags = append(buildGcflags, "-race")
3666 buildLdflags = append(buildLdflags, "-race")
3668 buildGcflags = append(buildGcflags, "-msan")
3669 buildLdflags = append(buildLdflags, "-msan")
3671 if buildContext.InstallSuffix != "" {
3672 buildContext.InstallSuffix += "_"
3676 buildContext.InstallSuffix += "race"
3677 buildContext.BuildTags = append(buildContext.BuildTags, "race")
3679 buildContext.InstallSuffix += "msan"
3680 buildContext.BuildTags = append(buildContext.BuildTags, "msan")