Injeksjon av variabler under kompilering i Go: bruk av go build -ldflags -X

Bakgrunn
Da jeg arbeidet med et prosjekt for selskapet, lette jeg etter en måte å injisere variabler under kompileringen uten å bruke .env. Jeg tenkte at dette ville være svært praktisk, siden man da bare trenger én fil i stedet for .env og flere konfigurasjonsfiler.
Først lette jeg etter et go:generate-CLI-verktøy som kunne generere en konstantfil basert på .env, men fant ingen slik løsning.
Men i så fall kunne man like gjerne bare endre constants direkte, uten å måtte kjøre generering, og jeg fant derfor en metode for å injisere verdier under kompileringen, lik include_bytes!-makroen i Rust.
Injisering av variabler under kompilering
Bruken er enkel.
1package main
2
3import "fmt"
4
5var Foo string
6
7func main() {
8 fmt.Println(Foo)
9}
Gitt koden ovenfor, kan man injisere verdien under bygging på følgende måte.
1go build -ldflags="-X 'main.Foo=bar'"
Ved å sende argumentet via ldflag injiseres verdien bar i variabelen Foo under kompileringen. Det er enkelt.
Dersom prosjektet har pakker eller variabler med samme navn på flere steder, kan man angi pakkebanen eksplisitt.
1// github.com/myproject/config/config.go
2package config
3
4var Version string
5
6// github.com/myproject/internal/config/config.go
7package config
8
9var BuildTime string
I slike tilfeller kan man skille mellom dem på følgende måte:
1go build -ldflags="-X 'github.com/myproject/config.Version=v1.0.0' -X 'github.com/myproject/internal/config.BuildTime=2025-05-27'"
Også når flere variabler finnes i samme pakke, er det tilstrekkelig å legge til ekstra argumenter.
1go build -ldflags="-X 'main.Version=v1.0.0' -X 'main.BuildTime=2025-05-27' -X 'main.GitCommit=abc123'"
Egenskapene er som følger:
- Variabelen trenger ikke å være offentlig: Variabler som starter med små bokstaver kan også injiseres.
- Kun støtte for string-typen: Andre typer støttes ikke.