返回介绍

上卷 程序设计

中卷 标准库

下卷 运行时

源码剖析

附录

工具

发布于 2024-10-12 19:16:09 字数 5049 浏览 0 评论 0 收藏 0

内置工具链使用方法及参数说明。

1. 编译

生成目标文件,分编译(compile)和链接(link)两步。

  • 忽略单元测试文件(_test.go)。
  • 默认复制 main 可执行文件到源码目录。
  • 同时编译多个包,或 non-main 包,仅检查和缓存,放弃复制。
go build [-o output] [build flags] [packages]
  • -o : 目标文件名。
  • -x : 显示正在执行的编译命令。
  • -n : 显示编译命令,但不执行。
  • -p : 并行编译所使用 CPU 核心数量(GOMAXPROCS)。
  • -a : 强制编译所有包(含标准库)。
  • -race : 启用数据竞争检测(amd64, arm64)。
  • -work : 显示临时目录,完成后不删除。
  • -gcflags : 传递给编译器的参数列表。
  • -ldflags : 传递给链接器的参数列表。
  • -C <dir> : 执行命令前,切换目录。

编译器

$ go tool compile -h
  • -B : 禁用边界检查(bounds checking)。
  • -N : 禁用优化(optimizations)。
  • -l : 禁用内联(inlining)。
  • -S : 输出汇编。
  • -m : 输出优化决策(optimization decisions, -m=2-m -m 详细信息)。

复杂参数需要引号,如: go build -gcflags "-m -S"

参数默认用于当前包或命令行指定目标,改为 -gcflags all="..." 作用于所有包(含标准库和依赖包)。

链接器

$ go tool link -h
  • -s : 禁用符号表(symbol table)。
  • -w : 禁止生成调试信息(DWARF)。
  • -X : 添加 全局字符串变量 初始值( importpath.name=value ,支持非导出成员)。
  • -H : 可执行文件类型(如: -H windowsgui )。

如 -X 值有空格,用引号将整个设置包起来。 -ldflags '-X "test/lib.x=a b c" '

反汇编

$ go tool objdump -h
  • -S : 输出源码。
  • -s : 仅输出所匹配符号(如函数名)代码。
  • -gnu : 以注释方式输出 AT&T 格式指令。
$ go tool objdump -S -s "main\.test" ./test

TEXT main.test(SB)
func test() {
  0x455200		4883ec18					SUBQ $0x18, SP		
  0x455204		48896c2410				MOVQ BP, 0x10(SP)	
  0x455209		488d6c2410				LEAQ 0x10(SP), BP	
	println("hello, world!")
  0x45520e		e80d83fdff				CALL runtime.printlock(SB)	
  0x455213		488d05a4d70000		LEAQ 0xd7a4(IP), AX		
  0x45521a		bb0e000000				MOVL $0xe, BX			
  0x45521f		90								NOPL				
  0x455220		e8fb8bfdff				CALL runtime.printstring(SB)	
  0x455225		e87683fdff				CALL runtime.printunlock(SB)	
}
  0x45522a		488b6c2410				MOVQ 0x10(SP), BP	
  0x45522f		4883c418					ADDQ $0x18, SP		
  0x455233		c3								RET

2. 下载

下载第三方包源码到缓存目录(GOMODCACHE),更新 go.mod 依赖设置。

  • 专注依赖管理。
  • 仅下载源码。(不编译,不安装)
  • 预编译用 install 命令。
go get [-t] [-u] [-v] [build flags] [packages]
  • -t : 下载测试所需依赖项。
  • -u : 更新包(依赖项)。
  • -x : 显示正在执行的命令。
$ go get example.com/pkg          # latest version
$ go get example.com/pkg@v1.2.3   # specific version

3. 信息

列出包相关信息,比如有哪些源码文件和依赖。

  • -json : 输出 JSON 格式。
  • -f : 指定字段。
  • -m all : 模块(含依赖及版本号)信息。
  • -m -u all : 模块(含更新)信息。
  • -deps : 依赖(含标准库)信息。
$ go list -json
$ go list -f {{.GoFiles}}

4. 清理

清理相关工作目录,删除编译和安装遗留文件。

go clean [clean flags] [build flags] [packages]
  • -i : 清理 go install 安装文件。
  • -r : 清理依赖项。
  • -x : 显示正在执行的清理命令。
  • -n : 显示清理命令,但不执行。
  • -cache : 清理 go build 缓存。
  • -modcache : 清理 go get 模块缓存。
  • -testcache : 清理 go test 缓存。
  • -fuzzcache : 清理模糊测试缓存。
$ go clean                               # 清除可执行文件等。
$ go clean -cache -testcache -fuzzcache  # 清除缓存。

5. 检查

代码静态检查,找出潜在错误。

$ go tool vet help

示例:对 mutex 值复制引发的错误。

package main

import "sync"

func main() {
	var m sync.Mutex
	m2 := m

	m2.Lock()
	defer m2.Unlock()
}
$ go vet test.go
./test.go:7:8: assignment copies lock value to m2: sync.Mutex

6. 格式

格式化源码文件。

$ gofmt -w *.go
  • -d : 输出要修改的位置,不写入。
  • -l : 列出要修改的文件名。
  • -w : 直接修改原文件。

7. 清单

供应链(开源和第三方组件)风险:

  • 知识产权。
  • 安全。
  • 断供。

软件物料清单 (SBOM, software bill of materials) 是代码库中所使用开源和第三方组件列表,含许可证、版本等信息。go 编译时会将清单嵌入可执行文件内,以便最终用户能快速识别相关设置和许可证风险。

$ go version -m ./test   # 可执行文件。

./test: go1.18.3
	path	test
	mod	test	(devel)	
  
	dep	github.com/shirou/gopsutil/v3	v3.22.5	...
	dep	golang.org/x/sys	            v0.0.0-2022012	...
	
  build	-compiler=gc
	build	CGO_ENABLED=1
	build	CGO_CFLAGS=
	build	CGO_CPPFLAGS=
	build	CGO_CXXFLAGS=
	build	CGO_LDFLAGS=
	build	GOARCH=amd64
	build	GOOS=linux
	build	GOAMD64=v1

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文