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

set CGO_ENABLED=0 when building release artifacts #60

Merged
merged 1 commit into from
Jun 3, 2024

Conversation

jameslamb
Copy link
Member

@jameslamb jameslamb commented May 24, 2024

Description

This project's release artifacts are currently built in a VM using GitHub Actions' ubuntu-latest image.

As of today, that's Ubuntu 22.04 (actions/runner-images), which has glibc 2.35.

Those builds are dynamically linking to glibc, and using some symbols from new-ish versions. As a result, using them on a just-slightly-older Linux environment (e.g. Ubuntu 20.04, which has glibc 2.31), results in errors like the following:

/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by /opt/work/bin/canary_linux_amd64)
/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /opt/work/bin/canary_linux_amd64)

This proposes setting CGO_ENABLED=0 when cross-compiling for Linux, so the artifact will statically link in what it needs and therefore be usable on systems with older glibc.

Notes for Reviewers

How I tested this

built with this setting on and off on Ubuntu 22.04, tested on Ubuntu 20.04 (click for details)

Built inside an Ubuntu 22.04 image

docker run \
    --rm \
    -v $(pwd):/opt/work \
    -w /opt/work \
    -it ubuntu:22.04 \
    bash

apt-get update
apt-get install -y --no-install-recommends \
    build-essential \
    ca-certificates \
    git \
    golang-go

git config --global --add safe.directory /opt/work

# build with default settings
make package
mv bin bin-cgo

# build with CGO off
export CGO_ENABLED=0
make package
mv bin bin-no-cgo

Tried using those on Ubuntu 20.04. The CGO-enabled one failed to run.

docker run \
    --rm \
    -v $(pwd):/opt/work:ro \
    -it ubuntu:20.04 \
    /opt/work/bin-cgo/canary_linux_amd64 version
# /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by /opt/work/bin-cgo/canary_linux_amd64)
# /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /opt/work/bin-cgo/canary_linux_amd64)

But the no-cgo one worked!

docker run \
    --rm \
    -v $(pwd):/opt/work:ro \
    -it ubuntu:20.04 \
    /opt/work/bin-no-cgo/canary_linux_amd64 version
# Container Canary
# Version:         a4f5c79-dirty
# Go Version:      go1.18.1
# Commit:          a4f5c79
# OS/Arch:         linux/amd64
# Built:           2024-05-24T17:12:44Z

And the no-cgo one worked validating an image! Ran the following outside of Docker, on an Ubuntu 20.04 VM.

bin-no-cgo/canary_linux_amd64 validate \
    --file https://raw.githubusercontent.com/NVIDIA/container-canary/main/examples/kubeflow.yaml \
    "ghcr.io/dask/dask-notebook"
Validating ghcr.io/dask/dask-notebook against kubeflow
 🆔 User ID is 1000                                  [passed]
 🏠 Home directory is /home/jovyan                   [passed]
 👩 User is jovyan                                   [passed]
 🌏 Exposes an HTTP interface on port 8888           [passed]
 🔓 Sets 'Access-Control-Allow-Origin: *' header     [passed]
 🧭 Correctly routes the NB_PREFIX                   [passed]
validation passed

Why not set this in the CI environment?

I chose to set this inline in the 2 Linux builds in make package so that if you run make package locally on a Linux system, it'll produce a similar artifact to the one produced in CI. To hopefully improve the chance of local tests catching issues.

But happy to change to any of these alternatives if someone has a compelling reason:

  • set it globally in the environment of the CI job(s)
  • set it for all go build commands in make package (not just Linux)
  • set it in some other place

Won't statically linking make the binary bigger?

I didn't find any meaningful change in binary size as a result of doing this. With and without CGO_ENABLED, canary_linux_amd64 was about 21MB.

References

@jameslamb jameslamb added the enhancement New feature or request label May 24, 2024
@jameslamb jameslamb requested a review from a team as a code owner May 24, 2024 17:38
Signed-off-by: James Lamb <jlamb@nvidia.com>
Copy link
Member

@jacobtomlinson jacobtomlinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't find any meaningful change in binary size as a result of doing this.

This was my only concern so thanks for verify it's a non-issue.

@jacobtomlinson jacobtomlinson merged commit c473896 into NVIDIA:main Jun 3, 2024
7 checks passed
@jacobtomlinson
Copy link
Member

I've just tagged v0.3.2 which will have statically linked linux binaries. Thanks!

@jameslamb jameslamb deleted the no-cgo branch June 3, 2024 13:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants