Description
Corresponding Zig issue: ziglang/zig#11398
What version of Go are you using (go version
)?
$ go version go version go1.18.1 linux/amd64
Does this issue reproduce with the latest release?
I only tested with go1.18.1.
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/home/andy/.cache/go-build" GOENV="/home/andy/.config/go/env" GOEXE="" GOEXPERIMENT="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="/home/andy/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/home/andy/go" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/nix/store/qyc0w8vsikzmbdy97gb68l2ri1jzqp9v-go-1.18.1/share/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/nix/store/qyc0w8vsikzmbdy97gb68l2ri1jzqp9v-go-1.18.1/share/go/pkg/tool/linux_amd64" GOVCS="" GOVERSION="go1.18.1" GCCGO="gccgo" GOAMD64="v1" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="/dev/null" GOWORK="" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/run/user/1000/go-build3829224601=/tmp/go-build -gno-record-gcc-switches"
What did you do?
go.mod
:
module test
go 1.18
foo.go
:
package test
func foo() {}
foo_test.go
:
package test
import (
"testing"
)
func TestFoo(t *testing.T) {
foo()
}
Then use zig cc as the C toolchain for go test
with race detection:
CGO_ENABLED=1 CC="zig cc" go test -race test
Zig Version 0.10.0-dev.2052+3cfde183f
What did you expect to see?
This should work, as it does without -race
.
What did you see instead?
We get errors from the Go linker:
# test.test
runtime/race(.text): relocation target getuid not defined
runtime/race(.text): relocation target pthread_self not defined
runtime/race(.text): relocation target sleep not defined
runtime/race(.text): relocation target usleep not defined
runtime/race(.text): relocation target abort not defined
runtime/race(.text): relocation target isatty not defined
runtime/race(.text): relocation target pthread_attr_getstack not defined
runtime/race(.text): relocation target sigaction not defined
runtime/race(.text): relocation target getrusage not defined
runtime/race(.text): relocation target syslog not defined
runtime/race(.text): relocation target confstr not defined
runtime/race(.text): relocation target getrlimit not defined
runtime/race(.text): relocation target pipe not defined
runtime/race(.text): relocation target sched_getaffinity not defined
runtime/race(.text): relocation target __sched_cpucount not defined
runtime/race(.text): relocation target pthread_attr_init not defined
runtime/race(.text): relocation target pthread_getattr_np not defined
runtime/race(.text): relocation target pthread_attr_destroy not defined
runtime/race(.text): relocation target exit not defined
runtime/race(.text): relocation target sysconf not defined
runtime/race(.text): relocation target setrlimit not defined
/home/kmicklas/go/pkg/tool/linux_amd64/link: too many errors
FAIL test [build failed]
FAIL
Notes
Related issue: #44695
It appears that cgo has asked the C compiler to compile C source files which contain dependencies on libc symbols, however the Go linker is not actually putting libc onto the linker line, causing these undefined symbol errors.
It does compile and run successfully using -linkmode external
, however, I don't see why it shouldn't work with the Go linker as well, given that zig cc
produces standard ELF object files (same as Clang and GCC).
It looks to me like the fix is simple: the Go linker needs to put libc onto the linker line when it is linking objects that contain libc dependencies.