英文:
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:build
comment 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 fmt
on a source file with a// +build
directive will automatically add the matching//go:build
one. -
running
go fmt
on a source file with a//go:build
directive 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论