Closed lmeunier closed 3 months ago
Ah yes, that's quite some variation. (:
The basic way to compile the latest mox release would be go install github.com/mjl-/mox@latest
. That fetches the mox code as Go module through the Go module proxy, resolving "latest" to the current latest version (git tag).
The command in the README adds GOBIN=$PWD
so the binary ends up in the working directory instead of the Go default of writing it to $HOME/go/bin. For Go developers, that default probably makes sense, but for non-Go-developers compiling mox themselves it's not helpful if the binary goes to some other location.
CGO_ENABLED=0
is added everywhere to prevent linking with C libraries. Compilation works fine without. But then the binary may depend on a local libc, and may prevent the binary from working on other machines with other libc's. The Go runtime may use the libc DNS resolver for some lookups (those that aren't going through the adns library, with CGO_ENABLED=0 they go through the Go stdlib resolver). This is in all the versions of the commands to compile, so it's probably not causing confusion.
The command shown on beta.gobuilds.org has more options to make the compilation reproducible, resulting in the exact same binary (identical bytes). The command has become a bit obscure, so I think it's not worth the obscurity to put the same command in the mox README. Details about the flags and env vars in the command on beta.gobuilds.org:
-trimpath
removes absolute file system paths from the binary (as shown in stack traces). Without this, the binary contains paths of the directory where the binary was built, making it harder to reproduce the identical binary.GO19CONCURRENTCOMPILATION=0
is a workaround for an old "bug" (long since fixed) in the Go toolchain that caused builds in some cases to be non-reproducible (this issue was found by gobuilds.org while verifying against other gobuild instances!).GO111MODULE=on
is for older Go toolchains to force Go module mode. This has been the default for the Go toolchain for a long time now, not actually required for current builds. But gobuilds.org can (in theory) build with old toolchains too.GOPROXY=https://proxy.golang.org/
forces all downloads to go through the Go module proxy, not going directly to the source. This is good for the gobuilds.org service, not for local builds.GOTOOLCHAIN=go1.23.0
sets an explicit toolchain version, preventing any automatic toolchain updates, important for the gobuilds.org service, not for local builds. Same for the explicit version in the Go command.github.com/mjl-/mox@v0.0.11
has the explicit version number (instead of latest) because the gobuilds.org page is for that specific version.The Docker.release file has -trimpath
for reproducibility (and the resulting docker image doesn't have the source anyway). The Go toolchain path is the same, so removing the buildid isn't needed. The -mod mod
ensures the local vendor/ directory (with all dependencies) isn't used, but all dependencies are downloaded. This is how go install github.com/mjl-/mox@latest
would build mox (the mox code is fetched from the Go module proxy, which does not include the vendor/ directory), and it's how the gobuilds.org service builds code. So it's to be closer to those builds.
The Makefile indeed builds twice: After the first build commands, the resulting binary is used to generate help output and API JSON & TS/JS files, and those are included in the binary in the second build. Those generated files are committed to git, so for building using "go install" we don't need to do a second build.
I consider the binaries from gobuilds.org to be the most authoritative releases. The binaries are reproducible, and it's the easiest way to get a binary for the most recent Go toolchain release (its runtime is included in the resulting mox binary). Building it locally is fine too, but there's a small risk that people have a somewhat older local Go toolchain/runtime installed.
Many thanks for taking the time to give such a complete and comprehensible reply. It makes sense now.
According to the README.md file, I can either build mox with the command
GOBIN=$PWD CGO_ENABLED=0 go install github.com/mjl-/mox@latest
or download it from beta.gobuilds.org where an other build command is given (GO19CONCURRENTCOMPILATION=0 GO111MODULE=on GOPROXY=https://proxy.golang.org/ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GOTOOLCHAIN=go1.23.0 go1.23.0 install -trimpath -ldflags='-buildid=' -- github.com/mjl-/mox@v0.0.11
);According to the Docker.release file, the command
CGO_ENABLED=0 GOOS=$goos GOARCH=$goarch go install -mod mod -trimpath github.com/mjl-/mox@$moxversion
is used to build mox, the result is then copied to the Docker image.And according to the Makefile, the command
make build
builds mox twice, builds a nodejs frontend and runs some shell scripts.So, I'm wondering what is the proper way to build a mox release and what are the differences between methods listed above.