Skip to content

Commit

Permalink
cmd/go: fix "#cgo pkg-config:" comments with gccgo
Browse files Browse the repository at this point in the history
DO NOT SUBMIT

This is too late for Go 1.6 but we'd like to get a fix into Ubuntu (as a distro
patch) so a review would be appreciated.

The unique difficulty of #cgo pkg-config is that the linker flags are recorded
when the package is compiled but (obviously) must be used when the package is
linked into an executable -- so the flags need to be stored on disk somewhere.
As it happens cgo already writes out a _cgo_flags file: nothing uses it
currently, but this change adds it to the lib$pkg.a file when compiling a
package, reads it out when linking (and passes a version of the .a file with
_cgo_flags stripped out of it to the linker). It's all fairly ugly but it works
and I can't really think of any way of reducing the essential level of
ugliness.

Fixes golang#11739

Change-Id: I35621878014e1e107eda77a5b0b23d0240ec5750
  • Loading branch information
mwhudson committed Jan 29, 2016
1 parent 2d916be commit 899b99e
Showing 1 changed file with 47 additions and 3 deletions.
50 changes: 47 additions & 3 deletions src/cmd/go/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -1437,6 +1437,7 @@ func (b *builder) build(a *action) (err error) {
if err != nil {
return err
}
cgoObjects = append(cgoObjects, filepath.Join(a.objdir, "_cgo_flags"))
cgoObjects = append(cgoObjects, outObj...)
gofiles = append(gofiles, outGo...)
}
Expand Down Expand Up @@ -2628,16 +2629,52 @@ func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions
// doesn't work.
if !apackagesSeen[a.p] {
apackagesSeen[a.p] = true
target := a.target
if len(a.p.CgoFiles) > 0 {
newa, err := ioutil.TempFile(b.work, filepath.Base(target))
if err != nil {
return
}
olda, err := os.Open(target)
if err != nil {
return
}
_, err = io.Copy(newa, olda)
if err != nil {
return
}
err = olda.Close()
if err != nil {
return
}
err = newa.Close()
if err != nil {
return
}

target = newa.Name()
err = b.run(b.work, root.p.ImportPath, nil, "ar", "x", target, "_cgo_flags")
err = b.run(".", root.p.ImportPath, nil, "ar", "d", target, "_cgo_flags")
flags, err := ioutil.ReadFile(filepath.Join(b.work, "_cgo_flags"))
if err != nil {
return
}
for _, line := range strings.Split(string(flags), "\n") {
if strings.HasPrefix(line, "_CGO_LDFLAGS=") {
cgoldflags = append(cgoldflags, strings.Fields(line[13:])...)
}
}
}
if a.p.fake && a.p.external {
// external _tests, if present must come before
// internal _tests. Store these on a separate list
// and place them at the head after this loop.
xfiles = append(xfiles, a.target)
xfiles = append(xfiles, target)
} else if a.p.fake {
// move _test files to the top of the link order
afiles = append([]string{a.target}, afiles...)
afiles = append([]string{target}, afiles...)
} else {
afiles = append(afiles, a.target)
afiles = append(afiles, target)
}
}
}
Expand All @@ -2647,10 +2684,17 @@ func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions
}
for _, a1 := range a.deps {
walk(a1, seenShlib)
if err != nil {
return
}
}
}
var err error
for _, a1 := range root.deps {
walk(a1, false)
if err != nil {
return err
}
}
afiles = append(xfiles, afiles...)

Expand Down

0 comments on commit 899b99e

Please sign in to comment.