Skip to content
Go
构建标签与条件编译

构建标签与条件编译

构建标签允许根据平台、Go 版本或自定义条件选择性编译文件


1. 语法(两种格式)

旧格式(// +build,Go < 1.17)

// +build linux,amd64
// +build !windows

package mypackage

注意:+buildpackage 之间必须有空行,用 , 表示 AND,多行表示 OR。

新格式(//go:build,Go 1.17+,推荐

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

package mypackage

新格式使用布尔表达式,更易读:

  • && — AND
  • || — OR
  • ! — NOT

💡 最佳实践:Go 1.17+ 使用 //go:build 格式,旧格式的 // +build 会逐步淘汰。


2. 常用预定义标签

操作系统

//go:build linux
//go:build windows
//go:build darwin

架构

//go:build amd64
//go:build arm64
//go:build 386

其他

//go:build cgo        // 需要 cgo 时编译
//go:build !cgo       // 不需要 cgo 时编译(纯 Go)
//go:build race       // go test -race 时编译
//go:build go1.21     // Go 版本 >= 1.21

文件名约定(自动标签)

// 不需要写 build tag,文件名已隐含
file_linux.go     // 只在 Linux 编译
file_windows.go   // 只在 Windows 编译
file_amd64.go     // 只在 amd64 编译
file_linux_amd64.go // Linux + amd64

3. 自定义标签

go build -tags debug
go test -tags "integration,debug"
//go:build debug

package main

func DebugLog(msg string) {
    fmt.Println("[DEBUG]", msg)
}
// 无标签的文件(生产版本)
package main

func DebugLog(msg string) {
    // 不输出
}

4. 实战应用

平台特定实现

// file_linux.go
//go:build linux

package platform

const Newline = "\n"

// file_windows.go
//go:build windows

package platform

const Newline = "\r\n"

测试辅助代码

// helpers_test.go
//go:build !race

package mypackage_test

// 只在非 race 模式下可用的测试

版本差异

// version_go1_20.go
//go:build go1.20

package mypackage

import "errors"

var ErrJoin = errors.Join

5. 🚨 常见陷阱

陷阱 说明
// +build 与 package 之间没有空行 编译时被当作普通注释
build tag 中 ! 的位置 //go:build !windows 正确;// +build !windows 正确
两个格式混用时不一致 go vet 会检查
文件名标签和 build tag 冲突 文件不会编译