External package detection for compilers (#43464)

This creates shared infrastructure for compiler packages to implement the 
detailed search capabilities from the `spack compiler find` command for the 
`spack external find` command.

After this commit, `spack compiler find` can be replaced with 
`spack external find --tag compiler`, with the exception of mixed toolchains.
This commit is contained in:
Greg Becker 2024-05-06 01:33:33 -07:00 committed by GitHub
parent 27aeb6e293
commit 1f31c3374c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
41 changed files with 1375 additions and 698 deletions

View file

@ -478,6 +478,13 @@ prefix, you can add them to the ``extra_attributes`` field. Similarly,
all other fields from the compilers config can be added to the all other fields from the compilers config can be added to the
``extra_attributes`` field for an external representing a compiler. ``extra_attributes`` field for an external representing a compiler.
Note that the format for the ``paths`` field in the
``extra_attributes`` section is different than in the ``compilers``
config. For compilers configured as external packages, the section is
named ``compilers`` and the dictionary maps language names (``c``,
``cxx``, ``fortran``) to paths, rather than using the names ``cc``,
``fc``, and ``f77``.
.. code-block:: yaml .. code-block:: yaml
packages: packages:
@ -493,11 +500,10 @@ all other fields from the compilers config can be added to the
- spec: llvm+clang@15.0.0 arch=linux-rhel8-skylake - spec: llvm+clang@15.0.0 arch=linux-rhel8-skylake
prefix: /usr prefix: /usr
extra_attributes: extra_attributes:
paths: compilers:
cc: /usr/bin/clang-with-suffix c: /usr/bin/clang-with-suffix
cxx: /usr/bin/clang++-with-extra-info cxx: /usr/bin/clang++-with-extra-info
fc: /usr/bin/gfortran fortran: /usr/bin/gfortran
f77: /usr/bin/gfortran
extra_rpaths: extra_rpaths:
- /usr/lib/llvm/ - /usr/lib/llvm/

View file

@ -0,0 +1,144 @@
# 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 itertools
import os
import pathlib
import re
import sys
from typing import Dict, List, Sequence, Tuple, Union
import llnl.util.tty as tty
from llnl.util.lang import classproperty
import spack.compiler
import spack.package_base
# Local "type" for type hints
Path = Union[str, pathlib.Path]
class CompilerPackage(spack.package_base.PackageBase):
"""A Package mixin for all common logic for packages that implement compilers"""
# TODO: how do these play nicely with other tags
tags: Sequence[str] = ["compiler"]
#: Optional suffix regexes for searching for this type of compiler.
#: Suffixes are used by some frameworks, e.g. macports uses an '-mp-X.Y'
#: version suffix for gcc.
compiler_suffixes: List[str] = [r"-.*"]
#: Optional prefix regexes for searching for this compiler
compiler_prefixes: List[str] = []
#: Compiler argument(s) that produces version information
#: If multiple arguments, the earlier arguments must produce errors when invalid
compiler_version_argument: Union[str, Tuple[str]] = "-dumpversion"
#: Regex used to extract version from compiler's output
compiler_version_regex: str = "(.*)"
#: Static definition of languages supported by this class
compiler_languages: Sequence[str] = ["c", "cxx", "fortran"]
def __init__(self, spec: "spack.spec.Spec"):
super().__init__(spec)
msg = f"Supported languages for {spec} are not a subset of possible supported languages"
msg += f" supports: {self.supported_languages}, valid values: {self.compiler_languages}"
assert set(self.supported_languages) <= set(self.compiler_languages), msg
@property
def supported_languages(self) -> Sequence[str]:
"""Dynamic definition of languages supported by this package"""
return self.compiler_languages
@classproperty
def compiler_names(cls) -> Sequence[str]:
"""Construct list of compiler names from per-language names"""
names = []
for language in cls.compiler_languages:
names.extend(getattr(cls, f"{language}_names"))
return names
@classproperty
def executables(cls) -> Sequence[str]:
"""Construct executables for external detection from names, prefixes, and suffixes."""
regexp_fmt = r"^({0}){1}({2})$"
prefixes = [""] + cls.compiler_prefixes
suffixes = [""] + cls.compiler_suffixes
if sys.platform == "win32":
ext = r"\.(?:exe|bat)"
suffixes += [suf + ext for suf in suffixes]
return [
regexp_fmt.format(prefix, re.escape(name), suffix)
for prefix, name, suffix in itertools.product(prefixes, cls.compiler_names, suffixes)
]
@classmethod
def determine_version(cls, exe: Path):
version_argument = cls.compiler_version_argument
if isinstance(version_argument, str):
version_argument = (version_argument,)
for va in version_argument:
try:
output = spack.compiler.get_compiler_version_output(exe, va)
match = re.search(cls.compiler_version_regex, output)
if match:
return ".".join(match.groups())
except spack.util.executable.ProcessError:
pass
except Exception as e:
tty.debug(
f"[{__file__}] Cannot detect a valid version for the executable "
f"{str(exe)}, for package '{cls.name}': {e}"
)
@classmethod
def compiler_bindir(cls, prefix: Path) -> Path:
"""Overridable method for the location of the compiler bindir within the preifx"""
return os.path.join(prefix, "bin")
@classmethod
def determine_compiler_paths(cls, exes: Sequence[Path]) -> Dict[str, Path]:
"""Compute the paths to compiler executables associated with this package
This is a helper method for ``determine_variants`` to compute the ``extra_attributes``
to include with each spec object."""
# There are often at least two copies (not symlinks) of each compiler executable in the
# same directory: one with a canonical name, e.g. "gfortran", and another one with the
# target prefix, e.g. "x86_64-pc-linux-gnu-gfortran". There also might be a copy of "gcc"
# with the version suffix, e.g. "x86_64-pc-linux-gnu-gcc-6.3.0". To ensure the consistency
# of values in the "paths" dictionary (i.e. we prefer all of them to reference copies
# with canonical names if possible), we iterate over the executables in the reversed sorted
# order:
# First pass over languages identifies exes that are perfect matches for canonical names
# Second pass checks for names with prefix/suffix
# Second pass is sorted by language name length because longer named languages
# e.g. cxx can often contain the names of shorter named languages
# e.g. c (e.g. clang/clang++)
paths = {}
exes = sorted(exes, reverse=True)
languages = {
lang: getattr(cls, f"{lang}_names")
for lang in sorted(cls.compiler_languages, key=len, reverse=True)
}
for exe in exes:
for lang, names in languages.items():
if os.path.basename(exe) in names:
paths[lang] = exe
break
else:
for lang, names in languages.items():
if any(name in os.path.basename(exe) for name in names):
paths[lang] = exe
break
return paths
@classmethod
def determine_variants(cls, exes: Sequence[Path], version_str: str) -> Tuple:
# path determination is separated so it can be reused in subclasses
return "", {"compilers": cls.determine_compiler_paths(exes=exes)}

View file

@ -164,33 +164,56 @@ def _compiler_config_from_package_config(config):
def _compiler_config_from_external(config): def _compiler_config_from_external(config):
extra_attributes_key = "extra_attributes"
compilers_key = "compilers"
c_key, cxx_key, fortran_key = "c", "cxx", "fortran"
# Allow `@x.y.z` instead of `@=x.y.z`
spec = spack.spec.parse_with_version_concrete(config["spec"]) spec = spack.spec.parse_with_version_concrete(config["spec"])
# use str(spec.versions) to allow `@x.y.z` instead of `@=x.y.z`
compiler_spec = spack.spec.CompilerSpec( compiler_spec = spack.spec.CompilerSpec(
package_name_to_compiler_name.get(spec.name, spec.name), spec.version package_name_to_compiler_name.get(spec.name, spec.name), spec.version
) )
extra_attributes = config.get("extra_attributes", {}) err_header = f"The external spec '{spec}' cannot be used as a compiler"
prefix = config.get("prefix", None)
compiler_class = class_for_compiler_name(compiler_spec.name) # If extra_attributes is not there I might not want to use this entry as a compiler,
paths = extra_attributes.get("paths", {}) # therefore just leave a debug message, but don't be loud with a warning.
compiler_langs = ["cc", "cxx", "fc", "f77"] if extra_attributes_key not in config:
for lang in compiler_langs: tty.debug(f"[{__file__}] {err_header}: missing the '{extra_attributes_key}' key")
if paths.setdefault(lang, None):
continue
if not prefix:
continue
# Check for files that satisfy the naming scheme for this compiler
bindir = os.path.join(prefix, "bin")
for f, regex in itertools.product(os.listdir(bindir), compiler_class.search_regexps(lang)):
if regex.match(f):
paths[lang] = os.path.join(bindir, f)
if all(v is None for v in paths.values()):
return None return None
extra_attributes = config[extra_attributes_key]
# If I have 'extra_attributes' warn if 'compilers' is missing, or we don't have a C compiler
if compilers_key not in extra_attributes:
warnings.warn(
f"{err_header}: missing the '{compilers_key}' key under '{extra_attributes_key}'"
)
return None
attribute_compilers = extra_attributes[compilers_key]
if c_key not in attribute_compilers:
warnings.warn(
f"{err_header}: missing the C compiler path under "
f"'{extra_attributes_key}:{compilers_key}'"
)
return None
c_compiler = attribute_compilers[c_key]
# C++ and Fortran compilers are not mandatory, so let's just leave a debug trace
if cxx_key not in attribute_compilers:
tty.debug(f"[{__file__}] The external spec {spec} does not have a C++ compiler")
if fortran_key not in attribute_compilers:
tty.debug(f"[{__file__}] The external spec {spec} does not have a Fortran compiler")
# compilers format has cc/fc/f77, externals format has "c/fortran"
paths = {
"cc": c_compiler,
"cxx": attribute_compilers.get(cxx_key, None),
"fc": attribute_compilers.get(fortran_key, None),
"f77": attribute_compilers.get(fortran_key, None),
}
if not spec.architecture: if not spec.architecture:
host_platform = spack.platforms.host() host_platform = spack.platforms.host()

View file

@ -39,6 +39,7 @@
) )
from spack.build_systems.cargo import CargoPackage from spack.build_systems.cargo import CargoPackage
from spack.build_systems.cmake import CMakePackage, generator from spack.build_systems.cmake import CMakePackage, generator
from spack.build_systems.compiler import CompilerPackage
from spack.build_systems.cuda import CudaPackage from spack.build_systems.cuda import CudaPackage
from spack.build_systems.generic import Package from spack.build_systems.generic import Package
from spack.build_systems.gnu import GNUMirrorPackage from spack.build_systems.gnu import GNUMirrorPackage

