summaryrefslogtreecommitdiff
path: root/var/spack/repos/builtin/packages/go-bootstrap/package.py
blob: 809926f4c17c5380802b14b93f4b0c6fd0428033 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

import platform
import re

from spack.package import *

# THIS PACKAGE SHOULD NOT EXIST
# it exists to make up for the inability to:
# * use an external go compiler
# * have go depend on itself
# * have a sensible way to find gccgo without a dep on gcc


class GoBootstrap(Package):
    """Old C-bootstrapped go to bootstrap real go"""

    homepage = "https://golang.org"
    url = "https://go.dev/dl/go1.20.1.darwin-amd64.tar.gz"

    extendable = True

    maintainers("alecbcs")

    depends_on("git", type=("build", "link", "run"))

    executables = ["^go$"]

    # List binary go releases for multiple operating systems and architectures.
    # These binary versions are not intended to stay up-to-date. Instead we
    # should update these binary releases on a yearly schedule as
    # bootstrapping requirements are modified by new releases of go.
    go_releases = {
        "1.17.13": {
            "darwin": {
                "amd64": "c101beaa232e0f448fab692dc036cd6b4677091ff89c4889cc8754b1b29c6608",
                "arm64": "e4ccc9c082d91eaa0b866078b591fc97d24b91495f12deb3dd2d8eda4e55a6ea",
            },
            "linux": {
                "amd64": "4cdd2bc664724dc7db94ad51b503512c5ae7220951cac568120f64f8e94399fc",
                "arm64": "914daad3f011cc2014dea799bb7490442677e4ad6de0b2ac3ded6cee7e3f493d",
                "ppc64le": "bd0763fb130f8412672ffe1e4a8e65888ebe2419e5caa9a67ac21e8c298aa254",
            },
        }
    }

    # Normalize architectures returned by platform to those used by the
    # Go project.
    go_targets = {
        "aarch64": "arm64",
        "arm64": "arm64",
        "ppc64le": "ppc64le",
        "amd64": "amd64",
        "x86_64": "amd64",
    }

    # determine system os and architecture/target
    os = platform.system().lower()
    target = go_targets.get(platform.machine().lower(), platform.machine().lower())

    license("BSD-3-Clause")

    # construct releases for current system configuration
    for release in go_releases:
        if os in go_releases[release] and target in go_releases[release][os]:
            version(release, sha256=go_releases[release][os][target])
            provides(f"go-or-gccgo-bootstrap@{release}", when=f"@{release}")

    # 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 url_for_version(self, version):
        # allow maintainers to checksum multiple architectures via
        # `spack checksum go-bootstrap@1.18.9-darwin-arm64`
        match = re.search(r"(\S+)-(\S+)-(\S+)", str(version))
        if match:
            version = match.group(1)
            os = match.group(2)
            target = match.group(3)
        else:
            os = self.os
            target = self.target

        url = "https://go.dev/dl/go{0}.{1}-{2}.tar.gz"
        return url.format(version, os, target)

    def install(self, spec, prefix):
        install_tree(".", prefix)

    def setup_dependent_build_environment(self, env, dependent_spec):
        """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)