大家好,我是建宇。我有一个朋友,他很高兴地进入了工作岗位,想要展示自己的实力。第一项任务是对旧的二进制文件进行研究。他看到这个文件的时候,不知道编译器是怎么用什么参数打出来的。他不知道环境是什么,更不知道来自哪个代码分支?除了项目过程中的问题,Go在这方面也有类似的小问题,处理起来比较麻烦。背景每天都很难从Go二进制文件中检索元信息,要么信息完全丢失,要么提取需要对二进制文件进行大量解析。包含的元信息如下:元信息提取点的Go构建版本符号表,通过全局变量runtime.buildVersion获取构建信息,例如:模块和版本符号表,获取编译器选项通过全局变量runtime/debug.modinfo,例如:Buildmode、compiler、gcflags、ldflags等无法获取用户自定义的自定义数据,例如:applicationversion等需要在编译时设置全局字符串变量,为了获得注意编译器选项,也就是参数等,是不可能知道的,也就是会增加获得如何编译它的难度。NewProposalMichaelObermüller提出了一个新的提案《cmd/go: add compiler flags, relevant env vars to 'go version -m' output》来解决上述问题。提案中需要的是JSON格式的结构化输出:{"version":"go1.13.4","compileropts":{"compiler":"gc","mode":"pie","os":"linux",...},"buildinfo":{"path":"我的脑子炸了","main":{"path":"HelloWorld","version":"(devel)",},"deps":[]},"user":{"customkey":"customval",...}}RussCox表示,由于编译信息已经有了现成的格式,默认使用JSON只会让二进制文件更大的。好处少,也没有必要。它已更改为可选支持。在新的Go1.18版本中,可以通过现有的:goversion-m查看提案中提到的信息。例如:$gotipversiongoversiondevelgo1.18-eba0e866faMonOct1822:56:072021+0000darwin/amd64$gotipbuild./$gotipversion-mko...buildcompilergcbuildtagsgoexperiment.regabiwrappers,goexperiment.regabireflect,goexperiment.regabiargsbuildCGO_ENABLEDtruebuildCGO_CPPFLAGSbuildCGO_CFLAGSbuildCGO_CXXFLAGSbuildCGO_LDFLAGSbuildgitrevision6447264ff8b5d48aff64000f81bb0847aefc7bacbuildgituncommittedtrue若需要输出JSON格式,也可以通过指定goversion-json达到一样的效果。Intheaboveoutput,the现有的编译器选项等都会被包含进来,让大家对整体编译后的二进制文件的可追溯性有更好的了解。总结在今天的文章中,我介绍了Go1.18的一个新变化。在新版本中,编译器选项/参数、相关环境变量等都将包含在编译后的二进制文件中,方便后人排查问题和查看信息。如有任何问题,欢迎在评论区反馈交流。最好的关系是相互成就。您的好评是炸鱼创作最大的动力。感谢您的支持。文章持续更新中。可以微信搜索【脑补炸鱼】阅读。本文已收录在GitHubgithub.com/eddycjy/blog中。学习Go语言可以看Go学习地图和路线。欢迎星星提醒。