View file

@ -261,15 +261,14 @@ def test_compiler_list_empty(no_compilers_yaml, working_env, compilers_dir):
[ [
( (
{ {
"spec": "gcc@=7.7.7 os=foobar target=x86_64", "spec": "gcc@=7.7.7 languages=c,cxx,fortran os=foobar target=x86_64",
"prefix": "/path/to/fake", "prefix": "/path/to/fake",
"modules": ["gcc/7.7.7", "foobar"], "modules": ["gcc/7.7.7", "foobar"],
"extra_attributes": { "extra_attributes": {
"paths": { "compilers": {
"cc": "/path/to/fake/gcc", "c": "/path/to/fake/gcc",
"cxx": "/path/to/fake/g++", "cxx": "/path/to/fake/g++",
"fc": "/path/to/fake/gfortran", "fortran": "/path/to/fake/gfortran",
"f77": "/path/to/fake/gfortran",
}, },
"flags": {"fflags": "-ffree-form"}, "flags": {"fflags": "-ffree-form"},
}, },
@ -285,26 +284,7 @@ def test_compiler_list_empty(no_compilers_yaml, working_env, compilers_dir):
\tmodules = ['gcc/7.7.7', 'foobar'] \tmodules = ['gcc/7.7.7', 'foobar']
\toperating system = foobar \toperating system = foobar
""", """,
), )
(
{
"spec": "gcc@7.7.7",
"prefix": "{prefix}",
"modules": ["gcc/7.7.7", "foobar"],
"extra_attributes": {"flags": {"fflags": "-ffree-form"}},
},
"""gcc@7.7.7:
\tpaths:
\t\tcc = {compilers_dir}{sep}gcc-8{suffix}
\t\tcxx = {compilers_dir}{sep}g++-8{suffix}
\t\tf77 = {compilers_dir}{sep}gfortran-8{suffix}
\t\tfc = {compilers_dir}{sep}gfortran-8{suffix}
\tflags:
\t\tfflags = ['-ffree-form']
\tmodules = ['gcc/7.7.7', 'foobar']
\toperating system = debian6
""",
),
], ],
) )
def test_compilers_shows_packages_yaml( def test_compilers_shows_packages_yaml(

View file

@ -1694,7 +1694,7 @@ def mock_executable(tmp_path):
"""Factory to create a mock executable in a temporary directory that """Factory to create a mock executable in a temporary directory that
output a custom string when run. output a custom string when run.
""" """
shebang = "#!/bin/sh\n" if sys.platform != "win32" else "@ECHO OFF" shebang = "#!/bin/sh\n" if sys.platform != "win32" else "@ECHO OFF\n"
def _factory(name, output, subdir=("bin",)): def _factory(name, output, subdir=("bin",)):
executable_dir = tmp_path.joinpath(*subdir) executable_dir = tmp_path.joinpath(*subdir)

View file

@ -0,0 +1,83 @@
paths:
- layout:
- executables:
- "bin/armclang"
- "bin/armclang++"
- "bin/armflang"
script: |
echo "Arm C/C++/Fortran Compiler version 19.0 (build number 73) (based on LLVM 7.0.2)"
echo "Target: aarch64--linux-gnu"
echo "Thread model: posix"
echo "InstalledDir:"
echo "/opt/arm/arm-hpc-compiler-19.0_Generic-AArch64_RHEL-7_aarch64-linux/bin"
platforms: [linux]
results:
- spec: acfl@19.0
extra_attributes:
compilers:
c: ".*/bin/armclang"
cxx: ".*/bin/armclang[+][+]"
fortran: ".*/bin/armflang"
- layout:
- executables:
- "bin/armclang"
- "bin/armclang++"
script: |
echo "Arm C/C++/Fortran Compiler version 19.0 (build number 73) (based on LLVM 7.0.2)"
echo "Target: aarch64--linux-gnu"
echo "Thread model: posix"
echo "InstalledDir:"
echo "/opt/arm/arm-hpc-compiler-19.0_Generic-AArch64_RHEL-7_aarch64-linux/bin"
platforms: [linux]
results:
- spec: acfl@19.0
extra_attributes:
compilers:
c: ".*/bin/armclang"
cxx: ".*/bin/armclang[+][+]"
- layout:
- executables:
- "bin/armclang"
- "bin/armclang++"
- "bin/armflang"
script: |
echo "Arm C/C++/Fortran Compiler version 19.3.1 (build number 75) (based on LLVM 7.0.2)"
echo "Target: aarch64--linux-gnu"
echo "Thread model: posix"
echo "InstalledDir:"
echo "/opt/arm/arm-hpc-compiler-19.3.5_Generic-AArch64_RHEL-7_aarch64-linux/bin"
- executables:
- "bin/armclang-18"
- "bin/armclang++-18"
- "bin/armflang-18"
script: |
echo "Arm C/C++/Fortran Compiler version 18.0 (build number 27) (based on LLVM 7.0.0)"
echo "Target: aarch64--linux-gnu"
echo "Thread model: posix"
echo "InstalledDir:"
echo "/opt/arm/arm-hpc-compiler-19_Generic-AArch64_RHEL-7_aarch64-linux/bin"
platforms: [linux]
results:
- spec: acfl@19.3.1
extra_attributes:
compilers:
c: ".*/bin/armclang$"
cxx: ".*/bin/armclang[+][+]$"
fortran: ".*/bin/armflang$"
- spec: acfl@18.0
extra_attributes:
compilers:
c: ".*/bin/armclang-18"
cxx: ".*/bin/armclang[+][+]-18"
fortran: ".*/bin/armflang-18"
- layout: # does not detect upstream clang
- executables:
- "bin/clang"
- "bin/clang++"
script: |
echo "clang version 8.0.0 (tags/RELEASE_800/final"
echo "Target: x86_64-unknown-linux-gnu\n"
echo "Thread model: posix\n"
echo "InstalledDir: /usr/bin"
platforms: [linux]
results: []

View file

@ -3,7 +3,6 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os import os
import re
from spack.package import * from spack.package import *
@ -228,7 +227,7 @@ def get_gcc_prefix(spec):
return join_path(spec.prefix, next(dir for dir in dirlist if dir.startswith("gcc"))) return join_path(spec.prefix, next(dir for dir in dirlist if dir.startswith("gcc")))
class Acfl(Package): class Acfl(Package, CompilerPackage):
"""Arm Compiler combines the optimized tools and libraries from Arm """Arm Compiler combines the optimized tools and libraries from Arm
with a modern LLVM-based compiler framework. with a modern LLVM-based compiler framework.
""" """
@ -275,33 +274,15 @@ def install(self, spec, prefix):
) )
exe("--accept", "--force", "--install-to", prefix) exe("--accept", "--force", "--install-to", prefix)
@classmethod compiler_languages = ["c", "cxx", "fortran"]
def determine_version(cls, exe): c_names = ["armclang"]
regex_str = r"Arm C\/C\+\+\/Fortran Compiler version ([\d\.]+) " r"\(build number (\d+)\) " cxx_names = ["armclang++"]
version_regex = re.compile(regex_str) fortran_names = ["armflang"]
try:
output = spack.compiler.get_compiler_version_output(exe, "--version")
match = version_regex.search(output)
if match:
if match.group(1).count(".") == 1:
return match.group(1) + ".0." + match.group(2)
return match.group(1) + "." + match.group(2)
except spack.util.executable.ProcessError:
pass
except Exception as e:
tty.debug(e)
@classmethod compiler_version_argument = "--version"
def determine_variants(cls, exes, version_str): compiler_version_regex = (
compilers = {} r"Arm C\/C\+\+\/Fortran Compiler version ([\d\.]+) \(build number \d+\) "
for exe in exes: )
if "armclang" in exe:
compilers["c"] = exe
if "armclang++" in exe:
compilers["cxx"] = exe
if "armflang" in exe:
compilers["fortran"] = exe
return "", {"compilers": compilers}
@property @property
def cc(self): def cc(self):

View file

@ -0,0 +1,75 @@
paths:
- layout:
- executables:
- "bin/clang"
- "bin/clang++"
- "bin/flang"
script: |
echo "AMD clang version 12.0.0 (CLANG: AOCC_3_1_0-Build#126 2021_06_07)(based on LLVM Mirror.Version.12.0.0)\n"
echo "Target: x86_64-unknown-linux-gnu\n"
echo "Thread model: posix\n"
platforms: [linux]
results:
- spec: aocc@3.1.0
extra_attributes:
compilers:
c: ".*/bin/clang"
cxx: ".*/bin/clang[+][+]"
fortran: ".*/bin/flang"
- layout:
- executables:
- "bin/clang"
- "bin/clang++"
script: |
echo "AMD clang version 12.0.0 (CLANG: AOCC_3_1_0-Build#126 2021_06_07)(based on LLVM Mirror.Version.12.0.0)\n"
echo "Target: x86_64-unknown-linux-gnu\n"
echo "Thread model: posix\n"
platforms: [linux]
results:
- spec: aocc@3.1.0
extra_attributes:
compilers:
c: ".*/bin/clang"
cxx: ".*/bin/clang[+][+]"
- layout:
- executables:
- "bin/clang"
- "bin/clang++"
- "bin/flang"
script: |
echo "AMD clang version 12.0.0 (CLANG: AOCC_3_0_0-Build#78 2020_12_10)(based on LLVM Mirror.Version.12.0.0)\n"
echo "Target: x86_64-unknown-linux-gnu\n"
echo "Thread model: posix\n"
- executables:
- "bin/clang-11"
- "bin/clang++-11"
- "bin/flang-11"
script: |
echo "AMD clang version 11.0.0 (CLANG: AOCC_2_3_0-Build#85 2020_11_10)(based on LLVM Mirror.Version.11.0.0)\n"
echo "Target: x86_64-unknown-linux-gnu\n"
echo "Thread model: posix\n"
platforms: [linux]
results:
- spec: aocc@3.0.0
extra_attributes:
compilers:
c: ".*/bin/clang$"
cxx: ".*/bin/clang[+][+]$"
fortran: ".*/bin/flang$"
- spec: aocc@2.3.0
extra_attributes:
compilers:
c: ".*/bin/clang-11"
cxx: ".*/bin/clang[+][+]-11"
fortran: ".*/bin/flang-11"
- layout:
- executables:
- "bin/clang"
- "bin/clang++"
script: |
echo "clang version 8.0.0 (tags/RELEASE_800/final"
echo "Target: x86_64-unknown-linux-gnu\n"
echo "Thread model: posix\n"
echo "InstalledDir: /usr/bin"
platforms: [linux]
results: []

View file

@ -8,7 +8,7 @@
from spack.package import * from spack.package import *
class Aocc(Package): class Aocc(Package, CompilerPackage):
""" """
The AOCC compiler system is a high performance, production quality code The AOCC compiler system is a high performance, production quality code
generation tool. The AOCC environment provides various options to developers generation tool. The AOCC environment provides various options to developers
@ -104,3 +104,9 @@ def cfg_files(self):
for compiler in ["clang", "clang++"]: for compiler in ["clang", "clang++"]:
with open(join_path(self.prefix.bin, "{}.cfg".format(compiler)), "w") as f: with open(join_path(self.prefix.bin, "{}.cfg".format(compiler)), "w") as f:
f.write(compiler_options) f.write(compiler_options)
compiler_version_argument = "--version"
compiler_version_regex = r"AOCC_(\d+[._]\d+[._]\d+)"
c_names = ["clang"]
cxx_names = ["clang++"]
fortran_names = ["flang"]

View file

@ -12,6 +12,11 @@ paths:
platforms: ["darwin"] platforms: ["darwin"]
results: results:
- spec: 'apple-clang@11.0.0' - spec: 'apple-clang@11.0.0'
extra_attributes:
compilers:
c: ".*/bin/clang"
cxx: ".*/bin/clang[+][+]"
# Apple Clang on Apple M1 (Ventura) # Apple Clang on Apple M1 (Ventura)
- layout: - layout:
- executables: - executables:
@ -25,6 +30,11 @@ paths:
platforms: ["darwin"] platforms: ["darwin"]
results: results:
- spec: 'apple-clang@15.0.0' - spec: 'apple-clang@15.0.0'
extra_attributes:
compilers:
c: ".*/bin/clang"
cxx: ".*/bin/clang[+][+]"
# Test that missing a compiler prevents the package from being detected # Test that missing a compiler prevents the package from being detected
- layout: - layout:
- executables: - executables:

View file

@ -2,12 +2,10 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details. # Spack Project Developers. See the top-level COPYRIGHT file for details.
# #
# 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 *
class AppleClang(BundlePackage): class AppleClang(BundlePackage, CompilerPackage):
"""Apple's Clang compiler""" """Apple's Clang compiler"""
homepage = "https://developer.apple.com/videos/developer-tools/compiler-and-llvm" homepage = "https://developer.apple.com/videos/developer-tools/compiler-and-llvm"
@ -15,44 +13,12 @@ class AppleClang(BundlePackage):
maintainers("alalazo") maintainers("alalazo")
executables = ["^clang$", r"^clang\+\+$", "^ld.lld$", "^lldb$"] compiler_languages = ["c", "cxx"]
c_names = ["clang"]
cxx_names = ["clang++"]
@classmethod compiler_version_regex = r"^Apple (?:LLVM|clang) version ([^ )]+)"
def determine_version(cls, exe): compiler_version_argument = "--version"
version_regex = re.compile(
# Apple's LLVM compiler has its own versions, which are
# different from vanilla LLVM
r"^Apple (?:LLVM|clang) version ([^ )]+)",
# Multi-line, since 'Apple clang' may not be on the first line
# in particular, when run as gcc, it seems to output
# "Configured with: --prefix=..." as the first line
re.M,
)
try:
compiler = Executable(exe)
output = compiler("--version", output=str, error=str)
match = version_regex.search(output)
if match:
return match.group(match.lastindex)
except Exception:
pass
return None
@classmethod
def determine_variants(cls, exes, version_str):
compilers = {}
for exe in exes:
if "clang++" in exe:
compilers["cxx"] = exe
elif "clang" in exe:
compilers["c"] = exe
elif "ld.lld" in exe:
compilers["ld"] = exe
elif "lldb" in exe:
compilers["lldb"] = exe
return "", {"compilers": compilers}
@classmethod @classmethod
def validate_detected_spec(cls, spec, extra_attributes): def validate_detected_spec(cls, spec, extra_attributes):

View file

@ -0,0 +1,44 @@
paths:
- layout:
- executables:
- "bin/craycc"
script: |
echo "Cray C : Version 8.4.6 Mon Apr 15, 2019 12:13:39"
- executables:
- "bin/crayCC"
script: |
echo "Cray C++ : Version 8.4.6 Mon Apr 15, 2019 12:13:39"
- executables:
- "bin/crayftn"
script: |
echo "Cray Fortran : Version 8.4.6 Mon Apr 15, 2019 12:13:39"
platforms: [linux]
results:
- spec: cce@8.4.6
extra_attributes:
compilers:
c: ".*/bin/craycc"
cxx: ".*/bin/crayCC"
fortran: ".*/bin/crayftn"
- layout:
- executables:
- "bin/craycc"
- "bin/crayCC"
script: |
echo "Cray clang version 17.0.1 (5ec9405551a8c8845cf14e81dc28bff7aa3935cb)"
echo "Target: x86_64-unknown-linux-gnu"
echo "Thread model: posix"
echo "InstalledDir: /opt/cray/pe/cce/17.0.1/cce-clang/x86_64/share/../bin"
echo "Configuration file: /opt/cray/pe/cce/17.0.1/cce-clang/x86_64/bin/clang.cfg"
- executables:
- "bin/crayftn"
script: |
echo "Cray Fortran : Version 17.0.1"
platforms: [linux]
results:
- spec: cce@17.0.1
extra_attributes:
compilers:
c: ".*/bin/craycc"
cxx: ".*/bin/crayCC"
fortran: ".*/bin/crayftn"

View file

@ -0,0 +1,30 @@
# 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)
from spack.package import *
class Cce(Package, CompilerPackage):
"""Stub package for external detection of the Cray compiler package."""
homepage = "https://cpe.ext.hpe.com/docs/cce/index.html"
url = "https://cpe.ext.hpe.com/docs/cce/index.html"
compiler_languages = ["c", "cxx", "fortran"]
c_names = ["craycc"]
cxx_names = ["crayCC"]
fortran_names = ["crayftn"]
compiler_version_argument = "--version"
compiler_version_regex = (
r"[Cc]ray (?:clang|C :|C\+\+ :|Fortran :) [Vv]ersion.*?(\d+(?:\.\d+)+)"
)
# notify when the package is updated.
maintainers("becker33")
version("16.0.0")
def install(self, spec, prefix):
raise NotImplementedError("cray compiler must be configured as external")

View file

@ -0,0 +1,27 @@
paths:
- layout:
- executables:
- "bin/fcc"
script: |
echo "fcc (FCC) 4.0.0a 20190314"
echo "simulating gcc version 6.1"
echo "Copyright FUJITSU LIMITED 2019"
- executables:
- "bin/FCC"
script: |
echo "FCC (FCC) 4.0.0a 20190314"
echo "simulating gcc version 6.1"
echo "Copyright FUJITSU LIMITED 2019"
- executables:
- "bin/frt"
script: |
echo "frt (FRT) 4.0.0a 20190314"
echo "Copyright FUJITSU LIMITED 2019"
platforms: [linux]
results:
- spec: fj@4.0.0a
extra_attributes:
compilers:
c: ".*/bin/fcc"
cxx: ".*/bin/FCC"
fortran: ".*/bin/frt"

View file

