for example, https://github.com/golang/sys/blob/master/cpu/cpu_gccgo_x86.go#L5 :
//go:build (386 || amd64 || amd64p32) && gccgo
// +build 386 amd64 amd64p32
// +build gccgo
package cpu
In my eyes, as a build tag, // +build ... can work well.
Why is //go:build still explicitly specified?
Btw, it is hard to find the mannual of //go:build, but // +build is easy(https://pkg.go.dev/cmd/go#hdr-Build_constraints)
gobuild is an automatic build tool that aims to replace Makefiles for simple projects written in the Go programming language. It creates a dependency graph of all local imports and compiles them in the right order using the gc Go compiler.
go build builds the command and leaves the result in the current working directory. go install builds the command in a temporary directory then moves it to $GOPATH/bin .
Additionally, other commands, such as go build or go test, will add new dependencies automatically based on the stipulated requirements. For example, as earlier illustrated, they can do this to satisfy import requirements, including upgrading go. mod file and installing the new dependencies.
go run is just a shortcut for compiling then running in a single step. While it is useful for development you should generally build it and run the binary directly when using it in production. There must be more to it than that - if I time the println in a helloworld, it runs faster with go run than compiled.
Before go run vs go build, let’s take a look at both the commands individually. The go build command-line tool takes a .go file and generates an executable file for windows and binary files for Linux. Note:- Go build tool will only make an executable or binary file if the .go file contains the main package and main function in it.
It was introduced in Go 1.17. It is meant to replace the old // +build directives; the use case is still same: it "lists the conditions under which a file should be included in the package". The new syntax brings a few key improvements:
The go build command-line tool takes a .go file and generates an executable file for windows and binary files for Linux. Note:- Go build tool will only make an executable or binary file if the .go file contains the main package and main function in it.
Note:- Go build tool will only make an executable or binary file if the .go file contains the main package and main function in it. The Program with the main package and main function is considered as a command and program without is considered as a package.
The new directive //go:build is now preferred and the toolchain will actively remove old directives; as mentioned in Go 1.18 release notes:
In Go 1.18,
go fixnow removes the now-obsolete// +buildlines in modules declaring go 1.18 or later in their go.mod files.
Due to the above, if you attempt to build a module with go.mod at 1.17 or lower that requires a dependency at 1.18 or above, the build may fail if the dependency is missing // +build lines.
//go:build is the new conditional compilation directive used to specify build constraints. It was introduced in Go 1.17.
It is meant to replace the old // +build directives; the use case is still same: it "lists the conditions under which a file should be included in the package". The new syntax brings a few key improvements:
//go:generate
//go:build foo && bar, whereas the old // +build comment has less intuitive syntax. For example AND was expressed with commas // +build foo,bar and OR with spaces // +build foo bar
go fmt, which will automatically fix incorrect placement of the directive in source files, thus avoiding common mistakes as not leaving a blank line between the directive and the package statement.The two build directives will coexist over a few Go releases in order to ensure a smooth transition, as outlined in the relevant proposal document (in the quote below N is 17, emphasis mine):
Go 1.N would start the transition. In Go 1.N:
Builds will start preferring
//go:buildlines for file selection. If there is no//go:buildin a file, then any// +buildlines still apply.Builds will no longer fail if a Go file contains
//go:buildwithout// +build.Builds will fail if a Go or assembly file contains
//go:buildtoo late in the file. Gofmt will move misplaced //go:build and // +build lines to their proper location in the file.
Gofmtwill format the expressions in//go:buildlines using the same rules as for other Go boolean expressions (spaces around all&&and||operators).If a file contains only
// +buildlines,gofmtwill add an equivalent//go:buildline above them.If a file contains both
//go:buildand// +buildlines,gofmtwill consider the//go:buildthe source of truth and update the// +buildlines to match, preserving compatibility with earlier versions of Go.Gofmtwill also reject//go:buildlines that are deemed too complex to convert into// +buildformat, although this situation will be rare. (Note the “If” at the start of this bullet.Gofmtwill not add// +buildlines to a file that only has//go:build.)The
buildtagscheck ingo vetwill add support for//go:buildconstraints. It will fail when a Go source file contains//go:buildand// +buildlines with different meanings. If the check fails, one can rungofmt -w.The
buildtagscheck will also fail when a Go source file contains//go:buildwithout// +buildand its containing module has a go line listing a version before Go 1.N. If the check fails, one can add any// +buildline and then rungofmt -w, which will replace it with the correct ones. Or one can bump thego.modgo version to Go 1.N.
More info about syntax changes: Golang conditional compilation
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With