I'm trying to read version control information from my Go binaries, but the build info doesn't seem to contain any VCS info.
From the Go 1.18 release notes:
The go command now embeds version control information in binaries. It includes the currently checked-out revision, commit time, 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, Mercurial, Fossil, or Bazaar 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.
Sample program:
package main
import (
"fmt"
"runtime/debug"
)
func main() {
if bi, ok := debug.ReadBuildInfo(); ok {
fmt.Printf("%+v\n", bi)
}
}
Using this code, here's my output:
go go1.18 path [redacted] mod [redacted] (devel) dep [redacted] v1.2.3 build -compiler=gc build CGO_ENABLED=1 build CGO_CFLAGS= build CGO_CPPFLAGS= build CGO_CXXFLAGS= build CGO_LDFLAGS= build GOARCH=amd64 build GOOS=windows build GOAMD64=v1
I expected to see this included, but didn't:
build vcs=git build vcs.revision=[sha] build vcs.time=2022-03-28T03:11:12Z build vcs.modified=true
I'm running the go
command from the root directory of a git repo, and the repo has commits. The program I'm building is in a subdirectory of the repo.
I have tried a number of different variations for building the binary, but none of them worked:
go run client/main.go
go build -o client.exe client/main.go && ./client.exe
go build -o client.exe client/main.go && ./client.exe
go build -o client.exe -buildvcs=true client/main.go && ./client.exe
To be clear, the program builds and executes, but doesn't contain embedded VCS information.
I also tried using go version -m client.exe
to see if that could read something that the binary couldn't read about itself, but the results were the same.
I'm using the first release of Go 1.18, so -buildvcs
should still default to true
as far as I know. I saw on the issue tracker that a future minor release will likely change the default to -buildvcs=auto
.
As far as I can tell, both conditions listed in the release notes (go
is invoked in a directory inside a git repo, and the main package is in the same repo) should both be satisfied when building from the project root. What might I be doing wrong?
go
command operates on packages -- you usually never want to use filename arguments. Usinggo build
with the full package name, or your relative path from within the module (e.g.go build ./client
) would suffice. – Cellgo build client/
from the project root and it resulted in an error of "package is not in GOROOT", butgo build ./client
worked as you suggested. If you were the one that downvoted the question could you explain how I might improve the quality of the question? – AfghaniGOROOT
only ever contained the stdlib packages, but it's sort of the "end of the line" when it runs out of places to search, so that's the error you see. If your module were calledclient
and contained a go package at the root level, the command would then be valid, though it would build the current directory rather that./client
. You either have to be explicit by using the full package name, or a non-ambiguous path. – Cell