语言交叉编译和构建标签

Go 构建标签 #

Go 的构建约束,即构建标签,是以// go:build为开始的行注释,如果是 1.16 或之前的版本,格式是// +build。跟此变更相关的 issue 可以参考25348

构建标签由||, &&, !运算符以及括号来组合表达。运算符与 Go 中的含义相同。

例如,以下构建标签在满足linux386约束,或者满足darwincgo不满足时构建文件:

//go:build (linux && 386) || (darwin && !cgo

又如:仅在使用 cgo 时,且仅在 Linux 和 OS X 上构建文件:

//go:build cgo && (linux || darwin)

注意:1.17 及以后的表达格式里,一个文件有多个 //go:build 行是错误的。

在 1.16 及以前的版本,多行构建标签是允许的,并且组合方式是通过空格和逗号等来区分,空格符表示 OR,逗号表示 AND,感叹号表示 NOT。而多行之间则表示 OR。gofmt 命令将在遇到旧语法时添加等效的 //go:build 约束。如下是示例

标签 约束含义
// +build linux,386 darwin,!cgo (linux AND 386) OR (darwin AND (NOT cgo))
// +build linux darwin // +build amd64 (linux OR darwin) AND amd64

如果文件名在去除扩展名和可能的_test后缀后匹配以下任何模式,

例如:source_windows_amd64.go 其中 GOOS 和 GOARCH 分别代表任何已知的操作系统和体系结构值,那么认为该文件除了文件中的任何显式约束之外,具有这些术语的所表达的隐式构建标签。

示例1 #

istest_windows.go (windows操作系统)

// +build windows

package main

import (
   "fmt"
   "runtime"
)

func isTest()  {
   fmt.Println("is window function",runtime.GOOS)
}

istest.go (非windows操作系统)

// +build !windows

package main

import (
	"fmt"
	"runtime"
)
func isTest()  {
	fmt.Println("is other os system function",runtime.GOOS)
}

main.go

package main

import "fmt"

func main() {
	isTest()
}

编译windows系统

go build -o hello.exe
./hello.exe

输出为
is window function windows

编译linux操作系统

env GO111MODULE=on CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o hello
./hello

输出为
is other os system function linux

示例2 #

增加版本控制

测试版本构建 dev_version.go

// +build dev

package main

var version = "dev"

生产版本构建 prod_version.go

// +build prod

package main

var version = "prod"

主文件

package main

import "fmt"

func main() {
	fmt.Println("current version is ",version)
}

构建命令

go build -tags dev -o dev.exe
go build -tags prod -o prod.exe

会生成dev.exe和prod.exe分别用于生产和测试环境的发布文件

./dev.exe
current version is dev

./prod.exe
current version is prod

示例3 #

通过链接器修改变量

package main

import "fmt"

var (
	Version string
	Mode string
)
func main() {
	fmt.Printf("version is %s\n", Version)
	fmt.Printf("mode is %s", Mode)

}

编译操作

go build -ldflags="-X main.Version=dev -X main.Mode=debug"   -o hello.exe

执行hello.exe

version is dev
mode is debug