go build 构建约束//go:build
source link: https://studygolang.com/articles/35985
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
go build 构建约束//go:build
123445 · 大约2小时之前 · 69 次点击 · 预计阅读时间 2 分钟 · 大约8小时之前 开始浏览在看别人源码的时候有时会看到类似这样打头的注释:
//go:build xxxx
比如gin的gin/internal/json
包里面就有。
这到底什么意思呢?
这其实是go里面的构建约束,也叫构建标签,build的时候给编译器的标签,可以决定一个文件是否需要包含在包之中。
比如://go:build (linux && 386) || (darwin && !cgo)
表示执行go build的时候,目标系统是386的linux或者没有启用cgo的darwin时,当前文件会被编译进来。
这个就是编译约束。
- 可以出现在任何源文件里面,不仅仅是go源文件。
- 必须写在文件顶部,前面只可以有空白行或其他注释
- 为了区分构建约束和包文件,在构建约束后面应该有一空白行
- 由
||
、&&
、!
运算符(或、与、非)和括号组成的表达式
可用的标签:
- 目标操作系统,拼写和
runtime.GOOS
一致,可以用命令go tool dist list
查看可能的值 - 目标系统架构,拼写和
runtime.GOARCH
一致 unix
,标识GOOS
是Unix或者Unix-like系统- 正在使用的编译器,
gc
或者gccgo
cgo
,如果支持cgo
命令- 每个go主要发布版本的术语,比如:
go1.1
,满足从go1.1版本开始,go1.12
从go1.12版本开始,其他类推 - 通过
-tags
标记给出的其他标签,-tags
多个标签用逗号分隔列出
//go:build ignore
:忽略编译
go 1.16和之前的版本的语法是使用// +build
,gofmt命令在遇到旧语法时会自动添加等效的新语法
gin的gin/internal/json
就是通过标签来确定使用哪个json库的:
go build -tags=jsoniter
go build -tags=go_json
如果一个文件名称,满足如下条件:
*_GOOS
*_GOARCH
*_GOOS_GOARCH
比如一个文件名称source_windows_amd64.go
当目标系统是windows系统amd64架构时会包含编译,GOOS
和 GOARCH
分别代表目标系统的类别和架构类型,满足上面规则的文件被认为需要满足这些条件的隐式约束。
例如以下文件名:
dns_windows.go
:编译windows包时才会本文件
math_386.s
:编译包目标是32-bit x86时包含
这样的好处就是,当同一个方法在不通操作系统下实现是不一样的时候,可以用相同的函数名称分别实现,编译的时候根据目标系统类型编译对应系统的源文件:
// test_windows.go
package pkg
import "log"
func PrintOS() {
log.Println("windows")
}
// test_linux.go
package pkg
import "log"
func PrintOS() {
log.Println("linux")
}
//main.go
package main
import (
"test/pkg"
)
func main() {
pkg.PrintOS()
}
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK