1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Action graph execution.
27 "cmd/go/internal/base"
28 "cmd/go/internal/cache"
30 "cmd/go/internal/load"
34 // actionList returns the list of actions in the dag rooted at root
35 // as visited in a depth-first post-order traversal.
36 func actionList(root
*Action
) []*Action
{
37 seen
:= map[*Action
]bool{}
39 var walk
func(*Action
)
40 walk
= func(a
*Action
) {
45 for _
, a1
:= range a
.Deps
{
54 // do runs the action graph rooted at root.
55 func (b
*Builder
) Do(root
*Action
) {
56 if c
:= cache
.Default(); c
!= nil && !b
.ComputeStaleOnly
{
57 // If we're doing real work, take time at the end to trim the cache.
61 // Build list of all actions, assigning depth-first post-order priority.
62 // The original implementation here was a true queue
63 // (using a channel) but it had the effect of getting
64 // distracted by low-level leaf actions to the detriment
65 // of completing higher-level actions. The order of
66 // work does not matter much to overall execution time,
67 // but when running "go test std" it is nice to see each test
68 // results as soon as possible. The priorities assigned
69 // ensure that, all else being equal, the execution prefers
70 // to do what it would have done first in a simple depth-first
71 // dependency order traversal.
72 all
:= actionList(root
)
73 for i
, a
:= range all
{
77 if cfg
.DebugActiongraph
!= "" {
78 js
:= actionGraphJSON(root
)
79 if err
:= ioutil
.WriteFile(cfg
.DebugActiongraph
, []byte(js
), 0666); err
!= nil {
80 fmt
.Fprintf(os
.Stderr
, "go: writing action graph: %v\n", err
)
85 b
.readySema
= make(chan bool, len(all
))
87 // Initialize per-action execution state.
88 for _
, a
:= range all
{
89 for _
, a1
:= range a
.Deps
{
90 a1
.triggers
= append(a1
.triggers
, a
)
92 a
.pending
= len(a
.Deps
)
99 // Handle runs a single action and takes care of triggering
100 // any actions that are runnable as a result.
101 handle
:= func(a
*Action
) {
104 if a
.Func
!= nil && (!a
.Failed || a
.IgnoreFail
) {
110 // The actions run in parallel but all the updates to the
111 // shared work state are serialized through b.exec.
113 defer b
.exec
.Unlock()
116 if err
== errPrintedOutput
{
117 base
.SetExitStatus(2)
119 base
.Errorf("%s", err
)
124 for _
, a0
:= range a
.triggers
{
128 if a0
.pending
--; a0
.pending
== 0 {
139 var wg sync
.WaitGroup
141 // Kick off goroutines according to parallelism.
142 // If we are using the -n flag (just printing commands)
143 // drop the parallelism to 1, both to make the output
144 // deterministic and because there is no real work anyway.
149 for i
:= 0; i
< par
; i
++ {
155 case _
, ok
:= <-b
.readySema
:
159 // Receiving a value from b.readySema entitles
160 // us to take from the ready queue.
165 case <-base
.Interrupted
:
166 base
.SetExitStatus(1)
176 // buildActionID computes the action ID for a build action.
177 func (b
*Builder
) buildActionID(a
*Action
) cache
.ActionID
{
179 h
:= cache
.NewHash("build " + p
.ImportPath
)
181 // Configuration independent of compiler toolchain.
182 // Note: buildmode has already been accounted for in buildGcflags
183 // and should not be inserted explicitly. Most buildmodes use the
184 // same compiler settings and can reuse each other's results.
185 // If not, the reason is already recorded in buildGcflags.
186 fmt
.Fprintf(h
, "compile\n")
187 // The compiler hides the exact value of $GOROOT
188 // when building things in GOROOT,
189 // but it does not hide the exact value of $GOPATH.
190 // Include the full dir in that case.
191 // Assume b.WorkDir is being trimmed properly.
192 if !p
.Goroot
&& !strings
.HasPrefix(p
.Dir
, b
.WorkDir
) {
193 fmt
.Fprintf(h
, "dir %s\n", p
.Dir
)
195 fmt
.Fprintf(h
, "goos %s goarch %s\n", cfg
.Goos
, cfg
.Goarch
)
196 fmt
.Fprintf(h
, "import %q\n", p
.ImportPath
)
197 fmt
.Fprintf(h
, "omitdebug %v standard %v local %v prefix %q\n", p
.Internal
.OmitDebug
, p
.Standard
, p
.Internal
.Local
, p
.Internal
.LocalPrefix
)
198 if len(p
.CgoFiles
)+len(p
.SwigFiles
) > 0 {
199 fmt
.Fprintf(h
, "cgo %q\n", b
.toolID("cgo"))
200 cppflags
, cflags
, cxxflags
, fflags
, _
:= b
.CFlags(p
)
201 fmt
.Fprintf(h
, "CC=%q %q %q\n", b
.ccExe(), cppflags
, cflags
)
202 if len(p
.CXXFiles
)+len(p
.SwigFiles
) > 0 {
203 fmt
.Fprintf(h
, "CXX=%q %q\n", b
.cxxExe(), cxxflags
)
205 if len(p
.FFiles
) > 0 {
206 fmt
.Fprintf(h
, "FC=%q %q\n", b
.fcExe(), fflags
)
208 // TODO(rsc): Should we include the SWIG version or Fortran/GCC/G++/Objective-C compiler versions?
210 if p
.Internal
.CoverMode
!= "" {
211 fmt
.Fprintf(h
, "cover %q %q\n", p
.Internal
.CoverMode
, b
.toolID("cover"))
214 // Configuration specific to compiler toolchain.
215 switch cfg
.BuildToolchainName
{
217 base
.Fatalf("buildActionID: unknown build toolchain %q", cfg
.BuildToolchainName
)
219 fmt
.Fprintf(h
, "compile %s %q %q\n", b
.toolID("compile"), forcedGcflags
, p
.Internal
.Gcflags
)
220 if len(p
.SFiles
) > 0 {
221 fmt
.Fprintf(h
, "asm %q %q %q\n", b
.toolID("asm"), forcedAsmflags
, p
.Internal
.Asmflags
)
223 fmt
.Fprintf(h
, "GO$GOARCH=%s\n", os
.Getenv("GO"+strings
.ToUpper(cfg
.BuildContext
.GOARCH
))) // GO386, GOARM, etc
225 // TODO(rsc): Convince compiler team not to add more magic environment variables,
226 // or perhaps restrict the environment variables passed to subprocesses.
230 "GO_SSA_PHI_LOC_CUTOFF",
233 for _
, env
:= range magic
{
234 if x
:= os
.Getenv(env
); x
!= "" {
235 fmt
.Fprintf(h
, "magic %s=%s\n", env
, x
)
238 if os
.Getenv("GOSSAHASH") != "" {
240 env
:= fmt
.Sprintf("GOSSAHASH%d", i
)
245 fmt
.Fprintf(h
, "magic %s=%s\n", env
, x
)
248 if os
.Getenv("GSHS_LOGFILE") != "" {
249 // Clumsy hack. Compiler writes to this log file,
250 // so do not allow use of cache at all.
251 // We will still write to the cache but it will be
252 // essentially unfindable.
253 fmt
.Fprintf(h
, "nocache %d\n", time
.Now().UnixNano())
257 id
, err
:= b
.gccgoToolID(BuildToolchain
.compiler(), "go")
259 base
.Fatalf("%v", err
)
261 fmt
.Fprintf(h
, "compile %s %q %q\n", id
, forcedGccgoflags
, p
.Internal
.Gccgoflags
)
262 fmt
.Fprintf(h
, "pkgpath %s\n", gccgoPkgpath(p
))
263 if len(p
.SFiles
) > 0 {
264 id
, err
= b
.gccgoToolID(BuildToolchain
.compiler(), "assembler-with-cpp")
265 // Ignore error; different assembler versions
266 // are unlikely to make any difference anyhow.
267 fmt
.Fprintf(h
, "asm %q\n", id
)
272 inputFiles
:= str
.StringList(
285 for _
, file
:= range inputFiles
{
286 fmt
.Fprintf(h
, "file %s %s\n", file
, b
.fileHash(filepath
.Join(p
.Dir
, file
)))
288 for _
, a1
:= range a
.Deps
{
291 fmt
.Fprintf(h
, "import %s %s\n", p1
.ImportPath
, contentID(a1
.buildID
))
298 // build is the action for building a single package.
299 // Note that any new influence on this logic must be reported in b.buildActionID above as well.
300 func (b
*Builder
) build(a
*Action
) (err error
) {
304 if b
.useCache(a
, p
, b
.buildActionID(a
), p
.Target
) {
305 // If this build triggers a header install, run cgo to get the header.
306 // TODO(rsc): Once we can cache multiple file outputs from an action,
307 // the header should be cached, and then this awful test can be deleted.
308 // Need to look for install header actions depending on this action,
309 // or depending on a link that depends on this action.
311 if (a
.Package
.UsesCgo() || a
.Package
.UsesSwig()) && (cfg
.BuildBuildmode
== "c-archive" || cfg
.BuildBuildmode
== "c-header") {
312 for _
, t1
:= range a
.triggers
{
313 if t1
.Mode
== "install header" {
318 for _
, t1
:= range a
.triggers
{
319 for _
, t2
:= range t1
.triggers
{
320 if t2
.Mode
== "install header" {
328 if b
.ComputeStaleOnly ||
!a
.needVet
&& !needHeader
{
333 defer b
.flushOutput(a
)
337 if err
!= nil && err
!= errPrintedOutput
{
338 err
= fmt
.Errorf("go build %s: %v", a
.Package
.ImportPath
, err
)
342 // In -n mode, print a banner between packages.
343 // The banner is five lines so that when changes to
344 // different sections of the bootstrap script have to
345 // be merged, the banners give patch something
346 // to use to find its context.
347 b
.Print("\n#\n# " + a
.Package
.ImportPath
+ "\n#\n\n")
351 b
.Print(a
.Package
.ImportPath
+ "\n")
354 if a
.Package
.BinaryOnly
{
355 _
, err
:= os
.Stat(a
.Package
.Target
)
357 a
.built
= a
.Package
.Target
358 a
.Target
= a
.Package
.Target
359 a
.buildID
= b
.fileHash(a
.Package
.Target
)
360 a
.Package
.Stale
= false
361 a
.Package
.StaleReason
= "binary-only package"
364 if b
.ComputeStaleOnly
{
365 a
.Package
.Stale
= true
366 a
.Package
.StaleReason
= "missing or invalid binary-only package"
369 return fmt
.Errorf("missing or invalid binary-only package")
372 if err
:= b
.Mkdir(a
.Objdir
); err
!= nil {
377 // make target directory
378 dir
, _
:= filepath
.Split(a
.Target
)
380 if err
:= b
.Mkdir(dir
); err
!= nil {
385 var gofiles
, cgofiles
, cfiles
, sfiles
, cxxfiles
, objects
, cgoObjects
, pcCFLAGS
, pcLDFLAGS
[]string
387 gofiles
= append(gofiles
, a
.Package
.GoFiles
...)
388 cgofiles
= append(cgofiles
, a
.Package
.CgoFiles
...)
389 cfiles
= append(cfiles
, a
.Package
.CFiles
...)
390 sfiles
= append(sfiles
, a
.Package
.SFiles
...)
391 cxxfiles
= append(cxxfiles
, a
.Package
.CXXFiles
...)
393 if a
.Package
.UsesCgo() || a
.Package
.UsesSwig() {
394 if pcCFLAGS
, pcLDFLAGS
, err
= b
.getPkgConfigFlags(a
.Package
); err
!= nil {
399 // Run SWIG on each .swig and .swigcxx file.
400 // Each run will generate two files, a .go file and a .c or .cxx file.
401 // The .go file will use import "C" and is to be processed by cgo.
402 if a
.Package
.UsesSwig() {
403 outGo
, outC
, outCXX
, err
:= b
.swig(a
, a
.Package
, objdir
, pcCFLAGS
)
407 cgofiles
= append(cgofiles
, outGo
...)
408 cfiles
= append(cfiles
, outC
...)
409 cxxfiles
= append(cxxfiles
, outCXX
...)
412 // If we're doing coverage, preprocess the .go files and put them in the work directory
413 if a
.Package
.Internal
.CoverMode
!= "" {
414 for i
, file
:= range str
.StringList(gofiles
, cgofiles
) {
415 var sourceFile
string
418 if strings
.HasSuffix(file
, ".cgo1.go") {
419 // cgo files have absolute paths
420 base
:= filepath
.Base(file
)
422 coverFile
= objdir
+ base
423 key
= strings
.TrimSuffix(base
, ".cgo1.go") + ".go"
425 sourceFile
= filepath
.Join(a
.Package
.Dir
, file
)
426 coverFile
= objdir
+ file
429 coverFile
= strings
.TrimSuffix(coverFile
, ".go") + ".cover.go"
430 cover
:= a
.Package
.Internal
.CoverVars
[key
]
431 if cover
== nil || base
.IsTestFile(file
) {
432 // Not covering this file.
435 if err
:= b
.cover(a
, coverFile
, sourceFile
, 0666, cover
.Var
); err
!= nil {
438 if i
< len(gofiles
) {
439 gofiles
[i
] = coverFile
441 cgofiles
[i
-len(gofiles
)] = coverFile
447 if a
.Package
.UsesCgo() || a
.Package
.UsesSwig() {
448 // In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
449 // There is one exception: runtime/cgo's job is to bridge the
450 // cgo and non-cgo worlds, so it necessarily has files in both.
451 // In that case gcc only gets the gcc_* files.
452 var gccfiles
[]string
453 gccfiles
= append(gccfiles
, cfiles
...)
455 if a
.Package
.Standard
&& a
.Package
.ImportPath
== "runtime/cgo" {
456 filter
:= func(files
, nongcc
, gcc
[]string) ([]string, []string) {
457 for _
, f
:= range files
{
458 if strings
.HasPrefix(f
, "gcc_") {
461 nongcc
= append(nongcc
, f
)
466 sfiles
, gccfiles
= filter(sfiles
, sfiles
[:0], gccfiles
)
468 for _
, sfile
:= range sfiles
{
469 data
, err
:= ioutil
.ReadFile(filepath
.Join(a
.Package
.Dir
, sfile
))
471 if bytes
.HasPrefix(data
, []byte("TEXT")) || bytes
.Contains(data
, []byte("\nTEXT")) ||
472 bytes
.HasPrefix(data
, []byte("DATA")) || bytes
.Contains(data
, []byte("\nDATA")) ||
473 bytes
.HasPrefix(data
, []byte("GLOBL")) || bytes
.Contains(data
, []byte("\nGLOBL")) {
474 return fmt
.Errorf("package using cgo has Go assembly file %s", sfile
)
478 gccfiles
= append(gccfiles
, sfiles
...)
482 outGo
, outObj
, err
:= b
.cgo(a
, base
.Tool("cgo"), objdir
, pcCFLAGS
, pcLDFLAGS
, mkAbsFiles(a
.Package
.Dir
, cgofiles
), gccfiles
, cxxfiles
, a
.Package
.MFiles
, a
.Package
.FFiles
)
486 if cfg
.BuildToolchainName
== "gccgo" {
487 cgoObjects
= append(cgoObjects
, a
.Objdir
+"_cgo_flags")
489 cgoObjects
= append(cgoObjects
, outObj
...)
490 gofiles
= append(gofiles
, outGo
...)
492 if cached
&& !a
.needVet
{
496 // Sanity check only, since Package.load already checked as well.
497 if len(gofiles
) == 0 {
498 return &load
.NoGoError
{Package
: a
.Package
}
501 // Prepare Go vet config if needed.
504 // Pass list of absolute paths to vet,
505 // so that vet's error messages will use absolute paths,
506 // so that we can reformat them relative to the directory
507 // in which the go command is invoked.
509 Compiler
: cfg
.BuildToolchainName
,
511 GoFiles
: mkAbsFiles(a
.Package
.Dir
, gofiles
),
512 ImportMap
: make(map[string]string),
513 PackageFile
: make(map[string]string),
516 for i
, raw
:= range a
.Package
.Internal
.RawImports
{
517 final
:= a
.Package
.Imports
[i
]
518 vcfg
.ImportMap
[raw
] = final
522 // Prepare Go import config.
523 var icfg bytes
.Buffer
524 for i
, raw
:= range a
.Package
.Internal
.RawImports
{
525 final
:= a
.Package
.Imports
[i
]
527 fmt
.Fprintf(&icfg
, "importmap %s=%s\n", raw
, final
)
531 // Compute the list of mapped imports in the vet config
532 // so that we can add any missing mappings below.
533 var vcfgMapped
map[string]bool
535 vcfgMapped
= make(map[string]bool)
536 for _
, p
:= range vcfg
.ImportMap
{
541 for _
, a1
:= range a
.Deps
{
543 if p1
== nil || p1
.ImportPath
== "" || a1
.built
== "" {
546 fmt
.Fprintf(&icfg
, "packagefile %s=%s\n", p1
.ImportPath
, a1
.built
)
548 // Add import mapping if needed
549 // (for imports like "runtime/cgo" that appear only in generated code).
550 if !vcfgMapped
[p1
.ImportPath
] {
551 vcfg
.ImportMap
[p1
.ImportPath
] = p1
.ImportPath
553 vcfg
.PackageFile
[p1
.ImportPath
] = a1
.built
558 // The cached package file is OK, so we don't need to run the compile.
559 // We've only going through the motions to prepare the vet configuration,
560 // which is now complete.
565 objpkg
:= objdir
+ "_pkg_.a"
566 ofile
, out
, err
:= BuildToolchain
.gc(b
, a
, objpkg
, icfg
.Bytes(), len(sfiles
) > 0, gofiles
)
568 b
.showOutput(a
, a
.Package
.Dir
, a
.Package
.ImportPath
, b
.processOutput(out
))
570 return errPrintedOutput
577 objects
= append(objects
, ofile
)
580 // Copy .h files named for goos or goarch or goos_goarch
581 // to names using GOOS and GOARCH.
582 // For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
583 _goos_goarch
:= "_" + cfg
.Goos
+ "_" + cfg
.Goarch
584 _goos
:= "_" + cfg
.Goos
585 _goarch
:= "_" + cfg
.Goarch
586 for _
, file
:= range a
.Package
.HFiles
{
587 name
, ext
:= fileExtSplit(file
)
589 case strings
.HasSuffix(name
, _goos_goarch
):
590 targ
:= file
[:len(name
)-len(_goos_goarch
)] + "_GOOS_GOARCH." + ext
591 if err
:= b
.copyFile(a
, objdir
+targ
, filepath
.Join(a
.Package
.Dir
, file
), 0666, true); err
!= nil {
594 case strings
.HasSuffix(name
, _goarch
):
595 targ
:= file
[:len(name
)-len(_goarch
)] + "_GOARCH." + ext
596 if err
:= b
.copyFile(a
, objdir
+targ
, filepath
.Join(a
.Package
.Dir
, file
), 0666, true); err
!= nil {
599 case strings
.HasSuffix(name
, _goos
):
600 targ
:= file
[:len(name
)-len(_goos
)] + "_GOOS." + ext
601 if err
:= b
.copyFile(a
, objdir
+targ
, filepath
.Join(a
.Package
.Dir
, file
), 0666, true); err
!= nil {
607 for _
, file
:= range cfiles
{
608 out
:= file
[:len(file
)-len(".c")] + ".o"
609 if err
:= BuildToolchain
.cc(b
, a
, objdir
+out
, file
); err
!= nil {
612 objects
= append(objects
, out
)
615 // Assemble .s files.
617 ofiles
, err
:= BuildToolchain
.asm(b
, a
, sfiles
)
621 objects
= append(objects
, ofiles
...)
624 // For gccgo on ELF systems, we write the build ID as an assembler file.
625 // This lets us set the the SHF_EXCLUDE flag.
626 // This is read by readGccgoArchive in cmd/internal/buildid/buildid.go.
627 if a
.buildID
!= "" && cfg
.BuildToolchainName
== "gccgo" {
629 case "android", "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
630 asmfile
, err
:= b
.gccgoBuildIDELFFile(a
)
634 ofiles
, err
:= BuildToolchain
.asm(b
, a
, []string{asmfile
})
638 objects
= append(objects
, ofiles
...)
642 // NOTE(rsc): On Windows, it is critically important that the
643 // gcc-compiled objects (cgoObjects) be listed after the ordinary
644 // objects in the archive. I do not know why this is.
645 // https://golang.org/issue/2601
646 objects
= append(objects
, cgoObjects
...)
648 // Add system object files.
649 for _
, syso
:= range a
.Package
.SysoFiles
{
650 objects
= append(objects
, filepath
.Join(a
.Package
.Dir
, syso
))
653 // Pack into archive in objdir directory.
654 // If the Go compiler wrote an archive, we only need to add the
655 // object files for non-Go sources to the archive.
656 // If the Go compiler wrote an archive and the package is entirely
657 // Go sources, there is no pack to execute at all.
658 if len(objects
) > 0 {
659 if err
:= BuildToolchain
.pack(b
, a
, objpkg
, objects
); err
!= nil {
664 if err
:= b
.updateBuildID(a
, objpkg
, true); err
!= nil {
672 type vetConfig
struct {
676 ImportMap
map[string]string
677 PackageFile
map[string]string
679 SucceedOnTypecheckFailure
bool
682 // VetFlags are the flags to pass to vet.
683 // The caller is expected to set them before executing any vet actions.
684 var VetFlags
[]string
686 func (b
*Builder
) vet(a
*Action
) error
{
687 // a.Deps[0] is the build of the package being vetted.
688 // a.Deps[1] is the build of the "fmt" package.
690 vcfg
:= a
.Deps
[0].vetCfg
692 // Vet config should only be missing if the build failed.
693 if !a
.Deps
[0].Failed
{
694 return fmt
.Errorf("vet config not found")
699 if vcfg
.ImportMap
["fmt"] == "" {
701 vcfg
.ImportMap
["fmt"] = "fmt"
702 vcfg
.PackageFile
["fmt"] = a1
.built
705 // During go test, ignore type-checking failures during vet.
706 // We only run vet if the compilation has succeeded,
707 // so at least for now assume the bug is in vet.
708 // We know of at least #18395.
709 // TODO(rsc,gri): Try to remove this for Go 1.11.
710 vcfg
.SucceedOnTypecheckFailure
= cfg
.CmdName
== "test"
712 js
, err
:= json
.MarshalIndent(vcfg
, "", "\t")
714 return fmt
.Errorf("internal error marshaling vet config: %v", err
)
716 js
= append(js
, '\n')
717 if err
:= b
.writeFile(a
.Objdir
+"vet.cfg", js
); err
!= nil {
722 if cfg
.BuildToolchainName
== "gccgo" {
723 env
= append(env
, "GCCGO="+BuildToolchain
.compiler())
727 return b
.run(a
, p
.Dir
, p
.ImportPath
, env
, cfg
.BuildToolexec
, base
.Tool("vet"), VetFlags
, a
.Objdir
+"vet.cfg")
730 // linkActionID computes the action ID for a link action.
731 func (b
*Builder
) linkActionID(a
*Action
) cache
.ActionID
{
733 h
:= cache
.NewHash("link " + p
.ImportPath
)
735 // Toolchain-independent configuration.
736 fmt
.Fprintf(h
, "link\n")
737 fmt
.Fprintf(h
, "buildmode %s goos %s goarch %s\n", cfg
.BuildBuildmode
, cfg
.Goos
, cfg
.Goarch
)
738 fmt
.Fprintf(h
, "import %q\n", p
.ImportPath
)
739 fmt
.Fprintf(h
, "omitdebug %v standard %v local %v prefix %q\n", p
.Internal
.OmitDebug
, p
.Standard
, p
.Internal
.Local
, p
.Internal
.LocalPrefix
)
741 // Toolchain-dependent configuration, shared with b.linkSharedActionID.
742 b
.printLinkerConfig(h
, p
)
745 for _
, a1
:= range a
.Deps
{
748 if a1
.built
!= "" || a1
.buildID
!= "" {
749 buildID
:= a1
.buildID
751 buildID
= b
.buildID(a1
.built
)
753 fmt
.Fprintf(h
, "packagefile %s=%s\n", p1
.ImportPath
, contentID(buildID
))
755 // Because we put package main's full action ID into the binary's build ID,
756 // we must also put the full action ID into the binary's action ID hash.
757 if p1
.Name
== "main" {
758 fmt
.Fprintf(h
, "packagemain %s\n", a1
.buildID
)
761 fmt
.Fprintf(h
, "packageshlib %s=%s\n", p1
.ImportPath
, contentID(b
.buildID(p1
.Shlib
)))
769 // printLinkerConfig prints the linker config into the hash h,
770 // as part of the computation of a linker-related action ID.
771 func (b
*Builder
) printLinkerConfig(h io
.Writer
, p
*load
.Package
) {
772 switch cfg
.BuildToolchainName
{
774 base
.Fatalf("linkActionID: unknown toolchain %q", cfg
.BuildToolchainName
)
777 fmt
.Fprintf(h
, "link %s %q %s\n", b
.toolID("link"), forcedLdflags
, ldBuildmode
)
779 fmt
.Fprintf(h
, "linkflags %q\n", p
.Internal
.Ldflags
)
781 fmt
.Fprintf(h
, "GO$GOARCH=%s\n", os
.Getenv("GO"+strings
.ToUpper(cfg
.BuildContext
.GOARCH
))) // GO386, GOARM, etc
784 // TODO(rsc): Enable this code.
785 // golang.org/issue/22475.
786 goroot := cfg.BuildContext.GOROOT
787 if final := os.Getenv("GOROOT_FINAL"); final != "" {
790 fmt.Fprintf(h, "GOROOT=%s\n", goroot)
793 // TODO(rsc): Convince linker team not to add more magic environment variables,
794 // or perhaps restrict the environment variables passed to subprocesses.
796 "GO_EXTLINK_ENABLED",
798 for _
, env
:= range magic
{
799 if x
:= os
.Getenv(env
); x
!= "" {
800 fmt
.Fprintf(h
, "magic %s=%s\n", env
, x
)
804 // TODO(rsc): Do cgo settings and flags need to be included?
805 // Or external linker settings and flags?
808 id
, err
:= b
.gccgoToolID(BuildToolchain
.linker(), "go")
810 base
.Fatalf("%v", err
)
812 fmt
.Fprintf(h
, "link %s %s\n", id
, ldBuildmode
)
813 // TODO(iant): Should probably include cgo flags here.
817 // link is the action for linking a single command.
818 // Note that any new influence on this logic must be reported in b.linkActionID above as well.
819 func (b
*Builder
) link(a
*Action
) (err error
) {
820 if b
.useCache(a
, a
.Package
, b
.linkActionID(a
), a
.Package
.Target
) {
823 defer b
.flushOutput(a
)
825 if err
:= b
.Mkdir(a
.Objdir
); err
!= nil {
829 importcfg
:= a
.Objdir
+ "importcfg.link"
830 if err
:= b
.writeLinkImportcfg(a
, importcfg
); err
!= nil {
834 // make target directory
835 dir
, _
:= filepath
.Split(a
.Target
)
837 if err
:= b
.Mkdir(dir
); err
!= nil {
842 if err
:= BuildToolchain
.ld(b
, a
, a
.Target
, importcfg
, a
.Deps
[0].built
); err
!= nil {
846 // Update the binary with the final build ID.
847 // But if OmitDebug is set, don't rewrite the binary, because we set OmitDebug
848 // on binaries that we are going to run and then delete.
849 // There's no point in doing work on such a binary.
850 // Worse, opening the binary for write here makes it
851 // essentially impossible to safely fork+exec due to a fundamental
852 // incompatibility between ETXTBSY and threads on modern Unix systems.
853 // See golang.org/issue/22220.
854 // We still call updateBuildID to update a.buildID, which is important
855 // for test result caching, but passing rewrite=false (final arg)
856 // means we don't actually rewrite the binary, nor store the
857 // result into the cache.
858 // Not calling updateBuildID means we also don't insert these
859 // binaries into the build object cache. That's probably a net win:
860 // less cache space wasted on large binaries we are not likely to
861 // need again. (On the other hand it does make repeated go test slower.)
862 if err
:= b
.updateBuildID(a
, a
.Target
, !a
.Package
.Internal
.OmitDebug
); err
!= nil {
870 func (b
*Builder
) writeLinkImportcfg(a
*Action
, file
string) error
{
871 // Prepare Go import cfg.
872 var icfg bytes
.Buffer
873 for _
, a1
:= range a
.Deps
{
878 fmt
.Fprintf(&icfg
, "packagefile %s=%s\n", p1
.ImportPath
, a1
.built
)
880 fmt
.Fprintf(&icfg
, "packageshlib %s=%s\n", p1
.ImportPath
, p1
.Shlib
)
883 return b
.writeFile(file
, icfg
.Bytes())
886 // PkgconfigCmd returns a pkg-config binary name
887 // defaultPkgConfig is defined in zdefaultcc.go, written by cmd/dist.
888 func (b
*Builder
) PkgconfigCmd() string {
889 return envList("PKG_CONFIG", cfg
.DefaultPkgConfig
)[0]
892 // splitPkgConfigOutput parses the pkg-config output into a slice of
893 // flags. pkg-config always uses \ to escape special characters.
894 func splitPkgConfigOutput(out
[]byte) []string {
899 flag
:= make([]byte, len(out
))
903 case ' ', '\t', '\r', '\n':
905 flags
= append(flags
, string(flag
[:w
]))
920 flags
= append(flags
, string(flag
[:w
]))
925 // Calls pkg-config if needed and returns the cflags/ldflags needed to build the package.
926 func (b
*Builder
) getPkgConfigFlags(p
*load
.Package
) (cflags
, ldflags
[]string, err error
) {
927 if pkgs
:= p
.CgoPkgConfig
; len(pkgs
) > 0 {
929 out
, err
= b
.runOut(p
.Dir
, p
.ImportPath
, nil, b
.PkgconfigCmd(), "--cflags", pkgs
)
931 b
.showOutput(nil, p
.Dir
, b
.PkgconfigCmd()+" --cflags "+strings
.Join(pkgs
, " "), string(out
))
932 b
.Print(err
.Error() + "\n")
933 err
= errPrintedOutput
937 cflags
= splitPkgConfigOutput(out
)
939 out
, err
= b
.runOut(p
.Dir
, p
.ImportPath
, nil, b
.PkgconfigCmd(), "--libs", pkgs
)
941 b
.showOutput(nil, p
.Dir
, b
.PkgconfigCmd()+" --libs "+strings
.Join(pkgs
, " "), string(out
))
942 b
.Print(err
.Error() + "\n")
943 err
= errPrintedOutput
947 ldflags
= strings
.Fields(string(out
))
953 func (b
*Builder
) installShlibname(a
*Action
) error
{
956 err
:= ioutil
.WriteFile(a
.Target
, []byte(filepath
.Base(a1
.Target
)+"\n"), 0666)
961 b
.Showcmd("", "echo '%s' > %s # internal", filepath
.Base(a1
.Target
), a
.Target
)
966 func (b
*Builder
) linkSharedActionID(a
*Action
) cache
.ActionID
{
967 h
:= cache
.NewHash("linkShared")
969 // Toolchain-independent configuration.
970 fmt
.Fprintf(h
, "linkShared\n")
971 fmt
.Fprintf(h
, "goos %s goarch %s\n", cfg
.Goos
, cfg
.Goarch
)
973 // Toolchain-dependent configuration, shared with b.linkActionID.
974 b
.printLinkerConfig(h
, nil)
977 for _
, a1
:= range a
.Deps
{
983 fmt
.Fprintf(h
, "packagefile %s=%s\n", p1
.ImportPath
, contentID(b
.buildID(a1
.built
)))
985 fmt
.Fprintf(h
, "packageshlib %s=%s\n", p1
.ImportPath
, contentID(b
.buildID(p1
.Shlib
)))
989 // Files named on command line are special.
990 for _
, a1
:= range a
.Deps
[0].Deps
{
992 fmt
.Fprintf(h
, "top %s=%s\n", p1
.ImportPath
, contentID(b
.buildID(a1
.built
)))
998 func (b
*Builder
) linkShared(a
*Action
) (err error
) {
999 if b
.useCache(a
, nil, b
.linkSharedActionID(a
), a
.Target
) {
1002 defer b
.flushOutput(a
)
1004 if err
:= b
.Mkdir(a
.Objdir
); err
!= nil {
1008 importcfg
:= a
.Objdir
+ "importcfg.link"
1009 if err
:= b
.writeLinkImportcfg(a
, importcfg
); err
!= nil {
1013 // TODO(rsc): There is a missing updateBuildID here,
1014 // but we have to decide where to store the build ID in these files.
1016 return BuildToolchain
.ldShared(b
, a
, a
.Deps
[0].Deps
, a
.Target
, importcfg
, a
.Deps
)
1019 // BuildInstallFunc is the action for installing a single package or executable.
1020 func BuildInstallFunc(b
*Builder
, a
*Action
) (err error
) {
1022 if err
!= nil && err
!= errPrintedOutput
{
1023 // a.Package == nil is possible for the go install -buildmode=shared
1024 // action that installs libmangledname.so, which corresponds to
1025 // a list of packages, not just one.
1027 if a
.Package
!= nil {
1028 sep
, path
= " ", a
.Package
.ImportPath
1030 err
= fmt
.Errorf("go %s%s%s: %v", cfg
.CmdName
, sep
, path
, err
)
1035 a
.buildID
= a1
.buildID
1037 // If we are using the eventual install target as an up-to-date
1038 // cached copy of the thing we built, then there's no need to
1039 // copy it into itself (and that would probably fail anyway).
1040 // In this case a1.built == a.Target because a1.built == p.Target,
1041 // so the built target is not in the a1.Objdir tree that b.cleanup(a1) removes.
1042 if a1
.built
== a
.Target
{
1045 // Whether we're smart enough to avoid a complete rebuild
1046 // depends on exactly what the staleness and rebuild algorithms
1047 // are, as well as potentially the state of the Go build cache.
1048 // We don't really want users to be able to infer (or worse start depending on)
1049 // those details from whether the modification time changes during
1050 // "go install", so do a best-effort update of the file times to make it
1051 // look like we rewrote a.Target even if we did not. Updating the mtime
1052 // may also help other mtime-based systems that depend on our
1053 // previous mtime updates that happened more often.
1054 // This is still not perfect - we ignore the error result, and if the file was
1055 // unwritable for some reason then pretending to have written it is also
1056 // confusing - but it's probably better than not doing the mtime update.
1058 // But don't do that for the special case where building an executable
1059 // with -linkshared implicitly installs all its dependent libraries.
1060 // We want to hide that awful detail as much as possible, so don't
1061 // advertise it by touching the mtimes (usually the libraries are up
1063 if !a
.buggyInstall
{
1065 os
.Chtimes(a
.Target
, now
, now
)
1069 if b
.ComputeStaleOnly
{
1073 if err
:= b
.Mkdir(a
.Objdir
); err
!= nil {
1077 perm
:= os
.FileMode(0666)
1078 if a1
.Mode
== "link" {
1079 switch cfg
.BuildBuildmode
{
1080 case "c-archive", "c-shared", "plugin":
1086 // make target directory
1087 dir
, _
:= filepath
.Split(a
.Target
)
1089 if err
:= b
.Mkdir(dir
); err
!= nil {
1096 return b
.moveOrCopyFile(a
, a
.Target
, a1
.built
, perm
, false)
1099 // cleanup removes a's object dir to keep the amount of
1100 // on-disk garbage down in a large build. On an operating system
1101 // with aggressive buffering, cleaning incrementally like
1102 // this keeps the intermediate objects from hitting the disk.
1103 func (b
*Builder
) cleanup(a
*Action
) {
1106 b
.Showcmd("", "rm -r %s", a
.Objdir
)
1108 os
.RemoveAll(a
.Objdir
)
1112 // moveOrCopyFile is like 'mv src dst' or 'cp src dst'.
1113 func (b
*Builder
) moveOrCopyFile(a
*Action
, dst
, src
string, perm os
.FileMode
, force
bool) error
{
1115 b
.Showcmd("", "mv %s %s", src
, dst
)
1119 // If we can update the mode and rename to the dst, do it.
1120 // Otherwise fall back to standard copy.
1122 // If the source is in the build cache, we need to copy it.
1123 if strings
.HasPrefix(src
, cache
.DefaultDir()) {
1124 return b
.copyFile(a
, dst
, src
, perm
, force
)
1127 // On Windows, always copy the file, so that we respect the NTFS
1128 // permissions of the parent folder. https://golang.org/issue/22343.
1129 // What matters here is not cfg.Goos (the system we are building
1130 // for) but runtime.GOOS (the system we are building on).
1131 if runtime
.GOOS
== "windows" {
1132 return b
.copyFile(a
, dst
, src
, perm
, force
)
1135 // If the destination directory has the group sticky bit set,
1136 // we have to copy the file to retain the correct permissions.
1137 // https://golang.org/issue/18878
1138 if fi
, err
:= os
.Stat(filepath
.Dir(dst
)); err
== nil {
1139 if fi
.IsDir() && (fi
.Mode()&os
.ModeSetgid
) != 0 {
1140 return b
.copyFile(a
, dst
, src
, perm
, force
)
1144 // The perm argument is meant to be adjusted according to umask,
1145 // but we don't know what the umask is.
1146 // Create a dummy file to find out.
1147 // This avoids build tags and works even on systems like Plan 9
1148 // where the file mask computation incorporates other information.
1150 f
, err
:= os
.OpenFile(filepath
.Clean(dst
)+"-go-tmp-umask", os
.O_WRONLY|os
.O_CREATE|os
.O_EXCL
, perm
)
1154 mode
= fi
.Mode() & 0777
1161 if err
:= os
.Chmod(src
, mode
); err
== nil {
1162 if err
:= os
.Rename(src
, dst
); err
== nil {
1164 b
.Showcmd("", "mv %s %s", src
, dst
)
1170 return b
.copyFile(a
, dst
, src
, perm
, force
)
1173 // copyFile is like 'cp src dst'.
1174 func (b
*Builder
) copyFile(a
*Action
, dst
, src
string, perm os
.FileMode
, force
bool) error
{
1175 if cfg
.BuildN || cfg
.BuildX
{
1176 b
.Showcmd("", "cp %s %s", src
, dst
)
1182 sf
, err
:= os
.Open(src
)
1188 // Be careful about removing/overwriting dst.
1189 // Do not remove/overwrite if dst exists and is a directory
1190 // or a non-object file.
1191 if fi
, err
:= os
.Stat(dst
); err
== nil {
1193 return fmt
.Errorf("build output %q already exists and is a directory", dst
)
1195 if !force
&& fi
.Mode().IsRegular() && !isObject(dst
) {
1196 return fmt
.Errorf("build output %q already exists and is not an object file", dst
)
1200 // On Windows, remove lingering ~ file from last attempt.
1201 if base
.ToolIsWindows
{
1202 if _
, err
:= os
.Stat(dst
+ "~"); err
== nil {
1203 os
.Remove(dst
+ "~")
1207 mayberemovefile(dst
)
1208 df
, err
:= os
.OpenFile(dst
, os
.O_WRONLY|os
.O_CREATE|os
.O_TRUNC
, perm
)
1209 if err
!= nil && base
.ToolIsWindows
{
1210 // Windows does not allow deletion of a binary file
1211 // while it is executing. Try to move it out of the way.
1212 // If the move fails, which is likely, we'll try again the
1213 // next time we do an install of this binary.
1214 if err
:= os
.Rename(dst
, dst
+"~"); err
== nil {
1215 os
.Remove(dst
+ "~")
1217 df
, err
= os
.OpenFile(dst
, os
.O_WRONLY|os
.O_CREATE|os
.O_TRUNC
, perm
)
1223 _
, err
= io
.Copy(df
, sf
)
1226 mayberemovefile(dst
)
1227 return fmt
.Errorf("copying %s to %s: %v", src
, dst
, err
)
1232 // writeFile writes the text to file.
1233 func (b
*Builder
) writeFile(file
string, text
[]byte) error
{
1234 if cfg
.BuildN || cfg
.BuildX
{
1235 b
.Showcmd("", "cat >%s << 'EOF' # internal\n%sEOF", file
, text
)
1240 return ioutil
.WriteFile(file
, text
, 0666)
1243 // Install the cgo export header file, if there is one.
1244 func (b
*Builder
) installHeader(a
*Action
) error
{
1245 src
:= a
.Objdir
+ "_cgo_install.h"
1246 if _
, err
:= os
.Stat(src
); os
.IsNotExist(err
) {
1247 // If the file does not exist, there are no exported
1248 // functions, and we do not install anything.
1249 // TODO(rsc): Once we know that caching is rebuilding
1250 // at the right times (not missing rebuilds), here we should
1251 // probably delete the installed header, if any.
1253 b
.Showcmd("", "# %s not created", src
)
1258 dir
, _
:= filepath
.Split(a
.Target
)
1260 if err
:= b
.Mkdir(dir
); err
!= nil {
1265 return b
.moveOrCopyFile(a
, a
.Target
, src
, 0666, true)
1268 // cover runs, in effect,
1269 // go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
1270 func (b
*Builder
) cover(a
*Action
, dst
, src
string, perm os
.FileMode
, varName
string) error
{
1271 return b
.run(a
, a
.Objdir
, "cover "+a
.Package
.ImportPath
, nil,
1274 "-mode", a
.Package
.Internal
.CoverMode
,
1280 var objectMagic
= [][]byte{
1281 {'!', '<', 'a', 'r', 'c', 'h', '>', '\n'}, // Package archive
1282 {'\x7F', 'E', 'L', 'F'}, // ELF
1283 {0xFE, 0xED, 0xFA, 0xCE}, // Mach-O big-endian 32-bit
1284 {0xFE, 0xED, 0xFA, 0xCF}, // Mach-O big-endian 64-bit
1285 {0xCE, 0xFA, 0xED, 0xFE}, // Mach-O little-endian 32-bit
1286 {0xCF, 0xFA, 0xED, 0xFE}, // Mach-O little-endian 64-bit
1287 {0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00}, // PE (Windows) as generated by 6l/8l and gcc
1288 {0x00, 0x00, 0x01, 0xEB}, // Plan 9 i386
1289 {0x00, 0x00, 0x8a, 0x97}, // Plan 9 amd64
1290 {0x00, 0x00, 0x06, 0x47}, // Plan 9 arm
1293 func isObject(s
string) bool {
1294 f
, err
:= os
.Open(s
)
1299 buf
:= make([]byte, 64)
1301 for _
, magic
:= range objectMagic
{
1302 if bytes
.HasPrefix(buf
, magic
) {
1309 // mayberemovefile removes a file only if it is a regular file
1310 // When running as a user with sufficient privileges, we may delete
1311 // even device files, for example, which is not intended.
1312 func mayberemovefile(s
string) {
1313 if fi
, err
:= os
.Lstat(s
); err
== nil && !fi
.Mode().IsRegular() {
1319 // fmtcmd formats a command in the manner of fmt.Sprintf but also:
1321 // If dir is non-empty and the script is not in dir right now,
1322 // fmtcmd inserts "cd dir\n" before the command.
1324 // fmtcmd replaces the value of b.WorkDir with $WORK.
1325 // fmtcmd replaces the value of goroot with $GOROOT.
1326 // fmtcmd replaces the value of b.gobin with $GOBIN.
1328 // fmtcmd replaces the name of the current directory with dot (.)
1329 // but only when it is at the beginning of a space-separated token.
1331 func (b
*Builder
) fmtcmd(dir
string, format
string, args
...interface{}) string {
1332 cmd
:= fmt
.Sprintf(format
, args
...)
1333 if dir
!= "" && dir
!= "/" {
1335 if dir
[len(dir
)-1] == filepath
.Separator
{
1336 to
+= string(filepath
.Separator
)
1338 cmd
= strings
.Replace(" "+cmd
, " "+dir
, " "+to
, -1)[1:]
1339 if b
.scriptDir
!= dir
{
1341 cmd
= "cd " + dir
+ "\n" + cmd
1344 if b
.WorkDir
!= "" {
1345 cmd
= strings
.Replace(cmd
, b
.WorkDir
, "$WORK", -1)
1350 // showcmd prints the given command to standard output
1351 // for the implementation of -n or -x.
1352 func (b
*Builder
) Showcmd(dir
string, format
string, args
...interface{}) {
1354 defer b
.output
.Unlock()
1355 b
.Print(b
.fmtcmd(dir
, format
, args
...) + "\n")
1358 // showOutput prints "# desc" followed by the given output.
1359 // The output is expected to contain references to 'dir', usually
1360 // the source directory for the package that has failed to build.
1361 // showOutput rewrites mentions of dir with a relative path to dir
1362 // when the relative path is shorter. This is usually more pleasant.
1363 // For example, if fmt doesn't compile and we are in src/html,
1368 // ../fmt/print.go:1090: undefined: asdf
1375 // /usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
1378 // showOutput also replaces references to the work directory with $WORK.
1380 // If a is not nil and a.output is not nil, showOutput appends to that slice instead of
1381 // printing to b.Print.
1383 func (b
*Builder
) showOutput(a
*Action
, dir
, desc
, out
string) {
1384 prefix
:= "# " + desc
1385 suffix
:= "\n" + out
1386 if reldir
:= base
.ShortPath(dir
); reldir
!= dir
{
1387 suffix
= strings
.Replace(suffix
, " "+dir
, " "+reldir
, -1)
1388 suffix
= strings
.Replace(suffix
, "\n"+dir
, "\n"+reldir
, -1)
1390 suffix
= strings
.Replace(suffix
, " "+b
.WorkDir
, " $WORK", -1)
1392 if a
!= nil && a
.output
!= nil {
1393 a
.output
= append(a
.output
, prefix
...)
1394 a
.output
= append(a
.output
, suffix
...)
1399 defer b
.output
.Unlock()
1400 b
.Print(prefix
, suffix
)
1403 // errPrintedOutput is a special error indicating that a command failed
1404 // but that it generated output as well, and that output has already
1405 // been printed, so there's no point showing 'exit status 1' or whatever
1406 // the wait status was. The main executor, builder.do, knows not to
1407 // print this error.
1408 var errPrintedOutput
= errors
.New("already printed output - no need to show error")
1410 var cgoLine
= regexp
.MustCompile(`\[[^\[\]]+\.(cgo1|cover)\.go:[0-9]+(:[0-9]+)?\]`)
1411 var cgoTypeSigRe
= regexp
.MustCompile(`\b_C2?(type|func|var|macro)_\B`)
1413 // run runs the command given by cmdline in the directory dir.
1414 // If the command fails, run prints information about the failure
1415 // and returns a non-nil error.
1416 func (b
*Builder
) run(a
*Action
, dir
string, desc
string, env
[]string, cmdargs
...interface{}) error
{
1417 out
, err
:= b
.runOut(dir
, desc
, env
, cmdargs
...)
1420 desc
= b
.fmtcmd(dir
, "%s", strings
.Join(str
.StringList(cmdargs
...), " "))
1422 b
.showOutput(a
, dir
, desc
, b
.processOutput(out
))
1424 err
= errPrintedOutput
1430 // processOutput prepares the output of runOut to be output to the console.
1431 func (b
*Builder
) processOutput(out
[]byte) string {
1432 if out
[len(out
)-1] != '\n' {
1433 out
= append(out
, '\n')
1435 messages
:= string(out
)
1436 // Fix up output referring to cgo-generated code to be more readable.
1437 // Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
1438 // Replace *[100]_Ctype_foo with *[100]C.foo.
1439 // If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
1440 if !cfg
.BuildX
&& cgoLine
.MatchString(messages
) {
1441 messages
= cgoLine
.ReplaceAllString(messages
, "")
1442 messages
= cgoTypeSigRe
.ReplaceAllString(messages
, "C.")
1447 // runOut runs the command given by cmdline in the directory dir.
1448 // It returns the command output and any errors that occurred.
1449 func (b
*Builder
) runOut(dir
string, desc
string, env
[]string, cmdargs
...interface{}) ([]byte, error
) {
1450 cmdline
:= str
.StringList(cmdargs
...)
1451 if cfg
.BuildN || cfg
.BuildX
{
1452 var envcmdline
string
1453 for _
, e
:= range env
{
1454 if j
:= strings
.IndexByte(e
, '='); j
!= -1 {
1455 if strings
.ContainsRune(e
[j
+1:], '\'') {
1456 envcmdline
+= fmt
.Sprintf("%s=%q", e
[:j
], e
[j
+1:])
1458 envcmdline
+= fmt
.Sprintf("%s='%s'", e
[:j
], e
[j
+1:])
1463 envcmdline
+= joinUnambiguously(cmdline
)
1464 b
.Showcmd(dir
, "%s", envcmdline
)
1470 var buf bytes
.Buffer
1471 cmd
:= exec
.Command(cmdline
[0], cmdline
[1:]...)
1475 cmd
.Env
= base
.MergeEnvLists(env
, base
.EnvForDir(cmd
.Dir
, os
.Environ()))
1478 // err can be something like 'exit status 1'.
1479 // Add information about what program was running.
1480 // Note that if buf.Bytes() is non-empty, the caller usually
1481 // shows buf.Bytes() and does not print err at all, so the
1482 // prefix here does not make most output any more verbose.
1484 err
= errors
.New(cmdline
[0] + ": " + err
.Error())
1486 return buf
.Bytes(), err
1489 // joinUnambiguously prints the slice, quoting where necessary to make the
1490 // output unambiguous.
1491 // TODO: See issue 5279. The printing of commands needs a complete redo.
1492 func joinUnambiguously(a
[]string) string {
1493 var buf bytes
.Buffer
1494 for i
, s
:= range a
{
1498 q
:= strconv
.Quote(s
)
1499 if s
== "" || strings
.ContainsAny(s
, " ()") ||
len(q
) > len(s
)+2 {
1508 // mkdir makes the named directory.
1509 func (b
*Builder
) Mkdir(dir
string) error
{
1510 // Make Mkdir(a.Objdir) a no-op instead of an error when a.Objdir == "".
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 cfg
.BuildN || cfg
.BuildX
{
1525 b
.Showcmd("", "mkdir -p %s", dir
)
1531 if err
:= os
.MkdirAll(dir
, 0777); err
!= nil {
1537 // symlink creates a symlink newname -> oldname.
1538 func (b
*Builder
) Symlink(oldname
, newname
string) error
{
1539 if cfg
.BuildN || cfg
.BuildX
{
1540 b
.Showcmd("", "ln -sf %s %s", oldname
, newname
)
1546 return os
.Symlink(oldname
, newname
)
1549 // mkAbs returns an absolute path corresponding to
1550 // evaluating f in the directory dir.
1551 // We always pass absolute paths of source files so that
1552 // the error messages will include the full path to a file
1553 // in need of attention.
1554 func mkAbs(dir
, f
string) string {
1555 // Leave absolute paths alone.
1556 // Also, during -n mode we use the pseudo-directory $WORK
1557 // instead of creating an actual work directory that won't be used.
1558 // Leave paths beginning with $WORK alone too.
1559 if filepath
.IsAbs(f
) || strings
.HasPrefix(f
, "$WORK") {
1562 return filepath
.Join(dir
, f
)
1565 type toolchain
interface {
1566 // gc runs the compiler in a specific directory on a set of files
1567 // and returns the name of the generated output file.
1568 gc(b
*Builder
, a
*Action
, archive
string, importcfg
[]byte, asmhdr
bool, gofiles
[]string) (ofile
string, out
[]byte, err error
)
1569 // cc runs the toolchain's C compiler in a directory on a C file
1570 // to produce an output file.
1571 cc(b
*Builder
, a
*Action
, ofile
, cfile
string) error
1572 // asm runs the assembler in a specific directory on specific files
1573 // and returns a list of named output files.
1574 asm(b
*Builder
, a
*Action
, sfiles
[]string) ([]string, error
)
1575 // pack runs the archive packer in a specific directory to create
1576 // an archive from a set of object files.
1577 // typically it is run in the object directory.
1578 pack(b
*Builder
, a
*Action
, afile
string, ofiles
[]string) error
1579 // ld runs the linker to create an executable starting at mainpkg.
1580 ld(b
*Builder
, root
*Action
, out
, importcfg
, mainpkg
string) error
1581 // ldShared runs the linker to create a shared library containing the pkgs built by toplevelactions
1582 ldShared(b
*Builder
, root
*Action
, toplevelactions
[]*Action
, out
, importcfg
string, allactions
[]*Action
) error
1588 type noToolchain
struct{}
1590 func noCompiler() error
{
1591 log
.Fatalf("unknown compiler %q", cfg
.BuildContext
.Compiler
)
1595 func (noToolchain
) compiler() string {
1600 func (noToolchain
) linker() string {
1605 func (noToolchain
) gc(b
*Builder
, a
*Action
, archive
string, importcfg
[]byte, asmhdr
bool, gofiles
[]string) (ofile
string, out
[]byte, err error
) {
1606 return "", nil, noCompiler()
1609 func (noToolchain
) asm(b
*Builder
, a
*Action
, sfiles
[]string) ([]string, error
) {
1610 return nil, noCompiler()
1613 func (noToolchain
) pack(b
*Builder
, a
*Action
, afile
string, ofiles
[]string) error
{
1617 func (noToolchain
) ld(b
*Builder
, root
*Action
, out
, importcfg
, mainpkg
string) error
{
1621 func (noToolchain
) ldShared(b
*Builder
, root
*Action
, toplevelactions
[]*Action
, out
, importcfg
string, allactions
[]*Action
) error
{
1625 func (noToolchain
) cc(b
*Builder
, a
*Action
, ofile
, cfile
string) error
{
1629 // gcc runs the gcc C compiler to create an object from a single C file.
1630 func (b
*Builder
) gcc(a
*Action
, p
*load
.Package
, workdir
, out
string, flags
[]string, cfile
string) error
{
1631 return b
.ccompile(a
, p
, out
, flags
, cfile
, b
.GccCmd(p
.Dir
, workdir
))
1634 // gxx runs the g++ C++ compiler to create an object from a single C++ file.
1635 func (b
*Builder
) gxx(a
*Action
, p
*load
.Package
, workdir
, out
string, flags
[]string, cxxfile
string) error
{
1636 return b
.ccompile(a
, p
, out
, flags
, cxxfile
, b
.GxxCmd(p
.Dir
, workdir
))
1639 // gfortran runs the gfortran Fortran compiler to create an object from a single Fortran file.
1640 func (b
*Builder
) gfortran(a
*Action
, p
*load
.Package
, workdir
, out
string, flags
[]string, ffile
string) error
{
1641 return b
.ccompile(a
, p
, out
, flags
, ffile
, b
.gfortranCmd(p
.Dir
, workdir
))
1644 // ccompile runs the given C or C++ compiler and creates an object from a single source file.
1645 func (b
*Builder
) ccompile(a
*Action
, p
*load
.Package
, outfile
string, flags
[]string, file
string, compiler
[]string) error
{
1646 file
= mkAbs(p
.Dir
, file
)
1647 desc
:= p
.ImportPath
1648 if !filepath
.IsAbs(outfile
) {
1649 outfile
= filepath
.Join(p
.Dir
, outfile
)
1651 output
, err
:= b
.runOut(filepath
.Dir(file
), desc
, nil, compiler
, flags
, "-o", outfile
, "-c", filepath
.Base(file
))
1652 if len(output
) > 0 {
1653 // On FreeBSD 11, when we pass -g to clang 3.8 it
1654 // invokes its internal assembler with -dwarf-version=2.
1655 // When it sees .section .note.GNU-stack, it warns
1656 // "DWARF2 only supports one section per compilation unit".
1657 // This warning makes no sense, since the section is empty,
1658 // but it confuses people.
1659 // We work around the problem by detecting the warning
1660 // and dropping -g and trying again.
1661 if bytes
.Contains(output
, []byte("DWARF2 only supports one section per compilation unit")) {
1662 newFlags
:= make([]string, 0, len(flags
))
1663 for _
, f
:= range flags
{
1664 if !strings
.HasPrefix(f
, "-g") {
1665 newFlags
= append(newFlags
, f
)
1668 if len(newFlags
) < len(flags
) {
1669 return b
.ccompile(a
, p
, outfile
, newFlags
, file
, compiler
)
1673 b
.showOutput(a
, p
.Dir
, desc
, b
.processOutput(output
))
1675 err
= errPrintedOutput
1676 } else if os
.Getenv("GO_BUILDER_NAME") != "" {
1677 return errors
.New("C compiler warning promoted to error on Go builders")
1683 // gccld runs the gcc linker to create an executable from a set of object files.
1684 func (b
*Builder
) gccld(p
*load
.Package
, objdir
, out
string, flags
[]string, objs
[]string) error
{
1686 if len(p
.CXXFiles
) > 0 ||
len(p
.SwigCXXFiles
) > 0 {
1687 cmd
= b
.GxxCmd(p
.Dir
, objdir
)
1689 cmd
= b
.GccCmd(p
.Dir
, objdir
)
1691 return b
.run(nil, p
.Dir
, p
.ImportPath
, nil, cmd
, "-o", out
, objs
, flags
)
1694 // Grab these before main helpfully overwrites them.
1696 origCC
= os
.Getenv("CC")
1697 origCXX
= os
.Getenv("CXX")
1700 // gccCmd returns a gcc command line prefix
1701 // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
1702 func (b
*Builder
) GccCmd(incdir
, workdir
string) []string {
1703 return b
.compilerCmd(b
.ccExe(), incdir
, workdir
)
1706 // gxxCmd returns a g++ command line prefix
1707 // defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
1708 func (b
*Builder
) GxxCmd(incdir
, workdir
string) []string {
1709 return b
.compilerCmd(b
.cxxExe(), incdir
, workdir
)
1712 // gfortranCmd returns a gfortran command line prefix.
1713 func (b
*Builder
) gfortranCmd(incdir
, workdir
string) []string {
1714 return b
.compilerCmd(b
.fcExe(), incdir
, workdir
)
1717 // ccExe returns the CC compiler setting without all the extra flags we add implicitly.
1718 func (b
*Builder
) ccExe() []string {
1719 return b
.compilerExe(origCC
, cfg
.DefaultCC(cfg
.Goos
, cfg
.Goarch
))
1722 // cxxExe returns the CXX compiler setting without all the extra flags we add implicitly.
1723 func (b
*Builder
) cxxExe() []string {
1724 return b
.compilerExe(origCXX
, cfg
.DefaultCXX(cfg
.Goos
, cfg
.Goarch
))
1727 // fcExe returns the FC compiler setting without all the extra flags we add implicitly.
1728 func (b
*Builder
) fcExe() []string {
1729 return b
.compilerExe(os
.Getenv("FC"), "gfortran")
1732 // compilerExe returns the compiler to use given an
1733 // environment variable setting (the value not the name)
1734 // and a default. The resulting slice is usually just the name
1735 // of the compiler but can have additional arguments if they
1736 // were present in the environment value.
1737 // For example if CC="gcc -DGOPHER" then the result is ["gcc", "-DGOPHER"].
1738 func (b
*Builder
) compilerExe(envValue
string, def
string) []string {
1739 compiler
:= strings
.Fields(envValue
)
1740 if len(compiler
) == 0 {
1741 compiler
= []string{def
}
1746 // compilerCmd returns a command line prefix for the given environment
1747 // variable and using the default command when the variable is empty.
1748 func (b
*Builder
) compilerCmd(compiler
[]string, incdir
, workdir
string) []string {
1749 // NOTE: env.go's mkEnv knows that the first three
1750 // strings returned are "gcc", "-I", incdir (and cuts them off).
1751 a
:= []string{compiler
[0], "-I", incdir
}
1752 a
= append(a
, compiler
[1:]...)
1754 // Definitely want -fPIC but on Windows gcc complains
1755 // "-fPIC ignored for target (all code is position independent)"
1756 if cfg
.Goos
!= "windows" {
1757 a
= append(a
, "-fPIC")
1759 a
= append(a
, b
.gccArchArgs()...)
1760 // gcc-4.5 and beyond require explicit "-pthread" flag
1761 // for multithreading with pthread library.
1762 if cfg
.BuildContext
.CgoEnabled
{
1765 a
= append(a
, "-mthreads")
1767 a
= append(a
, "-pthread")
1771 // disable ASCII art in clang errors, if possible
1772 if b
.gccSupportsFlag(compiler
, "-fno-caret-diagnostics") {
1773 a
= append(a
, "-fno-caret-diagnostics")
1775 // clang is too smart about command-line arguments
1776 if b
.gccSupportsFlag(compiler
, "-Qunused-arguments") {
1777 a
= append(a
, "-Qunused-arguments")
1780 // disable word wrapping in error messages
1781 a
= append(a
, "-fmessage-length=0")
1783 // Tell gcc not to include the work directory in object files.
1784 if b
.gccSupportsFlag(compiler
, "-fdebug-prefix-map=a=b") {
1788 workdir
= strings
.TrimSuffix(workdir
, string(filepath
.Separator
))
1789 a
= append(a
, "-fdebug-prefix-map="+workdir
+"=/tmp/go-build")
1792 // Tell gcc not to include flags in object files, which defeats the
1793 // point of -fdebug-prefix-map above.
1794 if b
.gccSupportsFlag(compiler
, "-gno-record-gcc-switches") {
1795 a
= append(a
, "-gno-record-gcc-switches")
1798 // On OS X, some of the compilers behave as if -fno-common
1799 // is always set, and the Mach-O linker in 6l/8l assumes this.
1800 // See https://golang.org/issue/3253.
1801 if cfg
.Goos
== "darwin" {
1802 a
= append(a
, "-fno-common")
1805 // gccgo uses the language-independent exception mechanism to
1806 // handle panics, so it always needs unwind tables.
1807 if cfg
.BuildToolchainName
== "gccgo" {
1808 a
= append(a
, "-funwind-tables")
1814 // gccNoPie returns the flag to use to request non-PIE. On systems
1815 // with PIE (position independent executables) enabled by default,
1816 // -no-pie must be passed when doing a partial link with -Wl,-r.
1817 // But -no-pie is not supported by all compilers, and clang spells it -nopie.
1818 func (b
*Builder
) gccNoPie(linker
[]string) string {
1819 if b
.gccSupportsFlag(linker
, "-no-pie") {
1822 if b
.gccSupportsFlag(linker
, "-nopie") {
1828 // gccSupportsFlag checks to see if the compiler supports a flag.
1829 func (b
*Builder
) gccSupportsFlag(compiler
[]string, flag
string) bool {
1830 key
:= [2]string{compiler
[0], flag
}
1833 defer b
.exec
.Unlock()
1834 if b
, ok
:= b
.flagCache
[key
]; ok
{
1837 if b
.flagCache
== nil {
1838 b
.flagCache
= make(map[[2]string]bool)
1840 // We used to write an empty C file, but that gets complicated with
1841 // go build -n. We tried using a file that does not exist, but that
1842 // fails on systems with GCC version 4.2.1; that is the last GPLv2
1843 // version of GCC, so some systems have frozen on it.
1844 // Now we pass an empty file on stdin, which should work at least for
1846 cmdArgs
:= str
.StringList(compiler
, flag
, "-c", "-x", "c", "-")
1847 if cfg
.BuildN || cfg
.BuildX
{
1848 b
.Showcmd(b
.WorkDir
, "%s", joinUnambiguously(cmdArgs
))
1853 cmd
:= exec
.Command(cmdArgs
[0], cmdArgs
[1:]...)
1855 cmd
.Env
= base
.MergeEnvLists([]string{"LC_ALL=C"}, base
.EnvForDir(cmd
.Dir
, os
.Environ()))
1856 out
, _
:= cmd
.CombinedOutput()
1857 // GCC says "unrecognized command line option".
1858 // clang says "unknown argument".
1859 // Older versions of GCC say "unrecognised debug output level".
1860 // For -fsplit-stack GCC says "'-fsplit-stack' is not supported".
1861 supported
:= !bytes
.Contains(out
, []byte("unrecognized")) &&
1862 !bytes
.Contains(out
, []byte("unknown")) &&
1863 !bytes
.Contains(out
, []byte("unrecognised")) &&
1864 !bytes
.Contains(out
, []byte("is not supported"))
1865 b
.flagCache
[key
] = supported
1869 // gccArchArgs returns arguments to pass to gcc based on the architecture.
1870 func (b
*Builder
) gccArchArgs() []string {
1873 return []string{"-m32"}
1874 case "amd64", "amd64p32":
1875 return []string{"-m64"}
1877 return []string{"-marm"} // not thumb
1879 return []string{"-m64", "-march=z196"}
1880 case "mips64", "mips64le":
1881 return []string{"-mabi=64"}
1882 case "mips", "mipsle":
1883 return []string{"-mabi=32", "-march=mips32"}
1885 if cfg
.Goos
== "aix" {
1886 return []string{"-maix64"}
1892 // envList returns the value of the given environment variable broken
1893 // into fields, using the default value when the variable is empty.
1894 func envList(key
, def
string) []string {
1899 return strings
.Fields(v
)
1902 // CFlags returns the flags to use when invoking the C, C++ or Fortran compilers, or cgo.
1903 func (b
*Builder
) CFlags(p
*load
.Package
) (cppflags
, cflags
, cxxflags
, fflags
, ldflags
[]string) {
1904 defaults
:= "-g -O2"
1906 cppflags
= str
.StringList(envList("CGO_CPPFLAGS", ""), p
.CgoCPPFLAGS
)
1907 cflags
= str
.StringList(envList("CGO_CFLAGS", defaults
), p
.CgoCFLAGS
)
1908 cxxflags
= str
.StringList(envList("CGO_CXXFLAGS", defaults
), p
.CgoCXXFLAGS
)
1909 fflags
= str
.StringList(envList("CGO_FFLAGS", defaults
), p
.CgoFFLAGS
)
1910 ldflags
= str
.StringList(envList("CGO_LDFLAGS", defaults
), p
.CgoLDFLAGS
)
1914 var cgoRe
= regexp
.MustCompile(`[/\\:]`)
1916 func (b
*Builder
) cgo(a
*Action
, cgoExe
, objdir
string, pcCFLAGS
, pcLDFLAGS
, cgofiles
, gccfiles
, gxxfiles
, mfiles
, ffiles
[]string) (outGo
, outObj
[]string, err error
) {
1918 cgoCPPFLAGS
, cgoCFLAGS
, cgoCXXFLAGS
, cgoFFLAGS
, cgoLDFLAGS
:= b
.CFlags(p
)
1919 cgoCPPFLAGS
= append(cgoCPPFLAGS
, pcCFLAGS
...)
1920 cgoLDFLAGS
= append(cgoLDFLAGS
, pcLDFLAGS
...)
1921 // If we are compiling Objective-C code, then we need to link against libobjc
1922 if len(mfiles
) > 0 {
1923 cgoLDFLAGS
= append(cgoLDFLAGS
, "-lobjc")
1926 // Likewise for Fortran, except there are many Fortran compilers.
1927 // Support gfortran out of the box and let others pass the correct link options
1929 if len(ffiles
) > 0 {
1930 fc
:= os
.Getenv("FC")
1934 if strings
.Contains(fc
, "gfortran") {
1935 cgoLDFLAGS
= append(cgoLDFLAGS
, "-lgfortran")
1940 cgoCFLAGS
= append([]string{"-fsanitize=memory"}, cgoCFLAGS
...)
1941 cgoLDFLAGS
= append([]string{"-fsanitize=memory"}, cgoLDFLAGS
...)
1944 // Allows including _cgo_export.h from .[ch] files in the package.
1945 cgoCPPFLAGS
= append(cgoCPPFLAGS
, "-I", objdir
)
1949 gofiles
:= []string{objdir
+ "_cgo_gotypes.go"}
1950 cfiles
:= []string{"_cgo_export.c"}
1951 for _
, fn
:= range cgofiles
{
1952 f
:= strings
.TrimSuffix(filepath
.Base(fn
), ".go")
1953 gofiles
= append(gofiles
, objdir
+f
+".cgo1.go")
1954 cfiles
= append(cfiles
, f
+".cgo2.c")
1957 // TODO: make cgo not depend on $GOARCH?
1959 cgoflags
:= []string{}
1960 if p
.Standard
&& p
.ImportPath
== "runtime/cgo" {
1961 cgoflags
= append(cgoflags
, "-import_runtime_cgo=false")
1963 if p
.Standard
&& (p
.ImportPath
== "runtime/race" || p
.ImportPath
== "runtime/msan" || p
.ImportPath
== "runtime/cgo") {
1964 cgoflags
= append(cgoflags
, "-import_syscall=false")
1967 // Update $CGO_LDFLAGS with p.CgoLDFLAGS.
1969 if len(cgoLDFLAGS
) > 0 {
1970 flags
:= make([]string, len(cgoLDFLAGS
))
1971 for i
, f
:= range cgoLDFLAGS
{
1972 flags
[i
] = strconv
.Quote(f
)
1974 cgoenv
= []string{"CGO_LDFLAGS=" + strings
.Join(flags
, " ")}
1977 if cfg
.BuildToolchainName
== "gccgo" {
1978 if b
.gccSupportsFlag([]string{BuildToolchain
.compiler()}, "-fsplit-stack") {
1979 cgoCFLAGS
= append(cgoCFLAGS
, "-fsplit-stack")
1981 cgoflags
= append(cgoflags
, "-gccgo")
1982 if pkgpath
:= gccgoPkgpath(p
); pkgpath
!= "" {
1983 cgoflags
= append(cgoflags
, "-gccgopkgpath="+pkgpath
)
1987 switch cfg
.BuildBuildmode
{
1988 case "c-archive", "c-shared":
1989 // Tell cgo that if there are any exported functions
1990 // it should generate a header file that C code can
1992 cgoflags
= append(cgoflags
, "-exportheader="+objdir
+"_cgo_install.h")
1995 if err
:= b
.run(a
, p
.Dir
, p
.ImportPath
, cgoenv
, cfg
.BuildToolexec
, cgoExe
, "-objdir", objdir
, "-importpath", p
.ImportPath
, cgoflags
, "--", cgoCPPFLAGS
, cgoCFLAGS
, cgofiles
); err
!= nil {
1996 return nil, nil, err
1998 outGo
= append(outGo
, gofiles
...)
2000 // Use sequential object file names to keep them distinct
2001 // and short enough to fit in the .a header file name slots.
2002 // We no longer collect them all into _all.o, and we'd like
2003 // tools to see both the .o suffix and unique names, so
2004 // we need to make them short enough not to be truncated
2005 // in the final archive.
2007 nextOfile
:= func() string {
2009 return objdir
+ fmt
.Sprintf("_x%03d.o", oseq
)
2013 cflags
:= str
.StringList(cgoCPPFLAGS
, cgoCFLAGS
)
2014 for _
, cfile
:= range cfiles
{
2015 ofile
:= nextOfile()
2016 if err
:= b
.gcc(a
, p
, a
.Objdir
, ofile
, cflags
, objdir
+cfile
); err
!= nil {
2017 return nil, nil, err
2019 outObj
= append(outObj
, ofile
)
2022 for _
, file
:= range gccfiles
{
2023 ofile
:= nextOfile()
2024 if err
:= b
.gcc(a
, p
, a
.Objdir
, ofile
, cflags
, file
); err
!= nil {
2025 return nil, nil, err
2027 outObj
= append(outObj
, ofile
)
2030 cxxflags
:= str
.StringList(cgoCPPFLAGS
, cgoCXXFLAGS
)
2031 for _
, file
:= range gxxfiles
{
2032 ofile
:= nextOfile()
2033 if err
:= b
.gxx(a
, p
, a
.Objdir
, ofile
, cxxflags
, file
); err
!= nil {
2034 return nil, nil, err
2036 outObj
= append(outObj
, ofile
)
2039 for _
, file
:= range mfiles
{
2040 ofile
:= nextOfile()
2041 if err
:= b
.gcc(a
, p
, a
.Objdir
, ofile
, cflags
, file
); err
!= nil {
2042 return nil, nil, err
2044 outObj
= append(outObj
, ofile
)
2047 fflags
:= str
.StringList(cgoCPPFLAGS
, cgoFFLAGS
)
2048 for _
, file
:= range ffiles
{
2049 ofile
:= nextOfile()
2050 if err
:= b
.gfortran(a
, p
, a
.Objdir
, ofile
, fflags
, file
); err
!= nil {
2051 return nil, nil, err
2053 outObj
= append(outObj
, ofile
)
2056 switch cfg
.BuildToolchainName
{
2058 importGo
:= objdir
+ "_cgo_import.go"
2059 if err
:= b
.dynimport(a
, p
, objdir
, importGo
, cgoExe
, cflags
, cgoLDFLAGS
, outObj
); err
!= nil {
2060 return nil, nil, err
2062 outGo
= append(outGo
, importGo
)
2065 defunC
:= objdir
+ "_cgo_defun.c"
2066 defunObj
:= objdir
+ "_cgo_defun.o"
2067 if err
:= BuildToolchain
.cc(b
, a
, defunObj
, defunC
); err
!= nil {
2068 return nil, nil, err
2070 outObj
= append(outObj
, defunObj
)
2076 return outGo
, outObj
, nil
2079 // dynimport creates a Go source file named importGo containing
2080 // //go:cgo_import_dynamic directives for each symbol or library
2081 // dynamically imported by the object files outObj.
2082 func (b
*Builder
) dynimport(a
*Action
, p
*load
.Package
, objdir
, importGo
, cgoExe
string, cflags
, cgoLDFLAGS
, outObj
[]string) error
{
2083 cfile
:= objdir
+ "_cgo_main.c"
2084 ofile
:= objdir
+ "_cgo_main.o"
2085 if err
:= b
.gcc(a
, p
, objdir
, ofile
, cflags
, cfile
); err
!= nil {
2089 linkobj
:= str
.StringList(ofile
, outObj
, p
.SysoFiles
)
2090 dynobj
:= objdir
+ "_cgo_.o"
2092 // we need to use -pie for Linux/ARM to get accurate imported sym
2093 ldflags
:= cgoLDFLAGS
2094 if (cfg
.Goarch
== "arm" && cfg
.Goos
== "linux") || cfg
.Goos
== "android" {
2095 ldflags
= append(ldflags
, "-pie")
2097 if err
:= b
.gccld(p
, objdir
, dynobj
, ldflags
, linkobj
); err
!= nil {
2102 var cgoflags
[]string
2103 if p
.Standard
&& p
.ImportPath
== "runtime/cgo" {
2104 cgoflags
= []string{"-dynlinker"} // record path to dynamic linker
2106 return b
.run(a
, p
.Dir
, p
.ImportPath
, nil, cfg
.BuildToolexec
, cgoExe
, "-dynpackage", p
.Name
, "-dynimport", dynobj
, "-dynout", importGo
, cgoflags
)
2109 // Run SWIG on all SWIG input files.
2110 // TODO: Don't build a shared library, once SWIG emits the necessary
2111 // pragmas for external linking.
2112 func (b
*Builder
) swig(a
*Action
, p
*load
.Package
, objdir
string, pcCFLAGS
[]string) (outGo
, outC
, outCXX
[]string, err error
) {
2113 if err
:= b
.swigVersionCheck(); err
!= nil {
2114 return nil, nil, nil, err
2117 intgosize
, err
:= b
.swigIntSize(objdir
)
2119 return nil, nil, nil, err
2122 for _
, f
:= range p
.SwigFiles
{
2123 goFile
, cFile
, err
:= b
.swigOne(a
, p
, f
, objdir
, pcCFLAGS
, false, intgosize
)
2125 return nil, nil, nil, err
2128 outGo
= append(outGo
, goFile
)
2131 outC
= append(outC
, cFile
)
2134 for _
, f
:= range p
.SwigCXXFiles
{
2135 goFile
, cxxFile
, err
:= b
.swigOne(a
, p
, f
, objdir
, pcCFLAGS
, true, intgosize
)
2137 return nil, nil, nil, err
2140 outGo
= append(outGo
, goFile
)
2143 outCXX
= append(outCXX
, cxxFile
)
2146 return outGo
, outC
, outCXX
, nil
2149 // Make sure SWIG is new enough.
2151 swigCheckOnce sync
.Once
2155 func (b
*Builder
) swigDoVersionCheck() error
{
2156 out
, err
:= b
.runOut("", "", nil, "swig", "-version")
2160 re
:= regexp
.MustCompile(`[vV]ersion +([\d]+)([.][\d]+)?([.][\d]+)?`)
2161 matches
:= re
.FindSubmatch(out
)
2163 // Can't find version number; hope for the best.
2167 major
, err
:= strconv
.Atoi(string(matches
[1]))
2169 // Can't find version number; hope for the best.
2172 const errmsg
= "must have SWIG version >= 3.0.6"
2174 return errors
.New(errmsg
)
2181 // We have SWIG version 3.x.
2182 if len(matches
[2]) > 0 {
2183 minor
, err
:= strconv
.Atoi(string(matches
[2][1:]))
2193 // We have SWIG version 3.0.x.
2194 if len(matches
[3]) > 0 {
2195 patch
, err
:= strconv
.Atoi(string(matches
[3][1:]))
2201 return errors
.New(errmsg
)
2208 func (b
*Builder
) swigVersionCheck() error
{
2209 swigCheckOnce
.Do(func() {
2210 swigCheck
= b
.swigDoVersionCheck()
2215 // Find the value to pass for the -intgosize option to swig.
2217 swigIntSizeOnce sync
.Once
2219 swigIntSizeError error
2222 // This code fails to build if sizeof(int) <= 32
2223 const swigIntSizeCode
= `
2225 const i int = 1 << 32
2228 // Determine the size of int on the target system for the -intgosize option
2229 // of swig >= 2.0.9. Run only once.
2230 func (b
*Builder
) swigDoIntSize(objdir
string) (intsize
string, err error
) {
2232 return "$INTBITS", nil
2234 src
:= filepath
.Join(b
.WorkDir
, "swig_intsize.go")
2235 if err
= ioutil
.WriteFile(src
, []byte(swigIntSizeCode
), 0666); err
!= nil {
2238 srcs
:= []string{src
}
2240 p
:= load
.GoFilesPackage(srcs
)
2242 if _
, _
, e
:= BuildToolchain
.gc(b
, &Action
{Mode
: "swigDoIntSize", Package
: p
, Objdir
: objdir
}, "", nil, false, srcs
); e
!= nil {
2248 // Determine the size of int on the target system for the -intgosize option
2249 // of swig >= 2.0.9.
2250 func (b
*Builder
) swigIntSize(objdir
string) (intsize
string, err error
) {
2251 swigIntSizeOnce
.Do(func() {
2252 swigIntSize
, swigIntSizeError
= b
.swigDoIntSize(objdir
)
2254 return swigIntSize
, swigIntSizeError
2257 // Run SWIG on one SWIG input file.
2258 func (b
*Builder
) swigOne(a
*Action
, p
*load
.Package
, file
, objdir
string, pcCFLAGS
[]string, cxx
bool, intgosize
string) (outGo
, outC
string, err error
) {
2259 cgoCPPFLAGS
, cgoCFLAGS
, cgoCXXFLAGS
, _
, _
:= b
.CFlags(p
)
2262 cflags
= str
.StringList(cgoCPPFLAGS
, pcCFLAGS
, cgoCXXFLAGS
)
2264 cflags
= str
.StringList(cgoCPPFLAGS
, pcCFLAGS
, cgoCFLAGS
)
2267 n
:= 5 // length of ".swig"
2269 n
= 8 // length of ".swigcxx"
2271 base
:= file
[:len(file
)-n
]
2272 goFile
:= base
+ ".go"
2273 gccBase
:= base
+ "_wrap."
2279 gccgo
:= cfg
.BuildToolchainName
== "gccgo"
2285 "-intgosize", intgosize
,
2287 "-o", objdir
+ gccBase
+ gccExt
,
2291 for _
, f
:= range cflags
{
2292 if len(f
) > 3 && f
[:2] == "-I" {
2293 args
= append(args
, f
)
2298 args
= append(args
, "-gccgo")
2299 if pkgpath
:= gccgoPkgpath(p
); pkgpath
!= "" {
2300 args
= append(args
, "-go-pkgpath", pkgpath
)
2304 args
= append(args
, "-c++")
2307 out
, err
:= b
.runOut(p
.Dir
, p
.ImportPath
, nil, "swig", args
, file
)
2310 if bytes
.Contains(out
, []byte("-intgosize")) || bytes
.Contains(out
, []byte("-cgo")) {
2311 return "", "", errors
.New("must have SWIG version >= 3.0.6")
2313 b
.showOutput(a
, p
.Dir
, p
.ImportPath
, b
.processOutput(out
)) // swig error
2314 return "", "", errPrintedOutput
2319 b
.showOutput(a
, p
.Dir
, p
.ImportPath
, b
.processOutput(out
)) // swig warning
2322 // If the input was x.swig, the output is x.go in the objdir.
2323 // But there might be an x.go in the original dir too, and if it
2324 // uses cgo as well, cgo will be processing both and will
2325 // translate both into x.cgo1.go in the objdir, overwriting one.
2326 // Rename x.go to _x_swig.go to avoid this problem.
2327 // We ignore files in the original dir that begin with underscore
2328 // so _x_swig.go cannot conflict with an original file we were
2329 // going to compile.
2330 goFile
= objdir
+ goFile
2331 newGoFile
:= objdir
+ "_" + base
+ "_swig.go"
2332 if err
:= os
.Rename(goFile
, newGoFile
); err
!= nil {
2335 return newGoFile
, objdir
+ gccBase
+ gccExt
, nil
2338 // disableBuildID adjusts a linker command line to avoid creating a
2339 // build ID when creating an object file rather than an executable or
2340 // shared library. Some systems, such as Ubuntu, always add
2341 // --build-id to every link, but we don't want a build ID when we are
2342 // producing an object file. On some of those system a plain -r (not
2343 // -Wl,-r) will turn off --build-id, but clang 3.0 doesn't support a
2344 // plain -r. I don't know how to turn off --build-id when using clang
2345 // other than passing a trailing --build-id=none. So that is what we
2346 // do, but only on systems likely to support it, which is to say,
2347 // systems that normally use gold or the GNU linker.
2348 func (b
*Builder
) disableBuildID(ldflags
[]string) []string {
2350 case "android", "dragonfly", "linux", "netbsd":
2351 ldflags
= append(ldflags
, "-Wl,--build-id=none")
2356 // mkAbsFiles converts files into a list of absolute files,
2357 // assuming they were originally relative to dir,
2358 // and returns that new list.
2359 func mkAbsFiles(dir
string, files
[]string) []string {
2360 abs
:= make([]string, len(files
))
2361 for i
, f
:= range files
{
2362 if !filepath
.IsAbs(f
) {
2363 f
= filepath
.Join(dir
, f
)