当前位置: 首页 > 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…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...