@ -2,16 +2,10 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details. # Spack Project Developers. See the top-level COPYRIGHT file for details.
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import re
import llnl.util.tty as tty
import spack.compiler
import spack.util.executable
from spack.package import * from spack.package import *
class Fj(Package): class Fj(Package, CompilerPackage):
"""The Fujitsu compiler system is a high performance, production quality """The Fujitsu compiler system is a high performance, production quality
code generation tool designed for high performance parallel code generation tool designed for high performance parallel
computing workloads. computing workloads.
@ -27,29 +21,9 @@ def install(self, spec, prefix):
"detected on a system where they are supplied by vendor" "detected on a system where they are supplied by vendor"
) )
executables = ["^fcc", "^FCC", "^frt"] compiler_languages = ["c", "cxx", "fortran"]
c_names = ["fcc"]
@classmethod cxx_names = ["FCC"]
def determine_version(cls, exe): fortran_names = ["frt"]
version_regex = re.compile(r"\((?:FCC|FRT)\) ([a-z\d.]+)") compiler_version_regex = r"\((?:FCC|FRT)\) ([a-z\d.]+)"
try: compiler_version_argument = "--version"
output = spack.compiler.get_compiler_version_output(exe, "--version")
match = version_regex.search(output)
if match:
return match.group(1)
except spack.util.executable.ProcessError:
pass
except Exception as e:
tty.debug(e)
@classmethod
def determine_variants(cls, exes, version_str):
compilers = {}
for exe in exes:
if "fcc" in exe:
compilers["c"] = exe
if "FCC" in exe:
compilers["cxx"] = exe
if "frt" in exe:
compilers["fortran"] = exe
return "", {"compilers": compilers}

View file

@ -27,6 +27,7 @@ paths:
compilers: compilers:
c: ".*/bin/gcc" c: ".*/bin/gcc"
cxx: ".*/bin/g++" cxx: ".*/bin/g++"
# Mock a version < 7 of GCC that requires -dumpversion and # Mock a version < 7 of GCC that requires -dumpversion and
# errors with -dumpfullversion # errors with -dumpfullversion
- layout: - layout:
@ -50,6 +51,7 @@ paths:
c: ".*/bin/gcc-5$" c: ".*/bin/gcc-5$"
cxx: ".*/bin/g[+][+]-5$" cxx: ".*/bin/g[+][+]-5$"
fortran: ".*/bin/gfortran-5$" fortran: ".*/bin/gfortran-5$"
# Multiple compilers present at the same time # Multiple compilers present at the same time
- layout: - layout:
- executables: - executables:
@ -70,6 +72,7 @@ paths:
compilers: compilers:
c: ".*/bin/x86_64-linux-gnu-gcc-10$" c: ".*/bin/x86_64-linux-gnu-gcc-10$"
cxx: ".*/bin/x86_64-linux-gnu-g[+][+]-10$" cxx: ".*/bin/x86_64-linux-gnu-g[+][+]-10$"
# Apple clang under disguise as gcc should not be detected # Apple clang under disguise as gcc should not be detected
- layout: - layout:
- executables: - executables:

View file

@ -5,13 +5,11 @@
import glob import glob
import itertools import itertools
import os import os
import re
import sys import sys
from archspec.cpu import UnsupportedMicroarchitecture from archspec.cpu import UnsupportedMicroarchitecture
import llnl.util.tty as tty import llnl.util.tty as tty
from llnl.util.lang import classproperty
from llnl.util.symlink import readlink from llnl.util.symlink import readlink
import spack.platforms import spack.platforms
@ -21,7 +19,7 @@
from spack.package import * from spack.package import *
class Gcc(AutotoolsPackage, GNUMirrorPackage): class Gcc(AutotoolsPackage, GNUMirrorPackage, CompilerPackage):
"""The GNU Compiler Collection includes front ends for C, C++, Objective-C, """The GNU Compiler Collection includes front ends for C, C++, Objective-C,
Fortran, Ada, and Go, as well as libraries for these languages.""" Fortran, Ada, and Go, as well as libraries for these languages."""
@ -503,11 +501,36 @@ class Gcc(AutotoolsPackage, GNUMirrorPackage):
build_directory = "spack-build" build_directory = "spack-build"
@classproperty compiler_languages = ["c", "cxx", "fortran", "d", "go"]
def executables(cls):
names = [r"gcc", r"[^\w]?g\+\+", r"gfortran", r"gdc", r"gccgo"] @property
suffixes = [r"", r"-mp-\d+\.\d", r"-\d+\.\d", r"-\d+", r"\d\d"] def supported_languages(self):
return [r"".join(x) for x in itertools.product(names, suffixes)] # This weirdness is because it could be called on an abstract spec
if "languages" not in self.spec.variants:
return self.compiler_languages
return [x for x in self.compiler_languages if x in self.spec.variants["languages"].value]
c_names = ["gcc"]
cxx_names = ["g++"]
fortran_names = ["gfortran"]
d_names = ["gdc"]
go_names = ["gccgo"]
compiler_prefixes = [r"\w+-\w+-\w+-"]
compiler_suffixes = [r"-mp-\d+(?:\.\d+)?", r"-\d+(?:\.\d+)?", r"\d\d"]
compiler_version_regex = r"(?<!clang version)\s?([0-9.]+)"
compiler_version_argument = ("-dumpfullversion", "-dumpversion")
@classmethod
def determine_version(cls, exe):
try:
output = spack.compiler.get_compiler_version_output(exe, "--version")
except Exception:
output = ""
# Apple's gcc is actually apple clang, so skip it.
if "Apple" in output:
return None
return super().determine_version(exe)
@classmethod @classmethod
def filter_detected_exes(cls, prefix, exes_in_prefix): def filter_detected_exes(cls, prefix, exes_in_prefix):
@ -537,58 +560,14 @@ def filter_detected_exes(cls, prefix, exes_in_prefix):
return result return result
@classmethod
def determine_version(cls, exe):
try:
output = spack.compiler.get_compiler_version_output(exe, "--version")
except Exception:
output = ""
# Apple's gcc is actually apple clang, so skip it.
# Users can add it manually to compilers.yaml at their own risk.
if "Apple" in output:
return None
version_regex = re.compile(r"([\d\.]+)")
for vargs in ("-dumpfullversion", "-dumpversion"):
try:
output = spack.compiler.get_compiler_version_output(exe, vargs)
match = version_regex.search(output)
if match:
return match.group(1)
except spack.util.executable.ProcessError:
pass
except Exception as e:
tty.debug(e)
return None
@classmethod @classmethod
def determine_variants(cls, exes, version_str): def determine_variants(cls, exes, version_str):
languages, compilers = set(), {} compilers = cls.determine_compiler_paths(exes=exes)
# There are often at least two copies (not symlinks) of each compiler executable in the
# same directory: one with a canonical name, e.g. "gfortran", and another one with the languages = set()
# target prefix, e.g. "x86_64-pc-linux-gnu-gfortran". There also might be a copy of "gcc" translation = {"cxx": "c++"}
# with the version suffix, e.g. "x86_64-pc-linux-gnu-gcc-6.3.0". To ensure the consistency for lang, compiler in compilers.items():
# of values in the "compilers" dictionary (i.e. we prefer all of them to reference copies languages.add(translation.get(lang, lang))
# with canonical names if possible), we iterate over the executables in the reversed sorted
# order:
for exe in sorted(exes, reverse=True):
basename = os.path.basename(exe)
if "g++" in basename:
languages.add("c++")
compilers["cxx"] = exe
elif "gfortran" in basename:
languages.add("fortran")
compilers["fortran"] = exe
elif "gcc" in basename:
languages.add("c")
compilers["c"] = exe
elif "gccgo" in basename:
languages.add("go")
compilers["go"] = exe
elif "gdc" in basename:
languages.add("d")
compilers["d"] = exe
variant_str = "languages={0}".format(",".join(languages)) variant_str = "languages={0}".format(",".join(languages))
return variant_str, {"compilers": compilers} return variant_str, {"compilers": compilers}

View file

@ -0,0 +1,89 @@
paths:
- layout:
- executables:
- "bin/intel64/icc"
script: |
echo "icc (ICC) 18.0.5 20180823"
echo "Copyright (C) 1985-2018 Intel Corporation. All rights reserved."
- executables:
- "bin/intel64/icpc"
script: |
echo "icpc (ICC) 18.0.5 20180823"
echo "Copyright (C) 1985-2018 Intel Corporation. All rights reserved."
- executables:
- "bin/intel64/ifort"
script: |
echo "ifort (IFORT) 18.0.5 20180823"
echo "Copyright (C) 1985-2018 Intel Corporation. All rights reserved."
platforms: [linux]
results:
- spec: 'intel-oneapi-compilers-classic@18.0.5'
extra_attributes:
compilers:
c: ".*/bin/intel64/icc"
cxx: ".*/bin/intel64/icpc"
fortran: ".*/bin/intel64/ifort"
- layout:
- executables:
- "bin/icc"
script: |
echo "icc (ICC) 18.0.5 20180823"
echo "Copyright (C) 1985-2018 Intel Corporation. All rights reserved."
- executables:
- "bin/icpc"
script: |
echo "icpc (ICC) 18.0.5 20180823"
echo "Copyright (C) 1985-2018 Intel Corporation. All rights reserved."
- executables:
- "bin/ifort"
script: |
echo "ifort (IFORT) 18.0.5 20180823"
echo "Copyright (C) 1985-2018 Intel Corporation. All rights reserved."
platforms: [linux]
results:
- spec: 'intel-oneapi-compilers-classic@18.0.5'
extra_attributes:
compilers:
c: ".*/bin/icc"
cxx: ".*/bin/icpc"
fortran: ".*/bin/ifort"
- layout:
- executables:
- "compiler/18.0.5/linux/bin/intel64/icc"
script: |
echo "icc (ICC) 18.0.5 20180823"
echo "Copyright (C) 1985-2018 Intel Corporation. All rights reserved."
- executables:
- "compiler/18.0.5/linux/bin/intel64/icpc"
script: |
echo "icpc (ICC) 18.0.5 20180823"
echo "Copyright (C) 1985-2018 Intel Corporation. All rights reserved."
- executables:
- "compiler/18.0.5/linux/bin/intel64/ifort"
script: |
echo "ifort (IFORT) 18.0.5 20180823"
echo "Copyright (C) 1985-2018 Intel Corporation. All rights reserved."
platforms: [linux]
results:
- spec: 'intel-oneapi-compilers-classic@18.0.5'
extra_attributes:
compilers:
c: ".*compiler/18.0.5/linux/bin/intel64/icc"
cxx: ".*compiler/18.0.5/linux/bin/intel64/icpc"
fortran: ".*compiler/18.0.5/linux/bin/intel64/ifort"
- layout: # oneapi compiler is not detected as classic
- executables:
- "compiler/18.0.5/linux/bin/icx"
- "compiler/18.0.5/linux/bin/icpx"
script: |
echo "Intel(R) oneAPI DPC++ Compiler 2021.2.0 (2021.2.0.20210317)"
echo "Target: x86_64-unknown-linux-gnu"
echo "Thread model: posix"
echo "InstalledDir: /made/up/path",
- executables:
- "compiler/18.0.5/linux/bin/ifx"
script: |
echo "ifx (IFORT) 2021.1.2 Beta 20201214"
echo "Copyright (C) 1985-2020 Intel Corporation. All rights reserved."
platforms: [linux]
results: []

