Lately, while working on my side project kvmcli , I ran into an issue. I had a version option in kvmcli, but I didn’t have a proper way to dynamically retrieve the latest version of the project when running:
kvmcli version
As a temporary workaround, I was manually updating the version inside the global config file /etc/kvmcli/kvmcli.toml under the meta section. But honestly, that approach is stupid.
The proper approach
What I learned recently is a Go concept called ldflags (linker flags). It allows you to inject values into variables at build time.
That’s exactly what I needed.
So the idea is simple: define a global variable in your code:
var Version = "None"
Then, at build time, override it dynamically.
Getting the last tag on a repo
With the following command on my git repo
git describe --tags --always
I can get the most recent tag (or commit hash if no tag exists).
Injecting the version at build time
I can pass this value into my Go binary using ldflags:
VERSION=$(git describe --tags --always)
go build -ldflags "-X <project url>/<package>.<Variable>=$VERSION"
In my case, the Version variable lives inside the cmd package, so the actual command becomes:
VERSION=$(git describe --tags --always)
go build -ldflags "-X github.com/zakariakebairia/kvmcli/cmd.Version=$VERSION"
Using a Makefile
Since I’m using a Makefile for kvmcli, I integrated everything there:
GO = /usr/local/go/bin/go
PROJECT := github.com/zakariakebairia/kvmcli
VERSION ?= $(shell git describe --tags --always --dirty)
LDFLAGS := -X $(PROJECT)/cmd.Version=$(VERSION)
all: build
build:
@echo "Building $(PROJECT)..."
$(GO) build -ldflags "$(LDFLAGS)" -o kvmcli .
Now when I run:
kvmcli version
I get:
kvmcli v0.4.1
Going further
You can extend this idea to include more build metadata like:
- commit hash
- build timestamp
- Go version
kvmcli version
kvmcli v0.4.1
commit: 20fa8ea
built: 2026-04-18T20:01:25Z
go: go1.25.3