]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: use pkg-config include pathes in swig and don't double compile c++ files.
authorAhmed Waheed Moanes <oneofone@gmail.com>
Tue, 16 Sep 2014 22:06:52 +0000 (15:06 -0700)
committerIan Lance Taylor <iant@golang.org>
Tue, 16 Sep 2014 22:06:52 +0000 (15:06 -0700)
Fixes #8566.

LGTM=iant
R=iant
CC=golang-codereviews
https://golang.org/cl/126210045

src/cmd/go/build.go

index 45b5bc32336105d77fbbf44bff7ce9295f348e82..2e52731529178a6bf01560ca02e73c853afc0670 100644 (file)
@@ -824,12 +824,17 @@ func (b *builder) build(a *action) (err error) {
                }
        }
 
-       var gofiles, cfiles, sfiles, objects, cgoObjects []string
+       var gofiles, cfiles, sfiles, objects, cgoObjects, pcCFLAGS, pcLDFLAGS []string
 
        gofiles = append(gofiles, a.p.GoFiles...)
        cfiles = append(cfiles, a.p.CFiles...)
        sfiles = append(sfiles, a.p.SFiles...)
 
+       if a.p.usesCgo() || a.p.usesSwig() {
+               if pcCFLAGS, pcLDFLAGS, err = b.getPkgConfigFlags(a.p); err != nil {
+                       return
+               }
+       }
        // Run cgo.
        if a.p.usesCgo() {
                // In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
@@ -860,7 +865,7 @@ func (b *builder) build(a *action) (err error) {
                if a.cgo != nil && a.cgo.target != "" {
                        cgoExe = a.cgo.target
                }
-               outGo, outObj, err := b.cgo(a.p, cgoExe, obj, gccfiles, a.p.CXXFiles, a.p.MFiles)
+               outGo, outObj, err := b.cgo(a.p, cgoExe, obj, pcCFLAGS, pcLDFLAGS, gccfiles, a.p.CXXFiles, a.p.MFiles)
                if err != nil {
                        return err
                }
@@ -873,9 +878,18 @@ func (b *builder) build(a *action) (err error) {
                // In a package using SWIG, any .c or .s files are
                // compiled with gcc.
                gccfiles := append(cfiles, sfiles...)
+               cxxfiles, mfiles := a.p.CXXFiles, a.p.MFiles
                cfiles = nil
                sfiles = nil
-               outGo, outObj, err := b.swig(a.p, obj, gccfiles, a.p.CXXFiles, a.p.MFiles)
+
+               // Don't build c/c++ files twice if cgo is enabled (mainly for pkg-config).
+               if a.p.usesCgo() {
+                       cxxfiles = nil
+                       gccfiles = nil
+                       mfiles = nil
+               }
+
+               outGo, outObj, err := b.swig(a.p, obj, pcCFLAGS, gccfiles, cxxfiles, mfiles)
                if err != nil {
                        return err
                }
@@ -1019,6 +1033,34 @@ func (b *builder) build(a *action) (err error) {
        return nil
 }
 
+// Calls pkg-config if needed and returns the cflags/ldflags needed to build the package.
+func (b *builder) getPkgConfigFlags(p *Package) (cflags, ldflags []string, err error) {
+       if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
+               var out []byte
+               out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--cflags", pkgs)
+               if err != nil {
+                       b.showOutput(p.Dir, "pkg-config --cflags "+strings.Join(pkgs, " "), string(out))
+                       b.print(err.Error() + "\n")
+                       err = errPrintedOutput
+                       return
+               }
+               if len(out) > 0 {
+                       cflags = strings.Fields(string(out))
+               }
+               out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--libs", pkgs)
+               if err != nil {
+                       b.showOutput(p.Dir, "pkg-config --libs "+strings.Join(pkgs, " "), string(out))
+                       b.print(err.Error() + "\n")
+                       err = errPrintedOutput
+                       return
+               }
+               if len(out) > 0 {
+                       ldflags = strings.Fields(string(out))
+               }
+       }
+       return
+}
+
 // install is the action for installing a single package or executable.
 func (b *builder) install(a *action) (err error) {
        defer func() {
@@ -2100,36 +2142,16 @@ var (
        cgoLibGccFileOnce sync.Once
 )
 
-func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
+func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
        cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoLDFLAGS := b.cflags(p, true)
        _, cgoexeCFLAGS, _, _ := b.cflags(p, false)
-
+       cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...)
+       cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...)
        // If we are compiling Objective-C code, then we need to link against libobjc
        if len(mfiles) > 0 {
                cgoLDFLAGS = append(cgoLDFLAGS, "-lobjc")
        }
 
-       if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
-               out, err := b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--cflags", pkgs)
-               if err != nil {
-                       b.showOutput(p.Dir, "pkg-config --cflags "+strings.Join(pkgs, " "), string(out))
-                       b.print(err.Error() + "\n")
-                       return nil, nil, errPrintedOutput
-               }
-               if len(out) > 0 {
-                       cgoCPPFLAGS = append(cgoCPPFLAGS, strings.Fields(string(out))...)
-               }
-               out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--libs", pkgs)
-               if err != nil {
-                       b.showOutput(p.Dir, "pkg-config --libs "+strings.Join(pkgs, " "), string(out))
-                       b.print(err.Error() + "\n")
-                       return nil, nil, errPrintedOutput
-               }
-               if len(out) > 0 {
-                       cgoLDFLAGS = append(cgoLDFLAGS, strings.Fields(string(out))...)
-               }
-       }
-
        // Allows including _cgo_export.h from .[ch] files in the package.
        cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", obj)
 
@@ -2344,7 +2366,7 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles, gxxfiles, mfiles
 // Run SWIG on all SWIG input files.
 // TODO: Don't build a shared library, once SWIG emits the necessary
 // pragmas for external linking.
-func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
+func (b *builder) swig(p *Package, obj string, pcCFLAGS, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
        cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
        cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
        cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
@@ -2385,7 +2407,7 @@ func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles, mfiles []stri
        }
 
        for _, f := range p.SwigFiles {
-               goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, false, intgosize)
+               goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, pcCFLAGS, false, intgosize)
                if err != nil {
                        return nil, nil, err
                }
@@ -2400,7 +2422,7 @@ func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles, mfiles []stri
                }
        }
        for _, f := range p.SwigCXXFiles {
-               goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, true, intgosize)
+               goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, pcCFLAGS, true, intgosize)
                if err != nil {
                        return nil, nil, err
                }
@@ -2479,13 +2501,13 @@ func (b *builder) swigIntSize(obj string) (intsize string, err error) {
 }
 
 // Run SWIG on one SWIG input file.
-func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize string) (outGo, outObj, objGccObj string, err error) {
+func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outObj, objGccObj string, err error) {
        cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
        var cflags []string
        if cxx {
-               cflags = stringList(cgoCPPFLAGS, cgoCXXFLAGS)
+               cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS)
        } else {
-               cflags = stringList(cgoCPPFLAGS, cgoCFLAGS)
+               cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS)
        }
 
        n := 5 // length of ".swig"
@@ -2511,6 +2533,13 @@ func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize stri
                "-o", obj + gccBase + gccExt,
                "-outdir", obj,
        }
+
+       for _, f := range cflags {
+               if len(f) > 3 && f[:2] == "-I" {
+                       args = append(args, f)
+               }
+       }
+
        if gccgo {
                args = append(args, "-gccgo")
                if pkgpath := gccgoPkgpath(p); pkgpath != "" {