In order to compile a fully static binary when using Cgo you'll need to use another standard C library like musl instead of the GNU libc, because Canonical and others simply decided that most of the whole damn point of using Golang, which is having a multi-platform and almost universal build toolchain, is simply not to their tastes.
A solution then is to do this messy thingy:
apt update && apt build-dep -y musl
MUSL_VER=2.2.2 # Matches Ubuntu 22.04 "Jammy" as of 2023-01-06
DIR=$(mktemp -d)
pushd $DIR
wget https://www.musl-libc.org/releases/musl-${MUSL_VER}.tar.gz -O musl.tar.gz
tar -zxf ../musl.tar.gz
cd musl-*
./configure --enable-static --disable-shared
make -j && make install
popd
Proceed to git clone
the repository you want to build into ${GOPATH:-${HOME}/go}/src/<canonical_repo_path>
, like ${GOPATH:-${HOME}/go}/src/github.com/peakgames/s5cmd
(the git install
command suggested by the CLI is broken right now and the Go developers removed a large part of the previously finally a little bit sane go get
functionality).
Run go get
after changing directory to that previous path, then run the following to build your progam:
PATH="/usr/local/musl/bin:${PATH}" CGO_ENABLED=1 CC=musl-gcc go build --ldflags '-linkmode external -extldflags "-static"'
Forget about running go install
to, well, install your just-built package because Go will not care even a tinny bit about your data or your effort so far, and will instead rebuild your binary again with dynamic linking against the glibc before copying the build result to the PATH. Instead, just copy the damn binary to ${GOBIN:-${GOPATH}/bin}
, /usr/local/bin
, ${HOME}/.bin
or whatever floats your boat and you should be gold.