View file

@ -3,14 +3,16 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os import os
import sys
from llnl.util.lang import classproperty
from llnl.util.link_tree import LinkTree from llnl.util.link_tree import LinkTree
from spack.package import * from spack.package import *
@IntelOneApiPackage.update_description @IntelOneApiPackage.update_description
class IntelOneapiCompilersClassic(Package): class IntelOneapiCompilersClassic(Package, CompilerPackage):
"""Relies on intel-oneapi-compilers to install the compilers, and """Relies on intel-oneapi-compilers to install the compilers, and
configures modules for icc/icpc/ifort. configures modules for icc/icpc/ifort.
@ -22,6 +24,23 @@ class IntelOneapiCompilersClassic(Package):
has_code = False has_code = False
compiler_languages = ["c", "cxx", "fortran"]
c_names = ["icc"]
cxx_names = ["icpc"]
fortran_names = ["ifort"]
@classproperty
def compiler_version_argument(self):
if sys.platform == "win32":
return "/QV"
return "--version"
@classproperty
def compiler_version_regex(self):
if sys.platform == "win32":
return r"([1-9][0-9]*\.[0-9]*\.[0-9]*)"
return r"\((?:IFORT|ICC)\) ([^ ]+)"
# Versions before 2021 are in the `intel` package # Versions before 2021 are in the `intel` package
# intel-oneapi versions before 2022 use intel@19.0.4 # intel-oneapi versions before 2022 use intel@19.0.4
for ver, oneapi_ver in { for ver, oneapi_ver in {

View file

@ -0,0 +1,23 @@
paths:
- layout:
- executables:
- "compiler/2021.2.0/linux/bin/icx"
- "compiler/2021.2.0/linux/bin/icpx"
script: |
echo "Intel(R) oneAPI DPC++ Compiler 2021.2.0 (2021.2.0.20210317)"
echo "Target: x86_64-unknown-linux-gnu"
echo "Thread model: posix"
echo "InstalledDir: /made/up/path",
- executables:
- "compiler/2021.2.0/linux/bin/ifx"
script: |
echo "ifx (IFORT) 2021.2.0 Beta 20201214"
echo "Copyright (C) 1985-2020 Intel Corporation. All rights reserved."
platforms: [linux]
results:
- spec: intel-oneapi-compilers@2021.2.0
extra_attributes:
compilers:
c: ".*/compiler/2021.2.0/linux/bin/icx"
cxx: ".*/compiler/2021.2.0/linux/bin/icpx"
fortran: ".*/compiler/2021.2.0/linux/bin/ifx"

View file

@ -222,13 +222,22 @@
@IntelOneApiPackage.update_description @IntelOneApiPackage.update_description
class IntelOneapiCompilers(IntelOneApiPackage): class IntelOneapiCompilers(IntelOneApiPackage, CompilerPackage):
"""Intel oneAPI Compilers. Includes: icc, icpc, ifort, icx, icpx, and ifx.""" """Intel oneAPI Compilers. Includes: icc, icpc, ifort, icx, icpx, and ifx."""
maintainers("rscohn2") maintainers("rscohn2")
homepage = "https://software.intel.com/content/www/us/en/develop/tools/oneapi.html" homepage = "https://software.intel.com/content/www/us/en/develop/tools/oneapi.html"
compiler_languages = ["c", "cxx", "fortran"]
c_names = ["icx"]
cxx_names = ["icpx"]
fortran_names = ["ifx"]
compiler_version_argument = "--version"
compiler_version_regex = (
r"(?:(?:oneAPI DPC\+\+(?:\/C\+\+)? Compiler)|(?:\(IFORT\))|(?:\(IFX\))) (\S+)"
)
# See https://github.com/spack/spack/issues/39252 # See https://github.com/spack/spack/issues/39252
depends_on("patchelf@:0.17", type="build") depends_on("patchelf@:0.17", type="build")

View file

@ -18,3 +18,8 @@ paths:
platforms: ["darwin", "linux"] platforms: ["darwin", "linux"]
results: results:
- spec: 'intel@18.0.5' - spec: 'intel@18.0.5'
extra_attributes:
compilers:
c: ".*/bin/intel64/icc"
cxx: ".*/bin/intel64/icpc"
fortran: ".*/bin/intel64/ifort"

View file

@ -0,0 +1,103 @@
paths:
- layout:
- executables:
- "bin/amdclang"
- "bin/amdclang++"
script: |
echo "AMD clang version 17.0.0 (https://github.com/RadeonOpenCompute/llvm-project roc-5.7.1 23382 f3e174a1d286158c06e4cc8276366b1d4bc0c914)"
echo "Target: x86_64-unknown-linux-gnu"
echo "Thread model: posix"
echo "InstalledDir: /opt/rocm-5.7.1/llvm/bin"
echo "Configuration file: /opt/rocm-5.7.1/llvm/bin/clang.cfg"
- executables:
- "bin/amdflang"
script: |
echo "AMD flang-classic version 17.0.0 (https://github.com/RadeonOpenCompute/llvm-project roc-5.7.1 23382 f3e174a1d286158c06e4cc8276366b1d4bc0c914)"
echo "Target: x86_64-unknown-linux-gnu"
echo "Thread model: posix"
echo "InstalledDir: /opt/rocm-5.7.1/llvm/bin"
platforms: [linux]
results:
- spec: llvm-amdgpu@5.7.1
extra_attributes:
compilers:
c: ".*/bin/amdclang"
cxx: ".*/bin/amdclang[+][+]"
fortran: ".*/bin/amdflang"
- layout:
- executables:
- "bin/amdclang"
- "bin/amdclang++"
script: |
echo "AMD clang version 17.0.0 (https://github.com/RadeonOpenCompute/llvm-project roc-5.7.1 23382 f3e174a1d286158c06e4cc8276366b1d4bc0c914)"
echo "Target: x86_64-unknown-linux-gnu"
echo "Thread model: posix"
echo "InstalledDir: /opt/rocm-5.7.1/llvm/bin"
echo "Configuration file: /opt/rocm-5.7.1/llvm/bin/clang.cfg"
platforms: [linux]
results:
- spec: llvm-amdgpu@5.7.1
extra_attributes:
compilers:
c: ".*/bin/amdclang"
cxx: ".*/bin/amdclang[+][+]"
- layout:
- executables:
- "bin/amdclang"
- "bin/amdclang++"
script: |
echo "AMD clang version 17.0.0 (https://github.com/RadeonOpenCompute/llvm-project roc-5.7.1 23382 f3e174a1d286158c06e4cc8276366b1d4bc0c914)"
echo "Target: x86_64-unknown-linux-gnu"
echo "Thread model: posix"
echo "InstalledDir: /opt/rocm-5.7.1/llvm/bin"
echo "Configuration file: /opt/rocm-5.7.1/llvm/bin/clang.cfg"
- executables:
- "bin/amdflang"
script: |
echo "AMD flang-classic version 17.0.0 (https://github.com/RadeonOpenCompute/llvm-project roc-5.7.1 23382 f3e174a1d286158c06e4cc8276366b1d4bc0c914)"
echo "Target: x86_64-unknown-linux-gnu"
echo "Thread model: posix"
echo "InstalledDir: /opt/rocm-5.7.1/llvm/bin"
- executables:
- "bin/amdclang-6"
- "bin/amdclang++-6"
script: |
echo "AMD clang version 17.0.0 (https://github.com/RadeonOpenCompute/llvm-project roc-6.0.2 24012 af27734ed982b52a9f1be0f035ac91726fc697e4)"
echo "Target: x86_64-unknown-linux-gnu"
echo "Thread model: posix"
echo "InstalledDir: /opt/rocm-6.0.2/llvm/bin"
echo "Configuration file: /opt/rocm-6.0.2/llvm/bin/clang.cfg"
- executables:
- "bin/amdflang-6"
script: |
echo "AMD flang-classic version 17.0.0 (https://github.com/RadeonOpenCompute/llvm-project roc-6.0.2 24012 af27734ed982b52a9f1be0f035ac91726fc697e4)"
echo "Target: x86_64-unknown-linux-gnu"
echo "Thread model: posix"
echo "InstalledDir: /opt/rocm-6.0.2/llvm/bin"
platforms: [linux]
results:
- spec: llvm-amdgpu@6.0.2
extra_attributes:
compilers:
c: ".*/bin/amdclang-6$"
cxx: ".*/bin/amdclang[+][+]-6$"
fortran: ".*/bin/amdflang-6$"
- spec: llvm-amdgpu@5.7.1
extra_attributes:
compilers:
c: ".*/bin/amdclang"
cxx: ".*/bin/amdclang[+][+]"
fortran: ".*/bin/amdflang"
- layout: # does not detect upstream clang
- executables:
- "bin/clang"
- "bin/clang++"
script: |
echo "clang version 8.0.0 (tags/RELEASE_800/final"
echo "Target: x86_64-unknown-linux-gnu\n"
echo "Thread model: posix\n"
echo "InstalledDir: /usr/bin"
platforms: [linux]
results: []

View file

@ -2,15 +2,12 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details. # Spack Project Developers. See the top-level COPYRIGHT file for details.
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os import os
import re
from spack.package import * from spack.package import *
class LlvmAmdgpu(CMakePackage): class LlvmAmdgpu(CMakePackage, CompilerPackage):
"""Toolkit for the construction of highly optimized compilers, """Toolkit for the construction of highly optimized compilers,
optimizers, and run-time environments.""" optimizers, and run-time environments."""
@ -247,18 +244,12 @@ def cmake_args(self):
args.append("-DSANITIZER_AMDGPU:Bool=ON") args.append("-DSANITIZER_AMDGPU:Bool=ON")
return args return args
@classmethod compiler_languages = ["c", "cxx", "fortran"]
def determine_version(cls, path): c_names = ["amdclang"]
match = re.search(r"amdclang", path) cxx_names = ["amdclang++"]
detected_version = None fortran_names = ["amdflang"]
if match: compiler_version_argument = "--version"
version_query = Executable(path)("--version", output=str) compiler_version_regex = r"roc-(\d+[._]\d+[._]\d+)"
match = re.search(r"roc-(\d)\.(\d).(\d)", version_query)
if match:
detected_version = "{0}.{1}.{2}".format(
int(match.group(1)), int(match.group(2)), int(match.group(3))
)
return detected_version
# Make sure that the compiler paths are in the LD_LIBRARY_PATH # Make sure that the compiler paths are in the LD_LIBRARY_PATH
def setup_run_environment(self, env): def setup_run_environment(self, env):

View file

@ -17,6 +17,11 @@ paths:
platforms: ["darwin", "linux"] platforms: ["darwin", "linux"]
results: results:
- spec: 'llvm@3.9.1 +clang~lld~lldb' - spec: 'llvm@3.9.1 +clang~lld~lldb'
extra_attributes:
compilers:
c: ".*/bin/clang-3.9$"
cxx: ".*/bin/clang[+][+]-3.9$"
# Multiple LLVM packages in the same prefix # Multiple LLVM packages in the same prefix
- layout: - layout:
- executables: - executables:
@ -44,7 +49,18 @@ paths:
platforms: ["darwin", "linux"] platforms: ["darwin", "linux"]
results: results:
- spec: 'llvm@8.0.0+clang+lld+lldb' - spec: 'llvm@8.0.0+clang+lld+lldb'
extra_attributes:
compilers:
c: ".*/bin/clang-8$"
cxx: ".*/bin/clang[+][+]-8$"
ld: ".*/bin/ld.lld-8$"
- spec: 'llvm@3.9.1+clang~lld~lldb' - spec: 'llvm@3.9.1+clang~lld~lldb'
extra_attributes:
compilers:
c: ".*/bin/clang-3.9$"
cxx: ".*/bin/clang[+][+]-3.9$"
# Apple Clang should not be detected # Apple Clang should not be detected
- layout: - layout:
- executables: - executables:

View file

@ -8,13 +8,14 @@
import sys import sys
import llnl.util.tty as tty import llnl.util.tty as tty
from llnl.util.lang import classproperty
import spack.build_environment import spack.build_environment
import spack.util.executable import spack.util.executable
from spack.package import * from spack.package import *
class Llvm(CMakePackage, CudaPackage): class Llvm(CMakePackage, CudaPackage, CompilerPackage):
"""The LLVM Project is a collection of modular and reusable compiler and """The LLVM Project is a collection of modular and reusable compiler and
toolchain technologies. Despite its name, LLVM has little to do toolchain technologies. Despite its name, LLVM has little to do
with traditional virtual machines, though it does provide helpful with traditional virtual machines, though it does provide helpful
@ -28,7 +29,7 @@ class Llvm(CMakePackage, CudaPackage):
git = "https://github.com/llvm/llvm-project" git = "https://github.com/llvm/llvm-project"
maintainers("trws", "haampie", "skosukhin") maintainers("trws", "haampie", "skosukhin")
tags = ["e4s"] tags = ["e4s", "compiler"]
generator("ninja") generator("ninja")
@ -594,11 +595,36 @@ def patch(self):
string=True, string=True,
) )
# The functions and attributes below implement external package compiler_version_regex = (
# detection for LLVM. See: # Normal clang compiler versions are left as-is
# r"clang version ([^ )\n]+)-svn[~.\w\d-]*|"
# https://spack.readthedocs.io/en/latest/packaging_guide.html#making-a-package-discoverable-with-spack-external-find # Don't include hyphenated patch numbers in the version
executables = ["clang", "flang", "ld.lld", "lldb"] # (see https://github.com/spack/spack/pull/14365 for details)
r"clang version ([^ )\n]+?)-[~.\w\d-]*|"
r"clang version ([^ )\n]+)|"
# LLDB
r"lldb version ([^ )\n]+)|"
# LLD
r"LLD ([^ )\n]+) \(compatible with GNU linkers\)"
)
compiler_version_argument = "--version"
compiler_languages = ["c", "cxx", "fortran"]
c_names = ["clang"]
cxx_names = ["clang++"]
fortran_names = ["flang"]
@property
def supported_languages(self):
languages = []
if self.spec.satisfies("+clang"):
languages.extend(["c", "cxx"])
if self.spec.satisfies("+flang"):
languages.append("fortran")
return languages
@classproperty
def executables(cls):
return super().executables + ["ld.lld", "lldb"]
@classmethod @classmethod
def filter_detected_exes(cls, prefix, exes_in_prefix): def filter_detected_exes(cls, prefix, exes_in_prefix):
@ -615,26 +641,14 @@ def filter_detected_exes(cls, prefix, exes_in_prefix):
@classmethod @classmethod
def determine_version(cls, exe): def determine_version(cls, exe):
version_regex = re.compile(
# Normal clang compiler versions are left as-is
r"clang version ([^ )\n]+)-svn[~.\w\d-]*|"
# Don't include hyphenated patch numbers in the version
# (see https://github.com/spack/spack/pull/14365 for details)
r"clang version ([^ )\n]+?)-[~.\w\d-]*|"
r"clang version ([^ )\n]+)|"
# LLDB
r"lldb version ([^ )\n]+)|"
# LLD
r"LLD ([^ )\n]+) \(compatible with GNU linkers\)"
)
try: try:
compiler = Executable(exe) compiler = Executable(exe)
output = compiler("--version", output=str, error=str) output = compiler(cls.compiler_version_argument, output=str, error=str)
if "Apple" in output: if "Apple" in output:
return None return None
if "AMD" in output: if "AMD" in output:
return None return None
match = version_regex.search(output) match = re.search(cls.compiler_version_regex, output)
if match: if match:
return match.group(match.lastindex) return match.group(match.lastindex)
except spack.util.executable.ProcessError: except spack.util.executable.ProcessError:
@ -646,21 +660,23 @@ def determine_version(cls, exe):
@classmethod @classmethod
def determine_variants(cls, exes, version_str): def determine_variants(cls, exes, version_str):
# Do not need to reuse more general logic from CompilerPackage
# because LLVM has kindly named compilers
variants, compilers = ["+clang"], {} variants, compilers = ["+clang"], {}
lld_found, lldb_found = False, False lld_found, lldb_found = False, False
for exe in exes: for exe in exes:
if "clang++" in exe: name = os.path.basename(exe)
if "clang++" in name:
compilers["cxx"] = exe compilers["cxx"] = exe
elif "clang" in exe: elif "clang" in name:
compilers["c"] = exe compilers["c"] = exe
elif "flang" in exe: elif "flang" in name:
variants.append("+flang") variants.append("+flang")
compilers["fc"] = exe compilers["fortran"] = exe
compilers["f77"] = exe elif "ld.lld" in name:
elif "ld.lld" in exe:
lld_found = True lld_found = True
compilers["ld"] = exe compilers["ld"] = exe
elif "lldb" in exe: elif "lldb" in name:
lldb_found = True lldb_found = True
compilers["lldb"] = exe compilers["lldb"] = exe

