Dockerfile: use TARGETPLATFORM to build Docker
follow-up #43529
~needs https://github.com/moby/moby/pull/44513~

fixes https://github.com/moby/moby/pull/41590
fixes https://github.com/moby/moby/issues/41862
fixes https://github.com/moby/moby/issues/41519
fixes https://github.com/moby/moby/issues/39380
closes https://github.com/moby/moby/pull/43492
closes https://github.com/moby/moby/pull/43613

Better support for cross compilation so we can fully rely on `--platform` flag of buildx for a seamless integration.

This removes unnecessary extra cross logic in the Dockerfile, removes `DOCKER_CROSSPLATFORMS` and `CROSS` vars and some hack scripts as well.

Non-sandboxed build invocation is still supported and dev stages in the Dockerfile have been updated accordingly.

Bake definition and GitHub Actions workflows have been updated accordingly as well.

cc @thaJeztah @rumpl @vvoland 
hack/make/.binary
#!/usr/bin/env bash
set -e

# a helper to provide ".exe" when it's appropriate
binary_extension() {
	if [ "$(go env GOOS)" = 'windows' ]; then
		echo -n '.exe'
	fi
}

BINARY_EXTENSION="$(binary_extension)"
BINARY_FULLNAME="$BINARY_NAME$BINARY_EXTENSION"

source "${MAKEDIR}/.go-autogen"

