GoSuda

Injeksjon av variabler under kompilering i Go: bruk av go build -ldflags -X

By wHoIsDReAmer views ...

Bakgrunn

Da jeg arbeidet med et prosjekt for selskapet, lette jeg etter en måte å injisere variabler under kompileringen uten å bruke .env. Jeg tenkte at dette ville være svært praktisk, siden man da bare trenger én fil i stedet for .env og flere konfigurasjonsfiler.

Først lette jeg etter et go:generate-CLI-verktøy som kunne generere en konstantfil basert på .env, men fant ingen slik løsning.

Men i så fall kunne man like gjerne bare endre constants direkte, uten å måtte kjøre generering, og jeg fant derfor en metode for å injisere verdier under kompileringen, lik include_bytes!-makroen i Rust.

Injisering av variabler under kompilering

Bruken er enkel.

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

Gitt koden ovenfor, kan man injisere verdien under bygging på følgende måte.

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

Ved å sende argumentet via ldflag injiseres verdien bar i variabelen Foo under kompileringen. Det er enkelt.

Dersom prosjektet har pakker eller variabler med samme navn på flere steder, kan man angi pakkebanen eksplisitt.

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 slike tilfeller kan man skille mellom dem på følgende måte:

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

Også når flere variabler finnes i samme pakke, er det tilstrekkelig å legge til ekstra argumenter.

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

Egenskapene er som følger:

  • Variabelen trenger ikke å være offentlig: Variabler som starter med små bokstaver kan også injiseres.
  • Kun støtte for string-typen: Andre typer støttes ikke.

Referanser