Merge pull request #2001 from mesonbuild/kwcheck

Decorator to check for unknown keyword arguments
pull/1995/merge
Jussi Pakkanen 8 years ago committed by GitHub
commit 80ebc916f7
  1. 7
      docs/markdown/Release-notes-for-0.42.0.md
  2. 235
      mesonbuild/interpreter.py
  3. 60
      mesonbuild/interpreterbase.py
  4. 16
      mesonbuild/modules/__init__.py
  5. 22
      mesonbuild/modules/gnome.py
  6. 4
      mesonbuild/modules/i18n.py
  7. 2
      mesonbuild/modules/modtest.py
  8. 4
      mesonbuild/modules/pkgconfig.py
  9. 13
      mesonbuild/modules/python3.py
  10. 2
      mesonbuild/modules/qt4.py
  11. 2
      mesonbuild/modules/qt5.py
  12. 2
      mesonbuild/modules/rpm.py
  13. 2
      mesonbuild/modules/windows.py
  14. 5
      test cases/failing/57 kwarg in module/meson.build

@ -11,3 +11,10 @@ short-description: Release notes for 0.42 (preliminary)
Creating distribution tarballs can now be made out of projects based on
Mercurial. As before, this remains possible only with the Ninja backend.
## Keyword argument verification
Meson will now check the keyword arguments used when calling any function
and print a warning if any of the keyword arguments is not known. In the
future this will become a hard error.

