diff --git a/go/tools/builders/cgo2.go b/go/tools/builders/cgo2.go index f088a8415b..0ccd150a8f 100644 --- a/go/tools/builders/cgo2.go +++ b/go/tools/builders/cgo2.go @@ -23,6 +23,7 @@ package main import ( "bytes" "fmt" + "io/ioutil" "os" "path/filepath" "strings" @@ -196,7 +197,8 @@ func cgo2(goenv *env, goSrcs, cgoSrcs, cSrcs, cxxSrcs, objcSrcs, objcxxSrcs, sSr mainBin := filepath.Join(workDir, "_cgo_.o") // .o is a lie; it's an executable args = append([]string{cc, "-o", mainBin, mainObj}, cObjs...) args = append(args, combinedLdFlags...) - if err := goenv.runCommand(args); err != nil { + originalErrBuf := &bytes.Buffer{} + if err := goenv.runCommandToFile(os.Stdout, originalErrBuf, args); err != nil { // If linking the binary for cgo fails, this is usually because the // object files reference external symbols that can't be resolved yet. // Since the binary is only produced to have its symbols read by the cgo @@ -214,13 +216,20 @@ func cgo2(goenv *env, goSrcs, cgoSrcs, cSrcs, cxxSrcs, objcSrcs, objcxxSrcs, sSr default: allowUnresolvedSymbolsLdFlag = "-Wl,--unresolved-symbols=ignore-all" } - if err2 := goenv.runCommand(append(args, allowUnresolvedSymbolsLdFlag)); err2 != nil { - // Return the original error if we can't link the binary with the - // additional linker flags as they may simply be incorrect for the - // particular compiler/linker pair and would obscure the true reason - // for the failure of the original command. + // Print and return the original error if we can't link the binary with + // the additional linker flags as they may simply be incorrect for the + // particular compiler/linker pair and would obscure the true reason for + // the failure of the original command. + if err2 := goenv.runCommandToFile( + os.Stdout, + ioutil.Discard, + append(args, allowUnresolvedSymbolsLdFlag), + ); err2 != nil { + os.Stderr.Write(relativizePaths(originalErrBuf.Bytes())) return "", nil, nil, err } + // Do not print the original error - rerunning the command with the + // additional linker flag fixed it. } cgoImportsGo := filepath.Join(workDir, "_cgo_imports.go") diff --git a/go/tools/builders/env.go b/go/tools/builders/env.go index d05992579e..e533e1db94 100644 --- a/go/tools/builders/env.go +++ b/go/tools/builders/env.go @@ -141,12 +141,12 @@ func (e *env) runCommand(args []string) error { return err } -// runCommandToFile executes a subprocess and writes the output to the given -// writer. -func (e *env) runCommandToFile(w io.Writer, args []string) error { +// runCommandToFile executes a subprocess and writes stdout/stderr to the given +// writers. +func (e *env) runCommandToFile(out io.Writer, err io.Writer, args []string) error { cmd := exec.Command(args[0], args[1:]...) - cmd.Stdout = w - cmd.Stderr = os.Stderr + cmd.Stdout = out + cmd.Stderr = err return runAndLogCommand(cmd, e.verbose) } diff --git a/go/tools/builders/info.go b/go/tools/builders/info.go index 1475cf02d5..852a98e3ea 100644 --- a/go/tools/builders/info.go +++ b/go/tools/builders/info.go @@ -48,10 +48,10 @@ func run(args []string) error { } defer f.Close() } - if err := goenv.runCommandToFile(f, goenv.goCmd("version")); err != nil { + if err := goenv.runCommandToFile(f, os.Stderr, goenv.goCmd("version")); err != nil { return err } - if err := goenv.runCommandToFile(f, goenv.goCmd("env")); err != nil { + if err := goenv.runCommandToFile(f, os.Stderr, goenv.goCmd("env")); err != nil { return err } return nil diff --git a/go/tools/builders/stdliblist.go b/go/tools/builders/stdliblist.go index 3eab29838d..eb203e21c7 100644 --- a/go/tools/builders/stdliblist.go +++ b/go/tools/builders/stdliblist.go @@ -223,7 +223,7 @@ func stdliblist(args []string) error { defer jsonFile.Close() jsonData := &bytes.Buffer{} - if err := goenv.runCommandToFile(jsonData, listArgs); err != nil { + if err := goenv.runCommandToFile(jsonData, os.Stderr, listArgs); err != nil { return err } encoder := json.NewEncoder(jsonFile)