Skip to content

Commit

Permalink
[dev.boringcrypto] cmd/go: pass dependency syso to cgo too
Browse files Browse the repository at this point in the history
Proposal #42477 asked for a way to apply conditional build tags
to syso files (which have no source code to hold //go:build lines).

We ended up suggesting that the standard answer should be to
put the syso in its own package and then import that package from
a source file that is itself conditionally compiled.

A followup comment on that issue pointed out a problem that I did
not understand until I tried to use this approach myself: the cgo
build fails by default, because the link step only uses syso files from
the current package. You have to override this explicitly by arranging
to pass a “ignore unresolved symbols” flag to the host linker.
Many users will not know how to do this.
(I don't know how to do this off the top of my head.)

If we want users to use this approach, we should make it work better.
This CL does that, by including the syso files from dependencies of
the current package in the link step.

For #51940.

Change-Id: I53a0371b2df17e39a000a645b7686daa6a98722d
Reviewed-on: https://go-review.googlesource.com/c/go/+/402596
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
  • Loading branch information
rsc committed Apr 29, 2022
1 parent e540750 commit 1f0547c
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 1 deletion.
22 changes: 21 additions & 1 deletion src/cmd/go/internal/work/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"path/filepath"
"regexp"
"runtime"
"sort"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -2991,7 +2992,26 @@ func (b *Builder) dynimport(a *Action, p *load.Package, objdir, importGo, cgoExe
return err
}

linkobj := str.StringList(ofile, outObj, mkAbsFiles(p.Dir, p.SysoFiles))
// Gather .syso files from this package and all (transitive) dependencies.
var syso []string
seen := make(map[*Action]bool)
var gatherSyso func(*Action)
gatherSyso = func(a1 *Action) {
if seen[a1] {
return
}
seen[a1] = true
if p1 := a1.Package; p1 != nil {
syso = append(syso, mkAbsFiles(p1.Dir, p1.SysoFiles)...)
}
for _, a2 := range a1.Deps {
gatherSyso(a2)
}
}
gatherSyso(a)
sort.Strings(syso)
str.Uniq(&syso)
linkobj := str.StringList(ofile, outObj, syso)
dynobj := objdir + "_cgo_.o"

ldflags := cgoLDFLAGS
Expand Down
54 changes: 54 additions & 0 deletions src/cmd/go/testdata/script/link_syso_deps.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Test that syso in deps is available to cgo.

[!gc] skip
[!cgo] skip

# External linking is not supported on linux/ppc64.
# See: https://github.com/golang/go/issues/8912
[linux] [ppc64] skip

cc -c -o syso/x.syso syso/x.c
cc -c -o syso2/x.syso syso2/x.c
go build m/cgo

-- go.mod --
module m

go 1.18
-- cgo/x.go --
package cgo

// extern void f(void);
// extern void g(void);
import "C"

func F() {
C.f()
}

func G() {
C.g()
}

-- cgo/x2.go --
package cgo

import _ "m/syso"

-- syso/x.c --
//go:build ignore

void f() {}

-- syso/x.go --
package syso

import _ "m/syso2"

-- syso2/x.c --
//go:build ignore

void g() {}

-- syso2/x.go --
package syso2

0 comments on commit 1f0547c

Please sign in to comment.