GoSuda

Injicering av variabler vid kompileringstid i Go: användning av go build -ldflags -X

By wHoIsDReAmer views ...

Bakgrund

I samband med ett företagsprojekt jag nyligen arbetade med undersökte jag om det finns ett sätt att injicera variabler vid kompileringstid utan en .env-fil. Jag tänkte att detta skulle vara mycket bekvämt eftersom man då bara behöver en enda fil utan .env eller flera konfigurationsfiler.

Först letade jag efter ett go:generate-CLI som genererar en konstantfil utifrån .env, men sådant fanns inte.

Men om det ändå var så skulle man lika gärna kunna ändra constants direkt, och det var onödigt krångligt att behöva köra gen, så jag letade vidare och fann metoder för att injicera värden vid kompileringstid, till exempel makrot include_bytes! i Rust.

Injicering av variabler vid kompileringstid

Användningen är enkel.

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

Givet kod som ovan kan man vid bygget injicera värde på följande sätt.

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

När argumentet skickas via ldflag injiceras värdet bar i variabeln Foo vid kompileringstid. Det är enkelt.

Om samma paketnamn eller variabelnamn förekommer på flera ställen i projektet kan man ange paketsökvägen.

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 sådana fall kan man injicera värden genom att särskilja dem på följande sätt:

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

Även när flera variabler finns i samma paket räcker det att skicka ytterligare argument.

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

Egenskaperna är följande:

  • Variabeln behöver inte vara publik: även variabler som börjar med gemener kan injiceras
  • Endast stringtyp stöds: andra typer stöds inte

Referenser