Skip to content

cmd/cgo, cmd/link: with zig as CC/CXX, Go linker does not put libc onto the linker line, causing undefined symbol errors #52690

Closed
@andrewrk

Description

@andrewrk

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions