英文:
Golang conditional compilation
问题
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
英文:
I've got a trouble with conditional compilation in Go 1.
Here is my test code. Is there anything I misunderstand about the "// +build" constraint and the "-tags" flag?
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")
}
when running "go build", I still got compile error
$ go build -tags 'main1'
# test
./main2.go:8: main redeclared in this block
previous declaration at ./main1.go:8
答案1
得分: 80
你必须在// +build XXX后面加上一个空行。
在我简短的搜索中,我找不到这个是否有文档记录。但是源代码明确指出了这一点。
英文:
You must follow // +build XXX with a blank line.
In my brief search, I couldn't find where/if this is documented. But the source clearly calls it out
答案2
得分: 17
// +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 |
|---|---|---|
| 或 | // +build foo bar(以空格分隔) |
`//go:build foo |
| 与 | // +build foo,bar |
//go:build foo && bar |
| 非(不变) | // +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即可解决您的问题。
<hr>
来源:Go 1.17构建约束草案设计。(目前仍然是草案,即使Go 1.17已正式发布)
英文:
The // +build tag, used up to Go 1.17, must be followed by an empty line:
// +build main1
package main
Starting from Go 1.17, conditional build tags are able to use //go:build lines that support boolean expressions instead of the old // +build lines.
Main improvement
//go:buildcomment format is consistent with other go directives as//go:embed,//go:generate,//go:noinline, etc.- the syntax for boolean expressions between build tags is now standardized, using
&&and||operators
Syntax comparison
| Expression | // +build |
//go:build |
|---|---|---|
| OR | // +build foo bar (space-separated) |
`//go:build foo |
| AND | // +build foo,bar |
//go:build foo && bar |
| NOT (unchanged) | // +build !foo |
//go:build !foo |
Multiline comments
More complex boolean expressions can make use of parenthesis, whereas before it required multiline comments:
From:
// +build foo bar
// +build 386
to:
//go:build (foo || bar) && 386
Additionally, with //go:build, multiple directives over more than one line are now disallowed.
Automatic formatting
-
running
go fmton a source file with a// +builddirective will automatically add the matching//go:buildone. -
running
go fmton a source file with a//go:builddirective in the wrong place will automatically fix it. So now your issue would be solved by simply runninggofmt -w main.go
<hr>
Source: Go 1.17 build constraints draft design. (Currently still a draft even if Go 1.17 is officially released)
答案3
得分: 14
> 构建约束
>
> 构建约束
>
> 构建约束是以指令+build开头的行注释,用于列出文件应该包含在包中的条件。约束可以出现在任何类型的源文件中(不仅仅是Go),但它们必须出现在文件的顶部附近,只能由空行和其他行注释前导。
>
> 为了区分构建约束和包文档,一系列构建约束后必须有一个空行。
在构建约束后添加一个空行。例如:
// +build main1
package main
import (
"fmt"
)
func main() {
fmt.Println("This is main 1")
}
英文:
> Package build
>
> Build Constraints
>
> A build constraint is a line comment beginning with the directive
> +build that lists the conditions under which a file should be
> included in the package. Constraints may appear in any kind of source
> file (not just Go), but they must appear near the top of the file,
> preceded only by blank lines and other line comments.
>
> To distinguish build constraints from package documentation, a series
> of build constraints must be followed by a blank line.
Add a blank line after the build constraint. For example,
// +build main1
package main
import (
"fmt"
)
func main() {
fmt.Println("This is main 1")
}
答案4
得分: 11
对的,你必须留下一个空行,不是紧跟在// +build XXX之后,而是在package main之前,因为在声明包的那一行之前的所有注释行都被视为包的描述,并由godoc解析。
英文:
Right, you must leave a blank line, not exactly after // +build XXX but before package main because all the comment lines before the line declaring the package are considered to be the description of the package and parsed by godoc.
答案5
得分: 4
从构建约束文档中:
> 为了区分构建约束和包文档,一系列的构建约束必须在一个空行之后。
英文:
From the Build Constraints docs:
> To distinguish build constraints from package documentation, a series of build constraints must be followed by a blank line.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论