func dynStrings(t *testing.T, path string, flag elf.DynTag) []string {
f, err := elf.Open(path)
- defer f.Close()
if err != nil {
t.Fatalf("elf.Open(%q) failed: %v", path, err)
}
+ defer f.Close()
dynstrings, err := f.DynString(flag)
if err != nil {
t.Fatalf("DynString(%s) failed on %s: %v", flag, path, err)
// If gccgo is not available or not new enough call t.Skip. Otherwise,
// return a build.Context that is set up for gccgo.
func prepGccgo(t *testing.T) build.Context {
- t.Skip("golang.org/issue/22472")
gccgoName := os.Getenv("GCCGO")
if gccgoName == "" {
gccgoName = "gccgo"
// library with gccgo, another GOPATH package that depends on the first and an
// executable that links the second library.
func TestTwoGopathShlibsGccgo(t *testing.T) {
- t.Skip("golang.org/issue/22224")
-
gccgoContext := prepGccgo(t)
libgoRE := regexp.MustCompile("libgo.so.[0-9]+")
func (tools gccgoToolchain) link(b *Builder, root *Action, out, importcfg string, allactions []*Action, buildmode, desc string) error {
// gccgo needs explicit linking with all package dependencies,
// and all LDFLAGS from cgo dependencies.
- apackagePathsSeen := make(map[string]bool)
afiles := []string{}
shlibs := []string{}
ldflags := b.gccArchArgs()
return newArchive, nil
}
- actionsSeen := make(map[*Action]bool)
- // Make a pre-order depth-first traversal of the action graph, taking note of
- // whether a shared library action has been seen on the way to an action (the
- // construction of the graph means that if any path to a node passes through
- // a shared library action, they all do).
- var walk func(a *Action, seenShlib bool)
- var err error
- walk = func(a *Action, seenShlib bool) {
- if actionsSeen[a] {
- return
- }
- actionsSeen[a] = true
- if a.Package != nil && !seenShlib {
- if a.Package.Standard {
- return
+ // If using -linkshared, find the shared library deps.
+ haveShlib := make(map[string]bool)
+ targetBase := filepath.Base(root.Target)
+ if cfg.BuildLinkshared {
+ for _, a := range root.Deps {
+ p := a.Package
+ if p == nil || p.Shlib == "" {
+ continue
}
- // We record the target of the first time we see a .a file
- // for a package to make sure that we prefer the 'install'
- // rather than the 'build' location (which may not exist any
- // more). We still need to traverse the dependencies of the
- // build action though so saying
- // if apackagePathsSeen[a.Package.ImportPath] { return }
- // doesn't work.
- if !apackagePathsSeen[a.Package.ImportPath] {
- apackagePathsSeen[a.Package.ImportPath] = true
- target := a.built
- if len(a.Package.CgoFiles) > 0 || a.Package.UsesSwig() {
- target, err = readAndRemoveCgoFlags(target)
- if err != nil {
- return
- }
- }
- afiles = append(afiles, target)
+
+ // The .a we are linking into this .so
+ // will have its Shlib set to this .so.
+ // Don't start thinking we want to link
+ // this .so into itself.
+ base := filepath.Base(p.Shlib)
+ if base != targetBase {
+ haveShlib[base] = true
}
}
- if strings.HasSuffix(a.Target, ".so") {
- shlibs = append(shlibs, a.Target)
- seenShlib = true
+ }
+
+ // Arrange the deps into afiles and shlibs.
+ addedShlib := make(map[string]bool)
+ for _, a := range root.Deps {
+ p := a.Package
+ if p != nil && p.Shlib != "" && haveShlib[filepath.Base(p.Shlib)] {
+ // This is a package linked into a shared
+ // library that we will put into shlibs.
+ continue
}
- for _, a1 := range a.Deps {
- walk(a1, seenShlib)
- if err != nil {
- return
+
+ if haveShlib[filepath.Base(a.Target)] {
+ // This is a shared library we want to link againt.
+ if !addedShlib[a.Target] {
+ shlibs = append(shlibs, a.Target)
+ addedShlib[a.Target] = true
}
+ continue
}
- }
- for _, a1 := range root.Deps {
- walk(a1, false)
- if err != nil {
- return err
+
+ if p != nil {
+ target := a.built
+ if p.UsesCgo() || p.UsesSwig() {
+ var err error
+ target, err = readAndRemoveCgoFlags(target)
+ if err != nil {
+ continue
+ }
+ }
+
+ afiles = append(afiles, target)
}
}
}
func (tools gccgoToolchain) ldShared(b *Builder, root *Action, toplevelactions []*Action, out, importcfg string, allactions []*Action) error {
- fakeRoot := *root
- fakeRoot.Deps = toplevelactions
- return tools.link(b, &fakeRoot, out, importcfg, allactions, "shared", out)
+ return tools.link(b, root, out, importcfg, allactions, "shared", out)
}
func (tools gccgoToolchain) cc(b *Builder, a *Action, ofile, cfile string) error {