mirror of
https://github.com/golang/go
synced 2024-11-22 05:34:39 -07:00
cmd/go: handle cgo pkg-config pragmas
Fixes #2681. R=golang-dev, bradfitz CC=golang-dev https://golang.org/cl/5540047
This commit is contained in:
parent
ba0e02b207
commit
811006c89d
@ -794,13 +794,8 @@ func (b *builder) showcmd(dir string, format string, args ...interface{}) {
|
|||||||
// showOutput also replaces references to the work directory with $WORK.
|
// showOutput also replaces references to the work directory with $WORK.
|
||||||
//
|
//
|
||||||
func (b *builder) showOutput(dir, desc, out string) {
|
func (b *builder) showOutput(dir, desc, out string) {
|
||||||
prefix := "# " + desc
|
prefix := "# " + desc + "\n"
|
||||||
suffix := "\n" + out
|
suffix := relPaths(dir, out)
|
||||||
pwd, _ := os.Getwd()
|
|
||||||
if reldir, err := filepath.Rel(pwd, dir); err == nil && len(reldir) < len(dir) {
|
|
||||||
suffix = strings.Replace(suffix, " "+dir, " "+reldir, -1)
|
|
||||||
suffix = strings.Replace(suffix, "\n"+dir, "\n"+reldir, -1)
|
|
||||||
}
|
|
||||||
suffix = strings.Replace(suffix, " "+b.work, " $WORK", -1)
|
suffix = strings.Replace(suffix, " "+b.work, " $WORK", -1)
|
||||||
|
|
||||||
b.output.Lock()
|
b.output.Lock()
|
||||||
@ -808,6 +803,18 @@ func (b *builder) showOutput(dir, desc, out string) {
|
|||||||
fmt.Print(prefix, suffix)
|
fmt.Print(prefix, suffix)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// relPaths returns a copy of out with references to dir
|
||||||
|
// made relative to the current directory if that would be shorter.
|
||||||
|
func relPaths(dir, out string) string {
|
||||||
|
x := "\n" + out
|
||||||
|
pwd, _ := os.Getwd()
|
||||||
|
if reldir, err := filepath.Rel(pwd, dir); err == nil && len(reldir) < len(dir) {
|
||||||
|
x = strings.Replace(x, " "+dir, " "+reldir, -1)
|
||||||
|
x = strings.Replace(x, "\n"+dir, "\n"+reldir, -1)
|
||||||
|
}
|
||||||
|
return x[1:]
|
||||||
|
}
|
||||||
|
|
||||||
// errPrintedOutput is a special error indicating that a command failed
|
// errPrintedOutput is a special error indicating that a command failed
|
||||||
// but that it generated output as well, and that output has already
|
// but that it generated output as well, and that output has already
|
||||||
// been printed, so there's no point showing 'exit status 1' or whatever
|
// been printed, so there's no point showing 'exit status 1' or whatever
|
||||||
@ -819,11 +826,30 @@ var errPrintedOutput = errors.New("already printed output - no need to show erro
|
|||||||
// If the commnd fails, run prints information about the failure
|
// If the commnd fails, run prints information about the failure
|
||||||
// and returns a non-nil error.
|
// and returns a non-nil error.
|
||||||
func (b *builder) run(dir string, desc string, cmdargs ...interface{}) error {
|
func (b *builder) run(dir string, desc string, cmdargs ...interface{}) error {
|
||||||
|
out, err := b.runOut(dir, desc, cmdargs...)
|
||||||
|
if len(out) > 0 {
|
||||||
|
if out[len(out)-1] != '\n' {
|
||||||
|
out = append(out, '\n')
|
||||||
|
}
|
||||||
|
if desc == "" {
|
||||||
|
desc = b.fmtcmd(dir, "%s", strings.Join(stringList(cmdargs...), " "))
|
||||||
|
}
|
||||||
|
b.showOutput(dir, desc, string(out))
|
||||||
|
if err != nil {
|
||||||
|
err = errPrintedOutput
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// runOut runs the command given by cmdline in the directory dir.
|
||||||
|
// It returns the command output and any errors that occurred.
|
||||||
|
func (b *builder) runOut(dir string, desc string, cmdargs ...interface{}) ([]byte, error) {
|
||||||
cmdline := stringList(cmdargs...)
|
cmdline := stringList(cmdargs...)
|
||||||
if buildN || buildX {
|
if buildN || buildX {
|
||||||
b.showcmd(dir, "%s", strings.Join(cmdline, " "))
|
b.showcmd(dir, "%s", strings.Join(cmdline, " "))
|
||||||
if buildN {
|
if buildN {
|
||||||
return nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -834,20 +860,7 @@ func (b *builder) run(dir string, desc string, cmdargs ...interface{}) error {
|
|||||||
cmd.Dir = dir
|
cmd.Dir = dir
|
||||||
// TODO: cmd.Env
|
// TODO: cmd.Env
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
if buf.Len() > 0 {
|
return buf.Bytes(), err
|
||||||
out := buf.Bytes()
|
|
||||||
if out[len(out)-1] != '\n' {
|
|
||||||
out = append(out, '\n')
|
|
||||||
}
|
|
||||||
if desc == "" {
|
|
||||||
desc = b.fmtcmd(dir, "%s", strings.Join(cmdline, " "))
|
|
||||||
}
|
|
||||||
b.showOutput(dir, desc, string(out))
|
|
||||||
if err != nil {
|
|
||||||
err = errPrintedOutput
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// mkdir makes the named directory.
|
// mkdir makes the named directory.
|
||||||
@ -980,6 +993,25 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo,
|
|||||||
|
|
||||||
outObj = append(outObj, "") // for importObj, at end of function
|
outObj = append(outObj, "") // for importObj, at end of function
|
||||||
|
|
||||||
|
cgoCFLAGS := stringList(p.info.CgoCFLAGS)
|
||||||
|
cgoLDFLAGS := stringList(p.info.CgoLDFLAGS)
|
||||||
|
if pkgs := p.info.CgoPkgConfig; len(pkgs) > 0 {
|
||||||
|
out, err := b.runOut(p.Dir, p.ImportPath, "pkg-config", "--cflags", pkgs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if len(out) > 0 {
|
||||||
|
cgoCFLAGS = append(cgoCFLAGS, strings.Fields(string(out))...)
|
||||||
|
}
|
||||||
|
out, err = b.runOut(p.Dir, p.ImportPath, "pkg-config", "--libs", pkgs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if len(out) > 0 {
|
||||||
|
cgoLDFLAGS = append(cgoLDFLAGS, strings.Fields(string(out))...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// cgo
|
// cgo
|
||||||
// TODO: CGOPKGPATH, CGO_FLAGS?
|
// TODO: CGOPKGPATH, CGO_FLAGS?
|
||||||
gofiles := []string{obj + "_cgo_gotypes.go"}
|
gofiles := []string{obj + "_cgo_gotypes.go"}
|
||||||
@ -991,7 +1023,6 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo,
|
|||||||
}
|
}
|
||||||
defunC := obj + "_cgo_defun.c"
|
defunC := obj + "_cgo_defun.c"
|
||||||
// TODO: make cgo not depend on $GOARCH?
|
// TODO: make cgo not depend on $GOARCH?
|
||||||
// TODO: make cgo write to obj
|
|
||||||
var runtimeFlag []string
|
var runtimeFlag []string
|
||||||
if p.Standard && p.ImportPath == "runtime/cgo" {
|
if p.Standard && p.ImportPath == "runtime/cgo" {
|
||||||
runtimeFlag = []string{"-import_runtime_cgo=false"}
|
runtimeFlag = []string{"-import_runtime_cgo=false"}
|
||||||
@ -1012,7 +1043,7 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo,
|
|||||||
var linkobj []string
|
var linkobj []string
|
||||||
for _, cfile := range cfiles {
|
for _, cfile := range cfiles {
|
||||||
ofile := obj + cfile[:len(cfile)-1] + "o"
|
ofile := obj + cfile[:len(cfile)-1] + "o"
|
||||||
if err := b.gcc(p, ofile, p.info.CgoCFLAGS, obj+cfile); err != nil {
|
if err := b.gcc(p, ofile, cgoCFLAGS, obj+cfile); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
linkobj = append(linkobj, ofile)
|
linkobj = append(linkobj, ofile)
|
||||||
@ -1022,14 +1053,14 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo,
|
|||||||
}
|
}
|
||||||
for _, file := range gccfiles {
|
for _, file := range gccfiles {
|
||||||
ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
|
ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
|
||||||
if err := b.gcc(p, ofile, p.info.CgoCFLAGS, file); err != nil {
|
if err := b.gcc(p, ofile, cgoCFLAGS, file); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
linkobj = append(linkobj, ofile)
|
linkobj = append(linkobj, ofile)
|
||||||
outObj = append(outObj, ofile)
|
outObj = append(outObj, ofile)
|
||||||
}
|
}
|
||||||
dynobj := obj + "_cgo_.o"
|
dynobj := obj + "_cgo_.o"
|
||||||
if err := b.gccld(p, dynobj, p.info.CgoLDFLAGS, linkobj); err != nil {
|
if err := b.gccld(p, dynobj, cgoLDFLAGS, linkobj); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user