
* GitHub Actions: do not install six in CI * Remove workflow code that was commented out * Remove any use of "six" from packages
406 lines
18 KiB
Python
406 lines
18 KiB
Python
# 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 re
|
|
|
|
from spack.package import *
|
|
|
|
|
|
class Rust(Package):
|
|
"""The Rust programming language toolchain
|
|
|
|
This package can bootstrap any version of the Rust compiler since Rust
|
|
1.23. It does this by downloading the platform-appropriate binary
|
|
distribution of the desired version of the rust compiler, and then building
|
|
that compiler from source.
|
|
"""
|
|
|
|
homepage = "https://www.rust-lang.org"
|
|
url = "https://static.rust-lang.org/dist/rustc-1.42.0-src.tar.gz"
|
|
git = "https://github.com/rust-lang/rust.git"
|
|
|
|
maintainers("AndrewGaspar")
|
|
|
|
phases = ["configure", "build", "install"]
|
|
|
|
extendable = True
|
|
|
|
variant("rustfmt", default=True, description="Formatting tool for Rust code")
|
|
|
|
variant(
|
|
"analysis",
|
|
default=True,
|
|
description="Outputs code analysis that can be consumed by other tools",
|
|
)
|
|
|
|
variant("clippy", default=True, description="Linting tool for Rust")
|
|
|
|
variant(
|
|
"rls",
|
|
default=False,
|
|
description="The Rust Language Server can be used for IDE integration",
|
|
)
|
|
|
|
variant("src", default=True, description="Install Rust source files")
|
|
variant(
|
|
"extra_targets",
|
|
default="none",
|
|
multi=True,
|
|
description="Triples for extra targets to enable. For supported targets, see: https://doc.rust-lang.org/nightly/rustc/platform-support.html",
|
|
)
|
|
|
|
depends_on("python@2.7:", type="build")
|
|
depends_on("gmake@3.81:", type="build")
|
|
depends_on("cmake@3.4.3:", type="build")
|
|
depends_on("ninja", when="@1.48.0:", type="build")
|
|
depends_on("pkgconfig", type="build")
|
|
# TODO: openssl@3.x should be supported in later versions
|
|
depends_on("openssl@:1")
|
|
# Cargo itself needs libcurl with nghttp2. If not found with pkg-config
|
|
# it will build vendored versions of libcurl, nghttp2, and openssl.
|
|
depends_on("curl+nghttp2")
|
|
depends_on("libssh2")
|
|
# https://github.com/rust-lang/cargo/issues/10446
|
|
depends_on("libgit2@:1.3", when="@0:1.60")
|
|
depends_on("libgit2")
|
|
|
|
# Pre-release Versions
|
|
version("master", branch="master", submodules=True)
|
|
|
|
# These version strings are officially supported, but aren't explicitly
|
|
# listed because there's no stable checksum for them.
|
|
version("nightly")
|
|
# version('beta')
|
|
|
|
# Version Notes:
|
|
# Here's some information on why your favorite Rust version may be missing.
|
|
#
|
|
# < 1.23:
|
|
# Rust seems to eagerly search for ar next to cc. Spack makes wrappers for
|
|
# cc and c++, but not for ar, so no ar is found. In future versions, ar
|
|
# can be specified in the config.
|
|
#
|
|
# < 1.17:
|
|
# The `x.py` bootstrapping script did not exist prior to Rust 1.17. It
|
|
# would be possible to support both, but for simplicitly, we only support
|
|
# Rust 1.17 and newer
|
|
version("1.65.0", sha256="5828bb67f677eabf8c384020582b0ce7af884e1c84389484f7f8d00dd82c0038")
|
|
version("1.60.0", sha256="20ca826d1cf674daf8e22c4f8c4b9743af07973211c839b85839742314c838b7")
|
|
version("1.58.1", sha256="a839afdd3625d6f3f3c4c10b79813675d1775c460d14be1feaf33a6c829c07c7")
|
|
version("1.51.0", sha256="7a6b9bafc8b3d81bbc566e7c0d1f17c9f499fd22b95142f7ea3a8e4d1f9eb847")
|
|
version("1.48.0", sha256="0e763e6db47d5d6f91583284d2f989eacc49b84794d1443355b85c58d67ae43b")
|
|
version("1.47.0", sha256="3185df064c4747f2c8b9bb8c4468edd58ff4ad6d07880c879ac1b173b768d81d")
|
|
version("1.46.0", sha256="2d6a3b7196db474ba3f37b8f5d50a1ecedff00738d7846840605b42bfc922728")
|
|
version("1.45.1", sha256="ea53e6424e3d1fe56c6d77a00e72c5d594b509ec920c5a779a7b8e1dbd74219b")
|
|
version("1.44.1", sha256="7e2e64cb298dd5d5aea52eafe943ba0458fa82f2987fdcda1ff6f537b6f88473")
|
|
version("1.44.0", sha256="bf2df62317e533e84167c5bc7d4351a99fdab1f9cd6e6ba09f51996ad8561100")
|
|
|
|
# The Rust bootstrapping process requires a bootstrapping compiler. The
|
|
# easiest way to do this is to download the binary distribution of the
|
|
# same version of the compiler and build with that.
|
|
#
|
|
# This dictionary contains a version: hash dictionary for each supported
|
|
# Rust target.
|
|
rust_releases = {
|
|
"1.65.0": {
|
|
"x86_64-unknown-linux-gnu": "8f754fdd5af783fe9020978c64e414cb45f3ad0a6f44d045219bbf2210ca3cb9",
|
|
"powerpc64le-unknown-linux-gnu": "3f1d0d5bb13213348dc65e373f8c412fc0a12ee55abc1c864f7e0300932fc687",
|
|
"aarch64-unknown-linux-gnu": "f406136010e6a1cdce3fb6573506f00d23858af49dd20a46723c3fa5257b7796",
|
|
"x86_64-apple-darwin": "139087a3937799415fd829e5a88162a69a32c23725a44457f9c96b98e4d64a7c",
|
|
"aarch64-apple-darwin": "7ddc335bd10fc32d3039ef36248a5d0c4865db2437c8aad20a2428a6cf41df09",
|
|
},
|
|
"1.60.0": {
|
|
"x86_64-unknown-linux-gnu": "b8a4c3959367d053825e31f90a5eb86418eb0d80cacda52bfa80b078e18150d5",
|
|
"powerpc64le-unknown-linux-gnu": "80125e90285b214c2b1f56ab86a09c8509aa17aec9d7127960a86a7008e8f7de",
|
|
"aarch64-unknown-linux-gnu": "99c419c2f35d4324446481c39402c7baecd7a8baed7edca9f8d6bbd33c05550c",
|
|
"x86_64-apple-darwin": "0b10dc45cddc4d2355e38cac86d71a504327cb41d41d702d4050b9847ad4258c",
|
|
"aarch64-apple-darwin": "b532672c278c25683ca63d78e82bae829eea1a32308e844954fb66cfe34ad222",
|
|
},
|
|
"1.58.1": {
|
|
"x86_64-unknown-linux-gnu": "4fac6df9ea49447682c333e57945bebf4f9f45ec7b08849e507a64b2ccd5f8fb",
|
|
"powerpc64le-unknown-linux-gnu": "b15baef702cbd6f0ea2bef7bf98ca7ce5644f2beb219028e8a12e7053da4c849",
|
|
"aarch64-unknown-linux-gnu": "ce557516593e4526709b0f33c2e1d7c932b3ddf76af94c2417d8d667921ce90c",
|
|
"x86_64-apple-darwin": "d0044680fc132a721481b130a0a4282a444867f423efdb890fe13e447966412f",
|
|
},
|
|
"1.51.0": {
|
|
"x86_64-unknown-linux-gnu": "9e125977aa13f012a68fdc6663629c685745091ae244f0587dd55ea4e3a3e42f",
|
|
"powerpc64le-unknown-linux-gnu": "7362f561104d7be4836507d3a53cd39444efcdf065813d559beb1f54ce9f7680",
|
|
"aarch64-unknown-linux-gnu": "fd31c78fffad52c03cac5a7c1ee5db3f34b2a77d7bc862707c0f71e209180a84",
|
|
"x86_64-apple-darwin": "765212098a415996b767d1e372ce266caf94027402b269fec33291fffc085ca4",
|
|
},
|
|
"1.48.0": {
|
|
"x86_64-unknown-linux-gnu": "950420a35b2dd9091f1b93a9ccd5abc026ca7112e667f246b1deb79204e2038b",
|
|
"powerpc64le-unknown-linux-gnu": "e6457a0214f3b1b04bd5b2618bba7e3826e254216420dede2971b571a1c13bb1",
|
|
"aarch64-unknown-linux-gnu": "c4769418d8d89f432e4a3a21ad60f99629e4b13bbfc29aef7d9d51c4e8ee8a8a",
|
|
"x86_64-apple-darwin": "f30ce0162b39dc7cf877020cec64d4826cad50467af493d180b5b28cf5eb50b3",
|
|
},
|
|
"1.47.0": {
|
|
"x86_64-unknown-linux-gnu": "d0e11e1756a072e8e246b05d54593402813d047d12e44df281fbabda91035d96",
|
|
"powerpc64le-unknown-linux-gnu": "5760c3b1897ea70791320c2565f3eef700a3d54059027b84bbe6b8d6157f81c8",
|
|
"aarch64-unknown-linux-gnu": "753c905e89a714ab9bce6fe1397b721f29c0760c32f09d2f328af3d39919c8e6",
|
|
"x86_64-apple-darwin": "84e5be6c5c78734deba911dcf80316be1e4c7da2c59413124d039ad96620612f",
|
|
},
|
|
"1.46.0": {
|
|
"x86_64-unknown-linux-gnu": "e3b98bc3440fe92817881933f9564389eccb396f5f431f33d48b979fa2fbdcf5",
|
|
"powerpc64le-unknown-linux-gnu": "89e2f4761d257f017a4b6aa427f36ac0603195546fa2cfded8c899789832941c",
|
|
"aarch64-unknown-linux-gnu": "f0c6d630f3dedb3db69d69ed9f833aa6b472363096f5164f1068c7001ca42aeb",
|
|
"x86_64-apple-darwin": "82d61582a3772932432a99789c3b3bd4abe6baca339e355048ca9efb9ea5b4db",
|
|
},
|
|
"1.45.1": {
|
|
"x86_64-unknown-linux-gnu": "76dc9f05b3bfd0465d6e6d22bc9fd5db0b473e3548e8b3d266ecfe4d9e5dca16",
|
|
"powerpc64le-unknown-linux-gnu": "271846e4f5adc9a33754794c2ffab851f9e0313c8c1315264e7db5c8f63ab7ab",
|
|
"aarch64-unknown-linux-gnu": "d17fd560e8d5d12304835b71a7e22ac2c3babf4b9768db6a0e89868b4444f728",
|
|
"x86_64-apple-darwin": "7334c927e4d2d12d209bf941b97ba309e548413e241d2d263c39c6e12b3ce154",
|
|
},
|
|
"1.44.1": {
|
|
"x86_64-unknown-linux-gnu": "a41df89a461a580536aeb42755e43037556fba2e527dd13a1e1bb0749de28202",
|
|
"powerpc64le-unknown-linux-gnu": "22deeca259459db31065af7c862fcab7fbfb623200520c65002ed2ba93d87ad2",
|
|
"aarch64-unknown-linux-gnu": "a2d74ebeec0b6778026b6c37814cdc91d14db3b0d8b6d69d036216f4d9cf7e49",
|
|
"x86_64-apple-darwin": "a5464e7bcbce9647607904a4afa8362382f1fc55d39e7bbaf4483ac00eb5d56a",
|
|
},
|
|
"1.44.0": {
|
|
"x86_64-unknown-linux-gnu": "eaa34271b4ac4d2c281831117d4d335eed0b37fe7a34477d9855a6f1d930a624",
|
|
"powerpc64le-unknown-linux-gnu": "97038ea935c7a5b21f5aaaaad409c514e2b2ae8ea55994ba39645f453e98bc9f",
|
|
"aarch64-unknown-linux-gnu": "bcc916003cb9c7ff44f5f9af348020b422dbc5bd4fe49bdbda2de6ce0a1bb745",
|
|
"x86_64-apple-darwin": "f20388b80b2b0a8b122d89058f785a2cf3b14e93bcac53471d60fdb4106ffa35",
|
|
},
|
|
}
|
|
|
|
# This dictionary maps Rust target architectures to Spack constraints that
|
|
# match that target.
|
|
rust_archs = {
|
|
"x86_64-unknown-linux-gnu": [
|
|
{"platform": "linux", "target": "x86_64:"},
|
|
{"platform": "cray", "target": "x86_64:"},
|
|
],
|
|
"powerpc64le-unknown-linux-gnu": [
|
|
{"platform": "linux", "target": "ppc64le:"},
|
|
{"platform": "cray", "target": "ppc64le:"},
|
|
],
|
|
"aarch64-unknown-linux-gnu": [
|
|
{"platform": "linux", "target": "aarch64:"},
|
|
{"platform": "cray", "target": "aarch64:"},
|
|
],
|
|
"x86_64-apple-darwin": [{"platform": "darwin", "target": "x86_64:"}],
|
|
"aarch64-apple-darwin": [{"platform": "darwin", "target": "aarch64:"}],
|
|
}
|
|
|
|
# Specifies the strings which represent a pre-release Rust version. These
|
|
# always bootstrap with the latest beta release.
|
|
#
|
|
# NOTE: These are moving targets, and therefore have no stable checksum. Be
|
|
# sure to specify "-n" or "--no-checksum" when installing these versions.
|
|
rust_prerelease_versions = ["beta", "nightly", "master"]
|
|
|
|
for prerelease_version in rust_prerelease_versions:
|
|
for rust_target, rust_arch_list in rust_archs.items():
|
|
for rust_arch in rust_arch_list:
|
|
# All pre-release builds are built with the latest beta
|
|
# compiler.
|
|
resource(
|
|
name="rust-beta-{target}".format(target=rust_target),
|
|
url="https://static.rust-lang.org/dist/rust-beta-{target}.tar.gz".format(
|
|
target=rust_target
|
|
),
|
|
# Fake SHA - checksums should never be checked for
|
|
# pre-release builds, anyway
|
|
sha256="0000000000000000000000000000000000000000000000000000000000000000",
|
|
destination="spack_bootstrap_stage",
|
|
when="@{version} platform={platform} target={target}".format(
|
|
version=prerelease_version,
|
|
platform=rust_arch["platform"],
|
|
target=rust_arch["target"],
|
|
),
|
|
)
|
|
|
|
# This loop generates resources for each binary distribution, and maps
|
|
# them to the version of the compiler they bootstrap. This is in place
|
|
# of listing each resource explicitly, which would be potentially even
|
|
# more verbose.
|
|
#
|
|
# NOTE: This loop should technically specify the architecture to be the
|
|
# _host_ architecture, not the target architecture, in order to support
|
|
# cross compiling. I'm not sure Spack provides a way to specify a
|
|
# distinction in the when clause, though.
|
|
for rust_version, rust_targets in rust_releases.items():
|
|
for rust_target, rust_sha256 in rust_targets.items():
|
|
for rust_arch in rust_archs[rust_target]:
|
|
resource(
|
|
name="rust-{version}-{target}".format(
|
|
version=rust_version, target=rust_target
|
|
),
|
|
url="https://static.rust-lang.org/dist/rust-{version}-{target}.tar.gz".format(
|
|
version=rust_version, target=rust_target
|
|
),
|
|
sha256=rust_sha256,
|
|
destination="spack_bootstrap_stage",
|
|
when="@{ver} platform={platform} target={target}".format(
|
|
ver=rust_version,
|
|
platform=rust_arch["platform"],
|
|
target=rust_arch["target"],
|
|
),
|
|
)
|
|
|
|
executables = ["^rustc$"]
|
|
|
|
@classmethod
|
|
def determine_version(csl, exe):
|
|
output = Executable(exe)("--version", output=str, error=str)
|
|
match = re.match(r"rustc (\S+)", output)
|
|
return match.group(1) if match else None
|
|
|
|
# This routine returns the target architecture we intend to build for.
|
|
def get_rust_target(self):
|
|
if "platform=linux" in self.spec or "platform=cray" in self.spec:
|
|
if "target=x86_64:" in self.spec:
|
|
return "x86_64-unknown-linux-gnu"
|
|
elif "target=ppc64le:" in self.spec:
|
|
return "powerpc64le-unknown-linux-gnu"
|
|
elif "target=aarch64:" in self.spec:
|
|
return "aarch64-unknown-linux-gnu"
|
|
elif "platform=darwin" in self.spec:
|
|
if "target=x86_64:" in self.spec:
|
|
return "x86_64-apple-darwin"
|
|
elif "target=aarch64:" in self.spec:
|
|
return "aarch64-apple-darwin"
|
|
|
|
raise InstallError("rust is not supported for '{0}'".format(self.spec.architecture))
|
|
|
|
def check_newer(self, version):
|
|
if "@master" in self.spec or "@beta" in self.spec or "@nightly" in self.spec:
|
|
return True
|
|
|
|
return "@{0}:".format(version) in self.spec
|
|
|
|
def patch(self):
|
|
if self.spec.satisfies("@1.51.0"):
|
|
# see 31c93397bde7 upstream
|
|
filter_file(
|
|
"panic!(out);", 'panic!("{}", out);', "src/bootstrap/builder.rs", string=True
|
|
)
|
|
|
|
def configure(self, spec, prefix):
|
|
target = self.get_rust_target()
|
|
|
|
# Bootstrapping compiler selection:
|
|
# Pre-release compilers use the latest beta release for the
|
|
# bootstrapping compiler.
|
|
# Versioned releases bootstrap themselves.
|
|
if "@beta" in spec or "@nightly" in spec or "@master" in spec:
|
|
bootstrap_version = "beta"
|
|
else:
|
|
bootstrap_version = spec.version
|
|
# See the NOTE above the resource loop - should be host architecture,
|
|
# not target aarchitecture if we're to support cross-compiling.
|
|
bootstrapping_install = Executable(
|
|
"./spack_bootstrap_stage/rust-{version}-{target}/install.sh".format(
|
|
version=bootstrap_version, target=target
|
|
)
|
|
)
|
|
# install into the staging area
|
|
bootstrapping_install(
|
|
"--prefix={0}".format(join_path(self.stage.source_path, "spack_bootstrap"))
|
|
)
|
|
|
|
boot_bin = join_path(self.stage.source_path, "spack_bootstrap/bin")
|
|
|
|
# Always build rustc and cargo
|
|
tools = ["rustc", "cargo"]
|
|
# Only make additional components available in 'rust-bootstrap'
|
|
if "+rustfmt" in self.spec:
|
|
tools.append("rustfmt")
|
|
if "+analysis" in self.spec:
|
|
tools.append("analysis")
|
|
if "@1.33: +clippy" in self.spec:
|
|
tools.append("clippy")
|
|
if "+rls" in self.spec:
|
|
tools.append("rls")
|
|
if "+src" in self.spec:
|
|
tools.append("src")
|
|
|
|
ar = which("ar", required=True)
|
|
|
|
extra_targets = []
|
|
if not self.spec.satisfies("extra_targets=none"):
|
|
extra_targets = list(self.spec.variants["extra_targets"].value)
|
|
|
|
targets = [self.get_rust_target()] + extra_targets
|
|
target_spec = "target=[" + ",".join('"{0}"'.format(target) for target in targets) + "]"
|
|
target_specs = "\n".join(
|
|
'[target.{0}]\nar = "{1}"\n'.format(target, ar.path) for target in targets
|
|
)
|
|
|
|
# build.tools was introduced in Rust 1.25
|
|
tools_spec = "tools={0}".format(tools) if self.check_newer("1.25") else ""
|
|
# This is a temporary fix due to rust 1.42 breaking self bootstrapping
|
|
# See: https://github.com/rust-lang/rust/issues/69953
|
|
#
|
|
# In general, this should be safe because bootstrapping typically
|
|
# ensures everything but the bootstrapping script is warning free for
|
|
# the latest set of warning.
|
|
deny_warnings_spec = "deny-warnings = false" if "@1.42.0" in self.spec else ""
|
|
|
|
# "Nightly" and master builds want a path to rustfmt - otherwise, it
|
|
# will try to download rustfmt from the Internet. We'll give it rustfmt
|
|
# for the bootstrapping compiler, but it ultimately shouldn't matter
|
|
# because this package never invokes it. To be clear, rustfmt from the
|
|
# bootstrapping compiler is probably incorrect. See: src/stage0.txt in
|
|
# Rust to see what the current "official" rustfmt version for Rust is.
|
|
if "@master" in spec or "@nightly" in spec:
|
|
rustfmt_spec = 'rustfmt="{0}"'.format(join_path(boot_bin, "rustfmt"))
|
|
else:
|
|
rustfmt_spec = ""
|
|
|
|
with open("config.toml", "w") as out_file:
|
|
out_file.write(
|
|
"""\
|
|
[build]
|
|
cargo = "{cargo}"
|
|
rustc = "{rustc}"
|
|
docs = false
|
|
vendor = true
|
|
extended = true
|
|
verbose = 2
|
|
{target_spec}
|
|
{tools_spec}
|
|
{rustfmt_spec}
|
|
|
|
[rust]
|
|
channel = "stable"
|
|
rpath = true
|
|
{deny_warnings_spec}
|
|
|
|
{target_specs}
|
|
|
|
[install]
|
|
prefix = "{prefix}"
|
|
sysconfdir = "etc"
|
|
""".format(
|
|
cargo=join_path(boot_bin, "cargo"),
|
|
rustc=join_path(boot_bin, "rustc"),
|
|
prefix=prefix,
|
|
deny_warnings_spec=deny_warnings_spec,
|
|
target_spec=target_spec,
|
|
target_specs=target_specs,
|
|
tools_spec=tools_spec,
|
|
rustfmt_spec=rustfmt_spec,
|
|
)
|
|
)
|
|
|
|
def build(self, spec, prefix):
|
|
python(
|
|
"./x.py",
|
|
"build",
|
|
extra_env={
|
|
# vendored libgit2 wasn't correctly building (couldn't find the
|
|
# vendored libssh2), so let's just have spack build it
|
|
"LIBSSH2_SYS_USE_PKG_CONFIG": "1",
|
|
"LIBGIT2_SYS_USE_PKG_CONFIG": "1",
|
|
},
|
|
)
|
|
|
|
def install(self, spec, prefix):
|
|
python("./x.py", "install")
|