您的位置 首页 golang

大白话 golang 编程-25-打包编译信息的套路

go build 可以编译出二进制的可执行文件,因为 go 有交叉编译的特性,在 mac 上也可以编译出 linux 的可执行文件,比如:

 CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go  

1. CGO_ENABLED=0 禁用 CGO 特性,该特性将在调用 C/C++ 部分学习

2. GOOS 指明运行的目标系统,有 darwin、linux、freebsd、windows 等

3. GOARCH 表示系统的CPU架构,386、amd64、arm 等

关于 GOOS 和 GOARCH 的值可以参考 。

运行某些 go 程序的时候常常打印出如下的信息:

 # ./main -version
version:v5.13.4
git hash:a8de74c76929d10dea7fe2c14fc098ef42f438c6
build time:20201228-10:20:29  

分别是版本号 version,应该是 git tag 的标签,git hash 仓库提交的 commit 的 SHA 码,build time 打包的时间,像这种嵌入到可执行文件的额外信息怎么在编译时生成呢? 按照上一章节的思路,使用 flag.Parse 处理 version 打印出三个字段的信息即可。

 // meta/config/config.go 

var ( 
  Version   = "" 
  GitHash   = "" 
  BuildTime = ""
)

// main.go

var version bool

func main() {
  flag.BoolVar(&version, "version", false, "print version info")
  flag.Parse()

  if version {
    fmt.Printf("version:\t\t%s", Version)
    fmt.Printf("git hash:\t\t%s", GitHash)
    fmt.Printf("build time:\t\t%s", BuildTime)
  }
}  

好了,运行 go build main.go && ./main 后打印了三行空信息,解析 version 的工作已经完成,现在的关键是如何在 build 时获得这三个字段的信息,获取后通过修改 config.go 文件中的代码后再 build 即可。

在 bash 中获取的方法:

1. version=`git tag | tail -n 1` # 获取最后一个 tag 标签

2. git_hash=`git rev-parse HEAD` # 提交的 commit 码

3. build_time=`date +%Y%m%d-%H:%M:%S` # 当前的日期时间

可以通过 bash 脚本直接替换掉 config.go 中的字段值,不过 go build 提供了 –ldflags 编译参数,配合 -X 可以替换掉 config.go 中的字段值,为了编译方便统一为 build.sh 脚本:

 #!/bin/bash 

build() {
  version=`git tag | tail -n 1`
  git_hash=`git rev-parse HEAD`
  build_time=`date +%Y%m%d-%H:%M:%S`

  cmd="GOOS=darwin GOARCH=amd64 go build -o=./main -ldflags \"
    -X '25-build-with-meta/meta/config.Version=$version' \
    -X '25-build-with-meta/meta/config.GitHash=$git_hash' \
    -X '25-build-with-meta/meta/config.BuiltTime=$build_time' \""
  echo $cmd
  eval $cmd
}

build
echo "build finish"  

注意 25-build-with-meta/meta/config 是包名,它对应的文件是 meta/config/config.go,运行 chmod +x ./build.sh && ./build.sh 显示 build finish 编译完成:

 # ./build.sh
GOOS=darwin GOARCH=amd64 go build -o=./main -ldflags " -X '25-build-with-meta/meta/config.Version=v1.0' -X '25-build-with-meta/meta/config.GitHash=415ca4116fdb354b121c59863d3509e34056f580' -X '25-build-with-meta/meta/config.BuildTime=20210120-10:41:57' "
build finish  

运行 ./main -version 显示:

 # ./main -version
version:v1.0
git hash:415ca4116fdb354b121c59863d3509e34056f580
build time:20210120-10:41:57  

主要用法 -ldflags -X importpath.name=value,参考 ,使用此方法你可以为程序嵌入其他元信息。

 -X importpath.name=value
Set the value of the string variable in importpath named name to value.
This is only effective if the variable is declared in the source code either uninitialized
or initialized to a constant string expression. -X will not work if the initializer makes
a function call or refers to other variables.
Note that before Go 1.5 this option took two separate arguments.  

作为一个小作业,请你嵌入编译时的 go 的版本信息,运行 ./main -version 显示:

 ./main -version
version:v1.0
git hash:2d432eac0876c7e33efe6ff32fbbb43ec44ad1c3
build time:20210120-10:55:14
go version:go version go1.15.5 darwin/amd64  

本章节的代码

文章来源:智云一二三科技

文章标题:大白话 golang 编程-25-打包编译信息的套路

文章地址:https://www.zhihuclub.com/86410.shtml

关于作者: 智云科技

热门文章

网站地图