-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
doc: best practices for cross-compiling universal binaries to distribute #48540
Comments
One question might be: why not automate all of this via a tool similar to https://pkg.go.dev/golang.org/x/exp/cmd/gorelease? That might certainly be a good idea. I still think documenting the general best practices is a must, because many of these decisions will vary depending on the project. One great example is CGo: some projects require it for their release builds, some others avoid it. So an automated tool may be a good idea, but I see it as a layer on top of this doc page. You could think of it as a tool that automates the most common decisions for the list above, to be sufficient for >90% of Go projects. |
I also realise many such "automating" tools exist, like goreleaser. That's pretty out of scope, as they tend to do far more than just build binaries, and still fall under "would build on top of this doc page". |
I should also note that the advice gets increasingly complex if you dive into any of the topics at hand. For example, if you choose to build with CGo, then you have to be careful with what versions of C libraries you're building. Cross-compiling with CGo also brings its own toolchain problems, such as #47175 and #44112. I don't think the doc page should aim to be exhaustive with all these narrow topics, but it could certainly point the users towards other threads or docs which do. |
More complexity added when signing or notarizing binaries e.g. for Mac. |
GOAMD64=v3 will also leave out CPUs as new as 2021 atom, pentium and celeron chips and amd embedded still being produced which are used a lot in NAS devices, routers and low end laptops as none of these have AVX: https://www.cpu-world.com/Compare_CPUs/Intel_J6413,Intel_CM8070104291511/? |
This issue is somewhat similar to #42119, in that it would be a collection of general recommendations for a fairly common use case that I see users struggle with.
Cross-compiling in Go is simple - for example, from
linux/amd64
, I can build a binary forwindows/arm64
via justGOOS=windows GOARCH=arm64 go build
. However, in practice that's often not enough when one wants to publish prebuilt binaries as part of a release's "download" page.In no particular order, one needs to consider:
GOOS/GOARCH
combinations to build for. I personally go for the first class ports on my projects via cmd/dist: show which GOOS/GOARCH combinations are first class ports #38874. Other projects might want a broader set.CGO_ENABLED
on (=1
) or off (=0
). By default, it will be on for the host target, and off for all other targets. This can result in confusion and bugs, as one binary behaves differently from the others.-trimpath
. For others to reproduce the same binary, full instructions should be published, including the Go version and build commands.GOAMD64=v3
will leave out most pre-2013 x86 users. Explicitly lowering these requirements is a good idea since your system might have higher defaults.Note that these are general recommendations, and not must-haves by any means. For example, maybe I don't want my cgo binaries to be fully static, because my users want to supply their own version of a large C dependency. Or maybe my hardware requirements are higher because my project targets specific new hardware that already meets those.
The text was updated successfully, but these errors were encountered: