Go 1.18 will embed source version information into binaries

October 26, 2021

Since Go 1.13, Go has embedded information about the modules used to build a program into its binary, and has reported them if you used 'go version -m ...' (release notes). This information has historically included a variety of things, including the path and module that the program was built from, an indication of any module replacements being used, and a marker that the program was being built from a source tree instead of with 'go install ...@...'. However, it hasn't historically included any information about the state of the source tree when you built from source.

In Go 1.18, this is changing due to issue 37475 and issue 35667. To quote from the draft release notes:

The go command now embeds version control information in binaries including the currently checked-out revision and a flag indicating whether edited or untracked files are present. Version control information is embedded if the go command is invoked in a directory within a Git or Mercurial repository, and the main package and its containing main module are in the same repository. This information may be omitted using the flag -buildvcs=false.

Additionally, the go command embeds information about the build including build and tool tags (set with -tags), compiler, assembler, and linker flags (like -gcflags), whether cgo was enabled, and if it was, the values of the cgo environment variables (like CGO_CFLAGS). This information may be omitted using the flag -buildinfo=false. [...]

(I don't know if the module and other information that will be embedded also includes information about the Go workspace you're in, if you're in one.)

At the moment this information is recorded in Go binaries in a form that can be read by Go 1.17's 'go version -m', and probably this also works for earlier versions (as I believe much of this information is actually in the binary as text).

The current information is pretty verbose by default since cgo is generally enabled, and this adds five lines of output, even if the code being compiled didn't actually use it and you have no special environment variables set. I suspect that this won't get reduced before release; the Go team seems to like being comprehensive here.

If nothing else, having this information embedded into binaries will make it harder to lose track of what exactly you're running. Now you have a better chance of figuring out the provenance of some old Go binary that's been running in the corner for who knows how long. People who distribute binaries widely and build them doing funny things may now have more of those funny things be somewhat visible, though. Well, until they turn these features off with those documented flags.

(As threatened, Go 1.18 will only support building programs in module mode, so this information only coming from 'go version -m' doesn't matter any more.)

Sidebar: What this extra information looks like today

Here is the additional output added by this, as reported by 'go version -m' from the current development version:

       build   compiler        gc
       build   tags    goexperiment.regabiwrappers,goexperiment.regabireflect,goexperiment.regabiargs
       build   CGO_ENABLED     true
       build   CGO_CPPFLAGS
       build   CGO_CFLAGS
       build   CGO_CXXFLAGS
       build   CGO_LDFLAGS
       build   gitrevision     4f8a1b5f197fc69bc1252b32b5a8ed670ff557b6
       build   gituncommitted  false

I wouldn't be surprised if some of the current build tags go away in the released version of Go 1.18, as some experiments are promoted out of that state.

Documentation on the current experiments is in the source code in internal/goexperiment/flags.go, and can be gotten for your particular version of Go with 'go doc goexperiment.Flags'. I'm not sure how you can find out the default set of experiments enabled in your version of Go, but in the source code this seems to be in the 'baseline' variable set in ParseGOEXPERIMENT() function in internal/buildcfg/exp.go. The current Go 1.18 build tags reported above appear to be this baseline state on amd64.

Written on 26 October 2021.
« Companies and their stewardship of open source projects
Vim visual mode and an unfortunate restriction on the filter operation »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Tue Oct 26 00:09:30 2021
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.