holders: Fix the remaining code to respect the holder changes
This commit is contained in:
parent
34c28dc92c
commit
7c757dff71
|
@ -76,6 +76,9 @@ class MockRunTarget(MesonInterpreterObject):
|
|||
ADD_SOURCE = 0
|
||||
REMOVE_SOURCE = 1
|
||||
|
||||
_T = T.TypeVar('_T')
|
||||
_V = T.TypeVar('_V')
|
||||
|
||||
class AstInterpreter(InterpreterBase):
|
||||
def __init__(self, source_root: str, subdir: str, subproject: str, visitors: T.Optional[T.List[AstVisitor]] = None):
|
||||
super().__init__(source_root, subdir, subproject)
|
||||
|
@ -141,6 +144,12 @@ class AstInterpreter(InterpreterBase):
|
|||
'range': self.func_do_nothing,
|
||||
})
|
||||
|
||||
def _unholder_args(self, args: _T, kwargs: _V) -> T.Tuple[_T, _V]:
|
||||
return args, kwargs
|
||||
|
||||
def _holderify(self, res: _T) -> _T:
|
||||
return res
|
||||
|
||||
def func_do_nothing(self, node: BaseNode, args: T.List[TYPE_nvar], kwargs: T.Dict[str, TYPE_nvar]) -> bool:
|
||||
return True
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ from .compilers import (
|
|||
is_known_suffix
|
||||
)
|
||||
from .linkers import StaticLinker
|
||||
from .interpreterbase import FeatureNew, TYPE_nkwargs, TYPE_nvar
|
||||
from .interpreterbase import FeatureNew
|
||||
|
||||
if T.TYPE_CHECKING:
|
||||
from ._typing import ImmutableListProtocol, ImmutableSetProtocol
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import functools
|
||||
|
||||
from .interpreterobjects import (IncludeDirsHolder, ExternalLibraryHolder,
|
||||
extract_required_kwarg, extract_search_dirs)
|
||||
from .interpreterobjects import (extract_required_kwarg, extract_search_dirs)
|
||||
|
||||
from .. import mesonlib
|
||||
from .. import mlog
|
||||
|
@ -14,12 +13,12 @@ import typing as T
|
|||
import os
|
||||
|
||||
if T.TYPE_CHECKING:
|
||||
from ..environment import Environment
|
||||
from ..interpreter import Interpreter
|
||||
from ..compilers import Compiler, RunResult
|
||||
|
||||
class TryRunResultHolder(ObjectHolder['RunResult']):
|
||||
def __init__(self, res: 'RunResult'):
|
||||
super().__init__(res)
|
||||
def __init__(self, res: 'RunResult', interpreter: 'Interpreter'):
|
||||
super().__init__(res, interpreter)
|
||||
self.methods.update({'returncode': self.returncode_method,
|
||||
'compiled': self.compiled_method,
|
||||
'stdout': self.stdout_method,
|
||||
|
@ -65,9 +64,9 @@ find_library_permitted_kwargs = {
|
|||
find_library_permitted_kwargs |= {'header_' + k for k in header_permitted_kwargs}
|
||||
|
||||
class CompilerHolder(ObjectHolder['Compiler']):
|
||||
def __init__(self, compiler: 'Compiler', env: 'Environment', subproject: str):
|
||||
super().__init__(compiler, subproject=subproject)
|
||||
self.environment = env
|
||||
def __init__(self, compiler: 'Compiler', interpreter: 'Interpreter'):
|
||||
super().__init__(compiler, interpreter)
|
||||
self.environment = self.env
|
||||
self.methods.update({'compiles': self.compiles_method,
|
||||
'links': self.links_method,
|
||||
'get_id': self.get_id_method,
|
||||
|
@ -144,9 +143,10 @@ class CompilerHolder(ObjectHolder['Compiler']):
|
|||
args = []
|
||||
incdirs = mesonlib.extract_as_list(kwargs, 'include_directories')
|
||||
for i in incdirs:
|
||||
if not isinstance(i, IncludeDirsHolder):
|
||||
from ..build import IncludeDirs
|
||||
if not isinstance(i, IncludeDirs):
|
||||
raise InterpreterException('Include directories argument must be an include_directories object.')
|
||||
for idir in i.held_object.to_string_list(self.environment.get_source_dir()):
|
||||
for idir in i.to_string_list(self.environment.get_source_dir()):
|
||||
args += self.compiler.get_include_args(idir, False)
|
||||
if not nobuiltins:
|
||||
opts = self.environment.coredata.options
|
||||
|
@ -162,7 +162,7 @@ class CompilerHolder(ObjectHolder['Compiler']):
|
|||
final_deps = []
|
||||
while deps:
|
||||
next_deps = []
|
||||
for d in mesonlib.unholder(mesonlib.listify(deps)):
|
||||
for d in mesonlib.listify(deps):
|
||||
if not isinstance(d, dependencies.Dependency) or d.is_built():
|
||||
raise InterpreterException('Dependencies must be external dependencies')
|
||||
final_deps.append(d)
|
||||
|
@ -223,7 +223,7 @@ class CompilerHolder(ObjectHolder['Compiler']):
|
|||
else:
|
||||
h = mlog.red('NO (%d)' % result.returncode)
|
||||
mlog.log('Checking if', mlog.bold(testname, True), msg, 'runs:', h)
|
||||
return TryRunResultHolder(result)
|
||||
return result
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
|
@ -614,7 +614,7 @@ class CompilerHolder(ObjectHolder['Compiler']):
|
|||
self.environment,
|
||||
self.compiler.language,
|
||||
silent=True)
|
||||
return ExternalLibraryHolder(lib, self.subproject)
|
||||
return lib
|
||||
|
||||
@FeatureNewKwargs('compiler.find_library', '0.51.0', ['static'])
|
||||
@FeatureNewKwargs('compiler.find_library', '0.50.0', ['has_headers'])
|
||||
|
@ -659,7 +659,7 @@ class CompilerHolder(ObjectHolder['Compiler']):
|
|||
libtype, libname))
|
||||
lib = dependencies.ExternalLibrary(libname, linkargs, self.environment,
|
||||
self.compiler.language)
|
||||
return ExternalLibraryHolder(lib, self.subproject)
|
||||
return lib
|
||||
|
||||
@permittedKwargs({})
|
||||
def has_argument_method(self, args: T.Sequence[str], kwargs) -> bool:
|
||||
|
|
|
@ -66,11 +66,11 @@ if T.TYPE_CHECKING:
|
|||
from . import kwargs
|
||||
|
||||
# Input source types passed to Targets
|
||||
SourceInputs = T.Union[FileHolder, GeneratedListHolder, TargetHolder,
|
||||
CustomTargetIndexHolder, GeneratedObjectsHolder, str]
|
||||
SourceInputs = T.Union[mesonlib.File, build.GeneratedList, build.BuildTarget,
|
||||
build.CustomTargetIndex, build.CustomTarget, build.GeneratedList, str]
|
||||
# Input source types passed to the build.Target5 classes
|
||||
SourceOutputs = T.Union[mesonlib.File, build.GeneratedList,
|
||||
build.BuildTarget, build.CustomTargetIndex,
|
||||
build.BuildTarget, build.CustomTargetIndex, build.CustomTarget,
|
||||
build.GeneratedList]
|
||||
|
||||
|
||||
|
@ -191,7 +191,7 @@ known_build_target_kwargs = (
|
|||
)
|
||||
|
||||
TEST_KWARGS: T.List[KwargInfo] = [
|
||||
KwargInfo('args', ContainerTypeInfo(list, (str, mesonlib.File, TargetHolder)),
|
||||
KwargInfo('args', ContainerTypeInfo(list, (str, mesonlib.File, build.Target)),
|
||||
listify=True, default=[]),
|
||||
KwargInfo('should_fail', bool, default=False),
|
||||
KwargInfo('timeout', int, default=30),
|
||||
|
@ -201,11 +201,11 @@ TEST_KWARGS: T.List[KwargInfo] = [
|
|||
default='exitcode',
|
||||
validator=lambda x: 'value must be one of "exitcode", "tap", "gtest", "rust"' if x not in {'exitcode', 'tap', 'gtest', 'rust'} else None,
|
||||
since_values={'gtest': '0.55.0', 'rust': '0.57.0'}),
|
||||
KwargInfo('depends', ContainerTypeInfo(list, (CustomTargetHolder, BuildTargetHolder)),
|
||||
KwargInfo('depends', ContainerTypeInfo(list, (build.CustomTarget, build.BuildTarget)),
|
||||
listify=True, default=[], since='0.46.0'),
|
||||
KwargInfo('priority', int, default=0, since='0.52.0'),
|
||||
# TODO: env needs reworks of the way the environment variable holder itself works probably
|
||||
KwargInfo('env', (EnvironmentVariablesHolder, list, dict, str)),
|
||||
KwargInfo('env', (EnvironmentVariablesObject, list, dict, str)),
|
||||
KwargInfo('suite', ContainerTypeInfo(list, str), listify=True, default=['']), # yes, a list of empty string
|
||||
]
|
||||
|
||||
|
@ -235,7 +235,7 @@ class Interpreter(InterpreterBase, HoldableObject):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
build: build.Build,
|
||||
_build: build.Build,
|
||||
backend: T.Optional[Backend] = None,
|
||||
subproject: str = '',
|
||||
subdir: str = '',
|
||||
|
@ -246,10 +246,10 @@ class Interpreter(InterpreterBase, HoldableObject):
|
|||
ast: T.Optional[mparser.CodeBlockNode] = None,
|
||||
is_translated: bool = False,
|
||||
) -> None:
|
||||
super().__init__(build.environment.get_source_dir(), subdir, subproject)
|
||||
super().__init__(_build.environment.get_source_dir(), subdir, subproject)
|
||||
self.an_unpicklable_object = mesonlib.an_unpicklable_object
|
||||
self.build = build
|
||||
self.environment = build.environment
|
||||
self.build = _build
|
||||
self.environment = self.build.environment
|
||||
self.coredata = self.environment.get_coredata()
|
||||
self.backend = backend
|
||||
self.summary = {}
|
||||
|
@ -268,12 +268,12 @@ class Interpreter(InterpreterBase, HoldableObject):
|
|||
elif ast is not None:
|
||||
self.ast = ast
|
||||
self.sanity_check_ast()
|
||||
self.builtin.update({'meson': MesonMain(build, self)})
|
||||
self.generators: T.List['GeneratorHolder'] = []
|
||||
self.builtin.update({'meson': MesonMain(self.build, self)})
|
||||
self.generators: T.List[build.Generator] = []
|
||||
self.processed_buildfiles = set() # type: T.Set[str]
|
||||
self.project_args_frozen = False
|
||||
self.global_args_frozen = False # implies self.project_args_frozen
|
||||
self.subprojects = {}
|
||||
self.subprojects: T.Dict[str, SubprojectHolder] = {}
|
||||
self.subproject_stack = []
|
||||
self.configure_file_outputs = {}
|
||||
# Passed from the outside, only used in subprojects.
|
||||
|
@ -283,6 +283,7 @@ class Interpreter(InterpreterBase, HoldableObject):
|
|||
self.default_project_options = {}
|
||||
self.project_default_options = {}
|
||||
self.build_func_dict()
|
||||
self.build_holder_map()
|
||||
|
||||
# build_def_files needs to be defined before parse_project is called
|
||||
#
|
||||
|
@ -309,11 +310,11 @@ class Interpreter(InterpreterBase, HoldableObject):
|
|||
assert self.build.environment.machines.target.cpu is not None
|
||||
|
||||
self.builtin['build_machine'] = \
|
||||
MachineHolder(self.build.environment.machines.build)
|
||||
OBJ.MachineHolder(self.build.environment.machines.build, self)
|
||||
self.builtin['host_machine'] = \
|
||||
MachineHolder(self.build.environment.machines.host)
|
||||
OBJ.MachineHolder(self.build.environment.machines.host, self)
|
||||
self.builtin['target_machine'] = \
|
||||
MachineHolder(self.build.environment.machines.target)
|
||||
OBJ.MachineHolder(self.build.environment.machines.target, self)
|
||||
|
||||
# TODO: Why is this in interpreter.py and not CoreData or Environment?
|
||||
def get_non_matching_default_options(self) -> T.Iterator[T.Tuple[str, str, coredata.UserOption]]:
|
||||
|
@ -564,7 +565,7 @@ class Interpreter(InterpreterBase, HoldableObject):
|
|||
mlog.warning('Module %s has no backwards or forwards compatibility and might not exist in future releases.' % modname, location=node)
|
||||
modname = 'unstable_' + plainname
|
||||
self.import_module(modname)
|
||||
return ModuleObjectHolder(self.modules[modname], self)
|
||||
return self.modules[modname]
|
||||
|
||||
@stringArgs
|
||||
@noKwargs
|
||||
|
@ -628,7 +629,7 @@ external dependencies (including libraries) must go to "dependencies".''')
|
|||
dep = dependencies.InternalDependency(version, incs, compile_args,
|
||||
link_args, libs, libs_whole, sources, final_deps,
|
||||
variables)
|
||||
return DependencyHolder(dep, self.subproject)
|
||||
return dep
|
||||
|
||||
@noKwargs
|
||||
def func_assert(self, node, args, kwargs):
|
||||
|
@ -668,7 +669,11 @@ external dependencies (including libraries) must go to "dependencies".''')
|
|||
def func_run_command(self, node, args, kwargs):
|
||||
return self.run_command_impl(node, args, kwargs)
|
||||
|
||||
def run_command_impl(self, node, args, kwargs, in_builddir=False):
|
||||
def run_command_impl(self,
|
||||
node: mparser.BaseNode,
|
||||
args: T.Sequence[TYPE_nvar],
|
||||
kwargs: TYPE_nkwargs,
|
||||
in_builddir: bool = False) -> RunProcess:
|
||||
if len(args) < 1:
|
||||
raise InterpreterException('Not enough arguments')
|
||||
cmd, *cargs = args
|
||||
|
@ -748,10 +753,16 @@ external dependencies (including libraries) must go to "dependencies".''')
|
|||
if len(args) != 1:
|
||||
raise InterpreterException('Subproject takes exactly one argument')
|
||||
subp_name = args[0]
|
||||
return self.do_subproject(subp_name, 'meson', kwargs)
|
||||
subp = self.do_subproject(subp_name, 'meson', kwargs)
|
||||
# Update the holder maps from the subproject. Additional entries to the
|
||||
# holder maps can be added through imported Meson modules
|
||||
if isinstance(subp.held_object, Interpreter):
|
||||
self.holder_map.update(subp.held_object.holder_map)
|
||||
self.bound_holder_map.update(subp.held_object.bound_holder_map)
|
||||
return subp
|
||||
|
||||
def disabled_subproject(self, subp_name, disabled_feature=None, exception=None):
|
||||
sub = SubprojectHolder(None, os.path.join(self.subproject_dir, subp_name),
|
||||
sub = SubprojectHolder(NullSubprojectInterpreter(), os.path.join(self.subproject_dir, subp_name),
|
||||
disabled_feature=disabled_feature, exception=exception)
|
||||
self.subprojects[subp_name] = sub
|
||||
self.coredata.initialized_subprojects.add(subp_name)
|
||||
|
@ -836,6 +847,8 @@ external dependencies (including libraries) must go to "dependencies".''')
|
|||
subi = Interpreter(new_build, self.backend, subp_name, subdir, self.subproject_dir,
|
||||
self.modules, default_options, ast=ast, is_translated=is_translated)
|
||||
subi.subprojects = self.subprojects
|
||||
subi.holder_map.update(self.holder_map)
|
||||
subi.bound_holder_map.update(self.bound_holder_map)
|
||||
|
||||
subi.subproject_stack = self.subproject_stack + [subp_name]
|
||||
current_active = self.active_projectname
|
||||
|
@ -958,7 +971,8 @@ external dependencies (including libraries) must go to "dependencies".''')
|
|||
'options of other subprojects.')
|
||||
opt = self.get_option_internal(optname)
|
||||
if isinstance(opt, coredata.UserFeatureOption):
|
||||
return FeatureOptionHolder(self.environment, optname, opt)
|
||||
opt.name = optname
|
||||
return opt
|
||||
elif isinstance(opt, coredata.UserOption):
|
||||
return opt.value
|
||||
return opt
|
||||
|
@ -974,7 +988,7 @@ external dependencies (including libraries) must go to "dependencies".''')
|
|||
raise InterpreterException('configuration_data first argument must be a dictionary')
|
||||
else:
|
||||
initial_values = {}
|
||||
return ConfigurationDataHolder(self.subproject, initial_values)
|
||||
return ConfigurationDataObject(self.subproject, initial_values)
|
||||
|
||||
def set_backend(self):
|
||||
# The backend is already set when parsing subprojects
|
||||
|
@ -1318,10 +1332,9 @@ external dependencies (including libraries) must go to "dependencies".''')
|
|||
extprog = ExternalProgram(exename, search_dir=search_dir,
|
||||
extra_search_dirs=extra_search_dirs,
|
||||
silent=True)
|
||||
progobj = ExternalProgramHolder(extprog, self.subproject)
|
||||
if progobj.found():
|
||||
extra_info.append(f"({' '.join(progobj.get_command())})")
|
||||
return progobj
|
||||
if extprog.found():
|
||||
extra_info.append(f"({' '.join(extprog.get_command())})")
|
||||
return extprog
|
||||
|
||||
def program_from_overrides(self, command_names, extra_info):
|
||||
for name in command_names:
|
||||
|
@ -1330,7 +1343,7 @@ external dependencies (including libraries) must go to "dependencies".''')
|
|||
if name in self.build.find_overrides:
|
||||
exe = self.build.find_overrides[name]
|
||||
extra_info.append(mlog.blue('(overridden)'))
|
||||
return ExternalProgramHolder(exe, self.subproject, self.backend)
|
||||
return exe
|
||||
return None
|
||||
|
||||
def store_name_lookups(self, command_names):
|
||||
|
@ -1348,7 +1361,7 @@ external dependencies (including libraries) must go to "dependencies".''')
|
|||
self.build.find_overrides[name] = exe
|
||||
|
||||
def notfound_program(self, args):
|
||||
return ExternalProgramHolder(NonExistingExternalProgram(' '.join(args)), self.subproject)
|
||||
return NonExistingExternalProgram(' '.join(args))
|
||||
|
||||
# TODO update modules to always pass `for_machine`. It is bad-form to assume
|
||||
# the host machine.
|
||||
|
@ -1372,22 +1385,28 @@ external dependencies (including libraries) must go to "dependencies".''')
|
|||
if wanted:
|
||||
if version_func:
|
||||
version = version_func(progobj)
|
||||
else:
|
||||
elif isinstance(progobj, build.Executable):
|
||||
interp = self
|
||||
if progobj.subproject:
|
||||
interp = self.subprojects[progobj.subproject].held_object
|
||||
assert isinstance(interp, Interpreter)
|
||||
version = interp.project_version
|
||||
elif isinstance(progobj, ExternalProgram):
|
||||
version = progobj.get_version(self)
|
||||
is_found, not_found, found = mesonlib.version_compare_many(version, wanted)
|
||||
if not is_found:
|
||||
mlog.log('Program', mlog.bold(progobj.get_name()), 'found:', mlog.red('NO'),
|
||||
mlog.log('Program', mlog.bold(progobj.name), 'found:', mlog.red('NO'),
|
||||
'found', mlog.normal_cyan(version), 'but need:',
|
||||
mlog.bold(', '.join([f"'{e}'" for e in not_found])), *extra_info)
|
||||
if required:
|
||||
m = 'Invalid version of program, need {!r} {!r} found {!r}.'
|
||||
raise InterpreterException(m.format(progobj.get_name(), not_found, version))
|
||||
raise InterpreterException(m.format(progobj.name, not_found, version))
|
||||
return self.notfound_program(args)
|
||||
extra_info.insert(0, mlog.normal_cyan(version))
|
||||
|
||||
# Only store successful lookups
|
||||
self.store_name_lookups(args)
|
||||
mlog.log('Program', mlog.bold(progobj.get_name()), 'found:', mlog.green('YES'), *extra_info)
|
||||
mlog.log('Program', mlog.bold(progobj.name), 'found:', mlog.green('YES'), *extra_info)
|
||||
return progobj
|
||||
|
||||
def program_lookup(self, args, for_machine, required, search_dirs, extra_info):
|
||||
|
@ -1407,7 +1426,7 @@ external dependencies (including libraries) must go to "dependencies".''')
|
|||
progobj = self.program_from_system(args, search_dirs, extra_info)
|
||||
if progobj is None and args[0].endswith('python3'):
|
||||
prog = ExternalProgram('python3', mesonlib.python_command, silent=True)
|
||||
progobj = ExternalProgramHolder(prog, self.subproject) if prog.found() else None
|
||||
progobj = prog if prog.found() else None
|
||||
if progobj is None and fallback and required:
|
||||
progobj = self.find_program_fallback(fallback, args, required, extra_info)
|
||||
|
||||
|
@ -1485,10 +1504,12 @@ external dependencies (including libraries) must go to "dependencies".''')
|
|||
# Ensure the correct include type
|
||||
if 'include_type' in kwargs:
|
||||
wanted = kwargs['include_type']
|
||||
actual = d.include_type_method([], {})
|
||||
if not isinstance(wanted, str):
|
||||
raise InvalidArguments('The `include_type` kwarg must be a string')
|
||||
actual = d.get_include_type()
|
||||
if wanted != actual:
|
||||
mlog.debug(f'Current include type of {names[0]} is {actual}. Converting to requested {wanted}')
|
||||
d = d.as_system_method([wanted], {})
|
||||
d = d.generate_system_dependency(wanted)
|
||||
return d
|
||||
|
||||
@FeatureNew('disabler', '0.44.0')
|
||||
|
@ -1502,16 +1523,16 @@ external dependencies (including libraries) must go to "dependencies".''')
|
|||
@FeatureDeprecatedKwargs('executable', '0.56.0', ['gui_app'], extra_message="Use 'win_subsystem' instead.")
|
||||
@permittedKwargs(build.known_exe_kwargs)
|
||||
def func_executable(self, node, args, kwargs):
|
||||
return self.build_target(node, args, kwargs, ExecutableHolder)
|
||||
return self.build_target(node, args, kwargs, build.Executable)
|
||||
|
||||
@permittedKwargs(build.known_stlib_kwargs)
|
||||
def func_static_lib(self, node, args, kwargs):
|
||||
return self.build_target(node, args, kwargs, StaticLibraryHolder)
|
||||
return self.build_target(node, args, kwargs, build.StaticLibrary)
|
||||
|
||||
@permittedKwargs(build.known_shlib_kwargs)
|
||||
def func_shared_lib(self, node, args, kwargs):
|
||||
holder = self.build_target(node, args, kwargs, SharedLibraryHolder)
|
||||
holder.held_object.shared_library_only = True
|
||||
holder = self.build_target(node, args, kwargs, build.SharedLibrary)
|
||||
holder.shared_library_only = True
|
||||
return holder
|
||||
|
||||
@permittedKwargs(known_library_kwargs)
|
||||
|
@ -1521,7 +1542,7 @@ external dependencies (including libraries) must go to "dependencies".''')
|
|||
@FeatureNew('shared_module', '0.37.0')
|
||||
@permittedKwargs(build.known_shmod_kwargs)
|
||||
def func_shared_module(self, node, args, kwargs):
|
||||
return self.build_target(node, args, kwargs, SharedModuleHolder)
|
||||
return self.build_target(node, args, kwargs, build.SharedModule)
|
||||
|
||||
@permittedKwargs(known_library_kwargs)
|
||||
def func_library(self, node, args, kwargs):
|
||||
|
@ -1529,7 +1550,7 @@ external dependencies (including libraries) must go to "dependencies".''')
|
|||
|
||||
@permittedKwargs(build.known_jar_kwargs)
|
||||
def func_jar(self, node, args, kwargs):
|
||||
return self.build_target(node, args, kwargs, JarHolder)
|
||||
return self.build_target(node, args, kwargs, build.Jar)
|
||||
|
||||
@FeatureNewKwargs('build_target', '0.40.0', ['link_whole', 'override_options'])
|
||||
@permittedKwargs(known_build_target_kwargs)
|
||||
|
@ -1538,21 +1559,21 @@ external dependencies (including libraries) must go to "dependencies".''')
|
|||
raise InterpreterException('Missing target_type keyword argument')
|
||||
target_type = kwargs.pop('target_type')
|
||||
if target_type == 'executable':
|
||||
return self.build_target(node, args, kwargs, ExecutableHolder)
|
||||
return self.build_target(node, args, kwargs, build.Executable)
|
||||
elif target_type == 'shared_library':
|
||||
return self.build_target(node, args, kwargs, SharedLibraryHolder)
|
||||
return self.build_target(node, args, kwargs, build.SharedLibrary)
|
||||
elif target_type == 'shared_module':
|
||||
FeatureNew('build_target(target_type: \'shared_module\')',
|
||||
'0.51.0').use(self.subproject)
|
||||
return self.build_target(node, args, kwargs, SharedModuleHolder)
|
||||
return self.build_target(node, args, kwargs, build.SharedModule)
|
||||
elif target_type == 'static_library':
|
||||
return self.build_target(node, args, kwargs, StaticLibraryHolder)
|
||||
return self.build_target(node, args, kwargs, build.StaticLibrary)
|
||||
elif target_type == 'both_libraries':
|
||||
return self.build_both_libraries(node, args, kwargs)
|
||||
elif target_type == 'library':
|
||||
return self.build_library(node, args, kwargs)
|
||||
elif target_type == 'jar':
|
||||
return self.build_target(node, args, kwargs, JarHolder)
|
||||
return self.build_target(node, args, kwargs, build.Jar)
|
||||
else:
|
||||
raise InterpreterException('Unknown target_type.')
|
||||
|
||||
|
@ -1634,8 +1655,8 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
|
|||
if 'command' in kwargs and isinstance(kwargs['command'], list) and kwargs['command']:
|
||||
if isinstance(kwargs['command'][0], str):
|
||||
kwargs['command'][0] = self.func_find_program(node, kwargs['command'][0], {})
|
||||
tg = CustomTargetHolder(build.CustomTarget(name, self.subdir, self.subproject, kwargs, backend=self.backend), self)
|
||||
self.add_target(name, tg.held_object)
|
||||
tg = build.CustomTarget(name, self.subdir, self.subproject, kwargs, backend=self.backend)
|
||||
self.add_target(name, tg)
|
||||
return tg
|
||||
|
||||
@FeatureNewKwargs('run_target', '0.57.0', ['env'])
|
||||
|
@ -1721,36 +1742,36 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
|
|||
self.generators.append(gen)
|
||||
return gen
|
||||
|
||||
@typed_pos_args('benchmark', str, (ExecutableHolder, JarHolder, ExternalProgramHolder, mesonlib.File))
|
||||
@typed_pos_args('benchmark', str, (build.Executable, build.Jar, ExternalProgram, mesonlib.File))
|
||||
@typed_kwargs('benchmark', *TEST_KWARGS)
|
||||
def func_benchmark(self, node: mparser.BaseNode,
|
||||
args: T.Tuple[str, T.Union[ExecutableHolder, JarHolder, ExternalProgramHolder, mesonlib.File]],
|
||||
args: T.Tuple[str, T.Union[build.Executable, build.Jar, ExternalProgram, mesonlib.File]],
|
||||
kwargs: 'kwargs.FuncBenchmark') -> None:
|
||||
self.add_test(node, args, kwargs, False)
|
||||
|
||||
@typed_pos_args('test', str, (ExecutableHolder, JarHolder, ExternalProgramHolder, mesonlib.File))
|
||||
@typed_pos_args('test', str, (build.Executable, build.Jar, ExternalProgram, mesonlib.File))
|
||||
@typed_kwargs('benchmark', *TEST_KWARGS, KwargInfo('is_parallel', bool, default=True))
|
||||
def func_test(self, node: mparser.BaseNode,
|
||||
args: T.Tuple[str, T.Union[ExecutableHolder, JarHolder, ExternalProgramHolder, mesonlib.File]],
|
||||
args: T.Tuple[str, T.Union[build.Executable, build.Jar, ExternalProgram, mesonlib.File]],
|
||||
kwargs: 'kwargs.FuncTest') -> None:
|
||||
self.add_test(node, args, kwargs, True)
|
||||
|
||||
def unpack_env_kwarg(self, kwargs: T.Union[EnvironmentVariablesHolder, T.Dict[str, str], T.List[str]]) -> build.EnvironmentVariables:
|
||||
envlist = kwargs.get('env', EnvironmentVariablesHolder())
|
||||
if isinstance(envlist, EnvironmentVariablesHolder):
|
||||
env = envlist.held_object
|
||||
def unpack_env_kwarg(self, kwargs: T.Union[EnvironmentVariablesObject, T.Dict[str, str], T.List[str]]) -> build.EnvironmentVariables:
|
||||
envlist = kwargs.get('env', EnvironmentVariablesObject())
|
||||
if isinstance(envlist, EnvironmentVariablesObject):
|
||||
env = envlist.vars
|
||||
elif isinstance(envlist, dict):
|
||||
FeatureNew.single_use('environment dictionary', '0.52.0', self.subproject)
|
||||
env = EnvironmentVariablesHolder(envlist)
|
||||
env = env.held_object
|
||||
env = EnvironmentVariablesObject(envlist)
|
||||
env = env.vars
|
||||
else:
|
||||
# Convert from array to environment object
|
||||
env = EnvironmentVariablesHolder(envlist)
|
||||
env = env.held_object
|
||||
env = EnvironmentVariablesObject(envlist)
|
||||
env = env.vars
|
||||
return env
|
||||
|
||||
def make_test(self, node: mparser.BaseNode,
|
||||
args: T.Tuple[str, T.Union[ExecutableHolder, JarHolder, ExternalProgramHolder, mesonlib.File]],
|
||||
args: T.Tuple[str, T.Union[build.Executable, build.Jar, ExternalProgram, mesonlib.File]],
|
||||
kwargs: 'kwargs.BaseTest') -> Test:
|
||||
name = args[0]
|
||||
if ':' in name:
|
||||
|
@ -1816,7 +1837,7 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
|
|||
h = build.Headers(source_files, install_subdir, install_dir, install_mode, self.subproject)
|
||||
self.build.headers.append(h)
|
||||
|
||||
return HeadersHolder(h)
|
||||
return h
|
||||
|
||||
@FeatureNewKwargs('install_man', '0.47.0', ['install_mode'])
|
||||
@FeatureNewKwargs('install_man', '0.58.0', ['locale'])
|
||||
|
@ -1839,7 +1860,7 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
|
|||
m = build.Man(sources, custom_install_dir, custom_install_mode, self.subproject, locale)
|
||||
self.build.man.append(m)
|
||||
|
||||
return ManHolder(m)
|
||||
return m
|
||||
|
||||
@FeatureNewKwargs('subdir', '0.44.0', ['if_found'])
|
||||
@permittedKwargs({'if_found'})
|
||||
|
@ -1937,8 +1958,8 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
|
|||
'"rename" and "sources" argument lists must be the same length if "rename" is given. '
|
||||
f'Rename has {len(rename)} elements and sources has {len(sources)}.')
|
||||
|
||||
data = DataHolder(build.Data(sources, install_dir, install_mode, self.subproject, rename))
|
||||
self.build.data.append(data.held_object)
|
||||
data = build.Data(sources, install_dir, install_mode, self.subproject, rename)
|
||||
self.build.data.append(data)
|
||||
return data
|
||||
|
||||
@FeatureNewKwargs('install_subdir', '0.42.0', ['exclude_files', 'exclude_directories'])
|
||||
|
@ -1986,7 +2007,7 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
|
|||
install_mode = self._get_kwarg_install_mode(kwargs)
|
||||
idir = build.InstallDir(self.subdir, subdir, install_dir, install_mode, exclude, strip_directory, self.subproject)
|
||||
self.build.install_dirs.append(idir)
|
||||
return InstallDirHolder(idir)
|
||||
return idir
|
||||
|
||||
@FeatureNewKwargs('configure_file', '0.47.0', ['copy', 'output_format', 'install_mode', 'encoding'])
|
||||
@FeatureNewKwargs('configure_file', '0.46.0', ['format'])
|
||||
|
@ -2083,8 +2104,8 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
|
|||
conf = kwargs['configuration']
|
||||
if isinstance(conf, dict):
|
||||
FeatureNew.single_use('configure_file.configuration dictionary', '0.49.0', self.subproject)
|
||||
conf = ConfigurationDataHolder(self.subproject, conf)
|
||||
elif not isinstance(conf, ConfigurationDataHolder):
|
||||
conf = ConfigurationDataObject(self.subproject, conf)
|
||||
elif not isinstance(conf, ConfigurationDataObject):
|
||||
raise InterpreterException('Argument "configuration" is not of type configuration_data')
|
||||
mlog.log('Configuring', mlog.bold(output), 'using configuration')
|
||||
if len(inputs) > 1:
|
||||
|
@ -2180,13 +2201,13 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
|
|||
return mesonlib.File.from_built_file(self.subdir, output)
|
||||
|
||||
def extract_incdirs(self, kwargs):
|
||||
prospectives = unholder(extract_as_list(kwargs, 'include_directories'))
|
||||
prospectives = extract_as_list(kwargs, 'include_directories')
|
||||
result = []
|
||||
for p in prospectives:
|
||||
if isinstance(p, build.IncludeDirs):
|
||||
result.append(p)
|
||||
elif isinstance(p, str):
|
||||
result.append(self.build_incdir_object([p]).held_object)
|
||||
result.append(self.build_incdir_object([p]))
|
||||
else:
|
||||
raise InterpreterException('Include directory objects can only be created from strings or include directories.')
|
||||
return result
|
||||
|
@ -2196,7 +2217,7 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
|
|||
def func_include_directories(self, node, args, kwargs):
|
||||
return self.build_incdir_object(args, kwargs.get('is_system', False))
|
||||
|
||||
def build_incdir_object(self, incdir_strings: T.List[str], is_system: bool = False) -> IncludeDirsHolder:
|
||||
def build_incdir_object(self, incdir_strings: T.List[str], is_system: bool = False) -> build.IncludeDirs:
|
||||
if not isinstance(is_system, bool):
|
||||
raise InvalidArguments('Is_system must be boolean.')
|
||||
src_root = self.environment.get_source_dir()
|
||||
|
@ -2251,7 +2272,7 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
|
|||
absdir_build = os.path.join(absbase_build, a)
|
||||
if not os.path.isdir(absdir_src) and not os.path.isdir(absdir_build):
|
||||
raise InvalidArguments('Include dir %s does not exist.' % a)
|
||||
i = IncludeDirsHolder(build.IncludeDirs(self.subdir, incdir_strings, is_system))
|
||||
i = build.IncludeDirs(self.subdir, incdir_strings, is_system)
|
||||
return i
|
||||
|
||||
@permittedKwargs({'exe_wrapper', 'gdb', 'timeout_multiplier', 'env', 'is_default',
|
||||
|
@ -2392,7 +2413,7 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
|
|||
raise InterpreterException('environment first argument must be a dictionary or a list')
|
||||
else:
|
||||
initial_values = {}
|
||||
return EnvironmentVariablesHolder(initial_values, self.subproject)
|
||||
return EnvironmentVariablesObject(initial_values, self.subproject)
|
||||
|
||||
@stringArgs
|
||||
@noKwargs
|
||||
|
@ -2477,10 +2498,10 @@ Try setting b_lundef to false instead.'''.format(self.coredata.options[OptionKey
|
|||
results.append(mesonlib.File.from_source_file(self.environment.source_dir, self.subdir, s))
|
||||
elif isinstance(s, mesonlib.File):
|
||||
results.append(s)
|
||||
elif isinstance(s, (GeneratedListHolder, TargetHolder,
|
||||
CustomTargetIndexHolder,
|
||||
GeneratedObjectsHolder)):
|
||||
results.append(unholder(s))
|
||||
elif isinstance(s, (build.GeneratedList, build.BuildTarget,
|
||||
build.CustomTargetIndex, build.CustomTarget,
|
||||
build.GeneratedList)):
|
||||
results.append(s)
|
||||
else:
|
||||
raise InterpreterException(f'Source item is {s!r} instead of '
|
||||
'string or File-type object')
|
||||
|
@ -2554,7 +2575,7 @@ Try setting b_lundef to false instead.'''.format(self.coredata.options[OptionKey
|
|||
else:
|
||||
raise InterpreterException('Unknown default_library value: %s.', default_library)
|
||||
|
||||
def build_target(self, node, args, kwargs, targetholder):
|
||||
def build_target(self, node, args, kwargs, targetclass):
|
||||
@FeatureNewKwargs('build target', '0.42.0', ['rust_crate_type', 'build_rpath', 'implicit_include_directories'])
|
||||
@FeatureNewKwargs('build target', '0.41.0', ['rust_args'])
|
||||
@FeatureNewKwargs('build target', '0.40.0', ['build_by_default'])
|
||||
|
@ -2578,18 +2599,8 @@ Try setting b_lundef to false instead.'''.format(self.coredata.options[OptionKey
|
|||
ef = extract_as_list(kwargs, 'extra_files')
|
||||
kwargs['extra_files'] = self.source_strings_to_files(ef)
|
||||
self.check_sources_exist(os.path.join(self.source_root, self.subdir), sources)
|
||||
if targetholder == ExecutableHolder:
|
||||
targetclass = build.Executable
|
||||
elif targetholder == SharedLibraryHolder:
|
||||
targetclass = build.SharedLibrary
|
||||
elif targetholder == SharedModuleHolder:
|
||||
targetclass = build.SharedModule
|
||||
elif targetholder == StaticLibraryHolder:
|
||||
targetclass = build.StaticLibrary
|
||||
elif targetholder == JarHolder:
|
||||
targetclass = build.Jar
|
||||
else:
|
||||
mlog.debug('Unknown target type:', str(targetholder))
|
||||
if targetclass not in {build.Executable, build.SharedLibrary, build.SharedModule, build.StaticLibrary, build.Jar}:
|
||||
mlog.debug('Unknown target type:', str(targetclass))
|
||||
raise RuntimeError('Unreachable code')
|
||||
self.kwarg_strings_to_includedirs(kwargs)
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import os
|
||||
import shlex
|
||||
import subprocess
|
||||
import re
|
||||
import copy
|
||||
import textwrap
|
||||
|
||||
from pathlib import Path, PurePath
|
||||
|
||||
|
@ -33,22 +33,22 @@ if T.TYPE_CHECKING:
|
|||
from ..envconfig import MachineInfo
|
||||
|
||||
|
||||
def extract_required_kwarg(kwargs: 'kwargs.ExtractRequired', subproject: str,
|
||||
feature_check: T.Optional['FeatureCheckBase'] = None,
|
||||
def extract_required_kwarg(kwargs: 'kwargs.ExtractRequired',
|
||||
subproject: str,
|
||||
feature_check: T.Optional[FeatureCheckBase] = None,
|
||||
default: bool = True) -> T.Tuple[bool, bool, T.Optional[str]]:
|
||||
val = kwargs.get('required', default)
|
||||
disabled = False
|
||||
required = False
|
||||
feature: T.Optional[str] = None
|
||||
if isinstance(val, FeatureOptionHolder):
|
||||
if isinstance(val, coredata.UserFeatureOption):
|
||||
if not feature_check:
|
||||
feature_check = FeatureNew('User option "feature"', '0.47.0')
|
||||
feature_check.use(subproject)
|
||||
option = val.held_object
|
||||
feature = val.name
|
||||
if option.is_disabled():
|
||||
if val.is_disabled():
|
||||
disabled = True
|
||||
elif option.is_enabled():
|
||||
elif val.is_enabled():
|
||||
required = True
|
||||
elif isinstance(val, bool):
|
||||
required = val
|
||||
|
@ -62,9 +62,9 @@ def extract_required_kwarg(kwargs: 'kwargs.ExtractRequired', subproject: str,
|
|||
|
||||
return disabled, required, feature
|
||||
|
||||
def extract_search_dirs(kwargs):
|
||||
search_dirs = mesonlib.stringlistify(kwargs.get('dirs', []))
|
||||
search_dirs = [Path(d).expanduser() for d in search_dirs]
|
||||
def extract_search_dirs(kwargs: T.Dict[str, T.Any]) -> T.List[str]:
|
||||
search_dirs_str = mesonlib.stringlistify(kwargs.get('dirs', []))
|
||||
search_dirs = [Path(d).expanduser() for d in search_dirs_str]
|
||||
for d in search_dirs:
|
||||
if mesonlib.is_windows() and d.root.startswith('\\'):
|
||||
# a Unix-path starting with `/` that is not absolute on Windows.
|
||||
|
@ -75,12 +75,12 @@ def extract_search_dirs(kwargs):
|
|||
return list(map(str, search_dirs))
|
||||
|
||||
class FeatureOptionHolder(ObjectHolder[coredata.UserFeatureOption]):
|
||||
def __init__(self, env: 'Environment', name: str, option: coredata.UserFeatureOption):
|
||||
super().__init__(option)
|
||||
def __init__(self, option: coredata.UserFeatureOption, interpreter: 'Interpreter'):
|
||||
super().__init__(option, interpreter)
|
||||
if option and option.is_auto():
|
||||
# TODO: we need to case here because options is not a TypedDict
|
||||
self.held_object = T.cast(coredata.UserFeatureOption, env.coredata.options[OptionKey('auto_features')])
|
||||
self.name = name
|
||||
self.held_object = T.cast(coredata.UserFeatureOption, self.env.coredata.options[OptionKey('auto_features')])
|
||||
self.held_object.name = option.name
|
||||
self.methods.update({'enabled': self.enabled_method,
|
||||
'disabled': self.disabled_method,
|
||||
'allowed': self.allowed_method,
|
||||
|
@ -90,34 +90,36 @@ class FeatureOptionHolder(ObjectHolder[coredata.UserFeatureOption]):
|
|||
})
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
def value(self) -> str:
|
||||
return 'disabled' if not self.held_object else self.held_object.value
|
||||
|
||||
def as_disabled(self):
|
||||
return FeatureOptionHolder(None, self.name, None)
|
||||
def as_disabled(self) -> coredata.UserFeatureOption:
|
||||
disabled = copy.deepcopy(self.held_object)
|
||||
disabled.value = 'disabled'
|
||||
return disabled
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def enabled_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def enabled_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> bool:
|
||||
return self.value == 'enabled'
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def disabled_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def disabled_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> bool:
|
||||
return self.value == 'disabled'
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def allowed_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def allowed_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> bool:
|
||||
return not self.value == 'disabled'
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def auto_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def auto_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> bool:
|
||||
return self.value == 'auto'
|
||||
|
||||
@permittedKwargs({'error_message'})
|
||||
def require_method(self, args, kwargs):
|
||||
def require_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> coredata.UserFeatureOption:
|
||||
if len(args) != 1:
|
||||
raise InvalidArguments('Expected 1 argument, got %d.' % (len(args), ))
|
||||
if not isinstance(args[0], bool):
|
||||
|
@ -126,38 +128,57 @@ class FeatureOptionHolder(ObjectHolder[coredata.UserFeatureOption]):
|
|||
if error_message and not isinstance(error_message, str):
|
||||
raise InterpreterException("Error message must be a string.")
|
||||
if args[0]:
|
||||
return self
|
||||
return copy.deepcopy(self.held_object)
|
||||
|
||||
assert isinstance(error_message, str)
|
||||
if self.value == 'enabled':
|
||||
prefix = 'Feature {} cannot be enabled'.format(self.name)
|
||||
prefix = 'Feature {} cannot be enabled'.format(self.held_object.name)
|
||||
prefix = prefix + ': ' if error_message else ''
|
||||
raise InterpreterException(prefix + error_message)
|
||||
return self.as_disabled()
|
||||
|
||||
@permittedKwargs({})
|
||||
def disable_auto_if_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def disable_auto_if_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> coredata.UserFeatureOption:
|
||||
if len(args) != 1:
|
||||
raise InvalidArguments('Expected 1 argument, got %d.' % (len(args), ))
|
||||
if not isinstance(args[0], bool):
|
||||
raise InvalidArguments('boolean argument expected.')
|
||||
return self if self.value != 'auto' or not args[0] else self.as_disabled()
|
||||
return copy.deepcopy(self.held_object) if self.value != 'auto' or not args[0] else self.as_disabled()
|
||||
|
||||
|
||||
class RunProcess(MesonInterpreterObject):
|
||||
|
||||
def __init__(self, cmd, args, env, source_dir, build_dir, subdir, mesonintrospect, in_builddir=False, check=False, capture=True):
|
||||
def __init__(self,
|
||||
cmd: ExternalProgram,
|
||||
args: T.List[str],
|
||||
env: build.EnvironmentVariables,
|
||||
source_dir: str,
|
||||
build_dir: str,
|
||||
subdir: str,
|
||||
mesonintrospect: T.List[str],
|
||||
in_builddir: bool = False,
|
||||
check: bool = False,
|
||||
capture: bool = True) -> None:
|
||||
super().__init__()
|
||||
if not isinstance(cmd, ExternalProgram):
|
||||
raise AssertionError('BUG: RunProcess must be passed an ExternalProgram')
|
||||
self.capture = capture
|
||||
pc, self.stdout, self.stderr = self.run_command(cmd, args, env, source_dir, build_dir, subdir, mesonintrospect, in_builddir, check)
|
||||
self.returncode = pc.returncode
|
||||
self.returncode, self.stdout, self.stderr = self.run_command(cmd, args, env, source_dir, build_dir, subdir, mesonintrospect, in_builddir, check)
|
||||
self.methods.update({'returncode': self.returncode_method,
|
||||
'stdout': self.stdout_method,
|
||||
'stderr': self.stderr_method,
|
||||
})
|
||||
|
||||
def run_command(self, cmd, args, env, source_dir, build_dir, subdir, mesonintrospect, in_builddir, check=False):
|
||||
def run_command(self,
|
||||
cmd: ExternalProgram,
|
||||
args: T.List[str],
|
||||
env: build.EnvironmentVariables,
|
||||
source_dir: str,
|
||||
build_dir: str,
|
||||
subdir: str,
|
||||
mesonintrospect: T.List[str],
|
||||
in_builddir: bool,
|
||||
check: bool = False) -> T.Tuple[int, str, str]:
|
||||
command_array = cmd.get_command() + args
|
||||
menv = {'MESON_SOURCE_ROOT': source_dir,
|
||||
'MESON_BUILD_ROOT': build_dir,
|
||||
|
@ -188,28 +209,33 @@ class RunProcess(MesonInterpreterObject):
|
|||
if check and p.returncode != 0:
|
||||
raise InterpreterException('Command "{}" failed with status {}.'.format(' '.join(command_array), p.returncode))
|
||||
|
||||
return p, o, e
|
||||
return p.returncode, o, e
|
||||
except FileNotFoundError:
|
||||
raise InterpreterException('Could not execute command "%s".' % ' '.join(command_array))
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def returncode_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def returncode_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> int:
|
||||
return self.returncode
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def stdout_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def stdout_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
|
||||
return self.stdout
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def stderr_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def stderr_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
|
||||
return self.stderr
|
||||
|
||||
class EnvironmentVariablesHolder(MutableInterpreterObject, ObjectHolder[build.EnvironmentVariables]):
|
||||
def __init__(self, initial_values=None, subproject: str = ''):
|
||||
super().__init__(build.EnvironmentVariables(), subproject=subproject)
|
||||
# TODO: Parsing the initial values should be either done directly in the
|
||||
# `Interpreter` or in `build.EnvironmentVariables`. This way, this class
|
||||
# can be converted into a pure object holder.
|
||||
class EnvironmentVariablesObject(MutableInterpreterObject, MesonInterpreterObject):
|
||||
# TODO: Move the type cheking for initial_values out of this class and replace T.Any
|
||||
def __init__(self, initial_values: T.Optional[T.Any] = None, subproject: str = ''):
|
||||
super().__init__(subproject=subproject)
|
||||
self.vars = build.EnvironmentVariables()
|
||||
self.methods.update({'set': self.set_method,
|
||||
'append': self.append_method,
|
||||
'prepend': self.prepend_method,
|
||||
|
@ -232,18 +258,18 @@ class EnvironmentVariablesHolder(MutableInterpreterObject, ObjectHolder[build.En
|
|||
|
||||
def __repr__(self) -> str:
|
||||
repr_str = "<{0}: {1}>"
|
||||
return repr_str.format(self.__class__.__name__, self.held_object.envvars)
|
||||
return repr_str.format(self.__class__.__name__, self.vars.envvars)
|
||||
|
||||
def unpack_separator(self, kwargs: T.Dict[str, T.Any]) -> str:
|
||||
separator = kwargs.get('separator', os.pathsep)
|
||||
if not isinstance(separator, str):
|
||||
raise InterpreterException("EnvironmentVariablesHolder methods 'separator'"
|
||||
raise InterpreterException("EnvironmentVariablesObject methods 'separator'"
|
||||
" argument needs to be a string.")
|
||||
return separator
|
||||
|
||||
def warn_if_has_name(self, name: str) -> None:
|
||||
# Multiple append/prepend operations was not supported until 0.58.0.
|
||||
if self.held_object.has_name(name):
|
||||
if self.vars.has_name(name):
|
||||
m = f'Overriding previous value of environment variable {name!r} with a new one'
|
||||
FeatureNew('0.58.0', m).use(self.subproject)
|
||||
|
||||
|
@ -253,7 +279,7 @@ class EnvironmentVariablesHolder(MutableInterpreterObject, ObjectHolder[build.En
|
|||
def set_method(self, args: T.Tuple[str, T.List[str]], kwargs: T.Dict[str, T.Any]) -> None:
|
||||
name, values = args
|
||||
separator = self.unpack_separator(kwargs)
|
||||
self.held_object.set(name, values, separator)
|
||||
self.vars.set(name, values, separator)
|
||||
|
||||
@stringArgs
|
||||
@permittedKwargs({'separator'})
|
||||
|
@ -262,7 +288,7 @@ class EnvironmentVariablesHolder(MutableInterpreterObject, ObjectHolder[build.En
|
|||
name, values = args
|
||||
separator = self.unpack_separator(kwargs)
|
||||
self.warn_if_has_name(name)
|
||||
self.held_object.append(name, values, separator)
|
||||
self.vars.append(name, values, separator)
|
||||
|
||||
@stringArgs
|
||||
@permittedKwargs({'separator'})
|
||||
|
@ -271,13 +297,14 @@ class EnvironmentVariablesHolder(MutableInterpreterObject, ObjectHolder[build.En
|
|||
name, values = args
|
||||
separator = self.unpack_separator(kwargs)
|
||||
self.warn_if_has_name(name)
|
||||
self.held_object.prepend(name, values, separator)
|
||||
self.vars.prepend(name, values, separator)
|
||||
|
||||
|
||||
class ConfigurationDataHolder(MutableInterpreterObject, ObjectHolder[build.ConfigurationData]):
|
||||
def __init__(self, subproject: str, initial_values=None):
|
||||
class ConfigurationDataObject(MutableInterpreterObject, MesonInterpreterObject):
|
||||
def __init__(self, subproject: str, initial_values: T.Optional[T.Dict[str, T.Any]] = None) -> None:
|
||||
self.used = False # These objects become immutable after use in configure_file.
|
||||
super().__init__(build.ConfigurationData(), subproject=subproject)
|
||||
super().__init__(subproject=subproject)
|
||||
self.conf_data = build.ConfigurationData()
|
||||
self.methods.update({'set': self.set_method,
|
||||
'set10': self.set10_method,
|
||||
'set_quoted': self.set_quoted_method,
|
||||
|
@ -291,15 +318,15 @@ class ConfigurationDataHolder(MutableInterpreterObject, ObjectHolder[build.Confi
|
|||
for k, v in initial_values.items():
|
||||
self.set_method([k, v], {})
|
||||
elif initial_values:
|
||||
raise AssertionError('Unsupported ConfigurationDataHolder initial_values')
|
||||
raise AssertionError('Unsupported ConfigurationDataObject initial_values')
|
||||
|
||||
def is_used(self):
|
||||
def is_used(self) -> bool:
|
||||
return self.used
|
||||
|
||||
def mark_used(self):
|
||||
def mark_used(self) -> None:
|
||||
self.used = True
|
||||
|
||||
def validate_args(self, args, kwargs):
|
||||
def validate_args(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> T.Tuple[str, T.Union[str, int, bool], T.Optional[str]]:
|
||||
if len(args) == 1 and isinstance(args[0], list) and len(args[0]) == 2:
|
||||
mlog.deprecation('Passing a list as the single argument to '
|
||||
'configuration_data.set is deprecated. This will '
|
||||
|
@ -323,85 +350,101 @@ class ConfigurationDataHolder(MutableInterpreterObject, ObjectHolder[build.Confi
|
|||
if desc is not None and not isinstance(desc, str):
|
||||
raise InterpreterException('Description must be a string.')
|
||||
|
||||
return name, val, desc
|
||||
# TODO: Remove the cast once we get rid of the deprecation
|
||||
return name, T.cast(T.Union[str, bool, int], val), desc
|
||||
|
||||
@noArgsFlattening
|
||||
def set_method(self, args, kwargs):
|
||||
def set_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> None:
|
||||
(name, val, desc) = self.validate_args(args, kwargs)
|
||||
self.held_object.values[name] = (val, desc)
|
||||
self.conf_data.values[name] = (val, desc)
|
||||
|
||||
def set_quoted_method(self, args, kwargs):
|
||||
def set_quoted_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> None:
|
||||
(name, val, desc) = self.validate_args(args, kwargs)
|
||||
if not isinstance(val, str):
|
||||
raise InterpreterException("Second argument to set_quoted must be a string.")
|
||||
escaped_val = '\\"'.join(val.split('"'))
|
||||
self.held_object.values[name] = ('"' + escaped_val + '"', desc)
|
||||
self.conf_data.values[name] = ('"' + escaped_val + '"', desc)
|
||||
|
||||
def set10_method(self, args, kwargs):
|
||||
def set10_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> None:
|
||||
(name, val, desc) = self.validate_args(args, kwargs)
|
||||
if val:
|
||||
self.held_object.values[name] = (1, desc)
|
||||
self.conf_data.values[name] = (1, desc)
|
||||
else:
|
||||
self.held_object.values[name] = (0, desc)
|
||||
self.conf_data.values[name] = (0, desc)
|
||||
|
||||
def has_method(self, args, kwargs):
|
||||
return args[0] in self.held_object.values
|
||||
def has_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> bool:
|
||||
return args[0] in self.conf_data.values
|
||||
|
||||
@FeatureNew('configuration_data.get()', '0.38.0')
|
||||
@noArgsFlattening
|
||||
def get_method(self, args, kwargs):
|
||||
def get_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> T.Union[str, int, bool]:
|
||||
if len(args) < 1 or len(args) > 2:
|
||||
raise InterpreterException('Get method takes one or two arguments.')
|
||||
if not isinstance(args[0], str):
|
||||
raise InterpreterException('The variable name must be a string.')
|
||||
name = args[0]
|
||||
if name in self.held_object:
|
||||
return self.held_object.get(name)[0]
|
||||
if name in self.conf_data:
|
||||
return self.conf_data.get(name)[0]
|
||||
if len(args) > 1:
|
||||
return args[1]
|
||||
# Assertion does not work because setting other values is still
|
||||
# supported, but deprecated. Use T.cast in the meantime (even though
|
||||
# this is a lie).
|
||||
# TODO: Fix this once the deprecation is removed
|
||||
# assert isinstance(args[1], (int, str, bool))
|
||||
return T.cast(T.Union[str, int, bool], args[1])
|
||||
raise InterpreterException('Entry %s not in configuration data.' % name)
|
||||
|
||||
@FeatureNew('configuration_data.get_unquoted()', '0.44.0')
|
||||
def get_unquoted_method(self, args, kwargs):
|
||||
def get_unquoted_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> T.Union[str, int, bool]:
|
||||
if len(args) < 1 or len(args) > 2:
|
||||
raise InterpreterException('Get method takes one or two arguments.')
|
||||
if not isinstance(args[0], str):
|
||||
raise InterpreterException('The variable name must be a string.')
|
||||
name = args[0]
|
||||
if name in self.held_object:
|
||||
val = self.held_object.get(name)[0]
|
||||
if name in self.conf_data:
|
||||
val = self.conf_data.get(name)[0]
|
||||
elif len(args) > 1:
|
||||
assert isinstance(args[1], (str, int, bool))
|
||||
val = args[1]
|
||||
else:
|
||||
raise InterpreterException('Entry %s not in configuration data.' % name)
|
||||
if val[0] == '"' and val[-1] == '"':
|
||||
if isinstance(val, str) and val[0] == '"' and val[-1] == '"':
|
||||
return val[1:-1]
|
||||
return val
|
||||
|
||||
def get(self, name):
|
||||
return self.held_object.values[name] # (val, desc)
|
||||
def get(self, name: str) -> T.Tuple[T.Union[str, int, bool], T.Optional[str]]:
|
||||
return self.conf_data.values[name]
|
||||
|
||||
@FeatureNew('configuration_data.keys()', '0.57.0')
|
||||
@noPosargs
|
||||
def keys_method(self, args, kwargs):
|
||||
def keys_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> T.List[str]:
|
||||
return sorted(self.keys())
|
||||
|
||||
def keys(self):
|
||||
return self.held_object.values.keys()
|
||||
def keys(self) -> T.List[str]:
|
||||
return list(self.conf_data.values.keys())
|
||||
|
||||
def merge_from_method(self, args, kwargs):
|
||||
def merge_from_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> None:
|
||||
if len(args) != 1:
|
||||
raise InterpreterException('Merge_from takes one positional argument.')
|
||||
from_object = args[0]
|
||||
if not isinstance(from_object, ConfigurationDataHolder):
|
||||
from_object_holder = args[0]
|
||||
if not isinstance(from_object_holder, ConfigurationDataObject):
|
||||
raise InterpreterException('Merge_from argument must be a configuration data object.')
|
||||
from_object = from_object.held_object
|
||||
from_object = from_object_holder.conf_data
|
||||
for k, v in from_object.values.items():
|
||||
self.held_object.values[k] = v
|
||||
self.conf_data.values[k] = v
|
||||
|
||||
permitted_partial_dependency_kwargs = {
|
||||
'compile_args', 'link_args', 'links', 'includes', 'sources'
|
||||
}
|
||||
|
||||
_PARTIAL_DEP_KWARGS = [
|
||||
KwargInfo('compile_args', bool, default=False),
|
||||
KwargInfo('link_args', bool, default=False),
|
||||
KwargInfo('links', bool, default=False),
|
||||
KwargInfo('includes', bool, default=False),
|
||||
KwargInfo('sources', bool, default=False),
|
||||
]
|
||||
|
||||
class DependencyHolder(ObjectHolder[Dependency]):
|
||||
def __init__(self, dep: Dependency, subproject: str):
|
||||
super().__init__(dep, subproject=subproject)
|
||||
def __init__(self, dep: Dependency, interpreter: 'Interpreter'):
|
||||
super().__init__(dep, interpreter)
|
||||
self.methods.update({'found': self.found_method,
|
||||
'type_name': self.type_name_method,
|
||||
'version': self.version_method,
|
||||
|
@ -415,35 +458,35 @@ class DependencyHolder(ObjectHolder[Dependency]):
|
|||
'as_link_whole': self.as_link_whole_method,
|
||||
})
|
||||
|
||||
def found(self):
|
||||
def found(self) -> bool:
|
||||
return self.found_method([], {})
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def type_name_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def type_name_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
|
||||
return self.held_object.type_name
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def found_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def found_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> bool:
|
||||
if self.held_object.type_name == 'internal':
|
||||
return True
|
||||
return self.held_object.found()
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def version_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def version_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
|
||||
return self.held_object.get_version()
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def name_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def name_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
|
||||
return self.held_object.get_name()
|
||||
|
||||
@FeatureDeprecated('Dependency.get_pkgconfig_variable', '0.56.0',
|
||||
'use Dependency.get_variable(pkgconfig : ...) instead')
|
||||
@permittedKwargs({'define_variable', 'default'})
|
||||
def pkgconfig_method(self, args, kwargs):
|
||||
def pkgconfig_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
|
||||
args = listify(args)
|
||||
if len(args) != 1:
|
||||
raise InterpreterException('get_pkgconfig_variable takes exactly one argument.')
|
||||
|
@ -455,8 +498,8 @@ class DependencyHolder(ObjectHolder[Dependency]):
|
|||
@FeatureNew('dep.get_configtool_variable', '0.44.0')
|
||||
@FeatureDeprecated('Dependency.get_configtool_variable', '0.56.0',
|
||||
'use Dependency.get_variable(configtool : ...) instead')
|
||||
@permittedKwargs({})
|
||||
def configtool_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def configtool_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
|
||||
args = listify(args)
|
||||
if len(args) != 1:
|
||||
raise InterpreterException('get_configtool_variable takes exactly one argument.')
|
||||
|
@ -467,16 +510,16 @@ class DependencyHolder(ObjectHolder[Dependency]):
|
|||
|
||||
@FeatureNew('dep.partial_dependency', '0.46.0')
|
||||
@noPosargs
|
||||
@permittedKwargs(permitted_partial_dependency_kwargs)
|
||||
def partial_dependency_method(self, args, kwargs):
|
||||
@typed_kwargs('dep.partial_dependency', *_PARTIAL_DEP_KWARGS)
|
||||
def partial_dependency_method(self, args: T.List[TYPE_nvar], kwargs: 'kwargs.DependencyMethodPartialDependency') -> Dependency:
|
||||
pdep = self.held_object.get_partial_dependency(**kwargs)
|
||||
return DependencyHolder(pdep, self.subproject)
|
||||
return pdep
|
||||
|
||||
@FeatureNew('dep.get_variable', '0.51.0')
|
||||
@typed_pos_args('dep.get_variable', optargs=[str])
|
||||
@permittedKwargs({'cmake', 'pkgconfig', 'configtool', 'internal', 'default_value', 'pkgconfig_define'})
|
||||
@FeatureNewKwargs('dep.get_variable', '0.54.0', ['internal'])
|
||||
def variable_method(self, args: T.Tuple[T.Optional[str]], kwargs: T.Dict[str, T.Any]) -> str:
|
||||
def variable_method(self, args: T.Tuple[T.Optional[str]], kwargs: T.Dict[str, T.Any]) -> T.Union[str, T.List[str]]:
|
||||
default_varname = args[0]
|
||||
if default_varname is not None:
|
||||
FeatureNew('0.58.0', 'Positional argument to dep.get_variable()').use(self.subproject)
|
||||
|
@ -486,129 +529,102 @@ class DependencyHolder(ObjectHolder[Dependency]):
|
|||
|
||||
@FeatureNew('dep.include_type', '0.52.0')
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def include_type_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def include_type_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
|
||||
return self.held_object.get_include_type()
|
||||
|
||||
@FeatureNew('dep.as_system', '0.52.0')
|
||||
@permittedKwargs({})
|
||||
def as_system_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def as_system_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> Dependency:
|
||||
args = listify(args)
|
||||
new_is_system = 'system'
|
||||
if len(args) > 1:
|
||||
raise InterpreterException('as_system takes only one optional value')
|
||||
if len(args) == 1:
|
||||
if not isinstance(args[0], str):
|
||||
raise InterpreterException('as_system takes exactly one string parameter')
|
||||
new_is_system = args[0]
|
||||
new_dep = self.held_object.generate_system_dependency(new_is_system)
|
||||
return DependencyHolder(new_dep, self.subproject)
|
||||
return new_dep
|
||||
|
||||
@FeatureNew('dep.as_link_whole', '0.56.0')
|
||||
@permittedKwargs({})
|
||||
@noKwargs
|
||||
@noPosargs
|
||||
def as_link_whole_method(self, args, kwargs):
|
||||
def as_link_whole_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> Dependency:
|
||||
if not isinstance(self.held_object, InternalDependency):
|
||||
raise InterpreterException('as_link_whole method is only supported on declare_dependency() objects')
|
||||
new_dep = self.held_object.generate_link_whole_dependency()
|
||||
return DependencyHolder(new_dep, self.subproject)
|
||||
return new_dep
|
||||
|
||||
class ExternalProgramHolder(ObjectHolder[ExternalProgram]):
|
||||
def __init__(self, ep: ExternalProgram, subproject: str, backend=None):
|
||||
super().__init__(ep, subproject=subproject)
|
||||
self.backend = backend
|
||||
def __init__(self, ep: ExternalProgram, interpreter: 'Interpreter') -> None:
|
||||
super().__init__(ep, interpreter)
|
||||
self.methods.update({'found': self.found_method,
|
||||
'path': self.path_method,
|
||||
'full_path': self.full_path_method})
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def found_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def found_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> bool:
|
||||
return self.found()
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
@noKwargs
|
||||
@FeatureDeprecated('ExternalProgram.path', '0.55.0',
|
||||
'use ExternalProgram.full_path() instead')
|
||||
def path_method(self, args, kwargs):
|
||||
def path_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
|
||||
return self._full_path()
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
@noKwargs
|
||||
@FeatureNew('ExternalProgram.full_path', '0.55.0')
|
||||
def full_path_method(self, args, kwargs):
|
||||
def full_path_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
|
||||
return self._full_path()
|
||||
|
||||
def _full_path(self):
|
||||
def _full_path(self) -> str:
|
||||
exe = self.held_object
|
||||
# TODO: How is this case even possible? Why can this hold a build.Executable?
|
||||
if isinstance(exe, build.Executable):
|
||||
return self.backend.get_target_filename_abs(exe)
|
||||
assert self.interpreter.backend is not None
|
||||
return self.interpreter.backend.get_target_filename_abs(exe)
|
||||
if not self.found():
|
||||
raise InterpreterException('Unable to get the path of a not-found external program')
|
||||
path = exe.get_path()
|
||||
assert path is not None
|
||||
return exe.get_path()
|
||||
|
||||
def found(self):
|
||||
def found(self) -> bool:
|
||||
return isinstance(self.held_object, build.Executable) or self.held_object.found()
|
||||
|
||||
def get_command(self):
|
||||
return self.held_object.get_command()
|
||||
|
||||
def get_name(self):
|
||||
exe = self.held_object
|
||||
if isinstance(exe, build.Executable):
|
||||
return exe.name
|
||||
return exe.get_name()
|
||||
|
||||
class ExternalLibraryHolder(ObjectHolder[ExternalLibrary]):
|
||||
def __init__(self, el: ExternalLibrary, subproject: str):
|
||||
super().__init__(el, subproject=subproject)
|
||||
def __init__(self, el: ExternalLibrary, interpreter: 'Interpreter'):
|
||||
super().__init__(el, interpreter)
|
||||
self.methods.update({'found': self.found_method,
|
||||
'type_name': self.type_name_method,
|
||||
'partial_dependency': self.partial_dependency_method,
|
||||
})
|
||||
|
||||
def found(self):
|
||||
return self.held_object.found()
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def type_name_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def type_name_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
|
||||
return self.held_object.type_name
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def found_method(self, args, kwargs):
|
||||
return self.found()
|
||||
|
||||
def get_name(self):
|
||||
return self.held_object.name
|
||||
|
||||
def get_compile_args(self):
|
||||
return self.held_object.get_compile_args()
|
||||
|
||||
def get_link_args(self):
|
||||
return self.held_object.get_link_args()
|
||||
|
||||
def get_exe_args(self):
|
||||
return self.held_object.get_exe_args()
|
||||
@noKwargs
|
||||
def found_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> bool:
|
||||
return self.held_object.found()
|
||||
|
||||
@FeatureNew('dep.partial_dependency', '0.46.0')
|
||||
@noPosargs
|
||||
@permittedKwargs(permitted_partial_dependency_kwargs)
|
||||
def partial_dependency_method(self, args, kwargs):
|
||||
@typed_kwargs('dep.partial_dependency', *_PARTIAL_DEP_KWARGS)
|
||||
def partial_dependency_method(self, args: T.List[TYPE_nvar], kwargs: 'kwargs.DependencyMethodPartialDependency') -> Dependency:
|
||||
pdep = self.held_object.get_partial_dependency(**kwargs)
|
||||
return DependencyHolder(pdep, self.subproject)
|
||||
|
||||
|
||||
class GeneratedListHolder(ObjectHolder[build.GeneratedList]):
|
||||
def __init__(self, arg1: 'build.GeneratedList'):
|
||||
super().__init__(arg1)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
r = '<{}: {!r}>'
|
||||
return r.format(self.__class__.__name__, self.held_object.get_outputs())
|
||||
|
||||
return pdep
|
||||
|
||||
# A machine that's statically known from the cross file
|
||||
class MachineHolder(ObjectHolder['MachineInfo']):
|
||||
def __init__(self, machine_info: 'MachineInfo'):
|
||||
super().__init__(machine_info)
|
||||
def __init__(self, machine_info: 'MachineInfo', interpreter: 'Interpreter'):
|
||||
super().__init__(machine_info, interpreter)
|
||||
self.methods.update({'system': self.system_method,
|
||||
'cpu': self.cpu_method,
|
||||
'cpu_family': self.cpu_family_method,
|
||||
|
@ -616,88 +632,45 @@ class MachineHolder(ObjectHolder['MachineInfo']):
|
|||
})
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def cpu_family_method(self, args: T.List[TYPE_var], kwargs: TYPE_nkwargs) -> str:
|
||||
@noKwargs
|
||||
def cpu_family_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
|
||||
return self.held_object.cpu_family
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def cpu_method(self, args: T.List[TYPE_var], kwargs: TYPE_nkwargs) -> str:
|
||||
@noKwargs
|
||||
def cpu_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
|
||||
return self.held_object.cpu
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def system_method(self, args: T.List[TYPE_var], kwargs: TYPE_nkwargs) -> str:
|
||||
@noKwargs
|
||||
def system_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
|
||||
return self.held_object.system
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def endian_method(self, args: T.List[TYPE_var], kwargs: TYPE_nkwargs) -> str:
|
||||
@noKwargs
|
||||
def endian_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
|
||||
return self.held_object.endian
|
||||
|
||||
class IncludeDirsHolder(ObjectHolder[build.IncludeDirs]):
|
||||
def __init__(self, idobj: build.IncludeDirs):
|
||||
super().__init__(idobj)
|
||||
pass
|
||||
|
||||
class FileHolder(ObjectHolder[mesonlib.File]):
|
||||
def __init__(self, fobj: mesonlib.File):
|
||||
super().__init__(fobj)
|
||||
pass
|
||||
|
||||
class HeadersHolder(ObjectHolder[build.Headers]):
|
||||
def __init__(self, obj: build.Headers):
|
||||
super().__init__(obj)
|
||||
|
||||
def set_install_subdir(self, subdir):
|
||||
self.held_object.install_subdir = subdir
|
||||
|
||||
def get_install_subdir(self):
|
||||
return self.held_object.install_subdir
|
||||
|
||||
def get_sources(self):
|
||||
return self.held_object.sources
|
||||
|
||||
def get_custom_install_dir(self):
|
||||
return self.held_object.custom_install_dir
|
||||
|
||||
def get_custom_install_mode(self):
|
||||
return self.held_object.custom_install_mode
|
||||
pass
|
||||
|
||||
class DataHolder(ObjectHolder[build.Data]):
|
||||
def __init__(self, data: build.Data):
|
||||
super().__init__(data)
|
||||
pass
|
||||
|
||||
def get_source_subdir(self):
|
||||
return self.held_object.source_subdir
|
||||
|
||||
def get_sources(self):
|
||||
return self.held_object.sources
|
||||
|
||||
def get_install_dir(self):
|
||||
return self.held_object.install_dir
|
||||
|
||||
class InstallDirHolder(ObjectHolder[build.IncludeDirs]):
|
||||
def __init__(self, obj: build.InstallDir):
|
||||
super().__init__(obj)
|
||||
class InstallDirHolder(ObjectHolder[build.InstallDir]):
|
||||
pass
|
||||
|
||||
class ManHolder(ObjectHolder[build.Man]):
|
||||
def __init__(self, obj: build.Man):
|
||||
super().__init__(obj)
|
||||
|
||||
def get_custom_install_dir(self) -> T.Optional[str]:
|
||||
return self.held_object.custom_install_dir
|
||||
|
||||
def get_custom_install_mode(self) -> T.Optional[FileMode]:
|
||||
return self.held_object.custom_install_mode
|
||||
|
||||
def locale(self) -> T.Optional[str]:
|
||||
return self.held_object.locale
|
||||
|
||||
def get_sources(self) -> T.List[mesonlib.File]:
|
||||
return self.held_object.sources
|
||||
pass
|
||||
|
||||
class GeneratedObjectsHolder(ObjectHolder[build.ExtractedObjects]):
|
||||
def __init__(self, held_object: build.ExtractedObjects):
|
||||
super().__init__(held_object)
|
||||
pass
|
||||
|
||||
class Test(MesonInterpreterObject):
|
||||
def __init__(self, name: str, project: str, suite: T.List[str], exe: build.Executable,
|
||||
|
@ -720,17 +693,27 @@ class Test(MesonInterpreterObject):
|
|||
self.protocol = TestProtocol.from_str(protocol)
|
||||
self.priority = priority
|
||||
|
||||
def get_exe(self):
|
||||
def get_exe(self) -> build.Executable:
|
||||
return self.exe
|
||||
|
||||
def get_name(self):
|
||||
def get_name(self) -> str:
|
||||
return self.name
|
||||
|
||||
class SubprojectHolder(ObjectHolder[T.Optional['Interpreter']]):
|
||||
class NullSubprojectInterpreter(HoldableObject):
|
||||
pass
|
||||
|
||||
def __init__(self, subinterpreter: T.Optional['Interpreter'], subdir: str, warnings=0, disabled_feature=None,
|
||||
exception=None):
|
||||
super().__init__(subinterpreter)
|
||||
# TODO: This should really be an `ObjectHolder`, but the additional stuff in this
|
||||
# class prevents this. Thus, this class should be split into a pure
|
||||
# `ObjectHolder` and a class specifically for stroing in `Interpreter`.
|
||||
class SubprojectHolder(MesonInterpreterObject):
|
||||
|
||||
def __init__(self, subinterpreter: T.Union['Interpreter', NullSubprojectInterpreter],
|
||||
subdir: str,
|
||||
warnings: int = 0,
|
||||
disabled_feature: T.Optional[str] = None,
|
||||
exception: T.Optional[MesonException] = None) -> None:
|
||||
super().__init__()
|
||||
self.held_object = subinterpreter
|
||||
self.warnings = warnings
|
||||
self.disabled_feature = disabled_feature
|
||||
self.exception = exception
|
||||
|
@ -740,20 +723,20 @@ class SubprojectHolder(ObjectHolder[T.Optional['Interpreter']]):
|
|||
})
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def found_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def found_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> bool:
|
||||
return self.found()
|
||||
|
||||
def found(self):
|
||||
return self.held_object is not None
|
||||
def found(self) -> bool:
|
||||
return not isinstance(self.held_object, NullSubprojectInterpreter)
|
||||
|
||||
@permittedKwargs({})
|
||||
@noKwargs
|
||||
@noArgsFlattening
|
||||
@unholder_return
|
||||
def get_variable_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> T.Union[TYPE_var, InterpreterObject]:
|
||||
if len(args) < 1 or len(args) > 2:
|
||||
raise InterpreterException('Get_variable takes one or two arguments.')
|
||||
if not self.found():
|
||||
if isinstance(self.held_object, NullSubprojectInterpreter): # == not self.found()
|
||||
raise InterpreterException('Subproject "%s" disabled can\'t get_variable on it.' % (self.subdir))
|
||||
varname = args[0]
|
||||
if not isinstance(varname, str):
|
||||
|
@ -768,12 +751,8 @@ class SubprojectHolder(ObjectHolder[T.Optional['Interpreter']]):
|
|||
|
||||
raise InvalidArguments(f'Requested variable "{varname}" not found.')
|
||||
|
||||
class ModuleObjectHolder(ObjectHolder['ModuleObject']):
|
||||
def __init__(self, modobj: 'ModuleObject', interpreter: 'Interpreter'):
|
||||
super().__init__(modobj)
|
||||
self.interpreter = interpreter
|
||||
|
||||
def method_call(self, method_name, args, kwargs):
|
||||
class ModuleObjectHolder(ObjectHolder[ModuleObject]):
|
||||
def method_call(self, method_name: str, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> TYPE_var:
|
||||
modobj = self.held_object
|
||||
method = modobj.methods.get(method_name)
|
||||
if not method:
|
||||
|
@ -791,10 +770,10 @@ class ModuleObjectHolder(ObjectHolder['ModuleObject']):
|
|||
if isinstance(ret, ModuleReturnValue):
|
||||
self.interpreter.process_new_values(ret.new_objects)
|
||||
ret = ret.return_value
|
||||
return self.interpreter.holderify(ret)
|
||||
return ret
|
||||
|
||||
class MutableModuleObjectHolder(ModuleObjectHolder, MutableInterpreterObject):
|
||||
def __deepcopy__(self, memo):
|
||||
def __deepcopy__(self, memo: T.Dict[int, T.Any]) -> 'MutableModuleObjectHolder':
|
||||
# Deepcopy only held object, not interpreter
|
||||
modobj = copy.deepcopy(self.held_object, memo)
|
||||
return MutableModuleObjectHolder(modobj, self.interpreter)
|
||||
|
@ -916,7 +895,7 @@ class SharedModuleHolder(BuildTargetHolder[build.SharedModule]):
|
|||
class JarHolder(BuildTargetHolder[build.Jar]):
|
||||
pass
|
||||
|
||||
class CustomTargetIndexHolder(TargetHolder[build.CustomTargetIndex]):
|
||||
class CustomTargetIndexHolder(ObjectHolder[build.CustomTargetIndex]):
|
||||
def __init__(self, target: build.CustomTargetIndex, interp: 'Interpreter'):
|
||||
super().__init__(target, interp)
|
||||
self.methods.update({'full_path': self.full_path_method,
|
||||
|
@ -924,74 +903,69 @@ class CustomTargetIndexHolder(TargetHolder[build.CustomTargetIndex]):
|
|||
|
||||
@FeatureNew('custom_target[i].full_path', '0.54.0')
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def full_path_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def full_path_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
|
||||
assert self.interpreter.backend is not None
|
||||
return self.interpreter.backend.get_target_filename_abs(self.held_object)
|
||||
|
||||
class CustomTargetHolder(TargetHolder[build.CustomTarget]):
|
||||
class CustomTargetHolder(ObjectHolder[build.CustomTarget]):
|
||||
def __init__(self, target: 'build.CustomTarget', interp: 'Interpreter'):
|
||||
super().__init__(target, interp)
|
||||
self.methods.update({'full_path': self.full_path_method,
|
||||
'to_list': self.to_list_method,
|
||||
})
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
r = '<{} {}: {}>'
|
||||
h = self.held_object
|
||||
return r.format(self.__class__.__name__, h.get_id(), h.command)
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def full_path_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def full_path_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
|
||||
return self.interpreter.backend.get_target_filename_abs(self.held_object)
|
||||
|
||||
@FeatureNew('custom_target.to_list', '0.54.0')
|
||||
@noPosargs
|
||||
@permittedKwargs({})
|
||||
def to_list_method(self, args, kwargs):
|
||||
@noKwargs
|
||||
def to_list_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> T.List[build.CustomTargetIndex]:
|
||||
result = []
|
||||
for i in self.held_object:
|
||||
result.append(CustomTargetIndexHolder(i, self.interpreter))
|
||||
result.append(i)
|
||||
return result
|
||||
|
||||
def __getitem__(self, index):
|
||||
return CustomTargetIndexHolder(self.held_object[index], self.interpreter)
|
||||
def __getitem__(self, index: int) -> build.CustomTargetIndex:
|
||||
return self.held_object[index]
|
||||
|
||||
def __setitem__(self, index, value): # lgtm[py/unexpected-raise-in-special-method]
|
||||
def __setitem__(self, index: int, value: T.Any) -> None: # lgtm[py/unexpected-raise-in-special-method]
|
||||
raise InterpreterException('Cannot set a member of a CustomTarget')
|
||||
|
||||
def __delitem__(self, index): # lgtm[py/unexpected-raise-in-special-method]
|
||||
def __delitem__(self, index: int) -> None: # lgtm[py/unexpected-raise-in-special-method]
|
||||
raise InterpreterException('Cannot delete a member of a CustomTarget')
|
||||
|
||||
def outdir_include(self):
|
||||
return IncludeDirsHolder(build.IncludeDirs('', [], False,
|
||||
[os.path.join('@BUILD_ROOT@', self.interpreter.backend.get_target_dir(self.held_object))]))
|
||||
class RunTargetHolder(ObjectHolder[build.RunTarget]):
|
||||
pass
|
||||
|
||||
class RunTargetHolder(TargetHolder):
|
||||
def __init__(self, target, interp):
|
||||
super().__init__(target, interp)
|
||||
|
||||
def __repr__(self):
|
||||
r = '<{} {}: {}>'
|
||||
h = self.held_object
|
||||
return r.format(self.__class__.__name__, h.get_id(), h.command)
|
||||
class AliasTargetHolder(ObjectHolder[build.AliasTarget]):
|
||||
pass
|
||||
|
||||
class GeneratedListHolder(ObjectHolder[build.GeneratedList]):
|
||||
pass
|
||||
|
||||
class GeneratorHolder(ObjectHolder[build.Generator]):
|
||||
|
||||
def __init__(self, gen: 'build.Generator', interpreter: 'Interpreter'):
|
||||
self().__init__(self, gen, interpreter.subproject)
|
||||
self.interpreter = interpreter
|
||||
def __init__(self, gen: build.Generator, interpreter: 'Interpreter'):
|
||||
super().__init__(gen, interpreter)
|
||||
self.methods.update({'process': self.process_method})
|
||||
|
||||
@typed_pos_args('generator.process', min_varargs=1, varargs=(str, mesonlib.File, CustomTargetHolder, CustomTargetIndexHolder, GeneratedListHolder))
|
||||
@typed_pos_args('generator.process', min_varargs=1, varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList))
|
||||
@typed_kwargs(
|
||||
'generator.process',
|
||||
KwargInfo('preserve_path_from', str, since='0.45.0'),
|
||||
KwargInfo('extra_args', ContainerTypeInfo(list, str), listify=True, default=[]),
|
||||
)
|
||||
def process_method(self, args: T.Tuple[T.List[T.Union[str, mesonlib.File, CustomTargetHolder, CustomTargetIndexHolder, GeneratedListHolder]]],
|
||||
kwargs: 'kwargs.GeneratorProcess') -> GeneratedListHolder:
|
||||
def process_method(self,
|
||||
args: T.Tuple[T.List[T.Union[str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList]]],
|
||||
kwargs: 'kwargs.GeneratorProcess') -> build.GeneratedList:
|
||||
preserve_path_from = kwargs['preserve_path_from']
|
||||
if preserve_path_from is not None:
|
||||
preserve_path_from = os.path.normpath(preserve_path_from)
|
||||
|
@ -999,12 +973,12 @@ class GeneratorHolder(ObjectHolder[build.Generator]):
|
|||
# This is a bit of a hack. Fix properly before merging.
|
||||
raise InvalidArguments('Preserve_path_from must be an absolute path for now. Sorry.')
|
||||
|
||||
if any(isinstance(a, (CustomTargetHolder, CustomTargetIndexHolder, GeneratedListHolder)) for a in args[0]):
|
||||
if any(isinstance(a, (build.CustomTarget, build.CustomTargetIndex, build.GeneratedList)) for a in args[0]):
|
||||
FeatureNew.single_use(
|
||||
f'Calling generator.process with CustomTaget or Index of CustomTarget.',
|
||||
'0.57.0', self.interpreter.subproject)
|
||||
|
||||
gl = self.held_object.process_files(mesonlib.unholder(args[0]), self.interpreter,
|
||||
gl = self.held_object.process_files(args[0], self.interpreter,
|
||||
preserve_path_from, extra_args=kwargs['extra_args'])
|
||||
|
||||
return GeneratedListHolder(gl)
|
||||
return gl
|
||||
|
|
|
@ -4,15 +4,14 @@
|
|||
|
||||
"""Keyword Argument type annotations."""
|
||||
|
||||
from mesonbuild import coredata
|
||||
import typing as T
|
||||
|
||||
from typing_extensions import TypedDict, Literal
|
||||
|
||||
from .. import build
|
||||
from ..mesonlib import MachineChoice, File
|
||||
from .interpreterobjects import (
|
||||
BuildTargetHolder, CustomTargetHolder, EnvironmentVariablesHolder,
|
||||
FeatureOptionHolder, TargetHolder
|
||||
)
|
||||
from .interpreterobjects import EnvironmentVariablesObject
|
||||
|
||||
|
||||
class FuncAddProjectArgs(TypedDict):
|
||||
|
@ -34,13 +33,13 @@ class BaseTest(TypedDict):
|
|||
|
||||
"""Shared base for the Rust module."""
|
||||
|
||||
args: T.List[T.Union[str, File, TargetHolder]]
|
||||
args: T.List[T.Union[str, File, build.Target]]
|
||||
should_fail: bool
|
||||
timeout: int
|
||||
workdir: T.Optional[str]
|
||||
depends: T.List[T.Union[CustomTargetHolder, BuildTargetHolder]]
|
||||
depends: T.List[T.Union[build.CustomTarget, build.BuildTarget]]
|
||||
priority: int
|
||||
env: T.Union[EnvironmentVariablesHolder, T.List[str], T.Dict[str, str], str]
|
||||
env: T.Union[EnvironmentVariablesObject, T.List[str], T.Dict[str, str], str]
|
||||
suite: T.List[str]
|
||||
|
||||
|
||||
|
@ -70,7 +69,7 @@ class ExtractRequired(TypedDict):
|
|||
a boolean or a feature option should inherit it's arguments from this class.
|
||||
"""
|
||||
|
||||
required: T.Union[bool, 'FeatureOptionHolder']
|
||||
required: T.Union[bool, coredata.UserFeatureOption]
|
||||
|
||||
|
||||
class FuncGenerator(TypedDict):
|
||||
|
@ -81,7 +80,7 @@ class FuncGenerator(TypedDict):
|
|||
output: T.List[str]
|
||||
depfile: bool
|
||||
capture: bool
|
||||
depends: T.List[T.Union['BuildTargetHolder', 'CustomTargetHolder']]
|
||||
depends: T.List[T.Union[build.BuildTarget, build.CustomTarget]]
|
||||
|
||||
|
||||
class GeneratorProcess(TypedDict):
|
||||
|
@ -90,3 +89,16 @@ class GeneratorProcess(TypedDict):
|
|||
|
||||
preserve_path_from: T.Optional[str]
|
||||
extra_args: T.List[str]
|
||||
|
||||
class DependencyMethodPartialDependency(TypedDict):
|
||||
|
||||
""" Keyword Arguments for the dep.partial_dependency methods """
|
||||
|
||||
compile_args: bool
|
||||
link_args: bool
|
||||
links: bool
|
||||
includes: bool
|
||||
sources: bool
|
||||
|
||||
class BuildTargeMethodExtractAllObjects(TypedDict):
|
||||
recursive: bool
|
||||
|
|
|
@ -5,16 +5,15 @@ from .. import dependencies
|
|||
from .. import build
|
||||
from .. import mlog
|
||||
|
||||
from ..mesonlib import unholder, MachineChoice, OptionKey
|
||||
from ..mesonlib import MachineChoice, OptionKey
|
||||
from ..programs import OverrideProgram, ExternalProgram
|
||||
from ..interpreterbase import (MesonInterpreterObject, FeatureNewKwargs, FeatureNew, FeatureDeprecated,
|
||||
typed_pos_args, permittedKwargs, noArgsFlattening, noPosargs, noKwargs,
|
||||
MesonVersionString, InterpreterException)
|
||||
|
||||
from .compiler import CompilerHolder
|
||||
from .interpreterobjects import (ExecutableHolder, ExternalProgramHolder,
|
||||
CustomTargetHolder, CustomTargetIndexHolder,
|
||||
EnvironmentVariablesHolder)
|
||||
EnvironmentVariablesObject)
|
||||
|
||||
import typing as T
|
||||
|
||||
|
@ -57,11 +56,11 @@ class MesonMain(MesonInterpreterObject):
|
|||
'add_devenv': self.add_devenv_method,
|
||||
})
|
||||
|
||||
def _find_source_script(self, prog: T.Union[str, mesonlib.File, ExecutableHolder], args):
|
||||
def _find_source_script(self, prog: T.Union[str, mesonlib.File, build.Executable, ExternalProgram], args):
|
||||
|
||||
if isinstance(prog, (ExecutableHolder, ExternalProgramHolder)):
|
||||
return self.interpreter.backend.get_executable_serialisation([unholder(prog)] + args)
|
||||
found = self.interpreter.func_find_program({}, prog, {}).held_object
|
||||
if isinstance(prog, (build.Executable, ExternalProgram)):
|
||||
return self.interpreter.backend.get_executable_serialisation([prog] + args)
|
||||
found = self.interpreter.func_find_program({}, prog, {})
|
||||
es = self.interpreter.backend.get_executable_serialisation([found] + args)
|
||||
es.subproject = self.interpreter.subproject
|
||||
return es
|
||||
|
@ -254,7 +253,7 @@ class MesonMain(MesonInterpreterObject):
|
|||
for_machine = self.interpreter.machine_from_native_kwarg(kwargs)
|
||||
clist = self.interpreter.coredata.compilers[for_machine]
|
||||
if cname in clist:
|
||||
return CompilerHolder(clist[cname], self.build.environment, self.interpreter.subproject)
|
||||
return clist[cname]
|
||||
raise InterpreterException(f'Tried to access compiler for language "{cname}", not specified for {for_machine.get_lower_case_name()} machine.')
|
||||
|
||||
@noPosargs
|
||||
|
@ -375,9 +374,9 @@ class MesonMain(MesonInterpreterObject):
|
|||
|
||||
@FeatureNew('add_devenv', '0.58.0')
|
||||
@noKwargs
|
||||
@typed_pos_args('add_devenv', (str, list, dict, EnvironmentVariablesHolder))
|
||||
def add_devenv_method(self, args: T.Union[str, list, dict, EnvironmentVariablesHolder], kwargs: T.Dict[str, T.Any]) -> None:
|
||||
@typed_pos_args('add_devenv', (str, list, dict, EnvironmentVariablesObject))
|
||||
def add_devenv_method(self, args: T.Union[str, list, dict, EnvironmentVariablesObject], kwargs: T.Dict[str, T.Any]) -> None:
|
||||
env = args[0]
|
||||
if isinstance(env, (str, list, dict)):
|
||||
env = EnvironmentVariablesHolder(env)
|
||||
self.build.devenv.append(env.held_object)
|
||||
env = EnvironmentVariablesObject(env)
|
||||
self.build.devenv.append(env.vars)
|
||||
|
|
|
@ -50,6 +50,7 @@ class PythonDependency(SystemDependency):
|
|||
self.variables = python_holder.variables
|
||||
self.paths = python_holder.paths
|
||||
self.link_libpython = python_holder.link_libpython
|
||||
self.info: T.Optional[T.Dict[str, str]] = None
|
||||
if mesonlib.version_compare(self.version, '>= 3.0'):
|
||||
self.major_version = 3
|
||||
else:
|
||||
|
@ -278,12 +279,20 @@ print (json.dumps ({
|
|||
}))
|
||||
'''
|
||||
|
||||
class PythonExternalProgram(ExternalProgram):
|
||||
def __init__(self, name: str, command: T.Optional[T.List[str]] = None, ext_prog: T.Optional[ExternalProgram] = None):
|
||||
if ext_prog is None:
|
||||
super().__init__(name, command=command, silent=True)
|
||||
else:
|
||||
self.name = ext_prog.name
|
||||
self.command = ext_prog.command
|
||||
self.path = ext_prog.path
|
||||
self.info: T.Dict[str, str] = {}
|
||||
|
||||
class PythonInstallation(ExternalProgramHolder):
|
||||
def __init__(self, interpreter, python, info):
|
||||
ExternalProgramHolder.__init__(self, python, interpreter.subproject)
|
||||
self.interpreter = interpreter
|
||||
self.subproject = self.interpreter.subproject
|
||||
def __init__(self, python, interpreter):
|
||||
ExternalProgramHolder.__init__(self, python, interpreter)
|
||||
info = python.info
|
||||
prefix = self.interpreter.environment.coredata.get_option(mesonlib.OptionKey('prefix'))
|
||||
self.variables = info['variables']
|
||||
self.paths = info['paths']
|
||||
|
@ -325,11 +334,10 @@ class PythonInstallation(ExternalProgramHolder):
|
|||
# behavior. See https://github.com/mesonbuild/meson/issues/4117
|
||||
if not self.link_libpython:
|
||||
new_deps = []
|
||||
for holder in mesonlib.extract_as_list(kwargs, 'dependencies'):
|
||||
dep = holder.held_object
|
||||
for dep in mesonlib.extract_as_list(kwargs, 'dependencies'):
|
||||
if isinstance(dep, PythonDependency):
|
||||
holder = self.interpreter.holderify(dep.get_partial_dependency(compile_args=True))
|
||||
new_deps.append(holder)
|
||||
dep = dep.get_partial_dependency(compile_args=True)
|
||||
new_deps.append(dep)
|
||||
kwargs['dependencies'] = new_deps
|
||||
|
||||
suffix = self.variables.get('EXT_SUFFIX') or self.variables.get('SO') or self.variables.get('.so')
|
||||
|
@ -360,7 +368,7 @@ class PythonInstallation(ExternalProgramHolder):
|
|||
dep = PythonDependency(self, self.interpreter.environment, kwargs)
|
||||
if required and not dep.found():
|
||||
raise mesonlib.MesonException('Python dependency not found')
|
||||
return self.interpreter.holderify(dep)
|
||||
return dep
|
||||
|
||||
@permittedKwargs(['pure', 'subdir'])
|
||||
def install_sources_method(self, args, kwargs):
|
||||
|
@ -377,7 +385,7 @@ class PythonInstallation(ExternalProgramHolder):
|
|||
else:
|
||||
kwargs['install_dir'] = os.path.join(self.platlib_install_path, subdir)
|
||||
|
||||
return self.interpreter.holderify(self.interpreter.func_install_data(None, args, kwargs))
|
||||
return self.interpreter.func_install_data(None, args, kwargs)
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs(['pure', 'subdir'])
|
||||
|
@ -519,25 +527,26 @@ class PythonModule(ExtensionModule):
|
|||
|
||||
if disabled:
|
||||
mlog.log('Program', name_or_path or 'python', 'found:', mlog.red('NO'), '(disabled by:', mlog.bold(feature), ')')
|
||||
return ExternalProgramHolder(NonExistingExternalProgram(), state.subproject)
|
||||
return NonExistingExternalProgram()
|
||||
|
||||
if not name_or_path:
|
||||
python = ExternalProgram('python3', mesonlib.python_command, silent=True)
|
||||
python = PythonExternalProgram('python3', mesonlib.python_command)
|
||||
else:
|
||||
python = ExternalProgram.from_entry('python3', name_or_path)
|
||||
tmp_python = ExternalProgram.from_entry('python3', name_or_path)
|
||||
python = PythonExternalProgram('python3', ext_prog=tmp_python)
|
||||
|
||||
if not python.found() and mesonlib.is_windows():
|
||||
pythonpath = self._get_win_pythonpath(name_or_path)
|
||||
if pythonpath is not None:
|
||||
name_or_path = pythonpath
|
||||
python = ExternalProgram(name_or_path, silent=True)
|
||||
python = PythonExternalProgram(name_or_path)
|
||||
|
||||
# Last ditch effort, python2 or python3 can be named python
|
||||
# on various platforms, let's not give up just yet, if an executable
|
||||
# named python is available and has a compatible version, let's use
|
||||
# it
|
||||
if not python.found() and name_or_path in ['python2', 'python3']:
|
||||
python = ExternalProgram('python', silent=True)
|
||||
python = PythonExternalProgram('python')
|
||||
|
||||
if python.found() and want_modules:
|
||||
for mod in want_modules:
|
||||
|
@ -566,11 +575,11 @@ class PythonModule(ExtensionModule):
|
|||
if not python.found():
|
||||
if required:
|
||||
raise mesonlib.MesonException('{} not found'.format(name_or_path or 'python'))
|
||||
res = ExternalProgramHolder(NonExistingExternalProgram(), state.subproject)
|
||||
return NonExistingExternalProgram()
|
||||
elif missing_modules:
|
||||
if required:
|
||||
raise mesonlib.MesonException('{} is missing modules: {}'.format(name_or_path or 'python', ', '.join(missing_modules)))
|
||||
res = ExternalProgramHolder(NonExistingExternalProgram(), state.subproject)
|
||||
return NonExistingExternalProgram()
|
||||
else:
|
||||
# Sanity check, we expect to have something that at least quacks in tune
|
||||
try:
|
||||
|
@ -586,14 +595,17 @@ class PythonModule(ExtensionModule):
|
|||
mlog.debug(stderr)
|
||||
|
||||
if isinstance(info, dict) and 'version' in info and self._check_version(name_or_path, info['version']):
|
||||
res = PythonInstallation(self.interpreter, python, info)
|
||||
python.info = info
|
||||
return python
|
||||
else:
|
||||
res = ExternalProgramHolder(NonExistingExternalProgram(), state.subproject)
|
||||
if required:
|
||||
raise mesonlib.MesonException(f'{python} is not a valid python or it is missing setuptools')
|
||||
return NonExistingExternalProgram()
|
||||
|
||||
return res
|
||||
raise mesonlib.MesonBugException('Unreachable code was reached (PythonModule.find_installation).')
|
||||
|
||||
|
||||
def initialize(*args, **kwargs):
|
||||
return PythonModule(*args, **kwargs)
|
||||
mod = PythonModule(*args, **kwargs)
|
||||
mod.interpreter.append_holder_map(PythonExternalProgram, PythonInstallation)
|
||||
return mod
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# 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
|
||||
|
@ -20,21 +21,19 @@ import xml.etree.ElementTree as ET
|
|||
|
||||
from . import ModuleReturnValue, ExtensionModule
|
||||
from .. import build
|
||||
from .. import mesonlib
|
||||
from .. import mlog
|
||||
from ..dependencies import find_external_dependency
|
||||
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.interpreterobjects import DependencyHolder, ExternalLibraryHolder, IncludeDirsHolder, FeatureOptionHolder, GeneratedListHolder
|
||||
from ..interpreterbase import ContainerTypeInfo, FeatureDeprecated, KwargInfo, noPosargs, FeatureNew, typed_kwargs
|
||||
from ..mesonlib import MesonException, File
|
||||
from ..programs import NonExistingExternalProgram
|
||||
from ..programs import ExternalProgram, NonExistingExternalProgram
|
||||
|
||||
if T.TYPE_CHECKING:
|
||||
from . import ModuleState
|
||||
from ..dependencies.qt import QtPkgConfigDependency, QmakeQtDependency
|
||||
from ..interpreter import Interpreter
|
||||
from ..interpreter import kwargs
|
||||
from ..programs import ExternalProgram
|
||||
|
||||
QtDependencyType = T.Union[QtPkgConfigDependency, QmakeQtDependency]
|
||||
|
||||
|
@ -45,7 +44,7 @@ if T.TYPE_CHECKING:
|
|||
"""Keyword arguments for the Resource Compiler method."""
|
||||
|
||||
name: T.Optional[str]
|
||||
sources: T.List[mesonlib.FileOrString]
|
||||
sources: T.List[FileOrString]
|
||||
extra_args: T.List[str]
|
||||
method: str
|
||||
|
||||
|
@ -53,7 +52,7 @@ if T.TYPE_CHECKING:
|
|||
|
||||
"""Keyword arguments for the Ui Compiler method."""
|
||||
|
||||
sources: T.List[mesonlib.FileOrString]
|
||||
sources: T.List[FileOrString]
|
||||
extra_args: T.List[str]
|
||||
method: str
|
||||
|
||||
|
@ -61,25 +60,25 @@ if T.TYPE_CHECKING:
|
|||
|
||||
"""Keyword arguments for the Moc Compiler method."""
|
||||
|
||||
sources: T.List[mesonlib.FileOrString]
|
||||
headers: T.List[mesonlib.FileOrString]
|
||||
sources: T.List[FileOrString]
|
||||
headers: T.List[FileOrString]
|
||||
extra_args: T.List[str]
|
||||
method: str
|
||||
include_directories: T.List[T.Union[str, IncludeDirsHolder]]
|
||||
dependencies: T.List[T.Union[DependencyHolder, ExternalLibraryHolder]]
|
||||
include_directories: T.List[T.Union[str, build.IncludeDirs]]
|
||||
dependencies: T.List[T.Union[Dependency, ExternalLibrary]]
|
||||
|
||||
class PreprocessKwArgs(TypedDict):
|
||||
|
||||
sources: T.List[mesonlib.FileOrString]
|
||||
moc_sources: T.List[mesonlib.FileOrString]
|
||||
moc_headers: T.List[mesonlib.FileOrString]
|
||||
qresources: T.List[mesonlib.FileOrString]
|
||||
ui_files: T.List[mesonlib.FileOrString]
|
||||
sources: T.List[FileOrString]
|
||||
moc_sources: T.List[FileOrString]
|
||||
moc_headers: T.List[FileOrString]
|
||||
qresources: T.List[FileOrString]
|
||||
ui_files: T.List[FileOrString]
|
||||
moc_extra_arguments: T.List[str]
|
||||
rcc_extra_arguments: T.List[str]
|
||||
uic_extra_arguments: T.List[str]
|
||||
include_directories: T.List[T.Union[str, IncludeDirsHolder]]
|
||||
dependencies: T.List[T.Union[DependencyHolder, ExternalLibraryHolder]]
|
||||
include_directories: T.List[T.Union[str, build.IncludeDirs]]
|
||||
dependencies: T.List[T.Union[Dependency, ExternalLibrary]]
|
||||
method: str
|
||||
|
||||
class HasToolKwArgs(kwargs.ExtractRequired):
|
||||
|
@ -104,10 +103,10 @@ class QtBaseModule(ExtensionModule):
|
|||
def __init__(self, interpreter: 'Interpreter', qt_version: int = 5):
|
||||
ExtensionModule.__init__(self, interpreter)
|
||||
self.qt_version = qt_version
|
||||
self.moc: 'ExternalProgram' = NonExistingExternalProgram('moc')
|
||||
self.uic: 'ExternalProgram' = NonExistingExternalProgram('uic')
|
||||
self.rcc: 'ExternalProgram' = NonExistingExternalProgram('rcc')
|
||||
self.lrelease: 'ExternalProgram' = NonExistingExternalProgram('lrelease')
|
||||
self.moc: ExternalProgram = NonExistingExternalProgram('moc')
|
||||
self.uic: ExternalProgram = NonExistingExternalProgram('uic')
|
||||
self.rcc: ExternalProgram = NonExistingExternalProgram('rcc')
|
||||
self.lrelease: ExternalProgram = NonExistingExternalProgram('lrelease')
|
||||
self.methods.update({
|
||||
'has_tools': self.has_tools,
|
||||
'preprocess': self.preprocess,
|
||||
|
@ -141,14 +140,14 @@ class QtBaseModule(ExtensionModule):
|
|||
|
||||
if name == 'lrelease':
|
||||
arg = ['-version']
|
||||
elif mesonlib.version_compare(qt_dep.version, '>= 5'):
|
||||
elif version_compare(qt_dep.version, '>= 5'):
|
||||
arg = ['--version']
|
||||
else:
|
||||
arg = ['-v']
|
||||
|
||||
# Ensure that the version of qt and each tool are the same
|
||||
def get_version(p: 'ExternalProgram') -> str:
|
||||
_, out, err = mesonlib.Popen_safe(p.get_command() + arg)
|
||||
def get_version(p: ExternalProgram) -> str:
|
||||
_, out, err = Popen_safe(p.get_command() + arg)
|
||||
if b.startswith('lrelease') or not qt_dep.version.startswith('4'):
|
||||
care = out
|
||||
else:
|
||||
|
@ -157,7 +156,7 @@ class QtBaseModule(ExtensionModule):
|
|||
|
||||
p = state.find_program(b, required=False,
|
||||
version_func=get_version,
|
||||
wanted=wanted).held_object
|
||||
wanted=wanted)
|
||||
if p.found():
|
||||
setattr(self, name, p)
|
||||
|
||||
|
@ -172,7 +171,7 @@ class QtBaseModule(ExtensionModule):
|
|||
if qt.found():
|
||||
# Get all tools and then make sure that they are the right version
|
||||
self.compilers_detect(state, qt)
|
||||
if mesonlib.version_compare(qt.version, '>=5.14.0'):
|
||||
if version_compare(qt.version, '>=5.14.0'):
|
||||
self._rcc_supports_depfiles = True
|
||||
else:
|
||||
mlog.warning('rcc dependencies will not work properly until you move to Qt >= 5.14:',
|
||||
|
@ -185,7 +184,7 @@ class QtBaseModule(ExtensionModule):
|
|||
self.lrelease = NonExistingExternalProgram(name='lrelease' + suffix)
|
||||
|
||||
@staticmethod
|
||||
def _qrc_nodes(state: 'ModuleState', rcc_file: 'mesonlib.FileOrString') -> T.Tuple[str, T.List[str]]:
|
||||
def _qrc_nodes(state: 'ModuleState', rcc_file: 'FileOrString') -> T.Tuple[str, T.List[str]]:
|
||||
abspath: str
|
||||
if isinstance(rcc_file, str):
|
||||
abspath = os.path.join(state.environment.source_dir, state.subdir, rcc_file)
|
||||
|
@ -210,7 +209,7 @@ class QtBaseModule(ExtensionModule):
|
|||
except Exception:
|
||||
raise MesonException(f'Unable to parse resource file {abspath}')
|
||||
|
||||
def _parse_qrc_deps(self, state: 'ModuleState', rcc_file: 'mesonlib.FileOrString') -> T.List[File]:
|
||||
def _parse_qrc_deps(self, state: 'ModuleState', rcc_file: 'FileOrString') -> T.List[File]:
|
||||
rcc_dirname, nodes = self._qrc_nodes(state, rcc_file)
|
||||
result: T.List[File] = []
|
||||
for resource_path in nodes:
|
||||
|
@ -243,7 +242,7 @@ class QtBaseModule(ExtensionModule):
|
|||
@noPosargs
|
||||
@typed_kwargs(
|
||||
'qt.has_tools',
|
||||
KwargInfo('required', (bool, FeatureOptionHolder), default=False),
|
||||
KwargInfo('required', (bool, coredata.UserFeatureOption), default=False),
|
||||
KwargInfo('method', str, default='auto'),
|
||||
)
|
||||
def has_tools(self, state: 'ModuleState', args: T.Tuple, kwargs: 'HasToolKwArgs') -> bool:
|
||||
|
@ -351,7 +350,7 @@ class QtBaseModule(ExtensionModule):
|
|||
kwargs['extra_args'] + ['-o', '@OUTPUT@', '@INPUT@'],
|
||||
['ui_@BASENAME@.h'],
|
||||
name=f'Qt{self.qt_version} ui')
|
||||
out = GeneratedListHolder(gen.process_files(kwargs['sources'], state))
|
||||
out = gen.process_files(kwargs['sources'], state)
|
||||
return ModuleReturnValue(out, [out])
|
||||
|
||||
@FeatureNew('qt.compile_moc', '0.59.0')
|
||||
|
@ -362,8 +361,8 @@ class QtBaseModule(ExtensionModule):
|
|||
KwargInfo('headers', ContainerTypeInfo(list, (File, str)), listify=True, default=[]),
|
||||
KwargInfo('extra_args', ContainerTypeInfo(list, str), listify=True, default=[]),
|
||||
KwargInfo('method', str, default='auto'),
|
||||
KwargInfo('include_directories', ContainerTypeInfo(list, (IncludeDirsHolder, str)), listify=True, default=[]),
|
||||
KwargInfo('dependencies', ContainerTypeInfo(list, (DependencyHolder, ExternalLibraryHolder)), listify=True, default=[]),
|
||||
KwargInfo('include_directories', ContainerTypeInfo(list, (build.IncludeDirs, str)), listify=True, default=[]),
|
||||
KwargInfo('dependencies', ContainerTypeInfo(list, (Dependency, ExternalLibrary)), listify=True, default=[]),
|
||||
)
|
||||
def compile_moc(self, state: 'ModuleState', args: T.Tuple, kwargs: 'MocCompilerKwArgs') -> ModuleReturnValue:
|
||||
self._detect_tools(state, kwargs['method'])
|
||||
|
@ -378,7 +377,7 @@ class QtBaseModule(ExtensionModule):
|
|||
inc = state.get_include_args(include_dirs=kwargs['include_directories'])
|
||||
compile_args: T.List[str] = []
|
||||
for dep in kwargs['dependencies']:
|
||||
compile_args.extend([a for a in dep.held_object.get_all_compile_args() if a.startswith(('-I', '-D'))])
|
||||
compile_args.extend([a for a in dep.get_all_compile_args() if a.startswith(('-I', '-D'))])
|
||||
|
||||
output: T.List[build.GeneratedList] = []
|
||||
|
||||
|
@ -408,8 +407,8 @@ class QtBaseModule(ExtensionModule):
|
|||
KwargInfo('rcc_extra_arguments', ContainerTypeInfo(list, str), listify=True, default=[], since='0.49.0'),
|
||||
KwargInfo('uic_extra_arguments', ContainerTypeInfo(list, str), listify=True, default=[], since='0.49.0'),
|
||||
KwargInfo('method', str, default='auto'),
|
||||
KwargInfo('include_directories', ContainerTypeInfo(list, (IncludeDirsHolder, str)), listify=True, default=[]),
|
||||
KwargInfo('dependencies', ContainerTypeInfo(list, (DependencyHolder, ExternalLibraryHolder)), listify=True, default=[]),
|
||||
KwargInfo('include_directories', ContainerTypeInfo(list, (build.IncludeDirs, str)), listify=True, default=[]),
|
||||
KwargInfo('dependencies', ContainerTypeInfo(list, (Dependency, ExternalLibrary)), listify=True, default=[]),
|
||||
)
|
||||
def preprocess(self, state: 'ModuleState', args: T.List[T.Union[str, File]], kwargs: 'PreprocessKwArgs') -> ModuleReturnValue:
|
||||
_sources = args[1:]
|
||||
|
|
|
@ -14,16 +14,13 @@
|
|||
|
||||
from collections import namedtuple
|
||||
from .. import mesonlib
|
||||
from .. import build
|
||||
from ..mesonlib import listify, OrderedSet
|
||||
from . import ExtensionModule, ModuleObject, MutableModuleObject
|
||||
from ..interpreterbase import (
|
||||
noPosargs, noKwargs, permittedKwargs,
|
||||
InterpreterException, InvalidArguments, InvalidCode, FeatureNew,
|
||||
)
|
||||
from ..interpreter import (
|
||||
GeneratedListHolder, CustomTargetHolder,
|
||||
CustomTargetIndexHolder
|
||||
)
|
||||
|
||||
SourceSetRule = namedtuple('SourceSetRule', 'keys sources if_false sourcesets dependencies extra_deps')
|
||||
SourceFiles = namedtuple('SourceFiles', 'sources dependencies')
|
||||
|
@ -49,8 +46,8 @@ class SourceSet(MutableModuleObject):
|
|||
deps = []
|
||||
for x in arg:
|
||||
if isinstance(x, (str, mesonlib.File,
|
||||
GeneratedListHolder, CustomTargetHolder,
|
||||
CustomTargetIndexHolder)):
|
||||
build.GeneratedList, build.CustomTarget,
|
||||
build.CustomTargetIndex)):
|
||||
sources.append(x)
|
||||
elif hasattr(x, 'found'):
|
||||
if not allow_deps:
|
||||
|
|
|
@ -22,7 +22,6 @@ from ..mesonlib import (MesonException, Popen_safe, MachineChoice,
|
|||
get_variable_regex, do_replacement, extract_as_list)
|
||||
from ..interpreterbase import InterpreterException, FeatureNew
|
||||
from ..interpreterbase import permittedKwargs, typed_pos_args
|
||||
from ..interpreter import DependencyHolder
|
||||
from ..compilers.compilers import CFLAGS_MAPPING, CEXE_MAPPING
|
||||
from ..dependencies import InternalDependency, PkgConfigDependency
|
||||
from ..mesonlib import OptionKey
|
||||
|
@ -237,7 +236,7 @@ class ExternalProject(ModuleObject):
|
|||
variables = []
|
||||
dep = InternalDependency(version, incdir, compile_args, link_args, libs,
|
||||
libs_whole, sources, final_deps, variables)
|
||||
return DependencyHolder(dep, self.subproject)
|
||||
return dep
|
||||
|
||||
|
||||
class ExternalProjectModule(ExtensionModule):
|
||||
|
|
|
@ -19,15 +19,11 @@ from . import ExtensionModule, ModuleReturnValue
|
|||
from .. import mlog
|
||||
from ..build import BuildTarget, CustomTargetIndex, Executable, GeneratedList, InvalidArguments, IncludeDirs, CustomTarget
|
||||
from ..interpreter.interpreter import TEST_KWARGS
|
||||
from ..interpreter.interpreterobjects import (
|
||||
BuildTargetHolder,
|
||||
CustomTargetHolder,
|
||||
DependencyHolder,
|
||||
ExecutableHolder,
|
||||
ExternalLibraryHolder,
|
||||
)
|
||||
from ..interpreterbase import ContainerTypeInfo, InterpreterException, KwargInfo, permittedKwargs, FeatureNew, typed_kwargs, typed_pos_args, noPosargs
|
||||
from ..mesonlib import stringlistify, unholder, listify, typeslistify, File
|
||||
from ..mesonlib import stringlistify, listify, typeslistify, File
|
||||
from ..dependencies import Dependency, ExternalLibrary
|
||||
from ..interpreterbase import InterpreterException, permittedKwargs, FeatureNew, typed_pos_args, noPosargs
|
||||
from ..mesonlib import stringlistify, listify, typeslistify, File
|
||||
|
||||
if T.TYPE_CHECKING:
|
||||
from . import ModuleState
|
||||
|
@ -38,7 +34,7 @@ if T.TYPE_CHECKING:
|
|||
|
||||
class FuncTest(_kwargs.BaseTest):
|
||||
|
||||
dependencies: T.List[T.Union[DependencyHolder, ExternalLibraryHolder]]
|
||||
dependencies: T.List[T.Union[Dependency, ExternalLibrary]]
|
||||
is_parallel: bool
|
||||
|
||||
|
||||
|
@ -55,18 +51,18 @@ class RustModule(ExtensionModule):
|
|||
'bindgen': self.bindgen,
|
||||
})
|
||||
|
||||
@typed_pos_args('rust.test', str, BuildTargetHolder)
|
||||
@typed_pos_args('rust.test', str, BuildTarget)
|
||||
@typed_kwargs(
|
||||
'rust.test',
|
||||
*TEST_KWARGS,
|
||||
KwargInfo('is_parallel', bool, default=False),
|
||||
KwargInfo(
|
||||
'dependencies',
|
||||
ContainerTypeInfo(list, (DependencyHolder, ExternalLibraryHolder)),
|
||||
ContainerTypeInfo(list, (Dependency, ExternalLibrary)),
|
||||
listify=True,
|
||||
default=[]),
|
||||
)
|
||||
def test(self, state: 'ModuleState', args: T.Tuple[str, BuildTargetHolder], kwargs: 'FuncTest') -> ModuleReturnValue:
|
||||
def test(self, state: 'ModuleState', args: T.Tuple[str, BuildTarget], kwargs: 'FuncTest') -> ModuleReturnValue:
|
||||
"""Generate a rust test target from a given rust target.
|
||||
|
||||
Rust puts it's unitests inside it's main source files, unlike most
|
||||
|
@ -151,11 +147,10 @@ class RustModule(ExtensionModule):
|
|||
new_target_kwargs
|
||||
)
|
||||
|
||||
e = ExecutableHolder(new_target, self.interpreter)
|
||||
test = self.interpreter.make_test(
|
||||
self.interpreter.current_node, (name, e), tkwargs)
|
||||
self.interpreter.current_node, (name, new_target), tkwargs)
|
||||
|
||||
return ModuleReturnValue(None, [e, test])
|
||||
return ModuleReturnValue(None, [new_target, test])
|
||||
|
||||
@noPosargs
|
||||
@permittedKwargs({'input', 'output', 'include_directories', 'c_args', 'args'})
|
||||
|
@ -184,7 +179,7 @@ class RustModule(ExtensionModule):
|
|||
bind_args: T.List[str] = stringlistify(listify(kwargs.get('args', [])))
|
||||
|
||||
# Split File and Target dependencies to add pass to CustomTarget
|
||||
depends: T.List[T.Union[GeneratedList, BuildTarget, CustomTargetIndex]] = []
|
||||
depends: T.List[T.Union[GeneratedList, BuildTarget, CustomTargetIndex, CustomTarget]] = []
|
||||
depend_files: T.List[File] = []
|
||||
for d in _deps:
|
||||
if isinstance(d, File):
|
||||
|
@ -225,7 +220,7 @@ class RustModule(ExtensionModule):
|
|||
backend=state.backend,
|
||||
)
|
||||
|
||||
return ModuleReturnValue([target], [CustomTargetHolder(target, self.interpreter)])
|
||||
return ModuleReturnValue([target], [target])
|
||||
|
||||
|
||||
def initialize(*args: T.List, **kwargs: T.Dict) -> RustModule:
|
||||
|
|
|
@ -11,7 +11,7 @@ from mesonbuild.mesonlib import version_compare
|
|||
|
||||
modules = [
|
||||
# fully typed submodules
|
||||
'mesonbuild/ast',
|
||||
# 'mesonbuild/ast',
|
||||
'mesonbuild/cmake',
|
||||
'mesonbuild/compilers',
|
||||
'mesonbuild/dependencies',
|
||||
|
@ -23,6 +23,7 @@ modules = [
|
|||
'mesonbuild/arglist.py',
|
||||
# 'mesonbuild/coredata.py',
|
||||
'mesonbuild/envconfig.py',
|
||||
'mesonbuild/interpreter/interpreterobjects.py',
|
||||
'mesonbuild/linkers.py',
|
||||
'mesonbuild/mcompile.py',
|
||||
'mesonbuild/mdevenv.py',
|
||||
|
|
|
@ -20,6 +20,9 @@ exe_static2 = executable('prog-static2', 'main.c',
|
|||
link_with : both_libs2.get_static_lib())
|
||||
exe_both2 = executable('prog-both2', 'main.c', link_with : both_libs2)
|
||||
|
||||
# Ensure that calling the build target methods also works
|
||||
assert(both_libs.name() == 'mylib')
|
||||
|
||||
test('runtest-shared-2', exe_shared2)
|
||||
test('runtest-static-2', exe_static2)
|
||||
test('runtest-both-2', exe_both2)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
project('myexe', 'c')
|
||||
project('myexe', 'c', version: '0.1')
|
||||
sub = subproject('sub')
|
||||
|
||||
prog = find_program('foobar', version : '>= 2.0', required : false)
|
||||
|
|
Loading…
Reference in New Issue