diff options
-rw-r--r-- | mesonbuild/compilers/__init__.py | 2 | ||||
-rw-r--r-- | mesonbuild/dependencies/cuda.py | 58 | ||||
-rw-r--r-- | mesonbuild/mesonlib/universal.py | 2 | ||||
-rwxr-xr-x | run_mypy.py | 1 |
4 files changed, 40 insertions, 23 deletions
diff --git a/mesonbuild/compilers/__init__.py b/mesonbuild/compilers/__init__.py index bda6086..60cfdfe 100644 --- a/mesonbuild/compilers/__init__.py +++ b/mesonbuild/compilers/__init__.py @@ -106,6 +106,7 @@ __all__ = [ 'VisualStudioLikeCompiler', 'VisualStudioCCompiler', 'VisualStudioCPPCompiler', + 'CLikeCompiler', ] # Bring symbols from each module into compilers sub-package namespace @@ -211,3 +212,4 @@ from .mixins.visualstudio import VisualStudioLikeCompiler from .mixins.gnu import GnuCompiler, GnuLikeCompiler from .mixins.intel import IntelGnuLikeCompiler, IntelVisualStudioLikeCompiler from .mixins.clang import ClangCompiler +from .mixins.clike import CLikeCompiler diff --git a/mesonbuild/dependencies/cuda.py b/mesonbuild/dependencies/cuda.py index a8325ff..bea4793 100644 --- a/mesonbuild/dependencies/cuda.py +++ b/mesonbuild/dependencies/cuda.py @@ -24,18 +24,24 @@ from ..environment import detect_cpu_family from .base import (DependencyException, ExternalDependency) +if T.TYPE_CHECKING: + from ..environment import Environment + from ..compilers import Compiler + +TV_ResultTuple = T.Tuple[T.Optional[str], T.Optional[str], bool] class CudaDependency(ExternalDependency): supported_languages = ['cuda', 'cpp', 'c'] # see also _default_language - def __init__(self, environment, kwargs): + def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None: compilers = environment.coredata.compilers[self.get_for_machine_from_kwargs(kwargs)] language = self._detect_language(compilers) if language not in self.supported_languages: raise DependencyException(f'Language \'{language}\' is not supported by the CUDA Toolkit. Supported languages are {self.supported_languages}.') super().__init__('cuda', environment, kwargs, language=language) + self.lib_modules: T.Dict[str, T.List[str]] = {} self.requested_modules = self.get_requested(kwargs) if 'cudart' not in self.requested_modules: self.requested_modules = ['cudart'] + self.requested_modules @@ -63,13 +69,13 @@ class CudaDependency(ExternalDependency): self.is_found = self._find_requested_libraries() @classmethod - def _detect_language(cls, compilers): + def _detect_language(cls, compilers: T.Dict[str, 'Compiler']) -> str: for lang in cls.supported_languages: if lang in compilers: return lang return list(compilers.keys())[0] - def _detect_cuda_path_and_version(self): + def _detect_cuda_path_and_version(self) -> TV_ResultTuple: self.env_var = self._default_path_env_var() mlog.debug('Default path env var:', mlog.bold(self.env_var)) @@ -102,12 +108,13 @@ class CudaDependency(ExternalDependency): msg = f'Please specify the desired CUDA Toolkit version (e.g. dependency(\'cuda\', version : \'>=10.1\')) or {platform_msg} to point to the location of your desired version.' return self._report_dependency_error(msg, (None, None, False)) - def _find_matching_toolkit(self, paths, version_reqs, nvcc_version): + def _find_matching_toolkit(self, paths: T.List[TV_ResultTuple], version_reqs: T.List[str], nvcc_version: T.Optional[str]) -> TV_ResultTuple: # keep the default paths order intact, sort the rest in the descending order # according to the toolkit version - defaults, rest = mesonlib.partition(lambda t: not t[2], paths) - defaults = list(defaults) - paths = defaults + sorted(rest, key=lambda t: mesonlib.Version(t[1]), reverse=True) + part_func: T.Callable[[TV_ResultTuple], bool] = lambda t: not t[2] + defaults_it, rest_it = mesonlib.partition(part_func, paths) + defaults = list(defaults_it) + paths = defaults + sorted(rest_it, key=lambda t: mesonlib.Version(t[1]), reverse=True) mlog.debug(f'Search paths: {paths}') if nvcc_version and defaults: @@ -127,7 +134,7 @@ class CudaDependency(ExternalDependency): mlog.warning(nvcc_warning) return (None, None, False) - def _default_path_env_var(self): + def _default_path_env_var(self) -> T.Optional[str]: env_vars = ['CUDA_PATH'] if self._is_windows() else ['CUDA_PATH', 'CUDA_HOME', 'CUDA_ROOT'] env_vars = [var for var in env_vars if var in os.environ] user_defaults = {os.environ[var] for var in env_vars} @@ -135,15 +142,15 @@ class CudaDependency(ExternalDependency): mlog.warning('Environment variables {} point to conflicting toolkit locations ({}). Toolkit selection might produce unexpected results.'.format(', '.join(env_vars), ', '.join(user_defaults))) return env_vars[0] if env_vars else None - def _cuda_paths(self): + def _cuda_paths(self) -> T.List[T.Tuple[str, bool]]: return ([(os.environ[self.env_var], True)] if self.env_var else []) \ + (self._cuda_paths_win() if self._is_windows() else self._cuda_paths_nix()) - def _cuda_paths_win(self): + def _cuda_paths_win(self) -> T.List[T.Tuple[str, bool]]: env_vars = os.environ.keys() return [(os.environ[var], False) for var in env_vars if var.startswith('CUDA_PATH_')] - def _cuda_paths_nix(self): + def _cuda_paths_nix(self) -> T.List[T.Tuple[str, bool]]: # include /usr/local/cuda default only if no env_var was found pattern = '/usr/local/cuda-*' if self.env_var else '/usr/local/cuda*' return [(path, os.path.basename(path) == 'cuda') for path in glob.iglob(pattern)] @@ -206,10 +213,10 @@ class CudaDependency(ExternalDependency): return None @classmethod - def _strip_patch_version(cls, version): + def _strip_patch_version(cls, version: str) -> str: return '.'.join(version.split('.')[:2]) - def _detect_arch_libdir(self): + def _detect_arch_libdir(self) -> str: arch = detect_cpu_family(self.env.coredata.compilers.host) machine = self.env.machines[self.for_machine] msg = '{} architecture is not supported in {} version of the CUDA Toolkit.' @@ -223,7 +230,7 @@ class CudaDependency(ExternalDependency): if arch not in libdirs: raise DependencyException(msg.format(arch, 'Linux')) return libdirs[arch] - elif machine.is_osx(): + elif machine.is_darwin(): libdirs = {'x86_64': 'lib64'} if arch not in libdirs: raise DependencyException(msg.format(arch, 'macOS')) @@ -231,8 +238,7 @@ class CudaDependency(ExternalDependency): else: raise DependencyException('CUDA Toolkit: unsupported platform.') - def _find_requested_libraries(self): - self.lib_modules = {} + def _find_requested_libraries(self) -> bool: all_found = True for module in self.requested_modules: @@ -246,33 +252,41 @@ class CudaDependency(ExternalDependency): return all_found - def _is_windows(self): + def _is_windows(self) -> bool: return self.env.machines[self.for_machine].is_windows() - def _report_dependency_error(self, msg, ret_val=None): + @T.overload + def _report_dependency_error(self, msg: str) -> None: ... + + @T.overload + def _report_dependency_error(self, msg: str, ret_val: TV_ResultTuple) -> TV_ResultTuple: ... + + def _report_dependency_error(self, msg: str, ret_val: T.Optional[TV_ResultTuple] = None) -> T.Optional[TV_ResultTuple]: if self.required: raise DependencyException(msg) mlog.debug(msg) return ret_val - def log_details(self): + def log_details(self) -> str: module_str = ', '.join(self.requested_modules) return 'modules: ' + module_str - def log_info(self): + def log_info(self) -> str: return self.cuda_path if self.cuda_path else '' - def get_requested(self, kwargs): + def get_requested(self, kwargs: T.Dict[str, T.Any]) -> T.List[str]: candidates = mesonlib.extract_as_list(kwargs, 'modules') for c in candidates: if not isinstance(c, str): raise DependencyException('CUDA module argument is not a string.') return candidates - def get_link_args(self, **kwargs): + def get_link_args(self, language: T.Optional[str] = None, raw: bool = False) -> T.List[str]: args = [] if self.libdir: + from ..compilers import CLikeCompiler + assert isinstance(self.clib_compiler, CLikeCompiler) args += self.clib_compiler.get_linker_search_args(self.libdir) for lib in self.requested_modules: args += self.lib_modules[lib] diff --git a/mesonbuild/mesonlib/universal.py b/mesonbuild/mesonlib/universal.py index b8fc763..08e8b9e 100644 --- a/mesonbuild/mesonlib/universal.py +++ b/mesonbuild/mesonlib/universal.py @@ -1319,7 +1319,7 @@ def expand_arguments(args: T.Iterable[str]) -> T.Optional[T.List[str]]: return expended_args -def partition(pred: T.Callable[[_T], object], iterable: T.Iterator[_T]) -> T.Tuple[T.Iterator[_T], T.Iterator[_T]]: +def partition(pred: T.Callable[[_T], object], iterable: T.Iterable[_T]) -> T.Tuple[T.Iterator[_T], T.Iterator[_T]]: """Use a predicate to partition entries into false entries and true entries. diff --git a/run_mypy.py b/run_mypy.py index 888207c..f1525be 100755 --- a/run_mypy.py +++ b/run_mypy.py @@ -21,6 +21,7 @@ modules = [ 'mesonbuild/dependencies/base.py', 'mesonbuild/dependencies/coarrays.py', 'mesonbuild/dependencies/configtool.py', + 'mesonbuild/dependencies/cuda.py', 'mesonbuild/dependencies/boost.py', 'mesonbuild/dependencies/hdf5.py', 'mesonbuild/dependencies/mpi.py', |