Golang条件编译

huangapple go评论84阅读模式
英文:

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 &amp;&amp; and || operators

Syntax comparison

Expression // +build //go:build
OR // +build foo bar (space-separated) `//go:build foo
AND // +build foo,bar //go:build foo &amp;&amp; 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) &amp;&amp; 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 running gofmt -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 (
    &quot;fmt&quot;
)

func main() {
    fmt.Println(&quot;This is main 1&quot;)
}

答案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.

huangapple
  • 本文由 发表于 2012年5月18日 12:02:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/10646531.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定