---
id: 1872edeaa3c5fc09a1eba338cf2b01b1
author: wHoIsDReAmer
title: Go 编译时变量注入:go build -ldflags -X 用法详解
description: 本文介绍如何在不使用外部 .env 文件的情况下，通过指定 go build -ldflags "-X" 链接器标志及包符号路径，在编译期注入 Go 字符串变量的值。
language: zh
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 传递参数后，在构建时的编译阶段，`bar` 值会被注入到 `Foo` 变量中。很简单。

如果项目中多个地方存在同名的包或变量，则**明确指定包路径**即可。

```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'"
```

其特点如下：

- **变量无需为公开的**：以小写字母开头的变量也可以注入
- **仅支持 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)
