Merge pull request #9167 from dcbaker/submit/meson-main-type-checking

Add type annotations and type checking to meson main
pull/9207/head
Jussi Pakkanen 3 years ago committed by GitHub
commit fee5cb697c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      .pylintrc
  2. 3
      mesonbuild/backend/backends.py
  3. 27
      mesonbuild/build.py
  4. 1
      mesonbuild/cmake/executor.py
  5. 2
      mesonbuild/compilers/cpp.py
  6. 3
      mesonbuild/compilers/d.py
  7. 1
      mesonbuild/environment.py
  8. 12
      mesonbuild/interpreter/interpreter.py
  9. 281
      mesonbuild/interpreter/mesonmain.py
  10. 2
      mesonbuild/mlog.py
  11. 2
      mesonbuild/modules/__init__.py
  12. 16
      mesonbuild/modules/pkgconfig.py
  13. 3
      mesonbuild/modules/qt.py
  14. 2
      mesonbuild/modules/unstable_external_project.py
  15. 5
      mesonbuild/scripts/meson_exe.py
  16. 1
      run_mypy.py

@ -22,6 +22,7 @@ enable=
mixed-indentation,
no-value-for-parameter,
redundant-keyword-arg,
reimported,
singleton-comparison,
superfluous-parens,
too-many-function-args,

@ -1144,7 +1144,8 @@ class Backend:
ifilename = os.path.join(self.environment.get_build_dir(), 'depmf.json')
ofilename = os.path.join(self.environment.get_prefix(), self.build.dep_manifest_name)
out_name = os.path.join('{prefix}', self.build.dep_manifest_name)
mfobj = {'type': 'dependency manifest', 'version': '1.0', 'projects': self.build.dep_manifest}
mfobj = {'type': 'dependency manifest', 'version': '1.0',
'projects': {k: v.to_json() for k, v in self.build.dep_manifest.items()}}
with open(ifilename, 'w', encoding='utf-8') as f:
f.write(json.dumps(mfobj))
# Copy file from, to, and with mode unchanged