@ -1,5 +1,4 @@
# Copyright 2012-2017 The Meson development team
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
@ -26,7 +25,7 @@ from .mesonlib import FileMode, Popen_safe, get_meson_script
from .dependencies import ExternalProgram
from .dependencies import InternalDependency, Dependency, DependencyException
from .interpreterbase import InterpreterBase
from .interpreterbase import check_stringlist, noPosargs, noKwargs, stringArgs
from .interpreterbase import check_stringlist, noPosargs, noKwargs, stringArgs, permittedKwargs
from .interpreterbase import InterpreterException, InvalidArguments, InvalidCode
from .interpreterbase import InterpreterObject, MutableInterpreterObject
from .modules import ModuleReturnValue
@ -1213,6 +1212,95 @@ class MesonMain(InterpreterObject):
return args[1]
raise InterpreterException('Unknown cross property: %s.' % propname)
pch_kwargs = set(['c_pch', 'cpp_pch'])
lang_arg_kwargs = set(['c_args',
'cpp_args',
'd_args',
'fortran_args',
'java_args',
'objc_args',
'objcpp_args',
'rust_args',
'vala_args',
])
vala_kwargs = set(['vala_header', 'vala_gir', 'vala_vapi'])
rust_kwargs = set(['rust_crate_type'])
cs_kwargs = set(['resources'])
buildtarget_kwargs = set(['build_by_default',
'dependencies',
'extra_files',
'gui_app',
'link_with',
'link_whole',
'link_args',
'link_depends',
'include_directories',
'install',
'install_rpath',
'install_dir',
'name_prefix',
'name_suffix',
'native',
'objects',
'override_options',
'pic',
'sources',
'vs_module_defs',
])
build_target_common_kwargs = (
buildtarget_kwargs |
lang_arg_kwargs |
pch_kwargs |
vala_kwargs |
rust_kwargs |
cs_kwargs)
exe_kwargs = set()
exe_kwargs.update(build_target_common_kwargs)
shlib_kwargs = (build_target_common_kwargs) | {'version', 'soversion'}
shmod_kwargs = shlib_kwargs
stlib_kwargs = shlib_kwargs
jar_kwargs = exe_kwargs.copy()
jar_kwargs.update(['main_class'])
build_target_kwargs = exe_kwargs.copy()
build_target_kwargs.update(['target_type'])
permitted_kwargs = {'add_global_arguments': {'language'},
'add_languages': {'required'},
'add_project_arguments': {'language'},
'add_test_setup': {'exe_wrapper', 'gdb', 'timeout_multiplier', 'env'},
'benchmark': {'args', 'env', 'should_fail', 'timeout', 'workdir', 'suite'},
'build_target': build_target_kwargs,
'configure_file': {'input', 'output', 'configuration', 'command', 'install_dir', 'capture', 'install'},
'custom_target': {'input', 'output', 'command', 'install', 'install_dir', 'build_always', 'capture', 'depends', 'depend_files', 'depfile', 'build_by_default'},
'declare_dependency': {'include_directories', 'link_with', 'sources', 'dependencies', 'compile_args', 'link_args', 'version'},
'executable': exe_kwargs,
'find_program': {'required'},
'generator': {'arguments', 'output', 'depfile'},
'include_directories': {'is_system'},
'install_data': {'install_dir', 'install_mode', 'sources'},
'install_headers': {'install_dir', 'subdir'},
'install_man': {'install_dir'},
'install_subdir': {'install_dir', 'install_mode'},
'jar': jar_kwargs,
'project': {'version', 'meson_version', 'default_options', 'license', 'subproject_dir'},
'run_target': {'command', 'depends'},
'shared_library': shlib_kwargs,
'shared_module': shmod_kwargs,
'static_library': stlib_kwargs,
'subproject': {'version', 'default_options'},
'test': {'args', 'env', 'is_parallel', 'should_fail', 'timeout', 'workdir', 'suite'},
'vcs_tag': {'input', 'output', 'fallback', 'command', 'replace_string'},
}
class Interpreter(InterpreterBase):
def __init__(self, build, backend, subproject='', subdir='', subproject_dir='subprojects',
@ -1254,53 +1342,53 @@ class Interpreter(InterpreterBase):
self.build_def_files = [os.path.join(self.subdir, environment.build_filename)]
def build_func_dict(self):
self.funcs.update({'project': self.func_project,
'message': self.func_message,
'error': self.func_error,
'executable': self.func_executable,
'dependency': self.func_dependency,
'static_library': self.func_static_lib,
'shared_library': self.func_shared_lib,
'shared_module': self.func_shared_module,
'library': self.func_library,
'jar': self.func_jar,
'build_target': self.func_build_target,
'custom_target': self.func_custom_target,
'run_target': self.func_run_target,
'generator': self.func_generator,
'test': self.func_test,
'benchmark': self.func_benchmark,
'install_headers': self.func_install_headers,
'install_man': self.func_install_man,
'subdir': self.func_subdir,
'install_data': self.func_install_data,
'install_subdir': self.func_install_subdir,
'configure_file': self.func_configure_file,
'include_directories': self.func_include_directories,
'add_global_arguments': self.func_add_global_arguments,
self.funcs.update({'add_global_arguments': self.func_add_global_arguments,
'add_project_arguments': self.func_add_project_arguments,
'add_global_link_arguments': self.func_add_global_link_arguments,
'add_project_link_arguments': self.func_add_project_link_arguments,
'add_test_setup': self.func_add_test_setup,
'add_languages': self.func_add_languages,
'find_program': self.func_find_program,
'find_library': self.func_find_library,
'assert': self.func_assert,
'benchmark': self.func_benchmark,
'build_target': self.func_build_target,
'configuration_data': self.func_configuration_data,
'run_command': self.func_run_command,
'configure_file': self.func_configure_file,
'custom_target': self.func_custom_target,
'declare_dependency': self.func_declare_dependency,
'dependency': self.func_dependency,
'environment': self.func_environment,
'error': self.func_error,
'executable': self.func_executable,
'generator': self.func_generator,
'gettext': self.func_gettext,
'option': self.func_option,
'get_option': self.func_get_option,
'subproject': self.func_subproject,
'vcs_tag': self.func_vcs_tag,
'set_variable': self.func_set_variable,
'is_variable': self.func_is_variable,
'get_variable': self.func_get_variable,
'import': self.func_import,
'files': self.func_files,
'declare_dependency': self.func_declare_dependency,
'assert': self.func_assert,
'environment': self.func_environment,
'find_library': self.func_find_library,
'find_program': self.func_find_program,
'include_directories': self.func_include_directories,
'import': self.func_import,
'install_data': self.func_install_data,
'install_headers': self.func_install_headers,
'install_man': self.func_install_man,
'install_subdir': self.func_install_subdir,
'is_variable': self.func_is_variable,
'jar': self.func_jar,
'join_paths': self.func_join_paths,
'library': self.func_library,
'message': self.func_message,
'option': self.func_option,
'project': self.func_project,
'run_target': self.func_run_target,
'run_command': self.func_run_command,
'set_variable': self.func_set_variable,
'subdir': self.func_subdir,
'subproject': self.func_subproject,
'shared_library': self.func_shared_lib,
'shared_module': self.func_shared_module,
'static_library': self.func_static_lib,
'test': self.func_test,
'vcs_tag': self.func_vcs_tag,
})
def holderify(self, item):
@ -1401,6 +1489,7 @@ class Interpreter(InterpreterBase):
def func_files(self, node, args, kwargs):
return [mesonlib.File.from_source_file(self.environment.source_dir, self.subdir, fname) for fname in args]
@permittedKwargs(permitted_kwargs['declare_dependency'])
@noPosargs
def func_declare_dependency(self, node, args, kwargs):
version = kwargs.get('version', self.project_version)
@ -1457,7 +1546,11 @@ class Interpreter(InterpreterBase):
if not isinstance(actual, wanted):
raise InvalidArguments('Incorrect argument type.')
@noKwargs
def func_run_command(self, node, args, kwargs):
return self.run_command_impl(node, args, kwargs)
def run_command_impl(self, node, args, kwargs, in_builddir=False):
if len(args) < 1:
raise InterpreterException('Not enough arguments')
cmd = args[0]
@ -1490,9 +1583,6 @@ class Interpreter(InterpreterBase):
expanded_args.append(a.held_object.get_path())
else:
raise InterpreterException('Arguments ' + m.format(a))
in_builddir = kwargs.get('in_builddir', False)
if not isinstance(in_builddir, bool):
raise InterpreterException('in_builddir must be boolean.')
return RunProcess(cmd, expanded_args, srcdir, builddir, self.subdir,
get_meson_script(self.environment, 'mesonintrospect'), in_builddir)
@ -1503,6 +1593,7 @@ class Interpreter(InterpreterBase):
def func_option(self, nodes, args, kwargs):
raise InterpreterException('Tried to call option() in build description file. All options must be in the option file.')
@permittedKwargs(permitted_kwargs['subproject'])
@stringArgs
def func_subproject(self, nodes, args, kwargs):
if len(args) != 1:
@ -1631,6 +1722,7 @@ class Interpreter(InterpreterBase):
self.environment.cmd_line_options.projectoptions = newoptions
@stringArgs
@permittedKwargs(permitted_kwargs['project'])
def func_project(self, node, args, kwargs):
if len(args) < 1:
raise InvalidArguments('Not enough arguments to project(). Needs at least the project name.')
@ -1677,6 +1769,7 @@ class Interpreter(InterpreterBase):
if not self.is_subproject():
self.check_cross_stdlibs()
@permittedKwargs(permitted_kwargs['add_languages'])
@stringArgs
def func_add_languages(self, node, args, kwargs):
return self.add_languages(args, kwargs.get('required', True))
@ -1820,6 +1913,7 @@ class Interpreter(InterpreterBase):
break
self.coredata.base_options[optname] = oobj
@permittedKwargs(permitted_kwargs['find_program'])
def func_find_program(self, node, args, kwargs):
if not args:
raise InterpreterException('No program name specified.')
@ -2000,15 +2094,19 @@ class Interpreter(InterpreterBase):
mlog.bold(name))
return dep
@permittedKwargs(permitted_kwargs['executable'])
def func_executable(self, node, args, kwargs):
return self.build_target(node, args, kwargs, ExecutableHolder)
@permittedKwargs(permitted_kwargs['static_library'])
def func_static_lib(self, node, args, kwargs):
return self.build_target(node, args, kwargs, StaticLibraryHolder)
@permittedKwargs(permitted_kwargs['shared_library'])
def func_shared_lib(self, node, args, kwargs):
return self.build_target(node, args, kwargs, SharedLibraryHolder)
@permittedKwargs(permitted_kwargs['shared_module'])
def func_shared_module(self, node, args, kwargs):
return self.build_target(node, args, kwargs, SharedModuleHolder)
@ -2017,9 +2115,12 @@ class Interpreter(InterpreterBase):
return self.func_shared_lib(node, args, kwargs)
return self.func_static_lib(node, args, kwargs)
@permittedKwargs(permitted_kwargs['jar'])
def func_jar(self, node, args, kwargs):
kwargs['target_type'] = 'jar'
return self.build_target(node, args, kwargs, JarHolder)
@permittedKwargs(permitted_kwargs['build_target'])
def func_build_target(self, node, args, kwargs):
if 'target_type' not in kwargs:
raise InterpreterException('Missing target_type keyword argument')
@ -2037,6 +2138,7 @@ class Interpreter(InterpreterBase):
else:
raise InterpreterException('Unknown target_type.')
@permittedKwargs(permitted_kwargs['vcs_tag'])
def func_vcs_tag(self, node, args, kwargs):
if 'input' not in kwargs or 'output' not in kwargs:
raise InterpreterException('Keyword arguments input and output must exist')
@ -2075,6 +2177,7 @@ class Interpreter(InterpreterBase):
return self.func_custom_target(node, [kwargs['output']], kwargs)
@stringArgs
@permittedKwargs(permitted_kwargs['custom_target'])
def func_custom_target(self, node, args, kwargs):
if len(args) != 1:
raise InterpreterException('custom_target: Only one positional argument is allowed, and it must be a string name')
@ -2083,6 +2186,7 @@ class Interpreter(InterpreterBase):
self.add_target(name, tg.held_object)
return tg
@permittedKwargs(permitted_kwargs['run_target'])
def func_run_target(self, node, args, kwargs):
global run_depr_printed
if len(args) > 1:
@ -2133,14 +2237,17 @@ class Interpreter(InterpreterBase):
self.add_target(name, tg.held_object)
return tg
@permittedKwargs(permitted_kwargs['generator'])
def func_generator(self, node, args, kwargs):
gen = GeneratorHolder(self, args, kwargs)
self.generators.append(gen)
return gen
@permittedKwargs(permitted_kwargs['benchmark'])
def func_benchmark(self, node, args, kwargs):
self.add_test(node, args, kwargs, False)
@permittedKwargs(permitted_kwargs['test'])
def func_test(self, node, args, kwargs):
self.add_test(node, args, kwargs, True)
@ -2210,12 +2317,14 @@ class Interpreter(InterpreterBase):
self.build.benchmarks.append(t)
mlog.debug('Adding benchmark "', mlog.bold(args[0]), '".', sep='')
@permittedKwargs(permitted_kwargs['install_headers'])
def func_install_headers(self, node, args, kwargs):
source_files = self.source_strings_to_files(args)
h = Headers(source_files, kwargs)
self.build.headers.append(h)
return h
@permittedKwargs(permitted_kwargs['install_man'])
@stringArgs
def func_install_man(self, node, args, kwargs):
m = Man(self.subdir, args, kwargs)
@ -2279,6 +2388,7 @@ class Interpreter(InterpreterBase):
'permissions arg to be a string or false')
return FileMode(*install_mode)
@permittedKwargs(permitted_kwargs['install_data'])
def func_install_data(self, node, args, kwargs):
kwsource = mesonlib.stringlistify(kwargs.get('sources', []))
raw_sources = args + kwsource
@ -2298,6 +2408,7 @@ class Interpreter(InterpreterBase):
self.build.data.append(data.held_object)
return data
@permittedKwargs(permitted_kwargs['install_subdir'])
@stringArgs
def func_install_subdir(self, node, args, kwargs):
if len(args) != 1:
@ -2312,6 +2423,7 @@ class Interpreter(InterpreterBase):
self.build.install_dirs.append(idir)
return idir
@permittedKwargs(permitted_kwargs['configure_file'])
def func_configure_file(self, node, args, kwargs):
if len(args) > 0:
raise InterpreterException("configure_file takes only keyword arguments.")
@ -2387,7 +2499,7 @@ class Interpreter(InterpreterBase):
# Substitute @INPUT@, @OUTPUT@, etc here.
cmd = mesonlib.substitute_values(kwargs['command'], values)
mlog.log('Configuring', mlog.bold(output), 'with command')
res = self.func_run_command(node, cmd, {'in_builddir': True})
res = self.run_command_impl(node, cmd, {}, True)
if res.returncode != 0:
raise InterpreterException('Running configure command failed.\n%s\n%s' %
(res.stdout, res.stderr))
@ -2406,6 +2518,7 @@ class Interpreter(InterpreterBase):
self.build.data.append(build.Data([cfile], idir))
return mesonlib.File.from_built_file(self.subdir, output)
@permittedKwargs(permitted_kwargs['include_directories'])
@stringArgs
def func_include_directories(self, node, args, kwargs):
src_root = self.environment.get_source_dir()
@ -2442,6 +2555,7 @@ different subdirectory.
i = IncludeDirsHolder(build.IncludeDirs(self.subdir, args, is_system))
return i
@permittedKwargs(permitted_kwargs['add_test_setup'])
@stringArgs
def func_add_test_setup(self, node, args, kwargs):
if len(args) != 1:
@ -2483,18 +2597,22 @@ different subdirectory.
# and just use the master project ones.
self.build.test_setups[setup_name] = setupobj
@permittedKwargs(permitted_kwargs['add_global_arguments'])
@stringArgs
def func_add_global_arguments(self, node, args, kwargs):
self.add_global_arguments(node, self.build.global_args, args, kwargs)
@noKwargs
@stringArgs
def func_add_global_link_arguments(self, node, args, kwargs):
self.add_global_arguments(node, self.build.global_link_args, args, kwargs)
@permittedKwargs(permitted_kwargs['add_project_arguments'])
@stringArgs
def func_add_project_arguments(self, node, args, kwargs):
self.add_project_arguments(node, self.build.projects_args, args, kwargs)
@noKwargs
@stringArgs
def func_add_project_link_arguments(self, node, args, kwargs):
self.add_project_arguments(node, self.build.projects_link_args, args, kwargs)
@ -2531,6 +2649,8 @@ different subdirectory.
lang = lang.lower()
argsdict[lang] = argsdict.get(lang, []) + args
@noKwargs
@noPosargs
def func_environment(self, node, args, kwargs):
return EnvironmentVariablesHolder()
@ -2684,3 +2804,34 @@ different subdirectory.
def is_subproject(self):
return self.subproject != ''
@noKwargs
def func_set_variable(self, node, args, kwargs):
if len(args) != 2:
raise InvalidCode('Set_variable takes two arguments.')
varname = args[0]
value = args[1]
self.set_variable(varname, value)
@noKwargs
def func_get_variable(self, node, args, kwargs):
if len(args) < 1 or len(args) > 2:
raise InvalidCode('Get_variable takes one or two arguments.')
varname = args[0]
if not isinstance(varname, str):
raise InterpreterException('First argument must be a string.')
try:
return self.variables[varname]
except KeyError:
pass
if len(args) == 2:
return args[1]
raise InterpreterException('Tried to get unknown variable "%s".' % varname)
@stringArgs
@noKwargs
def func_is_variable(self, node, args, kwargs):
if len(args) != 1:
raise InvalidCode('Is_variable takes two arguments.')
varname = args[0]
return varname in self.variables

@ -55,6 +55,19 @@ def stringArgs(f):
return f(self, node, args, kwargs)
return wrapped
class permittedKwargs:
def __init__(self, permitted):
self.permitted = permitted
def __call__(self, f):
def wrapped(s, node, args, kwargs):
for k in kwargs:
if k not in self.permitted:
mlog.warning('Passed invalid keyword argument %s. This will become a hard error in the future.' % k)
return f(s, node, args, kwargs)
return wrapped
class InterpreterException(mesonlib.MesonException):
pass
@ -578,52 +591,5 @@ To specify a keyword argument, use : instead of =.''')
return isinstance(value, (InterpreterObject, dependencies.Dependency,
str, int, list, mesonlib.File))
def func_build_target(self, node, args, kwargs):
if 'target_type' not in kwargs:
raise InterpreterException('Missing target_type keyword argument')
target_type = kwargs.pop('target_type')
if target_type == 'executable':
return self.func_executable(node, args, kwargs)
elif target_type == 'shared_library':
return self.func_shared_lib(node, args, kwargs)
elif target_type == 'static_library':
return self.func_static_lib(node, args, kwargs)
elif target_type == 'library':
return self.func_library(node, args, kwargs)
elif target_type == 'jar':
return self.func_jar(node, args, kwargs)
else:
raise InterpreterException('Unknown target_type.')
def func_set_variable(self, node, args, kwargs):
if len(args) != 2:
raise InvalidCode('Set_variable takes two arguments.')
varname = args[0]
value = args[1]
self.set_variable(varname, value)
# @noKwargs
def func_get_variable(self, node, args, kwargs):
if len(args) < 1 or len(args) > 2:
raise InvalidCode('Get_variable takes one or two arguments.')
varname = args[0]
if not isinstance(varname, str):
raise InterpreterException('First argument must be a string.')
try:
return self.variables[varname]
except KeyError:
pass
if len(args) == 2:
return args[1]
raise InterpreterException('Tried to get unknown variable "%s".' % varname)
@stringArgs
@noKwargs
def func_is_variable(self, node, args, kwargs):
if len(args) != 1:
raise InvalidCode('Is_variable takes two arguments.')
varname = args[0]
return varname in self.variables
def is_elementary_type(self, v):
return isinstance(v, (int, float, str, bool, list))

@ -2,10 +2,26 @@ import os
from .. import build
from .. import dependencies
from .. import mlog
from ..mesonlib import MesonException
from ..interpreterbase import permittedKwargs, noKwargs
class permittedSnippetKwargs:
def __init__(self, permitted):
self.permitted = permitted
def __call__(self, f):
def wrapped(s, interpreter, state, args, kwargs):
for k in kwargs:
if k not in self.permitted:
mlog.warning('Passed invalid keyword argument %s. This will become a hard error in the future.' % k)
return f(s, interpreter, state, args, kwargs)
return wrapped
_found_programs = {}
class ExtensionModule:
def __init__(self):
self.snippets = set() # List of methods that operate only on the interpreter.

@ -30,6 +30,7 @@ from .. import interpreter
from . import GResourceTarget, GResourceHeaderTarget, GirTarget, TypelibTarget, VapiTarget
from . import find_program, get_include_args
from . import ExtensionModule
from . import noKwargs, permittedKwargs
# gresource compilation is broken due to the way
@ -90,6 +91,8 @@ class GnomeModule(ExtensionModule):
mlog.bold('https://github.com/mesonbuild/meson/issues/1387'))
gdbuswarning_printed = True
@permittedKwargs({'source_dir', 'c_name', 'dependencies', 'export', 'gresource_bundle', 'install_header',
'install', 'install_dir', 'extra_args'})
def compile_resources(self, state, args, kwargs):
self.__print_gresources_warning(state)
glib_version = self._get_native_glib_version(state)
@ -377,6 +380,10 @@ class GnomeModule(ExtensionModule):
return cflags, ldflags, gi_includes
@permittedKwargs({'sources', 'nsversion', 'namespace', 'symbol_prefix', 'identifier_prefix',
'export_packagse', 'includes', 'dependencies', 'link_with', 'include_directories',
'install', 'install_dir_gir', 'install_dir_typelib', 'extra_args',
'packages'})
def generate_gir(self, state, args, kwargs):
if len(args) != 1:
raise MesonException('Gir takes one argument')
@ -595,6 +602,7 @@ class GnomeModule(ExtensionModule):
rv = [scan_target, typelib_target]
return ModuleReturnValue(rv, rv)
@noKwargs
def compile_schemas(self, state, args, kwargs):
if args:
raise MesonException('Compile_schemas does not take positional arguments.')
@ -613,6 +621,7 @@ class GnomeModule(ExtensionModule):
target_g = build.CustomTarget(targetname, state.subdir, kwargs)
return ModuleReturnValue(target_g, [target_g])
@permittedKwargs({'sources', 'media', 'symlink_media', 'languages'})
def yelp(self, state, args, kwargs):
if len(args) < 1:
raise MesonException('Yelp requires a project id')
@ -670,6 +679,10 @@ class GnomeModule(ExtensionModule):
rv = [inscript, pottarget, potarget]
return ModuleReturnValue(None, rv)
@permittedKwargs({'main_xml', 'main_sgml', 'src_dir', 'dependencies', 'install',
'install_dir', 'scan_args', 'scanobjs_args', 'gobject_typesfile',
'fixxref_args', 'html_args', 'html_assets', 'content_files',
'mkdb_args'})
def gtkdoc(self, state, args, kwargs):
if len(args) != 1:
raise MesonException('Gtkdoc must have one positional argument.')
@ -763,6 +776,7 @@ class GnomeModule(ExtensionModule):
return args
@noKwargs
def gtkdoc_html_dir(self, state, args, kwargs):
if len(args) != 1:
raise MesonException('Must have exactly one argument.')
@ -792,6 +806,7 @@ class GnomeModule(ExtensionModule):
return []
@permittedKwargs({'interface_prefix', 'namespace', 'object_manager'})
def gdbus_codegen(self, state, args, kwargs):
if len(args) != 2:
raise MesonException('Gdbus_codegen takes two arguments, name and xml file.')
@ -820,6 +835,9 @@ class GnomeModule(ExtensionModule):
ct = build.CustomTarget(target_name, state.subdir, custom_kwargs)
return ModuleReturnValue(ct, [ct])
@permittedKwargs({'sources', 'c_template', 'h_template', 'install_header', 'install_dir',
'comments', 'identifier_prefix', 'symbol_prefix', 'eprod', 'vprod',
'fhead', 'fprod', 'ftail', 'vhead', 'vtail', 'depends'})
def mkenums(self, state, args, kwargs):
if len(args) != 1:
raise MesonException('Mkenums requires one positional argument.')
@ -932,6 +950,8 @@ class GnomeModule(ExtensionModule):
# https://github.com/mesonbuild/meson/issues/973
absolute_paths=True)
@permittedKwargs({'sources', 'prefix', 'install_header', 'install_dir', 'stdinc',
'nostdinc', 'internal', 'skip_source', 'valist_marshallers'})
def genmarshal(self, state, args, kwargs):
if len(args) != 1:
raise MesonException(
@ -1070,6 +1090,8 @@ class GnomeModule(ExtensionModule):
link_with += self._get_vapi_link_with(dep)
return link_with
@permittedKwargs({'sources', 'packages', 'metadata_dirs', 'gir_dirs',
'vapi_dirs', 'install', 'install_dir'})
def generate_vapi(self, state, args, kwargs):
if len(args) != 1:
raise MesonException('The library name is required')

@ -20,6 +20,7 @@ from .. import coredata, mesonlib, build
from ..mesonlib import MesonException
from . import ModuleReturnValue
from . import ExtensionModule
from . import permittedKwargs
PRESET_ARGS = {
'glib': [
@ -55,6 +56,8 @@ class I18nModule(ExtensionModule):
src_dir = path.join(state.environment.get_source_dir(), state.subdir)
return [path.join(src_dir, d) for d in dirs]
@permittedKwargs({'languages', 'data_dirs', 'preset', 'args', 'po_dir', 'type',
'input', 'output', 'install', 'install_dir'})
def merge_file(self, state, args, kwargs):
podir = kwargs.pop('po_dir', None)
if not podir:
@ -78,6 +81,7 @@ class I18nModule(ExtensionModule):
ct = build.CustomTarget(kwargs['output'] + '_merge', state.subdir, kwargs)
return ModuleReturnValue(ct, [ct])
@permittedKwargs({'po_dir', 'data_dirs', 'type', 'languages'})
def gettext(self, state, args, kwargs):
if len(args) != 1:
raise coredata.MesonException('Gettext requires one positional argument (package name).')

@ -14,9 +14,11 @@
from . import ModuleReturnValue
from . import ExtensionModule
from . import noKwargs
class TestModule(ExtensionModule):
@noKwargs
def print_hello(self, state, args, kwargs):
print('Hello from a Meson module')
rv = ModuleReturnValue(None, [])

@ -19,6 +19,7 @@ from .. import mesonlib
from .. import mlog
from . import ModuleReturnValue
from . import ExtensionModule
from . import permittedKwargs
class PkgConfigModule(ExtensionModule):
@ -114,6 +115,9 @@ class PkgConfigModule(ExtensionModule):
processed_libs.append(l)
return processed_libs
@permittedKwargs({'libraries', 'version', 'name', 'description', 'filebase',
'subdirs', 'requires', 'requires_private', 'libraries_private',
'install_dir', 'variables'})
def generate(self, state, args, kwargs):
if len(args) > 0:
raise mesonlib.MesonException('Pkgconfig_gen takes no positional arguments.')

@ -18,6 +18,11 @@ from .. import mesonlib, dependencies
from . import ExtensionModule
from mesonbuild.modules import ModuleReturnValue
from . import noKwargs, permittedSnippetKwargs
from ..interpreter import shlib_kwargs
mod_kwargs = set()
mod_kwargs.update(shlib_kwargs)
class Python3Module(ExtensionModule):
@ -25,6 +30,7 @@ class Python3Module(ExtensionModule):
super().__init__()
self.snippets.add('extension_module')
@permittedSnippetKwargs(mod_kwargs)
def extension_module(self, interpreter, state, args, kwargs):
if 'name_prefix' in kwargs:
raise mesonlib.MesonException('Name_prefix is set automatically, specifying it is forbidden.')
@ -43,20 +49,19 @@ class Python3Module(ExtensionModule):
kwargs['name_suffix'] = suffix
return interpreter.func_shared_module(None, args, kwargs)
@noKwargs
def find_python(self, state, args, kwargs):
py3 = dependencies.ExternalProgram('python3', sys.executable, silent=True)
return ModuleReturnValue(py3, [py3])
@noKwargs
def language_version(self, state, args, kwargs):
if args or kwargs:
raise mesonlib.MesonException('language_version() takes no arguments.')
return ModuleReturnValue(sysconfig.get_python_version(), [])
@noKwargs
def sysconfig_path(self, state, args, kwargs):
if len(args) != 1:
raise mesonlib.MesonException('sysconfig_path() requires passing the name of path to get.')
if kwargs:
raise mesonlib.MesonException('sysconfig_path() does not accept keywords.')
path_name = args[0]
valid_names = sysconfig.get_path_names()
if path_name not in valid_names:

@ -20,6 +20,7 @@ from ..dependencies import Qt4Dependency
from . import ExtensionModule
import xml.etree.ElementTree as ET
from . import ModuleReturnValue
from . import permittedKwargs
class Qt4Module(ExtensionModule):
tools_detected = False
@ -96,6 +97,7 @@ class Qt4Module(ExtensionModule):
except Exception:
return []
@permittedKwargs({'moc_headers', 'moc_sources', 'ui_files', 'qresources', 'method'})
def preprocess(self, state, args, kwargs):
rcc_files = kwargs.pop('qresources', [])
if not isinstance(rcc_files, list):

@ -20,6 +20,7 @@ from ..dependencies import Qt5Dependency
from . import ExtensionModule
import xml.etree.ElementTree as ET
from . import ModuleReturnValue
from . import permittedKwargs
class Qt5Module(ExtensionModule):
tools_detected = False
@ -102,6 +103,7 @@ class Qt5Module(ExtensionModule):
except Exception:
return []
@permittedKwargs({'moc_headers', 'moc_sources', 'ui_files', 'qresources', 'method'})
def preprocess(self, state, args, kwargs):
rcc_files = kwargs.pop('qresources', [])
if not isinstance(rcc_files, list):

@ -22,11 +22,13 @@ from .. import mlog
from . import GirTarget, TypelibTarget
from . import ModuleReturnValue
from . import ExtensionModule
from . import noKwargs
import os
class RPMModule(ExtensionModule):
@noKwargs
def generate_spec_template(self, state, args, kwargs):
compiler_deps = set()
for compiler in state.compilers.values():

@ -20,6 +20,7 @@ from ..mesonlib import MesonException
from . import get_include_args
from . import ModuleReturnValue
from . import ExtensionModule
from . import permittedKwargs
class WindowsModule(ExtensionModule):
@ -29,6 +30,7 @@ class WindowsModule(ExtensionModule):
return compilers[l]
raise MesonException('Resource compilation requires a C or C++ compiler.')
@permittedKwargs({'args', 'include_directories'})
def compile_resources(self, state, args, kwargs):
comp = self.detect_compiler(state.compilers)

@ -0,0 +1,5 @@
project('module test', 'c')
modtest = import('modtest', i_cause: 'a_build_failure')
modtest.print_hello()
Loading…
Cancel
Save