Skip to content

Commit

Permalink
cmd/go: don't print dynimport link error messages
Browse files Browse the repository at this point in the history
When using the -x or -n option, we were printing the external
linker error messages from producing the dynimport file.
This was confusing because those linker errors are unimportant and
ignored; only the linker exit status matters, and failure doesn't
drop the build.

Change cmd/go -x to not print the error messages, and to instead
print the linker command line with a notation of whether the
link succeeded or failed.

Fixes #68743

Change-Id: Ie3cc58d2d6a7d33d7baa6f1273b4fb5a7deee7e5
Reviewed-on: https://go-review.googlesource.com/c/go/+/615916
Reviewed-by: Michael Matloob <[email protected]>
Auto-Submit: Ian Lance Taylor <[email protected]>
Reviewed-by: Ian Lance Taylor <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
  • Loading branch information
ianlancetaylor authored and gopherbot committed Sep 26, 2024
1 parent 712d47c commit 3587430
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 37 deletions.
44 changes: 7 additions & 37 deletions src/cmd/go/internal/work/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -2244,7 +2244,6 @@ func (b *Builder) ccompile(a *Action, outfile string, flags []string, file strin
}

// gccld runs the gcc linker to create an executable from a set of object files.
// Any error output is only displayed for BuildN or BuildX.
func (b *Builder) gccld(a *Action, objdir, outfile string, flags []string, objs []string) error {
p := a.Package
sh := b.Shell(a)
Expand All @@ -2256,47 +2255,18 @@ func (b *Builder) gccld(a *Action, objdir, outfile string, flags []string, objs
}

cmdargs := []any{cmd, "-o", outfile, objs, flags}
out, err := sh.runOut(base.Cwd(), b.cCompilerEnv(), cmdargs...)

if len(out) > 0 {
// Filter out useless linker warnings caused by bugs outside Go.
// See also cmd/link/internal/ld's hostlink method.
var save [][]byte
var skipLines int
for _, line := range bytes.SplitAfter(out, []byte("\n")) {
// golang.org/issue/26073 - Apple Xcode bug
if bytes.Contains(line, []byte("ld: warning: text-based stub file")) {
continue
}
_, err := sh.runOut(base.Cwd(), b.cCompilerEnv(), cmdargs...)

if skipLines > 0 {
skipLines--
continue
}

// Remove duplicate main symbol with runtime/cgo on AIX.
// With runtime/cgo, two main are available:
// One is generated by cgo tool with {return 0;}.
// The other one is the main calling runtime.rt0_go
// in runtime/cgo.
// The second can't be used by cgo programs because
// runtime.rt0_go is unknown to them.
// Therefore, we let ld remove this main version
// and used the cgo generated one.
if p.ImportPath == "runtime/cgo" && bytes.Contains(line, []byte("ld: 0711-224 WARNING: Duplicate symbol: .main")) {
skipLines = 1
continue
}

save = append(save, line)
}
out = bytes.Join(save, nil)
}
// Note that failure is an expected outcome here, so we report output only
// in debug mode and don't report the error.
if cfg.BuildN || cfg.BuildX {
sh.reportCmd("", "", out, nil)
saw := "succeeded"
if err != nil {
saw = "failed"
}
sh.ShowCmd("", "%s # test for internal linking errors (%s)", joinUnambiguously(str.StringList(cmdargs...)), saw)
}

return err
}

Expand Down
21 changes: 21 additions & 0 deletions src/cmd/go/testdata/script/cgo_undef.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,18 @@
cc -c -o a/b.syso b/b.c
cc -c -o b/lib.o b/lib.c
exec ar rc a/libb.a b/lib.o

go build
! stderr 'undefined reference'

! go build -ldflags=-linkmode=internal
stderr 'some packages could not be built to support internal linking.*m/c|requires external linking|does not support internal cgo'

# Test for issue #68743.
go build -x m/d
! stderr 'undefined reference'
stderr 'test for internal linking'

-- go.mod --
module m

Expand Down Expand Up @@ -58,6 +66,19 @@ func Fn(i int) (int, int) {
return a.GoFn(i), int(C.D(C.int(i)))
}

-- d/d.go --
// Package d is a copy of package c, to build with -x.
package d

// static int D(int i) { return i; }
import "C"

import "m/a"

func Fn(i int) (int, int) {
return a.GoFn(i), int(C.D(C.int(i)))
}

-- main.go --
package main

Expand Down

0 comments on commit 3587430

Please sign in to comment.