-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Description
Using an x/sys version that is too old for a Go version may result in build errors, and that has clearly confused at least hundreds of Go users in the past year or so:
- https://stackoverflow.com/questions/71507321/go-1-18-build-error-on-mac-unix-syscall-darwin-1-13-go253-golinkname-mus
- go:linkname must refer to declared function or variable #51706
Given that x/sys uses //go:linkname directives into unexported Go APIs, it is fairly tightly bound to a set of Go versions. If the Go version is too old or too new, it's entirely possible that the build may fail like the example above on GOOS=darwin.
If the x/sys version is too old, the solution is pretty easy: go get golang.org/x/sys to update the dependency. That is not obvious given the error message, though. And I bet that a good number of those end users are only indirectly depending on x/sys, so they might not even know what the library does or why it's being built.
Similarly, if one tries to use a recent version of x/sys with an ancient version of Go, I imagine the build may also fail in weird and confusing ways, though this side of the coin doesn't seem to be as common of a problem.
I think we should try to make these errors more intuitive. As a strawman idea, I suggest that we force the current master version of x/sys to fail to build on Go 1.17 and older, as well as Go 1.21 and newer, via build tags such as:
$ cat go_older.go
//go:build !go1.18
// +build !go1.18
"this version of golang.org/x/sys supports Go 1.18 and Go 1.19; upgrade your Go version or, if you cannot, downgrade x/sys"
$ cat go_newer.go
//go:build go1.21
"this version of golang.org/x/sys supports Go 1.18 and Go 1.19; upgrade x/sys via: go get golang.org/x/sys"
The string literals would cause a parse error which would show the string to the user, as a way of customizing the error message:
$ go1.16.15 build go_older.go
go_older.go:4:1: expected 'package', found "this version of golang.org/x/sys supports Go 1.18 and Go 1.19; upgrade your Go version or, if you cannot, downgrade x/sys"
We would not error on Go 1.20, as that is the current tip/master version, and we are continuously supporting and testing it. Erroring on Go 1.21 today is perhaps unnecessary, but it's the only way to prepare the current master versions for a future when Go 1.21 is widely used and may not work with today's versions of x/sys. When Go 1.20 is released and we start working towards 1.21, the build tags in x/sys master would be advanced by one version.
A potential alternative would be a toolchain line in go.mod, per #55092. However, that might only allow us to set a minimum Go toolchain version, and presumably not a maximum. It's also not yet implemented, nor is it understood by older Go versions. We definitely want our solution to make Go 1.16 fail to build the latest x/sys master version, for example.
cc @golang/runtime @ianlancetaylor @bradfitz @tklauser per https://dev.golang.org/owners