GoSuda

Инжектиране на променливи по време на компилация в Go: използване на go build -ldflags -X

By wHoIsDReAmer views ...

Предистория

В рамките на текущия проект в компанията търсих начин за инжектиране на променливи по време на компилация без използване на .env файл. Смятах, че ако това е възможно, ще е много удобно, тъй като ще е необходим само един файл, без .env или множество конфигурационни файлове.

Първоначално потърсих CLI инструмент за go:generate, който генерира файл с константи въз основа на .env, но такъв не намерих.

Но ако е така, би било по-просто да се редактират директно constants, без да се правят излишни стъпки за генериране. Тогава открих, че в Rust има възможности за инжектиране на стойности по време на компилация, като например макроса include_bytes!.

Инжектиране на променливи по време на компилация

Употребата е проста.

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

При наличие на горния код, по време на билд може да се инжектира стойност по следния начин.

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

Чрез подаване на аргумент с ldflag, стойността bar се инжектира в променливата Foo по време на компилация. Просто е.

Ако в проекта има пакети или променливи с едно и също име на различни места, може да се посочи пътят до пакета.

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

В такъв случай може да се инжектират стойности, като се разграничат по следния начин:

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

Когато в един и същи пакет има няколко променливи, е достатъчно да се подадат допълнителни аргументи.

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

Характеристиките са следните:

  • Променливата не е задължително public: може да се инжектира и променлива, започваща с малка буква
  • Поддържа се само тип string: други типове не се поддържат

Референции