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

这篇具有很好参考价值的文章主要介绍了Golang编译选项(ldflags)有趣应用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

应用程序的版本信息

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

docker version

返回结果:

Server: Docker Engine - Community
 Engine:
  Version:          23.0.1
  API version:      1.42 (minimum version 1.12)
  Go version:       go1.19.5
  Git commit:       bc3805a
  Built:            Thu Feb  9 19:46:56 2023
  OS/Arch:          linux/amd64
  Experimental:     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 main

import (
    "fmt"
)

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

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

package main

import (
    "fmt"
)

var GitCommit string

func 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 +0800

    first update

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

    initial

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 main

import (
	"fmt"
)

var GitCommit string
var BuildTime string
var BuildUser string

func 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= ( g i t r e v − l i s t − − a l l − 1 ) − X ′ m a i n . B u i l d U s e r = (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提交日志、编译时间等信息。最后还顺便介绍了压缩可执行文件的选项。文章来源地址https://www.toymoban.com/news/detail-674373.html

到了这里,关于Golang编译选项(ldflags)有趣应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Golang条件编译介绍

    相信熟悉 Golang 的小伙伴不少都知道 条件编译 这个事,最近项目中也可能会用到这个东西。所以特意重新学习下,记录下学习的过程。这样用的时候记不住了,还可以直接过来看自己的笔记。 文章很多内容来源于参考资料,感谢。 1.1、为什么需要条件编译 在实际的项目开发

    2024年02月15日
    浏览(44)
  • golang编译问题

    编译时提示工作目录文件系统只读 go: creating work dir: mkdir /tmp/go-build2069696743: read-only file system 方法一: 尝试了很多办法,重新挂载可读可写,还是不行,只能重启 方法二: 重新设置GOTMPDIR 编译时拉不下来指定依赖包 设置国内源 Go 1.13 及以上(推荐) 如果是低版本golang参考

    2024年02月06日
    浏览(44)
  • 【Golang】go条件编译

    交叉编译只是为了能在一个平台上编译出其他平台可运行的程序,Go 作为一个跨平台的语言,它提供的类库势必也是跨平台的,比如说程序的系统调用相关的功能,能根据所处环境选择对应的源码进行编译。让编译器只对满足条件的代码进行编译,将不满足条件的代码舍弃,

    2024年02月11日
    浏览(58)
  • 【Golang】go交叉编译

    交叉编译是用来在一个平台上生成另一个平台的可执行程序 。Go 命令集是原生支持交叉编译的。 Mac下编译:Linux 或 Windows 的可执行程序 Linux下编译:Mac 或 Windows的可执行程序 Windows下编译:Mac 或 Linux的可执行程序 需要写一个批处理程序,在里面去设置,因为windows 下的 ter

    2024年02月10日
    浏览(43)
  • Golang不同平台编译的思考

    $GOOS可选值如下: darwin dragonfly freebsd linux netbsd openbsd plan9 solaris windows $GOARCH可选值如下 386 amd64 arm 在编译的时候我们可以根据实际需要对这两个参数进行组合。更详细的说明可以进官网看看 下面是实际使用。在Linux系统下跨平台编译。

    2024年02月09日
    浏览(36)
  • Golang编译优化——公共子表达式消除

    公共子表达式消除(Common Subexpression Elimination,CSE)也有书上称为冗余表达式消除,旨在减少程序中重复计算相同表达式的次数,从而提高程序的执行效率。 在程序中,如果同一个表达式在不同的地方多次出现并且具有相同的输入,则这个表达式就是一个公共子表达式。公共

    2024年04月28日
    浏览(30)
  • 【Golang】Windows与Linux交叉编译保姆级教程

    大家好 我是寸铁👊 总结了一篇【golang】Windows与Linux交叉编译的文章✨ 喜欢的小伙伴可以点点关注 💝 今天寸铁想将 Windows 中的程序部到 Linux 下跑,我们知道在从 Windows 与 Linux 下要进行交叉编译,通常是在 Windows 中打包成一个文件在再 Linux 下编译执行,我们管这个过程叫做

    2024年04月09日
    浏览(44)
  • macOS 13(本机)golang程序交叉编译成 ARM架构

    ## 背景 golang程序(JuiceFS)需要支持ARM64架构,重新编译; 本地环境:macOS:13 ## 操作 安装交叉编译工具: 可以在 /usr/local/bin 找到musl相关的工具命令 Makefile ## 参考 https://saekiraku.github.io/article/18577/ https://liujinye.gitbook.io/openshift-docs/raspberry-pi/macosgolang-bian-yi-arm-huan-jing-gosqlite3-

    2024年01月17日
    浏览(39)
  • Golang 程序性能优化利器 PGO 详解(二):收集样本数据和编译

    在软件开发过程中,性能优化是不可或缺的一部分。无论是在Web服务、数据处理系统还是实时通信中,良好的性能都是至关重要的。Golang 从1.20版版本开始引入的 Profile Guided Optimization(PGO)机制能够帮助更好地优化 Go 程序的性能。 上篇文章讲解了 Golang PGO 的概念和使用方法

    2024年02月12日
    浏览(34)
  • golang 中使用 statik 将静态资源编译进二进制文件中

    现在的很多程序都会提供一个 Dashboard 类似的页面用于查看程序状态并进行一些管理的功能,通常都不会很复杂,但是其中用到的图片和网页的一些静态资源,如果需要用户额外存放在一个目录,也不是很方便,如果能打包进程序发布的二进制文件中,用户下载以后可以直接

    2024年01月19日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包