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
673 if _, ok := osArchSupportsCgo[goos+"/"+goarch]; !ok {
674 fmt.Fprintf(os.Stderr, "cmd/go: unsupported GOOS/GOARCH pair %s/%s\n", goos, goarch)
678 if goos == "windows" {
681 gopath = filepath.SplitList(buildContext.GOPATH)
684 // A builder holds global state about a build.
685 // It does not hold per-package state, because we
686 // build packages in parallel, and the builder is shared.
687 type builder struct {
688 work string // the temporary work directory (ends in filepath.Separator)
689 actionCache map[cacheKey]*action // a cache of already-constructed actions
690 mkdirCache map[string]bool // a cache of created directories
691 flagCache map[string]bool // a cache of supported compiler flags
692 print func(args ...interface{}) (int, error)
695 scriptDir string // current directory in printed script
702 // An action represents a single action in the action graph.
704 p *Package // the package this action works on
705 deps []*action // actions that must happen before this one
706 triggers []*action // inverse of deps
707 cgo *action // action for cgo binary if needed
708 args []string // additional args for runProgram
709 testOutput *bytes.Buffer // test output buffer
711 f func(*builder, *action) error // the action itself (nil = no-op)
712 ignoreFail bool // whether to run f even if dependencies fail
714 // Generated files, directories.
715 link bool // target is executable, not just package
716 pkgdir string // the -I or -L argument to use when importing this package
717 objdir string // directory for intermediate objects
718 objpkg string // the intermediate package .a file created during the action
719 target string // goal of the action: the created package or executable
722 pending int // number of deps yet to complete
723 priority int // relative execution priority
724 failed bool // whether the action failed
727 // cacheKey is the key for the action cache.
728 type cacheKey struct {
734 // buildMode specifies the build mode:
735 // are we just building things or also installing the results?
739 modeBuild buildMode = iota
744 goroot = filepath.Clean(runtime.GOROOT())
745 gobin = os.Getenv("GOBIN")
746 gorootBin = filepath.Join(goroot, "bin")
747 gorootPkg = filepath.Join(goroot, "pkg")
748 gorootSrc = filepath.Join(goroot, "src")
751 func (b *builder) init() {
753 b.print = func(a ...interface{}) (int, error) {
754 return fmt.Fprint(os.Stderr, a...)
756 b.actionCache = make(map[cacheKey]*action)
757 b.mkdirCache = make(map[string]bool)
762 b.work, err = ioutil.TempDir("", "go-build")
766 if buildX || buildWork {
767 fmt.Fprintf(os.Stderr, "WORK=%s\n", b.work)
771 atexit(func() { os.RemoveAll(workdir) })
776 // goFilesPackage creates a package for building a collection of Go files
777 // (typically named on the command line). The target is named p.a for
778 // package p or named after the first Go file for package main.
779 func goFilesPackage(gofiles []string) *Package {
780 // TODO: Remove this restriction.
781 for _, f := range gofiles {
782 if !strings.HasSuffix(f, ".go") {
783 fatalf("named files must be .go files")
789 ctxt.UseAllFiles = true
791 // Synthesize fake "directory" that only shows the named files,
792 // to make it look like this is a standard package or
793 // command directory. So that local imports resolve
794 // consistently, the files must all be in the same directory.
795 var dirent []os.FileInfo
797 for _, file := range gofiles {
798 fi, err := os.Stat(file)
803 fatalf("%s is a directory, should be a Go file", file)
805 dir1, _ := filepath.Split(file)
811 } else if dir != dir1 {
812 fatalf("named files must all be in one directory; have %s and %s", dir, dir1)
814 dirent = append(dirent, fi)
816 ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil }
822 dir, err = filepath.Abs(dir)
827 bp, err := ctxt.ImportDir(dir, 0)
832 pkg.load(&stk, bp, err)
834 pkg.localPrefix = dirToImportPath(dir)
835 pkg.ImportPath = "command-line-arguments"
838 if pkg.Name == "main" {
839 _, elem := filepath.Split(gofiles[0])
840 exe := elem[:len(elem)-len(".go")] + exeSuffix
845 pkg.target = filepath.Join(gobin, exe)
849 pkg.Target = pkg.target
851 pkg.StaleReason = "files named on command line"
857 // readpkglist returns the list of packages that were built into the shared library
858 // at shlibpath. For the native toolchain this list is stored, newline separated, in
859 // an ELF note with name "Go\x00\x00" and type 1. For GCCGO it is extracted from the
860 // .go_export section.
861 func readpkglist(shlibpath string) (pkgs []*Package) {
863 if _, gccgo := buildToolchain.(gccgoToolchain); gccgo {
864 f, _ := elf.Open(shlibpath)
865 sect := f.Section(".go_export")
866 data, _ := sect.Data()
867 scanner := bufio.NewScanner(bytes.NewBuffer(data))
870 if strings.HasPrefix(t, "pkgpath ") {
871 t = strings.TrimPrefix(t, "pkgpath ")
872 t = strings.TrimSuffix(t, ";")
873 pkgs = append(pkgs, loadPackage(t, &stk))
877 pkglistbytes, err := readELFNote(shlibpath, "Go\x00\x00", 1)
879 fatalf("readELFNote failed: %v", err)
881 scanner := bufio.NewScanner(bytes.NewBuffer(pkglistbytes))
884 pkgs = append(pkgs, loadPackage(t, &stk))
890 // action returns the action for applying the given operation (mode) to the package.
891 // depMode is the action to use when building dependencies.
892 // action never looks for p in a shared library, but may find p's dependencies in a
893 // shared library if buildLinkshared is true.
894 func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action {
895 return b.action1(mode, depMode, p, false, "")
898 // action1 returns the action for applying the given operation (mode) to the package.
899 // depMode is the action to use when building dependencies.
900 // action1 will look for p in a shared library if lookshared is true.
901 // forShlib is the shared library that p will become part of, if any.
902 func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, lookshared bool, forShlib string) *action {
907 key := cacheKey{mode, p, shlib}
909 a := b.actionCache[key]
914 key2 := cacheKey{modeInstall, nil, shlib}
915 a = b.actionCache[key2]
917 b.actionCache[key] = a
920 pkgs := readpkglist(shlib)
921 a = b.libaction(filepath.Base(shlib), pkgs, modeInstall, depMode)
922 b.actionCache[key2] = a
923 b.actionCache[key] = a
927 a = &action{p: p, pkgdir: p.build.PkgRoot}
928 if p.pkgdir != "" { // overrides p.t
931 b.actionCache[key] = a
933 for _, p1 := range p.imports {
935 // p is part of a shared library.
936 if p1.Shlib != "" && p1.Shlib != forShlib {
937 // p1 is explicitly part of a different shared library.
938 // Put the action for that shared library into a.deps.
939 a.deps = append(a.deps, b.action1(depMode, depMode, p1, true, p1.Shlib))
941 // p1 is (implicitly or not) part of this shared library.
942 // Put the action for p1 into a.deps.
943 a.deps = append(a.deps, b.action1(depMode, depMode, p1, false, forShlib))
946 // p is not part of a shared library.
947 // If p1 is in a shared library, put the action for that into
948 // a.deps, otherwise put the action for p1 into a.deps.
949 a.deps = append(a.deps, b.action1(depMode, depMode, p1, buildLinkshared, p1.Shlib))
953 // If we are not doing a cross-build, then record the binary we'll
954 // generate for cgo as a dependency of the build of any package
955 // using cgo, to make sure we do not overwrite the binary while
956 // a package is using it. If this is a cross-build, then the cgo we
957 // are writing is not the cgo we need to use.
958 if goos == runtime.GOOS && goarch == runtime.GOARCH && !buildRace && !buildMSan {
959 if (len(p.CgoFiles) > 0 || p.Standard && p.ImportPath == "runtime/cgo") && !buildLinkshared && buildBuildmode != "shared" {
961 p1 := loadPackage("cmd/cgo", &stk)
963 fatalf("load cmd/cgo: %v", p1.Error)
965 a.cgo = b.action(depMode, depMode, p1)
966 a.deps = append(a.deps, a.cgo)
971 switch p.ImportPath {
972 case "builtin", "unsafe":
973 // Fake packages - nothing to build.
976 // gccgo standard library is "fake" too.
977 if _, ok := buildToolchain.(gccgoToolchain); ok {
978 // the target name is needed for cgo.
984 if !p.Stale && p.target != "" {
985 // p.Stale==false implies that p.target is up-to-date.
986 // Record target name for use by actions depending on this one.
991 if p.local && p.target == "" {
992 // Imported via local path. No permanent target.
999 a.objdir = filepath.Join(work, a.p.ImportPath, "_obj") + string(filepath.Separator)
1000 a.objpkg = buildToolchain.pkgpath(work, a.p)
1001 a.link = p.Name == "main"
1005 a.f = (*builder).install
1006 a.deps = []*action{b.action1(modeBuild, depMode, p, lookshared, forShlib)}
1007 a.target = a.p.target
1009 // Install header for cgo in c-archive and c-shared modes.
1010 if p.usesCgo() && (buildBuildmode == "c-archive" || buildBuildmode == "c-shared") {
1011 hdrTarget := a.target[:len(a.target)-len(filepath.Ext(a.target))] + ".h"
1012 if buildContext.Compiler == "gccgo" {
1013 // For the header file, remove the "lib"
1014 // added by go/build, so we generate pkg.h
1015 // rather than libpkg.h.
1016 dir, file := filepath.Split(hdrTarget)
1017 file = strings.TrimPrefix(file, "lib")
1018 hdrTarget = filepath.Join(dir, file)
1022 deps: []*action{a.deps[0]},
1023 f: (*builder).installHeader,
1028 a.deps = append(a.deps, ah)
1032 a.f = (*builder).build
1035 // An executable file. (This is the name of a temporary file.)
1036 // Because we run the temporary file in 'go run' and 'go test',
1037 // the name will show up in ps listings. If the caller has specified
1038 // a name, use that instead of a.out. The binary is generated
1039 // in an otherwise empty subdirectory named exe to avoid
1040 // naming conflicts. The only possible conflict is if we were
1041 // to create a top-level package named exe.
1043 if p.exeName != "" {
1045 } else if goos == "darwin" && buildBuildmode == "c-shared" && p.target != "" {
1046 // On OS X, the linker output name gets recorded in the
1047 // shared library's LC_ID_DYLIB load command.
1048 // The code invoking the linker knows to pass only the final
1049 // path element. Arrange that the path element matches what
1050 // we'll install it as; otherwise the library is only loadable as "a.out".
1051 _, name = filepath.Split(p.target)
1053 a.target = a.objdir + filepath.Join("exe", name) + exeSuffix
1060 func (b *builder) libaction(libname string, pkgs []*Package, mode, depMode buildMode) *action {
1064 fatalf("unrecognized mode %v", mode)
1067 a.f = (*builder).linkShared
1068 a.target = filepath.Join(b.work, libname)
1069 for _, p := range pkgs {
1073 a.deps = append(a.deps, b.action(depMode, depMode, p))
1077 // Currently build mode shared forces external linking mode, and
1078 // external linking mode forces an import of runtime/cgo (and
1079 // math on arm). So if it was not passed on the command line and
1080 // it is not present in another shared library, add it here.
1081 _, gccgo := buildToolchain.(gccgoToolchain)
1084 for _, p := range pkgs {
1085 seencgo = seencgo || (p.Standard && p.ImportPath == "runtime/cgo")
1089 p := loadPackage("runtime/cgo", &stk)
1091 fatalf("load runtime/cgo: %v", p.Error)
1094 // If runtime/cgo is in another shared library, then that's
1095 // also the shared library that contains runtime, so
1096 // something will depend on it and so runtime/cgo's staleness
1097 // will be checked when processing that library.
1098 if p.Shlib == "" || p.Shlib == libname {
1099 pkgs = append([]*Package{}, pkgs...)
1100 pkgs = append(pkgs, p)
1103 if goarch == "arm" {
1105 for _, p := range pkgs {
1106 seenmath = seenmath || (p.Standard && p.ImportPath == "math")
1110 p := loadPackage("math", &stk)
1112 fatalf("load math: %v", p.Error)
1115 // If math is in another shared library, then that's
1116 // also the shared library that contains runtime, so
1117 // something will depend on it and so math's staleness
1118 // will be checked when processing that library.
1119 if p.Shlib == "" || p.Shlib == libname {
1120 pkgs = append([]*Package{}, pkgs...)
1121 pkgs = append(pkgs, p)
1127 // Figure out where the library will go.
1129 for _, p := range pkgs {
1130 plibdir := p.build.PkgTargetRoot
1132 plibdir = filepath.Join(plibdir, "shlibs")
1136 } else if libdir != plibdir {
1137 fatalf("multiple roots %s & %s", libdir, plibdir)
1140 a.target = filepath.Join(libdir, libname)
1142 // Now we can check whether we need to rebuild it.
1145 if fi, err := os.Stat(a.target); err == nil {
1146 built = fi.ModTime()
1148 for _, p := range pkgs {
1152 stale = stale || p.Stale
1153 lstat, err := os.Stat(p.target)
1154 if err != nil || lstat.ModTime().After(built) {
1157 a.deps = append(a.deps, b.action1(depMode, depMode, p, false, a.target))
1161 a.f = (*builder).install
1162 buildAction := b.libaction(libname, pkgs, modeBuild, depMode)
1163 a.deps = []*action{buildAction}
1164 for _, p := range pkgs {
1168 shlibnameaction := &action{}
1169 shlibnameaction.f = (*builder).installShlibname
1170 shlibnameaction.target = p.target[:len(p.target)-2] + ".shlibname"
1171 a.deps = append(a.deps, shlibnameaction)
1172 shlibnameaction.deps = append(shlibnameaction.deps, buildAction)
1179 // actionList returns the list of actions in the dag rooted at root
1180 // as visited in a depth-first post-order traversal.
1181 func actionList(root *action) []*action {
1182 seen := map[*action]bool{}
1184 var walk func(*action)
1185 walk = func(a *action) {
1190 for _, a1 := range a.deps {
1193 all = append(all, a)
1199 // allArchiveActions returns a list of the archive dependencies of root.
1200 // This is needed because if package p depends on package q that is in libr.so, the
1201 // action graph looks like p->libr.so->q and so just scanning through p's
1202 // dependencies does not find the import dir for q.
1203 func allArchiveActions(root *action) []*action {
1204 seen := map[*action]bool{}
1206 var walk func(*action)
1207 walk = func(a *action) {
1212 if strings.HasSuffix(a.target, ".so") || a == root {
1213 for _, a1 := range a.deps {
1216 } else if strings.HasSuffix(a.target, ".a") {
1224 // do runs the action graph rooted at root.
1225 func (b *builder) do(root *action) {
1226 // Build list of all actions, assigning depth-first post-order priority.
1227 // The original implementation here was a true queue
1228 // (using a channel) but it had the effect of getting
1229 // distracted by low-level leaf actions to the detriment
1230 // of completing higher-level actions. The order of
1231 // work does not matter much to overall execution time,
1232 // but when running "go test std" it is nice to see each test
1233 // results as soon as possible. The priorities assigned
1234 // ensure that, all else being equal, the execution prefers
1235 // to do what it would have done first in a simple depth-first
1236 // dependency order traversal.
1237 all := actionList(root)
1238 for i, a := range all {
1242 b.readySema = make(chan bool, len(all))
1244 // Initialize per-action execution state.
1245 for _, a := range all {
1246 for _, a1 := range a.deps {
1247 a1.triggers = append(a1.triggers, a)
1249 a.pending = len(a.deps)
1256 // Handle runs a single action and takes care of triggering
1257 // any actions that are runnable as a result.
1258 handle := func(a *action) {
1260 if a.f != nil && (!a.failed || a.ignoreFail) {
1264 // The actions run in parallel but all the updates to the
1265 // shared work state are serialized through b.exec.
1267 defer b.exec.Unlock()
1270 if err == errPrintedOutput {
1278 for _, a0 := range a.triggers {
1282 if a0.pending--; a0.pending == 0 {
1293 var wg sync.WaitGroup
1295 // Kick off goroutines according to parallelism.
1296 // If we are using the -n flag (just printing commands)
1297 // drop the parallelism to 1, both to make the output
1298 // deterministic and because there is no real work anyway.
1303 for i := 0; i < par; i++ {
1309 case _, ok := <-b.readySema:
1313 // Receiving a value from b.readySema entitles
1314 // us to take from the ready queue.
1330 // build is the action for building a single package or command.
1331 func (b *builder) build(a *action) (err error) {
1332 // Return an error for binary-only package.
1333 // We only reach this if isStale believes the binary form is
1334 // either not present or not usable.
1336 return fmt.Errorf("missing or invalid package binary for binary-only package %s", a.p.ImportPath)
1339 // Return an error if the package has CXX files but it's not using
1340 // cgo nor SWIG, since the CXX files can only be processed by cgo
1342 if len(a.p.CXXFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
1343 return fmt.Errorf("can't build package %s because it contains C++ files (%s) but it's not using cgo nor SWIG",
1344 a.p.ImportPath, strings.Join(a.p.CXXFiles, ","))
1346 // Same as above for Objective-C files
1347 if len(a.p.MFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
1348 return fmt.Errorf("can't build package %s because it contains Objective-C files (%s) but it's not using cgo nor SWIG",
1349 a.p.ImportPath, strings.Join(a.p.MFiles, ","))
1351 // Same as above for Fortran files
1352 if len(a.p.FFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
1353 return fmt.Errorf("can't build package %s because it contains Fortran files (%s) but it's not using cgo nor SWIG",
1354 a.p.ImportPath, strings.Join(a.p.FFiles, ","))
1358 if err != nil && err != errPrintedOutput {
1359 err = fmt.Errorf("go build %s: %v", a.p.ImportPath, err)
1363 // In -n mode, print a banner between packages.
1364 // The banner is five lines so that when changes to
1365 // different sections of the bootstrap script have to
1366 // be merged, the banners give patch something
1367 // to use to find its context.
1368 b.print("\n#\n# " + a.p.ImportPath + "\n#\n\n")
1372 b.print(a.p.ImportPath + "\n")
1375 // Make build directory.
1377 if err := b.mkdir(obj); err != nil {
1381 // make target directory
1382 dir, _ := filepath.Split(a.target)
1384 if err := b.mkdir(dir); err != nil {
1389 var gofiles, cgofiles, cfiles, sfiles, cxxfiles, objects, cgoObjects, pcCFLAGS, pcLDFLAGS []string
1391 gofiles = append(gofiles, a.p.GoFiles...)
1392 cgofiles = append(cgofiles, a.p.CgoFiles...)
1393 cfiles = append(cfiles, a.p.CFiles...)
1394 sfiles = append(sfiles, a.p.SFiles...)
1395 cxxfiles = append(cxxfiles, a.p.CXXFiles...)
1397 if a.p.usesCgo() || a.p.usesSwig() {
1398 if pcCFLAGS, pcLDFLAGS, err = b.getPkgConfigFlags(a.p); err != nil {
1403 // Run SWIG on each .swig and .swigcxx file.
1404 // Each run will generate two files, a .go file and a .c or .cxx file.
1405 // The .go file will use import "C" and is to be processed by cgo.
1407 outGo, outC, outCXX, err := b.swig(a.p, obj, pcCFLAGS)
1411 cgofiles = append(cgofiles, outGo...)
1412 cfiles = append(cfiles, outC...)
1413 cxxfiles = append(cxxfiles, outCXX...)
1417 if a.p.usesCgo() || a.p.usesSwig() {
1418 // In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
1419 // There is one exception: runtime/cgo's job is to bridge the
1420 // cgo and non-cgo worlds, so it necessarily has files in both.
1421 // In that case gcc only gets the gcc_* files.
1422 var gccfiles []string
1423 gccfiles = append(gccfiles, cfiles...)
1425 if a.p.Standard && a.p.ImportPath == "runtime/cgo" {
1426 filter := func(files, nongcc, gcc []string) ([]string, []string) {
1427 for _, f := range files {
1428 if strings.HasPrefix(f, "gcc_") {
1429 gcc = append(gcc, f)
1431 nongcc = append(nongcc, f)
1436 sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles)
1438 gccfiles = append(gccfiles, sfiles...)
1442 cgoExe := tool("cgo")
1443 if a.cgo != nil && a.cgo.target != "" {
1444 cgoExe = a.cgo.target
1446 outGo, outObj, err := b.cgo(a.p, cgoExe, obj, pcCFLAGS, pcLDFLAGS, cgofiles, gccfiles, cxxfiles, a.p.MFiles, a.p.FFiles)
1450 if _, ok := buildToolchain.(gccgoToolchain); ok {
1451 cgoObjects = append(cgoObjects, filepath.Join(a.objdir, "_cgo_flags"))
1453 cgoObjects = append(cgoObjects, outObj...)
1454 gofiles = append(gofiles, outGo...)
1457 if len(gofiles) == 0 {
1458 return &build.NoGoError{Dir: a.p.Dir}
1461 // If we're doing coverage, preprocess the .go files and put them in the work directory
1462 if a.p.coverMode != "" {
1463 for i, file := range gofiles {
1464 var sourceFile string
1465 var coverFile string
1467 if strings.HasSuffix(file, ".cgo1.go") {
1468 // cgo files have absolute paths
1469 base := filepath.Base(file)
1471 coverFile = filepath.Join(obj, base)
1472 key = strings.TrimSuffix(base, ".cgo1.go") + ".go"
1474 sourceFile = filepath.Join(a.p.Dir, file)
1475 coverFile = filepath.Join(obj, file)
1478 cover := a.p.coverVars[key]
1479 if cover == nil || isTestFile(file) {
1480 // Not covering this file.
1483 if err := b.cover(a, coverFile, sourceFile, 0666, cover.Var); err != nil {
1486 gofiles[i] = coverFile
1490 // Prepare Go import path list.
1491 inc := b.includeArgs("-I", allArchiveActions(a))
1494 ofile, out, err := buildToolchain.gc(b, a.p, a.objpkg, obj, len(sfiles) > 0, inc, gofiles)
1496 b.showOutput(a.p.Dir, a.p.ImportPath, b.processOutput(out))
1498 return errPrintedOutput
1504 if ofile != a.objpkg {
1505 objects = append(objects, ofile)
1508 // Copy .h files named for goos or goarch or goos_goarch
1509 // to names using GOOS and GOARCH.
1510 // For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
1511 _goos_goarch := "_" + goos + "_" + goarch
1513 _goarch := "_" + goarch
1514 for _, file := range a.p.HFiles {
1515 name, ext := fileExtSplit(file)
1517 case strings.HasSuffix(name, _goos_goarch):
1518 targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext
1519 if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666, true); err != nil {
1522 case strings.HasSuffix(name, _goarch):
1523 targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext
1524 if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666, true); err != nil {
1527 case strings.HasSuffix(name, _goos):
1528 targ := file[:len(name)-len(_goos)] + "_GOOS." + ext
1529 if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666, true); err != nil {
1535 for _, file := range cfiles {
1536 out := file[:len(file)-len(".c")] + ".o"
1537 if err := buildToolchain.cc(b, a.p, obj, obj+out, file); err != nil {
1540 objects = append(objects, out)
1543 // Assemble .s files.
1544 for _, file := range sfiles {
1545 out := file[:len(file)-len(".s")] + ".o"
1546 if err := buildToolchain.asm(b, a.p, obj, obj+out, file); err != nil {
1549 objects = append(objects, out)
1552 // NOTE(rsc): On Windows, it is critically important that the
1553 // gcc-compiled objects (cgoObjects) be listed after the ordinary
1554 // objects in the archive. I do not know why this is.
1555 // https://golang.org/issue/2601
1556 objects = append(objects, cgoObjects...)
1558 // Add system object files.
1559 for _, syso := range a.p.SysoFiles {
1560 objects = append(objects, filepath.Join(a.p.Dir, syso))
1563 // Pack into archive in obj directory.
1564 // If the Go compiler wrote an archive, we only need to add the
1565 // object files for non-Go sources to the archive.
1566 // If the Go compiler wrote an archive and the package is entirely
1567 // Go sources, there is no pack to execute at all.
1568 if len(objects) > 0 {
1569 if err := buildToolchain.pack(b, a.p, obj, a.objpkg, objects); err != nil {
1576 // The compiler only cares about direct imports, but the
1577 // linker needs the whole dependency tree.
1578 all := actionList(a)
1579 all = all[:len(all)-1] // drop a
1580 if err := buildToolchain.ld(b, a, a.target, all, a.objpkg, objects); err != nil {
1588 // Calls pkg-config if needed and returns the cflags/ldflags needed to build the package.
1589 func (b *builder) getPkgConfigFlags(p *Package) (cflags, ldflags []string, err error) {
1590 if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
1592 out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--cflags", pkgs)
1594 b.showOutput(p.Dir, "pkg-config --cflags "+strings.Join(pkgs, " "), string(out))
1595 b.print(err.Error() + "\n")
1596 err = errPrintedOutput
1600 cflags = strings.Fields(string(out))
1602 out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--libs", pkgs)
1604 b.showOutput(p.Dir, "pkg-config --libs "+strings.Join(pkgs, " "), string(out))
1605 b.print(err.Error() + "\n")
1606 err = errPrintedOutput
1610 ldflags = strings.Fields(string(out))
1616 func (b *builder) installShlibname(a *action) error {
1618 err := ioutil.WriteFile(a.target, []byte(filepath.Base(a1.target)+"\n"), 0666)
1623 b.showcmd("", "echo '%s' > %s # internal", filepath.Base(a1.target), a.target)
1628 func (b *builder) linkShared(a *action) (err error) {
1629 allactions := actionList(a)
1630 allactions = allactions[:len(allactions)-1]
1631 return buildToolchain.ldShared(b, a.deps, a.target, allactions)
1634 // install is the action for installing a single package or executable.
1635 func (b *builder) install(a *action) (err error) {
1637 if err != nil && err != errPrintedOutput {
1638 err = fmt.Errorf("go install %s: %v", a.p.ImportPath, err)
1642 perm := os.FileMode(0666)
1644 switch buildBuildmode {
1645 case "c-archive", "c-shared":
1651 // make target directory
1652 dir, _ := filepath.Split(a.target)
1654 if err := b.mkdir(dir); err != nil {
1659 // remove object dir to keep the amount of
1660 // garbage down in a large build. On an operating system
1661 // with aggressive buffering, cleaning incrementally like
1662 // this keeps the intermediate objects from hitting the disk.
1664 defer os.RemoveAll(a1.objdir)
1665 defer os.Remove(a1.target)
1668 return b.moveOrCopyFile(a, a.target, a1.target, perm, false)
1671 // includeArgs returns the -I or -L directory list for access
1672 // to the results of the list of actions.
1673 func (b *builder) includeArgs(flag string, all []*action) []string {
1675 incMap := map[string]bool{
1676 b.work: true, // handled later
1678 "": true, // ignore empty strings
1681 // Look in the temporary space for results of test-specific actions.
1682 // This is the $WORK/my/package/_test directory for the
1683 // package being built, so there are few of these.
1684 for _, a1 := range all {
1688 if dir := a1.pkgdir; dir != a1.p.build.PkgRoot && !incMap[dir] {
1690 inc = append(inc, flag, dir)
1694 // Also look in $WORK for any non-test packages that have
1695 // been built but not installed.
1696 inc = append(inc, flag, b.work)
1698 // Finally, look in the installed package directories for each action.
1699 // First add the package dirs corresponding to GOPATH entries
1700 // in the original GOPATH order.
1701 need := map[string]*build.Package{}
1702 for _, a1 := range all {
1703 if a1.p != nil && a1.pkgdir == a1.p.build.PkgRoot {
1704 need[a1.p.build.Root] = a1.p.build
1707 for _, root := range gopath {
1708 if p := need[root]; p != nil && !incMap[p.PkgRoot] {
1709 incMap[p.PkgRoot] = true
1710 inc = append(inc, flag, p.PkgTargetRoot)
1714 // Then add anything that's left.
1715 for _, a1 := range all {
1719 if dir := a1.pkgdir; dir == a1.p.build.PkgRoot && !incMap[dir] {
1721 inc = append(inc, flag, a1.p.build.PkgTargetRoot)
1728 // moveOrCopyFile is like 'mv src dst' or 'cp src dst'.
1729 func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode, force bool) error {
1731 b.showcmd("", "mv %s %s", src, dst)
1735 // If we can update the mode and rename to the dst, do it.
1736 // Otherwise fall back to standard copy.
1738 // The perm argument is meant to be adjusted according to umask,
1739 // but we don't know what the umask is.
1740 // Create a dummy file to find out.
1741 // This avoids build tags and works even on systems like Plan 9
1742 // where the file mask computation incorporates other information.
1744 f, err := os.OpenFile(filepath.Clean(dst)+"-go-tmp-umask", os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm)
1748 mode = fi.Mode() & 0777
1755 if err := os.Chmod(src, mode); err == nil {
1756 if err := os.Rename(src, dst); err == nil {
1758 b.showcmd("", "mv %s %s", src, dst)
1764 return b.copyFile(a, dst, src, perm, force)
1767 // copyFile is like 'cp src dst'.
1768 func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode, force bool) error {
1769 if buildN || buildX {
1770 b.showcmd("", "cp %s %s", src, dst)
1776 sf, err := os.Open(src)
1782 // Be careful about removing/overwriting dst.
1783 // Do not remove/overwrite if dst exists and is a directory
1784 // or a non-object file.
1785 if fi, err := os.Stat(dst); err == nil {
1787 return fmt.Errorf("build output %q already exists and is a directory", dst)
1789 if !force && fi.Mode().IsRegular() && !isObject(dst) {
1790 return fmt.Errorf("build output %q already exists and is not an object file", dst)
1794 // On Windows, remove lingering ~ file from last attempt.
1796 if _, err := os.Stat(dst + "~"); err == nil {
1797 os.Remove(dst + "~")
1801 mayberemovefile(dst)
1802 df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
1803 if err != nil && toolIsWindows {
1804 // Windows does not allow deletion of a binary file
1805 // while it is executing. Try to move it out of the way.
1806 // If the move fails, which is likely, we'll try again the
1807 // next time we do an install of this binary.
1808 if err := os.Rename(dst, dst+"~"); err == nil {
1809 os.Remove(dst + "~")
1811 df, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
1817 _, err = io.Copy(df, sf)
1820 mayberemovefile(dst)
1821 return fmt.Errorf("copying %s to %s: %v", src, dst, err)
1826 // Install the cgo export header file, if there is one.
1827 func (b *builder) installHeader(a *action) error {
1828 src := a.objdir + "_cgo_install.h"
1829 if _, err := os.Stat(src); os.IsNotExist(err) {
1830 // If the file does not exist, there are no exported
1831 // functions, and we do not install anything.
1835 dir, _ := filepath.Split(a.target)
1837 if err := b.mkdir(dir); err != nil {
1842 return b.moveOrCopyFile(a, a.target, src, 0666, true)
1845 // cover runs, in effect,
1846 // go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
1847 func (b *builder) cover(a *action, dst, src string, perm os.FileMode, varName string) error {
1848 return b.run(a.objdir, "cover "+a.p.ImportPath, nil,
1851 "-mode", a.p.coverMode,
1857 var objectMagic = [][]byte{
1858 {'!', '<', 'a', 'r', 'c', 'h', '>', '\n'}, // Package archive
1859 {'\x7F', 'E', 'L', 'F'}, // ELF
1860 {0xFE, 0xED, 0xFA, 0xCE}, // Mach-O big-endian 32-bit
1861 {0xFE, 0xED, 0xFA, 0xCF}, // Mach-O big-endian 64-bit
1862 {0xCE, 0xFA, 0xED, 0xFE}, // Mach-O little-endian 32-bit
1863 {0xCF, 0xFA, 0xED, 0xFE}, // Mach-O little-endian 64-bit
1864 {0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00}, // PE (Windows) as generated by 6l/8l and gcc
1865 {0x00, 0x00, 0x01, 0xEB}, // Plan 9 i386
1866 {0x00, 0x00, 0x8a, 0x97}, // Plan 9 amd64
1867 {0x00, 0x00, 0x06, 0x47}, // Plan 9 arm
1870 func isObject(s string) bool {
1871 f, err := os.Open(s)
1876 buf := make([]byte, 64)
1878 for _, magic := range objectMagic {
1879 if bytes.HasPrefix(buf, magic) {
1886 // mayberemovefile removes a file only if it is a regular file
1887 // When running as a user with sufficient privileges, we may delete
1888 // even device files, for example, which is not intended.
1889 func mayberemovefile(s string) {
1890 if fi, err := os.Lstat(s); err == nil && !fi.Mode().IsRegular() {
1896 // fmtcmd formats a command in the manner of fmt.Sprintf but also:
1898 // If dir is non-empty and the script is not in dir right now,
1899 // fmtcmd inserts "cd dir\n" before the command.
1901 // fmtcmd replaces the value of b.work with $WORK.
1902 // fmtcmd replaces the value of goroot with $GOROOT.
1903 // fmtcmd replaces the value of b.gobin with $GOBIN.
1905 // fmtcmd replaces the name of the current directory with dot (.)
1906 // but only when it is at the beginning of a space-separated token.
1908 func (b *builder) fmtcmd(dir string, format string, args ...interface{}) string {
1909 cmd := fmt.Sprintf(format, args...)
1910 if dir != "" && dir != "/" {
1911 cmd = strings.Replace(" "+cmd, " "+dir, " .", -1)[1:]
1912 if b.scriptDir != dir {
1914 cmd = "cd " + dir + "\n" + cmd
1918 cmd = strings.Replace(cmd, b.work, "$WORK", -1)
1923 // showcmd prints the given command to standard output
1924 // for the implementation of -n or -x.
1925 func (b *builder) showcmd(dir string, format string, args ...interface{}) {
1927 defer b.output.Unlock()
1928 b.print(b.fmtcmd(dir, format, args...) + "\n")
1931 // showOutput prints "# desc" followed by the given output.
1932 // The output is expected to contain references to 'dir', usually
1933 // the source directory for the package that has failed to build.
1934 // showOutput rewrites mentions of dir with a relative path to dir
1935 // when the relative path is shorter. This is usually more pleasant.
1936 // For example, if fmt doesn't compile and we are in src/html,
1941 // ../fmt/print.go:1090: undefined: asdf
1948 // /usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
1951 // showOutput also replaces references to the work directory with $WORK.
1953 func (b *builder) showOutput(dir, desc, out string) {
1954 prefix := "# " + desc
1955 suffix := "\n" + out
1956 if reldir := shortPath(dir); reldir != dir {
1957 suffix = strings.Replace(suffix, " "+dir, " "+reldir, -1)
1958 suffix = strings.Replace(suffix, "\n"+dir, "\n"+reldir, -1)
1960 suffix = strings.Replace(suffix, " "+b.work, " $WORK", -1)
1963 defer b.output.Unlock()
1964 b.print(prefix, suffix)
1967 // shortPath returns an absolute or relative name for path, whatever is shorter.
1968 func shortPath(path string) string {
1969 if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) {
1975 // relPaths returns a copy of paths with absolute paths
1976 // made relative to the current directory if they would be shorter.
1977 func relPaths(paths []string) []string {
1979 pwd, _ := os.Getwd()
1980 for _, p := range paths {
1981 rel, err := filepath.Rel(pwd, p)
1982 if err == nil && len(rel) < len(p) {
1985 out = append(out, p)
1990 // errPrintedOutput is a special error indicating that a command failed
1991 // but that it generated output as well, and that output has already
1992 // been printed, so there's no point showing 'exit status 1' or whatever
1993 // the wait status was. The main executor, builder.do, knows not to
1994 // print this error.
1995 var errPrintedOutput = errors.New("already printed output - no need to show error")
1997 var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.cgo1\.go:[0-9]+\]`)
1998 var cgoTypeSigRe = regexp.MustCompile(`\b_Ctype_\B`)
2000 // run runs the command given by cmdline in the directory dir.
2001 // If the command fails, run prints information about the failure
2002 // and returns a non-nil error.
2003 func (b *builder) run(dir string, desc string, env []string, cmdargs ...interface{}) error {
2004 out, err := b.runOut(dir, desc, env, cmdargs...)
2007 desc = b.fmtcmd(dir, "%s", strings.Join(stringList(cmdargs...), " "))
2009 b.showOutput(dir, desc, b.processOutput(out))
2011 err = errPrintedOutput
2017 // processOutput prepares the output of runOut to be output to the console.
2018 func (b *builder) processOutput(out []byte) string {
2019 if out[len(out)-1] != '\n' {
2020 out = append(out, '\n')
2022 messages := string(out)
2023 // Fix up output referring to cgo-generated code to be more readable.
2024 // Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
2025 // Replace *[100]_Ctype_foo with *[100]C.foo.
2026 // If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
2027 if !buildX && cgoLine.MatchString(messages) {
2028 messages = cgoLine.ReplaceAllString(messages, "")
2029 messages = cgoTypeSigRe.ReplaceAllString(messages, "C.")
2034 // runOut runs the command given by cmdline in the directory dir.
2035 // It returns the command output and any errors that occurred.
2036 func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) {
2037 cmdline := stringList(cmdargs...)
2038 if buildN || buildX {
2039 var envcmdline string
2040 for i := range env {
2041 envcmdline += env[i]
2044 envcmdline += joinUnambiguously(cmdline)
2045 b.showcmd(dir, "%s", envcmdline)
2053 var buf bytes.Buffer
2054 cmd := exec.Command(cmdline[0], cmdline[1:]...)
2058 cmd.Env = mergeEnvLists(env, envForDir(cmd.Dir, os.Environ()))
2061 // cmd.Run will fail on Unix if some other process has the binary
2062 // we want to run open for writing. This can happen here because
2063 // we build and install the cgo command and then run it.
2064 // If another command was kicked off while we were writing the
2065 // cgo binary, the child process for that command may be holding
2066 // a reference to the fd, keeping us from running exec.
2068 // But, you might reasonably wonder, how can this happen?
2069 // The cgo fd, like all our fds, is close-on-exec, so that we need
2070 // not worry about other processes inheriting the fd accidentally.
2071 // The answer is that running a command is fork and exec.
2072 // A child forked while the cgo fd is open inherits that fd.
2073 // Until the child has called exec, it holds the fd open and the
2074 // kernel will not let us run cgo. Even if the child were to close
2075 // the fd explicitly, it would still be open from the time of the fork
2076 // until the time of the explicit close, and the race would remain.
2078 // On Unix systems, this results in ETXTBSY, which formats
2079 // as "text file busy". Rather than hard-code specific error cases,
2080 // we just look for that string. If this happens, sleep a little
2081 // and try again. We let this happen three times, with increasing
2082 // sleep lengths: 100+200+400 ms = 0.7 seconds.
2084 // An alternate solution might be to split the cmd.Run into
2085 // separate cmd.Start and cmd.Wait, and then use an RWLock
2086 // to make sure that copyFile only executes when no cmd.Start
2087 // call is in progress. However, cmd.Start (really syscall.forkExec)
2088 // only guarantees that when it returns, the exec is committed to
2089 // happen and succeed. It uses a close-on-exec file descriptor
2090 // itself to determine this, so we know that when cmd.Start returns,
2091 // at least one close-on-exec file descriptor has been closed.
2092 // However, we cannot be sure that all of them have been closed,
2093 // so the program might still encounter ETXTBSY even with such
2094 // an RWLock. The race window would be smaller, perhaps, but not
2095 // guaranteed to be gone.
2097 // Sleeping when we observe the race seems to be the most reliable
2100 // https://golang.org/issue/3001
2102 if err != nil && nbusy < 3 && strings.Contains(err.Error(), "text file busy") {
2103 time.Sleep(100 * time.Millisecond << uint(nbusy))
2108 // err can be something like 'exit status 1'.
2109 // Add information about what program was running.
2110 // Note that if buf.Bytes() is non-empty, the caller usually
2111 // shows buf.Bytes() and does not print err at all, so the
2112 // prefix here does not make most output any more verbose.
2114 err = errors.New(cmdline[0] + ": " + err.Error())
2116 return buf.Bytes(), err
2120 // joinUnambiguously prints the slice, quoting where necessary to make the
2121 // output unambiguous.
2122 // TODO: See issue 5279. The printing of commands needs a complete redo.
2123 func joinUnambiguously(a []string) string {
2124 var buf bytes.Buffer
2125 for i, s := range a {
2129 q := strconv.Quote(s)
2130 if s == "" || strings.Contains(s, " ") || len(q) > len(s)+2 {
2139 // mkdir makes the named directory.
2140 func (b *builder) mkdir(dir string) error {
2142 defer b.exec.Unlock()
2143 // We can be a little aggressive about being
2144 // sure directories exist. Skip repeated calls.
2145 if b.mkdirCache[dir] {
2148 b.mkdirCache[dir] = true
2150 if buildN || buildX {
2151 b.showcmd("", "mkdir -p %s", dir)
2157 if err := os.MkdirAll(dir, 0777); err != nil {
2163 // mkAbs returns an absolute path corresponding to
2164 // evaluating f in the directory dir.
2165 // We always pass absolute paths of source files so that
2166 // the error messages will include the full path to a file
2167 // in need of attention.
2168 func mkAbs(dir, f string) string {
2169 // Leave absolute paths alone.
2170 // Also, during -n mode we use the pseudo-directory $WORK
2171 // instead of creating an actual work directory that won't be used.
2172 // Leave paths beginning with $WORK alone too.
2173 if filepath.IsAbs(f) || strings.HasPrefix(f, "$WORK") {
2176 return filepath.Join(dir, f)
2179 type toolchain interface {
2180 // gc runs the compiler in a specific directory on a set of files
2181 // and returns the name of the generated output file.
2182 // The compiler runs in the directory dir.
2183 gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error)
2184 // cc runs the toolchain's C compiler in a directory on a C file
2185 // to produce an output file.
2186 cc(b *builder, p *Package, objdir, ofile, cfile string) error
2187 // asm runs the assembler in a specific directory on a specific file
2188 // to generate the named output file.
2189 asm(b *builder, p *Package, obj, ofile, sfile string) error
2190 // pkgpath builds an appropriate path for a temporary package file.
2191 pkgpath(basedir string, p *Package) string
2192 // pack runs the archive packer in a specific directory to create
2193 // an archive from a set of object files.
2194 // typically it is run in the object directory.
2195 pack(b *builder, p *Package, objDir, afile string, ofiles []string) error
2196 // ld runs the linker to create an executable starting at mainpkg.
2197 ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error
2198 // ldShared runs the linker to create a shared library containing the pkgs built by toplevelactions
2199 ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error
2205 type noToolchain struct{}
2207 func noCompiler() error {
2208 log.Fatalf("unknown compiler %q", buildContext.Compiler)
2212 func (noToolchain) compiler() string {
2217 func (noToolchain) linker() string {
2222 func (noToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error) {
2223 return "", nil, noCompiler()
2226 func (noToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
2230 func (noToolchain) pkgpath(basedir string, p *Package) string {
2235 func (noToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
2239 func (noToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error {
2243 func (noToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
2247 func (noToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
2251 // The Go toolchain.
2252 type gcToolchain struct{}
2254 func (gcToolchain) compiler() string {
2255 return tool("compile")
2258 func (gcToolchain) linker() string {
2262 func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
2270 gcargs := []string{"-p", p.ImportPath}
2271 if p.Name == "main" {
2274 if p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal")) {
2275 // runtime compiles with a special gc flag to emit
2276 // additional reflect type data.
2277 gcargs = append(gcargs, "-+")
2280 // If we're giving the compiler the entire package (no C etc files), tell it that,
2281 // so that it can give good error messages about forward declarations.
2282 // Exceptions: a few standard packages have forward declarations for
2283 // pieces supplied behind-the-scenes by package runtime.
2284 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)
2286 switch p.ImportPath {
2287 case "bytes", "net", "os", "runtime/pprof", "sync", "time":
2292 gcargs = append(gcargs, "-complete")
2294 if buildContext.InstallSuffix != "" {
2295 gcargs = append(gcargs, "-installsuffix", buildContext.InstallSuffix)
2297 if p.buildID != "" {
2298 gcargs = append(gcargs, "-buildid", p.buildID)
2301 for _, path := range p.Imports {
2302 if i := strings.LastIndex(path, "/vendor/"); i >= 0 {
2303 gcargs = append(gcargs, "-importmap", path[i+len("/vendor/"):]+"="+path)
2304 } else if strings.HasPrefix(path, "vendor/") {
2305 gcargs = append(gcargs, "-importmap", path[len("vendor/"):]+"="+path)
2309 args := []interface{}{buildToolExec, tool("compile"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs}
2310 if ofile == archive {
2311 args = append(args, "-pack")
2314 args = append(args, "-asmhdr", obj+"go_asm.h")
2316 for _, f := range gofiles {
2317 args = append(args, mkAbs(p.Dir, f))
2320 output, err = b.runOut(p.Dir, p.ImportPath, nil, args...)
2321 return ofile, output, err
2324 func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
2325 // Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
2326 inc := filepath.Join(goroot, "pkg", "include")
2327 sfile = mkAbs(p.Dir, sfile)
2328 args := []interface{}{buildToolExec, tool("asm"), "-o", ofile, "-trimpath", b.work, "-I", obj, "-I", inc, "-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch, buildAsmflags, sfile}
2329 if err := b.run(p.Dir, p.ImportPath, nil, args...); err != nil {
2335 // toolVerify checks that the command line args writes the same output file
2336 // if run using newTool instead.
2337 // Unused now but kept around for future use.
2338 func toolVerify(b *builder, p *Package, newTool string, ofile string, args []interface{}) error {
2339 newArgs := make([]interface{}, len(args))
2341 newArgs[1] = tool(newTool)
2342 newArgs[3] = ofile + ".new" // x.6 becomes x.6.new
2343 if err := b.run(p.Dir, p.ImportPath, nil, newArgs...); err != nil {
2346 data1, err := ioutil.ReadFile(ofile)
2350 data2, err := ioutil.ReadFile(ofile + ".new")
2354 if !bytes.Equal(data1, data2) {
2355 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...), " "))
2357 os.Remove(ofile + ".new")
2361 func (gcToolchain) pkgpath(basedir string, p *Package) string {
2362 end := filepath.FromSlash(p.ImportPath + ".a")
2363 return filepath.Join(basedir, end)
2366 func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
2367 var absOfiles []string
2368 for _, f := range ofiles {
2369 absOfiles = append(absOfiles, mkAbs(objDir, f))
2371 absAfile := mkAbs(objDir, afile)
2373 // The archive file should have been created by the compiler.
2374 // Since it used to not work that way, verify.
2376 if _, err := os.Stat(absAfile); err != nil {
2377 fatalf("os.Stat of archive file failed: %v", err)
2381 if buildN || buildX {
2382 cmdline := stringList("pack", "r", absAfile, absOfiles)
2383 b.showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline))
2388 if err := packInternal(b, absAfile, absOfiles); err != nil {
2389 b.showOutput(p.Dir, p.ImportPath, err.Error()+"\n")
2390 return errPrintedOutput
2395 func packInternal(b *builder, afile string, ofiles []string) error {
2396 dst, err := os.OpenFile(afile, os.O_WRONLY|os.O_APPEND, 0)
2400 defer dst.Close() // only for error returns or panics
2401 w := bufio.NewWriter(dst)
2403 for _, ofile := range ofiles {
2404 src, err := os.Open(ofile)
2408 fi, err := src.Stat()
2413 // Note: Not using %-16.16s format because we care
2414 // about bytes, not runes.
2419 name += strings.Repeat(" ", 16-len(name))
2422 fmt.Fprintf(w, "%s%-12d%-6d%-6d%-8o%-10d`\n",
2423 name, 0, 0, 0, 0644, size)
2424 n, err := io.Copy(w, src)
2426 if err == nil && n < size {
2427 err = io.ErrUnexpectedEOF
2428 } else if err == nil && n > size {
2429 err = fmt.Errorf("file larger than size reported by stat")
2432 return fmt.Errorf("copying %s to %s: %v", ofile, afile, err)
2439 if err := w.Flush(); err != nil {
2445 // setextld sets the appropriate linker flags for the specified compiler.
2446 func setextld(ldflags []string, compiler []string) []string {
2447 for _, f := range ldflags {
2448 if f == "-extld" || strings.HasPrefix(f, "-extld=") {
2449 // don't override -extld if supplied
2453 ldflags = append(ldflags, "-extld="+compiler[0])
2454 if len(compiler) > 1 {
2456 add := strings.Join(compiler[1:], " ")
2457 for i, f := range ldflags {
2458 if f == "-extldflags" && i+1 < len(ldflags) {
2459 ldflags[i+1] = add + " " + ldflags[i+1]
2462 } else if strings.HasPrefix(f, "-extldflags=") {
2463 ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
2469 ldflags = append(ldflags, "-extldflags="+add)
2475 func (gcToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error {
2476 importArgs := b.includeArgs("-L", allactions)
2477 cxx := len(root.p.CXXFiles) > 0 || len(root.p.SwigCXXFiles) > 0
2478 for _, a := range allactions {
2479 if a.p != nil && (len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0) {
2483 var ldflags []string
2484 if buildContext.InstallSuffix != "" {
2485 ldflags = append(ldflags, "-installsuffix", buildContext.InstallSuffix)
2487 if root.p.omitDWARF {
2488 ldflags = append(ldflags, "-w")
2491 // If the user has not specified the -extld option, then specify the
2492 // appropriate linker. In case of C++ code, use the compiler named
2493 // by the CXX environment variable or defaultCXX if CXX is not set.
2494 // Else, use the CC environment variable and defaultCC as fallback.
2495 var compiler []string
2497 compiler = envList("CXX", defaultCXX)
2499 compiler = envList("CC", defaultCC)
2501 ldflags = setextld(ldflags, compiler)
2502 ldflags = append(ldflags, "-buildmode="+ldBuildmode)
2503 if root.p.buildID != "" {
2504 ldflags = append(ldflags, "-buildid="+root.p.buildID)
2506 ldflags = append(ldflags, buildLdflags...)
2508 // On OS X when using external linking to build a shared library,
2509 // the argument passed here to -o ends up recorded in the final
2510 // shared library in the LC_ID_DYLIB load command.
2511 // To avoid putting the temporary output directory name there
2512 // (and making the resulting shared library useless),
2513 // run the link in the output directory so that -o can name
2514 // just the final path element.
2516 if goos == "darwin" && buildBuildmode == "c-shared" {
2517 dir, out = filepath.Split(out)
2520 return b.run(dir, root.p.ImportPath, nil, buildToolExec, tool("link"), "-o", out, importArgs, ldflags, mainpkg)
2523 func (gcToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
2524 importArgs := b.includeArgs("-L", allactions)
2525 ldflags := []string{"-installsuffix", buildContext.InstallSuffix}
2526 ldflags = append(ldflags, "-buildmode=shared")
2527 ldflags = append(ldflags, buildLdflags...)
2529 for _, a := range allactions {
2530 if a.p != nil && (len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0) {
2534 // If the user has not specified the -extld option, then specify the
2535 // appropriate linker. In case of C++ code, use the compiler named
2536 // by the CXX environment variable or defaultCXX if CXX is not set.
2537 // Else, use the CC environment variable and defaultCC as fallback.
2538 var compiler []string
2540 compiler = envList("CXX", defaultCXX)
2542 compiler = envList("CC", defaultCC)
2544 ldflags = setextld(ldflags, compiler)
2545 for _, d := range toplevelactions {
2546 if !strings.HasSuffix(d.target, ".a") { // omit unsafe etc and actions for other shared libraries
2549 ldflags = append(ldflags, d.p.ImportPath+"="+d.target)
2551 return b.run(".", out, nil, buildToolExec, tool("link"), "-o", out, importArgs, ldflags)
2554 func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
2555 return fmt.Errorf("%s: C source files not supported without cgo", mkAbs(p.Dir, cfile))
2558 // The Gccgo toolchain.
2559 type gccgoToolchain struct{}
2561 var gccgoName, gccgoBin string
2564 gccgoName = os.Getenv("GCCGO")
2565 if gccgoName == "" {
2568 gccgoBin, _ = exec.LookPath(gccgoName)
2571 func (gccgoToolchain) compiler() string {
2575 func (gccgoToolchain) linker() string {
2579 func (tools gccgoToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
2582 gcargs := []string{"-g"}
2583 gcargs = append(gcargs, b.gccArchArgs()...)
2584 if pkgpath := gccgoPkgpath(p); pkgpath != "" {
2585 gcargs = append(gcargs, "-fgo-pkgpath="+pkgpath)
2587 if p.localPrefix != "" {
2588 gcargs = append(gcargs, "-fgo-relative-import-path="+p.localPrefix)
2590 args := stringList(tools.compiler(), importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags)
2591 for _, f := range gofiles {
2592 args = append(args, mkAbs(p.Dir, f))
2595 output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
2596 return ofile, output, err
2599 func (tools gccgoToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
2600 sfile = mkAbs(p.Dir, sfile)
2601 defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
2602 if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
2603 defs = append(defs, `-D`, `GOPKGPATH=`+pkgpath)
2605 defs = tools.maybePIC(defs)
2606 defs = append(defs, b.gccArchArgs()...)
2607 return b.run(p.Dir, p.ImportPath, nil, tools.compiler(), "-xassembler-with-cpp", "-I", obj, "-c", "-o", ofile, defs, sfile)
2610 func (gccgoToolchain) pkgpath(basedir string, p *Package) string {
2611 end := filepath.FromSlash(p.ImportPath + ".a")
2612 afile := filepath.Join(basedir, end)
2613 // add "lib" to the final element
2614 return filepath.Join(filepath.Dir(afile), "lib"+filepath.Base(afile))
2617 func (gccgoToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
2618 var absOfiles []string
2619 for _, f := range ofiles {
2620 absOfiles = append(absOfiles, mkAbs(objDir, f))
2622 return b.run(p.Dir, p.ImportPath, nil, "ar", "rc", mkAbs(objDir, afile), absOfiles)
2625 func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error {
2626 // gccgo needs explicit linking with all package dependencies,
2627 // and all LDFLAGS from cgo dependencies.
2628 apackagePathsSeen := make(map[string]bool)
2629 afiles := []string{}
2630 shlibs := []string{}
2631 ldflags := b.gccArchArgs()
2632 cgoldflags := []string{}
2634 cxx := len(root.p.CXXFiles) > 0 || len(root.p.SwigCXXFiles) > 0
2635 objc := len(root.p.MFiles) > 0
2636 fortran := len(root.p.FFiles) > 0
2638 readCgoFlags := func(flagsFile string) error {
2639 flags, err := ioutil.ReadFile(flagsFile)
2643 const ldflagsPrefix = "_CGO_LDFLAGS="
2644 for _, line := range strings.Split(string(flags), "\n") {
2645 if strings.HasPrefix(line, ldflagsPrefix) {
2646 newFlags := strings.Fields(line[len(ldflagsPrefix):])
2647 for _, flag := range newFlags {
2648 // Every _cgo_flags file has -g and -O2 in _CGO_LDFLAGS
2649 // but they don't mean anything to the linker so filter
2651 if flag != "-g" && !strings.HasPrefix(flag, "-O") {
2652 cgoldflags = append(cgoldflags, flag)
2660 readAndRemoveCgoFlags := func(archive string) (string, error) {
2661 newa, err := ioutil.TempFile(b.work, filepath.Base(archive))
2665 olda, err := os.Open(archive)
2669 _, err = io.Copy(newa, olda)
2682 newarchive := newa.Name()
2683 err = b.run(b.work, root.p.ImportPath, nil, "ar", "x", newarchive, "_cgo_flags")
2687 err = b.run(".", root.p.ImportPath, nil, "ar", "d", newarchive, "_cgo_flags")
2691 err = readCgoFlags(filepath.Join(b.work, "_cgo_flags"))
2695 return newarchive, nil
2698 actionsSeen := make(map[*action]bool)
2699 // Make a pre-order depth-first traversal of the action graph, taking note of
2700 // whether a shared library action has been seen on the way to an action (the
2701 // construction of the graph means that if any path to a node passes through
2702 // a shared library action, they all do).
2703 var walk func(a *action, seenShlib bool)
2705 walk = func(a *action, seenShlib bool) {
2709 actionsSeen[a] = true
2710 if a.p != nil && !seenShlib {
2714 // We record the target of the first time we see a .a file
2715 // for a package to make sure that we prefer the 'install'
2716 // rather than the 'build' location (which may not exist any
2717 // more). We still need to traverse the dependencies of the
2718 // build action though so saying
2719 // if apackagePathsSeen[a.p.ImportPath] { return }
2721 if !apackagePathsSeen[a.p.ImportPath] {
2722 apackagePathsSeen[a.p.ImportPath] = true
2724 if len(a.p.CgoFiles) > 0 {
2725 target, err = readAndRemoveCgoFlags(target)
2730 afiles = append(afiles, target)
2733 if strings.HasSuffix(a.target, ".so") {
2734 shlibs = append(shlibs, a.target)
2737 for _, a1 := range a.deps {
2744 for _, a1 := range root.deps {
2751 for _, a := range allactions {
2752 // Gather CgoLDFLAGS, but not from standard packages.
2753 // The go tool can dig up runtime/cgo from GOROOT and
2754 // think that it should use its CgoLDFLAGS, but gccgo
2755 // doesn't use runtime/cgo.
2760 cgoldflags = append(cgoldflags, a.p.CgoLDFLAGS...)
2762 if len(a.p.CgoFiles) > 0 {
2768 if len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0 {
2771 if len(a.p.MFiles) > 0 {
2774 if len(a.p.FFiles) > 0 {
2779 for i, o := range ofiles {
2780 if filepath.Base(o) == "_cgo_flags" {
2782 ofiles = append(ofiles[:i], ofiles[i+1:]...)
2787 ldflags = append(ldflags, "-Wl,--whole-archive")
2788 ldflags = append(ldflags, afiles...)
2789 ldflags = append(ldflags, "-Wl,--no-whole-archive")
2791 ldflags = append(ldflags, cgoldflags...)
2792 ldflags = append(ldflags, envList("CGO_LDFLAGS", "")...)
2793 ldflags = append(ldflags, root.p.CgoLDFLAGS...)
2795 ldflags = stringList("-Wl,-(", ldflags, "-Wl,-)")
2797 for _, shlib := range shlibs {
2800 "-L"+filepath.Dir(shlib),
2801 "-Wl,-rpath="+filepath.Dir(shlib),
2802 "-l"+strings.TrimSuffix(
2803 strings.TrimPrefix(filepath.Base(shlib), "lib"),
2808 switch ldBuildmode {
2810 if usesCgo && goos == "linux" {
2811 ldflags = append(ldflags, "-Wl,-E")
2815 // Link the Go files into a single .o, and also link
2818 // We need to use --whole-archive with -lgolibbegin
2819 // because it doesn't define any symbols that will
2820 // cause the contents to be pulled in; it's just
2821 // initialization code.
2823 // The user remains responsible for linking against
2824 // -lgo -lpthread -lm in the final link. We can't use
2825 // -r to pick them up because we can't combine
2826 // split-stack and non-split-stack code in a single -r
2827 // link, and libgo picks up non-split-stack code from
2829 ldflags = append(ldflags, "-Wl,-r", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive")
2831 if b.gccSupportsNoPie() {
2832 ldflags = append(ldflags, "-no-pie")
2835 // We are creating an object file, so we don't want a build ID.
2836 ldflags = b.disableBuildID(ldflags)
2842 ldflags = append(ldflags, "-shared", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive", "-lgo", "-lgcc_s", "-lgcc", "-lc", "-lgcc")
2845 fatalf("-buildmode=%s not supported for gccgo", ldBuildmode)
2848 switch ldBuildmode {
2849 case "exe", "c-shared":
2851 ldflags = append(ldflags, "-lstdc++")
2854 ldflags = append(ldflags, "-lobjc")
2857 fc := os.Getenv("FC")
2861 // support gfortran out of the box and let others pass the correct link options
2863 if strings.Contains(fc, "gfortran") {
2864 ldflags = append(ldflags, "-lgfortran")
2869 if err := b.run(".", root.p.ImportPath, nil, tools.linker(), "-o", out, ofiles, ldflags, buildGccgoflags); err != nil {
2873 switch ldBuildmode {
2875 if err := b.run(".", root.p.ImportPath, nil, "ar", "rc", realOut, out); err != nil {
2882 func (tools gccgoToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
2883 args := []string{"-o", out, "-shared", "-nostdlib", "-zdefs", "-Wl,--whole-archive"}
2884 for _, a := range toplevelactions {
2885 args = append(args, a.target)
2887 args = append(args, "-Wl,--no-whole-archive", "-shared", "-nostdlib", "-lgo", "-lgcc_s", "-lgcc", "-lc")
2888 shlibs := []string{}
2889 for _, a := range allactions {
2890 if strings.HasSuffix(a.target, ".so") {
2891 shlibs = append(shlibs, a.target)
2894 for _, shlib := range shlibs {
2897 "-L"+filepath.Dir(shlib),
2898 "-Wl,-rpath="+filepath.Dir(shlib),
2899 "-l"+strings.TrimSuffix(
2900 strings.TrimPrefix(filepath.Base(shlib), "lib"),
2903 return b.run(".", out, nil, tools.linker(), args, buildGccgoflags)
2906 func (tools gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
2907 inc := filepath.Join(goroot, "pkg", "include")
2908 cfile = mkAbs(p.Dir, cfile)
2909 defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
2910 defs = append(defs, b.gccArchArgs()...)
2911 if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
2912 defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
2915 case "386", "amd64":
2916 defs = append(defs, "-fsplit-stack")
2918 defs = tools.maybePIC(defs)
2919 return b.run(p.Dir, p.ImportPath, nil, envList("CC", defaultCC), "-Wall", "-g",
2920 "-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile)
2923 // maybePIC adds -fPIC to the list of arguments if needed.
2924 func (tools gccgoToolchain) maybePIC(args []string) []string {
2925 switch buildBuildmode {
2926 case "c-shared", "shared":
2927 args = append(args, "-fPIC")
2932 func gccgoPkgpath(p *Package) string {
2933 if p.build.IsCommand() && !p.forceLibrary {
2939 func gccgoCleanPkgpath(p *Package) string {
2940 clean := func(r rune) rune {
2942 case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
2943 '0' <= r && r <= '9':
2948 return strings.Map(clean, gccgoPkgpath(p))
2951 // gcc runs the gcc C compiler to create an object from a single C file.
2952 func (b *builder) gcc(p *Package, out string, flags []string, cfile string) error {
2953 return b.ccompile(p, out, flags, cfile, b.gccCmd(p.Dir))
2956 // gxx runs the g++ C++ compiler to create an object from a single C++ file.
2957 func (b *builder) gxx(p *Package, out string, flags []string, cxxfile string) error {
2958 return b.ccompile(p, out, flags, cxxfile, b.gxxCmd(p.Dir))
2961 // gfortran runs the gfortran Fortran compiler to create an object from a single Fortran file.
2962 func (b *builder) gfortran(p *Package, out string, flags []string, ffile string) error {
2963 return b.ccompile(p, out, flags, ffile, b.gfortranCmd(p.Dir))
2966 // ccompile runs the given C or C++ compiler and creates an object from a single source file.
2967 func (b *builder) ccompile(p *Package, out string, flags []string, file string, compiler []string) error {
2968 file = mkAbs(p.Dir, file)
2969 return b.run(p.Dir, p.ImportPath, nil, compiler, flags, "-o", out, "-c", file)
2972 // gccld runs the gcc linker to create an executable from a set of object files.
2973 func (b *builder) gccld(p *Package, out string, flags []string, obj []string) error {
2975 if len(p.CXXFiles) > 0 || len(p.SwigCXXFiles) > 0 {
2976 cmd = b.gxxCmd(p.Dir)
2978 cmd = b.gccCmd(p.Dir)
2980 return b.run(p.Dir, p.ImportPath, nil, cmd, "-o", out, obj, flags)
2983 // gccCmd returns a gcc command line prefix
2984 // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
2985 func (b *builder) gccCmd(objdir string) []string {
2986 return b.ccompilerCmd("CC", defaultCC, objdir)
2989 // gxxCmd returns a g++ command line prefix
2990 // defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
2991 func (b *builder) gxxCmd(objdir string) []string {
2992 return b.ccompilerCmd("CXX", defaultCXX, objdir)
2995 // gfortranCmd returns a gfortran command line prefix.
2996 func (b *builder) gfortranCmd(objdir string) []string {
2997 return b.ccompilerCmd("FC", "gfortran", objdir)
3000 // ccompilerCmd returns a command line prefix for the given environment
3001 // variable and using the default command when the variable is empty.
3002 func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
3003 // NOTE: env.go's mkEnv knows that the first three
3004 // strings returned are "gcc", "-I", objdir (and cuts them off).
3006 compiler := envList(envvar, defcmd)
3007 a := []string{compiler[0], "-I", objdir}
3008 a = append(a, compiler[1:]...)
3010 // Definitely want -fPIC but on Windows gcc complains
3011 // "-fPIC ignored for target (all code is position independent)"
3012 if goos != "windows" {
3013 a = append(a, "-fPIC")
3015 a = append(a, b.gccArchArgs()...)
3016 // gcc-4.5 and beyond require explicit "-pthread" flag
3017 // for multithreading with pthread library.
3018 if buildContext.CgoEnabled {
3021 a = append(a, "-mthreads")
3023 a = append(a, "-pthread")
3027 if strings.Contains(a[0], "clang") {
3028 // disable ASCII art in clang errors, if possible
3029 a = append(a, "-fno-caret-diagnostics")
3030 // clang is too smart about command-line arguments
3031 a = append(a, "-Qunused-arguments")
3034 // disable word wrapping in error messages
3035 a = append(a, "-fmessage-length=0")
3037 // Tell gcc not to include the work directory in object files.
3038 if b.gccSupportsFlag("-fdebug-prefix-map=a=b") {
3039 a = append(a, "-fdebug-prefix-map="+b.work+"=/tmp/go-build")
3042 // Tell gcc not to include flags in object files, which defeats the
3043 // point of -fdebug-prefix-map above.
3044 if b.gccSupportsFlag("-gno-record-gcc-switches") {
3045 a = append(a, "-gno-record-gcc-switches")
3048 // On OS X, some of the compilers behave as if -fno-common
3049 // is always set, and the Mach-O linker in 6l/8l assumes this.
3050 // See https://golang.org/issue/3253.
3051 if goos == "darwin" {
3052 a = append(a, "-fno-common")
3058 // On systems with PIE (position independent executables) enabled by default,
3059 // -no-pie must be passed when doing a partial link with -Wl,-r. But -no-pie is
3060 // not supported by all compilers.
3061 func (b *builder) gccSupportsNoPie() bool {
3062 return b.gccSupportsFlag("-no-pie")
3065 // gccSupportsFlag checks to see if the compiler supports a flag.
3066 func (b *builder) gccSupportsFlag(flag string) bool {
3068 defer b.exec.Unlock()
3069 if b, ok := b.flagCache[flag]; ok {
3072 if b.flagCache == nil {
3073 src := filepath.Join(b.work, "trivial.c")
3074 if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
3077 b.flagCache = make(map[string]bool)
3079 cmdArgs := append(envList("CC", defaultCC), flag, "-c", "trivial.c")
3080 if buildN || buildX {
3081 b.showcmd(b.work, "%s", joinUnambiguously(cmdArgs))
3086 cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
3088 cmd.Env = envForDir(cmd.Dir, os.Environ())
3089 out, err := cmd.CombinedOutput()
3090 supported := err == nil && !bytes.Contains(out, []byte("unrecognized"))
3091 b.flagCache[flag] = supported
3095 // gccArchArgs returns arguments to pass to gcc based on the architecture.
3096 func (b *builder) gccArchArgs() []string {
3099 return []string{"-m32"}
3100 case "amd64", "amd64p32":
3101 return []string{"-m64"}
3103 return []string{"-marm"} // not thumb
3105 return []string{"-m64", "-march=z196"}
3110 // envList returns the value of the given environment variable broken
3111 // into fields, using the default value when the variable is empty.
3112 func envList(key, def string) []string {
3117 return strings.Fields(v)
3120 // Return the flags to use when invoking the C, C++ or Fortran compilers, or cgo.
3121 func (b *builder) cflags(p *Package, def bool) (cppflags, cflags, cxxflags, fflags, ldflags []string) {
3127 cppflags = stringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS)
3128 cflags = stringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS)
3129 cxxflags = stringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS)
3130 fflags = stringList(envList("CGO_FFLAGS", defaults), p.CgoFFLAGS)
3131 ldflags = stringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS)
3135 var cgoRe = regexp.MustCompile(`[/\\:]`)
3137 func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofiles, gccfiles, gxxfiles, mfiles, ffiles []string) (outGo, outObj []string, err error) {
3138 cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoFFLAGS, cgoLDFLAGS := b.cflags(p, true)
3139 _, cgoexeCFLAGS, _, _, _ := b.cflags(p, false)
3140 cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...)
3141 cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...)
3142 // If we are compiling Objective-C code, then we need to link against libobjc
3143 if len(mfiles) > 0 {
3144 cgoLDFLAGS = append(cgoLDFLAGS, "-lobjc")
3147 // Likewise for Fortran, except there are many Fortran compilers.
3148 // Support gfortran out of the box and let others pass the correct link options
3150 if len(ffiles) > 0 {
3151 fc := os.Getenv("FC")
3155 if strings.Contains(fc, "gfortran") {
3156 cgoLDFLAGS = append(cgoLDFLAGS, "-lgfortran")
3160 if buildMSan && p.ImportPath != "runtime/cgo" {
3161 cgoCFLAGS = append([]string{"-fsanitize=memory"}, cgoCFLAGS...)
3162 cgoLDFLAGS = append([]string{"-fsanitize=memory"}, cgoLDFLAGS...)
3165 // Allows including _cgo_export.h from .[ch] files in the package.
3166 cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", obj)
3170 gofiles := []string{obj + "_cgo_gotypes.go"}
3171 cfiles := []string{"_cgo_main.c", "_cgo_export.c"}
3172 for _, fn := range cgofiles {
3173 f := cgoRe.ReplaceAllString(fn[:len(fn)-2], "_")
3174 gofiles = append(gofiles, obj+f+"cgo1.go")
3175 cfiles = append(cfiles, f+"cgo2.c")
3177 defunC := obj + "_cgo_defun.c"
3179 cgoflags := []string{}
3180 // TODO: make cgo not depend on $GOARCH?
3182 if p.Standard && p.ImportPath == "runtime/cgo" {
3183 cgoflags = append(cgoflags, "-import_runtime_cgo=false")
3185 if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/msan" || p.ImportPath == "runtime/cgo") {
3186 cgoflags = append(cgoflags, "-import_syscall=false")
3189 // Update $CGO_LDFLAGS with p.CgoLDFLAGS.
3191 if len(cgoLDFLAGS) > 0 {
3192 flags := make([]string, len(cgoLDFLAGS))
3193 for i, f := range cgoLDFLAGS {
3194 flags[i] = strconv.Quote(f)
3196 cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
3199 if _, ok := buildToolchain.(gccgoToolchain); ok {
3201 case "386", "amd64":
3202 cgoCFLAGS = append(cgoCFLAGS, "-fsplit-stack")
3204 cgoflags = append(cgoflags, "-gccgo")
3205 if pkgpath := gccgoPkgpath(p); pkgpath != "" {
3206 cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
3210 switch buildBuildmode {
3211 case "c-archive", "c-shared":
3212 // Tell cgo that if there are any exported functions
3213 // it should generate a header file that C code can
3215 cgoflags = append(cgoflags, "-exportheader="+obj+"_cgo_install.h")
3218 if err := b.run(p.Dir, p.ImportPath, cgoenv, buildToolExec, cgoExe, "-objdir", obj, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoexeCFLAGS, cgofiles); err != nil {
3219 return nil, nil, err
3221 outGo = append(outGo, gofiles...)
3224 _, gccgo := buildToolchain.(gccgoToolchain)
3226 defunObj := obj + "_cgo_defun.o"
3227 if err := buildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
3228 return nil, nil, err
3230 outObj = append(outObj, defunObj)
3234 var linkobj []string
3236 var bareLDFLAGS []string
3237 // When linking relocatable objects, various flags need to be
3238 // filtered out as they are inapplicable and can cause some linkers
3240 for i := 0; i < len(cgoLDFLAGS); i++ {
3243 // skip "-lc" or "-l somelib"
3244 case strings.HasPrefix(f, "-l"):
3248 // skip "-framework X" on Darwin
3249 case goos == "darwin" && f == "-framework":
3251 // skip "*.{dylib,so,dll}"
3252 case strings.HasSuffix(f, ".dylib"),
3253 strings.HasSuffix(f, ".so"),
3254 strings.HasSuffix(f, ".dll"):
3255 // Remove any -fsanitize=foo flags.
3256 // Otherwise the compiler driver thinks that we are doing final link
3257 // and links sanitizer runtime into the object file. But we are not doing
3258 // the final link, we will link the resulting object file again. And
3259 // so the program ends up with two copies of sanitizer runtime.
3260 // See issue 8788 for details.
3261 case strings.HasPrefix(f, "-fsanitize="):
3263 // runpath flags not applicable unless building a shared
3264 // object or executable; see issue 12115 for details. This
3265 // is necessary as Go currently does not offer a way to
3266 // specify the set of LDFLAGS that only apply to shared
3268 case strings.HasPrefix(f, "-Wl,-rpath"):
3269 if f == "-Wl,-rpath" || f == "-Wl,-rpath-link" {
3270 // Skip following argument to -rpath* too.
3274 bareLDFLAGS = append(bareLDFLAGS, f)
3278 var staticLibs []string
3279 if goos == "windows" {
3280 // libmingw32 and libmingwex have some inter-dependencies,
3281 // so must use linker groups.
3282 staticLibs = []string{"-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group"}
3285 cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
3286 for _, cfile := range cfiles {
3287 ofile := obj + cfile[:len(cfile)-1] + "o"
3288 if err := b.gcc(p, ofile, cflags, obj+cfile); err != nil {
3289 return nil, nil, err
3291 linkobj = append(linkobj, ofile)
3292 if !strings.HasSuffix(ofile, "_cgo_main.o") {
3293 outObj = append(outObj, ofile)
3297 for _, file := range gccfiles {
3298 ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
3299 if err := b.gcc(p, ofile, cflags, file); err != nil {
3300 return nil, nil, err
3302 linkobj = append(linkobj, ofile)
3303 outObj = append(outObj, ofile)
3306 cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
3307 for _, file := range gxxfiles {
3308 // Append .o to the file, just in case the pkg has file.c and file.cpp
3309 ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
3310 if err := b.gxx(p, ofile, cxxflags, file); err != nil {
3311 return nil, nil, err
3313 linkobj = append(linkobj, ofile)
3314 outObj = append(outObj, ofile)
3317 for _, file := range mfiles {
3318 // Append .o to the file, just in case the pkg has file.c and file.m
3319 ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
3320 if err := b.gcc(p, ofile, cflags, file); err != nil {
3321 return nil, nil, err
3323 linkobj = append(linkobj, ofile)
3324 outObj = append(outObj, ofile)
3327 fflags := stringList(cgoCPPFLAGS, cgoFFLAGS)
3328 for _, file := range ffiles {
3329 // Append .o to the file, just in case the pkg has file.c and file.f
3330 ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
3331 if err := b.gfortran(p, ofile, fflags, file); err != nil {
3332 return nil, nil, err
3334 linkobj = append(linkobj, ofile)
3335 outObj = append(outObj, ofile)
3338 linkobj = append(linkobj, p.SysoFiles...)
3339 dynobj := obj + "_cgo_.o"
3340 pie := (goarch == "arm" && goos == "linux") || goos == "android"
3341 if pie { // we need to use -pie for Linux/ARM to get accurate imported sym
3342 cgoLDFLAGS = append(cgoLDFLAGS, "-pie")
3344 if err := b.gccld(p, dynobj, cgoLDFLAGS, linkobj); err != nil {
3345 return nil, nil, err
3347 if pie { // but we don't need -pie for normal cgo programs
3348 cgoLDFLAGS = cgoLDFLAGS[0 : len(cgoLDFLAGS)-1]
3351 if _, ok := buildToolchain.(gccgoToolchain); ok {
3352 // we don't use dynimport when using gccgo.
3353 return outGo, outObj, nil
3357 importGo := obj + "_cgo_import.go"
3358 cgoflags = []string{}
3359 if p.Standard && p.ImportPath == "runtime/cgo" {
3360 cgoflags = append(cgoflags, "-dynlinker") // record path to dynamic linker
3362 if err := b.run(p.Dir, p.ImportPath, nil, buildToolExec, cgoExe, "-objdir", obj, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags); err != nil {
3363 return nil, nil, err
3365 outGo = append(outGo, importGo)
3367 ofile := obj + "_all.o"
3368 var gccObjs, nonGccObjs []string
3369 for _, f := range outObj {
3370 if strings.HasSuffix(f, ".o") {
3371 gccObjs = append(gccObjs, f)
3373 nonGccObjs = append(nonGccObjs, f)
3376 ldflags := stringList(bareLDFLAGS, "-Wl,-r", "-nostdlib", staticLibs)
3378 if b.gccSupportsNoPie() {
3379 ldflags = append(ldflags, "-no-pie")
3382 // We are creating an object file, so we don't want a build ID.
3383 ldflags = b.disableBuildID(ldflags)
3385 if err := b.gccld(p, ofile, ldflags, gccObjs); err != nil {
3386 return nil, nil, err
3389 // NOTE(rsc): The importObj is a 5c/6c/8c object and on Windows
3390 // must be processed before the gcc-generated objects.
3391 // Put it first. https://golang.org/issue/2601
3392 outObj = stringList(nonGccObjs, ofile)
3394 return outGo, outObj, nil
3397 // Run SWIG on all SWIG input files.
3398 // TODO: Don't build a shared library, once SWIG emits the necessary
3399 // pragmas for external linking.
3400 func (b *builder) swig(p *Package, obj string, pcCFLAGS []string) (outGo, outC, outCXX []string, err error) {
3401 if err := b.swigVersionCheck(); err != nil {
3402 return nil, nil, nil, err
3405 intgosize, err := b.swigIntSize(obj)
3407 return nil, nil, nil, err
3410 for _, f := range p.SwigFiles {
3411 goFile, cFile, err := b.swigOne(p, f, obj, pcCFLAGS, false, intgosize)
3413 return nil, nil, nil, err
3416 outGo = append(outGo, goFile)
3419 outC = append(outC, cFile)
3422 for _, f := range p.SwigCXXFiles {
3423 goFile, cxxFile, err := b.swigOne(p, f, obj, pcCFLAGS, true, intgosize)
3425 return nil, nil, nil, err
3428 outGo = append(outGo, goFile)
3431 outCXX = append(outCXX, cxxFile)
3434 return outGo, outC, outCXX, nil
3437 // Make sure SWIG is new enough.
3439 swigCheckOnce sync.Once
3443 func (b *builder) swigDoVersionCheck() error {
3444 out, err := b.runOut("", "", nil, "swig", "-version")
3448 re := regexp.MustCompile(`[vV]ersion +([\d]+)([.][\d]+)?([.][\d]+)?`)
3449 matches := re.FindSubmatch(out)
3451 // Can't find version number; hope for the best.
3455 major, err := strconv.Atoi(string(matches[1]))
3457 // Can't find version number; hope for the best.
3460 const errmsg = "must have SWIG version >= 3.0.6"
3462 return errors.New(errmsg)
3469 // We have SWIG version 3.x.
3470 if len(matches[2]) > 0 {
3471 minor, err := strconv.Atoi(string(matches[2][1:]))
3481 // We have SWIG version 3.0.x.
3482 if len(matches[3]) > 0 {
3483 patch, err := strconv.Atoi(string(matches[3][1:]))
3489 return errors.New(errmsg)
3496 func (b *builder) swigVersionCheck() error {
3497 swigCheckOnce.Do(func() {
3498 swigCheck = b.swigDoVersionCheck()
3503 // Find the value to pass for the -intgosize option to swig.
3505 swigIntSizeOnce sync.Once
3507 swigIntSizeError error
3510 // This code fails to build if sizeof(int) <= 32
3511 const swigIntSizeCode = `
3513 const i int = 1 << 32
3516 // Determine the size of int on the target system for the -intgosize option
3517 // of swig >= 2.0.9. Run only once.
3518 func (b *builder) swigDoIntSize(obj string) (intsize string, err error) {
3520 return "$INTBITS", nil
3522 src := filepath.Join(b.work, "swig_intsize.go")
3523 if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0666); err != nil {
3526 srcs := []string{src}
3528 p := goFilesPackage(srcs)
3530 if _, _, e := buildToolchain.gc(b, p, "", obj, false, nil, srcs); e != nil {
3536 // Determine the size of int on the target system for the -intgosize option
3537 // of swig >= 2.0.9.
3538 func (b *builder) swigIntSize(obj string) (intsize string, err error) {
3539 swigIntSizeOnce.Do(func() {
3540 swigIntSize, swigIntSizeError = b.swigDoIntSize(obj)
3542 return swigIntSize, swigIntSizeError
3545 // Run SWIG on one SWIG input file.
3546 func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outC string, err error) {
3547 cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _, _ := b.cflags(p, true)
3550 cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS)
3552 cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS)
3555 n := 5 // length of ".swig"
3557 n = 8 // length of ".swigcxx"
3559 base := file[:len(file)-n]
3560 goFile := base + ".go"
3561 gccBase := base + "_wrap."
3567 _, gccgo := buildToolchain.(gccgoToolchain)
3573 "-intgosize", intgosize,
3575 "-o", obj + gccBase + gccExt,
3579 for _, f := range cflags {
3580 if len(f) > 3 && f[:2] == "-I" {
3581 args = append(args, f)
3586 args = append(args, "-gccgo")
3587 if pkgpath := gccgoPkgpath(p); pkgpath != "" {
3588 args = append(args, "-go-pkgpath", pkgpath)
3592 args = append(args, "-c++")
3595 out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file)
3598 if bytes.Contains(out, []byte("-intgosize")) || bytes.Contains(out, []byte("-cgo")) {
3599 return "", "", errors.New("must have SWIG version >= 3.0.6")
3601 b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig error
3602 return "", "", errPrintedOutput
3607 b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig warning
3610 return obj + goFile, obj + gccBase + gccExt, nil
3613 // disableBuildID adjusts a linker command line to avoid creating a
3614 // build ID when creating an object file rather than an executable or
3615 // shared library. Some systems, such as Ubuntu, always add
3616 // --build-id to every link, but we don't want a build ID when we are
3617 // producing an object file. On some of those system a plain -r (not
3618 // -Wl,-r) will turn off --build-id, but clang 3.0 doesn't support a
3619 // plain -r. I don't know how to turn off --build-id when using clang
3620 // other than passing a trailing --build-id=none. So that is what we
3621 // do, but only on systems likely to support it, which is to say,
3622 // systems that normally use gold or the GNU linker.
3623 func (b *builder) disableBuildID(ldflags []string) []string {
3625 case "android", "dragonfly", "linux", "netbsd":
3626 ldflags = append(ldflags, "-Wl,--build-id=none")
3631 // An actionQueue is a priority queue of actions.
3632 type actionQueue []*action
3634 // Implement heap.Interface
3635 func (q *actionQueue) Len() int { return len(*q) }
3636 func (q *actionQueue) Swap(i, j int) { (*q)[i], (*q)[j] = (*q)[j], (*q)[i] }
3637 func (q *actionQueue) Less(i, j int) bool { return (*q)[i].priority < (*q)[j].priority }
3638 func (q *actionQueue) Push(x interface{}) { *q = append(*q, x.(*action)) }
3639 func (q *actionQueue) Pop() interface{} {
3646 func (q *actionQueue) push(a *action) {
3650 func (q *actionQueue) pop() *action {
3651 return heap.Pop(q).(*action)
3654 func instrumentInit() {
3655 if !buildRace && !buildMSan {
3658 if buildRace && buildMSan {
3659 fmt.Fprintf(os.Stderr, "go %s: may not use -race and -msan simultaneously", flag.Args()[0])
3662 if goarch != "amd64" || goos != "linux" && goos != "freebsd" && goos != "darwin" && goos != "windows" {
3663 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])
3666 if !buildContext.CgoEnabled {
3667 fmt.Fprintf(os.Stderr, "go %s: -race requires cgo; enable cgo by setting CGO_ENABLED=1\n", flag.Args()[0])
3671 buildGcflags = append(buildGcflags, "-race")
3672 buildLdflags = append(buildLdflags, "-race")
3674 buildGcflags = append(buildGcflags, "-msan")
3675 buildLdflags = append(buildLdflags, "-msan")
3677 if buildContext.InstallSuffix != "" {
3678 buildContext.InstallSuffix += "_"
3682 buildContext.InstallSuffix += "race"
3683 buildContext.BuildTags = append(buildContext.BuildTags, "race")
3685 buildContext.InstallSuffix += "msan"
3686 buildContext.BuildTags = append(buildContext.BuildTags, "msan")