@ -33,7 +33,7 @@ from .mesonlib import (
extract_as_list, typeslistify, stringlistify, classify_unity_sources,
get_filenames_templates_dict, substitute_values, has_path_sep,
OptionKey, PerMachineDefaultable,
MesonBugException, FileOrString,
MesonBugException,
)
from .compilers import (
Compiler, is_object, clink_langs, sort_clink, lang_suffixes,
@ -206,6 +206,19 @@ class InstallDir(HoldableObject):
self.install_tag = install_tag
class DepManifest:
def __init__(self, version: str, license: T.List[str]):
self.version = version
self.license = license
def to_json(self) -> T.Dict[str, T.Union[str, T.List[str]]]:
return {
'version': self.version,
'license': self.license,
}
class Build:
"""A class that holds the status of one build including
all dependencies and so on.
@ -230,16 +243,16 @@ class Build:
self.static_linker: PerMachine[StaticLinker] = PerMachine(None, None)
self.subprojects = {}
self.subproject_dir = ''
self.install_scripts = []
self.install_scripts: T.List['ExecutableSerialisation'] = []
self.postconf_scripts: T.List['ExecutableSerialisation'] = []
self.dist_scripts = []
self.dist_scripts: T.List['ExecutableSerialisation'] = []
self.install_dirs: T.List[InstallDir] = []
self.dep_manifest_name = None
self.dep_manifest = {}
self.dep_manifest_name: T.Optional[str] = None
self.dep_manifest: T.Dict[str, DepManifest] = {}
self.stdlibs = PerMachine({}, {})
self.test_setups: T.Dict[str, TestSetup] = {}
self.test_setup_default_name = None
self.find_overrides = {}
self.find_overrides: T.Dict[str, T.Union['Executable', programs.ExternalProgram, programs.OverrideProgram]] = {}
self.searched_programs = set() # The list of all programs that have been searched for.
# If we are doing a cross build we need two caches, if we're doing a
@ -921,7 +934,7 @@ class BuildTarget(Target):
if t in self.kwargs:
self.kwargs[t] = listify(self.kwargs[t], flatten=True)
def extract_objects(self, srclist: T.List[FileOrString]) -> ExtractedObjects:
def extract_objects(self, srclist: T.List['FileOrString']) -> ExtractedObjects:
obj_src: T.List['File'] = []
sources_set = set(self.sources)
for src in srclist:

@ -28,7 +28,6 @@ from ..mesonlib import PerMachine, Popen_safe, version_compare, MachineChoice, i
from ..programs import find_external_program, NonExistingExternalProgram
if T.TYPE_CHECKING:
from ..environment import Environment
from ..programs import ExternalProgram
TYPE_result = T.Tuple[int, T.Optional[str], T.Optional[str]]

@ -47,7 +47,7 @@ if T.TYPE_CHECKING:
from ..environment import Environment
from ..linkers import DynamicLinker
from ..programs import ExternalProgram
from .mixins.clike import CLikeCompiler as CompilerMixinBase
CompilerMixinBase = CLikeCompiler
else:
CompilerMixinBase = object

@ -33,11 +33,12 @@ from .compilers import (
from .mixins.gnu import GnuCompiler
if T.TYPE_CHECKING:
from .compilers import Compiler as CompilerMixinBase
from ..programs import ExternalProgram
from ..envconfig import MachineInfo
from ..environment import Environment
from ..linkers import DynamicLinker
CompilerMixinBase = Compiler
else:
CompilerMixinBase = object

@ -49,7 +49,6 @@ from mesonbuild import envconfig
if T.TYPE_CHECKING:
from configparser import ConfigParser
from .dependencies import ExternalProgram
from .wrap.wrap import Resolver
build_filename = 'meson.build'

@ -73,7 +73,9 @@ import importlib
if T.TYPE_CHECKING:
import argparse
from . import kwargs
from ..programs import OverrideProgram
# Input source types passed to Targets
SourceInputs = T.Union[mesonlib.File, build.GeneratedList, build.BuildTarget, build.BothLibraries,
@ -233,6 +235,7 @@ class Interpreter(InterpreterBase, HoldableObject):
user_defined_options: T.Optional['argparse.Namespace'] = None,
) -> None:
super().__init__(_build.environment.get_source_dir(), subdir, subproject)
self.active_projectname = ''
self.build = _build
self.environment = self.build.environment
self.coredata = self.environment.get_coredata()
@ -1057,8 +1060,7 @@ external dependencies (including libraries) must go to "dependencies".''')
if self.build.project_version is None:
self.build.project_version = self.project_version
proj_license = mesonlib.stringlistify(kwargs.get('license', 'unknown'))
self.build.dep_manifest[proj_name] = {'version': self.project_version,
'license': proj_license}
self.build.dep_manifest[proj_name] = build.DepManifest(self.project_version, proj_license)
if self.subproject in self.build.projects:
raise InvalidCode('Second call to project().')
@ -1342,7 +1344,7 @@ external dependencies (including libraries) must go to "dependencies".''')
if isinstance(name, str):
self.build.searched_programs.add(name)
def add_find_program_override(self, name, exe):
def add_find_program_override(self, name: str, exe: T.Union[build.Executable, ExternalProgram, 'OverrideProgram']) -> None:
if name in self.build.searched_programs:
raise InterpreterException(f'Tried to override finding of executable "{name}" which has already been found.')
if name in self.build.find_overrides:
@ -1435,7 +1437,7 @@ external dependencies (including libraries) must go to "dependencies".''')
@FeatureNewKwargs('find_program', '0.49.0', ['disabler'])
@disablerIfNotFound
@permittedKwargs({'required', 'native', 'version', 'dirs'})
def func_find_program(self, node, args, kwargs):
def func_find_program(self, node, args, kwargs) -> T.Union['build.Executable', ExternalProgram, 'OverrideProgram']:
if not args:
raise InterpreterException('No program name specified.')
@ -2648,7 +2650,7 @@ This will become a hard error in the future.''', location=self.current_node)
if self.subproject != buildtarget.subproject:
raise InterpreterException('Tried to extract objects from a different subproject.')
def is_subproject(self):
def is_subproject(self) -> bool:
return self.subproject != ''
@typed_pos_args('set_variable', str, object)

@ -1,4 +1,9 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2012-2021 The Meson development team
# Copyright © 2021 Intel Corporation
import os
import typing as T
from .. import mesonlib
from .. import dependencies
@ -9,22 +14,33 @@ from ..mesonlib import MachineChoice, OptionKey
from ..programs import OverrideProgram, ExternalProgram
from ..interpreter.type_checking import ENV_KW
from ..interpreterbase import (MesonInterpreterObject, FeatureNew, FeatureDeprecated,
typed_pos_args, permittedKwargs, noArgsFlattening, noPosargs, noKwargs,
typed_pos_args, noArgsFlattening, noPosargs, noKwargs,
typed_kwargs, KwargInfo, MesonVersionString, InterpreterException)
from .interpreterobjects import (ExecutableHolder, ExternalProgramHolder,
CustomTargetHolder, CustomTargetIndexHolder)
from .type_checking import NATIVE_KW, NoneType
import typing as T
if T.TYPE_CHECKING:
from ..backend.backends import ExecutableSerialisation
from ..compilers import Compiler
from ..interpreterbase import TYPE_kwargs, TYPE_var
from .interpreter import Interpreter
from typing_extensions import TypedDict
class FuncOverrideDependency(TypedDict):
native: mesonlib.MachineChoice
static: T.Optional[bool]
class AddInstallScriptKW(TypedDict):
skip_if_destdir: bool
install_tag: str
class NativeKW(TypedDict):
native: mesonlib.MachineChoice
class MesonMain(MesonInterpreterObject):
def __init__(self, build: 'build.Build', interpreter: 'Interpreter'):
super().__init__(subproject=interpreter.subproject)
@ -61,20 +77,26 @@ class MesonMain(MesonInterpreterObject):
'add_devenv': self.add_devenv_method,
})
def _find_source_script(self, prog: T.Union[str, mesonlib.File, build.Executable, ExternalProgram], args):
def _find_source_script(
self, prog: T.Union[str, mesonlib.File, build.Executable, ExternalProgram],
args: T.List[str]) -> 'ExecutableSerialisation':
largs: T.List[T.Union[str, build.Executable, ExternalProgram]] = []
if isinstance(prog, (build.Executable, ExternalProgram)):
return self.interpreter.backend.get_executable_serialisation([prog] + args)
largs.append(prog)
largs.extend(args)
return self.interpreter.backend.get_executable_serialisation(largs)
found = self.interpreter.func_find_program({}, prog, {})
es = self.interpreter.backend.get_executable_serialisation([found] + args)
largs.append(found)
largs.extend(args)
es = self.interpreter.backend.get_executable_serialisation(largs)
es.subproject = self.interpreter.subproject
return es
def _process_script_args(
self, name: str, args: T.List[T.Union[
str, mesonlib.File, CustomTargetHolder,
CustomTargetIndexHolder,
ExternalProgramHolder, ExecutableHolder,
self, name: str, args: T.Sequence[T.Union[
str, mesonlib.File, build.Target,
build.CustomTargetIndex,
ExternalProgram, build.Executable,
]], allow_built: bool = False) -> T.List[str]:
script_args = [] # T.List[str]
new = False
@ -84,7 +106,7 @@ class MesonMain(MesonInterpreterObject):
elif isinstance(a, mesonlib.File):
new = True
script_args.append(a.rel_to_builddir(self.interpreter.environment.source_dir))
elif isinstance(a, (build.BuildTarget, build.CustomTarget, build.CustomTargetIndex)):
elif isinstance(a, (build.Target, build.CustomTargetIndex)):
if not allow_built:
raise InterpreterException(f'Arguments to {name} cannot be built')
new = True
@ -98,13 +120,10 @@ class MesonMain(MesonInterpreterObject):
a.target.build_by_default = True
else:
a.build_by_default = True
elif isinstance(a, ExternalProgram):
else:
script_args.extend(a.command)
new = True
else:
raise InterpreterException(
f'Arguments to {name} must be strings, Files, or CustomTargets, '
'Indexes of CustomTargets')
if new:
FeatureNew.single_use(
f'Calling "{name}" with File, CustomTaget, Index of CustomTarget, '
@ -112,39 +131,60 @@ class MesonMain(MesonInterpreterObject):
'0.55.0', self.interpreter.subproject)
return script_args
@typed_pos_args(
'meson.add_install_script',
(str, mesonlib.File, build.Executable, ExternalProgram),
varargs=(str, mesonlib.File, build.Target, build.CustomTargetIndex, ExternalProgram)
)
@typed_kwargs(
'add_install_script',
'meson.add_install_script',
KwargInfo('skip_if_destdir', bool, default=False, since='0.57.0'),
KwargInfo('install_tag', (str, NoneType), since='0.60.0'),
)
def add_install_script_method(self, args: 'T.Tuple[T.Union[str, mesonlib.File, ExecutableHolder], T.Union[str, mesonlib.File, CustomTargetHolder, CustomTargetIndexHolder], ...]', kwargs):
if len(args) < 1:
raise InterpreterException('add_install_script takes one or more arguments')
def add_install_script_method(
self,
args: T.Tuple[T.Union[str, mesonlib.File, build.Executable, ExternalProgram],
T.List[T.Union[str, mesonlib.File, build.Target, build.CustomTargetIndex, ExternalProgram]]],
kwargs: 'AddInstallScriptKW') -> None:
if isinstance(args[0], mesonlib.File):
FeatureNew.single_use('Passing file object to script parameter of add_install_script',
'0.57.0', self.interpreter.subproject)
script_args = self._process_script_args('add_install_script', args[1:], allow_built=True)
script_args = self._process_script_args('add_install_script', args[1], allow_built=True)
script = self._find_source_script(args[0], script_args)
script.skip_if_destdir = kwargs['skip_if_destdir']
script.tag = kwargs['install_tag']
self.build.install_scripts.append(script)
@permittedKwargs(set())
def add_postconf_script_method(self, args, kwargs):
if len(args) < 1:
raise InterpreterException('add_postconf_script takes one or more arguments')
@typed_pos_args(
'meson.add_postconf_script',
(str, mesonlib.File, ExternalProgram),
varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex)
)
@noKwargs
def add_postconf_script_method(
self,
args: T.Tuple[T.Union[str, mesonlib.File, ExternalProgram],
T.List[T.Union[str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex]]],
kwargs: 'TYPE_kwargs') -> None:
if isinstance(args[0], mesonlib.File):
FeatureNew.single_use('Passing file object to script parameter of add_postconf_script',
'0.57.0', self.interpreter.subproject)
script_args = self._process_script_args('add_postconf_script', args[1:], allow_built=True)
script_args = self._process_script_args('add_postconf_script', args[1], allow_built=True)
script = self._find_source_script(args[0], script_args)
self.build.postconf_scripts.append(script)
@permittedKwargs(set())
def add_dist_script_method(self, args, kwargs):
if len(args) < 1:
raise InterpreterException('add_dist_script takes one or more arguments')
if len(args) > 1:
@typed_pos_args(
'meson.add_dist_script',
(str, mesonlib.File, build.Executable, ExternalProgram),
varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex)
)
@noKwargs
def add_dist_script_method(
self,
args: T.Tuple[T.Union[str, mesonlib.File, build.Executable, ExternalProgram],
T.List[T.Union[str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex]]],
kwargs: 'TYPE_kwargs') -> None:
if args[1]:
FeatureNew.single_use('Calling "add_dist_script" with multiple arguments',
'0.49.0', self.interpreter.subproject)
if isinstance(args[0], mesonlib.File):
@ -153,13 +193,13 @@ class MesonMain(MesonInterpreterObject):
if self.interpreter.subproject != '':
FeatureNew.single_use('Calling "add_dist_script" in a subproject',
'0.58.0', self.interpreter.subproject)
script_args = self._process_script_args('add_dist_script', args[1:], allow_built=True)
script_args = self._process_script_args('add_dist_script', args[1], allow_built=True)
script = self._find_source_script(args[0], script_args)
self.build.dist_scripts.append(script)
@noPosargs
@permittedKwargs({})
def current_source_dir_method(self, args, kwargs):
@noKwargs
def current_source_dir_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> str:
src = self.interpreter.environment.source_dir
sub = self.interpreter.subdir
if sub == '':
@ -167,8 +207,8 @@ class MesonMain(MesonInterpreterObject):
return os.path.join(src, sub)
@noPosargs
@permittedKwargs({})
def current_build_dir_method(self, args, kwargs):
@noKwargs
def current_build_dir_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> str:
src = self.interpreter.environment.build_dir
sub = self.interpreter.subdir
if sub == '':
@ -176,26 +216,26 @@ class MesonMain(MesonInterpreterObject):
return os.path.join(src, sub)
@noPosargs
@permittedKwargs({})
def backend_method(self, args, kwargs):
@noKwargs
def backend_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> str:
return self.interpreter.backend.name
@noPosargs
@permittedKwargs({})
@noKwargs
@FeatureDeprecated('meson.source_root', '0.56.0', 'use meson.project_source_root() or meson.global_source_root() instead.')
def source_root_method(self, args, kwargs):
def source_root_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> str:
return self.interpreter.environment.source_dir
@noPosargs
@permittedKwargs({})
@noKwargs
@FeatureDeprecated('meson.build_root', '0.56.0', 'use meson.project_build_root() or meson.global_build_root() instead.')
def build_root_method(self, args, kwargs):
def build_root_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> str:
return self.interpreter.environment.build_dir
@noPosargs
@permittedKwargs({})
@noKwargs
@FeatureNew('meson.project_source_root', '0.56.0')
def project_source_root_method(self, args, kwargs):
def project_source_root_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> str:
src = self.interpreter.environment.source_dir
sub = self.interpreter.root_subdir
if sub == '':
@ -203,9 +243,9 @@ class MesonMain(MesonInterpreterObject):
return os.path.join(src, sub)
@noPosargs
@permittedKwargs({})
@noKwargs
@FeatureNew('meson.project_build_root', '0.56.0')
def project_build_root_method(self, args, kwargs):
def project_build_root_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> str:
src = self.interpreter.environment.build_dir
sub = self.interpreter.root_subdir
if sub == '':
@ -215,89 +255,77 @@ class MesonMain(MesonInterpreterObject):
@noPosargs
@noKwargs
@FeatureNew('meson.global_source_root', '0.58.0')
def global_source_root_method(self, args, kwargs):
def global_source_root_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> str:
return self.interpreter.environment.source_dir
@noPosargs
@noKwargs
@FeatureNew('meson.global_build_root', '0.58.0')
def global_build_root_method(self, args, kwargs):
def global_build_root_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> str:
return self.interpreter.environment.build_dir
@noPosargs
@permittedKwargs({})
@noKwargs
@FeatureDeprecated('meson.has_exe_wrapper', '0.55.0', 'use meson.can_run_host_binaries instead.')
def has_exe_wrapper_method(self, args: T.Tuple[object, ...], kwargs: T.Dict[str, object]) -> bool:
return self.can_run_host_binaries_impl(args, kwargs)
def has_exe_wrapper_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> bool:
return self._can_run_host_binaries_impl()
@noPosargs
@permittedKwargs({})
@noKwargs
@FeatureNew('meson.can_run_host_binaries', '0.55.0')
def can_run_host_binaries_method(self, args: T.Tuple[object, ...], kwargs: T.Dict[str, object]) -> bool:
return self.can_run_host_binaries_impl(args, kwargs)
def can_run_host_binaries_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> bool:
return self._can_run_host_binaries_impl()
def can_run_host_binaries_impl(self, args, kwargs):
if (self.build.environment.is_cross_build() and
def _can_run_host_binaries_impl(self) -> bool:
return not (
self.build.environment.is_cross_build() and
self.build.environment.need_exe_wrapper() and
self.build.environment.exe_wrapper is None):
return False
# We return True when exe_wrap is defined, when it's not needed, or
# when we're compiling natively.
return True
self.build.environment.exe_wrapper is None
)
@noPosargs
@permittedKwargs({})
def is_cross_build_method(self, args, kwargs):
@noKwargs
def is_cross_build_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> bool:
return self.build.environment.is_cross_build()
@permittedKwargs({'native'})
def get_compiler_method(self, args, kwargs):
if len(args) != 1:
raise InterpreterException('get_compiler_method must have one and only one argument.')
@typed_pos_args('meson.get_compiler', str)
@typed_kwargs('meson.get_compiler', NATIVE_KW)
def get_compiler_method(self, args: T.Tuple[str], kwargs: 'NativeKW') -> 'Compiler':
cname = args[0]
for_machine = self.interpreter.machine_from_native_kwarg(kwargs)
for_machine = kwargs['native']
clist = self.interpreter.coredata.compilers[for_machine]
if cname in clist:
try:
return clist[cname]
raise InterpreterException(f'Tried to access compiler for language "{cname}", not specified for {for_machine.get_lower_case_name()} machine.')
except KeyError:
raise InterpreterException(f'Tried to access compiler for language "{cname}", not specified for {for_machine.get_lower_case_name()} machine.')
@noPosargs
@permittedKwargs({})
def is_unity_method(self, args, kwargs):
@noKwargs
def is_unity_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> bool:
optval = self.interpreter.environment.coredata.get_option(OptionKey('unity'))
if optval == 'on' or (optval == 'subprojects' and self.interpreter.is_subproject()):
return True
return False
return optval == 'on' or (optval == 'subprojects' and self.interpreter.is_subproject())
@noPosargs
@permittedKwargs({})
def is_subproject_method(self, args, kwargs):
@noKwargs
def is_subproject_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> bool:
return self.interpreter.is_subproject()
@permittedKwargs({})
def install_dependency_manifest_method(self, args, kwargs):
if len(args) != 1:
raise InterpreterException('Must specify manifest install file name')
if not isinstance(args[0], str):
raise InterpreterException('Argument must be a string.')
@typed_pos_args('meson.install_dependency_manifest', str)
@noKwargs
def install_dependency_manifest_method(self, args: T.Tuple[str], kwargs: 'TYPE_kwargs') -> None:
self.build.dep_manifest_name = args[0]
@FeatureNew('meson.override_find_program', '0.46.0')
@permittedKwargs({})
def override_find_program_method(self, args, kwargs):
if len(args) != 2:
raise InterpreterException('Override needs two arguments')
@typed_pos_args('meson.override_find_program', str, (mesonlib.File, ExternalProgram, build.Executable))
@noKwargs
def override_find_program_method(self, args: T.Tuple[str, T.Union[mesonlib.File, ExternalProgram, build.Executable]], kwargs: 'TYPE_kwargs') -> None:
name, exe = args
if not isinstance(name, str):
raise InterpreterException('First argument must be a string')
if isinstance(exe, mesonlib.File):
abspath = exe.absolute_path(self.interpreter.environment.source_dir,
self.interpreter.environment.build_dir)
if not os.path.exists(abspath):
raise InterpreterException('Tried to override %s with a file that does not exist.' % name)
exe = OverrideProgram(name, abspath)
if not isinstance(exe, (ExternalProgram, build.Executable)):
raise InterpreterException('Second argument must be an external program or executable.')
raise InterpreterException(f'Tried to override {name} with a file that does not exist.')
exe = OverrideProgram(name, [abspath])
self.interpreter.add_find_program_override(name, exe)
@typed_kwargs(
@ -339,13 +367,16 @@ class MesonMain(MesonInterpreterObject):
self._override_dependency_impl(name, dep, kwargs, static=None, permissive=True)
self._override_dependency_impl(name, dep, kwargs, static=static)
def _override_dependency_impl(self, name: str, dep: dependencies.Dependency, kwargs: 'FuncOverrideDependency', static: T.Optional[bool], permissive: bool = False) -> None:
kwargs = kwargs.copy()
def _override_dependency_impl(self, name: str, dep: dependencies.Dependency, kwargs: 'FuncOverrideDependency',
static: T.Optional[bool], permissive: bool = False) -> None:
# We need the cast here as get_dep_identifier works on such a dict,
# which FuncOverrideDependency is, but mypy can't fgure that out
nkwargs = T.cast(T.Dict[str, T.Any], kwargs.copy())
if static is None:
del kwargs['static']
del nkwargs['static']
else:
kwargs['static'] = static
identifier = dependencies.get_dep_identifier(name, kwargs)
nkwargs['static'] = static
identifier = dependencies.get_dep_identifier(name, nkwargs)
for_machine = kwargs['native']
override = self.build.dependency_overrides[for_machine].get(identifier)
if override:
@ -358,24 +389,24 @@ class MesonMain(MesonInterpreterObject):
build.DependencyOverride(dep, self.interpreter.current_node)
@noPosargs
@permittedKwargs({})
def project_version_method(self, args, kwargs):
return self.build.dep_manifest[self.interpreter.active_projectname]['version']
@noKwargs
def project_version_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> str:
return self.build.dep_manifest[self.interpreter.active_projectname].version
@FeatureNew('meson.project_license()', '0.45.0')
@noPosargs
@permittedKwargs({})
def project_license_method(self, args, kwargs):
return self.build.dep_manifest[self.interpreter.active_projectname]['license']
@noKwargs
def project_license_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> T.List[str]:
return self.build.dep_manifest[self.interpreter.active_projectname].license
@noPosargs
@permittedKwargs({})
def version_method(self, args, kwargs):
@noKwargs
def version_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> MesonVersionString:
return MesonVersionString(self.interpreter.coredata.version)
@noPosargs
@permittedKwargs({})
def project_name_method(self, args, kwargs):
@noKwargs
def project_name_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> str:
return self.interpreter.active_projectname
def __get_external_property_impl(self, propname: str, fallback: T.Optional[object], machine: MachineChoice) -> object:
@ -388,37 +419,37 @@ class MesonMain(MesonInterpreterObject):
raise InterpreterException(f'Unknown property for {machine.get_lower_case_name()} machine: {propname}')
@noArgsFlattening
@permittedKwargs({})
@FeatureDeprecated('meson.get_cross_property', '0.58.0', 'Use meson.get_external_property() instead')
@typed_pos_args('meson.get_cross_property', str, optargs=[object])
def get_cross_property_method(self, args: T.Tuple[str, T.Optional[object]], kwargs: T.Dict[str, T.Any]) -> object:
@noKwargs
def get_cross_property_method(self, args: T.Tuple[str, T.Optional[object]], kwargs: 'TYPE_kwargs') -> object:
propname, fallback = args
return self.__get_external_property_impl(propname, fallback, MachineChoice.HOST)
@noArgsFlattening
@permittedKwargs({'native'})
@FeatureNew('meson.get_external_property', '0.54.0')
@typed_pos_args('meson.get_external_property', str, optargs=[object])
def get_external_property_method(self, args: T.Tuple[str, T.Optional[object]], kwargs: T.Dict[str, T.Any]) -> object:
@typed_kwargs('meson.get_external_property', NATIVE_KW)
def get_external_property_method(self, args: T.Tuple[str, T.Optional[object]], kwargs: 'NativeKW') -> object:
propname, fallback = args
machine = self.interpreter.machine_from_native_kwarg(kwargs)
return self.__get_external_property_impl(propname, fallback, machine)
return self.__get_external_property_impl(propname, fallback, kwargs['native'])
@permittedKwargs({'native'})
@FeatureNew('meson.has_external_property', '0.58.0')
@typed_pos_args('meson.has_external_property', str)
def has_external_property_method(self, args: T.Tuple[str], kwargs: T.Dict[str, T.Any]) -> str:
@typed_kwargs('meson.has_external_property', NATIVE_KW)
def has_external_property_method(self, args: T.Tuple[str], kwargs: 'NativeKW') -> bool:
prop_name = args[0]
for_machine = self.interpreter.machine_from_native_kwarg(kwargs)
return prop_name in self.interpreter.environment.properties[for_machine]
return prop_name in self.interpreter.environment.properties[kwargs['native']]
@FeatureNew('add_devenv', '0.58.0')
@noKwargs
@typed_pos_args('add_devenv', (str, list, dict, build.EnvironmentVariables))
def add_devenv_method(self, args: T.Tuple[T.Union[str, list, dict, build.EnvironmentVariables]], kwargs: T.Dict[str, T.Any]) -> None:
def add_devenv_method(self, args: T.Tuple[T.Union[str, list, dict, build.EnvironmentVariables]], kwargs: 'TYPE_kwargs') -> None:
env = args[0]
msg = ENV_KW.validator(env)
if msg:
raise build.InvalidArguments(f'"add_devenv": {msg}')
self.build.devenv.append(ENV_KW.convertor(env))
converted = ENV_KW.convertor(env)
assert isinstance(converted, build.EnvironmentVariables)
self.build.devenv.append(converted)

@ -293,7 +293,7 @@ def log_once(*args: TV_Loggable, is_error: bool = False,
#
# This would more accurately embody what this function can handle, but we
# don't have that yet, so instead we'll do some casting to work around it
def get_error_location_string(fname: str, lineno: str) -> str:
def get_error_location_string(fname: str, lineno: int) -> str:
return f'{fname}:{lineno}:'
def _log_error(severity: str, *rargs: TV_Loggable,

@ -45,7 +45,7 @@ class ModuleState:
self.current_lineno = interpreter.current_lineno
self.environment = interpreter.environment
self.project_name = interpreter.build.project_name
self.project_version = interpreter.build.dep_manifest[interpreter.active_projectname]
self.project_version = interpreter.build.dep_manifest[interpreter.active_projectname].version
# The backend object is under-used right now, but we will need it:
# https://github.com/mesonbuild/meson/issues/1419
self.backend = interpreter.backend

@ -12,18 +12,22 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import os
from pathlib import PurePath
import os
import typing as T
from . import ExtensionModule
from . import ModuleReturnValue
from .. import build
from .. import dependencies
from ..dependencies import ThreadDependency
from .. import mesonlib
from .. import mlog
from . import ModuleReturnValue
from . import ExtensionModule
from ..dependencies import ThreadDependency
from ..interpreterbase import permittedKwargs, FeatureNew, FeatureNewKwargs
if T.TYPE_CHECKING:
from . import ModuleState
already_warned_objs = set()
class DependenciesHelper:
@ -451,8 +455,8 @@ class PkgConfigModule(ExtensionModule):
'install_dir', 'extra_cflags', 'variables', 'url', 'd_module_versions',
'dataonly', 'conflicts', 'uninstalled_variables',
'unescaped_variables', 'unescaped_uninstalled_variables'})
def generate(self, state, args, kwargs):
default_version = state.project_version['version']
def generate(self, state: 'ModuleState', args, kwargs):
default_version = state.project_version
default_install_dir = None
default_description = None
default_name = None

@ -13,7 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from mesonbuild import coredata
import os
import shutil
import typing as T
@ -21,10 +20,10 @@ import xml.etree.ElementTree as ET
from . import ModuleReturnValue, ExtensionModule
from .. import build
from .. import coredata
from .. import mlog
from ..dependencies import find_external_dependency, Dependency, ExternalLibrary
from ..mesonlib import MesonException, File, FileOrString, version_compare, Popen_safe
from . import ModuleReturnValue, ExtensionModule
from ..interpreter import extract_required_kwarg
from ..interpreter.type_checking import NoneType
from ..interpreterbase import ContainerTypeInfo, FeatureDeprecated, KwargInfo, noPosargs, FeatureNew, typed_kwargs

@ -232,7 +232,7 @@ class ExternalProject(NewExtensionModule):
abs_includedir = Path(abs_includedir, subdir)
abs_libdir = Path(self.install_dir, self.rel_prefix, self.libdir)
version = self.project_version['version']
version = self.project_version
incdir = []
compile_args = [f'-I{abs_includedir}']
link_args = [f'-L{abs_libdir}', f'-l{libname}']

@ -32,7 +32,7 @@ def buildparser() -> argparse.ArgumentParser:
parser.add_argument('--feed')
return parser
def run_exe(exe: ExecutableSerialisation, extra_env: T.Optional[dict] = None) -> int:
def run_exe(exe: ExecutableSerialisation, extra_env: T.Optional[T.Dict[str, str]] = None) -> int:
if exe.exe_runner:
if not exe.exe_runner.found():
raise AssertionError('BUG: Can\'t run cross-compiled exe {!r} with not-found '
@ -67,6 +67,9 @@ def run_exe(exe: ExecutableSerialisation, extra_env: T.Optional[dict] = None) ->
close_fds=False, stdin=stdin, stdout=pipe, stderr=pipe)
stdout, stderr = p.communicate()
if stdin is not None:
stdin.close()
if p.returncode == 0xc0000135:
# STATUS_DLL_NOT_FOUND on Windows indicating a common problem that is otherwise hard to diagnose
raise FileNotFoundError('due to missing DLLs')

@ -27,6 +27,7 @@ modules = [
# 'mesonbuild/coredata.py',
'mesonbuild/envconfig.py',
'mesonbuild/interpreter/compiler.py',
'mesonbuild/interpreter/mesonmain.py',
'mesonbuild/interpreter/interpreterobjects.py',
'mesonbuild/interpreter/type_checking.py',
'mesonbuild/mcompile.py',

Loading…
Cancel
Save