diff --git a/lib/spack/llnl/util/lang.py b/lib/spack/llnl/util/lang.py index 1cd7091aa3e..4c1289118a1 100644 --- a/lib/spack/llnl/util/lang.py +++ b/lib/spack/llnl/util/lang.py @@ -73,7 +73,7 @@ def index_by(objects, *funcs): if isinstance(f, str): f = lambda x: getattr(x, funcs[0]) elif isinstance(f, tuple): - f = lambda x: tuple(getattr(x, p) for p in funcs[0]) + f = lambda x: tuple(getattr(x, p, None) for p in funcs[0]) result = {} for o in objects: diff --git a/lib/spack/spack/ci.py b/lib/spack/spack/ci.py index 6fba4863561..56dbbdc66f3 100644 --- a/lib/spack/spack/ci.py +++ b/lib/spack/spack/ci.py @@ -2137,7 +2137,7 @@ def build_name(self): Returns: (str) current spec's CDash build name.""" spec = self.current_spec if spec: - build_name = f"{spec.name}@{spec.version}%{spec.compiler} \ + build_name = f"{spec.name}@{spec.version} \ hash={spec.dag_hash()} arch={spec.architecture} ({self.build_group})" tty.debug(f"Generated CDash build name ({build_name}) from the {spec.name}") return build_name diff --git a/lib/spack/spack/cmd/__init__.py b/lib/spack/spack/cmd/__init__.py index 368c174c794..7c489cf4b49 100644 --- a/lib/spack/spack/cmd/__init__.py +++ b/lib/spack/spack/cmd/__init__.py @@ -369,8 +369,13 @@ def iter_groups(specs, indent, all_headers): index = index_by(specs, ("architecture", "compiler")) ispace = indent * " " + def _key(item): + if item is None: + return "" + return str(item) + # Traverse the index and print out each package - for i, (architecture, compiler) in enumerate(sorted(index)): + for i, (architecture, compiler) in enumerate(sorted(index, key=_key)): if i > 0: print() @@ -443,7 +448,6 @@ def get_arg(name, default=None): hashes = get_arg("long", False) namespaces = get_arg("namespaces", False) flags = get_arg("show_flags", False) - full_compiler = get_arg("show_full_compiler", False) variants = get_arg("variants", False) groups = get_arg("groups", True) all_headers = get_arg("all_headers", False) @@ -465,10 +469,7 @@ def get_arg(name, default=None): if format_string is None: nfmt = "{fullname}" if namespaces else "{name}" ffmt = "" - if full_compiler or flags: - ffmt += "{%compiler.name}" - if full_compiler: - ffmt += "{@compiler.version}" + if flags: ffmt += " {compiler_flags}" vfmt = "{variants}" if variants else "" format_string = nfmt + "{@version}" + ffmt + vfmt diff --git a/lib/spack/spack/cmd/config.py b/lib/spack/spack/cmd/config.py index aef2d7a5412..a722e88babc 100644 --- a/lib/spack/spack/cmd/config.py +++ b/lib/spack/spack/cmd/config.py @@ -518,8 +518,6 @@ def config_prefer_upstream(args): for spec in pref_specs: # Collect all the upstream compilers and versions for this package. pkg = pkgs.get(spec.name, {"version": []}) - all = pkgs.get("all", {"compiler": []}) - pkgs["all"] = all pkgs[spec.name] = pkg # We have no existing variant if this is our first added version. @@ -529,10 +527,6 @@ def config_prefer_upstream(args): if version not in pkg["version"]: pkg["version"].append(version) - compiler = str(spec.compiler) - if compiler not in all["compiler"]: - all["compiler"].append(compiler) - # Get and list all the variants that differ from the default. variants = [] for var_name, variant in spec.variants.items(): diff --git a/lib/spack/spack/cmd/find.py b/lib/spack/spack/cmd/find.py index b019db4316d..ff2901d1acc 100644 --- a/lib/spack/spack/cmd/find.py +++ b/lib/spack/spack/cmd/find.py @@ -99,7 +99,7 @@ def setup_parser(subparser): "--show-full-compiler", action="store_true", dest="show_full_compiler", - help="(DEPRECATED) show full compiler specs", + help="(DEPRECATED) show full compiler specs. Currently it's a no-op", ) implicit_explicit = subparser.add_mutually_exclusive_group() implicit_explicit.add_argument( @@ -279,7 +279,6 @@ def root_decorator(spec, string): # these enforce details in the root specs to show what the user asked for namespaces=True, show_flags=True, - show_full_compiler=True, decorator=root_decorator, variants=True, ) @@ -302,7 +301,6 @@ def root_decorator(spec, string): decorator=lambda s, f: color.colorize("@*{%s}" % f), namespace=True, show_flags=True, - show_full_compiler=True, variants=True, ) print() diff --git a/lib/spack/spack/package_base.py b/lib/spack/spack/package_base.py index fb6e82cea9b..01c4d87a772 100644 --- a/lib/spack/spack/package_base.py +++ b/lib/spack/spack/package_base.py @@ -32,7 +32,6 @@ from llnl.util.lang import classproperty, memoized from llnl.util.link_tree import LinkTree -import spack.compilers.config import spack.config import spack.dependency import spack.deptypes as dt @@ -1937,17 +1936,14 @@ def _resource_stage(self, resource): return resource_stage_folder def do_test(self, dirty=False, externals=False): - if self.test_requires_compiler: - compilers = spack.compilers.config.compilers_for_spec( - self.spec.compiler, arch_spec=self.spec.architecture + if self.test_requires_compiler and not any( + lang in self.spec for lang in ("c", "cxx", "fortran") + ): + tty.error( + f"Skipping tests for package {self.spec}, since a compiler is required, " + f"but not available" ) - if not compilers: - tty.error( - "Skipping tests for package %s\n" - % self.spec.format("{name}-{version}-{hash:7}") - + "Package test requires missing compiler %s" % self.spec.compiler - ) - return + return kwargs = { "dirty": dirty, diff --git a/lib/spack/spack/report.py b/lib/spack/spack/report.py index 409810f58a9..5aedb837c2e 100644 --- a/lib/spack/spack/report.py +++ b/lib/spack/spack/report.py @@ -78,7 +78,6 @@ def __enter__(self): "packages": [], } spec_record["properties"].append(Property("architecture", input_spec.architecture)) - spec_record["properties"].append(Property("compiler", input_spec.compiler)) self.init_spec_record(input_spec, spec_record) self.specs.append(spec_record) diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py index 5f1a4b8434a..983b7b919a2 100644 --- a/lib/spack/spack/spec.py +++ b/lib/spack/spack/spec.py @@ -82,6 +82,7 @@ import spack.provider_index import spack.repo import spack.solver +import spack.spec import spack.store import spack.traverse as traverse import spack.util.executable @@ -594,7 +595,7 @@ def __contains__(self, string): return string in str(self) or string in self.target def complete_with_defaults(self) -> None: - default_architecture = spack.spec.ArchSpec.default_arch() + default_architecture = ArchSpec.default_arch() if not self.platform: self.platform = default_architecture.platform @@ -667,7 +668,8 @@ def factory(self, instance, owner): deps = instance.dependencies(virtuals=language) if deps: return CompilerSpec(deps[0]) - return CompilerSpec(Spec()) + + raise AttributeError(f"{instance} has no C, C++, or Fortran compiler") @lang.lazy_lexicographic_ordering @@ -1386,13 +1388,13 @@ def tree( class SpecAnnotations: def __init__(self) -> None: self.original_spec_format = SPECFILE_FORMAT_VERSION - self.compiler_node_attribute: Optional["spack.spec.Spec"] = None + self.compiler_node_attribute: Optional["Spec"] = None def with_spec_format(self, spec_format: int) -> "SpecAnnotations": self.original_spec_format = spec_format return self - def with_compiler(self, compiler: "spack.spec.Spec") -> "SpecAnnotations": + def with_compiler(self, compiler: "Spec") -> "SpecAnnotations": self.compiler_node_attribute = compiler return self @@ -2945,7 +2947,7 @@ def _finalize_concretization(self): for spec in self.traverse(): spec._cached_hash(ht.dag_hash) - def concretized(self, tests: Union[bool, Iterable[str]] = False) -> "spack.spec.Spec": + def concretized(self, tests: Union[bool, Iterable[str]] = False) -> "Spec": """This is a non-destructive version of concretize(). First clones, then returns a concrete version of this package @@ -3952,6 +3954,9 @@ def format_attribute(match_object: Match) -> str: try: current = getattr(current, part) except AttributeError: + if part == "compiler": + return "none" + raise SpecFormatStringError( f"Attempted to format attribute {attribute}. " f"Spec {'.'.join(parts[:idx])} has no attribute {part}"