Go新项目-项目添加版本说明,以及参数传递:ldflags、gcflags,外加stripped说明(5)
在Go项目中,会存在展示该项目的版本信息,以及打包日期,项目版本,Go版本等;继Go新项目-编译项目的细节(4)以后再记录下编译优化方向,刚好也有项目版本输出的需求。
关键词:ldflags、gcflag、stripped
ldflags
**************** ldflags ****************
- 当把应用程序部署到生产环境中时,用版本信息和其他元数据构建二进制文件将改善你的监控、日志和调试过程,增加识别信息以帮助跟踪你的构建时间.
go 的 ldflags参数
- -w 去掉调试信息
- -s 去掉符号表
- -X 注入变量, 编译时赋值
-w 和 -s 通常一起使用,用来减少可执行文件的体积。但删除了调试信息后,可执行文件将无法使用 gdb/dlv 调试
使用范围可以在go install 、go build、go run 、go test中使用
Module=github.com/pubgo/xxx
GOPATH=$(shell go env GOPATH)
Version=$(shell git tag --sort=committerdate | tail -n 1)
GoVersion=$(shell go version)
BuildTime=$(shell date "+%F %T")
CommitID=$(shell git rev-parse HEAD)
LDFLAGS:=-ldflags "-X 'github.com/pubgo/xxx/version.GoVersion=${GoVersion}' \
-X 'github.com/pubgo/xxx/version.BuildTime=${BuildTime}' \
-X 'github.com/pubgo/xxx/version.GoPath=${GOPATH}' \
-X 'github.com/pubgo/xxx/version.CommitID=${CommitID}' \
-X 'github.com/pubgo/xxx/version.Module=${Module}' \
-X 'github.com/pubgo/xxx/version.Version=${Version:-v0.0.1}'"
编译
go build ${LDFLAGS} -mod vendor -race -v -o main main.go
go build -ldflags "-w -s" -mod vendor -race -v -o main main.gogo build -ldflags "-w -s" -race -v -o main main.go
gcflags
**************** gcflags ****************
- -N参数代表禁止优化,
- -l参数代表禁止内联,
- -c int: 编译过程中的并发数,默认是1
go在编译目标程序的时候会嵌入运行时(runtime)的二进制,
禁止优化和内联可以让运行时(runtime)中的函数变得更容易调试.
go build -gcflags='all=-N -l' main.go
1. go tool compile -N -l -S main.go
2. go tool compile -N -l main.go1. go tool objdump main.o //反汇编出代码2. go tool objdump -s Do main.o //反汇编特定的函
3. go build -gcflags -S main.go
4. go tool compile 和 go build -gcflags -S 生成的是过程中的汇编,和最终的机器码的汇编可以通过go tool objdump生成
逃逸分析
该参数不光优化编译的二进制包,还能进行项目的逃逸分析
go build -gcflags="-m -l" ./main.go
- 这一命令中,-m 表示打印出逃逸分析信息,-l 表示禁止内联,可以更好地观察逃逸。
- 从以下输出结果可以看到,发生了逃逸,也就是说指针作为函数返回值的时候,一定会发生逃逸。
// 变量 m 没有逃逸,反而被变量 m 引用的变量 s 逃逸到了堆上。
// 所以被map、slice 和 chan 这三种类型引用的指针一定会发生逃逸的。func main() {m := map[int]*string{}s := "小胡"m[0] = &s
}
stripped
文件属性解释词:stripped,曾经在编译Go项目过程中,没有转为Linux适配的二进制,而导致出错(cannot execute binary file
),就是采用 file 文件名
命令来分析二进制文件的属性;来快速定位问题。
**************** stripped ****************
- 同样名字的动态库,带not stripped库会大很多。
- stripped 表示执行程序中剔除了符号表信息
- not stripped 表示没有剔除
- 一般最终的程序都会使用strip来减小可执行文件的体积,而调试中的程序则不使用strip。
- strip 是一个命令,就是负责剔除符号表信息,这样执行程序的尺寸会变小,但是不便调试
主程序
- 用于项目编译过程展示:项目版本号、日期、git版本、go版本;
var (version = "" // "1.0.0"buildstamp = "" // time.Now()githash = "" // "1.0.0"goversion = "" // fmt.Sprintf("%s %s/%s", runtime.Version(), runtime.GOOS, runtime.GOARCH)// VERSION string// BUILD_TIME string// GO_VERSION string
)func main() {// fmt.Printf("%s\n%s\n%s\n", VERSION, BUILD_TIME, GO_VERSION)args := os.Argsif len(args) == 2 && (args[1] == "--version" || args[1] == "-v") {fmt.Printf("Version : %s\n", version)fmt.Printf("Git Commit Hash: %s\n", githash)fmt.Printf("CST Build Time : %s\n", buildstamp)fmt.Printf("Golang Version : %s\n", goversion)return}
}
build.sh
展示一个编译的shell脚本,补充上篇在写项目编译的过程只是给出了命令,没有通过脚本执行,这样提升了了编译的效率
#!/bin/bashecho "(1)Windows下 编译 Linux流程:"
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" main.go# 文件 file main的属性
# main: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, strippedecho "(2)Linux 下编译 Mac 和 Windows 平台64位可执行程序:"
#CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build
#CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go buildecho "(3)Mac 下编译 Linux 和 Windows平台 64位 可执行程序:"
#CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build
#CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go buildecho "动态传值1-完整版(注入-版本号、时间date、版本git、go版本): -u 是展示UTC时间"
#flags="-X main.version=1.0.0 -X main.buildstamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X main.githash=`git describe --long --dirty --abbrev=14` -X 'main.goversion=$(go version)'"
flags="-X main.version=1.0.0 -X main.buildstamp=`date '+%Y-%m-%d_%H:%M:%S'` -X main.githash=`git describe --long --dirty --abbrev=14` -X 'main.goversion=$(go version)'"
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -ldflags "$flags" -x -o build-version main.go# 文件 file bulid-version的属性
# build-version: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not strippedecho "手动传值2 (注入:版本号、时间、go版本) :"
# data = UTC
#CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -ldflags "-X main.VERSION=1.0.0 -X 'main.BUILD_TIME=`date -u '+%Y-%m-%d_%I:%M:%S%p'`' -X 'main.GO_VERSION=$(go version)'"# data = CST
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-X main.VERSION=1.0.0 -X 'main.BUILD_TIME=`date`' -X 'main.GO_VERSION=$(go version)'"
参考:https://www.digitalocean.com/community/tutorials/using-ldflags-to-set-version-information-for-go-applications
Go新项目-项目添加版本说明,以及参数传递:ldflags、gcflags,外加stripped说明(5)相关推荐
- visual studio添加对项目的多版本sln配置
我们开发的库文件,适用于多个APP产品,而不同的产品使用了不同版本的IDE工具,VS2005,vs2008,vs2010以及vs2013等,所以为了跟app兼容,我们也需要提供不同版本的库文件,这时就 ...
- IntelliJ IDEA for Mac 如何在当前的普通Java项目中创建新的模块/添加模块/创建模块
文章目录 添加模块的入口 创建新的项目模块 添加模块的入口 添加新的模块的入口有两个,如下图所示: 第一种方式,[File] --> [New] --> [Module]: 第二种方式,打 ...
- 【解决问题】Qt项目不能添加新文件Files are not automatically added to the CmakeLists.text file of the CMake project.
Qt项目不能添加新文件Files are not automatically added to the CmakeLists.text file of the CMake project. 在Qt项目 ...
- 物联网新零售项目 物联网亿万级通信一站式解决方案EMQ
物联网亿万级通信一站式解决方案EMQ 1. MQTT 1.1 MQTT简介 1.1.1 什么是MQTT MQTT(Message Queuing Telemetry Transport,消息队列遥 ...
- 使用gitlab创建项目和添加成员,并提交本地代码至gitlab远程仓库
一.背景 GitHub和GitLab 都是基于web的Git仓库,使用起来二者差不多,它们都提供了分享开源项目的平台,为开发团队提供了存储.分享.发布和合作开发项目的中心化云存储的场所. GitHub ...
- 新个人项目-- 拼图游戏
正式开博记录,想和很久但一直没有执行的新个人项目-- 拼图游戏. 完全由前端技术完成.从简单粗糙到复杂精细. 为了督促自己持续推进该项目,立博为证. 之后会陆续将文档.计划补充上来.都是非官方非正式的 ...
- Entity Framework 的小实例:在项目中添加一个实体类,并做插入操作
Entity Framework 的小实例:在项目中添加一个实体类,并做插入操作 Entity Framework 的小实例:在项目中添加一个实体类,并做插入操作 1>. 创建一个控制台程序 2 ...
- 使用 dotnet-outdated 维护项目 nuget 包版本
使用 dotnet-outdated 维护项目 nuget 包版本 Intro 我们项目中或多或少都会有一些 NuGet 包,使用到 NuGet 包时,如何保证我们的 NuGet 包不会太旧呢?我们可 ...
- Abp Vnext应用程序项目中添加docker支持的小结
文章目录 介绍 具体步骤 1.创建项目 2.添加docker支持 3.调整 4.运行实例 总结 介绍 abp vnext 里面的只有 module 项目里面是自动添加 docker 支持的,因为其是面 ...
- Linux下SVN创建新的项目
Linux下SVN创建新的项目 Linux环境下的SVN创建新的项目 一.前置条件: 1)有安装了linux系统的服务器,123.*.*.29 2)服务器上安装了svn,本人服务器的svn的数据安装的 ...
最新文章
- 重庆南岸召开总结会,今年将引进30家车联网企业
- 怎么判断日出时间早晚_珠海最全防堵攻略,知道这些上班时间或缩短半小时!有大数据分析!...
- coreData使用
- 临床观察性研究论文如何撰写“方法”?
- VTK:InfoVis之DelimitedTextWriter
- 线程池状态和使用注意点
- TableView下拉图片放大
- [FY20 创新人才班 ASE] 第 1 次作业成绩
- 量子力学到底神奇在哪里?看完这个,我的认知彻底坍塌了
- android.mk ndk编译选项优化,Android NDK 编译脚本分析 之一
- javascript进制转换_《算法笔记》3.5小节——入门模拟-gt;进制转换
- js——window.open用法
- python爬虫工程师必学app数据抓取实战_另辟蹊径,appium抓取app应用数据了解一下!...
- 金蝶kiss专业版财务软件下载。
- vos网络电话系统怎样搭建?
- Unity 3D官方教程——2D Roguelike学习记录
- 艰难环境下,面腾讯、美团、商汤科技等七家大厂前端有感
- 计算机导论论文对课程的思考,计算机导论课浅析论文
- 使用yum安装java
- LABVIEW绘制等高线
热门文章
- vue 前端导出Excel表格(基础版 + 多级标题)纯前端导出
- MTK芯片型号和对应支持功能
- 为什么获取crm服务器信息失败,CRM项目失败的七大原因
- linux | setfacl - - 细分文件权限
- Setfacl : Operation not supported
- ES6 Array every()实例讲解
- 上计算机专业的梦想与目标,坚定升学目标,放飞大学梦想 ——计算机专业部召开强化班战前动员会...
- linux获取DNS地址 C语言,使用C语言获取DNS nameserver并进行域名解析
- 实战:从文件夹中庞大的excel(.xlsx)文件中提取并整合数据
- python-opencv之人脸检测