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