参考:
构建约束
Go 语言的构建约束(Build Constraints)是一种条件编译机制,允许开发者根据不同的构建条件编译不同的代码文件或代码块。这种机制在以下场景特别有用:
- 为不同操作系统编写特定代码
- 创建功能开关
- 构建不同版本的程序(如社区版/专业版)
- 处理平台特定的依赖
使用方式
编译标签(build tag)
- 在源码文件顶部添加 (在所有代码之前),来决定文件是否参与编译
- 与其他注释之间需要存在一个空行
常用预定义约束条件
| 约束条件 | 说明 | 
|---|---|
| linux | Linux 系统 | 
| darwin | macOS 系统 | 
| windows | Windows 系统 | 
| amd64 | 64位 x86 架构 | 
| arm | ARM 架构 | 
| 386 | 32位 x86 架构 | 
| arm64 | 64位 ARM 架构 | 
| cgo | 启用 CGO | 
| race | 启用竞态检测 | 
| test | 测试模式 | 
| prod | 生产环境(自定义) | 
| debug | 调试模式(自定义) | 
语法
- 以下是 Go 1.17 之后新版构建约束语法: - 1BuildLine = "//go:build" Expr 2Expr = OrExpr 3OrExpr = AndExpr { "||" AndExpr } 4AndExpr = UnaryExpr { "&&" UnaryExpr } 5UnaryExpr = "!" UnaryExpr | "(" Expr ")" | tag 6tag = tag_letter { tag_letter } 7tag_letter = unicode_letter | unicode_digit | "_" | "."- 1&& 表示:AND 2|| 表示:OR 3! 表示:NOT 4() 表示:分组- 1//go:build linux && amd64
- 旧语法(向后兼容) - 1空格表示:AND 2逗号表示:OR 3!表示:NOT 4换行表示:AND- 1// +build linux,amd64
构建命令示例
1//go:build dog
2
3package main
4
5func sum(a, b int) int {
6	return a + b
7}
1//go:build !dog
2
3package main
4
5func sum(a, b int) int {
6	return a + b
7}
- 当使用 go build或go build !dog时,编译的是第二个文件
- 当使用 go build tags dog时,编译的是第一个文件
编译器根据 tag 标识,有选择性的加载对应文件进行编译
 1# 构建 Linux 版本
 2go build -tags linux
 3
 4# 构建生产版本
 5go build -tags prod
 6
 7# 构建带调试信息的 Windows 版本
 8go build -tags "windows debug"
 9
10# 构建测试版本(带竞态检测)
11go test -race -tags test
文件后缀
| 文件名模式 | 等效构建约束 | 
|---|---|
| *_linux.go | // +build linux | 
| *_windows_amd64.go | // +build windows,amd64 | 
| *_test.go | // +build test | 
Go源码中 os 包的Linux、windows实现:
1src/runtime/os_linux.go
2src/runtime/os_linux_arm.go
3src/runtime/os_linux_arm64.go
4src/runtime/os_windows.go
5src/runtime/os_windows_arm.go
6src/runtime/os_windows_arm64.go
注意事项
- 构建约束注释后必须有一个空行
- 当使用文件命名约定时,显式的构建约束会覆盖命名约定
- 构建约束不会影响导入的包,只会影响当前文件的编译