diff --git a/go/loader/cgo.go b/go/loader/cgo.go index f698197c..c925ace4 100644 --- a/go/loader/cgo.go +++ b/go/loader/cgo.go @@ -112,14 +112,19 @@ var cgoRe = regexp.MustCompile(`[/\\:]`) // // runCgo is adapted from (*builder).cgo in // $GOROOT/src/cmd/go/build.go, but these features are unsupported: -// pkg-config, Objective C, CGOPKGPATH, CGO_FLAGS. +// Objective C, CGOPKGPATH, CGO_FLAGS. // func runCgo(bp *build.Package, pkgdir, tmpdir string) (files, displayFiles []string, err error) { - cgoCPPFLAGS, _, _, _ := cflags(bp, true) + cgoCPPFLAGS, _, _, cgoLDFLAGS := cflags(bp, true) _, cgoexeCFLAGS, _, _ := cflags(bp, false) if len(bp.CgoPkgConfig) > 0 { - return nil, nil, fmt.Errorf("cgo pkg-config not supported") + pcCFLAGS, pcLDFLAGS, err := pkgConfigFlags(bp) + if err != nil { + return nil, nil, err + } + cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...) + cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...) } // Allows including _cgo_export.h from .[ch] files in the package. @@ -145,7 +150,7 @@ func runCgo(bp *build.Package, pkgdir, tmpdir string) (files, displayFiles []str args := stringList( "go", "tool", "cgo", "-objdir", tmpdir, cgoflags, "--", - cgoCPPFLAGS, cgoexeCFLAGS, bp.CgoFiles, + cgoCPPFLAGS, cgoLDFLAGS, cgoexeCFLAGS, bp.CgoFiles, ) if false { log.Printf("Running cgo for package %q: %s (dir=%s)", bp.ImportPath, args, pkgdir) diff --git a/go/loader/cgo14.go b/go/loader/cgo14.go index 1dac420f..d484c7db 100644 --- a/go/loader/cgo14.go +++ b/go/loader/cgo14.go @@ -112,14 +112,19 @@ var cgoRe = regexp.MustCompile(`[/\\:]`) // // runCgo is adapted from (*builder).cgo in // $GOROOT/src/cmd/go/build.go, but these features are unsupported: -// pkg-config, Objective C, CGOPKGPATH, CGO_FLAGS. +// Objective C, CGOPKGPATH, CGO_FLAGS. // func runCgo(bp *build.Package, pkgdir, tmpdir string) (files, displayFiles []string, err error) { - cgoCPPFLAGS, _, _, _ := cflags(bp, true) + cgoCPPFLAGS, _, _, cgoLDFLAGS := cflags(bp, true) _, cgoexeCFLAGS, _, _ := cflags(bp, false) if len(bp.CgoPkgConfig) > 0 { - return nil, nil, fmt.Errorf("cgo pkg-config not supported") + pcCFLAGS, pcLDFLAGS, err := pkgConfigFlags(bp) + if err != nil { + return nil, nil, err + } + cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...) + cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...) } // Allows including _cgo_export.h from .[ch] files in the package. @@ -145,7 +150,7 @@ func runCgo(bp *build.Package, pkgdir, tmpdir string) (files, displayFiles []str args := stringList( "go", "tool", "cgo", "-objdir", tmpdir, cgoflags, "--", - cgoCPPFLAGS, cgoexeCFLAGS, bp.CgoFiles, + cgoCPPFLAGS, cgoLDFLAGS, cgoexeCFLAGS, bp.CgoFiles, ) if false { log.Printf("Running cgo for package %q: %s (dir=%s)", bp.ImportPath, args, pkgdir) diff --git a/go/loader/cgo_pkgconfig.go b/go/loader/cgo_pkgconfig.go new file mode 100644 index 00000000..91ab2ccf --- /dev/null +++ b/go/loader/cgo_pkgconfig.go @@ -0,0 +1,45 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package loader + +import ( + "errors" + "fmt" + "go/build" + "os/exec" + "strings" +) + +// pkgConfig runs pkg-config with the specified arguments and returns the flags it prints. +func pkgConfig(mode string, pkgs []string) (flags []string, err error) { + cmd := exec.Command("pkg-config", append([]string{mode}, pkgs...)...) + out, err := cmd.CombinedOutput() + if err != nil { + s := fmt.Sprintf("%s failed: %v", strings.Join(cmd.Args, " "), err) + if len(out) > 0 { + s = fmt.Sprintf("%s: %s", s, out) + } + return nil, errors.New(s) + } + if len(out) > 0 { + flags = strings.Fields(string(out)) + } + return +} + +// pkgConfigFlags calls pkg-config if needed and returns the cflags/ldflags needed to build the package. +func pkgConfigFlags(p *build.Package) (cflags, ldflags []string, err error) { + if pkgs := p.CgoPkgConfig; len(pkgs) > 0 { + cflags, err = pkgConfig("--cflags", pkgs) + if err != nil { + return nil, nil, err + } + ldflags, err = pkgConfig("--libs", pkgs) + if err != nil { + return nil, nil, err + } + } + return +}