GoSuda

Wstrzykiwanie zmiennych w czasie kompilacji w Go: zastosowanie go build -ldflags -X

By wHoIsDReAmer views ...

Tło

Pracując nad projektem firmowym, sprawdziłem, czy istnieje sposób na wstrzykiwanie zmiennych w czasie kompilacji bez użycia pliku .env. Pomyślałem, że byłoby to bardzo wygodne, ponieważ wystarczyłby jeden plik, bez .env i wielu plików konfiguracyjnych.

Na początku szukałem narzędzia CLI dla go:generate, które generowałoby plik ze stałymi na podstawie .env, ale takiego nie znalazłem.

Skoro jednak i tak miałbym to zrobić, to lepiej po prostu zmodyfikować constants, bez zawracania sobie głowy generowaniem. Znalazłem wtedy sposób, który przypomina makro include_bytes! z Rusta, pozwalający wstrzyknąć wartość w czasie kompilacji.

Wstrzykiwanie zmiennych w czasie kompilacji

Sposób użycia jest prosty.

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

Mając powyższy kod, podczas budowania można wstrzyknąć wartość w następujący sposób.

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

Przekazując argument przez ldflag, wartość bar zostaje wstrzyknięta do zmiennej Foo w czasie kompilacji. To proste.

Jeśli w projekcie istnieją pakiety lub zmienne o tej samej nazwie w wielu miejscach, wystarczy podać ścieżkę pakietu.

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

W takim przypadku można rozróżnić je w następujący sposób:

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

Również gdy w jednym pakiecie znajduje się wiele zmiennych, wystarczy przekazać dodatkowe argumenty.

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

Charakterystyka tego rozwiązania jest następująca:

  • Zmienna nie musi być publiczna: można wstrzyknąć również zmienną zaczynającą się od małej litery
  • Obsługiwany jest wyłącznie typ string: inne typy nie są obsługiwane

Odniesienia