mdoules/external_project: fix most of the mypy warnings/errors

pull/9347/head
Dylan Baker 3 years ago
parent 0f9ec8bc88
commit f228e0244b
  1. 64
      mesonbuild/modules/unstable_external_project.py

@ -18,7 +18,7 @@ import shlex
import subprocess import subprocess
import typing as T import typing as T
from . import ExtensionModule, ModuleReturnValue, ModuleState, NewExtensionModule from . import ExtensionModule, ModuleReturnValue, NewExtensionModule
from .. import mlog, build from .. import mlog, build
from ..compilers.compilers import CFLAGS_MAPPING, CEXE_MAPPING from ..compilers.compilers import CFLAGS_MAPPING, CEXE_MAPPING
from ..dependencies import InternalDependency, PkgConfigDependency from ..dependencies import InternalDependency, PkgConfigDependency
@ -27,9 +27,15 @@ from ..interpreterbase import permittedKwargs, typed_pos_args
from ..mesonlib import (EnvironmentException, MesonException, Popen_safe, MachineChoice, from ..mesonlib import (EnvironmentException, MesonException, Popen_safe, MachineChoice,
get_variable_regex, do_replacement, extract_as_list, join_args, OptionKey) get_variable_regex, do_replacement, extract_as_list, join_args, OptionKey)
if T.TYPE_CHECKING:
from . import ModuleState
from ..interpreter import Interpreter
from ..interpreterbase import TYPE_var
class ExternalProject(NewExtensionModule): class ExternalProject(NewExtensionModule):
def __init__(self, def __init__(self,
state: ModuleState, state: 'ModuleState',
configure_command: str, configure_command: str,
configure_options: T.List[str], configure_options: T.List[str],
cross_configure_options: T.List[str], cross_configure_options: T.List[str],
@ -54,9 +60,15 @@ class ExternalProject(NewExtensionModule):
self.src_dir = Path(self.env.get_source_dir(), self.subdir) self.src_dir = Path(self.env.get_source_dir(), self.subdir)
self.build_dir = Path(self.env.get_build_dir(), self.subdir, 'build') self.build_dir = Path(self.env.get_build_dir(), self.subdir, 'build')
self.install_dir = Path(self.env.get_build_dir(), self.subdir, 'dist') self.install_dir = Path(self.env.get_build_dir(), self.subdir, 'dist')
self.prefix = Path(self.env.coredata.get_option(OptionKey('prefix'))) _p = self.env.coredata.get_option(OptionKey('prefix'))
self.libdir = Path(self.env.coredata.get_option(OptionKey('libdir'))) assert isinstance(_p, str), 'for mypy'
self.includedir = Path(self.env.coredata.get_option(OptionKey('includedir'))) self.prefix = Path(_p)
_l = self.env.coredata.get_option(OptionKey('libdir'))
assert isinstance(_l, str), 'for mypy'
self.libdir = Path(_l)
_i = self.env.coredata.get_option(OptionKey('includedir'))
assert isinstance(_i, str), 'for mypy'
self.includedir = Path(_i)
self.name = self.src_dir.name self.name = self.src_dir.name
# On Windows if the prefix is "c:/foo" and DESTDIR is "c:/bar", `make` # On Windows if the prefix is "c:/foo" and DESTDIR is "c:/bar", `make`
@ -72,7 +84,7 @@ class ExternalProject(NewExtensionModule):
self.targets = self._create_targets() self.targets = self._create_targets()
def _configure(self, state: ModuleState) -> None: def _configure(self, state: 'ModuleState') -> None:
if self.configure_command == 'waf': if self.configure_command == 'waf':
FeatureNew('Waf external project', '0.60.0').use(self.subproject) FeatureNew('Waf external project', '0.60.0').use(self.subproject)
waf = state.find_program('waf') waf = state.find_program('waf')
@ -105,18 +117,21 @@ class ExternalProject(NewExtensionModule):
configure_cmd += self._format_options(self.cross_configure_options, d) configure_cmd += self._format_options(self.cross_configure_options, d)
# Set common env variables like CFLAGS, CC, etc. # Set common env variables like CFLAGS, CC, etc.
link_exelist = [] link_exelist: T.List[str] = []
link_args = [] link_args: T.List[str] = []
self.run_env = os.environ.copy() self.run_env = os.environ.copy()
for lang, compiler in self.env.coredata.compilers[MachineChoice.HOST].items(): for lang, compiler in self.env.coredata.compilers[MachineChoice.HOST].items():
if any(lang not in i for i in (CEXE_MAPPING, CFLAGS_MAPPING)): if any(lang not in i for i in (CEXE_MAPPING, CFLAGS_MAPPING)):
continue continue
cargs = self.env.coredata.get_external_args(MachineChoice.HOST, lang) cargs = self.env.coredata.get_external_args(MachineChoice.HOST, lang)
assert isinstance(cargs, list), 'for mypy'
self.run_env[CEXE_MAPPING[lang]] = self._quote_and_join(compiler.get_exelist()) self.run_env[CEXE_MAPPING[lang]] = self._quote_and_join(compiler.get_exelist())
self.run_env[CFLAGS_MAPPING[lang]] = self._quote_and_join(cargs) self.run_env[CFLAGS_MAPPING[lang]] = self._quote_and_join(cargs)
if not link_exelist: if not link_exelist:
link_exelist = compiler.get_linker_exelist() link_exelist = compiler.get_linker_exelist()
link_args = self.env.coredata.get_external_link_args(MachineChoice.HOST, lang) _l = self.env.coredata.get_external_link_args(MachineChoice.HOST, lang)
assert isinstance(_l, list), 'for mypy'
link_args = _l
if link_exelist: if link_exelist:
# FIXME: Do not pass linker because Meson uses CC as linker wrapper, # FIXME: Do not pass linker because Meson uses CC as linker wrapper,
# but autotools often expects the real linker (e.h. GNU ld). # but autotools often expects the real linker (e.h. GNU ld).
@ -135,7 +150,7 @@ class ExternalProject(NewExtensionModule):
def _quote_and_join(self, array: T.List[str]) -> str: def _quote_and_join(self, array: T.List[str]) -> str:
return ' '.join([shlex.quote(i) for i in array]) return ' '.join([shlex.quote(i) for i in array])
def _validate_configure_options(self, variables: T.List[T.Tuple[str, str, str]]): def _validate_configure_options(self, variables: T.List[T.Tuple[str, str, str]]) -> None:
# Ensure the user at least try to pass basic info to the build system, # Ensure the user at least try to pass basic info to the build system,
# like the prefix, libdir, etc. # like the prefix, libdir, etc.
for key, default, val in variables: for key, default, val in variables:
@ -150,10 +165,10 @@ class ExternalProject(NewExtensionModule):
self.configure_options.append(default) self.configure_options.append(default)
def _format_options(self, options: T.List[str], variables: T.List[T.Tuple[str, str, str]]) -> T.List[str]: def _format_options(self, options: T.List[str], variables: T.List[T.Tuple[str, str, str]]) -> T.List[str]:
out = [] out: T.List[str] = []
missing = set() missing = set()
regex = get_variable_regex('meson') regex = get_variable_regex('meson')
confdata = {k: (v, None) for k, d, v in variables} confdata: T.Dict[str, T.Tuple[str, T.Optional[str]]] = {k: (v, None) for k, _, v in variables}
for o in options: for o in options:
arg, missing_vars = do_replacement(regex, o, 'meson', confdata) arg, missing_vars = do_replacement(regex, o, 'meson', confdata)
missing.update(missing_vars) missing.update(missing_vars)
@ -164,7 +179,7 @@ class ExternalProject(NewExtensionModule):
f"Variables {var_list} in configure options are missing.") f"Variables {var_list} in configure options are missing.")
return out return out
def _run(self, step: str, command: T.List[str], workdir: Path): def _run(self, step: str, command: T.List[str], workdir: Path) -> None:
mlog.log(f'External project {self.name}:', mlog.bold(step)) mlog.log(f'External project {self.name}:', mlog.bold(step))
m = 'Running command ' + str(command) + ' in directory ' + str(workdir) + '\n' m = 'Running command ' + str(command) + ' in directory ' + str(workdir) + '\n'
log_filename = Path(mlog.log_dir, f'{self.name}-{step}.log') log_filename = Path(mlog.log_dir, f'{self.name}-{step}.log')
@ -175,7 +190,7 @@ class ExternalProject(NewExtensionModule):
output.flush() output.flush()
else: else:
mlog.log(m) mlog.log(m)
p, o, e = Popen_safe(command, cwd=str(workdir), env=self.run_env, p, *_ = Popen_safe(command, cwd=str(workdir), env=self.run_env,
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
stdout=output) stdout=output)
if p.returncode != 0: if p.returncode != 0:
@ -184,7 +199,7 @@ class ExternalProject(NewExtensionModule):
m += '\nSee logs: ' + str(log_filename) m += '\nSee logs: ' + str(log_filename)
raise MesonException(m) raise MesonException(m)
def _create_targets(self): def _create_targets(self) -> T.List['TYPE_var']:
cmd = self.env.get_build_command() cmd = self.env.get_build_command()
cmd += ['--internal', 'externalproject', cmd += ['--internal', 'externalproject',
'--name', self.name, '--name', self.name,
@ -220,7 +235,7 @@ class ExternalProject(NewExtensionModule):
@permittedKwargs({'subdir'}) @permittedKwargs({'subdir'})
@typed_pos_args('external_project.dependency', str) @typed_pos_args('external_project.dependency', str)
def dependency_method(self, state, args: T.Tuple[str], kwargs): def dependency_method(self, state: 'ModuleState', args: T.Tuple[str], kwargs) -> InternalDependency:
libname = args[0] libname = args[0]
subdir = kwargs.get('subdir', '') subdir = kwargs.get('subdir', '')
@ -234,29 +249,24 @@ class ExternalProject(NewExtensionModule):
abs_libdir = Path(self.install_dir, self.rel_prefix, self.libdir) abs_libdir = Path(self.install_dir, self.rel_prefix, self.libdir)
version = self.project_version version = self.project_version
incdir = []
compile_args = [f'-I{abs_includedir}'] compile_args = [f'-I{abs_includedir}']
link_args = [f'-L{abs_libdir}', f'-l{libname}'] link_args = [f'-L{abs_libdir}', f'-l{libname}']
libs = []
libs_whole = []
sources = self.target sources = self.target
final_deps = [] dep = InternalDependency(version, [], compile_args, link_args, [],
variables = {} [], [sources], [], {})
dep = InternalDependency(version, incdir, compile_args, link_args, libs,
libs_whole, sources, final_deps, variables)
return dep return dep
class ExternalProjectModule(ExtensionModule): class ExternalProjectModule(ExtensionModule):
@FeatureNew('External build system Module', '0.56.0') @FeatureNew('External build system Module', '0.56.0')
def __init__(self, interpreter): def __init__(self, interpreter: 'Interpreter'):
super().__init__(interpreter) super().__init__(interpreter)
self.methods.update({'add_project': self.add_project, self.methods.update({'add_project': self.add_project,
}) })
@permittedKwargs({'configure_options', 'cross_configure_options', 'verbose', 'env'}) @permittedKwargs({'configure_options', 'cross_configure_options', 'verbose', 'env'})
@typed_pos_args('external_project_mod.add_project', str) @typed_pos_args('external_project_mod.add_project', str)
def add_project(self, state: ModuleState, args: T.Tuple[str], kwargs: T.Dict[str, T.Any]): def add_project(self, state: 'ModuleState', args: T.Tuple[str], kwargs: T.Dict[str, T.Any]) -> ModuleReturnValue:
configure_command = args[0] configure_command = args[0]
configure_options = extract_as_list(kwargs, 'configure_options') configure_options = extract_as_list(kwargs, 'configure_options')
cross_configure_options = extract_as_list(kwargs, 'cross_configure_options') cross_configure_options = extract_as_list(kwargs, 'cross_configure_options')
@ -272,5 +282,5 @@ class ExternalProjectModule(ExtensionModule):
return ModuleReturnValue(project, project.targets) return ModuleReturnValue(project, project.targets)
def initialize(*args, **kwargs): def initialize(interp: 'Interpreter') -> ExternalProjectModule:
return ExternalProjectModule(*args, **kwargs) return ExternalProjectModule(interp)

Loading…
Cancel
Save