Logo
Section 1 / 13

理解 Go 构建过程

让我们来看看如何构建 Go 程序。

导入

理解 Go 构建过程

让我们来看看如何构建 Go 程序。

我们将讨论 Go 的工具哲学,理解 Go 的构建过程,并研究 go build 命令。

概览

Go 以其工具链而自豪。与许多编程语言将工具链视为次要考虑甚至交由社区处理不同,Go 将工具链视为语言核心功能的重要组成部分。现代 Go 使用模块来构建包并管理依赖项。虽然旧式的 GOPATH 仍为向后兼容而保留,但除非你维护的是遗留系统且无法向前迁移,否则应专注于 Go 模块。

主要工具是 go build 命令,它允许我们在链接程序时嵌入信息。go build 默认会调用链接器。

Multi-git 可以利用这一特性,输出有用的版本信息。

理解 Go 构建过程

Go 构建包。这些包可以是可执行文件、静态包或动态包。当你通过构建一个 main 包来创建可执行程序时,生成的二进制文件可能仍然依赖于动态链接库。要使可执行文件真正静态化,你需要提供一些标志。

Go 还可以通过特殊的 import 语句和 CGO 工具与 C 紧密集成。

所有这些构建过程中的细微差别,以及更多内容,都由各种构建标志控制。

go build 命令

以下是 go build 的签名:

1go build [-o output] [-i] [build flags] [packages]

我们将重点关注构建标志:

1 -a 2 强制重新构建已经最新更新的包。 3 -n 4 打印命令但不执行它们。 5 -p n 6 可并行运行的程序数量,例如构建命令或测试二进制文件。 7 默认值是可用 CPU 数量。 8 -race 9 启用数据竞争检测。 10 仅支持 linux/amd64、freebsd/amd64、darwin/amd64、windows/amd64、 11 linux/ppc64le 和 linux/arm64(仅限 48 位 VMA)。 12 -msan 13 启用与内存探测器的互操作性。 14 仅支持 linux/amd64、linux/arm64, 15 且必须使用 Clang/LLVM 作为宿主 C 编译器。 16 在 linux/arm64 上,将使用 pie 构建模式。 17 -v 18 在编译时打印包名称。 19 -work 20 打印临时工作目录的名称,并在退出时不删除它。 21 -x 22 打印命令。 23 24 -asmflags '[pattern=]arg list' 25 传递给每次 go tool asm 调用的参数。 26 -buildmode mode 27 使用的构建模式。详见 'go help buildmode'。 28 -compiler name 29 要使用的编译器名称,如 runtime.Compiler (gccgo 或 gc)。 30 -gccgoflags '[pattern=]arg list' 31 传递给每次 gccgo 编译器/链接器调用的参数。 32 -gcflags '[pattern=]arg list' 33 传递给每次 go tool compile 调用的参数。 34 -installsuffix suffix 35 用于包安装目录名称的后缀,以便将输出与默认构建分开。 36 如果使用 -race 标志,安装后缀会自动设为 race, 37 或显式设置时会在其后追加 _race。同样适用于 -msan 标志。 38 使用需要非默认编译标志的 -buildmode 选项也有类似效果。 39 -ldflags '[pattern=]arg list' 40 传递给每次 go tool link 调用的参数。 41 -linkshared 42 构建将与之前使用 -buildmode=shared 创建的共享库链接的代码。 43 -mod mode 44 模块下载模式:readonly、vendor 或 mod。 45 详见 'go help modules'。 46 -modcacherw 47 在模块缓存中新建的目录保持读写状态, 48 而不是将其设为只读。 49 -modfile file 50 在模块感知模式下,读取(并可能写入)替代的 go.mod 文件, 51 而不是模块根目录中的那个。尽管仍需存在名为 "go.mod" 的文件 52 以确定模块根目录,但不会被访问。当指定 -modfile 时, 53 也会使用替代的 go.sum 文件:其路径通过从 -modfile 标志中 54 去掉 ".mod" 扩展名并添加 ".sum" 得到。 55 -pkgdir dir 56 从 dir 安装和加载所有包,而不是通常的位置。 57 例如,在使用非标准配置构建时, 58 使用 -pkgdir 将生成的包保留在单独位置。 59 -tags tag,list 60 逗号分隔的构建标签列表,构建期间视为已满足。 61 有关构建标签的更多信息,请参阅 go/build 包文档中关于构建约束的描述。 62 (早期版本的 Go 使用空格分隔列表,该形式已弃用但仍被识别。) 63 -trimpath 64 从最终生成的可执行文件中移除所有文件系统路径。 65 记录的文件名将不再包含绝对路径, 66 而是以 "go"(标准库)、 67 模块路径@版本(使用模块时),或普通导入路径(使用 GOPATH 时)开头。 68 -toolexec 'cmd args' 69 用于调用工具链程序(如 vet 和 asm)的程序。 70 例如,不是直接运行 asm,go 命令将运行 71 'cmd args /path/to/asm <asm 的参数>'。

标志众多,但本课程中我们仅关注通过 -ldflags 指定的链接器标志。

如前所述,go build 命令在构建可执行文件时也会运行链接器工具。

在下一课中,我们将学习如何使用 Go 构建包。

添加高级配置

构建 Go 包