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.
29
var cmdBuild = &Command{
30
UsageLine: "build [-o output] [build flags] [packages]",
31
Short: "compile packages and dependencies",
33
Build compiles the packages named by the import paths,
34
along with their dependencies, but it does not install the results.
36
If the arguments are a list of .go files, build treats them as a list
37
of source files specifying a single package.
39
When the command line specifies a single main package,
40
build writes the resulting executable to output.
41
Otherwise build compiles the packages but discards the results,
42
serving only as a check that the packages can be built.
44
The -o flag specifies the output file name. If not specified, the
45
output file name depends on the arguments and derives from the name
46
of the package, such as p.a for package p, unless p is 'main'. If
47
the package is main and file names are provided, the file name
48
derives from the first file name mentioned, such as f1 for 'go build
49
f1.go f2.go'; with no files provided ('go build'), the output file
50
name is the base name of the containing directory.
52
The build flags are shared by the build, install, run, and test commands:
55
force rebuilding of packages that are already up-to-date.
57
print the commands but do not run them.
59
the number of builds that can be run in parallel.
60
The default is the number of CPUs available.
62
enable data race detection.
63
Supported only on linux/amd64, darwin/amd64 and windows/amd64.
65
print the names of packages as they are compiled.
67
print the name of the temporary work directory and
68
do not delete it when exiting.
73
arguments to pass on each 5c, 6c, or 8c compiler invocation.
75
name of compiler to use, as in runtime.Compiler (gccgo or gc).
76
-gccgoflags 'arg list'
77
arguments to pass on each gccgo compiler/linker invocation.
79
arguments to pass on each 5g, 6g, or 8g compiler invocation.
81
a suffix to use in the name of the package installation directory,
82
in order to keep output separate from default builds.
83
If using the -race flag, the install suffix is automatically set to race
84
or, if set explicitly, has _race appended to it.
86
arguments to pass on each 5l, 6l, or 8l linker invocation.
88
a list of build tags to consider satisfied during the build.
89
See the documentation for the go/build package for
90
more information about build tags.
92
The list flags accept a space-separated list of strings. To embed spaces
93
in an element in the list, surround it with either single or double quotes.
95
For more about specifying packages, see 'go help packages'.
96
For more about where packages and binaries are installed,
97
run 'go help gopath'. For more about calling between Go and C/C++,
100
See also: go install, go get, go clean.
106
cmdBuild.Run = runBuild
107
cmdInstall.Run = runInstall
109
addBuildFlags(cmdBuild)
110
addBuildFlags(cmdInstall)
113
// Flags set by multiple commands.
114
var buildA bool // -a flag
115
var buildN bool // -n flag
116
var buildP = runtime.NumCPU() // -p flag
117
var buildV bool // -v flag
118
var buildX bool // -x flag
119
var buildO = cmdBuild.Flag.String("o", "", "output file")
120
var buildWork bool // -work flag
121
var buildGcflags []string // -gcflags flag
122
var buildCcflags []string // -ccflags flag
123
var buildLdflags []string // -ldflags flag
124
var buildGccgoflags []string // -gccgoflags flag
125
var buildRace bool // -race flag
127
var buildContext = build.Default
128
var buildToolchain toolchain = noToolchain{}
130
// buildCompiler implements flag.Var.
131
// It implements Set by updating both
132
// buildToolchain and buildContext.Compiler.
133
type buildCompiler struct{}
135
func (c buildCompiler) Set(value string) error {
138
buildToolchain = gcToolchain{}
140
buildToolchain = gccgoToolchain{}
142
return fmt.Errorf("unknown compiler %q", value)
144
buildContext.Compiler = value
148
func (c buildCompiler) String() string {
149
return buildContext.Compiler
153
switch build.Default.Compiler {
155
buildToolchain = gcToolchain{}
157
buildToolchain = gccgoToolchain{}
161
// addBuildFlags adds the flags common to the build and install commands.
162
func addBuildFlags(cmd *Command) {
163
// NOTE: If you add flags here, also add them to testflag.go.
164
cmd.Flag.BoolVar(&buildA, "a", false, "")
165
cmd.Flag.BoolVar(&buildN, "n", false, "")
166
cmd.Flag.IntVar(&buildP, "p", buildP, "")
167
cmd.Flag.StringVar(&buildContext.InstallSuffix, "installsuffix", "", "")
168
cmd.Flag.BoolVar(&buildV, "v", false, "")
169
cmd.Flag.BoolVar(&buildX, "x", false, "")
170
cmd.Flag.BoolVar(&buildWork, "work", false, "")
171
cmd.Flag.Var((*stringsFlag)(&buildGcflags), "gcflags", "")
172
cmd.Flag.Var((*stringsFlag)(&buildCcflags), "ccflags", "")
173
cmd.Flag.Var((*stringsFlag)(&buildLdflags), "ldflags", "")
174
cmd.Flag.Var((*stringsFlag)(&buildGccgoflags), "gccgoflags", "")
175
cmd.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
176
cmd.Flag.Var(buildCompiler{}, "compiler", "")
177
cmd.Flag.BoolVar(&buildRace, "race", false, "")
180
func addBuildFlagsNX(cmd *Command) {
181
cmd.Flag.BoolVar(&buildN, "n", false, "")
182
cmd.Flag.BoolVar(&buildX, "x", false, "")
185
func isSpaceByte(c byte) bool {
186
return c == ' ' || c == '\t' || c == '\n' || c == '\r'
189
// fileExtSplit expects a filename and returns the name
190
// and ext (without the dot). If the file has no
191
// extension, ext will be empty.
192
func fileExtSplit(file string) (name, ext string) {
193
dotExt := filepath.Ext(file)
194
name = file[:len(file)-len(dotExt)]
201
type stringsFlag []string
203
func (v *stringsFlag) Set(s string) error {
205
*v, err = splitQuotedFields(s)
209
func splitQuotedFields(s string) ([]string, error) {
210
// Split fields allowing '' or "" around elements.
211
// Quotes further inside the string do not count.
214
for len(s) > 0 && isSpaceByte(s[0]) {
220
// Accepted quoted string. No unescaping inside.
221
if s[0] == '"' || s[0] == '\'' {
225
for i < len(s) && s[i] != quote {
229
return nil, fmt.Errorf("unterminated %c string", quote)
236
for i < len(s) && !isSpaceByte(s[i]) {
245
func (v *stringsFlag) String() string {
246
return "<stringsFlag>"
249
func runBuild(cmd *Command, args []string) {
254
pkgs := packagesForBuild(args)
256
if len(pkgs) == 1 && pkgs[0].Name == "main" && *buildO == "" {
257
_, *buildO = path.Split(pkgs[0].ImportPath)
261
// sanity check some often mis-used options
262
switch buildContext.Compiler {
264
if len(buildGcflags) != 0 {
265
fmt.Println("go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags")
267
if len(buildLdflags) != 0 {
268
fmt.Println("go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags")
271
if len(buildGccgoflags) != 0 {
272
fmt.Println("go build: when using gc toolchain, please pass compile flags using -gcflags, and linker flags using -ldflags")
278
fatalf("go build: cannot use -o with multiple packages")
281
p.target = "" // must build - not up to date
282
a := b.action(modeInstall, modeBuild, p)
289
for _, p := range packages(args) {
290
a.deps = append(a.deps, b.action(modeBuild, modeBuild, p))
295
var cmdInstall = &Command{
296
UsageLine: "install [build flags] [packages]",
297
Short: "compile and install packages and dependencies",
299
Install compiles and installs the packages named by the import paths,
300
along with their dependencies.
302
For more about the build flags, see 'go help build'.
303
For more about specifying packages, see 'go help packages'.
305
See also: go build, go get, go clean.
309
func runInstall(cmd *Command, args []string) {
311
pkgs := packagesForBuild(args)
313
for _, p := range pkgs {
314
if p.Target == "" && (!p.Standard || p.ImportPath != "unsafe") {
316
errorf("go install: no install location for .go files listed on command line (GOBIN not set)")
317
} else if p.ConflictDir != "" {
318
errorf("go install: no install location for %s: hidden by %s", p.Dir, p.ConflictDir)
320
errorf("go install: no install location for directory %s outside GOPATH", p.Dir)
329
for _, p := range pkgs {
330
a.deps = append(a.deps, b.action(modeInstall, modeInstall, p))
335
// Global build parameters (used during package load)
344
goarch = buildContext.GOARCH
345
goos = buildContext.GOOS
346
if goos == "windows" {
350
archChar, err = build.ArchChar(goarch)
356
// A builder holds global state about a build.
357
// It does not hold per-package state, because we
358
// build packages in parallel, and the builder is shared.
359
type builder struct {
360
work string // the temporary work directory (ends in filepath.Separator)
361
actionCache map[cacheKey]*action // a cache of already-constructed actions
362
mkdirCache map[string]bool // a cache of created directories
363
print func(args ...interface{}) (int, error)
366
scriptDir string // current directory in printed script
373
// An action represents a single action in the action graph.
375
p *Package // the package this action works on
376
deps []*action // actions that must happen before this one
377
triggers []*action // inverse of deps
378
cgo *action // action for cgo binary if needed
379
args []string // additional args for runProgram
380
testOutput *bytes.Buffer // test output buffer
382
f func(*builder, *action) error // the action itself (nil = no-op)
383
ignoreFail bool // whether to run f even if dependencies fail
385
// Generated files, directories.
386
link bool // target is executable, not just package
387
pkgdir string // the -I or -L argument to use when importing this package
388
objdir string // directory for intermediate objects
389
objpkg string // the intermediate package .a file created during the action
390
target string // goal of the action: the created package or executable
393
pending int // number of deps yet to complete
394
priority int // relative execution priority
395
failed bool // whether the action failed
398
// cacheKey is the key for the action cache.
399
type cacheKey struct {
404
// buildMode specifies the build mode:
405
// are we just building things or also installing the results?
409
modeBuild buildMode = iota
414
goroot = filepath.Clean(runtime.GOROOT())
415
gobin = os.Getenv("GOBIN")
416
gorootBin = filepath.Join(goroot, "bin")
417
gorootSrcPkg = filepath.Join(goroot, "src/pkg")
418
gorootPkg = filepath.Join(goroot, "pkg")
419
gorootSrc = filepath.Join(goroot, "src")
422
func (b *builder) init() {
424
b.print = func(a ...interface{}) (int, error) {
425
return fmt.Fprint(os.Stderr, a...)
427
b.actionCache = make(map[cacheKey]*action)
428
b.mkdirCache = make(map[string]bool)
433
b.work, err = ioutil.TempDir("", "go-build")
437
if buildX || buildWork {
438
fmt.Fprintf(os.Stderr, "WORK=%s\n", b.work)
441
atexit(func() { os.RemoveAll(b.work) })
446
// goFilesPackage creates a package for building a collection of Go files
447
// (typically named on the command line). The target is named p.a for
448
// package p or named after the first Go file for package main.
449
func goFilesPackage(gofiles []string) *Package {
450
// TODO: Remove this restriction.
451
for _, f := range gofiles {
452
if !strings.HasSuffix(f, ".go") {
453
fatalf("named files must be .go files")
459
ctxt.UseAllFiles = true
461
// Synthesize fake "directory" that only shows the named files,
462
// to make it look like this is a standard package or
463
// command directory. So that local imports resolve
464
// consistently, the files must all be in the same directory.
465
var dirent []os.FileInfo
467
for _, file := range gofiles {
468
fi, err := os.Stat(file)
473
fatalf("%s is a directory, should be a Go file", file)
475
dir1, _ := filepath.Split(file)
478
} else if dir != dir1 {
479
fatalf("named files must all be in one directory; have %s and %s", dir, dir1)
481
dirent = append(dirent, fi)
483
ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil }
485
if !filepath.IsAbs(dir) {
486
dir = filepath.Join(cwd, dir)
489
bp, err := ctxt.ImportDir(dir, 0)
493
pkg.load(&stk, bp, err)
494
pkg.localPrefix = dirToImportPath(dir)
495
pkg.ImportPath = "command-line-arguments"
498
if pkg.Name == "main" {
499
_, elem := filepath.Split(gofiles[0])
500
exe := elem[:len(elem)-len(".go")] + exeSuffix
505
pkg.target = filepath.Join(gobin, exe)
509
*buildO = pkg.Name + ".a"
512
pkg.Target = pkg.target
519
// action returns the action for applying the given operation (mode) to the package.
520
// depMode is the action to use when building dependencies.
521
func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action {
522
key := cacheKey{mode, p}
523
a := b.actionCache[key]
528
a = &action{p: p, pkgdir: p.build.PkgRoot}
529
if p.pkgdir != "" { // overrides p.t
533
b.actionCache[key] = a
535
for _, p1 := range p.imports {
536
a.deps = append(a.deps, b.action(depMode, depMode, p1))
539
// If we are not doing a cross-build, then record the binary we'll
540
// generate for cgo as a dependency of the build of any package
541
// using cgo, to make sure we do not overwrite the binary while
542
// a package is using it. If this is a cross-build, then the cgo we
543
// are writing is not the cgo we need to use.
544
if goos == runtime.GOOS && goarch == runtime.GOARCH && !buildRace {
545
if len(p.CgoFiles) > 0 || p.Standard && p.ImportPath == "runtime/cgo" {
547
p1 := loadPackage("cmd/cgo", &stk)
549
fatalf("load cmd/cgo: %v", p1.Error)
551
a.cgo = b.action(depMode, depMode, p1)
552
a.deps = append(a.deps, a.cgo)
557
switch p.ImportPath {
558
case "builtin", "unsafe":
559
// Fake packages - nothing to build.
562
// gccgo standard library is "fake" too.
563
if _, ok := buildToolchain.(gccgoToolchain); ok {
564
// the target name is needed for cgo.
570
if !p.Stale && p.target != "" {
571
// p.Stale==false implies that p.target is up-to-date.
572
// Record target name for use by actions depending on this one.
577
if p.local && p.target == "" {
578
// Imported via local path. No permanent target.
585
a.objdir = filepath.Join(work, a.p.ImportPath, "_obj") + string(filepath.Separator)
586
a.objpkg = buildToolchain.pkgpath(work, a.p)
587
a.link = p.Name == "main"
591
a.f = (*builder).install
592
a.deps = []*action{b.action(modeBuild, depMode, p)}
593
a.target = a.p.target
595
a.f = (*builder).build
598
// An executable file. (This is the name of a temporary file.)
599
// Because we run the temporary file in 'go run' and 'go test',
600
// the name will show up in ps listings. If the caller has specified
601
// a name, use that instead of a.out. The binary is generated
602
// in an otherwise empty subdirectory named exe to avoid
603
// naming conflicts. The only possible conflict is if we were
604
// to create a top-level package named exe.
609
a.target = a.objdir + filepath.Join("exe", name) + exeSuffix
616
// actionList returns the list of actions in the dag rooted at root
617
// as visited in a depth-first post-order traversal.
618
func actionList(root *action) []*action {
619
seen := map[*action]bool{}
621
var walk func(*action)
622
walk = func(a *action) {
627
for _, a1 := range a.deps {
636
// do runs the action graph rooted at root.
637
func (b *builder) do(root *action) {
638
// Build list of all actions, assigning depth-first post-order priority.
639
// The original implementation here was a true queue
640
// (using a channel) but it had the effect of getting
641
// distracted by low-level leaf actions to the detriment
642
// of completing higher-level actions. The order of
643
// work does not matter much to overall execution time,
644
// but when running "go test std" it is nice to see each test
645
// results as soon as possible. The priorities assigned
646
// ensure that, all else being equal, the execution prefers
647
// to do what it would have done first in a simple depth-first
648
// dependency order traversal.
649
all := actionList(root)
650
for i, a := range all {
654
b.readySema = make(chan bool, len(all))
656
// Initialize per-action execution state.
657
for _, a := range all {
658
for _, a1 := range a.deps {
659
a1.triggers = append(a1.triggers, a)
661
a.pending = len(a.deps)
668
// Handle runs a single action and takes care of triggering
669
// any actions that are runnable as a result.
670
handle := func(a *action) {
672
if a.f != nil && (!a.failed || a.ignoreFail) {
676
// The actions run in parallel but all the updates to the
677
// shared work state are serialized through b.exec.
679
defer b.exec.Unlock()
682
if err == errPrintedOutput {
690
for _, a0 := range a.triggers {
694
if a0.pending--; a0.pending == 0 {
705
var wg sync.WaitGroup
707
// Kick off goroutines according to parallelism.
708
// If we are using the -n flag (just printing commands)
709
// drop the parallelism to 1, both to make the output
710
// deterministic and because there is no real work anyway.
715
for i := 0; i < par; i++ {
721
case _, ok := <-b.readySema:
725
// Receiving a value from b.readySema entitles
726
// us to take from the ready queue.
742
// hasString reports whether s appears in the list of strings.
743
func hasString(strings []string, s string) bool {
744
for _, t := range strings {
752
// build is the action for building a single package or command.
753
func (b *builder) build(a *action) (err error) {
754
// Return an error if the package has CXX files but it's not using
755
// cgo nor SWIG, since the CXX files can only be processed by cgo
756
// and SWIG (it's possible to have packages with C files without
757
// using cgo, they will get compiled with the plan9 C compiler and
758
// linked with the rest of the package).
759
if len(a.p.CXXFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
760
return fmt.Errorf("can't build package %s because it contains C++ files (%s) but it's not using cgo nor SWIG",
761
a.p.ImportPath, strings.Join(a.p.CXXFiles, ","))
764
if err != nil && err != errPrintedOutput {
765
err = fmt.Errorf("go build %s: %v", a.p.ImportPath, err)
769
// In -n mode, print a banner between packages.
770
// The banner is five lines so that when changes to
771
// different sections of the bootstrap script have to
772
// be merged, the banners give patch something
773
// to use to find its context.
774
fmt.Printf("\n#\n# %s\n#\n\n", a.p.ImportPath)
778
fmt.Fprintf(os.Stderr, "%s\n", a.p.ImportPath)
781
if a.p.Standard && a.p.ImportPath == "runtime" && buildContext.Compiler == "gc" &&
782
!hasString(a.p.HFiles, "zasm_"+buildContext.GOOS+"_"+buildContext.GOARCH+".h") {
783
return fmt.Errorf("%s/%s must be bootstrapped using make%v", buildContext.GOOS, buildContext.GOARCH, defaultSuffix())
786
// Make build directory.
788
if err := b.mkdir(obj); err != nil {
792
// make target directory
793
dir, _ := filepath.Split(a.target)
795
if err := b.mkdir(dir); err != nil {
800
var gofiles, cfiles, sfiles, objects, cgoObjects []string
802
// If we're doing coverage, preprocess the .go files and put them in the work directory
803
if a.p.coverMode != "" {
804
for _, file := range a.p.GoFiles {
805
sourceFile := filepath.Join(a.p.Dir, file)
806
cover := a.p.coverVars[file]
807
if cover == nil || isTestFile(file) {
808
// Not covering this file.
809
gofiles = append(gofiles, file)
812
coverFile := filepath.Join(obj, file)
813
if err := b.cover(a, coverFile, sourceFile, 0666, cover.Var); err != nil {
816
gofiles = append(gofiles, coverFile)
819
gofiles = append(gofiles, a.p.GoFiles...)
821
cfiles = append(cfiles, a.p.CFiles...)
822
sfiles = append(sfiles, a.p.SFiles...)
826
// In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
827
// There is one exception: runtime/cgo's job is to bridge the
828
// cgo and non-cgo worlds, so it necessarily has files in both.
829
// In that case gcc only gets the gcc_* files.
830
var gccfiles []string
831
if a.p.Standard && a.p.ImportPath == "runtime/cgo" {
832
filter := func(files, nongcc, gcc []string) ([]string, []string) {
833
for _, f := range files {
834
if strings.HasPrefix(f, "gcc_") {
837
nongcc = append(nongcc, f)
842
cfiles, gccfiles = filter(cfiles, cfiles[:0], gccfiles)
843
sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles)
845
gccfiles = append(cfiles, sfiles...)
850
cgoExe := tool("cgo")
851
if a.cgo != nil && a.cgo.target != "" {
852
cgoExe = a.cgo.target
854
outGo, outObj, err := b.cgo(a.p, cgoExe, obj, gccfiles, a.p.CXXFiles)
858
cgoObjects = append(cgoObjects, outObj...)
859
gofiles = append(gofiles, outGo...)
864
// In a package using SWIG, any .c or .s files are
865
// compiled with gcc.
866
gccfiles := append(cfiles, sfiles...)
869
outGo, outObj, err := b.swig(a.p, obj, gccfiles, a.p.CXXFiles)
873
cgoObjects = append(cgoObjects, outObj...)
874
gofiles = append(gofiles, outGo...)
877
// Prepare Go import path list.
878
inc := b.includeArgs("-I", a.deps)
881
if len(gofiles) > 0 {
882
ofile, out, err := buildToolchain.gc(b, a.p, obj, inc, gofiles)
884
b.showOutput(a.p.Dir, a.p.ImportPath, b.processOutput(out))
886
return errPrintedOutput
892
objects = append(objects, ofile)
895
// Copy .h files named for goos or goarch or goos_goarch
896
// to names using GOOS and GOARCH.
897
// For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
898
_goos_goarch := "_" + goos + "_" + goarch
900
_goarch := "_" + goarch
901
for _, file := range a.p.HFiles {
902
name, ext := fileExtSplit(file)
904
case strings.HasSuffix(name, _goos_goarch):
905
targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext
906
if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
909
case strings.HasSuffix(name, _goarch):
910
targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext
911
if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
914
case strings.HasSuffix(name, _goos):
915
targ := file[:len(name)-len(_goos)] + "_GOOS." + ext
916
if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
923
if _, ok := buildToolchain.(gccgoToolchain); ok {
927
for _, file := range cfiles {
928
out := file[:len(file)-len(".c")] + "." + objExt
929
if err := buildToolchain.cc(b, a.p, obj, obj+out, file); err != nil {
932
objects = append(objects, out)
935
// Assemble .s files.
936
for _, file := range sfiles {
937
out := file[:len(file)-len(".s")] + "." + objExt
938
if err := buildToolchain.asm(b, a.p, obj, obj+out, file); err != nil {
941
objects = append(objects, out)
944
// NOTE(rsc): On Windows, it is critically important that the
945
// gcc-compiled objects (cgoObjects) be listed after the ordinary
946
// objects in the archive. I do not know why this is.
947
// http://golang.org/issue/2601
948
objects = append(objects, cgoObjects...)
950
// Add system object files.
951
for _, syso := range a.p.SysoFiles {
952
objects = append(objects, filepath.Join(a.p.Dir, syso))
955
// Pack into archive in obj directory
956
if err := buildToolchain.pack(b, a.p, obj, a.objpkg, objects); err != nil {
962
// The compiler only cares about direct imports, but the
963
// linker needs the whole dependency tree.
965
all = all[:len(all)-1] // drop a
966
if err := buildToolchain.ld(b, a.p, a.target, all, a.objpkg, objects); err != nil {
974
// install is the action for installing a single package or executable.
975
func (b *builder) install(a *action) (err error) {
977
if err != nil && err != errPrintedOutput {
978
err = fmt.Errorf("go install %s: %v", a.p.ImportPath, err)
982
perm := os.FileMode(0666)
987
// make target directory
988
dir, _ := filepath.Split(a.target)
990
if err := b.mkdir(dir); err != nil {
995
// remove object dir to keep the amount of
996
// garbage down in a large build. On an operating system
997
// with aggressive buffering, cleaning incrementally like
998
// this keeps the intermediate objects from hitting the disk.
1000
defer os.RemoveAll(a1.objdir)
1001
defer os.Remove(a1.target)
1005
for _, f := range stringList(a.p.SwigFiles, a.p.SwigCXXFiles) {
1006
dir = a.p.swigDir(&buildContext)
1007
if err := b.mkdir(dir); err != nil {
1010
soname := a.p.swigSoname(f)
1011
source := filepath.Join(a.objdir, soname)
1012
target := filepath.Join(dir, soname)
1013
if err = b.copyFile(a, target, source, perm); err != nil {
1019
return b.copyFile(a, a.target, a1.target, perm)
1022
// includeArgs returns the -I or -L directory list for access
1023
// to the results of the list of actions.
1024
func (b *builder) includeArgs(flag string, all []*action) []string {
1026
incMap := map[string]bool{
1027
b.work: true, // handled later
1029
"": true, // ignore empty strings
1032
// Look in the temporary space for results of test-specific actions.
1033
// This is the $WORK/my/package/_test directory for the
1034
// package being built, so there are few of these.
1035
for _, a1 := range all {
1036
if dir := a1.pkgdir; dir != a1.p.build.PkgRoot && !incMap[dir] {
1038
inc = append(inc, flag, dir)
1042
// Also look in $WORK for any non-test packages that have
1043
// been built but not installed.
1044
inc = append(inc, flag, b.work)
1046
// Finally, look in the installed package directories for each action.
1047
for _, a1 := range all {
1048
if dir := a1.pkgdir; dir == a1.p.build.PkgRoot && !incMap[dir] {
1050
if _, ok := buildToolchain.(gccgoToolchain); ok {
1051
dir = filepath.Join(dir, "gccgo_"+goos+"_"+goarch)
1053
dir = filepath.Join(dir, goos+"_"+goarch)
1054
if buildContext.InstallSuffix != "" {
1055
dir += "_" + buildContext.InstallSuffix
1058
inc = append(inc, flag, dir)
1065
// copyFile is like 'cp src dst'.
1066
func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode) error {
1067
if buildN || buildX {
1068
b.showcmd("", "cp %s %s", src, dst)
1074
sf, err := os.Open(src)
1080
// Be careful about removing/overwriting dst.
1081
// Do not remove/overwrite if dst exists and is a directory
1082
// or a non-object file.
1083
if fi, err := os.Stat(dst); err == nil {
1085
return fmt.Errorf("build output %q already exists and is a directory", dst)
1088
return fmt.Errorf("build output %q already exists and is not an object file", dst)
1092
// On Windows, remove lingering ~ file from last attempt.
1094
if _, err := os.Stat(dst + "~"); err == nil {
1095
os.Remove(dst + "~")
1100
df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
1101
if err != nil && toolIsWindows {
1102
// Windows does not allow deletion of a binary file
1103
// while it is executing. Try to move it out of the way.
1104
// If the move fails, which is likely, we'll try again the
1105
// next time we do an install of this binary.
1106
if err := os.Rename(dst, dst+"~"); err == nil {
1107
os.Remove(dst + "~")
1109
df, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
1115
_, err = io.Copy(df, sf)
1119
return fmt.Errorf("copying %s to %s: %v", src, dst, err)
1124
// cover runs, in effect,
1125
// go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
1126
func (b *builder) cover(a *action, dst, src string, perm os.FileMode, varName string) error {
1127
return b.run(a.objdir, "cover "+a.p.ImportPath, nil,
1129
"-mode", a.p.coverMode,
1135
var objectMagic = [][]byte{
1136
{'!', '<', 'a', 'r', 'c', 'h', '>', '\n'}, // Package archive
1137
{'\x7F', 'E', 'L', 'F'}, // ELF
1138
{0xFE, 0xED, 0xFA, 0xCE}, // Mach-O big-endian 32-bit
1139
{0xFE, 0xED, 0xFA, 0xCF}, // Mach-O big-endian 64-bit
1140
{0xCE, 0xFA, 0xED, 0xFE}, // Mach-O little-endian 32-bit
1141
{0xCF, 0xFA, 0xED, 0xFE}, // Mach-O little-endian 64-bit
1142
{0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x04, 0x00}, // PE (Windows) as generated by 6l/8l
1143
{0x00, 0x00, 0x01, 0xEB}, // Plan 9 i386
1144
{0x00, 0x00, 0x8a, 0x97}, // Plan 9 amd64
1147
func isObject(s string) bool {
1148
f, err := os.Open(s)
1153
buf := make([]byte, 64)
1155
for _, magic := range objectMagic {
1156
if bytes.HasPrefix(buf, magic) {
1163
// fmtcmd formats a command in the manner of fmt.Sprintf but also:
1165
// If dir is non-empty and the script is not in dir right now,
1166
// fmtcmd inserts "cd dir\n" before the command.
1168
// fmtcmd replaces the value of b.work with $WORK.
1169
// fmtcmd replaces the value of goroot with $GOROOT.
1170
// fmtcmd replaces the value of b.gobin with $GOBIN.
1172
// fmtcmd replaces the name of the current directory with dot (.)
1173
// but only when it is at the beginning of a space-separated token.
1175
func (b *builder) fmtcmd(dir string, format string, args ...interface{}) string {
1176
cmd := fmt.Sprintf(format, args...)
1177
if dir != "" && dir != "/" {
1178
cmd = strings.Replace(" "+cmd, " "+dir, " .", -1)[1:]
1179
if b.scriptDir != dir {
1181
cmd = "cd " + dir + "\n" + cmd
1185
cmd = strings.Replace(cmd, b.work, "$WORK", -1)
1190
// showcmd prints the given command to standard output
1191
// for the implementation of -n or -x.
1192
func (b *builder) showcmd(dir string, format string, args ...interface{}) {
1194
defer b.output.Unlock()
1195
b.print(b.fmtcmd(dir, format, args...) + "\n")
1198
// showOutput prints "# desc" followed by the given output.
1199
// The output is expected to contain references to 'dir', usually
1200
// the source directory for the package that has failed to build.
1201
// showOutput rewrites mentions of dir with a relative path to dir
1202
// when the relative path is shorter. This is usually more pleasant.
1203
// For example, if fmt doesn't compile and we are in src/pkg/html,
1208
// ../fmt/print.go:1090: undefined: asdf
1215
// /usr/gopher/go/src/pkg/fmt/print.go:1090: undefined: asdf
1218
// showOutput also replaces references to the work directory with $WORK.
1220
func (b *builder) showOutput(dir, desc, out string) {
1221
prefix := "# " + desc
1222
suffix := "\n" + out
1223
if reldir := shortPath(dir); reldir != dir {
1224
suffix = strings.Replace(suffix, " "+dir, " "+reldir, -1)
1225
suffix = strings.Replace(suffix, "\n"+dir, "\n"+reldir, -1)
1227
suffix = strings.Replace(suffix, " "+b.work, " $WORK", -1)
1230
defer b.output.Unlock()
1231
b.print(prefix, suffix)
1234
// shortPath returns an absolute or relative name for path, whatever is shorter.
1235
func shortPath(path string) string {
1236
if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) {
1242
// relPaths returns a copy of paths with absolute paths
1243
// made relative to the current directory if they would be shorter.
1244
func relPaths(paths []string) []string {
1246
pwd, _ := os.Getwd()
1247
for _, p := range paths {
1248
rel, err := filepath.Rel(pwd, p)
1249
if err == nil && len(rel) < len(p) {
1252
out = append(out, p)
1257
// errPrintedOutput is a special error indicating that a command failed
1258
// but that it generated output as well, and that output has already
1259
// been printed, so there's no point showing 'exit status 1' or whatever
1260
// the wait status was. The main executor, builder.do, knows not to
1261
// print this error.
1262
var errPrintedOutput = errors.New("already printed output - no need to show error")
1264
var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.cgo1\.go:[0-9]+\]`)
1266
// run runs the command given by cmdline in the directory dir.
1267
// If the command fails, run prints information about the failure
1268
// and returns a non-nil error.
1269
func (b *builder) run(dir string, desc string, env []string, cmdargs ...interface{}) error {
1270
out, err := b.runOut(dir, desc, env, cmdargs...)
1273
desc = b.fmtcmd(dir, "%s", strings.Join(stringList(cmdargs...), " "))
1275
b.showOutput(dir, desc, b.processOutput(out))
1277
err = errPrintedOutput
1283
// processOutput prepares the output of runOut to be output to the console.
1284
func (b *builder) processOutput(out []byte) string {
1285
if out[len(out)-1] != '\n' {
1286
out = append(out, '\n')
1288
messages := string(out)
1289
// Fix up output referring to cgo-generated code to be more readable.
1290
// Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
1291
// Replace _Ctype_foo with C.foo.
1292
// If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
1293
if !buildX && cgoLine.MatchString(messages) {
1294
messages = cgoLine.ReplaceAllString(messages, "")
1295
messages = strings.Replace(messages, "type _Ctype_", "type C.", -1)
1300
// runOut runs the command given by cmdline in the directory dir.
1301
// It returns the command output and any errors that occurred.
1302
func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) {
1303
cmdline := stringList(cmdargs...)
1304
if buildN || buildX {
1305
b.showcmd(dir, "%s", joinUnambiguously(cmdline))
1313
var buf bytes.Buffer
1314
cmd := exec.Command(cmdline[0], cmdline[1:]...)
1318
cmd.Env = mergeEnvLists(env, envForDir(cmd.Dir))
1321
// cmd.Run will fail on Unix if some other process has the binary
1322
// we want to run open for writing. This can happen here because
1323
// we build and install the cgo command and then run it.
1324
// If another command was kicked off while we were writing the
1325
// cgo binary, the child process for that command may be holding
1326
// a reference to the fd, keeping us from running exec.
1328
// But, you might reasonably wonder, how can this happen?
1329
// The cgo fd, like all our fds, is close-on-exec, so that we need
1330
// not worry about other processes inheriting the fd accidentally.
1331
// The answer is that running a command is fork and exec.
1332
// A child forked while the cgo fd is open inherits that fd.
1333
// Until the child has called exec, it holds the fd open and the
1334
// kernel will not let us run cgo. Even if the child were to close
1335
// the fd explicitly, it would still be open from the time of the fork
1336
// until the time of the explicit close, and the race would remain.
1338
// On Unix systems, this results in ETXTBSY, which formats
1339
// as "text file busy". Rather than hard-code specific error cases,
1340
// we just look for that string. If this happens, sleep a little
1341
// and try again. We let this happen three times, with increasing
1342
// sleep lengths: 100+200+400 ms = 0.7 seconds.
1344
// An alternate solution might be to split the cmd.Run into
1345
// separate cmd.Start and cmd.Wait, and then use an RWLock
1346
// to make sure that copyFile only executes when no cmd.Start
1347
// call is in progress. However, cmd.Start (really syscall.forkExec)
1348
// only guarantees that when it returns, the exec is committed to
1349
// happen and succeed. It uses a close-on-exec file descriptor
1350
// itself to determine this, so we know that when cmd.Start returns,
1351
// at least one close-on-exec file descriptor has been closed.
1352
// However, we cannot be sure that all of them have been closed,
1353
// so the program might still encounter ETXTBSY even with such
1354
// an RWLock. The race window would be smaller, perhaps, but not
1355
// guaranteed to be gone.
1357
// Sleeping when we observe the race seems to be the most reliable
1360
// http://golang.org/issue/3001
1362
if err != nil && nbusy < 3 && strings.Contains(err.Error(), "text file busy") {
1363
time.Sleep(100 * time.Millisecond << uint(nbusy))
1368
return buf.Bytes(), err
1372
// joinUnambiguously prints the slice, quoting where necessary to make the
1373
// output unambiguous.
1374
// TODO: See issue 5279. The printing of commands needs a complete redo.
1375
func joinUnambiguously(a []string) string {
1376
var buf bytes.Buffer
1377
for i, s := range a {
1381
q := strconv.Quote(s)
1382
if s == "" || strings.Contains(s, " ") || len(q) > len(s)+2 {
1391
// mkdir makes the named directory.
1392
func (b *builder) mkdir(dir string) error {
1394
defer b.exec.Unlock()
1395
// We can be a little aggressive about being
1396
// sure directories exist. Skip repeated calls.
1397
if b.mkdirCache[dir] {
1400
b.mkdirCache[dir] = true
1402
if buildN || buildX {
1403
b.showcmd("", "mkdir -p %s", dir)
1409
if err := os.MkdirAll(dir, 0777); err != nil {
1415
// mkAbs returns an absolute path corresponding to
1416
// evaluating f in the directory dir.
1417
// We always pass absolute paths of source files so that
1418
// the error messages will include the full path to a file
1419
// in need of attention.
1420
func mkAbs(dir, f string) string {
1421
// Leave absolute paths alone.
1422
// Also, during -n mode we use the pseudo-directory $WORK
1423
// instead of creating an actual work directory that won't be used.
1424
// Leave paths beginning with $WORK alone too.
1425
if filepath.IsAbs(f) || strings.HasPrefix(f, "$WORK") {
1428
return filepath.Join(dir, f)
1431
type toolchain interface {
1432
// gc runs the compiler in a specific directory on a set of files
1433
// and returns the name of the generated output file.
1434
// The compiler runs in the directory dir.
1435
gc(b *builder, p *Package, obj string, importArgs []string, gofiles []string) (ofile string, out []byte, err error)
1436
// cc runs the toolchain's C compiler in a directory on a C file
1437
// to produce an output file.
1438
cc(b *builder, p *Package, objdir, ofile, cfile string) error
1439
// asm runs the assembler in a specific directory on a specific file
1440
// to generate the named output file.
1441
asm(b *builder, p *Package, obj, ofile, sfile string) error
1442
// pkgpath builds an appropriate path for a temporary package file.
1443
pkgpath(basedir string, p *Package) string
1444
// pack runs the archive packer in a specific directory to create
1445
// an archive from a set of object files.
1446
// typically it is run in the object directory.
1447
pack(b *builder, p *Package, objDir, afile string, ofiles []string) error
1448
// ld runs the linker to create a package starting at mainpkg.
1449
ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error
1455
type noToolchain struct{}
1457
func noCompiler() error {
1458
log.Fatalf("unknown compiler %q", buildContext.Compiler)
1462
func (noToolchain) compiler() string {
1467
func (noToolchain) linker() string {
1472
func (noToolchain) gc(b *builder, p *Package, obj string, importArgs []string, gofiles []string) (ofile string, out []byte, err error) {
1473
return "", nil, noCompiler()
1476
func (noToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
1480
func (noToolchain) pkgpath(basedir string, p *Package) string {
1485
func (noToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
1489
func (noToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
1493
func (noToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
1497
// The Go toolchain.
1498
type gcToolchain struct{}
1500
func (gcToolchain) compiler() string {
1501
return tool(archChar + "g")
1504
func (gcToolchain) linker() string {
1505
return tool(archChar + "l")
1508
func (gcToolchain) gc(b *builder, p *Package, obj string, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
1509
out := "_go_." + archChar
1511
gcargs := []string{"-p", p.ImportPath}
1512
if p.Standard && p.ImportPath == "runtime" {
1513
// runtime compiles with a special 6g flag to emit
1514
// additional reflect type data.
1515
gcargs = append(gcargs, "-+")
1518
// If we're giving the compiler the entire package (no C etc files), tell it that,
1519
// so that it can give good error messages about forward declarations.
1520
// Exceptions: a few standard packages have forward declarations for
1521
// pieces supplied behind-the-scenes by package runtime.
1522
extFiles := len(p.CgoFiles) + len(p.CFiles) + len(p.CXXFiles) + len(p.SFiles) + len(p.SysoFiles) + len(p.SwigFiles) + len(p.SwigCXXFiles)
1524
switch p.ImportPath {
1525
case "os", "runtime/pprof", "sync", "time":
1530
gcargs = append(gcargs, "-complete")
1532
if buildContext.InstallSuffix != "" {
1533
gcargs = append(gcargs, "-installsuffix", buildContext.InstallSuffix)
1536
args := stringList(tool(archChar+"g"), "-o", ofile, buildGcflags, gcargs, "-D", p.localPrefix, importArgs)
1537
for _, f := range gofiles {
1538
args = append(args, mkAbs(p.Dir, f))
1541
output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
1542
return ofile, output, err
1545
func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
1546
sfile = mkAbs(p.Dir, sfile)
1547
return b.run(p.Dir, p.ImportPath, nil, tool(archChar+"a"), "-I", obj, "-o", ofile, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, sfile)
1550
func (gcToolchain) pkgpath(basedir string, p *Package) string {
1551
end := filepath.FromSlash(p.ImportPath + ".a")
1552
return filepath.Join(basedir, end)
1555
func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
1556
var absOfiles []string
1557
for _, f := range ofiles {
1558
absOfiles = append(absOfiles, mkAbs(objDir, f))
1560
return b.run(p.Dir, p.ImportPath, nil, tool("pack"), "grcP", b.work, mkAbs(objDir, afile), absOfiles)
1563
func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
1564
importArgs := b.includeArgs("-L", allactions)
1565
swigDirs := make(map[string]bool)
1566
swigArg := []string{}
1568
for _, a := range allactions {
1569
if a.p != nil && a.p.usesSwig() {
1570
sd := a.p.swigDir(&buildContext)
1571
if len(swigArg) == 0 {
1572
swigArg = []string{"-r", sd}
1573
} else if !swigDirs[sd] {
1578
if a.objdir != "" && !swigDirs[a.objdir] {
1580
swigArg[1] += a.objdir
1581
swigDirs[a.objdir] = true
1584
if a.p != nil && len(a.p.CXXFiles) > 0 {
1588
ldflags := buildLdflags
1589
if buildContext.InstallSuffix != "" {
1590
ldflags = append(ldflags, "-installsuffix", buildContext.InstallSuffix)
1593
// The program includes C++ code. If the user has not
1594
// specified the -extld option, then default to
1595
// linking with the compiler named by the CXX
1596
// environment variable, or g++ if CXX is not set.
1598
for _, f := range ldflags {
1599
if f == "-extld" || strings.HasPrefix(f, "-extld=") {
1605
compiler := strings.Fields(os.Getenv("CXX"))
1606
if len(compiler) == 0 {
1607
compiler = []string{"g++"}
1609
ldflags = append(ldflags, "-extld="+compiler[0])
1610
if len(compiler) > 1 {
1612
add := strings.Join(compiler[1:], " ")
1613
for i, f := range ldflags {
1614
if f == "-extldflags" && i+1 < len(ldflags) {
1615
ldflags[i+1] = add + " " + ldflags[i+1]
1618
} else if strings.HasPrefix(f, "-extldflags=") {
1619
ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
1625
ldflags = append(ldflags, "-extldflags="+add)
1630
return b.run(".", p.ImportPath, nil, tool(archChar+"l"), "-o", out, importArgs, swigArg, ldflags, mainpkg)
1633
func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
1634
inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
1635
cfile = mkAbs(p.Dir, cfile)
1636
args := stringList(tool(archChar+"c"), "-F", "-V", "-w", "-I", objdir, "-I", inc, "-o", ofile, buildCcflags, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, cfile)
1637
return b.run(p.Dir, p.ImportPath, nil, args)
1640
// The Gccgo toolchain.
1641
type gccgoToolchain struct{}
1643
var gccgoBin, _ = exec.LookPath("gccgo")
1645
func (gccgoToolchain) compiler() string {
1649
func (gccgoToolchain) linker() string {
1653
func (gccgoToolchain) gc(b *builder, p *Package, obj string, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
1654
out := p.Name + ".o"
1656
gcargs := []string{"-g"}
1657
gcargs = append(gcargs, b.gccArchArgs()...)
1658
if pkgpath := gccgoPkgpath(p); pkgpath != "" {
1659
gcargs = append(gcargs, "-fgo-pkgpath="+pkgpath)
1661
if p.localPrefix != "" {
1662
gcargs = append(gcargs, "-fgo-relative-import-path="+p.localPrefix)
1664
args := stringList("gccgo", importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags)
1665
for _, f := range gofiles {
1666
args = append(args, mkAbs(p.Dir, f))
1669
output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
1670
return ofile, output, err
1673
func (gccgoToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
1674
sfile = mkAbs(p.Dir, sfile)
1675
defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
1676
if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
1677
defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
1679
defs = append(defs, b.gccArchArgs()...)
1680
return b.run(p.Dir, p.ImportPath, nil, "gccgo", "-I", obj, "-o", ofile, defs, sfile)
1683
func (gccgoToolchain) pkgpath(basedir string, p *Package) string {
1684
end := filepath.FromSlash(p.ImportPath + ".a")
1685
afile := filepath.Join(basedir, end)
1686
// add "lib" to the final element
1687
return filepath.Join(filepath.Dir(afile), "lib"+filepath.Base(afile))
1690
func (gccgoToolchain) 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))
1695
return b.run(p.Dir, p.ImportPath, nil, "ar", "cru", mkAbs(objDir, afile), absOfiles)
1698
func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
1699
// gccgo needs explicit linking with all package dependencies,
1700
// and all LDFLAGS from cgo dependencies.
1701
afilesSeen := make(map[*Package]bool)
1702
afiles := []string{}
1703
sfiles := []string{}
1704
ldflags := b.gccArchArgs()
1705
cgoldflags := []string{}
1708
for _, a := range allactions {
1711
if !afilesSeen[a.p] || a.objpkg != a.target {
1712
afilesSeen[a.p] = true
1713
afiles = append(afiles, a.target)
1716
cgoldflags = append(cgoldflags, a.p.CgoLDFLAGS...)
1717
if len(a.p.CgoFiles) > 0 {
1721
sd := a.p.swigDir(&buildContext)
1725
for _, f := range stringList(a.p.SwigFiles, a.p.SwigCXXFiles) {
1726
soname := a.p.swigSoname(f)
1727
sfiles = append(sfiles, filepath.Join(sd, soname))
1731
if len(a.p.CXXFiles) > 0 {
1736
ldflags = append(ldflags, afiles...)
1737
ldflags = append(ldflags, sfiles...)
1738
ldflags = append(ldflags, cgoldflags...)
1739
if usesCgo && goos == "linux" {
1740
ldflags = append(ldflags, "-Wl,-E")
1743
ldflags = append(ldflags, "-lstdc++")
1745
return b.run(".", p.ImportPath, nil, "gccgo", "-o", out, ofiles, "-Wl,-(", ldflags, "-Wl,-)", buildGccgoflags)
1748
func (gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
1749
inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
1750
cfile = mkAbs(p.Dir, cfile)
1751
defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
1752
defs = append(defs, b.gccArchArgs()...)
1753
if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
1754
defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
1756
// TODO: Support using clang here (during gccgo build)?
1757
return b.run(p.Dir, p.ImportPath, nil, "gcc", "-Wall", "-g",
1758
"-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile)
1761
func gccgoPkgpath(p *Package) string {
1762
if p.build.IsCommand() && !p.forceLibrary {
1768
func gccgoCleanPkgpath(p *Package) string {
1769
clean := func(r rune) rune {
1771
case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
1772
'0' <= r && r <= '9':
1777
return strings.Map(clean, gccgoPkgpath(p))
1780
// libgcc returns the filename for libgcc, as determined by invoking gcc with
1781
// the -print-libgcc-file-name option.
1782
func (b *builder) libgcc(p *Package) (string, error) {
1783
var buf bytes.Buffer
1785
gccCmd := b.gccCmd(p.Dir)
1789
// In -n mode we temporarily swap out the builder's
1790
// print function to capture the command-line. This
1791
// let's us assign it to $LIBGCC and produce a valid
1792
// buildscript for cgo packages.
1793
b.print = func(a ...interface{}) (int, error) {
1794
return fmt.Fprint(&buf, a...)
1797
f, err := b.runOut(p.Dir, p.ImportPath, nil, gccCmd, "-print-libgcc-file-name")
1799
return "", fmt.Errorf("gcc -print-libgcc-file-name: %v (%s)", err, f)
1802
s := fmt.Sprintf("LIBGCC=$(%s)\n", buf.Next(buf.Len()-1))
1805
return "$LIBGCC", nil
1808
// clang might not be able to find libgcc, and in that case,
1809
// it will simply return "libgcc.a", which is of no use to us.
1810
if strings.Contains(gccCmd[0], "clang") && !filepath.IsAbs(string(f)) {
1814
return strings.Trim(string(f), "\r\n"), nil
1817
// gcc runs the gcc C compiler to create an object from a single C file.
1818
func (b *builder) gcc(p *Package, out string, flags []string, cfile string) error {
1819
return b.ccompile(p, out, flags, cfile, b.gccCmd(p.Dir))
1822
// gxx runs the g++ C++ compiler to create an object from a single C++ file.
1823
func (b *builder) gxx(p *Package, out string, flags []string, cxxfile string) error {
1824
return b.ccompile(p, out, flags, cxxfile, b.gxxCmd(p.Dir))
1827
// ccompile runs the given C or C++ compiler and creates an object from a single source file.
1828
func (b *builder) ccompile(p *Package, out string, flags []string, file string, compiler []string) error {
1829
file = mkAbs(p.Dir, file)
1830
return b.run(p.Dir, p.ImportPath, nil, compiler, flags, "-o", out, "-c", file)
1833
// gccld runs the gcc linker to create an executable from a set of object files.
1834
func (b *builder) gccld(p *Package, out string, flags []string, obj []string) error {
1836
if len(p.CXXFiles) > 0 {
1837
cmd = b.gxxCmd(p.Dir)
1839
cmd = b.gccCmd(p.Dir)
1841
return b.run(p.Dir, p.ImportPath, nil, cmd, "-o", out, obj, flags)
1844
// gccCmd returns a gcc command line prefix
1845
// defaultCC is defined in zdefaultcc.go, written by cmd/dist.
1846
func (b *builder) gccCmd(objdir string) []string {
1847
return b.ccompilerCmd("CC", defaultCC, objdir)
1850
// gxxCmd returns a g++ command line prefix
1851
// defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
1852
func (b *builder) gxxCmd(objdir string) []string {
1853
return b.ccompilerCmd("CXX", defaultCXX, objdir)
1856
// ccompilerCmd returns a command line prefix for the given environment
1857
// variable and using the default command when the variable is empty
1858
func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
1859
// NOTE: env.go's mkEnv knows that the first three
1860
// strings returned are "gcc", "-I", objdir (and cuts them off).
1862
compiler := strings.Fields(os.Getenv(envvar))
1863
if len(compiler) == 0 {
1864
compiler = strings.Fields(defcmd)
1866
a := []string{compiler[0], "-I", objdir, "-g", "-O2"}
1867
a = append(a, compiler[1:]...)
1869
// Definitely want -fPIC but on Windows gcc complains
1870
// "-fPIC ignored for target (all code is position independent)"
1871
if goos != "windows" {
1872
a = append(a, "-fPIC")
1874
a = append(a, b.gccArchArgs()...)
1875
// gcc-4.5 and beyond require explicit "-pthread" flag
1876
// for multithreading with pthread library.
1877
if buildContext.CgoEnabled {
1880
a = append(a, "-mthreads")
1882
a = append(a, "-pthread")
1886
if strings.Contains(a[0], "clang") {
1887
// disable ASCII art in clang errors, if possible
1888
a = append(a, "-fno-caret-diagnostics")
1889
// clang is too smart about command-line arguments
1890
a = append(a, "-Qunused-arguments")
1893
// On OS X, some of the compilers behave as if -fno-common
1894
// is always set, and the Mach-O linker in 6l/8l assumes this.
1895
// See http://golang.org/issue/3253.
1896
if goos == "darwin" {
1897
a = append(a, "-fno-common")
1903
// gccArchArgs returns arguments to pass to gcc based on the architecture.
1904
func (b *builder) gccArchArgs() []string {
1907
return []string{"-m32"}
1909
return []string{"-m64"}
1911
return []string{"-marm"} // not thumb
1916
func envList(key string) []string {
1917
return strings.Fields(os.Getenv(key))
1920
var cgoRe = regexp.MustCompile(`[/\\:]`)
1923
cgoLibGccFile string
1925
cgoLibGccFileOnce sync.Once
1928
func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string, gxxfiles []string) (outGo, outObj []string, err error) {
1929
if goos != toolGOOS {
1930
return nil, nil, errors.New("cannot use cgo when compiling for a different operating system")
1933
cgoCPPFLAGS := stringList(envList("CGO_CPPFLAGS"), p.CgoCPPFLAGS)
1934
cgoCFLAGS := stringList(envList("CGO_CFLAGS"), p.CgoCFLAGS)
1935
cgoCXXFLAGS := stringList(envList("CGO_CXXFLAGS"), p.CgoCXXFLAGS)
1936
cgoLDFLAGS := stringList(envList("CGO_LDFLAGS"), p.CgoLDFLAGS)
1938
if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
1939
out, err := b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--cflags", pkgs)
1941
b.showOutput(p.Dir, "pkg-config --cflags "+strings.Join(pkgs, " "), string(out))
1942
b.print(err.Error() + "\n")
1943
return nil, nil, errPrintedOutput
1946
cgoCPPFLAGS = append(cgoCPPFLAGS, strings.Fields(string(out))...)
1948
out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--libs", pkgs)
1950
b.showOutput(p.Dir, "pkg-config --libs "+strings.Join(pkgs, " "), string(out))
1951
b.print(err.Error() + "\n")
1952
return nil, nil, errPrintedOutput
1955
cgoLDFLAGS = append(cgoLDFLAGS, strings.Fields(string(out))...)
1959
// Allows including _cgo_export.h from .[ch] files in the package.
1960
cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", obj)
1963
// TODO: CGOPKGPATH, CGO_FLAGS?
1964
gofiles := []string{obj + "_cgo_gotypes.go"}
1965
cfiles := []string{"_cgo_main.c", "_cgo_export.c"}
1966
for _, fn := range p.CgoFiles {
1967
f := cgoRe.ReplaceAllString(fn[:len(fn)-2], "_")
1968
gofiles = append(gofiles, obj+f+"cgo1.go")
1969
cfiles = append(cfiles, f+"cgo2.c")
1971
defunC := obj + "_cgo_defun.c"
1973
cgoflags := []string{}
1974
// TODO: make cgo not depend on $GOARCH?
1978
if p.Standard && p.ImportPath == "runtime/cgo" {
1979
cgoflags = append(cgoflags, "-import_runtime_cgo=false")
1981
if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/cgo") {
1982
cgoflags = append(cgoflags, "-import_syscall=false")
1985
// Update $CGO_LDFLAGS with p.CgoLDFLAGS.
1987
if len(cgoLDFLAGS) > 0 {
1988
flags := make([]string, len(cgoLDFLAGS))
1989
for i, f := range cgoLDFLAGS {
1990
flags[i] = strconv.Quote(f)
1992
cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
1995
if _, ok := buildToolchain.(gccgoToolchain); ok {
1996
cgoflags = append(cgoflags, "-gccgo")
1997
if pkgpath := gccgoPkgpath(p); pkgpath != "" {
1998
cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
2002
if err := b.run(p.Dir, p.ImportPath, cgoenv, cgoExe, "-objdir", obj, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, p.CgoFiles); err != nil {
2003
return nil, nil, err
2005
outGo = append(outGo, gofiles...)
2008
defunObj := obj + "_cgo_defun." + objExt
2009
if err := buildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
2010
return nil, nil, err
2012
outObj = append(outObj, defunObj)
2015
var linkobj []string
2017
var bareLDFLAGS []string
2018
// filter out -lsomelib, -l somelib, *.{so,dll,dylib}, and (on Darwin) -framework X
2019
for i := 0; i < len(cgoLDFLAGS); i++ {
2022
// skip "-lc" or "-l somelib"
2023
case strings.HasPrefix(f, "-l"):
2027
// skip "-framework X" on Darwin
2028
case goos == "darwin" && f == "-framework":
2030
// skip "*.{dylib,so,dll}"
2031
case strings.HasSuffix(f, ".dylib"),
2032
strings.HasSuffix(f, ".so"),
2033
strings.HasSuffix(f, ".dll"):
2036
bareLDFLAGS = append(bareLDFLAGS, f)
2040
cgoLibGccFileOnce.Do(func() {
2041
cgoLibGccFile, cgoLibGccErr = b.libgcc(p)
2043
if cgoLibGccFile == "" && cgoLibGccErr != nil {
2044
return nil, nil, err
2047
var staticLibs []string
2048
if goos == "windows" {
2049
// libmingw32 and libmingwex might also use libgcc, so libgcc must come last,
2050
// and they also have some inter-dependencies, so must use linker groups.
2051
staticLibs = []string{"-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group"}
2053
if cgoLibGccFile != "" {
2054
staticLibs = append(staticLibs, cgoLibGccFile)
2057
cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
2058
for _, cfile := range cfiles {
2059
ofile := obj + cfile[:len(cfile)-1] + "o"
2060
if err := b.gcc(p, ofile, cflags, obj+cfile); err != nil {
2061
return nil, nil, err
2063
linkobj = append(linkobj, ofile)
2064
if !strings.HasSuffix(ofile, "_cgo_main.o") {
2065
outObj = append(outObj, ofile)
2069
for _, file := range gccfiles {
2070
ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
2071
if err := b.gcc(p, ofile, cflags, file); err != nil {
2072
return nil, nil, err
2074
linkobj = append(linkobj, ofile)
2075
outObj = append(outObj, ofile)
2078
cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
2079
for _, file := range gxxfiles {
2080
// Append .o to the file, just in case the pkg has file.c and file.cpp
2081
ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
2082
if err := b.gxx(p, ofile, cxxflags, file); err != nil {
2083
return nil, nil, err
2085
linkobj = append(linkobj, ofile)
2086
outObj = append(outObj, ofile)
2089
linkobj = append(linkobj, p.SysoFiles...)
2090
dynobj := obj + "_cgo_.o"
2091
if goarch == "arm" && goos == "linux" { // we need to use -pie for Linux/ARM to get accurate imported sym
2092
cgoLDFLAGS = append(cgoLDFLAGS, "-pie")
2094
if err := b.gccld(p, dynobj, cgoLDFLAGS, linkobj); err != nil {
2095
return nil, nil, err
2097
if goarch == "arm" && goos == "linux" { // but we don't need -pie for normal cgo programs
2098
cgoLDFLAGS = cgoLDFLAGS[0 : len(cgoLDFLAGS)-1]
2101
if _, ok := buildToolchain.(gccgoToolchain); ok {
2102
// we don't use dynimport when using gccgo.
2103
return outGo, outObj, nil
2107
importC := obj + "_cgo_import.c"
2108
cgoflags = []string{}
2109
if p.Standard && p.ImportPath == "runtime/cgo" {
2110
cgoflags = append(cgoflags, "-dynlinker") // record path to dynamic linker
2112
if err := b.run(p.Dir, p.ImportPath, nil, cgoExe, "-objdir", obj, "-dynimport", dynobj, "-dynout", importC, cgoflags); err != nil {
2113
return nil, nil, err
2116
// cc _cgo_import.ARCH
2117
importObj := obj + "_cgo_import." + objExt
2118
if err := buildToolchain.cc(b, p, obj, importObj, importC); err != nil {
2119
return nil, nil, err
2122
ofile := obj + "_all.o"
2123
var gccObjs, nonGccObjs []string
2124
for _, f := range outObj {
2125
if strings.HasSuffix(f, ".o") {
2126
gccObjs = append(gccObjs, f)
2128
nonGccObjs = append(nonGccObjs, f)
2131
if err := b.gccld(p, ofile, stringList(bareLDFLAGS, "-Wl,-r", "-nostdlib", staticLibs), gccObjs); err != nil {
2132
return nil, nil, err
2135
// NOTE(rsc): The importObj is a 5c/6c/8c object and on Windows
2136
// must be processed before the gcc-generated objects.
2137
// Put it first. http://golang.org/issue/2601
2138
outObj = stringList(importObj, nonGccObjs, ofile)
2140
return outGo, outObj, nil
2143
// Run SWIG on all SWIG input files.
2144
// TODO: Don't build a shared library, once SWIG emits the necessary
2145
// pragmas for external linking.
2146
func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles []string) (outGo, outObj []string, err error) {
2148
var extraObj []string
2149
for _, file := range gccfiles {
2150
ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
2151
if err := b.gcc(p, ofile, nil, file); err != nil {
2152
return nil, nil, err
2154
extraObj = append(extraObj, ofile)
2157
for _, file := range gxxfiles {
2158
// Append .o to the file, just in case the pkg has file.c and file.cpp
2159
ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
2160
if err := b.gxx(p, ofile, nil, file); err != nil {
2161
return nil, nil, err
2163
extraObj = append(extraObj, ofile)
2166
intgosize, err := b.swigIntSize(obj)
2168
return nil, nil, err
2171
for _, f := range p.SwigFiles {
2172
goFile, objFile, err := b.swigOne(p, f, obj, false, intgosize, extraObj)
2174
return nil, nil, err
2177
outGo = append(outGo, goFile)
2180
outObj = append(outObj, objFile)
2183
for _, f := range p.SwigCXXFiles {
2184
goFile, objFile, err := b.swigOne(p, f, obj, true, intgosize, extraObj)
2186
return nil, nil, err
2189
outGo = append(outGo, goFile)
2192
outObj = append(outObj, objFile)
2195
return outGo, outObj, nil
2198
// This code fails to build if sizeof(int) <= 32
2199
const swigIntSizeCode = `
2201
const i int = 1 << 32
2204
// Determine the size of int on the target system for the -intgosize option
2206
func (b *builder) swigIntSize(obj string) (intsize string, err error) {
2208
return "$INTBITS", nil
2210
src := filepath.Join(b.work, "swig_intsize.go")
2211
if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0644); err != nil {
2214
srcs := []string{src}
2216
p := goFilesPackage(srcs)
2218
if _, _, e := buildToolchain.gc(b, p, obj, nil, srcs); e != nil {
2224
// Run SWIG on one SWIG input file.
2225
func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize string, extraObj []string) (outGo, outObj string, err error) {
2226
n := 5 // length of ".swig"
2228
n = 8 // length of ".swigcxx"
2230
base := file[:len(file)-n]
2231
goFile := base + ".go"
2232
cBase := base + "_gc."
2233
gccBase := base + "_wrap."
2238
soname := p.swigSoname(file)
2240
_, gccgo := buildToolchain.(gccgoToolchain)
2245
"-intgosize", intgosize,
2248
"-o", obj + gccBase + gccExt,
2252
args = append(args, "-gccgo")
2255
args = append(args, "-c++")
2258
if out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file); err != nil {
2260
if bytes.Contains(out, []byte("Unrecognized option -intgosize")) {
2261
return "", "", errors.New("must have SWIG version >= 2.0.9\n")
2263
b.showOutput(p.Dir, p.ImportPath, b.processOutput(out))
2264
return "", "", errPrintedOutput
2272
cObj = obj + cBase + archChar
2273
if err := buildToolchain.cc(b, p, obj, cObj, obj+cBase+"c"); err != nil {
2279
gccObj := obj + gccBase + "o"
2280
if err := b.gcc(p, gccObj, []string{"-g", "-fPIC", "-O2"}, obj+gccBase+gccExt); err != nil {
2284
// create shared library
2285
osldflags := map[string][]string{
2286
"darwin": {"-dynamiclib", "-Wl,-undefined,dynamic_lookup"},
2287
"freebsd": {"-shared", "-lpthread", "-lm"},
2288
"linux": {"-shared", "-lpthread", "-lm"},
2289
"windows": {"-shared", "-lm", "-mthreads"},
2293
cxxlib = []string{"-lstdc++"}
2295
ldflags := stringList(osldflags[goos], cxxlib)
2296
target := filepath.Join(obj, soname)
2297
b.run(p.Dir, p.ImportPath, nil, b.gccCmd(p.Dir), "-o", target, gccObj, extraObj, ldflags)
2299
return obj + goFile, cObj, nil
2302
// An actionQueue is a priority queue of actions.
2303
type actionQueue []*action
2305
// Implement heap.Interface
2306
func (q *actionQueue) Len() int { return len(*q) }
2307
func (q *actionQueue) Swap(i, j int) { (*q)[i], (*q)[j] = (*q)[j], (*q)[i] }
2308
func (q *actionQueue) Less(i, j int) bool { return (*q)[i].priority < (*q)[j].priority }
2309
func (q *actionQueue) Push(x interface{}) { *q = append(*q, x.(*action)) }
2310
func (q *actionQueue) Pop() interface{} {
2317
func (q *actionQueue) push(a *action) {
2321
func (q *actionQueue) pop() *action {
2322
return heap.Pop(q).(*action)
2329
if goarch != "amd64" || goos != "linux" && goos != "darwin" && goos != "windows" {
2330
fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0])
2333
buildGcflags = append(buildGcflags, "-race")
2334
buildLdflags = append(buildLdflags, "-race")
2335
buildCcflags = append(buildCcflags, "-D", "RACE")
2336
if buildContext.InstallSuffix != "" {
2337
buildContext.InstallSuffix += "_"
2339
buildContext.InstallSuffix += "race"
2340
buildContext.BuildTags = append(buildContext.BuildTags, "race")
2343
// defaultSuffix returns file extension used for command files in
2344
// current os environment.
2345
func defaultSuffix() string {
2346
switch runtime.GOOS {