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

-ldflags
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就好定位代码了。

改造项目,结构如下:

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...