Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation to address errors like "/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found" #3167

Open
gonzojive opened this issue Jun 1, 2022 · 7 comments

Comments

@gonzojive
Copy link

gonzojive commented Jun 1, 2022

I'm running into the error in the subject line when building locally and deploying in a docker container.

I can't tell if I need to do anything special to make rules_go build hermetically. Based on the output below, I'm guessing my host system's GLIBC is somehow affecting the binaries being compiled, but I'm not sure.

I thought rules_go and bazel mostly ignored the host system's installed libraries and toolchains. Maybe that is not the default behavior?

Relevant links:

  1. Examples on hermetic x86 cc_toolchains? on bazel-discuss
  2. Document setting up a cross-compiling toolchain with cgo #1642

GLIBC links:

  1. https://github.com/bazelbuild/bazel/blob/master/tools/cpp/unix_cc_configure.bzl
  2. https://bazel.build/tutorials/cc-toolchain-config
  3. https://docs.bazel.build/versions/5.1.1/skylark/lib/cc_common.html#create_cc_toolchain_config_info documents target_libc with an example value of "glibc-2.2.2"
  4. https://sourcegraph.com/search?q=context:global+target_libc&patternType=literal - tensorflow seems to define their own toolchains?
  5. https://github.com/bazelRio/bazelRio/blob/1aad71917e2b4e372e295c015b82a8a79c721d2a/bazelrio/toolchains/roborio/toolchain_config.bzl

What version of rules_go are you using?

v0.32.0

What version of gazelle are you using?

v0.25.0

What version of Bazel are you using?

7.1.1

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

Yes

What operating system and processor architecture are you using?

Linux 22.04

Any other potentially useful information about your toolchain?

Local execution but running the cgo binary I'm building on Kubernetes using this rules_docker rule:

container_pull(
    name = "golang_container",
    registry = "index.docker.io",
    repository = "golang",
    tag = "1.18.2-bullseye",
)

What did you do?

I used rules_k8s to deploy a program to a cluster using a locally built docker image. I can provide more details later on. The project I'm working in is a lot like this one, except it uses cgo: https://github.com/gonzojive/beam-go-k8s

load("@io_bazel_rules_docker//go:image.bzl", "go_image")

go_image(
    name = "my-image",
    args = [],
    #base = "@distroless//base:base_root_amd64_debian11",
    #base = "@distroless//cc:cc_root_amd64_debian11",
    #base = "@official_ubuntu//image",
    base = "@golang_container//image",
    binary = ":my-program",
    goarch = "amd64",
    goos = "linux",
)

my-image uses cgo

(I can provide more information if needed)

What did you expect to see?

Successful program execution.

What did you see instead?

Error when running the program in the cluster:

... /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /app/data/...)
... /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by /app/data/...)
@achew22
Copy link
Member

achew22 commented Jun 1, 2022

I believe the issue here is that you don't have a statically linked binary. We already have documentation on how to do that here. What additional docs would you be interested in there being?

@gonzojive
Copy link
Author

gonzojive commented Jun 2, 2022 via email

@achew22
Copy link
Member

achew22 commented Jun 2, 2022

I suppose what I'm looking for is a guide to a reproducible build for code that involves Go with or without C/C++ dependencies.

Why do you believe the builds are not reproducible? If you bazel build twice with a bazel clean in the middle, are you getting different binaries out when you sha256sum the binary? Your build should be deterministic and give the same result between multiple builds, even on different machines. There are no flags that enable reproducibility in any configuration. It should always build reproducibly, there is no way to opt out of that.

gonzojive added a commit to gonzojive/rules-go-cgo-glibc that referenced this issue Jun 3, 2022
@gonzojive
Copy link
Author

Please take a look at https://github.com/gonzojive/rules-go-cgo-glibc.

On ubuntu 18.04, the output is

