|
|
@ -50,6 +50,11 @@ import typing as T |
|
|
|
|
|
|
|
|
|
|
|
import importlib |
|
|
|
import importlib |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if T.TYPE_CHECKING: |
|
|
|
|
|
|
|
from .envconfig import MachineInfo |
|
|
|
|
|
|
|
from .environment import Environment |
|
|
|
|
|
|
|
from .modules import ExtensionModule |
|
|
|
|
|
|
|
|
|
|
|
permitted_method_kwargs = { |
|
|
|
permitted_method_kwargs = { |
|
|
|
'partial_dependency': {'compile_args', 'link_args', 'links', 'includes', |
|
|
|
'partial_dependency': {'compile_args', 'link_args', 'links', 'includes', |
|
|
|
'sources'}, |
|
|
|
'sources'}, |
|
|
@ -716,34 +721,26 @@ class IncludeDirsHolder(InterpreterObject, ObjectHolder): |
|
|
|
InterpreterObject.__init__(self) |
|
|
|
InterpreterObject.__init__(self) |
|
|
|
ObjectHolder.__init__(self, idobj) |
|
|
|
ObjectHolder.__init__(self, idobj) |
|
|
|
|
|
|
|
|
|
|
|
class Headers(InterpreterObject): |
|
|
|
class HeadersHolder(InterpreterObject, ObjectHolder): |
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, sources, kwargs): |
|
|
|
def __init__(self, obj: build.Headers): |
|
|
|
InterpreterObject.__init__(self) |
|
|
|
InterpreterObject.__init__(self) |
|
|
|
self.sources = sources |
|
|
|
ObjectHolder.__init__(self, obj) |
|
|
|
self.install_subdir = kwargs.get('subdir', '') |
|
|
|
|
|
|
|
if os.path.isabs(self.install_subdir): |
|
|
|
|
|
|
|
mlog.deprecation('Subdir keyword must not be an absolute path. This will be a hard error in the next release.') |
|
|
|
|
|
|
|
self.custom_install_dir = kwargs.get('install_dir', None) |
|
|
|
|
|
|
|
self.custom_install_mode = kwargs.get('install_mode', None) |
|
|
|
|
|
|
|
if self.custom_install_dir is not None: |
|
|
|
|
|
|
|
if not isinstance(self.custom_install_dir, str): |
|
|
|
|
|
|
|
raise InterpreterException('Custom_install_dir must be a string.') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def set_install_subdir(self, subdir): |
|
|
|
def set_install_subdir(self, subdir): |
|
|
|
self.install_subdir = subdir |
|
|
|
self.held_object.install_subdir = subdir |
|
|
|
|
|
|
|
|
|
|
|
def get_install_subdir(self): |
|
|
|
def get_install_subdir(self): |
|
|
|
return self.install_subdir |
|
|
|
return self.held_object.install_subdir |
|
|
|
|
|
|
|
|
|
|
|
def get_sources(self): |
|
|
|
def get_sources(self): |
|
|
|
return self.sources |
|
|
|
return self.held_object.sources |
|
|
|
|
|
|
|
|
|
|
|
def get_custom_install_dir(self): |
|
|
|
def get_custom_install_dir(self): |
|
|
|
return self.custom_install_dir |
|
|
|
return self.held_object.custom_install_dir |
|
|
|
|
|
|
|
|
|
|
|
def get_custom_install_mode(self): |
|
|
|
def get_custom_install_mode(self): |
|
|
|
return self.custom_install_mode |
|
|
|
return self.held_object.custom_install_mode |
|
|
|
|
|
|
|
|
|
|
|
class DataHolder(InterpreterObject, ObjectHolder): |
|
|
|
class DataHolder(InterpreterObject, ObjectHolder): |
|
|
|
def __init__(self, data): |
|
|
|
def __init__(self, data): |
|
|
@ -771,34 +768,20 @@ class InstallDir(InterpreterObject): |
|
|
|
self.strip_directory = strip_directory |
|
|
|
self.strip_directory = strip_directory |
|
|
|
self.from_source_dir = from_source_dir |
|
|
|
self.from_source_dir = from_source_dir |
|
|
|
|
|
|
|
|
|
|
|
class Man(InterpreterObject): |
|
|
|
class ManHolder(InterpreterObject, ObjectHolder): |
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, sources, kwargs): |
|
|
|
def __init__(self, obj: build.Man): |
|
|
|
InterpreterObject.__init__(self) |
|
|
|
InterpreterObject.__init__(self) |
|
|
|
self.sources = sources |
|
|
|
ObjectHolder.__init__(self, obj) |
|
|
|
self.validate_sources() |
|
|
|
|
|
|
|
self.custom_install_dir = kwargs.get('install_dir', None) |
|
|
|
|
|
|
|
self.custom_install_mode = kwargs.get('install_mode', None) |
|
|
|
|
|
|
|
if self.custom_install_dir is not None and not isinstance(self.custom_install_dir, str): |
|
|
|
|
|
|
|
raise InterpreterException('Custom_install_dir must be a string.') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def validate_sources(self): |
|
|
|
|
|
|
|
for s in self.sources: |
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
num = int(s.split('.')[-1]) |
|
|
|
|
|
|
|
except (IndexError, ValueError): |
|
|
|
|
|
|
|
num = 0 |
|
|
|
|
|
|
|
if num < 1 or num > 8: |
|
|
|
|
|
|
|
raise InvalidArguments('Man file must have a file extension of a number between 1 and 8') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_custom_install_dir(self): |
|
|
|
def get_custom_install_dir(self) -> T.Optional[str]: |
|
|
|
return self.custom_install_dir |
|
|
|
return self.held_object.custom_install_dir |
|
|
|
|
|
|
|
|
|
|
|
def get_custom_install_mode(self): |
|
|
|
def get_custom_install_mode(self) -> T.Optional[FileMode]: |
|
|
|
return self.custom_install_mode |
|
|
|
return self.held_object.custom_install_mode |
|
|
|
|
|
|
|
|
|
|
|
def get_sources(self): |
|
|
|
def get_sources(self) -> T.List[mesonlib.File]: |
|
|
|
return self.sources |
|
|
|
return self.held_object.sources |
|
|
|
|
|
|
|
|
|
|
|
class GeneratedObjectsHolder(InterpreterObject, ObjectHolder): |
|
|
|
class GeneratedObjectsHolder(InterpreterObject, ObjectHolder): |
|
|
|
def __init__(self, held_object): |
|
|
|
def __init__(self, held_object): |
|
|
@ -878,7 +861,7 @@ class BuildTargetHolder(TargetHolder): |
|
|
|
return self.held_object.name |
|
|
|
return self.held_object.name |
|
|
|
|
|
|
|
|
|
|
|
class ExecutableHolder(BuildTargetHolder): |
|
|
|
class ExecutableHolder(BuildTargetHolder): |
|
|
|
def __init__(self, target, interp): |
|
|
|
def __init__(self, target: build.Executable, interp: 'Interpreter'): |
|
|
|
super().__init__(target, interp) |
|
|
|
super().__init__(target, interp) |
|
|
|
|
|
|
|
|
|
|
|
class StaticLibraryHolder(BuildTargetHolder): |
|
|
|
class StaticLibraryHolder(BuildTargetHolder): |
|
|
@ -1781,14 +1764,37 @@ class CompilerHolder(InterpreterObject): |
|
|
|
return self.compiler.get_argument_syntax() |
|
|
|
return self.compiler.get_argument_syntax() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ModuleState = collections.namedtuple('ModuleState', [ |
|
|
|
class ModuleState(T.NamedTuple): |
|
|
|
'source_root', 'build_to_src', 'subproject', 'subdir', 'current_lineno', 'environment', |
|
|
|
|
|
|
|
'project_name', 'project_version', 'backend', 'targets', |
|
|
|
"""Object passed to a module when it a method is called. |
|
|
|
'data', 'headers', 'man', 'global_args', 'project_args', 'build_machine', |
|
|
|
|
|
|
|
'host_machine', 'target_machine', 'current_node']) |
|
|
|
holds the current state of the meson process at a given method call in |
|
|
|
|
|
|
|
the interpreter. |
|
|
|
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
source_root: str |
|
|
|
|
|
|
|
build_to_src: str |
|
|
|
|
|
|
|
subproject: str |
|
|
|
|
|
|
|
subdir: str |
|
|
|
|
|
|
|
current_lineno: str |
|
|
|
|
|
|
|
environment: 'Environment' |
|
|
|
|
|
|
|
project_name: str |
|
|
|
|
|
|
|
project_version: str |
|
|
|
|
|
|
|
backend: str |
|
|
|
|
|
|
|
targets: T.Dict[str, build.Target] |
|
|
|
|
|
|
|
data: T.List[build.Data] |
|
|
|
|
|
|
|
headers: T.List[build.Headers] |
|
|
|
|
|
|
|
man: T.List[build.Man] |
|
|
|
|
|
|
|
global_args: T.Dict[str, T.List[str]] |
|
|
|
|
|
|
|
project_args: T.Dict[str, T.List[str]] |
|
|
|
|
|
|
|
build_machine: 'MachineInfo' |
|
|
|
|
|
|
|
host_machine: 'MachineInfo' |
|
|
|
|
|
|
|
target_machine: 'MachineInfo' |
|
|
|
|
|
|
|
current_node: mparser.BaseNode |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ModuleHolder(InterpreterObject, ObjectHolder): |
|
|
|
class ModuleHolder(InterpreterObject, ObjectHolder): |
|
|
|
def __init__(self, modname, module, interpreter): |
|
|
|
def __init__(self, modname: str, module: 'ExtensionModule', interpreter: 'Interpreter'): |
|
|
|
InterpreterObject.__init__(self) |
|
|
|
InterpreterObject.__init__(self) |
|
|
|
ObjectHolder.__init__(self, module) |
|
|
|
ObjectHolder.__init__(self, module) |
|
|
|
self.modname = modname |
|
|
|
self.modname = modname |
|
|
@ -4189,19 +4195,43 @@ This will become a hard error in the future.''' % kwargs['input'], location=self |
|
|
|
@permittedKwargs(permitted_kwargs['install_headers']) |
|
|
|
@permittedKwargs(permitted_kwargs['install_headers']) |
|
|
|
def func_install_headers(self, node, args, kwargs): |
|
|
|
def func_install_headers(self, node, args, kwargs): |
|
|
|
source_files = self.source_strings_to_files(args) |
|
|
|
source_files = self.source_strings_to_files(args) |
|
|
|
kwargs['install_mode'] = self._get_kwarg_install_mode(kwargs) |
|
|
|
install_mode = self._get_kwarg_install_mode(kwargs) |
|
|
|
h = Headers(source_files, kwargs) |
|
|
|
|
|
|
|
|
|
|
|
install_subdir = kwargs.get('subdir', '') |
|
|
|
|
|
|
|
if not isinstance(install_subdir, str): |
|
|
|
|
|
|
|
raise InterpreterException('subdir keyword argument must be a string') |
|
|
|
|
|
|
|
elif os.path.isabs(install_subdir): |
|
|
|
|
|
|
|
mlog.deprecation('Subdir keyword must not be an absolute path. This will be a hard error in the next release.') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
install_dir = kwargs.get('install_dir', None) |
|
|
|
|
|
|
|
if install_dir is not None and not isinstance(install_dir, str): |
|
|
|
|
|
|
|
raise InterpreterException('install_dir keyword argument must be a string if provided') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
h = build.Headers(source_files, install_subdir, install_dir, install_mode) |
|
|
|
self.build.headers.append(h) |
|
|
|
self.build.headers.append(h) |
|
|
|
return h |
|
|
|
|
|
|
|
|
|
|
|
return HeadersHolder(h) |
|
|
|
|
|
|
|
|
|
|
|
@FeatureNewKwargs('install_man', '0.47.0', ['install_mode']) |
|
|
|
@FeatureNewKwargs('install_man', '0.47.0', ['install_mode']) |
|
|
|
@permittedKwargs(permitted_kwargs['install_man']) |
|
|
|
@permittedKwargs(permitted_kwargs['install_man']) |
|
|
|
def func_install_man(self, node, args, kwargs): |
|
|
|
def func_install_man(self, node, args, kwargs): |
|
|
|
fargs = self.source_strings_to_files(args) |
|
|
|
sources = self.source_strings_to_files(args) |
|
|
|
kwargs['install_mode'] = self._get_kwarg_install_mode(kwargs) |
|
|
|
for s in sources: |
|
|
|
m = Man(fargs, kwargs) |
|
|
|
try: |
|
|
|
|
|
|
|
num = int(s.split('.')[-1]) |
|
|
|
|
|
|
|
except (IndexError, ValueError): |
|
|
|
|
|
|
|
num = 0 |
|
|
|
|
|
|
|
if num < 1 or num > 8: |
|
|
|
|
|
|
|
raise InvalidArguments('Man file must have a file extension of a number between 1 and 8') |
|
|
|
|
|
|
|
custom_install_mode = self._get_kwarg_install_mode(kwargs) |
|
|
|
|
|
|
|
custom_install_dir = kwargs.get('install_dir', None) |
|
|
|
|
|
|
|
if custom_install_dir is not None and not isinstance(custom_install_dir, str): |
|
|
|
|
|
|
|
raise InterpreterException('install_dir must be a string.') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m = build.Man(sources, custom_install_dir, custom_install_mode) |
|
|
|
self.build.man.append(m) |
|
|
|
self.build.man.append(m) |
|
|
|
return m |
|
|
|
|
|
|
|
|
|
|
|
return ManHolder(m) |
|
|
|
|
|
|
|
|
|
|
|
@FeatureNewKwargs('subdir', '0.44.0', ['if_found']) |
|
|
|
@FeatureNewKwargs('subdir', '0.44.0', ['if_found']) |
|
|
|
@permittedKwargs(permitted_kwargs['subdir']) |
|
|
|
@permittedKwargs(permitted_kwargs['subdir']) |
|
|
@ -4251,10 +4281,10 @@ This will become a hard error in the future.''' % kwargs['input'], location=self |
|
|
|
pass |
|
|
|
pass |
|
|
|
self.subdir = prev_subdir |
|
|
|
self.subdir = prev_subdir |
|
|
|
|
|
|
|
|
|
|
|
def _get_kwarg_install_mode(self, kwargs): |
|
|
|
def _get_kwarg_install_mode(self, kwargs: T.Dict[str, T.Any]) -> T.Optional[FileMode]: |
|
|
|
if kwargs.get('install_mode', None) is None: |
|
|
|
if kwargs.get('install_mode', None) is None: |
|
|
|
return None |
|
|
|
return None |
|
|
|
install_mode = [] |
|
|
|
install_mode: T.List[str] = [] |
|
|
|
mode = mesonlib.typeslistify(kwargs.get('install_mode', []), (str, int)) |
|
|
|
mode = mesonlib.typeslistify(kwargs.get('install_mode', []), (str, int)) |
|
|
|
for m in mode: |
|
|
|
for m in mode: |
|
|
|
# We skip any arguments that are set to `false` |
|
|
|
# We skip any arguments that are set to `false` |
|
|
@ -4806,11 +4836,11 @@ Try setting b_lundef to false instead.'''.format(self.coredata.base_options['b_s |
|
|
|
if sproj_name != self.subproject_directory_name: |
|
|
|
if sproj_name != self.subproject_directory_name: |
|
|
|
raise InterpreterException('Sandbox violation: Tried to grab file %s from a different subproject.' % plain_filename) |
|
|
|
raise InterpreterException('Sandbox violation: Tried to grab file %s from a different subproject.' % plain_filename) |
|
|
|
|
|
|
|
|
|
|
|
def source_strings_to_files(self, sources): |
|
|
|
def source_strings_to_files(self, sources: T.List[str]) -> T.List[mesonlib.File]: |
|
|
|
results = [] |
|
|
|
|
|
|
|
mesonlib.check_direntry_issues(sources) |
|
|
|
mesonlib.check_direntry_issues(sources) |
|
|
|
if not isinstance(sources, list): |
|
|
|
if not isinstance(sources, list): |
|
|
|
sources = [sources] |
|
|
|
sources = [sources] |
|
|
|
|
|
|
|
results: T.List[mesonlib.File] = [] |
|
|
|
for s in sources: |
|
|
|
for s in sources: |
|
|
|
if isinstance(s, (mesonlib.File, GeneratedListHolder, |
|
|
|
if isinstance(s, (mesonlib.File, GeneratedListHolder, |
|
|
|
TargetHolder, CustomTargetIndexHolder, |
|
|
|
TargetHolder, CustomTargetIndexHolder, |
|
|
|