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.
30 var cmdBuild = &Command{
31 UsageLine: "build [-o output] [-i] [build flags] [packages]",
32 Short: "compile packages and dependencies",
34 Build compiles the packages named by the import paths,
35 along with their dependencies, but it does not install the results.
37 If the arguments are a list of .go files, build treats them as a list
38 of source files specifying a single package.
40 When the command line specifies a single main package,
41 build writes the resulting executable to output.
42 Otherwise build compiles the packages but discards the results,
43 serving only as a check that the packages can be built.
45 The -o flag specifies the output file name. If not specified, the
46 output file name depends on the arguments and derives from the name
47 of the package, such as p.a for package p, unless p is 'main'. If
48 the package is main and file names are provided, the file name
49 derives from the first file name mentioned, such as f1 for 'go build
50 f1.go f2.go'; with no files provided ('go build'), the output file
51 name is the base name of the containing directory.
53 The -i flag installs the packages that are dependencies of the target.
55 The build flags are shared by the build, clean, get, install, list, run,
59 force rebuilding of packages that are already up-to-date.
60 In Go releases, does not apply to the standard library.
62 print the commands but do not run them.
64 the number of builds that can be run in parallel.
65 The default is the number of CPUs available.
67 enable data race detection.
68 Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
70 print the names of packages as they are compiled.
72 print the name of the temporary work directory and
73 do not delete it when exiting.
78 name of compiler to use, as in runtime.Compiler (gccgo or gc).
79 -gccgoflags 'arg list'
80 arguments to pass on each gccgo compiler/linker invocation.
82 arguments to pass on each 5g, 6g, 8g, or 9g compiler invocation.
84 a suffix to use in the name of the package installation directory,
85 in order to keep output separate from default builds.
86 If using the -race flag, the install suffix is automatically set to race
87 or, if set explicitly, has _race appended to it.
89 arguments to pass on each 5l, 6l, 8l, or 9l linker invocation.
91 a list of build tags to consider satisfied during the build.
92 For more information about build tags, see the description of
93 build constraints in the documentation for the go/build package.
95 a program to use to invoke toolchain programs like 5a, 5g, and 5l.
96 For example, instead of running 5g, the go command will run
97 'cmd args /path/to/5g <arguments for 5g>'.
99 The list flags accept a space-separated list of strings. To embed spaces
100 in an element in the list, surround it with either single or double quotes.
102 For more about specifying packages, see 'go help packages'.
103 For more about where packages and binaries are installed,
104 run 'go help gopath'. For more about calling between Go and C/C++,
107 See also: go install, go get, go clean.
113 cmdBuild.Run = runBuild
114 cmdInstall.Run = runInstall
116 cmdBuild.Flag.BoolVar(&buildI, "i", false, "")
118 addBuildFlags(cmdBuild)
119 addBuildFlags(cmdInstall)
122 // Flags set by multiple commands.
123 var buildA bool // -a flag
124 var buildN bool // -n flag
125 var buildP = runtime.NumCPU() // -p flag
126 var buildV bool // -v flag
127 var buildX bool // -x flag
128 var buildI bool // -i flag
129 var buildO = cmdBuild.Flag.String("o", "", "output file")
130 var buildWork bool // -work flag
131 var buildGcflags []string // -gcflags flag
132 var buildLdflags []string // -ldflags flag
133 var buildGccgoflags []string // -gccgoflags flag
134 var buildRace bool // -race flag
135 var buildToolExec []string // -toolexec flag
137 var buildContext = build.Default
138 var buildToolchain toolchain = noToolchain{}
140 // buildCompiler implements flag.Var.
141 // It implements Set by updating both
142 // buildToolchain and buildContext.Compiler.
143 type buildCompiler struct{}
145 func (c buildCompiler) Set(value string) error {
148 buildToolchain = gcToolchain{}
150 buildToolchain = gccgoToolchain{}
152 return fmt.Errorf("unknown compiler %q", value)
154 buildContext.Compiler = value
158 func (c buildCompiler) String() string {
159 return buildContext.Compiler
163 switch build.Default.Compiler {
165 buildToolchain = gcToolchain{}
167 buildToolchain = gccgoToolchain{}
171 // addBuildFlags adds the flags common to the build, clean, get,
172 // install, list, run, and test commands.
173 func addBuildFlags(cmd *Command) {
174 // NOTE: If you add flags here, also add them to testflag.go.
175 cmd.Flag.BoolVar(&buildA, "a", false, "")
176 cmd.Flag.BoolVar(&buildN, "n", false, "")
177 cmd.Flag.IntVar(&buildP, "p", buildP, "")
178 cmd.Flag.StringVar(&buildContext.InstallSuffix, "installsuffix", "", "")
179 cmd.Flag.BoolVar(&buildV, "v", false, "")
180 cmd.Flag.BoolVar(&buildX, "x", false, "")
181 cmd.Flag.BoolVar(&buildWork, "work", false, "")
182 cmd.Flag.Var((*stringsFlag)(&buildGcflags), "gcflags", "")
183 cmd.Flag.Var((*stringsFlag)(&buildLdflags), "ldflags", "")
184 cmd.Flag.Var((*stringsFlag)(&buildGccgoflags), "gccgoflags", "")
185 cmd.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
186 cmd.Flag.Var(buildCompiler{}, "compiler", "")
187 cmd.Flag.BoolVar(&buildRace, "race", false, "")
188 cmd.Flag.Var((*stringsFlag)(&buildToolExec), "toolexec", "")
191 func addBuildFlagsNX(cmd *Command) {
192 cmd.Flag.BoolVar(&buildN, "n", false, "")
193 cmd.Flag.BoolVar(&buildX, "x", false, "")
196 func isSpaceByte(c byte) bool {
197 return c == ' ' || c == '\t' || c == '\n' || c == '\r'
200 // fileExtSplit expects a filename and returns the name
201 // and ext (without the dot). If the file has no
202 // extension, ext will be empty.
203 func fileExtSplit(file string) (name, ext string) {
204 dotExt := filepath.Ext(file)
205 name = file[:len(file)-len(dotExt)]
212 type stringsFlag []string
214 func (v *stringsFlag) Set(s string) error {
216 *v, err = splitQuotedFields(s)
223 func splitQuotedFields(s string) ([]string, error) {
224 // Split fields allowing '' or "" around elements.
225 // Quotes further inside the string do not count.
228 for len(s) > 0 && isSpaceByte(s[0]) {
234 // Accepted quoted string. No unescaping inside.
235 if s[0] == '"' || s[0] == '\'' {
239 for i < len(s) && s[i] != quote {
243 return nil, fmt.Errorf("unterminated %c string", quote)
250 for i < len(s) && !isSpaceByte(s[i]) {
259 func (v *stringsFlag) String() string {
260 return "<stringsFlag>"
263 func runBuild(cmd *Command, args []string) {
268 pkgs := packagesForBuild(args)
270 if len(pkgs) == 1 && pkgs[0].Name == "main" && *buildO == "" {
271 _, *buildO = path.Split(pkgs[0].ImportPath)
275 // sanity check some often mis-used options
276 switch buildContext.Compiler {
278 if len(buildGcflags) != 0 {
279 fmt.Println("go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags")
281 if len(buildLdflags) != 0 {
282 fmt.Println("go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags")
285 if len(buildGccgoflags) != 0 {
286 fmt.Println("go build: when using gc toolchain, please pass compile flags using -gcflags, and linker flags using -ldflags")
292 depMode = modeInstall
297 fatalf("go build: cannot use -o with multiple packages")
298 } else if len(pkgs) == 0 {
299 fatalf("no packages to build")
302 p.target = "" // must build - not up to date
303 a := b.action(modeInstall, depMode, p)
310 for _, p := range packages(args) {
311 a.deps = append(a.deps, b.action(modeBuild, depMode, p))
316 var cmdInstall = &Command{
317 UsageLine: "install [build flags] [packages]",
318 Short: "compile and install packages and dependencies",
320 Install compiles and installs the packages named by the import paths,
321 along with their dependencies.
323 For more about the build flags, see 'go help build'.
324 For more about specifying packages, see 'go help packages'.
326 See also: go build, go get, go clean.
330 func runInstall(cmd *Command, args []string) {
332 pkgs := packagesForBuild(args)
334 for _, p := range pkgs {
335 if p.Target == "" && (!p.Standard || p.ImportPath != "unsafe") {
337 errorf("go install: no install location for .go files listed on command line (GOBIN not set)")
338 } else if p.ConflictDir != "" {
339 errorf("go install: no install location for %s: hidden by %s", p.Dir, p.ConflictDir)
341 errorf("go install: no install location for directory %s outside GOPATH", p.Dir)
350 for _, p := range pkgs {
351 a.deps = append(a.deps, b.action(modeInstall, modeInstall, p))
356 // Global build parameters (used during package load)
365 goarch = buildContext.GOARCH
366 goos = buildContext.GOOS
367 if goos == "windows" {
371 archChar, err = build.ArchChar(goarch)
373 if _, isgc := buildToolchain.(gcToolchain); isgc {
376 // archChar is only required for gcToolchain, if we're using
377 // another toolchain leave it blank.
382 // A builder holds global state about a build.
383 // It does not hold per-package state, because we
384 // build packages in parallel, and the builder is shared.
385 type builder struct {
386 work string // the temporary work directory (ends in filepath.Separator)
387 actionCache map[cacheKey]*action // a cache of already-constructed actions
388 mkdirCache map[string]bool // a cache of created directories
389 print func(args ...interface{}) (int, error)
392 scriptDir string // current directory in printed script
399 // An action represents a single action in the action graph.
401 p *Package // the package this action works on
402 deps []*action // actions that must happen before this one
403 triggers []*action // inverse of deps
404 cgo *action // action for cgo binary if needed
405 args []string // additional args for runProgram
406 testOutput *bytes.Buffer // test output buffer
408 f func(*builder, *action) error // the action itself (nil = no-op)
409 ignoreFail bool // whether to run f even if dependencies fail
411 // Generated files, directories.
412 link bool // target is executable, not just package
413 pkgdir string // the -I or -L argument to use when importing this package
414 objdir string // directory for intermediate objects
415 objpkg string // the intermediate package .a file created during the action
416 target string // goal of the action: the created package or executable
419 pending int // number of deps yet to complete
420 priority int // relative execution priority
421 failed bool // whether the action failed
424 // cacheKey is the key for the action cache.
425 type cacheKey struct {
430 // buildMode specifies the build mode:
431 // are we just building things or also installing the results?
435 modeBuild buildMode = iota
440 goroot = filepath.Clean(runtime.GOROOT())
441 gobin = os.Getenv("GOBIN")
442 gorootBin = filepath.Join(goroot, "bin")
443 gorootPkg = filepath.Join(goroot, "pkg")
444 gorootSrc = filepath.Join(goroot, "src")
447 func (b *builder) init() {
449 b.print = func(a ...interface{}) (int, error) {
450 return fmt.Fprint(os.Stderr, a...)
452 b.actionCache = make(map[cacheKey]*action)
453 b.mkdirCache = make(map[string]bool)
458 b.work, err = ioutil.TempDir("", "go-build")
462 if buildX || buildWork {
463 fmt.Fprintf(os.Stderr, "WORK=%s\n", b.work)
467 atexit(func() { os.RemoveAll(workdir) })
472 // goFilesPackage creates a package for building a collection of Go files
473 // (typically named on the command line). The target is named p.a for
474 // package p or named after the first Go file for package main.
475 func goFilesPackage(gofiles []string) *Package {
476 // TODO: Remove this restriction.
477 for _, f := range gofiles {
478 if !strings.HasSuffix(f, ".go") {
479 fatalf("named files must be .go files")
485 ctxt.UseAllFiles = true
487 // Synthesize fake "directory" that only shows the named files,
488 // to make it look like this is a standard package or
489 // command directory. So that local imports resolve
490 // consistently, the files must all be in the same directory.
491 var dirent []os.FileInfo
493 for _, file := range gofiles {
494 fi, err := os.Stat(file)
499 fatalf("%s is a directory, should be a Go file", file)
501 dir1, _ := filepath.Split(file)
504 } else if dir != dir1 {
505 fatalf("named files must all be in one directory; have %s and %s", dir, dir1)
507 dirent = append(dirent, fi)
509 ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil }
515 dir, err = filepath.Abs(dir)
520 bp, err := ctxt.ImportDir(dir, 0)
524 pkg.load(&stk, bp, err)
525 pkg.localPrefix = dirToImportPath(dir)
526 pkg.ImportPath = "command-line-arguments"
529 if pkg.Name == "main" {
530 _, elem := filepath.Split(gofiles[0])
531 exe := elem[:len(elem)-len(".go")] + exeSuffix
536 pkg.target = filepath.Join(gobin, exe)
540 *buildO = pkg.Name + ".a"
543 pkg.Target = pkg.target
550 // action returns the action for applying the given operation (mode) to the package.
551 // depMode is the action to use when building dependencies.
552 func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action {
553 key := cacheKey{mode, p}
554 a := b.actionCache[key]
559 a = &action{p: p, pkgdir: p.build.PkgRoot}
560 if p.pkgdir != "" { // overrides p.t
564 b.actionCache[key] = a
566 for _, p1 := range p.imports {
567 a.deps = append(a.deps, b.action(depMode, depMode, p1))
570 // If we are not doing a cross-build, then record the binary we'll
571 // generate for cgo as a dependency of the build of any package
572 // using cgo, to make sure we do not overwrite the binary while
573 // a package is using it. If this is a cross-build, then the cgo we
574 // are writing is not the cgo we need to use.
575 if goos == runtime.GOOS && goarch == runtime.GOARCH && !buildRace {
576 if len(p.CgoFiles) > 0 || p.Standard && p.ImportPath == "runtime/cgo" {
578 p1 := loadPackage("cmd/cgo", &stk)
580 fatalf("load cmd/cgo: %v", p1.Error)
582 a.cgo = b.action(depMode, depMode, p1)
583 a.deps = append(a.deps, a.cgo)
588 switch p.ImportPath {
589 case "builtin", "unsafe":
590 // Fake packages - nothing to build.
593 // gccgo standard library is "fake" too.
594 if _, ok := buildToolchain.(gccgoToolchain); ok {
595 // the target name is needed for cgo.
601 if !p.Stale && p.target != "" {
602 // p.Stale==false implies that p.target is up-to-date.
603 // Record target name for use by actions depending on this one.
608 if p.local && p.target == "" {
609 // Imported via local path. No permanent target.
616 a.objdir = filepath.Join(work, a.p.ImportPath, "_obj") + string(filepath.Separator)
617 a.objpkg = buildToolchain.pkgpath(work, a.p)
618 a.link = p.Name == "main"
622 a.f = (*builder).install
623 a.deps = []*action{b.action(modeBuild, depMode, p)}
624 a.target = a.p.target
626 a.f = (*builder).build
629 // An executable file. (This is the name of a temporary file.)
630 // Because we run the temporary file in 'go run' and 'go test',
631 // the name will show up in ps listings. If the caller has specified
632 // a name, use that instead of a.out. The binary is generated
633 // in an otherwise empty subdirectory named exe to avoid
634 // naming conflicts. The only possible conflict is if we were
635 // to create a top-level package named exe.
640 a.target = a.objdir + filepath.Join("exe", name) + exeSuffix
647 // actionList returns the list of actions in the dag rooted at root
648 // as visited in a depth-first post-order traversal.
649 func actionList(root *action) []*action {
650 seen := map[*action]bool{}
652 var walk func(*action)
653 walk = func(a *action) {
658 for _, a1 := range a.deps {
667 // do runs the action graph rooted at root.
668 func (b *builder) do(root *action) {
669 // Build list of all actions, assigning depth-first post-order priority.
670 // The original implementation here was a true queue
671 // (using a channel) but it had the effect of getting
672 // distracted by low-level leaf actions to the detriment
673 // of completing higher-level actions. The order of
674 // work does not matter much to overall execution time,
675 // but when running "go test std" it is nice to see each test
676 // results as soon as possible. The priorities assigned
677 // ensure that, all else being equal, the execution prefers
678 // to do what it would have done first in a simple depth-first
679 // dependency order traversal.
680 all := actionList(root)
681 for i, a := range all {
685 b.readySema = make(chan bool, len(all))
687 // Initialize per-action execution state.
688 for _, a := range all {
689 for _, a1 := range a.deps {
690 a1.triggers = append(a1.triggers, a)
692 a.pending = len(a.deps)
699 // Handle runs a single action and takes care of triggering
700 // any actions that are runnable as a result.
701 handle := func(a *action) {
703 if a.f != nil && (!a.failed || a.ignoreFail) {
707 // The actions run in parallel but all the updates to the
708 // shared work state are serialized through b.exec.
710 defer b.exec.Unlock()
713 if err == errPrintedOutput {
721 for _, a0 := range a.triggers {
725 if a0.pending--; a0.pending == 0 {
736 var wg sync.WaitGroup
738 // Kick off goroutines according to parallelism.
739 // If we are using the -n flag (just printing commands)
740 // drop the parallelism to 1, both to make the output
741 // deterministic and because there is no real work anyway.
746 for i := 0; i < par; i++ {
752 case _, ok := <-b.readySema:
756 // Receiving a value from b.readySema entitles
757 // us to take from the ready queue.
773 // hasString reports whether s appears in the list of strings.
774 func hasString(strings []string, s string) bool {
775 for _, t := range strings {
783 // build is the action for building a single package or command.
784 func (b *builder) build(a *action) (err error) {
785 // Return an error if the package has CXX files but it's not using
786 // cgo nor SWIG, since the CXX files can only be processed by cgo
787 // and SWIG (it's possible to have packages with C files without
788 // using cgo, they will get compiled with the plan9 C compiler and
789 // linked with the rest of the package).
790 if len(a.p.CXXFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
791 return fmt.Errorf("can't build package %s because it contains C++ files (%s) but it's not using cgo nor SWIG",
792 a.p.ImportPath, strings.Join(a.p.CXXFiles, ","))
794 // Same as above for Objective-C files
795 if len(a.p.MFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
796 return fmt.Errorf("can't build package %s because it contains Objective-C files (%s) but it's not using cgo nor SWIG",
797 a.p.ImportPath, strings.Join(a.p.MFiles, ","))
800 if err != nil && err != errPrintedOutput {
801 err = fmt.Errorf("go build %s: %v", a.p.ImportPath, err)
805 // In -n mode, print a banner between packages.
806 // The banner is five lines so that when changes to
807 // different sections of the bootstrap script have to
808 // be merged, the banners give patch something
809 // to use to find its context.
810 fmt.Printf("\n#\n# %s\n#\n\n", a.p.ImportPath)
814 fmt.Fprintf(os.Stderr, "%s\n", a.p.ImportPath)
817 if a.p.Standard && a.p.ImportPath == "runtime" && buildContext.Compiler == "gc" &&
818 (!hasString(a.p.GoFiles, "zgoos_"+buildContext.GOOS+".go") ||
819 !hasString(a.p.GoFiles, "zgoarch_"+buildContext.GOARCH+".go")) {
820 return fmt.Errorf("%s/%s must be bootstrapped using make%v", buildContext.GOOS, buildContext.GOARCH, defaultSuffix())
823 // Make build directory.
825 if err := b.mkdir(obj); err != nil {
829 // make target directory
830 dir, _ := filepath.Split(a.target)
832 if err := b.mkdir(dir); err != nil {
837 var gofiles, cfiles, sfiles, objects, cgoObjects, pcCFLAGS, pcLDFLAGS []string
839 gofiles = append(gofiles, a.p.GoFiles...)
840 cfiles = append(cfiles, a.p.CFiles...)
841 sfiles = append(sfiles, a.p.SFiles...)
843 if a.p.usesCgo() || a.p.usesSwig() {
844 if pcCFLAGS, pcLDFLAGS, err = b.getPkgConfigFlags(a.p); err != nil {
850 // In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
851 // There is one exception: runtime/cgo's job is to bridge the
852 // cgo and non-cgo worlds, so it necessarily has files in both.
853 // In that case gcc only gets the gcc_* files.
854 var gccfiles []string
855 if a.p.Standard && a.p.ImportPath == "runtime/cgo" {
856 filter := func(files, nongcc, gcc []string) ([]string, []string) {
857 for _, f := range files {
858 if strings.HasPrefix(f, "gcc_") {
861 nongcc = append(nongcc, f)
866 cfiles, gccfiles = filter(cfiles, cfiles[:0], gccfiles)
867 sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles)
869 gccfiles = append(cfiles, sfiles...)
874 cgoExe := tool("cgo")
875 if a.cgo != nil && a.cgo.target != "" {
876 cgoExe = a.cgo.target
878 outGo, outObj, err := b.cgo(a.p, cgoExe, obj, pcCFLAGS, pcLDFLAGS, gccfiles, a.p.CXXFiles, a.p.MFiles)
882 cgoObjects = append(cgoObjects, outObj...)
883 gofiles = append(gofiles, outGo...)
888 // In a package using SWIG, any .c or .s files are
889 // compiled with gcc.
890 gccfiles := append(cfiles, sfiles...)
891 cxxfiles, mfiles := a.p.CXXFiles, a.p.MFiles
895 // Don't build c/c++ files twice if cgo is enabled (mainly for pkg-config).
902 outGo, outObj, err := b.swig(a.p, obj, pcCFLAGS, gccfiles, cxxfiles, mfiles)
906 cgoObjects = append(cgoObjects, outObj...)
907 gofiles = append(gofiles, outGo...)
910 if len(gofiles) == 0 {
911 return &build.NoGoError{Dir: a.p.Dir}
914 // If we're doing coverage, preprocess the .go files and put them in the work directory
915 if a.p.coverMode != "" {
916 for i, file := range gofiles {
917 var sourceFile string
920 if strings.HasSuffix(file, ".cgo1.go") {
921 // cgo files have absolute paths
922 base := filepath.Base(file)
924 coverFile = filepath.Join(obj, base)
925 key = strings.TrimSuffix(base, ".cgo1.go") + ".go"
927 sourceFile = filepath.Join(a.p.Dir, file)
928 coverFile = filepath.Join(obj, file)
931 cover := a.p.coverVars[key]
932 if cover == nil || isTestFile(file) {
933 // Not covering this file.
936 if err := b.cover(a, coverFile, sourceFile, 0666, cover.Var); err != nil {
939 gofiles[i] = coverFile
943 // Prepare Go import path list.
944 inc := b.includeArgs("-I", a.deps)
947 ofile, out, err := buildToolchain.gc(b, a.p, a.objpkg, obj, len(sfiles) > 0, inc, gofiles)
949 b.showOutput(a.p.Dir, a.p.ImportPath, b.processOutput(out))
951 return errPrintedOutput
957 if ofile != a.objpkg {
958 objects = append(objects, ofile)
961 // Copy .h files named for goos or goarch or goos_goarch
962 // to names using GOOS and GOARCH.
963 // For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
964 _goos_goarch := "_" + goos + "_" + goarch
966 _goarch := "_" + goarch
967 for _, file := range a.p.HFiles {
968 name, ext := fileExtSplit(file)
970 case strings.HasSuffix(name, _goos_goarch):
971 targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext
972 if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
975 case strings.HasSuffix(name, _goarch):
976 targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext
977 if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
980 case strings.HasSuffix(name, _goos):
981 targ := file[:len(name)-len(_goos)] + "_GOOS." + ext
982 if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
989 if _, ok := buildToolchain.(gccgoToolchain); ok {
993 for _, file := range cfiles {
994 out := file[:len(file)-len(".c")] + "." + objExt
995 if err := buildToolchain.cc(b, a.p, obj, obj+out, file); err != nil {
998 objects = append(objects, out)
1001 // Assemble .s files.
1002 for _, file := range sfiles {
1003 out := file[:len(file)-len(".s")] + "." + objExt
1004 if err := buildToolchain.asm(b, a.p, obj, obj+out, file); err != nil {
1007 objects = append(objects, out)
1010 // NOTE(rsc): On Windows, it is critically important that the
1011 // gcc-compiled objects (cgoObjects) be listed after the ordinary
1012 // objects in the archive. I do not know why this is.
1013 // http://golang.org/issue/2601
1014 objects = append(objects, cgoObjects...)
1016 // Add system object files.
1017 for _, syso := range a.p.SysoFiles {
1018 objects = append(objects, filepath.Join(a.p.Dir, syso))
1021 // Pack into archive in obj directory.
1022 // If the Go compiler wrote an archive, we only need to add the
1023 // object files for non-Go sources to the archive.
1024 // If the Go compiler wrote an archive and the package is entirely
1025 // Go sources, there is no pack to execute at all.
1026 if len(objects) > 0 {
1027 if err := buildToolchain.pack(b, a.p, obj, a.objpkg, objects); err != nil {
1034 // The compiler only cares about direct imports, but the
1035 // linker needs the whole dependency tree.
1036 all := actionList(a)
1037 all = all[:len(all)-1] // drop a
1038 if err := buildToolchain.ld(b, a.p, a.target, all, a.objpkg, objects); err != nil {
1046 // Calls pkg-config if needed and returns the cflags/ldflags needed to build the package.
1047 func (b *builder) getPkgConfigFlags(p *Package) (cflags, ldflags []string, err error) {
1048 if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
1050 out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--cflags", pkgs)
1052 b.showOutput(p.Dir, "pkg-config --cflags "+strings.Join(pkgs, " "), string(out))
1053 b.print(err.Error() + "\n")
1054 err = errPrintedOutput
1058 cflags = strings.Fields(string(out))
1060 out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--libs", pkgs)
1062 b.showOutput(p.Dir, "pkg-config --libs "+strings.Join(pkgs, " "), string(out))
1063 b.print(err.Error() + "\n")
1064 err = errPrintedOutput
1068 ldflags = strings.Fields(string(out))
1074 // install is the action for installing a single package or executable.
1075 func (b *builder) install(a *action) (err error) {
1077 if err != nil && err != errPrintedOutput {
1078 err = fmt.Errorf("go install %s: %v", a.p.ImportPath, err)
1082 perm := os.FileMode(0644)
1087 // make target directory
1088 dir, _ := filepath.Split(a.target)
1090 if err := b.mkdir(dir); err != nil {
1095 // remove object dir to keep the amount of
1096 // garbage down in a large build. On an operating system
1097 // with aggressive buffering, cleaning incrementally like
1098 // this keeps the intermediate objects from hitting the disk.
1100 defer os.RemoveAll(a1.objdir)
1101 defer os.Remove(a1.target)
1104 return b.moveOrCopyFile(a, a.target, a1.target, perm)
1107 // includeArgs returns the -I or -L directory list for access
1108 // to the results of the list of actions.
1109 func (b *builder) includeArgs(flag string, all []*action) []string {
1111 incMap := map[string]bool{
1112 b.work: true, // handled later
1114 "": true, // ignore empty strings
1117 // Look in the temporary space for results of test-specific actions.
1118 // This is the $WORK/my/package/_test directory for the
1119 // package being built, so there are few of these.
1120 for _, a1 := range all {
1121 if dir := a1.pkgdir; dir != a1.p.build.PkgRoot && !incMap[dir] {
1123 inc = append(inc, flag, dir)
1127 // Also look in $WORK for any non-test packages that have
1128 // been built but not installed.
1129 inc = append(inc, flag, b.work)
1131 // Finally, look in the installed package directories for each action.
1132 for _, a1 := range all {
1133 if dir := a1.pkgdir; dir == a1.p.build.PkgRoot && !incMap[dir] {
1135 if _, ok := buildToolchain.(gccgoToolchain); ok {
1136 dir = filepath.Join(dir, "gccgo_"+goos+"_"+goarch)
1138 dir = filepath.Join(dir, goos+"_"+goarch)
1139 if buildContext.InstallSuffix != "" {
1140 dir += "_" + buildContext.InstallSuffix
1143 inc = append(inc, flag, dir)
1150 // moveOrCopyFile is like 'mv src dst' or 'cp src dst'.
1151 func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode) error {
1153 b.showcmd("", "mv %s %s", src, dst)
1157 // If we can update the mode and rename to the dst, do it.
1158 // Otherwise fall back to standard copy.
1159 if err := os.Chmod(src, perm); err == nil {
1160 if err := os.Rename(src, dst); err == nil {
1162 b.showcmd("", "mv %s %s", src, dst)
1168 return b.copyFile(a, dst, src, perm)
1171 // copyFile is like 'cp src dst'.
1172 func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode) error {
1173 if buildN || buildX {
1174 b.showcmd("", "cp %s %s", src, dst)
1180 sf, err := os.Open(src)
1186 // Be careful about removing/overwriting dst.
1187 // Do not remove/overwrite if dst exists and is a directory
1188 // or a non-object file.
1189 if fi, err := os.Stat(dst); err == nil {
1191 return fmt.Errorf("build output %q already exists and is a directory", dst)
1194 return fmt.Errorf("build output %q already exists and is not an object file", dst)
1198 // On Windows, remove lingering ~ file from last attempt.
1200 if _, err := os.Stat(dst + "~"); err == nil {
1201 os.Remove(dst + "~")
1206 df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
1207 if err != nil && toolIsWindows {
1208 // Windows does not allow deletion of a binary file
1209 // while it is executing. Try to move it out of the way.
1210 // If the move fails, which is likely, we'll try again the
1211 // next time we do an install of this binary.
1212 if err := os.Rename(dst, dst+"~"); err == nil {
1213 os.Remove(dst + "~")
1215 df, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
1221 _, err = io.Copy(df, sf)
1225 return fmt.Errorf("copying %s to %s: %v", src, dst, err)
1230 // cover runs, in effect,
1231 // go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
1232 func (b *builder) cover(a *action, dst, src string, perm os.FileMode, varName string) error {
1233 return b.run(a.objdir, "cover "+a.p.ImportPath, nil,
1236 "-mode", a.p.coverMode,
1242 var objectMagic = [][]byte{
1243 {'!', '<', 'a', 'r', 'c', 'h', '>', '\n'}, // Package archive
1244 {'\x7F', 'E', 'L', 'F'}, // ELF
1245 {0xFE, 0xED, 0xFA, 0xCE}, // Mach-O big-endian 32-bit
1246 {0xFE, 0xED, 0xFA, 0xCF}, // Mach-O big-endian 64-bit
1247 {0xCE, 0xFA, 0xED, 0xFE}, // Mach-O little-endian 32-bit
1248 {0xCF, 0xFA, 0xED, 0xFE}, // Mach-O little-endian 64-bit
1249 {0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x04, 0x00}, // PE (Windows) as generated by 6l/8l
1250 {0x00, 0x00, 0x01, 0xEB}, // Plan 9 i386
1251 {0x00, 0x00, 0x8a, 0x97}, // Plan 9 amd64
1254 func isObject(s string) bool {
1255 f, err := os.Open(s)
1260 buf := make([]byte, 64)
1262 for _, magic := range objectMagic {
1263 if bytes.HasPrefix(buf, magic) {
1270 // fmtcmd formats a command in the manner of fmt.Sprintf but also:
1272 // If dir is non-empty and the script is not in dir right now,
1273 // fmtcmd inserts "cd dir\n" before the command.
1275 // fmtcmd replaces the value of b.work with $WORK.
1276 // fmtcmd replaces the value of goroot with $GOROOT.
1277 // fmtcmd replaces the value of b.gobin with $GOBIN.
1279 // fmtcmd replaces the name of the current directory with dot (.)
1280 // but only when it is at the beginning of a space-separated token.
1282 func (b *builder) fmtcmd(dir string, format string, args ...interface{}) string {
1283 cmd := fmt.Sprintf(format, args...)
1284 if dir != "" && dir != "/" {
1285 cmd = strings.Replace(" "+cmd, " "+dir, " .", -1)[1:]
1286 if b.scriptDir != dir {
1288 cmd = "cd " + dir + "\n" + cmd
1292 cmd = strings.Replace(cmd, b.work, "$WORK", -1)
1297 // showcmd prints the given command to standard output
1298 // for the implementation of -n or -x.
1299 func (b *builder) showcmd(dir string, format string, args ...interface{}) {
1301 defer b.output.Unlock()
1302 b.print(b.fmtcmd(dir, format, args...) + "\n")
1305 // showOutput prints "# desc" followed by the given output.
1306 // The output is expected to contain references to 'dir', usually
1307 // the source directory for the package that has failed to build.
1308 // showOutput rewrites mentions of dir with a relative path to dir
1309 // when the relative path is shorter. This is usually more pleasant.
1310 // For example, if fmt doesn't compile and we are in src/html,
1315 // ../fmt/print.go:1090: undefined: asdf
1322 // /usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
1325 // showOutput also replaces references to the work directory with $WORK.
1327 func (b *builder) showOutput(dir, desc, out string) {
1328 prefix := "# " + desc
1329 suffix := "\n" + out
1330 if reldir := shortPath(dir); reldir != dir {
1331 suffix = strings.Replace(suffix, " "+dir, " "+reldir, -1)
1332 suffix = strings.Replace(suffix, "\n"+dir, "\n"+reldir, -1)
1334 suffix = strings.Replace(suffix, " "+b.work, " $WORK", -1)
1337 defer b.output.Unlock()
1338 b.print(prefix, suffix)
1341 // shortPath returns an absolute or relative name for path, whatever is shorter.
1342 func shortPath(path string) string {
1343 if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) {
1349 // relPaths returns a copy of paths with absolute paths
1350 // made relative to the current directory if they would be shorter.
1351 func relPaths(paths []string) []string {
1353 pwd, _ := os.Getwd()
1354 for _, p := range paths {
1355 rel, err := filepath.Rel(pwd, p)
1356 if err == nil && len(rel) < len(p) {
1359 out = append(out, p)
1364 // errPrintedOutput is a special error indicating that a command failed
1365 // but that it generated output as well, and that output has already
1366 // been printed, so there's no point showing 'exit status 1' or whatever
1367 // the wait status was. The main executor, builder.do, knows not to
1368 // print this error.
1369 var errPrintedOutput = errors.New("already printed output - no need to show error")
1371 var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.cgo1\.go:[0-9]+\]`)
1372 var cgoTypeSigRe = regexp.MustCompile(`\b_Ctype_\B`)
1374 // run runs the command given by cmdline in the directory dir.
1375 // If the command fails, run prints information about the failure
1376 // and returns a non-nil error.
1377 func (b *builder) run(dir string, desc string, env []string, cmdargs ...interface{}) error {
1378 out, err := b.runOut(dir, desc, env, cmdargs...)
1381 desc = b.fmtcmd(dir, "%s", strings.Join(stringList(cmdargs...), " "))
1383 b.showOutput(dir, desc, b.processOutput(out))
1385 err = errPrintedOutput
1391 // processOutput prepares the output of runOut to be output to the console.
1392 func (b *builder) processOutput(out []byte) string {
1393 if out[len(out)-1] != '\n' {
1394 out = append(out, '\n')
1396 messages := string(out)
1397 // Fix up output referring to cgo-generated code to be more readable.
1398 // Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
1399 // Replace *[100]_Ctype_foo with *[100]C.foo.
1400 // If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
1401 if !buildX && cgoLine.MatchString(messages) {
1402 messages = cgoLine.ReplaceAllString(messages, "")
1403 messages = cgoTypeSigRe.ReplaceAllString(messages, "C.")
1408 // runOut runs the command given by cmdline in the directory dir.
1409 // It returns the command output and any errors that occurred.
1410 func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) {
1411 cmdline := stringList(cmdargs...)
1412 if buildN || buildX {
1413 var envcmdline string
1414 for i := range env {
1415 envcmdline += env[i]
1418 envcmdline += joinUnambiguously(cmdline)
1419 b.showcmd(dir, "%s", envcmdline)
1427 var buf bytes.Buffer
1428 cmd := exec.Command(cmdline[0], cmdline[1:]...)
1432 cmd.Env = mergeEnvLists(env, envForDir(cmd.Dir))
1435 // cmd.Run will fail on Unix if some other process has the binary
1436 // we want to run open for writing. This can happen here because
1437 // we build and install the cgo command and then run it.
1438 // If another command was kicked off while we were writing the
1439 // cgo binary, the child process for that command may be holding
1440 // a reference to the fd, keeping us from running exec.
1442 // But, you might reasonably wonder, how can this happen?
1443 // The cgo fd, like all our fds, is close-on-exec, so that we need
1444 // not worry about other processes inheriting the fd accidentally.
1445 // The answer is that running a command is fork and exec.
1446 // A child forked while the cgo fd is open inherits that fd.
1447 // Until the child has called exec, it holds the fd open and the
1448 // kernel will not let us run cgo. Even if the child were to close
1449 // the fd explicitly, it would still be open from the time of the fork
1450 // until the time of the explicit close, and the race would remain.
1452 // On Unix systems, this results in ETXTBSY, which formats
1453 // as "text file busy". Rather than hard-code specific error cases,
1454 // we just look for that string. If this happens, sleep a little
1455 // and try again. We let this happen three times, with increasing
1456 // sleep lengths: 100+200+400 ms = 0.7 seconds.
1458 // An alternate solution might be to split the cmd.Run into
1459 // separate cmd.Start and cmd.Wait, and then use an RWLock
1460 // to make sure that copyFile only executes when no cmd.Start
1461 // call is in progress. However, cmd.Start (really syscall.forkExec)
1462 // only guarantees that when it returns, the exec is committed to
1463 // happen and succeed. It uses a close-on-exec file descriptor
1464 // itself to determine this, so we know that when cmd.Start returns,
1465 // at least one close-on-exec file descriptor has been closed.
1466 // However, we cannot be sure that all of them have been closed,
1467 // so the program might still encounter ETXTBSY even with such
1468 // an RWLock. The race window would be smaller, perhaps, but not
1469 // guaranteed to be gone.
1471 // Sleeping when we observe the race seems to be the most reliable
1474 // http://golang.org/issue/3001
1476 if err != nil && nbusy < 3 && strings.Contains(err.Error(), "text file busy") {
1477 time.Sleep(100 * time.Millisecond << uint(nbusy))
1482 // err can be something like 'exit status 1'.
1483 // Add information about what program was running.
1484 // Note that if buf.Bytes() is non-empty, the caller usually
1485 // shows buf.Bytes() and does not print err at all, so the
1486 // prefix here does not make most output any more verbose.
1488 err = errors.New(cmdline[0] + ": " + err.Error())
1490 return buf.Bytes(), err
1494 // joinUnambiguously prints the slice, quoting where necessary to make the
1495 // output unambiguous.
1496 // TODO: See issue 5279. The printing of commands needs a complete redo.
1497 func joinUnambiguously(a []string) string {
1498 var buf bytes.Buffer
1499 for i, s := range a {
1503 q := strconv.Quote(s)
1504 if s == "" || strings.Contains(s, " ") || len(q) > len(s)+2 {
1513 // mkdir makes the named directory.
1514 func (b *builder) mkdir(dir string) error {
1516 defer b.exec.Unlock()
1517 // We can be a little aggressive about being
1518 // sure directories exist. Skip repeated calls.
1519 if b.mkdirCache[dir] {
1522 b.mkdirCache[dir] = true
1524 if buildN || buildX {
1525 b.showcmd("", "mkdir -p %s", dir)
1531 if err := os.MkdirAll(dir, 0777); err != nil {
1537 // mkAbs returns an absolute path corresponding to
1538 // evaluating f in the directory dir.
1539 // We always pass absolute paths of source files so that
1540 // the error messages will include the full path to a file
1541 // in need of attention.
1542 func mkAbs(dir, f string) string {
1543 // Leave absolute paths alone.
1544 // Also, during -n mode we use the pseudo-directory $WORK
1545 // instead of creating an actual work directory that won't be used.
1546 // Leave paths beginning with $WORK alone too.
1547 if filepath.IsAbs(f) || strings.HasPrefix(f, "$WORK") {
1550 return filepath.Join(dir, f)
1553 type toolchain interface {
1554 // gc runs the compiler in a specific directory on a set of files
1555 // and returns the name of the generated output file.
1556 // The compiler runs in the directory dir.
1557 gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error)
1558 // cc runs the toolchain's C compiler in a directory on a C file
1559 // to produce an output file.
1560 cc(b *builder, p *Package, objdir, ofile, cfile string) error
1561 // asm runs the assembler in a specific directory on a specific file
1562 // to generate the named output file.
1563 asm(b *builder, p *Package, obj, ofile, sfile string) error
1564 // pkgpath builds an appropriate path for a temporary package file.
1565 pkgpath(basedir string, p *Package) string
1566 // pack runs the archive packer in a specific directory to create
1567 // an archive from a set of object files.
1568 // typically it is run in the object directory.
1569 pack(b *builder, p *Package, objDir, afile string, ofiles []string) error
1570 // ld runs the linker to create a package starting at mainpkg.
1571 ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error
1577 type noToolchain struct{}
1579 func noCompiler() error {
1580 log.Fatalf("unknown compiler %q", buildContext.Compiler)
1584 func (noToolchain) compiler() string {
1589 func (noToolchain) linker() string {
1594 func (noToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error) {
1595 return "", nil, noCompiler()
1598 func (noToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
1602 func (noToolchain) pkgpath(basedir string, p *Package) string {
1607 func (noToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
1611 func (noToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
1615 func (noToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
1619 // The Go toolchain.
1620 type gcToolchain struct{}
1622 func (gcToolchain) compiler() string {
1623 return tool(archChar + "g")
1626 func (gcToolchain) linker() string {
1627 return tool(archChar + "l")
1630 func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
1634 out := "_go_." + archChar
1638 gcargs := []string{"-p", p.ImportPath}
1639 if p.Standard && p.ImportPath == "runtime" {
1640 // runtime compiles with a special 6g flag to emit
1641 // additional reflect type data.
1642 gcargs = append(gcargs, "-+")
1645 // If we're giving the compiler the entire package (no C etc files), tell it that,
1646 // so that it can give good error messages about forward declarations.
1647 // Exceptions: a few standard packages have forward declarations for
1648 // pieces supplied behind-the-scenes by package runtime.
1649 extFiles := len(p.CgoFiles) + len(p.CFiles) + len(p.CXXFiles) + len(p.MFiles) + len(p.SFiles) + len(p.SysoFiles) + len(p.SwigFiles) + len(p.SwigCXXFiles)
1651 switch p.ImportPath {
1652 case "bytes", "net", "os", "runtime/pprof", "sync", "time":
1657 gcargs = append(gcargs, "-complete")
1659 if buildContext.InstallSuffix != "" {
1660 gcargs = append(gcargs, "-installsuffix", buildContext.InstallSuffix)
1663 args := stringList(buildToolExec, tool(archChar+"g"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs)
1664 if ofile == archive {
1665 args = append(args, "-pack")
1668 args = append(args, "-asmhdr", obj+"go_asm.h")
1670 for _, f := range gofiles {
1671 args = append(args, mkAbs(p.Dir, f))
1674 output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
1675 return ofile, output, err
1678 func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
1679 // Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
1680 inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
1681 sfile = mkAbs(p.Dir, sfile)
1682 return b.run(p.Dir, p.ImportPath, nil, stringList(buildToolExec, tool(archChar+"a"), "-trimpath", b.work, "-I", obj, "-I", inc, "-o", ofile, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, sfile))
1685 func (gcToolchain) pkgpath(basedir string, p *Package) string {
1686 end := filepath.FromSlash(p.ImportPath + ".a")
1687 return filepath.Join(basedir, end)
1690 func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
1691 var absOfiles []string
1692 for _, f := range ofiles {
1693 absOfiles = append(absOfiles, mkAbs(objDir, f))
1696 absAfile := mkAbs(objDir, afile)
1698 if _, err := os.Stat(absAfile); err == nil {
1703 cmdline := stringList("pack", cmd, absAfile, absOfiles)
1706 if buildN || buildX {
1707 b.showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline))
1712 if err := packInternal(b, absAfile, absOfiles); err != nil {
1713 b.showOutput(p.Dir, p.ImportPath, err.Error()+"\n")
1714 return errPrintedOutput
1719 // Need actual pack.
1720 cmdline[0] = tool("pack")
1721 return b.run(p.Dir, p.ImportPath, nil, buildToolExec, cmdline)
1724 func packInternal(b *builder, afile string, ofiles []string) error {
1725 dst, err := os.OpenFile(afile, os.O_WRONLY|os.O_APPEND, 0)
1729 defer dst.Close() // only for error returns or panics
1730 w := bufio.NewWriter(dst)
1732 for _, ofile := range ofiles {
1733 src, err := os.Open(ofile)
1737 fi, err := src.Stat()
1742 // Note: Not using %-16.16s format because we care
1743 // about bytes, not runes.
1748 name += strings.Repeat(" ", 16-len(name))
1751 fmt.Fprintf(w, "%s%-12d%-6d%-6d%-8o%-10d`\n",
1752 name, 0, 0, 0, 0644, size)
1753 n, err := io.Copy(w, src)
1755 if err == nil && n < size {
1756 err = io.ErrUnexpectedEOF
1757 } else if err == nil && n > size {
1758 err = fmt.Errorf("file larger than size reported by stat")
1761 return fmt.Errorf("copying %s to %s: %v", ofile, afile, err)
1768 if err := w.Flush(); err != nil {
1774 func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
1775 importArgs := b.includeArgs("-L", allactions)
1776 cxx := len(p.CXXFiles) > 0
1777 for _, a := range allactions {
1778 if a.p != nil && len(a.p.CXXFiles) > 0 {
1782 var ldflags []string
1783 if buildContext.InstallSuffix != "" {
1784 ldflags = append(ldflags, "-installsuffix", buildContext.InstallSuffix)
1787 ldflags = append(ldflags, "-w")
1790 // If the user has not specified the -extld option, then specify the
1791 // appropriate linker. In case of C++ code, use the compiler named
1792 // by the CXX environment variable or defaultCXX if CXX is not set.
1793 // Else, use the CC environment variable and defaultCC as fallback.
1795 for _, f := range ldflags {
1796 if f == "-extld" || strings.HasPrefix(f, "-extld=") {
1802 var compiler []string
1804 compiler = envList("CXX", defaultCXX)
1806 compiler = envList("CC", defaultCC)
1808 ldflags = append(ldflags, "-extld="+compiler[0])
1809 if len(compiler) > 1 {
1811 add := strings.Join(compiler[1:], " ")
1812 for i, f := range ldflags {
1813 if f == "-extldflags" && i+1 < len(ldflags) {
1814 ldflags[i+1] = add + " " + ldflags[i+1]
1817 } else if strings.HasPrefix(f, "-extldflags=") {
1818 ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
1824 ldflags = append(ldflags, "-extldflags="+add)
1828 ldflags = append(ldflags, buildLdflags...)
1829 return b.run(".", p.ImportPath, nil, stringList(buildToolExec, tool(archChar+"l"), "-o", out, importArgs, ldflags, mainpkg))
1832 func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
1833 return fmt.Errorf("%s: C source files not supported without cgo", mkAbs(p.Dir, cfile))
1836 // The Gccgo toolchain.
1837 type gccgoToolchain struct{}
1839 var gccgoName, gccgoBin string
1842 gccgoName = os.Getenv("GCCGO")
1843 if gccgoName == "" {
1846 gccgoBin, _ = exec.LookPath(gccgoName)
1849 func (gccgoToolchain) compiler() string {
1853 func (gccgoToolchain) linker() string {
1857 func (gccgoToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
1860 gcargs := []string{"-g"}
1861 gcargs = append(gcargs, b.gccArchArgs()...)
1862 if pkgpath := gccgoPkgpath(p); pkgpath != "" {
1863 gcargs = append(gcargs, "-fgo-pkgpath="+pkgpath)
1865 if p.localPrefix != "" {
1866 gcargs = append(gcargs, "-fgo-relative-import-path="+p.localPrefix)
1868 args := stringList(gccgoName, importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags)
1869 for _, f := range gofiles {
1870 args = append(args, mkAbs(p.Dir, f))
1873 output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
1874 return ofile, output, err
1877 func (gccgoToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
1878 sfile = mkAbs(p.Dir, sfile)
1879 defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
1880 if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
1881 defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
1883 defs = append(defs, b.gccArchArgs()...)
1884 return b.run(p.Dir, p.ImportPath, nil, gccgoName, "-I", obj, "-o", ofile, defs, sfile)
1887 func (gccgoToolchain) pkgpath(basedir string, p *Package) string {
1888 end := filepath.FromSlash(p.ImportPath + ".a")
1889 afile := filepath.Join(basedir, end)
1890 // add "lib" to the final element
1891 return filepath.Join(filepath.Dir(afile), "lib"+filepath.Base(afile))
1894 func (gccgoToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
1895 var absOfiles []string
1896 for _, f := range ofiles {
1897 absOfiles = append(absOfiles, mkAbs(objDir, f))
1899 return b.run(p.Dir, p.ImportPath, nil, "ar", "cru", mkAbs(objDir, afile), absOfiles)
1902 func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
1903 // gccgo needs explicit linking with all package dependencies,
1904 // and all LDFLAGS from cgo dependencies.
1905 afiles := []string{}
1906 ldflags := b.gccArchArgs()
1907 cgoldflags := []string{}
1909 cxx := len(p.CXXFiles) > 0
1910 objc := len(p.MFiles) > 0
1912 // For a given package import path:
1913 // 1) prefer a test package (created by (*builder).test) to a non-test package
1914 // 2) prefer the output of an install action to the output of a build action
1915 // because the install action will delete the output of the build
1917 // Iterating over the list backwards (reverse dependency order) ensures that we
1918 // always see an install before a build.
1919 importPathsSeen := make(map[string]bool)
1920 for i := len(allactions) - 1; i >= 0; i-- {
1922 if a.p.fake && !importPathsSeen[a.p.ImportPath] {
1923 importPathsSeen[a.p.ImportPath] = true
1924 afiles = append(afiles, a.target)
1927 for i := len(allactions) - 1; i >= 0; i-- {
1929 if !a.p.Standard && !importPathsSeen[a.p.ImportPath] {
1930 importPathsSeen[a.p.ImportPath] = true
1931 afiles = append(afiles, a.target)
1935 for _, a := range allactions {
1936 cgoldflags = append(cgoldflags, a.p.CgoLDFLAGS...)
1937 if len(a.p.CgoFiles) > 0 {
1943 if len(a.p.CXXFiles) > 0 {
1946 if len(a.p.MFiles) > 0 {
1950 ldflags = append(ldflags, afiles...)
1951 ldflags = append(ldflags, cgoldflags...)
1952 ldflags = append(ldflags, envList("CGO_LDFLAGS", "")...)
1953 ldflags = append(ldflags, p.CgoLDFLAGS...)
1954 if usesCgo && goos == "linux" {
1955 ldflags = append(ldflags, "-Wl,-E")
1958 ldflags = append(ldflags, "-lstdc++")
1961 ldflags = append(ldflags, "-lobjc")
1963 return b.run(".", p.ImportPath, nil, gccgoName, "-o", out, ofiles, "-Wl,-(", ldflags, "-Wl,-)", buildGccgoflags)
1966 func (gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
1967 inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
1968 cfile = mkAbs(p.Dir, cfile)
1969 defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
1970 defs = append(defs, b.gccArchArgs()...)
1971 if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
1972 defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
1974 return b.run(p.Dir, p.ImportPath, nil, envList("CC", defaultCC), "-Wall", "-g",
1975 "-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile)
1978 func gccgoPkgpath(p *Package) string {
1979 if p.build.IsCommand() && !p.forceLibrary {
1985 func gccgoCleanPkgpath(p *Package) string {
1986 clean := func(r rune) rune {
1988 case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
1989 '0' <= r && r <= '9':
1994 return strings.Map(clean, gccgoPkgpath(p))
1997 // libgcc returns the filename for libgcc, as determined by invoking gcc with
1998 // the -print-libgcc-file-name option.
1999 func (b *builder) libgcc(p *Package) (string, error) {
2000 var buf bytes.Buffer
2002 gccCmd := b.gccCmd(p.Dir)
2006 // In -n mode we temporarily swap out the builder's
2007 // print function to capture the command-line. This
2008 // let's us assign it to $LIBGCC and produce a valid
2009 // buildscript for cgo packages.
2010 b.print = func(a ...interface{}) (int, error) {
2011 return fmt.Fprint(&buf, a...)
2014 f, err := b.runOut(p.Dir, p.ImportPath, nil, gccCmd, "-print-libgcc-file-name")
2016 return "", fmt.Errorf("gcc -print-libgcc-file-name: %v (%s)", err, f)
2019 s := fmt.Sprintf("LIBGCC=$(%s)\n", buf.Next(buf.Len()-1))
2022 return "$LIBGCC", nil
2025 // The compiler might not be able to find libgcc, and in that case,
2026 // it will simply return "libgcc.a", which is of no use to us.
2027 if !filepath.IsAbs(string(f)) {
2031 return strings.Trim(string(f), "\r\n"), nil
2034 // gcc runs the gcc C compiler to create an object from a single C file.
2035 func (b *builder) gcc(p *Package, out string, flags []string, cfile string) error {
2036 return b.ccompile(p, out, flags, cfile, b.gccCmd(p.Dir))
2039 // gxx runs the g++ C++ compiler to create an object from a single C++ file.
2040 func (b *builder) gxx(p *Package, out string, flags []string, cxxfile string) error {
2041 return b.ccompile(p, out, flags, cxxfile, b.gxxCmd(p.Dir))
2044 // ccompile runs the given C or C++ compiler and creates an object from a single source file.
2045 func (b *builder) ccompile(p *Package, out string, flags []string, file string, compiler []string) error {
2046 file = mkAbs(p.Dir, file)
2047 return b.run(p.Dir, p.ImportPath, nil, compiler, flags, "-o", out, "-c", file)
2050 // gccld runs the gcc linker to create an executable from a set of object files.
2051 func (b *builder) gccld(p *Package, out string, flags []string, obj []string) error {
2053 if len(p.CXXFiles) > 0 {
2054 cmd = b.gxxCmd(p.Dir)
2056 cmd = b.gccCmd(p.Dir)
2058 return b.run(p.Dir, p.ImportPath, nil, cmd, "-o", out, obj, flags)
2061 // gccCmd returns a gcc command line prefix
2062 // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
2063 func (b *builder) gccCmd(objdir string) []string {
2064 return b.ccompilerCmd("CC", defaultCC, objdir)
2067 // gxxCmd returns a g++ command line prefix
2068 // defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
2069 func (b *builder) gxxCmd(objdir string) []string {
2070 return b.ccompilerCmd("CXX", defaultCXX, objdir)
2073 // ccompilerCmd returns a command line prefix for the given environment
2074 // variable and using the default command when the variable is empty.
2075 func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
2076 // NOTE: env.go's mkEnv knows that the first three
2077 // strings returned are "gcc", "-I", objdir (and cuts them off).
2079 compiler := envList(envvar, defcmd)
2080 a := []string{compiler[0], "-I", objdir}
2081 a = append(a, compiler[1:]...)
2083 // Definitely want -fPIC but on Windows gcc complains
2084 // "-fPIC ignored for target (all code is position independent)"
2085 if goos != "windows" {
2086 a = append(a, "-fPIC")
2088 a = append(a, b.gccArchArgs()...)
2089 // gcc-4.5 and beyond require explicit "-pthread" flag
2090 // for multithreading with pthread library.
2091 if buildContext.CgoEnabled {
2094 a = append(a, "-mthreads")
2096 a = append(a, "-pthread")
2100 if strings.Contains(a[0], "clang") {
2101 // disable ASCII art in clang errors, if possible
2102 a = append(a, "-fno-caret-diagnostics")
2103 // clang is too smart about command-line arguments
2104 a = append(a, "-Qunused-arguments")
2107 // disable word wrapping in error messages
2108 a = append(a, "-fmessage-length=0")
2110 // On OS X, some of the compilers behave as if -fno-common
2111 // is always set, and the Mach-O linker in 6l/8l assumes this.
2112 // See http://golang.org/issue/3253.
2113 if goos == "darwin" {
2114 a = append(a, "-fno-common")
2120 // gccArchArgs returns arguments to pass to gcc based on the architecture.
2121 func (b *builder) gccArchArgs() []string {
2124 return []string{"-m32"}
2126 return []string{"-m64"}
2128 return []string{"-marm"} // not thumb
2133 // envList returns the value of the given environment variable broken
2134 // into fields, using the default value when the variable is empty.
2135 func envList(key, def string) []string {
2140 return strings.Fields(v)
2143 // Return the flags to use when invoking the C or C++ compilers, or cgo.
2144 func (b *builder) cflags(p *Package, def bool) (cppflags, cflags, cxxflags, ldflags []string) {
2150 cppflags = stringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS)
2151 cflags = stringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS)
2152 cxxflags = stringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS)
2153 ldflags = stringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS)
2157 var cgoRe = regexp.MustCompile(`[/\\:]`)
2160 cgoLibGccFile string
2162 cgoLibGccFileOnce sync.Once
2165 func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
2166 cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoLDFLAGS := b.cflags(p, true)
2167 _, cgoexeCFLAGS, _, _ := b.cflags(p, false)
2168 cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...)
2169 cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...)
2170 // If we are compiling Objective-C code, then we need to link against libobjc
2171 if len(mfiles) > 0 {
2172 cgoLDFLAGS = append(cgoLDFLAGS, "-lobjc")
2175 // Allows including _cgo_export.h from .[ch] files in the package.
2176 cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", obj)
2179 // TODO: CGOPKGPATH, CGO_FLAGS?
2180 gofiles := []string{obj + "_cgo_gotypes.go"}
2181 cfiles := []string{"_cgo_main.c", "_cgo_export.c"}
2182 for _, fn := range p.CgoFiles {
2183 f := cgoRe.ReplaceAllString(fn[:len(fn)-2], "_")
2184 gofiles = append(gofiles, obj+f+"cgo1.go")
2185 cfiles = append(cfiles, f+"cgo2.c")
2187 defunC := obj + "_cgo_defun.c"
2189 cgoflags := []string{}
2190 // TODO: make cgo not depend on $GOARCH?
2194 if p.Standard && p.ImportPath == "runtime/cgo" {
2195 cgoflags = append(cgoflags, "-import_runtime_cgo=false")
2197 if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/cgo") {
2198 cgoflags = append(cgoflags, "-import_syscall=false")
2201 // Update $CGO_LDFLAGS with p.CgoLDFLAGS.
2203 if len(cgoLDFLAGS) > 0 {
2204 flags := make([]string, len(cgoLDFLAGS))
2205 for i, f := range cgoLDFLAGS {
2206 flags[i] = strconv.Quote(f)
2208 cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
2211 if _, ok := buildToolchain.(gccgoToolchain); ok {
2212 cgoflags = append(cgoflags, "-gccgo")
2213 if pkgpath := gccgoPkgpath(p); pkgpath != "" {
2214 cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
2218 if err := b.run(p.Dir, p.ImportPath, cgoenv, buildToolExec, cgoExe, "-objdir", obj, cgoflags, "--", cgoCPPFLAGS, cgoexeCFLAGS, p.CgoFiles); err != nil {
2219 return nil, nil, err
2221 outGo = append(outGo, gofiles...)
2224 _, gccgo := buildToolchain.(gccgoToolchain)
2226 defunObj := obj + "_cgo_defun." + objExt
2227 if err := buildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
2228 return nil, nil, err
2230 outObj = append(outObj, defunObj)
2234 var linkobj []string
2236 var bareLDFLAGS []string
2237 // filter out -lsomelib, -l somelib, *.{so,dll,dylib}, and (on Darwin) -framework X
2238 for i := 0; i < len(cgoLDFLAGS); i++ {
2241 // skip "-lc" or "-l somelib"
2242 case strings.HasPrefix(f, "-l"):
2246 // skip "-framework X" on Darwin
2247 case goos == "darwin" && f == "-framework":
2249 // skip "*.{dylib,so,dll}"
2250 case strings.HasSuffix(f, ".dylib"),
2251 strings.HasSuffix(f, ".so"),
2252 strings.HasSuffix(f, ".dll"):
2254 // Remove any -fsanitize=foo flags.
2255 // Otherwise the compiler driver thinks that we are doing final link
2256 // and links sanitizer runtime into the object file. But we are not doing
2257 // the final link, we will link the resulting object file again. And
2258 // so the program ends up with two copies of sanitizer runtime.
2259 // See issue 8788 for details.
2260 case strings.HasPrefix(f, "-fsanitize="):
2263 bareLDFLAGS = append(bareLDFLAGS, f)
2267 cgoLibGccFileOnce.Do(func() {
2268 cgoLibGccFile, cgoLibGccErr = b.libgcc(p)
2270 if cgoLibGccFile == "" && cgoLibGccErr != nil {
2271 return nil, nil, err
2274 var staticLibs []string
2275 if goos == "windows" {
2276 // libmingw32 and libmingwex might also use libgcc, so libgcc must come last,
2277 // and they also have some inter-dependencies, so must use linker groups.
2278 staticLibs = []string{"-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group"}
2280 if cgoLibGccFile != "" {
2281 staticLibs = append(staticLibs, cgoLibGccFile)
2284 cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
2285 for _, cfile := range cfiles {
2286 ofile := obj + cfile[:len(cfile)-1] + "o"
2287 if err := b.gcc(p, ofile, cflags, obj+cfile); err != nil {
2288 return nil, nil, err
2290 linkobj = append(linkobj, ofile)
2291 if !strings.HasSuffix(ofile, "_cgo_main.o") {
2292 outObj = append(outObj, ofile)
2296 for _, file := range gccfiles {
2297 ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
2298 if err := b.gcc(p, ofile, cflags, file); err != nil {
2299 return nil, nil, err
2301 linkobj = append(linkobj, ofile)
2302 outObj = append(outObj, ofile)
2305 cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
2306 for _, file := range gxxfiles {
2307 // Append .o to the file, just in case the pkg has file.c and file.cpp
2308 ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
2309 if err := b.gxx(p, ofile, cxxflags, file); err != nil {
2310 return nil, nil, err
2312 linkobj = append(linkobj, ofile)
2313 outObj = append(outObj, ofile)
2316 for _, file := range mfiles {
2317 // Append .o to the file, just in case the pkg has file.c and file.m
2318 ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
2319 if err := b.gcc(p, ofile, cflags, file); err != nil {
2320 return nil, nil, err
2322 linkobj = append(linkobj, ofile)
2323 outObj = append(outObj, ofile)
2326 linkobj = append(linkobj, p.SysoFiles...)
2327 dynobj := obj + "_cgo_.o"
2328 pie := goarch == "arm" && (goos == "linux" || goos == "android")
2329 if pie { // we need to use -pie for Linux/ARM to get accurate imported sym
2330 cgoLDFLAGS = append(cgoLDFLAGS, "-pie")
2332 if err := b.gccld(p, dynobj, cgoLDFLAGS, linkobj); err != nil {
2333 return nil, nil, err
2335 if pie { // but we don't need -pie for normal cgo programs
2336 cgoLDFLAGS = cgoLDFLAGS[0 : len(cgoLDFLAGS)-1]
2339 if _, ok := buildToolchain.(gccgoToolchain); ok {
2340 // we don't use dynimport when using gccgo.
2341 return outGo, outObj, nil
2345 importGo := obj + "_cgo_import.go"
2346 cgoflags = []string{}
2347 if p.Standard && p.ImportPath == "runtime/cgo" {
2348 cgoflags = append(cgoflags, "-dynlinker") // record path to dynamic linker
2350 if err := b.run(p.Dir, p.ImportPath, nil, buildToolExec, cgoExe, "-objdir", obj, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags); err != nil {
2351 return nil, nil, err
2353 outGo = append(outGo, importGo)
2355 ofile := obj + "_all.o"
2356 var gccObjs, nonGccObjs []string
2357 for _, f := range outObj {
2358 if strings.HasSuffix(f, ".o") {
2359 gccObjs = append(gccObjs, f)
2361 nonGccObjs = append(nonGccObjs, f)
2364 ldflags := stringList(bareLDFLAGS, "-Wl,-r", "-nostdlib", staticLibs)
2366 // Some systems, such as Ubuntu, always add --build-id to
2367 // every link, but we don't want a build ID since we are
2368 // producing an object file. On some of those system a plain
2369 // -r (not -Wl,-r) will turn off --build-id, but clang 3.0
2370 // doesn't support a plain -r. I don't know how to turn off
2371 // --build-id when using clang other than passing a trailing
2372 // --build-id=none. So that is what we do, but only on
2373 // systems likely to support it, which is to say, systems that
2374 // normally use gold or the GNU linker.
2376 case "android", "dragonfly", "linux", "netbsd":
2377 ldflags = append(ldflags, "-Wl,--build-id=none")
2380 if err := b.gccld(p, ofile, ldflags, gccObjs); err != nil {
2381 return nil, nil, err
2384 // NOTE(rsc): The importObj is a 5c/6c/8c object and on Windows
2385 // must be processed before the gcc-generated objects.
2386 // Put it first. http://golang.org/issue/2601
2387 outObj = stringList(nonGccObjs, ofile)
2389 return outGo, outObj, nil
2392 // Run SWIG on all SWIG input files.
2393 // TODO: Don't build a shared library, once SWIG emits the necessary
2394 // pragmas for external linking.
2395 func (b *builder) swig(p *Package, obj string, pcCFLAGS, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
2396 cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
2397 cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
2398 cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
2400 for _, file := range gccfiles {
2401 ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
2402 if err := b.gcc(p, ofile, cflags, file); err != nil {
2403 return nil, nil, err
2405 outObj = append(outObj, ofile)
2408 for _, file := range gxxfiles {
2409 // Append .o to the file, just in case the pkg has file.c and file.cpp
2410 ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
2411 if err := b.gxx(p, ofile, cxxflags, file); err != nil {
2412 return nil, nil, err
2414 outObj = append(outObj, ofile)
2417 for _, file := range mfiles {
2418 // Append .o to the file, just in case the pkg has file.c and file.cpp
2419 ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
2420 if err := b.gcc(p, ofile, cflags, file); err != nil {
2421 return nil, nil, err
2423 outObj = append(outObj, ofile)
2426 if err := b.swigVersionCheck(); err != nil {
2427 return nil, nil, err
2430 intgosize, err := b.swigIntSize(obj)
2432 return nil, nil, err
2435 for _, f := range p.SwigFiles {
2436 goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, pcCFLAGS, false, intgosize)
2438 return nil, nil, err
2441 outGo = append(outGo, goFile)
2444 outObj = append(outObj, objFile)
2446 if gccObjFile != "" {
2447 outObj = append(outObj, gccObjFile)
2450 for _, f := range p.SwigCXXFiles {
2451 goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, pcCFLAGS, true, intgosize)
2453 return nil, nil, err
2456 outGo = append(outGo, goFile)
2459 outObj = append(outObj, objFile)
2461 if gccObjFile != "" {
2462 outObj = append(outObj, gccObjFile)
2465 return outGo, outObj, nil
2468 // Make sure SWIG is new enough.
2470 swigCheckOnce sync.Once
2474 func (b *builder) swigDoVersionCheck() error {
2475 out, err := b.runOut("", "", nil, "swig", "-version")
2479 re := regexp.MustCompile(`[vV]ersion +([\d])`)
2480 matches := re.FindSubmatch(out)
2482 // Can't find version number; hope for the best.
2485 major, err := strconv.Atoi(string(matches[1]))
2487 // Can't find version number; hope for the best.
2491 return errors.New("must have SWIG version >= 3.0")
2496 func (b *builder) swigVersionCheck() error {
2497 swigCheckOnce.Do(func() {
2498 swigCheck = b.swigDoVersionCheck()
2503 // This code fails to build if sizeof(int) <= 32
2504 const swigIntSizeCode = `
2506 const i int = 1 << 32
2509 // Determine the size of int on the target system for the -intgosize option
2511 func (b *builder) swigIntSize(obj string) (intsize string, err error) {
2513 return "$INTBITS", nil
2515 src := filepath.Join(b.work, "swig_intsize.go")
2516 if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0644); err != nil {
2519 srcs := []string{src}
2521 p := goFilesPackage(srcs)
2523 if _, _, e := buildToolchain.gc(b, p, "", obj, false, nil, srcs); e != nil {
2529 // Run SWIG on one SWIG input file.
2530 func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outObj, objGccObj string, err error) {
2531 cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
2534 cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS)
2536 cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS)
2539 n := 5 // length of ".swig"
2541 n = 8 // length of ".swigcxx"
2543 base := file[:len(file)-n]
2544 goFile := base + ".go"
2545 cBase := base + "_gc."
2546 gccBase := base + "_wrap."
2552 _, gccgo := buildToolchain.(gccgoToolchain)
2557 "-intgosize", intgosize,
2559 "-o", obj + gccBase + gccExt,
2563 for _, f := range cflags {
2564 if len(f) > 3 && f[:2] == "-I" {
2565 args = append(args, f)
2570 args = append(args, "-gccgo")
2571 if pkgpath := gccgoPkgpath(p); pkgpath != "" {
2572 args = append(args, "-go-pkgpath", pkgpath)
2576 args = append(args, "-c++")
2579 if out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file); err != nil {
2581 if bytes.Contains(out, []byte("Unrecognized option -intgosize")) {
2582 return "", "", "", errors.New("must have SWIG version >= 3.0")
2584 b.showOutput(p.Dir, p.ImportPath, b.processOutput(out))
2585 return "", "", "", errPrintedOutput
2587 return "", "", "", err
2593 cObj = obj + cBase + archChar
2594 if err := buildToolchain.cc(b, p, obj, cObj, obj+cBase+"c"); err != nil {
2595 return "", "", "", err
2600 gccObj := obj + gccBase + "o"
2602 if err := b.gcc(p, gccObj, cflags, obj+gccBase+gccExt); err != nil {
2603 return "", "", "", err
2606 if err := b.gxx(p, gccObj, cflags, obj+gccBase+gccExt); err != nil {
2607 return "", "", "", err
2611 return obj + goFile, cObj, gccObj, nil
2614 // An actionQueue is a priority queue of actions.
2615 type actionQueue []*action
2617 // Implement heap.Interface
2618 func (q *actionQueue) Len() int { return len(*q) }
2619 func (q *actionQueue) Swap(i, j int) { (*q)[i], (*q)[j] = (*q)[j], (*q)[i] }
2620 func (q *actionQueue) Less(i, j int) bool { return (*q)[i].priority < (*q)[j].priority }
2621 func (q *actionQueue) Push(x interface{}) { *q = append(*q, x.(*action)) }
2622 func (q *actionQueue) Pop() interface{} {
2629 func (q *actionQueue) push(a *action) {
2633 func (q *actionQueue) pop() *action {
2634 return heap.Pop(q).(*action)
2641 if goarch != "amd64" || goos != "linux" && goos != "freebsd" && goos != "darwin" && goos != "windows" {
2642 fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0])
2645 buildGcflags = append(buildGcflags, "-race")
2646 buildLdflags = append(buildLdflags, "-race")
2647 if buildContext.InstallSuffix != "" {
2648 buildContext.InstallSuffix += "_"
2650 buildContext.InstallSuffix += "race"
2651 buildContext.BuildTags = append(buildContext.BuildTags, "race")
2654 // defaultSuffix returns file extension used for command files in
2655 // current os environment.
2656 func defaultSuffix() string {
2657 switch runtime.GOOS {