标签 github 下的文章

探索Go gcflags的使用模式与完整参数选项列表

本文永久链接 – https://tonybai.com/2025/01/22/gcflags-options-list-and-usage

Go build是Go开发中不可或缺的构建工具,其中-gcflags参数为开发者提供了向编译器传递额外选项的能力。然而,关于-gcflags的完整参数选项和使用模式,官方文档多有局限,很多开发者对此了解不深。本文将系统性地解析-gcflags的完整参数来源以及其结合包模式(package pattern)的使用方法,供大家参考。

注:本文主要以-gcflags为例,其实go build的-ldflags参数与-gcflags在使用方法上如出一辙,唯一不同的是ldflags是将参数传递给go链接器。

gcflags是Go构建工具的一个标志,用于向Go编译器 (go tool compile) 传递额外的编译参数。通过它,开发者可以调整编译行为,例如禁用优化、生成调试信息或输出反汇编代码等。

Go build文档中关于-gcflags的说明很短小精悍:

$go help build
... ...
    -gcflags '[pattern=]arg list'
        arguments to pass on each go tool compile invocation.
    -ldflags '[pattern=]arg list'
        arguments to pass on each go tool link invocation.
... ...

The -asmflags, -gccgoflags, -gcflags, and -ldflags flags accept a space-separated list of arguments to pass to an underlying tool during the build. To embed spaces in an element in the list, surround it with either single or double quotes. The argument list may be preceded by a package pattern and an equal sign, which restricts the use of that argument list to the building of packages matching that pattern (see 'go help packages' for a description of package patterns). Without a pattern, the argument list applies only to the packages named on the command line. The flags may be repeated with different patterns in order to specify different arguments for different sets of packages. If a package matches patterns given in multiple flags, the latest match on the command line wins. For example, 'go build -gcflags=-S fmt' prints the disassembly only for package fmt, while 'go build -gcflags=all=-S fmt' prints the disassembly for fmt and all its dependencies.

... ...

多数Go初学者初次看到上述关于gcflags的说明,都无法知道到底有哪些arg可用以及究竟如何使用gcflags,而Go cmd文档中关于gcflags的内容也仅限于上述这些。

我将大家遇到的主要问题总结为下面两条:

  • gcflags的完整参数选项列表在哪里可以找到?
  • gcflags的使用模式,尤其是其中的package pattern应该如何正确使用?

如果你能正确回答上述两个问题,那你就基本掌握了gcflags的使用,大可不必继续往下看了

否则,我们就一起分别看一下这两个问题该如何解答。

在哪里能查找到gcflags可用的全部参数选项呢?go help build不行,go command的web文档中没有!甚至Go tool compile的web文档中列举的gcflag的参数列表也是不全的(或者说是文档没有及时同步最新的参数列表变化),也许我们应该提一个issue给Go团队^_^。

远在天边近在眼前!下面命令可以让-gcflag可用的参数选项完整列表尽收眼底:

$go tool compile -h
usage: compile [options] file.go...
  -%    debug non-static initializers
  -+    compiling runtime
  -B    disable bounds checking
  -C    disable printing of columns in error messages
  -D path
        set relative path for local imports
  -E    debug symbol export
  -I directory
        add directory to import search path
  -K    debug missing line numbers
  -L    also show actual source file names in error messages for positions affected by //line directives
  -N    disable optimizations
  -S    print assembly listing
  -V    print version and exit
  -W    debug parse tree after type checking
  -asan
        build code compatible with C/C++ address sanitizer
  -asmhdr file
        write assembly header to file
... ...

同样,如果你要查看-ldflags的完整参数选项列表,你可以使用下面命令:

$go tool link -h
usage: link [options] main.o
  -B note
        add an ELF NT_GNU_BUILD_ID note when using ELF; use "gobuildid" to generate it from the Go build ID
  -E entry
        set entry symbol name
  -H type
        set header type
  -I linker
        use linker as ELF dynamic linker
  -L directory
        add specified directory to library path
  -R quantum
        set address rounding quantum (default -1)
  -T int
        set the start address of text symbols (default -1)
  -V    print version and exit
  -X definition
        add string value definition of the form importpath.name=value
  -a    no-op (deprecated)
  -asan
        enable ASan interface
... ...

到这里,我们得到了第一个问题的答案。

接下来,我们再来看第二个问题:-gcflags的使用模式。

根据go help build的输出,我们知道-gcflags的使用形式如下:

-gcflags '[pattern=]arg list'

其中:

  • [pattern=](可选):包模式(package pattern),用于作用范围控制,即限定参数仅应用于特定的包。如果省略此部分,则参数仅适用于命令行中指定的包。
  • arg list:参数选项列表,多个参数以空格分隔。

对包模式有很好地理解并非是使用好gcflags的必要条件。但在一些复杂项目中,我们可能会通过包模式精确控制调试和优化,在这种情况下,对包模式有深入理解还是大有裨益的。

包模式是一种通过匹配规则指定目标包的方式,常见的包模式有几下几种:

  • ./…:匹配当前目录及其所有子目录中的包。
  • /DIR/…:匹配/DIR及其子目录中的包。
  • cmd/…:匹配Go仓库中cmd目录下的所有命令包。
  • github.com/user/repo/…:匹配该github仓库中的所有包。
  • all:GOPATH模式下,匹配的是所有GOPATH路径中的包,Go module模式下,all匹配主模块及其所有依赖的包(包括测试依赖)。
  • std:仅匹配标准库包。
  • cmd:匹配Go仓库中的Go命令及其内部包(internal)。

基于上述关于gcflags使用形式以及包模式的说明,我们举几个示例来直观理解一下gcflags的用法:

  • 对单个包设置参数
$go build -gcflags=-S fmt

上述命令中的参数-S仅作用于fmt包,显示其反汇编代码。

  • 对特定模式(比如all/std等)的包设置参数
$go build -gcflags='all=-N -l'

在Go module模式下,参数-N和-l应用于当前主模块所有包及其依赖,禁用优化和内联。

  • 对不同包模式设置不同参数
$go build -gcflags='fmt=-S' -gcflags='net/http=-N'

Go build命令行中可以多次使用-gcflags,上述命令中的第一个gcflags对fmt包启用反汇编输出(-S)。第二个gcflags对net/http包禁用优化(-N)。

  • 模式的优先级
$go build -gcflags='all=-N' -gcflags='fmt=-S'

像上面命令中,两个gcflags都匹配了fmt包,或者说两个gcflags的作用范围都包含了fmt包,这种情况下哪些参数会对fmt包生效呢?Go规定:当一个包匹配多个模式时,以最后一个匹配的参数为准。在这个例子中,fmt包将只应用-S参数,而其他包应用-N参数。

到这里,我们完成了对两个关于gcflags问题的回答!

最后小结一下:

  • gcflags(以及-ldflags)是Go构建工具中的重要选项,能极大提升调试和优化效率。
  • gcflags的完整的参数选项需通过底层工具获取,即go tool compile -h和go tool link -h。
  • 对包模式的灵活使用能够精确控制gcflags参数的作用范围,为复杂项目提供了更大的自由度。

通过本篇文章,希望你能掌握查看gcflags完整参数列表的方法以及gcflags的使用模式,并在构建和调试Go项目时能更加得心应手。


Gopher部落知识星球在2025年将继续致力于打造一个高品质的Go语言学习和交流平台。我们将继续提供优质的Go技术文章首发和阅读体验。并且,2025年将在星球首发“Go陷阱与缺陷”和“Go原理课”专栏!此外,我们还会加强星友之间的交流和互动。欢迎大家踊跃提问,分享心得,讨论技术。我会在第一时间进行解答和交流。我衷心希望Gopher部落可以成为大家学习、进步、交流的港湾
。让我相聚在Gopher部落,享受coding的快乐! 欢迎大家踊跃加入!

img{512x368}
img{512x368}

img{512x368}
img{512x368}

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

Gopher Daily(Gopher每日新闻) – https://gopherdaily.tonybai.com

我的联系方式:

  • 微博(暂不可用):https://weibo.com/bigwhite20xx
  • 微博2:https://weibo.com/u/6484441286
  • 博客:tonybai.com
  • github: https://github.com/bigwhite
  • Gopher Daily归档 – https://github.com/bigwhite/gopherdaily
  • Gopher Daily Feed订阅 – https://gopherdaily.tonybai.com/feed

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

2024年Go语言盘点:排名历史新高,团队新老传承

本文永久链接 – https://tonybai.com/2024/01/06/the-2024-review-of-go-programming-language

2024年底,由于感染了甲流,我在家卧床休息了两天,原定于2024年进行的Go语言盘点写作因此被迫推迟。不过,我始终相信:迟到但不会缺席。在2025年元旦的第一天,我终于开始了这篇博客的撰写。

时间过得真快,《2023年Go语言盘点:稳中求新,稳中求变》依然历历在目。转眼之间,一年365天过去了,发生了许多事情,甚至有些记忆已在脑海中模糊或消逝。在这里,我将带你盘点那些关于Go的重要时刻,唤起你对Go的美好回忆。

回顾整个2024年,如果非要用一句话来形容Go语言的状态,我会选择:Go完成了技术成熟度曲线中的“稳步爬升复苏期”,开始进入“生产成熟期”。这一点在Go的排名中得到了直接体现,并在Go社区的活跃度方面得到了间接的印证。而Go的年中换帅似乎也预示着这是一个新的起点!在过去一年中,得益于Go团队和社区的共同努力,Go发布了许多值得关注的新特性。

接下来,我将为大家逐一详细介绍!

1. Go排名创历史新高

说到编程语言排名,程序员们首先想到的就是TIOBE!在2024年的TIOBE排行榜上,尽管Go语言没有像AI时代的霸主语言Python那样耀眼,但跻身前十并站稳第七名这一成绩也足以让其他语言羡慕不已!


图:2024年12月TIOBE排名TOP 10

而从2009年开源至今,Go在TIOBE排名走势如下:


图:2010年-2024年TIOBE排行榜Go语言走势

了解Go历史的朋友都知道,Go语言真正具备生产级成熟度是从2015年的Go 1.5版本开始的。按照技术成熟度曲线的划分,2015年之前及其后的一段时间可以视为技术萌芽期。从曲线中可以看出,2017年时达到了期望膨胀期的峰值。此后,Go经历了一段“漫长”的泡沫破裂低谷期以及稳步爬升的复苏期。从2023年开始,到2024年末,Go语言复苏的速度日益加快!目前来看,如无意外,Go将进入技术成熟度曲线的下一阶段:生产成熟期!我曾提到过:绝大多数主流编程语言将在其诞生后的第15至第20年间大步前进。按照这个编程语言的一般规律,刚刚迈过开源第15个年头的Go刚刚迈进自己的黄金5-10年。

当然,单看TIOBE单一榜单似乎说服力不足,我们再来看看今年的Github octoverse报告。在这份报告中,Go依旧稳居github热门编程语言前10(如下图),这一位置已经保持了三年多了!


图:2024年Github最热门编程语言排行榜

此外,在2024年年中发布的“IEEE Spectrum 2024编程语言排行榜”中,Go在Spectrum排名和Trending排名中分列第8位和第7位。

除了排行榜之外,通过Reddit中编程语言论坛的活跃度也可以看出Go语言在全球的受欢迎程度和用户广度。以下是2025年1月1日Reddit上最活跃的9门编程语言子论坛的实时状态截图:


图:2025.1.1 Reddit编程语言子论坛状态对比

我们看到Go子论坛在成员数量和某一时刻的在线人数上都表现良好。此外,如果你是长期关注Reddit Go论坛的Gopher,一定注意到自2024年初以来,Go论坛的人气迅速增长,日均帖子数相比前两年显著增加,其中很多都是新加入Go阵营的初学者!

注:Rust的人气是真高啊,online人数断崖领先!

编程语言技术大会是衡量语言流行度和受欢迎程度的另一重要风向标。自从全球从新冠疫情中恢复后,GopherCon逐渐在各地线下恢复,到了2024年基本回到了疫情前的状态,甚至在一些地方的GopherCon还超越了以往的受欢迎程度。例如,2024年GopherCon欧洲大会破例举办了两次。此外,首届在非洲举行的GopherCon Africa也于2024年10月份在肯尼亚首都内罗毕成功举行!唯一的遗憾是GopherChina在2024年缺席,这或许与国内的经济形势有关。

Go的增长趋势来的有些快,不知道是否是得益于AI应用的快速发展!但就像Go团队前成员Jaana Dogan(Rakyll)所说的那样:

Go将成为AI时代重要的AI应用开发语言!AI大模型三强:OpenAI、Claude和Google都提供了对Go SDK的官方支持:

  • OpenAI Go SDK – https://github.com/openai/openai-go
  • Claude GO SDK – https://github.com/anthropics/anthropic-sdk-go
  • Google AI Go SDK – https://github.com/google/generative-ai-go

此外,提到Go和AI大模型,我们不得不提及一个重量级的开源项目——Ollama,它可以说是当前私有部署和使用开源大模型的事实标准!在2024年的用户调查报告中,Go团队还特别关注了用户对使用Go开发AI应用的需求,并将AI应用开发视为Go应用的下一个重要赛道。此外,Russ Cox也积极参与这一领域,开源了专用于开源项目运营维护的AI机器人:Oscar,同时探索Go在AI领域的应用。