sha256sum bazel-out/k8-fastbuild/bin/program_/program:
d008634d2a4cee180ce1ab47a0ad5274964e76631590294ac72297746a95f5ff  bazel-out/k8-fastbuild/bin/program_/program
===========================
ldd --verbose bazel-out/k8-fastbuild/bin/program_/program:
        linux-vdso.so.1 (0x00007ffe94923000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f2d203bb000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f2d2019c000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2d1fdab000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f2d20759000)

        Version information:
        bazel-out/k8-fastbuild/bin/program_/program:
                libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6
                libpthread.so.0 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libpthread.so.0
                libpthread.so.0 (GLIBC_2.3.2) => /lib/x86_64-linux-gnu/libpthread.so.0
                libm.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libm.so.6
        /lib/x86_64-linux-gnu/libm.so.6:
                ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2
                libc.so.6 (GLIBC_2.4) => /lib/x86_64-linux-gnu/libc.so.6
                libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6
                libc.so.6 (GLIBC_PRIVATE) => /lib/x86_64-linux-gnu/libc.so.6
        /lib/x86_64-linux-gnu/libpthread.so.0:
                ld-linux-x86-64.so.2 (GLIBC_2.2.5) => /lib64/ld-linux-x86-64.so.2
                ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2
                libc.so.6 (GLIBC_2.14) => /lib/x86_64-linux-gnu/libc.so.6
                libc.so.6 (GLIBC_2.3.2) => /lib/x86_64-linux-gnu/libc.so.6
                libc.so.6 (GLIBC_2.4) => /lib/x86_64-linux-gnu/libc.so.6
                libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6
                libc.so.6 (GLIBC_PRIVATE) => /lib/x86_64-linux-gnu/libc.so.6
        /lib/x86_64-linux-gnu/libc.so.6:
                ld-linux-x86-64.so.2 (GLIBC_2.3) => /lib64/ld-linux-x86-64.so.2
                ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2

On 22.04:

sha256sum bazel-out/k8-fastbuild/bin/program_/program:
0963b7459542358503fb497962cd3bb28c02fb65c86c2324a22e52d9737afe3a  bazel-out/k8-fastbuild/bin/program_/program
===========================
ldd --verbose bazel-out/k8-fastbuild/bin/program_/program:
        linux-vdso.so.1 (0x00007ffeaed85000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f8b5dd53000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8b5db2b000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f8b5de3f000)

        Version information:
        bazel-out/k8-fastbuild/bin/program_/program:
                libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6
                libc.so.6 (GLIBC_2.3.2) => /lib/x86_64-linux-gnu/libc.so.6
                libc.so.6 (GLIBC_2.34) => /lib/x86_64-linux-gnu/libc.so.6
                libc.so.6 (GLIBC_2.32) => /lib/x86_64-linux-gnu/libc.so.6
                libm.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libm.so.6
        /lib/x86_64-linux-gnu/libm.so.6:
                ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2
                libc.so.6 (GLIBC_2.4) => /lib/x86_64-linux-gnu/libc.so.6
                libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6
                libc.so.6 (GLIBC_PRIVATE) => /lib/x86_64-linux-gnu/libc.so.6
        /lib/x86_64-linux-gnu/libc.so.6:
                ld-linux-x86-64.so.2 (GLIBC_2.2.5) => /lib64/ld-linux-x86-64.so.2
                ld-linux-x86-64.so.2 (GLIBC_2.3) => /lib64/ld-linux-x86-64.so.2
                ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2

@gonzojive
Copy link
Author

I'm guessing there's a way to set it up so that a WORKSPACE-supplied gcc is used to make the build reproducible. It seems pretty complicated to accomplish that, however.

@fmeum
Copy link
Member

fmeum commented Jun 3, 2022

If you use CGo, both vanilla Go and rules_go will pick up local libraries - without further setup, there simply isn't anything else to use to satisfy the libc requirement. If you want to be sure that you get a completely hermetic build with CGo, you have to:

  1. Disable Bazel's auto-detection of the host C/C++ toolchain by adding a line like this to your .bazelrc:
common --repo_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1
  1. Set up a hermetic toolchain such as https://github.com/grailbio/bazel-toolchain in your WORKSPACE.
  2. Additionally, use a sysroot (see https://github.com/grailbio/bazel-toolchain/blob/f14a8a5de8f7e98a011a52163d4855572c07a1a3/tests/WORKSPACE#L60-L87 for how to do this with bazel-toolchain).

@gonzojive
Copy link
Author

Thanks so much - great information. Consider adding this answer to the official docs of rules_go (and probably rules_cc as well).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants