当前位置: 首页 > 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提交日志、编译时间等信息。最后还顺便介绍了压缩可执行文件的选项。

相关文章:

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

本文介绍如何在构建时使用ldflags选项给Golang应用程序注入变量&#xff0c;用于给Go可执行文件增加版本标识或GIT提交摘要等信息。 应用程序的版本信息 我们首先查看Docker Cli 包含的提交信息&#xff1a; docker version 返回结果&#xff1a; Server: Docker Engine - Co…...

AIR32F103(十一) 在AIR32F103上移植微雪墨水屏驱动

目录 AIR32F103(一) 合宙AIR32F103CBT6开发板上手报告AIR32F103(二) Linux环境和LibOpenCM3项目模板AIR32F103(三) Linux环境基于标准外设库的项目模板AIR32F103(四) 27倍频216MHz,CoreMark跑分测试AIR32F103(五) FreeRTOSv202112核心库的集成和示例代码AIR32F103(六) ADC,I2S…...

Uipath Excel 自动化基础系列文章

Uipath Excel 自动化基础系列文章已发布到CSDN,网址&#xff1a;https://blog.csdn.net/Marshaljun?typeblog (3月份会在CSDN博客发布Uipath Excel 实战课程及经验分享) Uipath Studio流程设计器介绍 https://blog.csdn.net/Marshaljun/article/details/128699022 Uipath St…...

神经网络优化器之随机梯度下降法的理解

随机梯度下降法&#xff08;SGD&#xff09;随机梯度下降方法&#xff0c;在每次更新时用1个样本&#xff0c;随机也就是说我们用样本中的一个例子来近似我所有的样本&#xff0c;由于计算得到的并不是准确的一个梯度&#xff0c;因而不是全局最优的。但是相比于批量梯度&#…...

记录一次WIN11开机在登录页面循环的问题

记录一次由于未进行win密码设置&#xff0c;导致开机后卡在登录界面无法登录进去的问题。最后完美解决了。 1. 背景 开机后&#xff0c;显示用户登录界面&#xff0c;但是和以往不同&#xff0c;没有了密码输入框&#xff0c;只有一个“登录”按钮孤零零地显示在屏幕中间&…...

始终从最不易改变的方面开始

在你刚开始新工作、转换职业或者是加入新项目时&#xff0c;始终从最不易改变的方面开始。 在工作中&#xff0c;这可能意味着与团队成员建立关系&#xff0c;了解公司的流程和文化&#xff0c;或者熟悉公司的产品或服务。 在一项新项目中&#xff0c;这可能意味着了解项目范…...

4、Httpclient源码解析之HTTP协议

初始化CloseableHttpClient过程中涉及ExecChainHandler & DefaultHttpProcessor&#xff0c;即典型客户端责任链中的请求执行处理器。 责任链中各节点涉及请求处理器【ExecChainHandler】顺序如下&#xff1a;RedirectExec、ContentCompressionExec、HttpRequestRetryExec…...

浏览器并发行为记录

使用nodejs koa起一个服务&#xff0c;使请求延时返回。 服务端代码 /** 延时 */ exports.timeoutTestData async function (ctx) {console.log(get query:, ctx.request.query);const query ctx.request.query;let timeout query.timeout || 2000;await new Promise(res…...

工厂模式与抽象工厂

原理&#xff1a;逻辑和业务全部封装 不需要细节 只要结果 示例&#xff1a; # 简单工厂 class SimpleFactory:# 产品staticmethoddef product(name):return nameif __name__ "__main__":product SimpleFactory.product("Gitee")print(product) 装饰器…...

什么?你不知道 ConcurrentHashMap 的 kv 不能为 null?

一、背景 最近设计某个类库时使用了 ConcurrentHashMap 最后遇到了 value 为 null 时报了空指针异常的坑。 本文想探讨下以下几个问题&#xff1a; &#xff08;1&#xff09; Map接口的常见子类的 kv 对 null 的支持情况。 &#xff08;2&#xff09;为什么 ConcurrentHashM…...

SQL复习04 | 复杂查询

1. 视图 视图和表的区别&#xff1a; 表保存的是实际的数据视图保存的是SELECT语句 视图的优点&#xff1a; 视图无需保存数据&#xff0c;可节省存储设备的容量可以将频繁使用的SELECT语句保存成视图&#xff0c;可大大提高效率 1.1 创建视图 CREATE VIEW 视图名称&…...

【面试题】Java面试题汇总(无解答)

此内容会持续补充。。。 基础 short s1 1; s1 s1 1;有错吗? short s1 1; s1 1; 有错吗&#xff1f;String str”aaa”,与 String strnew String(“aaa”)一样吗&#xff1f;String 和 StringBuilder、StringBuffer 的区别&#xff1f;Sring最大能存多大内容&#xff1f…...

C++---背包模型---收服精灵(每日一道算法2023.3.11)

注意事项&#xff1a; 本题是"动态规划—01背包"的扩展题&#xff0c;优化的思路不多赘述&#xff0c;dp思路会稍有不同&#xff0c;下面详细讲解。 本题偏向阅读理解&#xff0c;给每种变量归类起名字很有帮助哦。 切记先看思路&#xff0c;再看代码。&#xff08;大…...

day30_JS

今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 一、作业 二、BOM 三、定时器 四、正则表达式 零、 复习昨日 事件 事件绑定方式鼠标事件 onmouseoveronmouseoutonmousemove 键盘事件 onkeydownonkeyupon…...

【Java学习笔记】19.Java 正则表达式(2)

前言 本章继续介绍Java的正则表达式。 Matcher 类的方法 索引方法 索引方法提供了有用的索引值&#xff0c;精确表明输入字符串中在哪能找到匹配&#xff1a; 序号方法及说明1public int start()返回以前匹配的初始索引。2public int start(int group)返回在以前的匹配操作…...

华为云arm架构轻松安装kubeedge

先安装k8s 华为云arm架构安装k8s(kubernetes) 下载kubeedge需要的软件 官方github下载kubeedge地址 cloudcore.service文件下载地址 注意:下载对应的版本和arm架构 keadm-v1.6.1-linux-arm64.tar.gz 下面的2个文件可以不用下载,安装kubeedge时也会自动去下载到/etc/kubee…...

33--Vue-前端开发-使用Vue脚手架快速搭建项目

一、vue脚手架搭建项目 node的安装: 官方下载,一路下一步 node命令类似于python npm命令类似于pip 使用npm安装第三方模块,速度慢一些,需换成淘宝镜像 以后用cmpm代替npm的使用 npm install -g cnpm --registry=https://registry.npm.taobao.org安装脚手架: cnpm inst…...

TMS WEB Core开发Web应用优势说明

一、Delphi开发Web应用的三大框架如下: IntraWEB适合于WEB前、后端的开发,其自带的网络服务器非常强大、稳定,笔者使用Cesium框架开发的WEB GIS地理信息系统前端不需要Apache Tomcat或Nginx即可稳定运行; uniGUI是对JavaScript库Sencha ExtJS的封装,它带有两套VCL组件包,…...

人工智能简单应用1-OCR分栏识别:两栏识别三栏识别都可以,本地部署完美拼接

大家好&#xff0c;我是微学AI&#xff0c;今天给大家带来OCR的分栏识别。 一、文本分栏的问题 在OCR识别过程中&#xff0c;遇到文字是两个分栏的情况确实是一个比较常见的问题。通常情况下&#xff0c;OCR引擎会将文本按照从左到右&#xff0c;从上到下的顺序一行一行地识别…...

Gin框架路由拆分与注册详解析

Gin框架路由拆分与注册详解析1.基本的路由注册2.路由拆分成单独文件或包3.路由拆分成多个文件4.路由拆分到不同的APP1.基本的路由注册 下面最基础的gin路由注册方式&#xff0c;适用于路由条目比较少的简单项目或者项目demo // StatCost 是一个统计耗时请求耗时的中间件 func…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...