golang在编译时用ldflags设置变量的值

我们经常会在一些程序的输出中看到程序版本、编译时间、Git的commit id等信息,比如docker

ming@vultr:~$ docker version
Client:
 Version:      1.12.5
 API version:  1.24
 Go version:   go1.6.4
 Git commit:   7392c3b
 Built:        Fri Dec 16 02:42:17 2016
 OS/Arch:      linux/amd64
...

我们可以提供一个配置文件version.conf,程序运行时从version.conf取得这些信息进行显示。但是在部署程序时,除了二进制文件还需要额外的配置文件,不是很方便。

或者将这些信息写入代码中,这样不需要额外的version.conf,但要在每次编译时修改代码文件,也够麻烦的了。

Golang 是编译成可执行文件运行的。有没有办法可以在编译时把一些信息比如打包时间,作者,git 信息打包到可执行文件里呢?

有,可以通过-ldflags -X importpath.name=value参数设置,官方解释如下

-X importpath.name=value
Set the value of the string variable in importpath named name to value.
Note that before Go 1.5 this option took two separate arguments.
Now it takes one argument split on the first = sign.

package main

// 定义变量
var Version string

func main() {
    fmt.Println(Version)
}
  • 编译设置变量
go build -o bin/ -ldflags "-X main.Version=0.1.0"

-X definition: 添加形式为 importpath.name=value 的字符串值定义,注意 value 字符串不能有空格(暂时没找到解决方案)

有了这个参数,就可以给编译增加一些版本信息注入了,这样有bug就好定位代码了。


Go build -ldflags编译时设置变量用例

改造项目,结构如下:

demo
 ├───build
 │    └─build.go
 ├───cmd
 │    └─main.go
 ├─go.mod
 ├─go.sum
  • main.go
package main

import (
	"demo/build"
	"flag"
	"fmt"
	"os"
)

var version = flag.Bool("v", false, "Version")

func main() {
	flag.Parse()

	if *version {
		fmt.Println(build.String())
		os.Exit(0)
		return
	}

	fmt.Println("Other...")
}
  • build.go
package build

import "fmt"

var (
	AppName string
	Branch  string
	Commit  string
	Author  string
	Date    string
	Version string
)

func String() string {
	return fmt.Sprintf("AppName: %s\nVersion: %s\nBranch: %s\nCommit: %s\nAuthor: %s\nDate: %s", AppName, Version, Branch, Commit, Author, Date)
}

build.sh

#!/usr/bin/env bash

BRANCH=$(git symbolic-ref --short -q HEAD)
COMMIT=$(git rev-parse --verify HEAD)
NOW=$(date '+%FT%T%z')
VERSION="0.1.0"
RUN_USER=$(whoami)

go build -o bin/ -ldflags "-X demo/build.AppName=Demo\
 -X demo/build.Branch=${BRANCH}\
 -X demo/build.Commit=${COMMIT}\
 -X demo/build.Author=${RUN_USER}\
 -X demo/build.Date=${NOW}\
 -X demo/build.Version=${VERSION}" cmd/main.go

打包,执行

$ ./build.sh
$ ./bin/main.exe -v                                   
AppName: Demo                                         
Version: 0.1.0                                        
Branch: master                                        
Commit: ea2ce0b45e2c2def3bbbd2dd3787e1d84272f6ea      
Author: lanyue                                        
Date: 2021-12-03T10:11:33+0800
$ ./bin/main.exe
Other...

参考:

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