GoSuda

Injektion af variabler ved kompileringstid i Go: anvendelse af go build -ldflags -X

By wHoIsDReAmer views ...

Baggrund

I forbindelse med et virksomhedsprojekt undersøgte jeg, om der findes en metode til at injicere variabler på kompileringstidspunktet uden brug af .env. Jeg mente, at dette ville være meget praktisk, da kun en enkelt fil ville være nødvendig uden .env-filer eller flere konfigurationsfiler.

Til at begynde med ledte jeg efter et go:generate-CLI, der genererer en konstantfil baseret på .env, men jeg fandt ingen.

Hvis det var sådan, kunne man dog lige så godt redigere constants direkte, og det var ikke nødvendigt at besvære sig med at køre gen. Jeg fandt så en metode, der kan injicere værdier på kompileringstidspunktet, ligesom include_bytes!-makroen i Rust.

Injektion af variabler på kompileringstidspunktet

Brugen er enkel.

1package main
2
3import "fmt"
4
5var Foo string
6
7func main() {
8    fmt.Println(Foo)
9}

Givet en kode som ovenfor, kan man ved build injicere værdien på følgende måde.

1go build -ldflags="-X 'main.Foo=bar'"

Når argumentet overføres via ldflag, injiceres værdien bar i variablen Foo på kompileringstidspunktet under build. Det er ligetil.

Hvis der i projektet findes pakker eller variabler med samme navn flere steder, kan man angive pakkestien.

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 et sådant tilfælde kan man injicere værdierne ved at skelne dem på følgende måde:

1go build -ldflags="-X 'github.com/myproject/config.Version=v1.0.0' -X 'github.com/myproject/internal/config.BuildTime=2025-05-27'"

Når der er flere variabler i samme pakke, skal man blot tilføje yderligere argumenter.

1go build -ldflags="-X 'main.Version=v1.0.0' -X 'main.BuildTime=2025-05-27' -X 'main.GitCommit=abc123'"

Egenskaberne er som følger:

  • Variablen behøver ikke at være public: Variabler, der starter med et lille bogstav, kan også injiceres.
  • Kun string-typen understøttes: Andre typer understøttes ikke.

Referencer