当前位置: 首页 > news >正文

Golang编译选项(ldflags)有趣应用

本文介绍如何在构建时使用ldflags选项给Golang应用程序注入变量,用于给Go可执行文件增加版本标识或GIT提交摘要等信息。

应用程序的版本信息

我们首先查看Docker Cli 包含的提交信息:

docker version

返回结果:

Server: Docker Engine - CommunityEngine:Version:          23.0.1API version:      1.42 (minimum version 1.12)Go version:       go1.19.5Git commit:       bc3805aBuilt:            Thu Feb  9 19:46:56 2023OS/Arch:          linux/amd64Experimental:     false

可以看到包含了 Git commit: bc3805a 信息,这是git最后提交的版本信息。

那为什么要增加版本信息呢?通过该信息可以很方便识别用户正在使用的版本,以及已使用的时长。

Git提交日志

在进入主题之前,让我们思考下在构建时注入什么信息有意义?它可以是任何信息,如提供WEB服务的主机名称或更常见的GIT最后提交ID。下面简单演示下如何获取GIT最后提交日志的ID。

$ git init && echo "let's work with git" > readme && git add . && git commit -m "initial "

Initialized empty Git repository in C:/Users/86137/Desktop/test/.git/
warning: LF will be replaced by CRLF in readme.
The file will have its original line endings in your working directory
[master (root-commit) b446263] initial
1 file changed, 1 insertion(+)
create mode 100644 readme

$ ls

readme

$ cat readme

let’s work with git

$ echo "let's keep working" >> readme && git add . && git commit -m "first update"

warning: LF will be replaced by CRLF in readme.
The file will have its original line endings in your working directory
[master b7a900c] first update
1 file changed, 1 insertion(+)

$ cat readme

let’s work with git
let’s keep working

现在我们查看GIT两次提交日志:

$ git log

commit b7a900cdbb23493c4d48d009173daf9eb4b4e9d0 (HEAD -> master)
Author: test test@gmail.com
Date: Sat Mar 11 15:30:16 2023 +0800

first update

commit b446263cf7af8f62906587cbe97029df575ae592
Author: test test@gmail.com
Date: Sat Mar 11 15:29:34 2023 +0800

initial

通过下面命令获取最后的提交ID:

$ git rev-list --all -1

b7a900cdbb23493c4d48d009173daf9eb4b4e9d0

$ export GIT_COMMIT=$(git rev-list --all -1) && echo $GIT_COMMIT

b7a900cdbb23493c4d48d009173daf9eb4b4e9d0

示例Go应用

让我们使用简单的Hello World吧:

package mainimport ("fmt"
)func main() {fmt.Println("Hello world")
}

为了传入构建时变量,需要main包中拆改那就一个变量,这里命名为GitCommit:

package mainimport ("fmt"
)var GitCommit stringfunc main() {fmt.Printf("Hello world, version: %s\n", GitCommit)
}

编译并运行:

$ go build main.go && ./main.exe

Hello world, version:

版本信息为空,下面开始注入版本给GitCommit变量。

使用-ldflags

现在我们给 go build命令增加选项,传入git最后提交ID作为版本信息,先看看提交情况:

$ git log
commit 1111c009f3caf4730bd31a4226d5a36e4b5a0083 (HEAD -> master)
Author: test <test@gmail.com>
Date:   Sat Mar 11 15:53:57 2023 +0800增加GIT_COMMIT变量commit b7a900cdbb23493c4d48d009173daf9eb4b4e9d0
Author: test <test@gmail.com>
Date:   Sat Mar 11 15:30:16 2023 +0800first updatecommit b446263cf7af8f62906587cbe97029df575ae592
Author: test <test@gmail.com>
Date:   Sat Mar 11 15:29:34 2023 +0800initial

ldflags的语法

go build -ldflags="-X 'package_path.variable_name=new_value'",可以一次性指定多个变量。

现在利用前面的知识增加最后提交ID:

go build -ldflags "-X 'main.GitCommit=$(git rev-list --all -1)'" main.go

执行程序可以看到版本信息

$ ./main.exe

Hello world, version: 1111c009f3caf4730bd31a4226d5a36e4b5a0083

当然我们还可以增加多个变量:

package mainimport ("fmt"
)var GitCommit string
var BuildTime string
var BuildUser stringfunc main() {fmt.Printf("Hello world, version: %s\n", GitCommit)fmt.Println("build.Time:\t", BuildTime)fmt.Println("build.User:\t", BuildUser)
}

go build -ldflags "-X main.GitCommit=$(git rev-list --all -1) -X 'main.BuildUser=$(id -u -n)' -X 'main.BuildTime=$(date +%F_%T)'" main.go

运行程序:

Hello world, version: 1111c009f3caf4730bd31a4226d5a36e4b5a0083
build.Time: 2023-03-11_16:36:50
build.User: 86137

压缩可执行文件

我们还可以利用 -ldflags “-s -w” 选项压缩可执行文件:

go build -ldflags “-X main.GitCommit=(gitrev−list−−all−1)−X′main.BuildUser=(git rev-list --all -1) -X 'main.BuildUser=(gitrevlistall1)Xmain.BuildUser=(id -u -n)’ -X ‘main.BuildTime=$(date +%F_%T)’ -s -w” main.go

对比编译前后文件的大小:

# 压缩前大约1.9M
-rwxr-xr-x 1 86137 197609 1965056  3月 11 16:37 main.exe*# 压缩后为大约1.3M
-rwxr-xr-x 1 86137 197609 1338880  3月 11 16:58 main.exe*

总结

本文介绍了git提交日志,如何在构建时给Go程序增加信息,如GIT提交日志、编译时间等信息。最后还顺便介绍了压缩可执行文件的选项。

http://www.lryc.cn/news/38516.html

相关文章:

  • AIR32F103(十一) 在AIR32F103上移植微雪墨水屏驱动
  • Uipath Excel 自动化基础系列文章
  • 神经网络优化器之随机梯度下降法的理解
  • 记录一次WIN11开机在登录页面循环的问题
  • 始终从最不易改变的方面开始
  • 4、Httpclient源码解析之HTTP协议
  • 浏览器并发行为记录
  • 工厂模式与抽象工厂
  • 什么?你不知道 ConcurrentHashMap 的 kv 不能为 null?
  • SQL复习04 | 复杂查询
  • 【面试题】Java面试题汇总(无解答)
  • C++---背包模型---收服精灵(每日一道算法2023.3.11)
  • day30_JS
  • 【Java学习笔记】19.Java 正则表达式(2)
  • 华为云arm架构轻松安装kubeedge
  • 33--Vue-前端开发-使用Vue脚手架快速搭建项目
  • TMS WEB Core开发Web应用优势说明
  • 人工智能简单应用1-OCR分栏识别:两栏识别三栏识别都可以,本地部署完美拼接
  • Gin框架路由拆分与注册详解析
  • 2020蓝桥杯真题凯撒加密 C语言/C++
  • taro+vue3小程序使用v-html渲染的内容为class写了样式无效
  • MASK-RCNN网络介绍
  • 导航技术调研(CSDN_0023_20221217)
  • 买卖股票的最佳时机 I II III IV
  • STM32—LCD1602
  • 英雄算法学习路线
  • 【设计模式】备忘录模式和迭代器模式
  • rapidcsv 写csv文件实例
  • 数据库--进阶篇--9--存储引擎
  • 物品的管理的隐私政策