github.com/gopherjs/gopherjs@v1.19.0-beta1.0.20240506212314-27071a8796e4/build/versionhack/versionhack.go (about)

     1  // Package versionhack makes sure go/build doesn't disable module support
     2  // whenever GopherJS is compiled by a different Go version than it's targeted
     3  // Go version.
     4  //
     5  // Under the hood, go/build relies on `go list` utility for module support; more
     6  // specifically, for package location discovery. Since ReleaseTags are
     7  // effectively baked into the go binary and can't be overridden, it needs to
     8  // ensure that ReleaseTags set in a go/build.Context instance match the Go tool.
     9  //
    10  // However, it naively assumes that the go tool version in the PATH matches the
    11  // version that was used to build GopherJS and disables module support whenever
    12  // ReleaseTags in the context are set to anything other than the default. This,
    13  // unfortunately, isn't very helpful since gopherjs may be built by a Go version
    14  // other than the PATH's default.
    15  //
    16  // Luckily, even if go tool version is mismatched, it's only used for discovery
    17  // of the package locations, and go/build evaluates build constraints on its own
    18  // with ReleaseTags we've passed.
    19  //
    20  // A better solution would've been for go/build to use go tool from GOROOT and
    21  // check its version against build tags: https://github.com/golang/go/issues/46856.
    22  //
    23  // Until that issue is fixed, we trick go/build into thinking that whatever
    24  // ReleaseTags we've passed are indeed the default. We gain access to the
    25  // variable go/build checks against using "go:linkname" directive and override
    26  // its content as we wish.
    27  package versionhack
    28  
    29  import (
    30  	"go/build" // Must be initialized before this package.
    31  
    32  	"github.com/gopherjs/gopherjs/compiler"
    33  
    34  	_ "unsafe" // For go:linkname
    35  )
    36  
    37  //go:linkname releaseTags go/build.defaultReleaseTags
    38  var releaseTags []string
    39  
    40  //go:linkname toolTags go/build.defaultToolTags
    41  var toolTags []string
    42  
    43  func init() {
    44  	releaseTags = build.Default.ReleaseTags[:compiler.GoVersion]
    45  	toolTags = []string{}
    46  	build.Default.ToolTags = []string{}
    47  }