Merge pull request #9167 from dcbaker/submit/meson-main-type-checking
Add type annotations and type checking to meson main
This commit is contained in:
commit
fee5cb697c
|
@ -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…
Reference in New Issue