go,gcc: Support external go compilers for Go bootstrap (#27769)
For ARM64, fallback to gccgo. (go-bootstrap@1.4 can't support ARM64)
This commit is contained in:
		@@ -27,7 +27,8 @@ packages:
 | 
				
			|||||||
      fuse: [libfuse]
 | 
					      fuse: [libfuse]
 | 
				
			||||||
      gl: [glx, osmesa]
 | 
					      gl: [glx, osmesa]
 | 
				
			||||||
      glu: [mesa-glu, openglu]
 | 
					      glu: [mesa-glu, openglu]
 | 
				
			||||||
      golang: [gcc]
 | 
					      golang: [go, gcc]
 | 
				
			||||||
 | 
					      go-external-or-gccgo-bootstrap: [go-bootstrap, gcc]
 | 
				
			||||||
      iconv: [libiconv]
 | 
					      iconv: [libiconv]
 | 
				
			||||||
      ipp: [intel-ipp]
 | 
					      ipp: [intel-ipp]
 | 
				
			||||||
      java: [openjdk, jdk, ibm-java]
 | 
					      java: [openjdk, jdk, ibm-java]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -206,9 +206,24 @@ class Gcc(AutotoolsPackage, GNUMirrorPackage):
 | 
				
			|||||||
        provides("golang@:1.4", when="@5:")
 | 
					        provides("golang@:1.4", when="@5:")
 | 
				
			||||||
        provides("golang@:1.6.1", when="@6:")
 | 
					        provides("golang@:1.6.1", when="@6:")
 | 
				
			||||||
        provides("golang@:1.8", when="@7:")
 | 
					        provides("golang@:1.8", when="@7:")
 | 
				
			||||||
 | 
					        provides("golang@:1.10", when="@8:")
 | 
				
			||||||
 | 
					        provides("golang@:1.12", when="@9:")
 | 
				
			||||||
 | 
					        provides("golang@:1.14", when="@10:")
 | 
				
			||||||
 | 
					        provides("golang@:1.16", when="@11:")
 | 
				
			||||||
 | 
					        provides("golang@:1.18", when="@11:")
 | 
				
			||||||
        # GCC 4.6 added support for the Go programming language.
 | 
					        # GCC 4.6 added support for the Go programming language.
 | 
				
			||||||
        # See https://gcc.gnu.org/gcc-4.6/changes.html
 | 
					        # See https://gcc.gnu.org/gcc-4.6/changes.html
 | 
				
			||||||
        conflicts("@:4.5", msg="support for Go has been added in GCC 4.6")
 | 
					        conflicts("@:4.5", msg="support for Go has been added in GCC 4.6")
 | 
				
			||||||
 | 
					        # aarch64 machines (including Macs with Apple silicon) can't use
 | 
				
			||||||
 | 
					        # go-bootstrap because it pre-dates aarch64 support in Go. When not
 | 
				
			||||||
 | 
					        # using an external go bootstrap go, These machines have to rely on
 | 
				
			||||||
 | 
					        # Go support in gcc (which may require compiling a version of gcc
 | 
				
			||||||
 | 
					        # with Go support just to satisfy this requirement).  However,
 | 
				
			||||||
 | 
					        # there's also a bug in some versions of GCC's Go front-end that prevents
 | 
				
			||||||
 | 
					        # these versions from properly bootstrapping Go.  (See issue #47771
 | 
				
			||||||
 | 
					        # https://github.com/golang/go/issues/47771 )  On the 10.x branch, we need
 | 
				
			||||||
 | 
					        # at least 10.4.  On the 11.x branch, we need at least 11.3:
 | 
				
			||||||
 | 
					        provides("go-external-or-gccgo-bootstrap", when="gcc@10.4.0:10,11.3.0:target=aarch64:")
 | 
				
			||||||
        # Go is not supported on macOS
 | 
					        # Go is not supported on macOS
 | 
				
			||||||
        conflicts("platform=darwin", msg="Go not supported on MacOS")
 | 
					        conflicts("platform=darwin", msg="Go not supported on MacOS")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -442,7 +457,7 @@ class Gcc(AutotoolsPackage, GNUMirrorPackage):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @classproperty
 | 
					    @classproperty
 | 
				
			||||||
    def executables(cls):
 | 
					    def executables(cls):
 | 
				
			||||||
        names = [r"gcc", r"[^\w]?g\+\+", r"gfortran", r"gdc"]
 | 
					        names = [r"gcc", r"[^\w]?g\+\+", r"gfortran", r"gdc", r"gccgo"]
 | 
				
			||||||
        suffixes = [r"", r"-mp-\d+\.\d", r"-\d+\.\d", r"-\d+", r"\d\d"]
 | 
					        suffixes = [r"", r"-mp-\d+\.\d", r"-\d+\.\d", r"-\d+", r"\d\d"]
 | 
				
			||||||
        return [r"".join(x) for x in itertools.product(names, suffixes)]
 | 
					        return [r"".join(x) for x in itertools.product(names, suffixes)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -520,6 +535,9 @@ def determine_variants(cls, exes, version_str):
 | 
				
			|||||||
            elif "gcc" in basename:
 | 
					            elif "gcc" in basename:
 | 
				
			||||||
                languages.add("c")
 | 
					                languages.add("c")
 | 
				
			||||||
                compilers["c"] = exe
 | 
					                compilers["c"] = exe
 | 
				
			||||||
 | 
					            elif "gccgo" in basename:
 | 
				
			||||||
 | 
					                languages.add("go")
 | 
				
			||||||
 | 
					                compilers["go"] = exe
 | 
				
			||||||
            elif "gdc" in basename:
 | 
					            elif "gdc" in basename:
 | 
				
			||||||
                languages.add("d")
 | 
					                languages.add("d")
 | 
				
			||||||
                compilers["d"] = exe
 | 
					                compilers["d"] = exe
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,8 @@
 | 
				
			|||||||
#
 | 
					#
 | 
				
			||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
 | 
					# SPDX-License-Identifier: (Apache-2.0 OR MIT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from spack.package import *
 | 
					from spack.package import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# THIS PACKAGE SHOULD NOT EXIST
 | 
					# THIS PACKAGE SHOULD NOT EXIST
 | 
				
			||||||
@@ -47,6 +49,25 @@ class GoBootstrap(Package):
 | 
				
			|||||||
    conflicts("os=monterey", msg="go-bootstrap won't build on new macOS")
 | 
					    conflicts("os=monterey", msg="go-bootstrap won't build on new macOS")
 | 
				
			||||||
    conflicts("target=aarch64:", msg="Go bootstrap doesn't support aarch64 architectures")
 | 
					    conflicts("target=aarch64:", msg="Go bootstrap doesn't support aarch64 architectures")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # This virtual package allows a fallback to gccgo for aarch64,
 | 
				
			||||||
 | 
					    # where go-bootstrap cannot be built(aarch64 was added with Go 1.5)
 | 
				
			||||||
 | 
					    provides("go-external-or-gccgo-bootstrap")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Support for aarch64 was added in Go 1.5, use an external package or gccgo instead:
 | 
				
			||||||
 | 
					    conflicts("@:1.4", when="target=aarch64:")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    executables = ["^go$"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # When the user adds a go compiler using ``spack external find go-bootstrap``,
 | 
				
			||||||
 | 
					    # this lets us get the version for packages.yaml. Then, the solver can avoid
 | 
				
			||||||
 | 
					    # to build the bootstrap go compiler(for aarch64, it's only gccgo) from source:
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def determine_version(cls, exe):
 | 
				
			||||||
 | 
					        """Return the version of an externally provided go executable or ``None``"""
 | 
				
			||||||
 | 
					        output = Executable(exe)("version", output=str, error=str)
 | 
				
			||||||
 | 
					        match = re.search(r"go version go(\S+)", output)
 | 
				
			||||||
 | 
					        return match.group(1) if match else None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def patch(self):
 | 
					    def patch(self):
 | 
				
			||||||
        if self.spec.satisfies("@:1.4.3"):
 | 
					        if self.spec.satisfies("@:1.4.3"):
 | 
				
			||||||
            # NOTE: Older versions of Go attempt to download external files that have
 | 
					            # NOTE: Older versions of Go attempt to download external files that have
 | 
				
			||||||
@@ -72,7 +93,13 @@ def install(self, spec, prefix):
 | 
				
			|||||||
        install_tree(".", prefix)
 | 
					        install_tree(".", prefix)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setup_dependent_build_environment(self, env, dependent_spec):
 | 
					    def setup_dependent_build_environment(self, env, dependent_spec):
 | 
				
			||||||
        env.set("GOROOT_BOOTSTRAP", self.spec.prefix)
 | 
					        """Set GOROOT_BOOTSTRAP: When using an external compiler, get its GOROOT env"""
 | 
				
			||||||
 | 
					        if self.spec.external:
 | 
				
			||||||
 | 
					            # Use the go compiler added by ``spack external find go-bootstrap``:
 | 
				
			||||||
 | 
					            goroot = Executable(self.spec.prefix.bin.go)("env", "GOROOT", output=str)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            goroot = self.spec.prefix
 | 
				
			||||||
 | 
					        env.set("GOROOT_BOOTSTRAP", goroot)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setup_build_environment(self, env):
 | 
					    def setup_build_environment(self, env):
 | 
				
			||||||
        env.set("GOROOT_FINAL", self.spec.prefix)
 | 
					        env.set("GOROOT_FINAL", self.spec.prefix)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -152,14 +152,13 @@ class Go(Package):
 | 
				
			|||||||
    # aarch64 machines (including Macs with Apple silicon) can't use
 | 
					    # aarch64 machines (including Macs with Apple silicon) can't use
 | 
				
			||||||
    # go-bootstrap because it pre-dates aarch64 support in Go.  These machines
 | 
					    # go-bootstrap because it pre-dates aarch64 support in Go.  These machines
 | 
				
			||||||
    # have to rely on Go support in gcc (which may require compiling a version
 | 
					    # have to rely on Go support in gcc (which may require compiling a version
 | 
				
			||||||
    # of gcc with Go support just to satisfy this requirement).  However,
 | 
					    # of gcc with Go support just to satisfy this requirement) or external go:
 | 
				
			||||||
    # there's also a bug in some versions of GCC's Go front-end that prevents
 | 
					 | 
				
			||||||
    # these versions from properly bootstrapping Go.  (See issue #47771
 | 
					 | 
				
			||||||
    # https://github.com/golang/go/issues/47771 )  On the 10.x branch, we need
 | 
					 | 
				
			||||||
    # at least 10.4.  On the 11.x branch, we need at least 11.3.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if platform.machine() == "aarch64":
 | 
					    # #27769: On M1/MacOS, platform.machine() may return arm64:
 | 
				
			||||||
        depends_on("gcc@10.4.0:10,11.3.0: languages=go", type="build")
 | 
					    if platform.machine() in ["arm64", "aarch64"]:
 | 
				
			||||||
 | 
					        # Use an external go compiler from packages.yaml/`spack external find go-bootstrap`,
 | 
				
			||||||
 | 
					        # but fallback to build go-bootstrap@1.4 or to gcc with languages=go (for aarch64):
 | 
				
			||||||
 | 
					        depends_on("go-external-or-gccgo-bootstrap", type="build")
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        depends_on("go-bootstrap", type="build")
 | 
					        depends_on("go-bootstrap", type="build")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user