Go -v 显示版本号和编译时间示例

时间:2021-05-28 20:52:08

C语言想要 -v 显示编译时间,可以使用 __DATE__, __TIME__ 这两个宏,
而 Go 没有类似的常量,当然可以使用 Go 调用 C 代码(这是另一种方法)
然而,更好的方法是使用 go build 的 -ldflags 参数
原理如下:

$ go build --help
    -ldflags 'flag list'
        arguments to pass on each go tool link invocation.

$ go tool link --help
    -X definition
        add string value definition of the form importpath.name=value

也就是可以在编译Go程序时,添加指定包的指定变量

—————————– 项目示例分割线 —————————-

完整项目见 github
version/version.go:

package version

import (
    "fmt"
    "os"
)

var (
    BuildVersion string
    BuildTime    string
    BuildName    string
)

func init() {
    args := os.Args
    if nil == args || len(args) < 2 {
        return
    }
    if "-v" == args[1] {
        fmt.Printf("%s: v%s (%s)\n", BuildName, BuildVersion, BuildTime)
    } else if "-h" == args[1] {
        fmt.Println("Usage:")
        fmt.Printf("./%s\n", BuildName)
        fmt.Printf("./%s -v\n", BuildName)
        fmt.Printf("./%s -h\n", BuildName)
    }
    os.Exit(0)
}

makefile:

BUILD_VERSION   := 1.0.0
BUILD_TIME      := $(shell date "+%F %T")
BUILD_NAME      := go-version-sample
SOURCE          := ./*.go
TARGET_DIR      := /path-you-want/${BUILD_NAME}

all:
    go build -ldflags \
    "-X ${BUILD_NAME}/version.BuildVersion=${BUILD_VERSION} \ -X '${BUILD_NAME}/version.BuildTime=${BUILD_TIME}' \ -X ${BUILD_NAME}/version.BuildName=${BUILD_NAME}" \
    -o ${BUILD_NAME} ${SOURCE}

clean:
    rm ${BUILD_NAME} -f

install:
    # mkdir -p ${TARGET_DIR}
    # cp ${BUILD_NAME} ${TARGET_DIR} -f

.PHONY : all clean install ${BUILD_NAME}

makefile 文件中定义了 version 包中的 BuildTime 等变量,
然后在 version 包的 init() 函数中使用
(还可以添加 COMMIT_SHA1=`git rev-parse HEAD` 类似的变量)
main.go:

package main

import _ "go-version-sample/version"

import (
    "fmt"
)

func main() {
    fmt.Println("From main(): hello")
}

这里把 version 包的引用放在最前面,好处是程序第一时间检查参数,-v 显示版本号后直接退出程序(包的初始化是按照声明顺序)。
否则程序会执行其他包不必要的初始化(比如mysql连接)
(不把变量放到main包也是同样的道理,因为main总会包含其他包)
最后,通过 make, make clean, make install 命令就可以使用了