如果说Go的排名再创新高让Gopher和Go社区对Go充满了更多自信,那么Go团队的换帅则向整个编程语言界展示了团队的传承与发展!

2. Go团队换帅展示团队传承

对于Go团队来说,2024年的最大的事件不是Go 1.22Go 1.23的发布,而是团队换帅

2024年中旬,Go团队的技术负责人Russ Cox宣布,他将于2024年9月1日起卸任Go项目的技术领导职务。自2008年参与Go项目以来,Russ于2012年成为其技术负责人。在过去的12年里,他引领Go语言从一个实验性项目成长为当今最受欢迎的编程语言之一。在他的带领下,Go凭借简洁的语法、高效的并发模型和强大的标准库赢得了众多开发者的青睐,并在云计算、微服务和DevOps等领域得到了广泛应用。

Russ分享了他卸任的想法,表示这一决定是经过深思熟虑的,是自然发展的结果。他认为,尽管长期稳定的领导对大型项目至关重要,但领导层的变动也能为项目注入新的活力和视角。他强调,定期更换领导者是非常重要的,这有助于引入新思想并防止项目陷入停滞。

接替Russ Cox的是Austin Clements,他将成为新的Go技术负责人,同时领导Google的Go团队和整个Go项目。Austin自2014年起就在Google从事与Go相关的工作,拥有丰富的经验和深厚的技术背景。同时,Cherry Mui将接手负责编译器和运行时等“Go核心”领域的工作。Cherry自2016年加入Google,在Go的核心开发领域表现出色。Russ Cox对这两位新领导给予了高度评价,称赞他们具备卓越的判断力以及对Go语言和其运行系统的广泛而深入的理解。

通过9月份到12月份的角色过期期的观察来看,两位“新负责人”的表现是中规中矩,沿袭了Russ Cox之前确定的Go项目管理框架,Cherry Mui在Go core领域表现的十分积极,这从”Go compiler and runtime meeting notes“的记录中可见一斑!

第333期GoTime播客中,两位新leader也初步分享了他们对后续Go演进的一些想法。

Austin强调,虽然Go保持着稳定和简洁,但它必须继续演进。他的首要目标之一是改善Go的可扩展性,无论是在开发过程中还是在背后的工程流程中。他希望通过提高透明度和扩大社区参与度,赋能社区,创建一个能够更好整合用户反馈的平台(可能是一个论坛),使贡献者能够开发与核心团队目标一致的工具和解决方案。在性能改进方面,Austin长期致力于优化Go的垃圾回收系统,目前正在试验一种新算法,幽默地称其为“绿茶”,旨在优化资源使用,进一步提升Go在越来越大系统上的扩展能力。

Cherry则指出,Go的用户基础正在快速增长,而核心团队的资源却有限。她的任务是确保Go平台能够支持这一日益增长的社区,无论是通过构建更好的API还是平台,帮助用户在Go的基础上开发更强大的工具和解决方案。在技术扩展性方面,Cherry也表达了自己的关注。随着计算能力的提升,核心数量和内存容量不断增加,Go需要适应,以高效处理更大的工作负载。Cherry表示,她非常期待与社区中的工程师合作,解决这些挑战,保持Go简单且可扩展的声誉。

从两位领导的想法与目标中,我们可以看到Go团队传承的文化。对于这样的“换帅”,Go社区应充满信心。

注:GoTime博客在完成其第340期内容后,因平台方Changelog的变动宣布停播了!

3. Go Release新特性一览

对于已经过了15个生日的Go来说,其演进的节奏已经非常稳定和成熟了。2024年,Go平稳地发布了两个重要版本:Go 1.22和Go 1.23。下面我们就来简单浏览一下这两个版本的主要新特性。

3.1 Go 1.22主要新特性

语言特性

  • loopvar语义修正:for循环中通过短声明定义的循环变量,由整个循环共享一个实例变为每次迭代定义一个实例。这是 Go 语言发展历史上第一次真正的填语义层面的“坑”。
  • for range支持整型表达式:for range循环可以遍历整型范围,如for i := range 10。

编译器和运行时

  • PGO优化增强:基于PGO的构建可以实现更高比例的调用去虚拟化(devirtualize),带来性能提升。
  • 编译器优化:编译器可以更多地运用devirtualize和inline技术进行优化。
  • 运行时优化:运行时可以使基于类型的垃圾收集的元数据更接近每个堆对象,从而降低CPU和内存开销。

