导入
理解 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 构建包。