Reputation: 961
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
Upvotes: 58
Views: 31543
Reputation: 44587
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.
//go:build
comment format is consistent with other go directives as //go:embed
, //go:generate
, //go:noinline
, etc.&&
and ||
operatorsExpression | // +build |
//go:build |
---|---|---|
OR | // +build foo bar (space-separated) |
//go:build foo || bar |
AND | // +build foo,bar |
//go:build foo && bar |
NOT (unchanged) | // +build !foo |
//go:build !foo |
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.
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
Source: Go 1.17 build constraints draft design. (Currently still a draft even if Go 1.17 is officially released)
Upvotes: 22
Reputation: 49
From the Build Constraints docs:
To distinguish build constraints from package documentation, a series of build constraints must be followed by a blank line.
Upvotes: 4
Reputation: 166529
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")
}
Upvotes: 14
Reputation: 7083
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
Upvotes: 82
Reputation: 119
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
.
Upvotes: 11