diff --git a/lib/spack/spack/compilers/adaptor.py b/lib/spack/spack/compilers/adaptor.py index ad4a9d75819..ad9a929d342 100644 --- a/lib/spack/spack/compilers/adaptor.py +++ b/lib/spack/spack/compilers/adaptor.py @@ -2,15 +2,13 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) import enum -import typing from typing import Dict, List from llnl.util import lang -from .libraries import CompilerPropertyDetector +import spack.spec -if typing.TYPE_CHECKING: - import spack.spec +from .libraries import CompilerPropertyDetector class Languages(enum.Enum): @@ -21,7 +19,7 @@ class Languages(enum.Enum): class CompilerAdaptor: def __init__( - self, compiled_spec: "spack.spec.Spec", compilers: Dict[Languages, "spack.spec.Spec"] + 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") diff --git a/lib/spack/spack/compilers/config.py b/lib/spack/spack/compilers/config.py index 6568cdded02..ef6695c06b4 100644 --- a/lib/spack/spack/compilers/config.py +++ b/lib/spack/spack/compilers/config.py @@ -53,7 +53,7 @@ def compiler_config_files(): def add_compiler_to_config(new_compilers, *, scope=None) -> None: """Add a Compiler object to the configuration, at the required scope.""" - by_name: Dict[str, List["spack.spec.Spec"]] = {} + by_name: Dict[str, List[spack.spec.Spec]] = {} for x in new_compilers: by_name.setdefault(x.name, []).append(x) @@ -65,7 +65,7 @@ def find_compilers( *, scope: Optional[str] = None, max_workers: Optional[int] = None, -) -> List["spack.spec.Spec"]: +) -> List[spack.spec.Spec]: """Searches for compiler in the paths given as argument. If any new compiler is found, the configuration is updated, and the list of new compiler objects is returned. @@ -93,8 +93,8 @@ def find_compilers( def select_new_compilers( - candidates: List["spack.spec.Spec"], *, scope: Optional[str] = None -) -> List["spack.spec.Spec"]: + candidates: List[spack.spec.Spec], *, scope: Optional[str] = None +) -> List[spack.spec.Spec]: """Given a list of compilers, remove those that are already defined in the configuration. """ @@ -107,9 +107,7 @@ def supported_compilers() -> List[str]: return sorted(spack.repo.PATH.packages_with_tags(COMPILER_TAG)) -def all_compilers( - scope: Optional[str] = None, init_config: bool = True -) -> List["spack.spec.Spec"]: +def all_compilers(scope: Optional[str] = None, init_config: bool = True) -> List[spack.spec.Spec]: """Returns all the compilers from the current global configuration. Args: @@ -127,7 +125,7 @@ def all_compilers( def _init_packages_yaml( - configuration: "spack.config.ConfigurationType", *, scope: Optional[str] + configuration: spack.config.ConfigurationType, *, scope: Optional[str] ) -> None: # Try importing from compilers.yaml legacy_compilers = CompilerFactory.from_compilers_yaml(configuration, scope=scope) @@ -153,8 +151,8 @@ def _init_packages_yaml( def all_compilers_from( - configuration: "spack.config.ConfigurationType", scope: Optional[str] = None -) -> List["spack.spec.Spec"]: + configuration: spack.config.ConfigurationType, scope: Optional[str] = None +) -> List[spack.spec.Spec]: """Returns all the compilers from the current global configuration. Args: @@ -169,13 +167,11 @@ def all_compilers_from( class CompilerRemover: """Removes compiler from configuration.""" - def __init__(self, configuration: "spack.config.ConfigurationType") -> None: + def __init__(self, configuration: spack.config.ConfigurationType) -> None: self.configuration = configuration self.marked_packages_yaml: List[Tuple[str, Any]] = [] - def mark_compilers( - self, *, match: str, scope: Optional[str] = None - ) -> List["spack.spec.Spec"]: + def mark_compilers(self, *, match: str, scope: Optional[str] = None) -> List[spack.spec.Spec]: """Marks compilers to be removed in configuration, and returns a corresponding list of specs. @@ -238,8 +234,8 @@ def flush(self): def compilers_for_arch( - arch_spec: "spack.spec.ArchSpec", *, scope: Optional[str] = None -) -> List["spack.spec.Spec"]: + arch_spec: spack.spec.ArchSpec, *, scope: Optional[str] = None +) -> List[spack.spec.Spec]: """Returns the compilers that can be used on the input architecture""" compilers = all_compilers_from(spack.config.CONFIG, scope=scope) query = f"platform={arch_spec.platform} target=:{arch_spec.target}" @@ -252,7 +248,7 @@ def compilers_for_arch( _CXX_KEY, _FORTRAN_KEY = "cxx", "fortran" -def name_os_target(spec: "spack.spec.Spec") -> Tuple[str, str, str]: +def name_os_target(spec: spack.spec.Spec) -> Tuple[str, str, str]: if not spec.architecture: host_platform = spack.platforms.host() operating_system = host_platform.operating_system("default_os") @@ -274,13 +270,13 @@ def name_os_target(spec: "spack.spec.Spec") -> Tuple[str, str, str]: class CompilerFactory: """Class aggregating all ways of constructing a list of compiler specs from config entries.""" - _PACKAGES_YAML_CACHE: Dict[str, Optional["spack.spec.Spec"]] = {} + _PACKAGES_YAML_CACHE: Dict[str, Optional[spack.spec.Spec]] = {} _GENERIC_TARGET = None @staticmethod def from_packages_yaml( - configuration: "spack.config.ConfigurationType", *, scope: Optional[str] = None - ) -> List["spack.spec.Spec"]: + configuration: spack.config.ConfigurationType, *, scope: Optional[str] = None + ) -> List[spack.spec.Spec]: """Returns the compiler specs defined in the "packages" section of the configuration""" compilers = [] compiler_package_names = supported_compilers() @@ -309,7 +305,7 @@ def from_packages_yaml( return compilers @staticmethod - def from_external_yaml(config: Dict[str, Any]) -> Optional["spack.spec.Spec"]: + def from_external_yaml(config: Dict[str, Any]) -> Optional[spack.spec.Spec]: """Returns a compiler spec from an external definition from packages.yaml.""" # Allow `@x.y.z` instead of `@=x.y.z` err_header = f"The external spec '{config['spec']}' cannot be used as a compiler" @@ -341,7 +337,7 @@ def _finalize_external_concretization(abstract_spec): abstract_spec._finalize_concretization() @staticmethod - def from_legacy_yaml(compiler_dict: Dict[str, Any]) -> List["spack.spec.Spec"]: + def from_legacy_yaml(compiler_dict: Dict[str, Any]) -> List[spack.spec.Spec]: """Returns a list of external specs, corresponding to a compiler entry from compilers.yaml. """ @@ -368,10 +364,10 @@ def from_legacy_yaml(compiler_dict: Dict[str, Any]) -> List["spack.spec.Spec"]: @staticmethod def from_compilers_yaml( - configuration: "spack.config.ConfigurationType", *, scope: Optional[str] = None - ) -> List["spack.spec.Spec"]: + configuration: spack.config.ConfigurationType, *, scope: Optional[str] = None + ) -> List[spack.spec.Spec]: """Returns the compiler specs defined in the "compilers" section of the configuration""" - result: List["spack.spec.Spec"] = [] + result: List[spack.spec.Spec] = [] for item in configuration.get("compilers", scope=scope): result.extend(CompilerFactory.from_legacy_yaml(item["compiler"])) return result diff --git a/lib/spack/spack/compilers/libraries.py b/lib/spack/spack/compilers/libraries.py index c625407360e..f70e4d2bfc7 100644 --- a/lib/spack/spack/compilers/libraries.py +++ b/lib/spack/spack/compilers/libraries.py @@ -10,7 +10,6 @@ import stat import sys import tempfile -import typing from typing import Dict, List, Optional, Set, Tuple import llnl.path @@ -19,15 +18,14 @@ from llnl.util.filesystem import path_contains_subdirectory, paths_containing_libs import spack.caches +import spack.schema.environment +import spack.spec import spack.util.executable import spack.util.libc +import spack.util.module_cmd from spack.util.environment import filter_system_paths from spack.util.file_cache import FileCache -if typing.TYPE_CHECKING: - import spack.spec - - #: regex for parsing linker lines _LINKER_LINE = re.compile(r"^( *|.*[/\\])" r"(link|ld|([^/\\]+-)?ld|collect2)" r"[^/\\]*( |$)") @@ -141,7 +139,7 @@ def _parse_link_paths(string): class CompilerPropertyDetector: - def __init__(self, compiler_spec: "spack.spec.Spec"): + def __init__(self, compiler_spec: spack.spec.Spec): assert compiler_spec.concrete, "only concrete compiler specs are allowed" self.spec = compiler_spec self.cache = COMPILER_CACHE @@ -149,8 +147,6 @@ def __init__(self, compiler_spec: "spack.spec.Spec"): @contextlib.contextmanager def compiler_environment(self): """Sets the environment to run this compiler""" - import spack.schema.environment - import spack.util.module_cmd # No modifications for Spack managed compilers if not self.spec.external: @@ -234,7 +230,7 @@ def default_dynamic_linker(self) -> Optional[str]: return spack.util.libc.parse_dynamic_linker(output) - def default_libc(self) -> Optional["spack.spec.Spec"]: + def default_libc(self) -> Optional[spack.spec.Spec]: """Determine libc targeted by the compiler from link line""" # technically this should be testing the target platform of the compiler, but we don't have # that, so stick to host platform for now. @@ -301,7 +297,7 @@ def __call__(self, dirs: List[str]) -> List[str]: return [p for p in dirs if not self.is_dynamic_loader_default_path(p)] -def dynamic_linker_filter_for(node: "spack.spec.Spec") -> Optional[DefaultDynamicLinkerFilter]: +def dynamic_linker_filter_for(node: spack.spec.Spec) -> Optional[DefaultDynamicLinkerFilter]: compiler = compiler_spec(node) if compiler is None: return None @@ -312,7 +308,7 @@ def dynamic_linker_filter_for(node: "spack.spec.Spec") -> Optional[DefaultDynami return DefaultDynamicLinkerFilter(dynamic_linker) -def compiler_spec(node: "spack.spec.Spec") -> Optional["spack.spec.Spec"]: +def compiler_spec(node: spack.spec.Spec) -> Optional[spack.spec.Spec]: """Returns the compiler spec associated with the node passed as argument. The function looks for a "c", "cxx", and "fortran" compiler in that order, @@ -355,10 +351,10 @@ def from_dict(cls, data: Dict[str, Optional[str]]): class CompilerCache: """Base class for compiler output cache. Default implementation does not cache anything.""" - def value(self, compiler: "spack.spec.Spec") -> Dict[str, Optional[str]]: + def value(self, compiler: spack.spec.Spec) -> Dict[str, Optional[str]]: return {"c_compiler_output": CompilerPropertyDetector(compiler)._compile_dummy_c_source()} - def get(self, compiler: "spack.spec.Spec") -> CompilerCacheEntry: + def get(self, compiler: spack.spec.Spec) -> CompilerCacheEntry: return CompilerCacheEntry.from_dict(self.value(compiler)) @@ -383,7 +379,7 @@ def _get_entry(self, key: str, *, allow_empty: bool) -> Optional[CompilerCacheEn pass return None - def get(self, compiler: "spack.spec.Spec") -> CompilerCacheEntry: + def get(self, compiler: spack.spec.Spec) -> CompilerCacheEntry: # Cache hit try: with self.cache.read_transaction(self.name) as f: @@ -419,7 +415,7 @@ def get(self, compiler: "spack.spec.Spec") -> CompilerCacheEntry: return entry - def _key(self, compiler: "spack.spec.Spec") -> str: + def _key(self, compiler: spack.spec.Spec) -> str: as_bytes = json.dumps(compiler.to_dict(), separators=(",", ":")).encode("utf-8") return hashlib.sha256(as_bytes).hexdigest()