View file

@ -0,0 +1,14 @@
paths:
- layout:
- executables:
- cl.bat
script: |
echo "Microsoft (R) C/C++ Optimizing Compiler Version 19.04.54321 for x86"
platforms: [windows]
results:
- spec: msvc@19.04.54321
extra_attributes:
compilers:
c: ".*cl.bat$"
cxx: ".*cl.bat"

View file

@ -0,0 +1,66 @@
# Copyright 2013-2024 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 Msvc(Package, CompilerPackage):
"""
Microsoft Visual C++ is a compiler for the C, C++, C++/CLI and C++/CX programming languages.
"""
homepage = "https://visualstudio.microsoft.com/vs/features/cplusplus/"
def install(self, spec, prefix):
raise InstallError(
"MSVC compilers are not installable with Spack, but can be "
"detected on a system where they are externally installed"
)
compiler_languages = ["c", "cxx"]
c_names = ["cl"]
cxx_names = ["cl"]
compiler_version_argument = ""
compiler_version_regex = r"([1-9][0-9]*\.[0-9]*\.[0-9]*)"
@classmethod
def determine_version(cls, exe):
# MSVC compiler does not have a proper version argument
# Errors out and prints version info with no args
match = re.search(
cls.compiler_version_regex,
spack.compiler.get_compiler_version_output(exe, version_arg=None, ignore_errors=True),
)
if match:
return match.group(1)
@classmethod
def determine_variants(cls, exes, version_str):
# MSVC uses same executable for both languages
spec, extras = super().determine_variants(exes, version_str)
extras["compilers"]["c"] = extras["compilers"]["cxx"]
return spec, extras
@property
def cc(self):
if self.spec.external:
return self.spec.extra_attributes["compilers"]["c"]
msg = "cannot retrieve C compiler [spec is not concrete]"
assert self.spec.concrete, msg
@property
def cxx(self):
if self.spec.external:
return self.spec.extra_attributes["compilers"]["cxx"]
msg = "cannot retrieve C++ compiler [spec is not concrete]"
assert self.spec.concrete, msg
@property
def fortran(self):
if self.spec.external:
return self.spec.extra_attributes["compilers"]["fortran"]
msg = "cannot retrieve Fortran compiler [spec is not concrete]"
assert self.spec.concrete, msg

