ZK

Dynamic Versions in golang using ldflags

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