aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2021-06-01 21:13:38 -0700
committerDylan Baker <dylan@pnwbakers.com>2021-06-15 12:48:53 -0700
commit35bdaada1dfb64366f1533a79fea670502f69732 (patch)
treee334647e95426a6505b6365ab1cba58ddbd2ecd7 /mesonbuild
parent491c756dc99fa4b126ddcbbee7de149d47c9199f (diff)
downloadmeson-35bdaada1dfb64366f1533a79fea670502f69732.zip
meson-35bdaada1dfb64366f1533a79fea670502f69732.tar.gz
meson-35bdaada1dfb64366f1533a79fea670502f69732.tar.bz2
interpreter|build: Do Generator keyword argument checking in the interpreter
For qt we already have all of the necissary checking in place. Now in the interpreter we have the same, the intrperter does all of the checking, then passed the arguments to the Generator initializer, which just assigns the passed values. This is nice, neat, and clean and fixes the layering violatino between build and interpreter.
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/build.py65
-rw-r--r--mesonbuild/interpreter/interpreter.py18
-rw-r--r--mesonbuild/modules/qt.py22
3 files changed, 37 insertions, 68 deletions
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index c401bd2..ddce65c 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -1498,12 +1498,19 @@ You probably should put it in link_with instead.''')
return
class Generator:
- def __init__(self, exe: T.Union['Executable', programs.ExternalProgram], kwargs):
+ def __init__(self, exe: T.Union['Executable', programs.ExternalProgram],
+ arguments: T.List[str],
+ output: T.List[str],
+ *,
+ depfile: T.Optional[str] = None,
+ capture: bool = False,
+ depends: T.Optional[T.List[T.Union[BuildTarget, 'CustomTarget']]] = None):
self.exe = exe
- self.depfile = None
- self.capture = False
- self.depends = []
- self.process_kwargs(kwargs)
+ self.depfile = depfile
+ self.capture = capture
+ self.depends: T.List[T.Union[BuildTarget, 'CustomTarget']] = depends or []
+ self.arglist = arguments
+ self.outputs = output
def __repr__(self):
repr_str = "<{0}: {1}>"
@@ -1512,53 +1519,7 @@ class Generator:
def get_exe(self) -> T.Union['Executable', programs.ExternalProgram]:
return self.exe
- def process_kwargs(self, kwargs):
- if 'arguments' not in kwargs:
- raise InvalidArguments('Generator must have "arguments" keyword argument.')
- args = kwargs['arguments']
- if isinstance(args, str):
- args = [args]
- if not isinstance(args, list):
- raise InvalidArguments('"Arguments" keyword argument must be a string or a list of strings.')
- for a in args:
- if not isinstance(a, str):
- raise InvalidArguments('A non-string object in "arguments" keyword argument.')
- self.arglist = args
- if 'output' not in kwargs:
- raise InvalidArguments('Generator must have "output" keyword argument.')
- outputs = listify(kwargs['output'])
- for rule in outputs:
- if not isinstance(rule, str):
- raise InvalidArguments('"output" may only contain strings.')
- if '@BASENAME@' not in rule and '@PLAINNAME@' not in rule:
- raise InvalidArguments('Every element of "output" must contain @BASENAME@ or @PLAINNAME@.')
- if has_path_sep(rule):
- raise InvalidArguments('"outputs" must not contain a directory separator.')
- if len(outputs) > 1:
- for o in outputs:
- if '@OUTPUT@' in o:
- raise InvalidArguments('Tried to use @OUTPUT@ in a rule with more than one output.')
- self.outputs = outputs
- if 'depfile' in kwargs:
- depfile = kwargs['depfile']
- if not isinstance(depfile, str):
- raise InvalidArguments('Depfile must be a string.')
- if os.path.basename(depfile) != depfile:
- raise InvalidArguments('Depfile must be a plain filename without a subdirectory.')
- self.depfile = depfile
- if 'capture' in kwargs:
- capture = kwargs['capture']
- if not isinstance(capture, bool):
- raise InvalidArguments('Capture must be boolean.')
- self.capture = capture
- if 'depends' in kwargs:
- depends = unholder(listify(kwargs['depends']))
- for d in depends:
- if not (isinstance(d, (BuildTarget, CustomTarget))):
- raise InvalidArguments('Depends entries must be build targets.')
- self.depends.append(d)
-
- def get_base_outnames(self, inname) -> T.List[str]:
+ def get_base_outnames(self, inname):
plainname = os.path.basename(inname)
basename = os.path.splitext(plainname)[0]
bases = [x.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname) for x in self.outputs]
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index f2b1bd9..dce0391 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -1959,15 +1959,27 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
'generator',
KwargInfo('arguments', ContainerTypeInfo(list, str, allow_empty=False), required=True, listify=True),
KwargInfo('output', ContainerTypeInfo(list, str, allow_empty=False), required=True, listify=True),
- KwargInfo('depfile', str),
+ KwargInfo('depfile', str, validator=lambda x: 'Depfile must be a plain filename with a subdirectory' if has_path_sep(x) else None),
KwargInfo('capture', bool, default=False, since='0.43.0'),
KwargInfo('depends', ContainerTypeInfo(list, (BuildTargetHolder, CustomTargetHolder)), default=[], listify=True),
)
def func_generator(self, node: mparser.FunctionNode,
args: T.Tuple[T.Union[ExecutableHolder, ExternalProgramHolder]],
kwargs: 'kwargs.FuncGenerator') -> GeneratorHolder:
- gen = build.Generator(args[0].held_object, kwargs)
- holder = GeneratorHolder(self, gen, self)
+ for rule in kwargs['output']:
+ if '@BASENAME@' not in rule and '@PLAINNAME@' not in rule:
+ raise InvalidArguments('Every element of "output" must contain @BASENAME@ or @PLAINNAME@.')
+ if has_path_sep(rule):
+ raise InvalidArguments('"output" must not contain a directory separator.')
+ if len(kwargs['output']) > 1:
+ for o in kwargs['output']:
+ if '@OUTPUT@' in o:
+ raise InvalidArguments('Tried to use @OUTPUT@ in a rule with more than one output.')
+
+ depends = [d.held_object for d in kwargs.pop('depends')]
+
+ gen = build.Generator(args[0].held_object, depends=depends, **kwargs)
+ holder = GeneratorHolder(gen, self)
self.generators.append(holder)
return holder
diff --git a/mesonbuild/modules/qt.py b/mesonbuild/modules/qt.py
index 76cc4db..f328027 100644
--- a/mesonbuild/modules/qt.py
+++ b/mesonbuild/modules/qt.py
@@ -344,12 +344,12 @@ class QtBaseModule(ExtensionModule):
"please check your qt{2} installation")
raise MesonException(err_msg.format('UIC', f'uic-qt{self.qt_version}', self.qt_version))
- ui_kwargs: T.Dict[str, T.Any] = { # TODO: if Generator was properly annotatedā€¦
- 'output': 'ui_@BASENAME@.h',
- 'arguments': kwargs['extra_args'] + ['-o', '@OUTPUT@', '@INPUT@']}
# TODO: This generator isn't added to the generator list in the Interpreter
- gen = build.Generator(self.uic, ui_kwargs) # type: ignore
- out = gen.process_files(f'Qt{self.qt_version} ui', kwargs['sources'], state)
+ gen = build.Generator(
+ self.uic,
+ kwargs['extra_args'] + ['-o', '@OUTPUT@', '@INPUT@'],
+ ['ui_@BASENAME@.h'])
+ out = gen.process_files(f'Qt{self.qt_version} ui', kwargs['sources'], state) # type: ignore
return ModuleReturnValue(out, [out])
@FeatureNew('qt.compile_moc', '0.59.0')
@@ -382,15 +382,11 @@ class QtBaseModule(ExtensionModule):
arguments = kwargs['extra_args'] + inc + compile_args + ['@INPUT@', '-o', '@OUTPUT@']
if kwargs['headers']:
- moc_kwargs = {'output': 'moc_@BASENAME@.cpp',
- 'arguments': arguments}
- moc_gen = build.Generator(self.moc, moc_kwargs) # type: ignore
- output.append(moc_gen.process_files(f'Qt{self.qt_version} moc header', kwargs['headers'], state))
+ moc_gen = build.Generator(self.moc, arguments, ['moc_@BASENAME@.cpp'])
+ output.append(moc_gen.process_files(f'Qt{self.qt_version} moc header', kwargs['headers'], state)) # type: ignore
if kwargs['sources']:
- moc_kwargs = {'output': '@BASENAME@.moc',
- 'arguments': arguments}
- moc_gen = build.Generator(self.moc, moc_kwargs) # type: ignore
- output.append(moc_gen.process_files(f'Qt{self.qt_version} moc source', kwargs['sources'], state))
+ moc_gen = build.Generator(self.moc, arguments, ['@BASENAME@.moc'])
+ output.append(moc_gen.process_files(f'Qt{self.qt_version} moc source', kwargs['sources'], state)) # type: ignore
return ModuleReturnValue(output, [output])