Source code for spack.compilers.adaptor

# Copyright Spack Project Developers. See COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import enum
from typing import Dict, List

import spack.spec
from spack.llnl.util import lang

from .libraries import CompilerPropertyDetector


[docs] class Languages(enum.Enum): C = "c" CXX = "cxx" FORTRAN = "fortran"
[docs] class CompilerAdaptor: """Provides access to compiler attributes via ``Package.compiler``. Useful for packages which do not yet access compiler properties via ``self.spec[language]``. """ def __init__( self, compiled_spec: spack.spec.Spec, compilers: Dict[Languages, spack.spec.Spec] ) -> None: if not compilers: raise AttributeError(f"{compiled_spec} has no 'compiler' attribute") self.compilers = compilers self.compiled_spec = compiled_spec def _lang_exists_or_raise(self, name: str, *, lang: Languages) -> None: if lang not in self.compilers: raise AttributeError( f"'{self.compiled_spec}' has no {lang.value} compiler, so the " f"'{name}' property cannot be retrieved" ) def _maybe_return_attribute(self, name: str, *, lang: Languages) -> str: self._lang_exists_or_raise(name, lang=lang) return getattr(self.compilers[lang].package, name) @property def cc_rpath_arg(self) -> str: self._lang_exists_or_raise("cc_rpath_arg", lang=Languages.C) return self.compilers[Languages.C].package.rpath_arg @property def cxx_rpath_arg(self) -> str: self._lang_exists_or_raise("cxx_rpath_arg", lang=Languages.CXX) return self.compilers[Languages.CXX].package.rpath_arg @property def fc_rpath_arg(self) -> str: self._lang_exists_or_raise("fc_rpath_arg", lang=Languages.FORTRAN) return self.compilers[Languages.FORTRAN].package.rpath_arg @property def f77_rpath_arg(self) -> str: self._lang_exists_or_raise("f77_rpath_arg", lang=Languages.FORTRAN) return self.compilers[Languages.FORTRAN].package.rpath_arg @property def linker_arg(self) -> str: return self._maybe_return_attribute("linker_arg", lang=Languages.C) @property def name(self): return next(iter(self.compilers.values())).name @property def version(self): return next(iter(self.compilers.values())).version
[docs] def implicit_rpaths(self) -> List[str]: result, seen = [], set() for compiler in self.compilers.values(): if compiler in seen: continue seen.add(compiler) result.extend(CompilerPropertyDetector(compiler).implicit_rpaths()) return result
@property def opt_flags(self) -> List[str]: return next(iter(self.compilers.values())).package.opt_flags @property def debug_flags(self) -> List[str]: return next(iter(self.compilers.values())).package.debug_flags @property def openmp_flag(self) -> str: return next(iter(self.compilers.values())).package.openmp_flag @property def cxx98_flag(self) -> str: return self.compilers[Languages.CXX].package.standard_flag( language=Languages.CXX.value, standard="98" ) @property def cxx11_flag(self) -> str: return self.compilers[Languages.CXX].package.standard_flag( language=Languages.CXX.value, standard="11" ) @property def cxx14_flag(self) -> str: return self.compilers[Languages.CXX].package.standard_flag( language=Languages.CXX.value, standard="14" ) @property def cxx17_flag(self) -> str: return self.compilers[Languages.CXX].package.standard_flag( language=Languages.CXX.value, standard="17" ) @property def cxx20_flag(self) -> str: return self.compilers[Languages.CXX].package.standard_flag( language=Languages.CXX.value, standard="20" ) @property def cxx23_flag(self) -> str: return self.compilers[Languages.CXX].package.standard_flag( language=Languages.CXX.value, standard="23" ) @property def c99_flag(self) -> str: return self.compilers[Languages.C].package.standard_flag( language=Languages.C.value, standard="99" ) @property def c11_flag(self) -> str: return self.compilers[Languages.C].package.standard_flag( language=Languages.C.value, standard="11" ) @property def c17_flag(self) -> str: return self.compilers[Languages.C].package.standard_flag( language=Languages.C.value, standard="17" ) @property def c23_flag(self) -> str: return self.compilers[Languages.C].package.standard_flag( language=Languages.C.value, standard="23" ) @property def cc_pic_flag(self) -> str: self._lang_exists_or_raise("cc_pic_flag", lang=Languages.C) return self.compilers[Languages.C].package.pic_flag @property def cxx_pic_flag(self) -> str: self._lang_exists_or_raise("cxx_pic_flag", lang=Languages.CXX) return self.compilers[Languages.CXX].package.pic_flag @property def fc_pic_flag(self) -> str: self._lang_exists_or_raise("fc_pic_flag", lang=Languages.FORTRAN) return self.compilers[Languages.FORTRAN].package.pic_flag @property def f77_pic_flag(self) -> str: self._lang_exists_or_raise("f77_pic_flag", lang=Languages.FORTRAN) return self.compilers[Languages.FORTRAN].package.pic_flag @property def prefix(self) -> str: return next(iter(self.compilers.values())).prefix @property def extra_rpaths(self) -> List[str]: compiler = next(iter(self.compilers.values())) return getattr(compiler, "extra_attributes", {}).get("extra_rpaths", []) @property def cc(self): return self._maybe_return_attribute("cc", lang=Languages.C) @property def cxx(self): return self._maybe_return_attribute("cxx", lang=Languages.CXX) @property def fc(self): self._lang_exists_or_raise("fc", lang=Languages.FORTRAN) return self.compilers[Languages.FORTRAN].package.fortran @property def f77(self): self._lang_exists_or_raise("f77", lang=Languages.FORTRAN) return self.compilers[Languages.FORTRAN].package.fortran @property def stdcxx_libs(self): return self._maybe_return_attribute("stdcxx_libs", lang=Languages.CXX)
[docs] class DeprecatedCompiler(lang.DeprecatedProperty): def __init__(self) -> None: super().__init__(name="compiler")
[docs] def factory(self, instance, owner) -> CompilerAdaptor: spec = instance.spec if not spec.concrete: raise ValueError("Can only get a compiler for a concrete package.") compilers = {} for language in Languages: deps = spec.dependencies(virtuals=[language.value]) if deps: compilers[language] = deps[0] return CompilerAdaptor(instance, compilers)