工具链

  • go work支持vendor:go work命令可以管理vendor目录,并且支持使用go build -mod=vendor构建。
  • go mod init改进:不再尝试导入其他vendor工具(比如Gopkg)的配置文件。
  • go test -cover改进: 对于没有测试文件的包,会报告覆盖率为0.0%。

标准库

  • math/rand/v2: 标准库第一个V2版本包。
  • 增强http.ServeMux的表达能力: 新版ServeMux支持静态路由、通配符、主机匹配和变量捕获。

3.2 Go 1.23 主要新特性

语言特性

  • 自定义函数迭代器:for range语句支持遍历用户自定义的集合类型,需要定义满足特定签名的迭代器函数。
  • 别名中增加泛型参数:支持在类型别名定义中使用类型参数,如:
type MySlice[T any] = []T

编译器与运行时

  • PGO构建速度提升: 该版本优化后,PGO带来的编译开销显著降低。
  • 限制对linkname的使用: Go 1.23禁止使用linkname指令引用标准库中未标记的内部符号。

工具链

  • Telemetry (遥测): go工具链程序收集性能和使用数据的系统,且支持go telemetry on|off|local命令。
  • go env -changed: go env子命令增加-changed选项,可以查看当前Go环境中设置的Go环境变量值与默认值有差异的项的值。
  • go mod tidy -diff: go mod tidy增加-diff选项,只打印更新信息但不做实际更新。
  • go.mod中增加godebug指示符: 可以通过该指示符设置特定的GODEBUG选项。

标准库

  • Timer/Ticker变化: Timer和Ticker的GC不再需要Stop方法,Stop/Reset后不再接收旧值。
  • structs包: 添加一个零size的类型HostLayout,用于控制编译器对结构体类型的布局方式。
  • unique包: 新增了unique包,用于处理唯一值的集合。
  • iter包: 新增了iter包,并增加了函数迭代器相关的实用函数到maps、slices等包中。

更多更详细关于Go新特性的内容,请阅读《Go 1.22中值得关注的几个变化》和《Go 1.23中值得关注的几个变化》。

4. 2025展望

按照Go演进的一贯风格,我本不该对Go抱有过多期待^_^,但还是忍不住想说几句。

Go已经稳稳地占据了云计算领域的头部后端编程语言地位,在多个编程语言排行榜上名列前茅,Go社区也在健康快速地发展。然而,机遇与风险总是并存。

虽然Go在云原生、Web服务、微服务、API和CLI开发方面拥有明显优势,但也面临着来自Rust等语言的挑战。Go需要进一步巩固其在这些优势领域的地位,同时探索一些能够发挥自身优势的新方向,例如AI应用开发等。

同时,我们期待新一代Go团队领导者,尤其是来自Go编译器和运行时组的领导者们,能够深入打磨和优化Go语言的编译器、运行时性能以及语言互操作性。毕竟,谁不喜欢那种因性能自然增长而带来的愉悦感,以及借助其他语言优势生态快速完成功能的灵活性呢!

最后,感谢Go团队和Go社区在Go语言演进发展上做出的贡献,希望Go越走越好!


Gopher部落知识星球在2024年将继续致力于打造一个高品质的Go语言学习和交流平台。我们将继续提供优质的Go技术文章首发和阅读体验。同时,我们也会加强代码质量和最佳实践的分享,包括如何编写简洁、可读、可测试的Go代码。此外,我们还会加强星友之间的交流和互动。欢迎大家踊跃提问,分享心得,讨论技术。我会在第一时间进行解答和交流。我衷心希望Gopher部落可以成为大家学习、进步、交流的港湾。让我相聚在Gopher部落,享受coding的快乐! 欢迎大家踊跃加入!

img{512x368}
img{512x368}

img{512x368}
img{512x368}

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

Gopher Daily(Gopher每日新闻) – https://gopherdaily.tonybai.com

我的联系方式:

  • 微博(暂不可用):https://weibo.com/bigwhite20xx
  • 微博2:https://weibo.com/u/6484441286
  • 博客:tonybai.com
  • github: https://github.com/bigwhite
  • Gopher Daily归档 – https://github.com/bigwhite/gopherdaily
  • Gopher Daily Feed订阅 – https://gopherdaily.tonybai.com/feed

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



Statcounter View My Stats