---
id: 1872edeaa3c5fc09a1eba338cf2b01b1
author: wHoIsDReAmer
title: 'Go コンパイル時変数の注入: go build -ldflags -X の活用法'
description: 外部の .env ファイルを使用せず、go build -ldflags "-X" リンカーフラグとパッケージのシンボルパスを指定することで、コンパイル時に Go の文字列変数の値を埋め込む方法について説明します。
language: ja
date: 2025-06-01T15:56:46.352281271Z
path: /blog/posts/compile-time-variable-injection-of-go-z5420556c
category: api
---

## 背景

今回の会社プロジェクトの作業において、.env なしでコンパイル時に変数を注入する方法がないかを調べてみました。
この方法であれば `.env` や複数の設定ファイルがなく、単一のファイルだけで済むため、非常に便利だろうと考えました。

まず最初に探したのは、`.env` をもとに定数ファイルを生成する `go:generate` の CLI のようなものでしたが、見つかりませんでした。

ただ、そうするのであれば単に constants を修正すればよく、わざわざ gen を実行する必要はありませんでした。そこで、Rust の `include_bytes!` マクロのように、コンパイル時に値を注入できる方法を調べました。

## コンパイル時変数の注入

使い方は簡単です。

```go
package main

import "fmt"

var Foo string

func main() {
    fmt.Println(Foo)
}
```

上記のようなコードがある場合、ビルド時に次のように注入できます。

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

ldflag で引数を渡すと、ビルド時のコンパイル時に `Foo` 変数へ `bar` の値が注入されます。シンプルです。

もしプロジェクト内に同じ名前のパッケージや変数が複数の場所に存在する場合は、**パッケージパスを明示すればよい**です。

```go
// github.com/myproject/config/config.go
package config

var Version string

// github.com/myproject/internal/config/config.go
package config

var BuildTime string
```

このような場合は、次のように区別して注入することができます:

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

同じパッケージに複数の変数がある場合も、追加の引数を渡すだけで済みます。

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

特徴は次のとおりです:

- **変数が public でなくてもよい**: 小文字で始まる変数にも注入可能です
- **string 型のみサポート**: それ以外の型はサポートされていません

## 参照

- [https://stackoverflow.com/questions/47509272/how-to-set-package-variable-using-ldflags-x-in-golang-build](https://stackoverflow.com/questions/47509272/how-to-set-package-variable-using-ldflags-x-in-golang-build)
