GoSuda

Compile-Time Variable Injection i Go

By wHoIsDReAmer
views ...

Bakgrund

När jag arbetade med ett företagsprojekt den här gången, letade jag efter om det fanns ett sätt att injicera variabler vid kompileringstid utan .env. Jag trodde att detta skulle vara mycket bekvämt eftersom det bara skulle kräva en enda fil istället för .env eller flera konfigurationsfiler.

Först letade jag efter något som en go:generate CLI som genererar konstanta filer baserat på .env, men jag hittade inget.

Men i så fall kunde jag bara ändra constants direkt istället för att behöva göra en besvärlig generering, och jag hittade ett sätt att injicera värden vid kompileringstid, liknande Rusts include_bytes! makro.

Injektion 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}

Om det finns kod som den ovan, kan variabler injiceras vid byggnadstid på följande sätt.

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

Om du skickar argument med ldflag injiceras värdet bar i variabeln Foo vid kompileringstid under byggnaden. Det är enkelt.

Om det finns paket eller variabler med samma namn på flera ställen i projektet, kan du ange paketets sökväg.

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 du injicera genom att särskilja 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 om det finns flera variabler i samma paket, kan du helt enkelt skicka ytterligare argument.

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

Egenskaper

Egenskaperna är följande:

  • Variabeln behöver inte vara public: Variabler som börjar med en liten bokstav kan också injiceras.
  • Stöder endast string typ: Andra typer stöds inte.

Referenser