什么是构建约束
构建约束也称之为条件编译,就是可以对某些源代码文件指定在特定的平台,架构,编译器甚至Go
版本下面进行编译,在其他环境中会自动忽略这些文件
为什么需要构建约束呢
go
是支持交叉编译的,也就是说,可以在linux
平台编译生成windows
下的可执行程序的;但是,有些API
在不同的平台和架构中是不一样的,比如:
syscall.NewLazyDLL("test.dll")
加载dll
的程序在Linux
平台中就没有,所以当你写程序时就需要指定包含这个API
的文件只能在Windows
下面编译,在其他平台自动忽略,这样就不会代码移植到别的平台出现编译时错误了
golang
支持的两种构建约束
-
使用文件后缀进行约束
这种方式就是通过文件的后缀名来对要指定平台的编译的文件进行约束,文件格式如下:
sourcefilename_GOOS_GOARCH.go
上面的格式就是
文件名_系统名_架构名.go
,GOOS
和GOARCH
可以通过go env
看到,也可以在环境变量中指定;下面举个例子:user_windows_amd64.go //在 windows 中 amd64 架构下才会编译,其他的环境中会自动忽略 user_linux_arm.go // 在 linux 中的 arm 架构下才会编译,其他环境中会自动忽略
-
通过代码文件中添加注释进行约束
该方式就是通过在代码文件中的第一行添加注释来标明该文件是否参与该上下文环境的编译,比如:
// +build linux,amd64 package user func User(){}
注释编译首先就是在文件头部添加注释
// +build
然后后面添加编译条件,该注释要和下面的代码空一行,否则就会被作为普通的注释对待;当然,也可以使用如下的注释//go:build linux,amd64
这两种注释的区别在于前者可以存在多个,比如:
// +build linux // +build amd64
它们两个之间是“与”的关系,即
linux && amd64
;而//go:build
这种注释在同一个文件当中只能存在一行注释支持五种已有的标签,有:
- 操作系统,环境变量中GOOS的值,如:linux、darwin、windows等等
- 操作系统的架构,环境变量中GOARCH的值,如:arch64、x86、i386等等
- 使用的编译器,如:gc或者gccgo,是否开启CGO,cgo
golang
版本号,如:Go Version 1.5
,Go Version 1.13
,以此类推- 自定义标签,这种标签就需要在编译时指定,如:通过
go build -tags
自定义tag名称 指定tag值 // +build ignore
,编译时自动忽略该文件
标签之间有如下几种运算关系:
空格表示:AND 逗号表示:OR !表示:NOT 换行表示:AND
比如:
// +build linux,386 darwin,!cgo 运算表达式为:(linux && 386) || (darwin && !cgo)