Skip to content

go1.20: Suddenly linking static binaries #3590

@zecke

Description

@zecke

What version of rules_go are you using?

0.39.0

What version of gazelle are you using?

0.30.0

What version of Bazel are you using?

6.2.1

Does this issue reproduce with the latest releases of all the above?

Yes

What operating system and processor architecture are you using?

Linux. Reproduces on x86_64 and aarch64

Any other potentially useful information about your toolchain?

It needs to have cgo selected

What did you do?

$ cat .bazelrc
build --features=fully_static_link --dynamic_mode=off

$ cat WORKSPACE
workspace(name = "rules_go_static")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "io_bazel_rules_go",
    sha256 = "6b65cb7917b4d1709f9410ffe00ecf3e160edf674b78c54a894471320862184f",
    urls = [
        "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.39.0/rules_go-v0.39.0.zip",
        "https://github.com/bazelbuild/rules_go/releases/download/v0.39.0/rules_go-v0.39.0.zip",
    ],
)

http_archive(
    name = "bazel_gazelle",
    sha256 = "727f3e4edd96ea20c29e8c2ca9e8d2af724d8c7778e7923a854b2c80952bc405",
    urls = [
        "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.30.0/bazel-gazelle-v0.30.0.tar.gz",
        "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.30.0/bazel-gazelle-v0.30.0.tar.gz",
    ],
)

load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")

go_rules_dependencies()

#go_register_toolchains(version = "1.19.3")
go_register_toolchains(version = "1.20.3")

gazelle_dependencies()

$ cat BUILD.bazel
load("@io_bazel_rules_go//go:def.bzl", "go_binary")

go_binary(
    name = "hello",
    srcs = ["hello.go"],
    cgo = True,
)

$ cat hello.go
package main

import (
	"fmt"
	"os/user"
)

func main() {
	u, _ := user.Current()
	print(u)
	fmt.Println("vim-go")
}


$ bazel build //:hello && file ./bazel-bin/hello_/hello

What did you expect to see?

For Go1.19.3 I see this:

./bazel-bin/hello_/hello: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, Go BuildID=redacted, with debug_info, not stripped

What did you see instead?

For Go1.20 I see this:

/tmp/go-link-3680801931/000001.o:cgo_lookup_cgo.cgo2.c:function mygetpwuid_r: warning: Using 'getpwuid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/tmp/go-link-3680801931/000001.o:cgo_lookup_cgo.cgo2.c:function mygetpwnam_r: warning: Using 'getpwnam_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/tmp/go-link-3680801931/000001.o:cgo_lookup_cgo.cgo2.c:function mygetgrgid_r: warning: Using 'getgrgid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/tmp/go-link-3680801931/000001.o:cgo_lookup_cgo.cgo2.c:function mygetgrnam_r: warning: Using 'getgrnam_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/tmp/go-link-3680801931/000002.o:getgrouplist_unix.cgo2.c:function mygetgrouplist: warning: Using 'getgrouplist' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
...
./bazel-bin/hello_/hello: ELF 64-bit LSB executable, ARM aarch64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.7.0, Go BuildID=redacted, with debug_info, not stripped

With Go1.19 the binary was linked dynamically against glibc besides the features selection. In Go 1.20 this suddenly becomes statically linked. It is a surprising behavior change, especially as the go_binary rule has selection for pure/cgo/static.

I noticed this because a grpc protoc compiler plugin started to crash (when the log library invoked the app as the glibc version of the host and link didn't match...)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions