From 74c9c261fd24a8e6e78361d8d50ad00896563c28 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Wed, 8 Jun 2022 17:06:45 +0200 Subject: [PATCH] Do not print to stderr if cgo linking succeeds after retry (#3187) The rety logic introduced by 6ab73ec5b still emitted the stderr of the failing compiler execution before the retry. Now, this output is cached and only emitted if the retry also fails. --- go/tools/builders/cgo2.go | 21 +++++++++++++++------ go/tools/builders/env.go | 10 +++++----- go/tools/builders/info.go | 4 ++-- go/tools/builders/stdliblist.go | 2 +- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/go/tools/builders/cgo2.go b/go/tools/builders/cgo2.go index f088a8415b..fc2876a994 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 { + var 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..b4b5eded48 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, 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)