libgo patch committed: Support pkg-config in go tool

Ian Lance Taylor iant@golang.org
Wed Feb 10 18:30:00 GMT 2016


Michael Hudson-Doyle has written a patch to support pkg-config for
gccgo in the go tool.  The patch has not been committed to the master
sources, because they are in a freeze for the Go 1.6 release.  I've
decided to pick it up and commit it to the gccgo sources, so that it
is available for the GCC 6 release.  This fixes GCC PR 66904.
Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
to mainline.

Ian
-------------- next part --------------
Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE	(revision 233260)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -1,4 +1,4 @@
-4cec4c5db5b054c5536ec5c50ee7aebec83563bc
+28a9dfbc3cda0bf7fd4f3fb1506c547f6cdf41a5
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: libgo/go/cmd/go/build.go
===================================================================
--- libgo/go/cmd/go/build.go	(revision 233110)
+++ libgo/go/cmd/go/build.go	(working copy)
@@ -1445,6 +1445,9 @@ func (b *builder) build(a *action) (err
 		if err != nil {
 			return err
 		}
+		if _, ok := buildToolchain.(gccgoToolchain); ok {
+			cgoObjects = append(cgoObjects, filepath.Join(a.objdir, "_cgo_flags"))
+		}
 		cgoObjects = append(cgoObjects, outObj...)
 		gofiles = append(gofiles, outGo...)
 	}
@@ -2620,12 +2623,64 @@ func (tools gccgoToolchain) ld(b *builde
 	cxx := len(root.p.CXXFiles) > 0 || len(root.p.SwigCXXFiles) > 0
 	objc := len(root.p.MFiles) > 0
 
+	readCgoFlags := func(flagsFile string) error {
+		flags, err := ioutil.ReadFile(flagsFile)
+		if err != nil {
+			return err
+		}
+		for _, line := range strings.Split(string(flags), "\n") {
+			if strings.HasPrefix(line, "_CGO_LDFLAGS=") {
+				cgoldflags = append(cgoldflags, strings.Fields(line[13:])...)
+			}
+		}
+		return nil
+	}
+
+	readAndRemoveCgoFlags := func(archive string) (string, error) {
+		newa, err := ioutil.TempFile(b.work, filepath.Base(archive))
+		if err != nil {
+			return "", err
+		}
+		olda, err := os.Open(archive)
+		if err != nil {
+			return "", err
+		}
+		_, err = io.Copy(newa, olda)
+		if err != nil {
+			return "", err
+		}
+		err = olda.Close()
+		if err != nil {
+			return "", err
+		}
+		err = newa.Close()
+		if err != nil {
+			return "", err
+		}
+
+		newarchive := newa.Name()
+		err = b.run(b.work, root.p.ImportPath, nil, "ar", "x", newarchive, "_cgo_flags")
+		if err != nil {
+			return "", err
+		}
+		err = b.run(".", root.p.ImportPath, nil, "ar", "d", newarchive, "_cgo_flags")
+		if err != nil {
+			return "", err
+		}
+		err = readCgoFlags(filepath.Join(b.work, "_cgo_flags"))
+		if err != nil {
+			return "", err
+		}
+		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
@@ -2644,16 +2699,23 @@ func (tools gccgoToolchain) ld(b *builde
 			// doesn't work.
 			if !apackagesSeen[a.p] {
 				apackagesSeen[a.p] = true
+				target := a.target
+				if len(a.p.CgoFiles) > 0 {
+					target, err = readAndRemoveCgoFlags(target)
+					if err != nil {
+						return
+					}
+				}
 				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)
 				}
 			}
 		}
@@ -2663,10 +2725,16 @@ func (tools gccgoToolchain) ld(b *builde
 		}
 		for _, a1 := range a.deps {
 			walk(a1, seenShlib)
+			if err != nil {
+				return
+			}
 		}
 	}
 	for _, a1 := range root.deps {
 		walk(a1, false)
+		if err != nil {
+			return err
+		}
 	}
 	afiles = append(xfiles, afiles...)
 
@@ -2695,6 +2763,14 @@ func (tools gccgoToolchain) ld(b *builde
 		}
 	}
 
+	for i, o := range ofiles {
+		if filepath.Base(o) == "_cgo_flags" {
+			readCgoFlags(o)
+			ofiles = append(ofiles[:i], ofiles[i+1:]...)
+			break
+		}
+	}
+
 	ldflags = append(ldflags, "-Wl,--whole-archive")
 	ldflags = append(ldflags, afiles...)
 	ldflags = append(ldflags, "-Wl,--no-whole-archive")


More information about the Gcc-patches mailing list