参考:
构建约束
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
注意事项
- 构建约束注释后必须有一个空行
- 当使用文件命名约定时,显式的构建约束会覆盖命名约定
- 构建约束不会影响导入的包,只会影响当前文件的编译