Golang 条件编译

58

我在Go 1中遇到了条件编译的问题。

这是我的测试代码。关于“// +build”约束和“-tags”标志,我是否有什么误解?

main1.go

// +build main1
package main

import (
    "fmt"
)

func main() {
    fmt.Println("This is main 1")
}

main2.go

// +build main2
package main

import (
    "fmt"
)

func main() {
    fmt.Println("This is main 2")
}

在运行 "go build" 时,我仍然遇到编译错误

$ go build -tags 'main1'
# test
./main2.go:8: main redeclared in this block
        previous declaration at ./main1.go:8
5个回答

81

你必须在// +build XXX和下一行之间空一行。

在我的简短搜索中,我没有找到这是否有文档记录。但是源代码明确指出了这一点。


7
在http://golang.org/pkg/go/build/#hdr-Build_Constraints中有记录。具体来说:“为了区分构建约束和包文档,一系列构建约束必须在一个空行之后。” - chowey

19

// +build 标签,在 Go 1.17 及以下版本中使用时,必须在后面加一个空行:

// +build main1

package main

从Go 1.17开始,条件构建标签能够使用支持布尔表达式的//go:build行,而不是旧的// +build行。

主要改进

  • //go:build注释格式与其他go指令一致,如//go:embed//go:generate//go:noinline等。
  • 在构建标签之间使用布尔表达式的语法现在已经标准化,使用&&||操作符。

语法比较

表达式// +build//go:build
OR// +build foo bar(以空格分隔)//go:build foo || bar
AND// +build foo,bar//go:build foo && bar
NOT(未改变)// +build !foo//go:build !foo

多行注释

更复杂的布尔表达式可以使用括号,而以前需要多行注释:

从:

// +build foo bar
// +build 386

至:

//go:build (foo || bar) && 386
此外,使用//go:build,现在不允许多个跨越多行的指令。
自动格式化: - 对于带有// +build指令的源文件运行go fmt将自动添加匹配的//go:build。 - 在错误的位置带有//go:build指令的源文件上运行go fmt将自动修复。因此,只需运行gofmt -w main.go即可解决问题。
来源:Go 1.17构建约束草案设计。(即使Go 1.17已正式发布,此文档仍为草案)

14

构建包

构建约束

构建约束是以指令+build开始的行注释,用于列出应在包中包含文件的条件。约束可以出现在任何类型的源文件(不限于Go),但必须出现在文件顶部附近,之前只能有空行和其他行注释。

为了区分构建约束和包文档,一系列构建约束后必须加一个空行。

在构建约束后添加一个空行。例如:

// +build main1

package main

import (
    "fmt"
)

func main() {
    fmt.Println("This is main 1")
}

11

在使用 // +build XXX 标记时,必须留出一行空白。不是紧接着 // +build XXX,而是在 package main 声明之前留出空行。因为在宣告 package 的那一行之前的所有注释都被认为是 package 的描述,并由 godoc 解析。


4

来自构建约束文档:

为了区分构建约束和包文档,一系列构建约束必须紧跟着一个空行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接