Closed the-hotmann closed 12 months ago
When building Go applications, you would use GOAMD64
environment variable to configure the compiler. https://github.com/golang/go/wiki/MinimumRequirements#microarchitecture-support
ARG TARGETVARIANT
RUN GOAMD64=$TARGETVARIANT GOOS=...
If you get different binaries or the same depends on if your app uses some feature where Go compiler produces different machine code.
Yeah I know this, I usually work around this by using this RUN
command:
RUN if [ "$TARGETARCH" == "AMD64" ] && [ "$TARGETVARIANT" != "" ]; then \
GOOS=$TARGETOS GOARCH=$TARGETARCH GOAMD64=$TARGETVARIANT CGO_ENABLED=0 go build -ldflags "-s -w" -o appName -v main.go; \
else \
GOOS=$TARGETOS GOARCH=$TARGETARCH CGO_ENABLED=0 go build -ldflags "-s -w" -o appName -v main.go; \
fi
But I just dont get, why it is just working fine for linux/arm/v4
, linux/arm/v5
, linux/arm/v6
, linux/arm/v7
even if I do NOT use $TARGETVARIANT
at all!?
For me this sounds like this is unexpected behaviour.
It is probably the base image that is different for your arm builds, not the generated code from compiler. In Go you would still need to pass GOARM
same way to control the generated code. It isn't a direct GOARM=$TARGETVARIANT
setting there though so helper scripts like xx
https://github.com/tonistiigi/xx/blob/master/src/xx-go#L12 are needed to do it without lot of if statements in the Dockerfile.
if [ "$TARGETARCH" == "AMD64" ]
Btw, these comparisons are case-sensitive so this would never match.
Btw, these comparisons are case-sensitive so this would never match.
My mistake, this actually did the trick - thank you! GOAMD64 thats why I mixed it up. Still I think that this is somehow weird. Should be enough to pass the plattforms, but golang does not support this as simple as this.
Contributing guidelines
I've found a bug and checked that ...
Description
I build a container with this script/command:
Dockerfile:
So all the platforms/architectures are getting build, but all these:
linux/amd64
(basicallylinux/amd64/v1
)linux/amd64/v2
linux/amd64/v3
are 100% the same, and actually they are NOT optimized for the tagged microcode version - they all basically are
linux/amd64
/linux/amd64/v1
. That is good for compatibility, but bad for the optimization, as it basically is just yet another tag that consumes space but does not bring any benefit.Maybe I am in the wrong here, but as I also build the application for:
linux/arm/v4
linux/arm/v5
linux/arm/v6
linux/arm/v7
(basicallylinux/arm
)linux/arm/v8
and they all aswell build successfully and are all indeed unique.
If I just build for
linux/amd64
and add theselinux/amd64/v2
linux/amd64/v3
later, it does not even build them, but instead directly pushes them as they are 'already build' (since it just takeslinux/amd64
for it)Maybe the problem is with me, but I indeed was expecting it to work just like this, as I pass in all the wanted platforms and usually got them out as expected. If the problem is with me, please lead me to the right way - if not, please take this as a bug, or just unexpected behaviour, which does not break anything, but does not work as intended,
Expected behaviour
It really should re-build the app with the new
Microarchitecture level
and therefore also build an app which is made for the specific Microarchitecture level - not just link/copy them.Actual behaviour
For ALL
linux/amd64
versions it just uses the compiledlinux/amd64/v1
build. So you basically always get the same.Buildx version
github.com/docker/buildx v0.11.2 9872040
Docker info
Builders list
Configuration
Build logs
No response
Additional info
For
linux/arm
the microarchitecture level gets passed on, which I also can specify, but when I do the same forlinux/amd64
it does not behave the same.