View file

@ -0,0 +1,13 @@
paths:
- layout:
- executables:
- bin/nagfor
script: |
echo "NAG Fortran Compiler Release 6.0(Hibiya) Build 1037"
echo "Product NPL6A60NA for x86-64 Linux"
platforms: [linux]
results:
- spec: nag@6.0.1037
extra_attributes:
compilers:
fortran: ".*/bin/nagfor"

View file

@ -3,15 +3,11 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os import os
import re
import llnl.util.tty as tty
import spack.compiler
from spack.package import * from spack.package import *
class Nag(Package): class Nag(Package, CompilerPackage):
"""The NAG Fortran Compiler.""" """The NAG Fortran Compiler."""
homepage = "https://www.nag.com/nagware/np.asp" homepage = "https://www.nag.com/nagware/np.asp"
@ -64,54 +60,10 @@ def setup_run_environment(self, env):
env.set("F77", self.prefix.bin.nagfor) env.set("F77", self.prefix.bin.nagfor)
env.set("FC", self.prefix.bin.nagfor) env.set("FC", self.prefix.bin.nagfor)
executables = ["^nagfor$"] compiler_languages = ["fortran"]
fortran_names = ["nagfor"]
@classmethod compiler_version_regex = r"NAG Fortran Compiler Release (\d+).(\d+)\(.*\) Build (\d+)"
def determine_version(cls, exe): compiler_version_argument = "-V"
version_regex = re.compile(r"NAG Fortran Compiler Release ([0-9.]+)")
# NAG does not support a flag that would enable verbose output and
# compilation/linking at the same time (with either '-#' or '-dryrun'
# the compiler only prints the commands but does not run them).
# Therefore, the only thing we can do is to pass the '-v' argument to
# the underlying GCC. In order to get verbose output from the latter
# at both compile and linking stages, we need to call NAG with two
# additional flags: '-Wc,-v' and '-Wl,-v'. However, we return only
# '-Wl,-v' for the following reasons:
# 1) the interface of this method does not support multiple flags in
# the return value and, at least currently, verbose output at the
# linking stage has a higher priority for us;
# 2) NAG is usually mixed with GCC compiler, which also accepts
# '-Wl,-v' and produces meaningful result with it: '-v' is passed
# to the linker and the latter produces verbose output for the
# linking stage ('-Wc,-v', however, would break the compilation
# with a message from GCC that the flag is not recognized).
#
# This way, we at least enable the implicit rpath detection, which is
# based on compilation of a C file (see method
# spack.compiler._get_compiler_link_paths): in the case of a mixed
# NAG/GCC toolchain, the flag will be passed to g++ (e.g.
# 'g++ -Wl,-v ./main.c'), otherwise, the flag will be passed to nagfor
# (e.g. 'nagfor -Wl,-v ./main.c' - note that nagfor recognizes '.c'
# extension and treats the file accordingly). The list of detected
# rpaths will contain only GCC-related directories and rpaths to
# NAG-related directories are injected by nagfor anyway.
try:
output = spack.compiler.get_compiler_version_output(exe, "-Wl,-v")
match = version_regex.search(output)
if match:
return match.group(1)
except spack.util.executable.ProcessError:
pass
except Exception as e:
tty.debug(e)
@classmethod
def determine_variants(cls, exes, version_str):
compilers = {}
for exe in exes:
if "nagfor" in exe:
compilers["fortran"] = exe
return "", {"compilers": compilers}
@property @property
def fortran(self): def fortran(self):

View file

@ -0,0 +1,82 @@
paths:
- layout:
- executables:
- bin/nvc
script: |
echo "nvc 20.9-0 LLVM 64-bit target on x86-64 Linux -tp haswell"
echo "NVIDIA Compilers and Tools"
echo "Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved."
- executables:
- bin/nvc++
script: |
echo "nvc++ 20.9-0 LLVM 64-bit target on x86-64 Linux -tp haswell"
echo "NVIDIA Compilers and Tools"
echo "Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved."
- executables:
- bin/nvfortran
script: |
echo "nvfortran 20.9-0 LLVM 64-bit target on x86-64 Linux -tp haswell"
echo "NVIDIA Compilers and Tools"
echo "Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved."
platforms: [linux]
results:
- spec: nvhpc@20.9~blas~lapack~mpi
extra_attributes:
compilers:
c: ".*/bin/nvc"
cxx: ".*/bin/nvc++"
fortran: ".*/bin/nvfortran"
- layout:
- executables:
- bin/nvc
script: |
echo "nvc 20.9-0 linuxpower target on Linuxpower"
echo "NVIDIA Compilers and Tools"
echo "Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved."
- executables:
- bin/nvc++
script: |
echo "nvc++ 20.9-0 linuxpower target on Linuxpower"
echo "NVIDIA Compilers and Tools"
echo "Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved."
- executables:
- bin/nvfortran
script: |
echo "nvfortran 20.9-0 linuxpower target on Linuxpower"
echo "NVIDIA Compilers and Tools"
echo "Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved."
platforms: [linux]
results:
- spec: nvhpc@20.9~blas~lapack~mpi
extra_attributes:
compilers:
c: ".*/bin/nvc"
cxx: ".*/bin/nvc++"
fortran: ".*/bin/nvfortran"
- layout:
- executables:
- bin/nvc
script: |
echo "nvc 20.9-0 linuxarm64 target on aarch64 Linux"
echo "NVIDIA Compilers and Tools"
echo "Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved."
- executables:
- bin/nvc++
script: |
echo "nvc++ 20.9-0 linuxarm64 target on aarch64 Linux"
echo "NVIDIA Compilers and Tools"
echo "Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved."
- executables:
- bin/nvfortran
script: |
echo "nvfortran 20.9-0 linuxarm64 target on aarch64 Linux"
echo "NVIDIA Compilers and Tools"
echo "Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved."
platforms: [linux]
results:
- spec: nvhpc@20.9~blas~lapack~mpi
extra_attributes:
compilers:
c: ".*/bin/nvc"
cxx: ".*/bin/nvc++"
fortran: ".*/bin/nvfortran"

View file

@ -370,7 +370,7 @@
} }
class Nvhpc(Package): class Nvhpc(Package, CompilerPackage):
"""The NVIDIA HPC SDK is a comprehensive suite of compilers, libraries """The NVIDIA HPC SDK is a comprehensive suite of compilers, libraries
and tools essential to maximizing developer productivity and the and tools essential to maximizing developer productivity and the
performance and portability of HPC applications. The NVIDIA HPC performance and portability of HPC applications. The NVIDIA HPC
@ -419,6 +419,20 @@ class Nvhpc(Package):
requires("%gcc", msg="nvhpc must be installed with %gcc") requires("%gcc", msg="nvhpc must be installed with %gcc")
# For now we only detect compiler components
# It will require additional work to detect mpi/lapack/blas components
compiler_languages = ["c", "cxx", "fortran"]
c_names = ["nvc"]
cxx_names = ["nvc++"]
fortran_names = ["nvfortran"]
compiler_version_argument = "--version"
compiler_version_regex = r"nv[^ ]* (?:[^ ]+ Dev-r)?([0-9.]+)(?:-[0-9]+)?"
@classmethod
def determine_variants(cls, exes, version_str):
# TODO: use other exes to determine default_cuda/install_type/blas/lapack/mpi variants
return "~blas~lapack~mpi", {"compilers": cls.determine_compiler_paths(exes=exes)}
def _version_prefix(self): def _version_prefix(self):
return join_path(self.prefix, "Linux_%s" % self.spec.target.family, self.version) return join_path(self.prefix, "Linux_%s" % self.spec.target.family, self.version)

View file

