Compile-Time Variable Injection in Go
Hintergrund
Im Rahmen eines aktuellen Firmenprojekts habe ich nach einer Möglichkeit gesucht, Variablen zur Kompilierzeit ohne .env-Dateien einzubinden.
Ich dachte, dies wäre äußerst praktisch, da man dann nur eine einzige Datei statt .env oder mehrerer Konfigurationsdateien bräuchte.
Zuerst suchte ich nach einem go:generate CLI-Tool, das auf Basis von .env Konstantendateien generiert, aber ich fand keines.
Doch dann wurde mir klar, dass es nicht nötig wäre, umständlich zu generieren, wenn man die Konstanten einfach direkt ändern könnte, und ich fand eine Methode, Werte zur Kompilierzeit einzubinden, ähnlich dem include_bytes! Makro in Rust.
Kompilierzeit-Variableneinbindung
Die Verwendung ist einfach.
1package main
2
3import "fmt"
4
5var Foo string
6
7func main() {
8 fmt.Println(Foo)
9}
Wenn Code wie der obige vorliegt, kann die Einbindung während des Builds wie folgt erfolgen:
1go build -ldflags="-X 'main.Foo=bar'"
Wenn Argumente über ldflag übergeben werden, wird der Wert bar zur Kompilierzeit in die Variable Foo während des Builds eingefügt. Es ist einfach.
Falls im Projekt mehrere Pakete oder Variablen mit demselben Namen existieren, muss der Paketpfad explizit angegeben werden.
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
In solchen Fällen kann die Einbindung wie folgt unterschieden werden:
1go build -ldflags="-X 'github.com/myproject/config.Version=v1.0.0' -X 'github.com/myproject/internal/config.BuildTime=2025-05-27'"
Wenn mehrere Variablen im selben Paket vorhanden sind, müssen einfach zusätzliche Argumente übergeben werden.
1go build -ldflags="-X 'main.Version=v1.0.0' -X 'main.BuildTime=2025-05-27' -X 'main.GitCommit=abc123'"
Die Merkmale sind wie folgt:
- Die Variable muss nicht public sein: Auch Variablen, die mit Kleinbuchstaben beginnen, können injiziert werden.
- Nur string-Typen werden unterstützt: Andere Typen werden nicht unterstützt.