mirror of
https://github.com/docker/cli.git
synced 2026-11-06 13:10:41 -04:00
Pass -w to the Go linker to reduce binary size while retaining the
symbol table for tools that inspect Go binaries.
For a linux/arm64 build, this reduces the CLI binary from 39,809,791
to 31,310,197 bytes: a saving of 8.5 MB (21.4%).
Place the default before caller-supplied GO_LDFLAGS so builds can
retain DWARF by passing GO_LDFLAGS="-w=0".
Before
ls -l /go/src/github.com/docker/cli/build/docker-linux-arm64
-rwxr-xr-x 1 root root 39809791 Oct 29 17:34 /go/src/github.com/docker/cli/build/docker-linux-arm64
After
ls -l /go/src/github.com/docker/cli/build/docker-linux-arm64
-rwxr-xr-x 1 root root 31310197 Oct 29 17:36 /go/src/github.com/docker/cli/build/docker-linux-arm64
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
143 lines
5.0 KiB
Bash
Executable File
143 lines
5.0 KiB
Bash
Executable File
#!/usr/bin/env sh
|
|
set -eu
|
|
|
|
: "${CGO_ENABLED=}"
|
|
: "${GO_LINKMODE=static}"
|
|
: "${GO_BUILDMODE=}"
|
|
: "${GO_BUILDTAGS=}"
|
|
: "${GO_STRIP=}"
|
|
|
|
TARGET=${TARGET:-"build"}
|
|
|
|
PLATFORM=${PLATFORM:-}
|
|
VERSION=${VERSION:-$(git describe --match 'v[0-9]*' --dirty='.m' --always --tags | sed 's/^v//' 2>/dev/null || echo "unknown-version" )}
|
|
GITCOMMIT=${GITCOMMIT:-$(git rev-parse --short HEAD 2> /dev/null || true)}
|
|
|
|
if [ "$(uname)" = "Darwin" ]; then
|
|
# Using BSD date (macOS), which doesn't suppoort the --date option
|
|
# date -jf "<input format>" "<input value>" +"<output format>" (https://unix.stackexchange.com/a/86510)
|
|
BUILDTIME=${BUILDTIME:-$(TZ=UTC date -jf "%s" "${SOURCE_DATE_EPOCH:-$(date +%s)}" +"%Y-%m-%dT%H:%M:%SZ")}
|
|
else
|
|
# Using GNU date (Linux)
|
|
BUILDTIME=${BUILDTIME:-$(TZ=UTC date -u --date="@${SOURCE_DATE_EPOCH:-$(date +%s)}" +"%Y-%m-%dT%H:%M:%SZ")}
|
|
fi
|
|
|
|
case "$VERSION" in
|
|
refs/tags/v*) VERSION=${VERSION#refs/tags/v} ;;
|
|
refs/tags/*) VERSION=${VERSION#refs/tags/} ;;
|
|
refs/heads/*) VERSION=$(echo "${VERSION#refs/heads/}" | sed -r 's#/+#-#g') ;;
|
|
refs/pull/*) VERSION=pr-$(echo "$VERSION" | grep -o '[0-9]\+') ;;
|
|
esac
|
|
|
|
GOOS="$(go env GOOS)"
|
|
GOARCH="$(go env GOARCH)"
|
|
if [ "${GOARCH}" = "arm" ]; then
|
|
GOARM="$(go env GOARM)"
|
|
fi
|
|
|
|
TARGET="$TARGET/docker-${GOOS}-${GOARCH}"
|
|
if [ "${GOARCH}" = "arm" ] && [ -n "${GOARM}" ]; then
|
|
TARGET="${TARGET}-v${GOARM}"
|
|
fi
|
|
if [ "${GOOS}" = "windows" ]; then
|
|
TARGET="${TARGET}.exe"
|
|
fi
|
|
export TARGET
|
|
|
|
# No CGO when cross building to darwin
|
|
if [ "$(go env GOOS)" = "darwin" ] && [ "$(uname)" != "Darwin" ]; then
|
|
if [ -z "$CGO_ENABLED" ]; then
|
|
CGO_ENABLED=0
|
|
elif [ "$CGO_ENABLED" = "1" ]; then
|
|
echo "CGO_ENABLED=1 not supported when cross-compiling for Darwin"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
if [ -z "$CGO_ENABLED" ]; then
|
|
case "$(go env GOOS)" in
|
|
linux)
|
|
case "$(go env GOARCH)" in
|
|
amd64|arm64|arm|s390x|riscv64|loong64)
|
|
CGO_ENABLED=1
|
|
;;
|
|
*)
|
|
CGO_ENABLED=0
|
|
;;
|
|
esac
|
|
;;
|
|
darwin|windows)
|
|
CGO_ENABLED=1
|
|
;;
|
|
*)
|
|
CGO_ENABLED=0
|
|
;;
|
|
esac
|
|
fi
|
|
export CGO_ENABLED
|
|
|
|
if [ "$CGO_ENABLED" = "1" ] && [ "$(go env GOOS)" != "windows" ]; then
|
|
case "$(go env GOARCH)" in
|
|
mips*|ppc64)
|
|
# pie build mode is not supported on mips architectures
|
|
;;
|
|
*)
|
|
GO_BUILDMODE="-buildmode=pie"
|
|
;;
|
|
esac
|
|
fi
|
|
export GO_BUILDMODE
|
|
|
|
# Omit DWARF debug information to reduce binary size, but retain the symbol
|
|
# table for tools that inspect Go binaries. Pass GO_LDFLAGS="-w=0" to retain DWARF.
|
|
GO_LDFLAGS="-w ${GO_LDFLAGS:-}"
|
|
|
|
# Quotes are interpreted by Go's -ldflags parser, not the shell.
|
|
# shellcheck disable=SC2089
|
|
{
|
|
GO_LDFLAGS="$GO_LDFLAGS -X \"github.com/docker/cli/cli/version.GitCommit=${GITCOMMIT}\""
|
|
GO_LDFLAGS="$GO_LDFLAGS -X \"github.com/docker/cli/cli/version.BuildTime=${BUILDTIME}\""
|
|
GO_LDFLAGS="$GO_LDFLAGS -X \"github.com/docker/cli/cli/version.Version=${VERSION}\""
|
|
if test -n "${PLATFORM}"; then
|
|
GO_LDFLAGS="$GO_LDFLAGS -X \"github.com/docker/cli/cli/version.PlatformName=${PLATFORM}\""
|
|
fi
|
|
}
|
|
if [ "$CGO_ENABLED" = "1" ] && [ "$GO_LINKMODE" = "static" ] && [ "$(go env GOOS)" = "linux" ]; then
|
|
GO_LDFLAGS="$GO_LDFLAGS -linkmode external -extldflags -static"
|
|
fi
|
|
|
|
# We only import google.golang.org/grpc as an indirect dependency, and
|
|
# do not make gRPC connections.
|
|
#
|
|
# grpcnotrace avoids importing golang.org/x/net/trace, which in turn enables
|
|
# dead code elimination, which can reduce binary size when tracing is not needed.
|
|
#
|
|
# see https://github.com/grpc/grpc-go/blob/v1.81.1/trace_notrace.go#L23-L25
|
|
GO_BUILDTAGS="$GO_BUILDTAGS grpcnotrace"
|
|
|
|
if [ "$CGO_ENABLED" = "1" ] && [ "$GO_LINKMODE" = "static" ]; then
|
|
# compiling statically with CGO enabled requires osusergo and netgo to be set.
|
|
GO_BUILDTAGS="$GO_BUILDTAGS osusergo netgo"
|
|
fi
|
|
# XXX: Disable netgo on Windows and use Windows system resolver instead.
|
|
#
|
|
# go1.19 and newer added support for netgo on Windows (https://go.dev/doc/go1.19#net),
|
|
# which may not respect VPN adaptors (such as Twingate) due to resolver ordering,
|
|
# resulting in queries being sent through the local network adapter instead of the
|
|
# VPN tunnel. See https://github.com/docker/cli/issues/6665
|
|
if [ "$(go env GOOS)" = "windows" ]; then
|
|
GO_BUILDTAGS=$(echo "$GO_BUILDTAGS" | sed 's/\(^\| \)netgo\( \|$\)/\1/g')
|
|
fi
|
|
if [ -n "$GO_STRIP" ]; then
|
|
# if stripping enabled and building with llvm < 12 against darwin/amd64
|
|
# platform, it will fail with:
|
|
# # github.com/docker/cli/cmd/docker
|
|
# /usr/local/go/pkg/tool/linux_amd64/link: /usr/local/go/pkg/tool/linux_amd64/link: running strip failed: exit status 1
|
|
# llvm-strip: error: unsupported load command (cmd=0x5)
|
|
# more info: https://github.com/docker/cli/pull/3717
|
|
GO_LDFLAGS="$GO_LDFLAGS -s"
|
|
fi
|
|
export GO_LDFLAGS="$GO_LDFLAGS" # https://github.com/koalaman/shellcheck/issues/2064
|
|
|
|
export SOURCE="github.com/docker/cli/cmd/docker"
|