@ -0,0 +1,11 @@
paths:
- layout:
- executables:
- bin/pgcc
script: |
echo "pgcc 15.10-0 64-bit target on x86-64 Linux -tp sandybridge"
echo "The Portland Group - PGI Compilers and Tools"
echo "Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved."
platforms: [linux]
results:
- spec: pgi@15.10

View file

@ -9,7 +9,7 @@
from spack.util.prefix import Prefix from spack.util.prefix import Prefix
class Pgi(Package): class Pgi(Package, CompilerPackage):
"""PGI optimizing multi-core x64 compilers for Linux, MacOS & Windows """PGI optimizing multi-core x64 compilers for Linux, MacOS & Windows
with support for debugging and profiling of local MPI processes. with support for debugging and profiling of local MPI processes.
@ -58,6 +58,13 @@ def url_for_version(self, version):
os.getcwd(), version.up_to(1), version.joined os.getcwd(), version.up_to(1), version.joined
) )
compiler_languages = ["c", "cxx", "fortran"]
c_names = ["pgcc"]
cxx_names = ["pgc++", "pgCC"]
fortran_names = ["pgfortran"] # older names long deprecated
compiler_version_argument = "-V"
compiler_version_regex = r"pg[^ ]* ([0-9.]+)-[0-9]+ (?:LLVM )?[^ ]+ target on "
def install(self, spec, prefix): def install(self, spec, prefix):
# Enable the silent installation feature # Enable the silent installation feature
os.environ["PGI_SILENT"] = "true" os.environ["PGI_SILENT"] = "true"

View file

@ -0,0 +1,31 @@
paths:
- layout:
- executables:
- "bin/xlc"
- "bin/xlc++"
- "bin/xlc_r"
- "bin/xlc++_r"
script: |
echo "IBM XL C/C++ for Linux, V16.1.1 (5725-C73, 5765-J13)"
echo "Version: 16.01.0001.0006"
- executables:
- "bin/xlf"
- "bin/xlf_r"
- "bin/xlcuf"
script: |
echo "IBM XL Fortran for Linux, V16.1.1 (5725-C73, 5765-J13)"
echo "Version: 16.01.0001.0006"
platforms: ["linux"]
results:
- spec: "xl~r@16.1"
extra_attributes:
compilers:
c: ".*/bin/xlc"
cxx: ".*/bin/xlc[+][+]"
fortran: ".*/bin/xlf"
- spec: "xl+r@16.1"
extra_attributes:
compilers:
c: ".*/bin/xlc_r"
cxx: ".*/bin/xlc[+][+]_r"
fortran: ".*/bin/xlf_r"

View file

@ -0,0 +1,65 @@
# Copyright 2013-2024 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)
from spack.package import *
class Xl(Package, CompilerPackage):
"""IBM XL C/C++/Fortran is an advanced, high-performance compiler that can be
used for developing complex, computationally intensive programs, including
interlanguage calls with C and Fortran programs.
"""
homepage = "https://www.ibm.com/support/knowledgecenter/SSXVZZ_16.1.1/com.ibm.compilers.linux.doc/welcome.html"
variant("r", default=True, description="The _r version of compilers")
def install(self, spec, prefix):
raise InstallError(
"XL compilers are not installable yet, but can be "
"detected on a system where they are supplied by vendor"
)
compiler_languages = ["c", "cxx", "fortran"]
c_names = ["xlc", "xlc_r"]
cxx_names = ["xlc++", "xlC", "xlc++_r", "xlC_r"]
fortran_names = ["xlf", "xlf_r"] # TODO complete this
compiler_version_argument = "-qversion"
compiler_version_regex = r"([0-9]?[0-9]\.[0-9])"
@classmethod
def determine_variants(cls, exes, version_str):
_r_exes = [e for e in exes if "_r" in e]
_exes = [e for e in exes if "_r" not in e]
_r_compilers = cls.determine_compiler_paths(exes=_r_exes) if _r_exes else None
_compilers = cls.determine_compiler_paths(exes=_exes) if _exes else None
results = []
if _r_compilers:
results.append(("+r", {"compilers": _r_compilers}))
if _compilers:
results.append(("~r", {"compilers": _compilers}))
return results
@property
def cc(self):
if self.spec.external:
return self.spec.extra_attributes["compilers"]["c"]
msg = "cannot retrieve C compiler [spec is not concrete]"
assert self.spec.concrete, msg
@property
def cxx(self):
if self.spec.external:
return self.spec.extra_attributes["compilers"]["cxx"]
msg = "cannot retrieve C++ compiler [spec is not concrete]"
assert self.spec.concrete, msg
@property
def fortran(self):
if self.spec.external:
return self.spec.extra_attributes["compilers"]["fortran"]
msg = "cannot retrieve Fortran compiler [spec is not concrete]"
assert self.spec.concrete, msg

View file

@ -1,19 +0,0 @@
paths:
- layout:
- executables:
- "bin/xlc"
- "bin/xlc++"
- "bin/xlc_r"
- "bin/xlc++_r"
script: |
echo "IBM XL C/C++ for Linux, V16.1.1 (5725-C73, 5765-J13)"
echo "Version: 16.01.0001.0006"
- executables:
- "bin/xlcuf"
script: |
echo "IBM XL Fortran for Linux, V16.1.1 (5725-C73, 5765-J13)"
echo "Version: 16.01.0001.0006"
platforms: ["linux"]
results:
- spec: "xlc+r@16.1"
- spec: "xlc~r@16.1"

View file

@ -1,81 +0,0 @@
# Copyright 2013-2024 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 collections
import re
import llnl.util.tty as tty
import spack.compiler
from spack.package import *
class Xlc(Package):
"""IBM XL C/C++ is an advanced, high-performance compiler that can be
used for developing complex, computationally intensive programs, including
interlanguage calls with C and Fortran programs.
"""
homepage = "https://www.ibm.com/support/knowledgecenter/SSXVZZ_16.1.1/com.ibm.compilers.linux.doc/welcome.html"
variant("r", default=True, description="The _r version of compilers")
def install(self, spec, prefix):
raise InstallError(
"XL compilers are not installable yet, but can be "
"detected on a system where they are supplied by vendor"
)
executables = [r"xlc", r"xlC", r"xlc\+\+"]
@classmethod
def determine_version(cls, exe):
version_regex = re.compile(r"([0-9]?[0-9]\.[0-9])")
try:
output = spack.compiler.get_compiler_version_output(exe, "-qversion")
# Exclude spurious Fortran compilers
if "Fortran" in output:
return None
match = version_regex.search(output)
if match:
return match.group(1)
except spack.util.executable.ProcessError:
pass
except Exception as e:
tty.debug(str(e))
@classmethod
def determine_variants(cls, exes, version_str):
variants = collections.defaultdict(dict)
for exe in exes:
# Determine the variant of the spec
variant_str = "+r" if "_r" in exe else "~r"
if "xlc++" in exe:
variants[variant_str]["cxx"] = exe
continue
if "xlc" in exe:
variants[variant_str]["c"] = exe
continue
results = []
for variant_str, compilers in variants.items():
results.append((variant_str, {"compilers": compilers}))
return results
@property
def cc(self):
if self.spec.external:
return self.spec.extra_attributes["compilers"]["c"]
msg = "cannot retrieve C compiler [spec is not concrete]"
assert self.spec.concrete, msg
@property
def cxx(self):
if self.spec.external:
return self.spec.extra_attributes["compilers"]["cxx"]
msg = "cannot retrieve C compiler [spec is not concrete]"
assert self.spec.concrete, msg

View file

@ -1,12 +0,0 @@
paths:
- layout:
- executables:
- "bin/xlf"
- "bin/xlf_r"
script: |
echo "IBM XL Fortran for Linux, V16.1.1 (5725-C73, 5765-J13)"
echo "Version: 16.01.0001.0006"
platforms: ["linux"]
results:
- spec: "xlf+r@16.1"
- spec: "xlf~r@16.1"

View file

@ -1,69 +0,0 @@
# Copyright 2013-2024 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 collections
import os.path
import re
import llnl.util.tty as tty
import spack.compiler
from spack.package import *
class Xlf(Package):
"""IBM XL Fortran is an advanced, high-performance compiler that can be
used for developing complex, computationally intensive programs, including
interlanguage calls with C and Fortran programs.
"""
homepage = "https://www.ibm.com/support/knowledgecenter/SSXVZZ_16.1.1/com.ibm.compilers.linux.doc/welcome.html"
variant("r", default=True, description="The _r version of compilers")
def install(self, spec, prefix):
raise InstallError(
"XL compilers are not installable yet, but can be "
"detected on a system where they are supplied by vendor"
)
executables = [r"xlf"]
@classmethod
def determine_version(cls, exe):
version_regex = re.compile(r"([0-9]?[0-9]\.[0-9])")
try:
output = spack.compiler.get_compiler_version_output(exe, "-qversion")
match = version_regex.search(output)
if match:
return match.group(1)
except spack.util.executable.ProcessError:
pass
except Exception as e:
tty.debug(e)
@classmethod
def determine_variants(cls, exes, version_str):
variants = collections.defaultdict(dict)
for exe in exes:
if os.path.basename(exe) == "xlf":
variants["~r"]["fortran"] = exe
continue
if os.path.basename(exe) == "xlf_r":
variants["+r"]["fortran"] = exe
continue
results = []
for variant_str, compilers in variants.items():
results.append((variant_str, {"compilers": compilers}))
return results
@property
def fortran(self):
if self.spec.external:
return self.spec.extra_attributes["compilers"]["fortran"]
msg = "cannot retrieve C compiler [spec is not concrete]"
assert self.spec.concrete, msg