(
	export GOGC=${DOCKER_BUILD_GOGC:-1000}

	if [ "$(go env GOOS)/$(go env GOARCH)" != "$(go env GOHOSTOS)/$(go env GOHOSTARCH)" ]; then
		# must be cross-compiling!
		case "$(go env GOOS)/$(go env GOARCH)" in
			windows/amd64)
				export CC="${CC:-x86_64-w64-mingw32-gcc}"
				export CGO_ENABLED=1
				;;
			linux/arm)
				case "${GOARM}" in
					5)
						export CC="${CC:-arm-linux-gnueabi-gcc}"
						export CGO_ENABLED=1
						export CGO_CFLAGS="-march=armv5t"
						export CGO_CXXFLAGS="-march=armv5t"
						;;
					6)
						export CC="${CC:-arm-linux-gnueabi-gcc}"
						export CGO_ENABLED=1
						export CGO_CFLAGS="-march=armv6"
						export CGO_CXXFLAGS="-march=armv6"
						;;
					7)
						export CC="${CC:-arm-linux-gnueabihf-gcc}"
						export CGO_ENABLED=1
						export CGO_CFLAGS="-march=armv7-a"
						export CGO_CXXFLAGS="-march=armv7-a"
						;;
					*)
						export CC="${CC:-arm-linux-gnueabihf-gcc}"
						export CGO_ENABLED=1
						;;
				esac
				;;
			linux/arm64)
				export CC="${CC:-aarch64-linux-gnu-gcc}"
				export CGO_ENABLED=1
				;;
			linux/amd64)
				export CC="${CC:-x86_64-linux-gnu-gcc}"
				export CGO_ENABLED=1
				;;
			linux/ppc64le)
				export CC="${CC:-powerpc64le-linux-gnu-gcc}"
				export CGO_ENABLED=1
				;;
			linux/s390x)
				export CC="${CC:-s390x-linux-gnu-gcc}"
				export CGO_ENABLED=1
				;;
		esac
	fi

	# -buildmode=pie is not supported on Windows and Linux on mips, riscv64 and ppc64be.
	# https://github.com/golang/go/blob/77aa209b386a184e7f4b44938f2a05a1b5c5a3cf/src/cmd/internal/sys/supported.go#L89-L99
	case "$(go env GOOS)/$(go env GOARCH)" in
		windows/* | linux/mips* | linux/riscv* | linux/ppc64) ;;
		# TODO remove windows in Go 1.15+: https://github.com/golang/go/commit/95f382139043059a2a0780ba577b53893408f7e4
		# TODO remove riscv64 in Go 1.16+: https://github.com/golang/go/commit/8eb846fd37eb7bded8a1cf6932be2c59069863e5

		*)
			BUILDFLAGS+=("-buildmode=pie")
			;;
	esac

	echo "Building: $DEST/$BINARY_FULLNAME"
	echo "GOOS=\"${GOOS}\" GOARCH=\"${GOARCH}\" GOARM=\"${GOARM}\""
	go build \
		-o "$DEST/$BINARY_FULLNAME" \
		"${BUILDFLAGS[@]}" \
		-ldflags "
		$LDFLAGS
		$LDFLAGS_STATIC_DOCKER
		$DOCKER_LDFLAGS
	" \
		${GO_PACKAGE}
)

echo "Created binary: $DEST/$BINARY_FULLNAME"

#!/usr/bin/env bash
set -e

# a helper to provide ".exe" when it's appropriate
binary_extension() {
	if [ "$(go env GOOS)" = 'windows' ]; then
		echo -n '.exe'
	fi
}

BINARY_EXTENSION="$(binary_extension)"
BINARY_FULLNAME="$BINARY_NAME$BINARY_EXTENSION"

source "${MAKEDIR}/.go-autogen"

(
	export GOGC=${DOCKER_BUILD_GOGC:-1000}

	# for non-sandboxed invocation
	if ! command -v xx-go > /dev/null 2>&1; then
		if [ "$(go env GOOS)/$(go env GOARCH)" != "$(go env GOHOSTOS)/$(go env GOHOSTARCH)" ]; then
			# must be cross-compiling!
			case "$(go env GOOS)/$(go env GOARCH)" in
				windows/amd64)
					export CC="${CC:-x86_64-w64-mingw32-gcc}"
					export CGO_ENABLED=1
					;;
				linux/arm)
					case "${GOARM}" in
						5)
							export CC="${CC:-arm-linux-gnueabi-gcc}"
							export CGO_ENABLED=1
							export CGO_CFLAGS="-march=armv5t"
							export CGO_CXXFLAGS="-march=armv5t"
							;;
						6)
							export CC="${CC:-arm-linux-gnueabi-gcc}"
							export CGO_ENABLED=1
							export CGO_CFLAGS="-march=armv6"
							export CGO_CXXFLAGS="-march=armv6"
							;;
						7)
							export CC="${CC:-arm-linux-gnueabihf-gcc}"
							export CGO_ENABLED=1
							export CGO_CFLAGS="-march=armv7-a"
							export CGO_CXXFLAGS="-march=armv7-a"
							;;
						*)
							export CC="${CC:-arm-linux-gnueabihf-gcc}"
							export CGO_ENABLED=1
							;;
					esac
					;;
				linux/arm64)
					export CC="${CC:-aarch64-linux-gnu-gcc}"
					export CGO_ENABLED=1
					;;
				linux/amd64)
					export CC="${CC:-x86_64-linux-gnu-gcc}"
					export CGO_ENABLED=1
					;;
				linux/ppc64le)
					export CC="${CC:-powerpc64le-linux-gnu-gcc}"
					export CGO_ENABLED=1
					;;
				linux/s390x)
					export CC="${CC:-s390x-linux-gnu-gcc}"
					export CGO_ENABLED=1
					;;
			esac
		fi
	fi

	# -buildmode=pie is not supported on Windows arm64 and Linux mips*, ppc64be
	# https://github.com/golang/go/blob/go1.19.4/src/cmd/internal/sys/supported.go#L125-L132
	if ! [ "$DOCKER_STATIC" = "1" ]; then
		case "$(go env GOOS)/$(go env GOARCH)" in
			windows/arm64 | linux/mips* | linux/ppc64) ;;
			*)
				BUILDFLAGS+=("-buildmode=pie")
				;;
		esac
	fi

	# only necessary for non-sandboxed invocation where TARGETPLATFORM is empty
	PLATFORM_NAME=$TARGETPLATFORM
	if [ -z "$PLATFORM_NAME" ]; then
		PLATFORM_NAME="$(go env GOOS)/$(go env GOARCH)"
		if [ -n "$(go env GOARM)" ]; then
			PLATFORM_NAME+="/$(go env GOARM)"
		elif [ -n "$(go env GOAMD64)" ] && [ "$(go env GOAMD64)" != "v1" ]; then
			PLATFORM_NAME+="/$(go env GOAMD64)"
		fi
	fi

	echo "Building $([ "$DOCKER_STATIC" = "1" ] && echo "static" || echo "dynamic") $DEST/$BINARY_FULLNAME ($PLATFORM_NAME)..."
	go build \
		-o "$DEST/$BINARY_FULLNAME" \
		"${BUILDFLAGS[@]}" \
		-ldflags "
		$LDFLAGS
		$LDFLAGS_STATIC_DOCKER
		$DOCKER_LDFLAGS
	" \
		${GO_PACKAGE}
)

echo "Created binary: $DEST/$BINARY_FULLNAME"

Wondering if this check is one of the things missing in containerd's makefiles / scripts 🤔 