diff options
Diffstat (limited to 'mesonbuild')
-rw-r--r-- | mesonbuild/backend/backends.py | 3 | ||||
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 2 | ||||
-rw-r--r-- | mesonbuild/compilers/c.py | 2 | ||||
-rw-r--r-- | mesonbuild/compilers/compilers.py | 25 | ||||
-rw-r--r-- | mesonbuild/compilers/cpp.py | 3 | ||||
-rw-r--r-- | mesonbuild/compilers/cs.py | 3 | ||||
-rw-r--r-- | mesonbuild/compilers/objc.py | 3 | ||||
-rw-r--r-- | mesonbuild/compilers/objcpp.py | 3 | ||||
-rw-r--r-- | mesonbuild/dependencies/misc.py | 18 | ||||
-rw-r--r-- | mesonbuild/dependencies/ui.py | 10 | ||||
-rw-r--r-- | mesonbuild/environment.py | 8 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 248 | ||||
-rw-r--r-- | mesonbuild/interpreterbase.py | 60 | ||||
-rw-r--r-- | mesonbuild/modules/__init__.py | 16 | ||||
-rw-r--r-- | mesonbuild/modules/gnome.py | 22 | ||||
-rw-r--r-- | mesonbuild/modules/i18n.py | 4 | ||||
-rw-r--r-- | mesonbuild/modules/modtest.py | 2 | ||||
-rw-r--r-- | mesonbuild/modules/pkgconfig.py | 4 | ||||
-rw-r--r-- | mesonbuild/modules/python3.py | 13 | ||||
-rw-r--r-- | mesonbuild/modules/qt4.py | 2 | ||||
-rw-r--r-- | mesonbuild/modules/qt5.py | 2 | ||||
-rw-r--r-- | mesonbuild/modules/rpm.py | 2 | ||||
-rw-r--r-- | mesonbuild/modules/windows.py | 2 | ||||
-rw-r--r-- | mesonbuild/mparser.py | 7 |
24 files changed, 339 insertions, 125 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index a24b65f..d2ea467 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -429,6 +429,9 @@ class Backend: # NOTE: We must preserve the order in which external deps are # specified, so we reverse the list before iterating over it. for dep in reversed(target.get_external_deps()): + if not dep.found(): + continue + if compiler.language == 'vala': if isinstance(dep, dependencies.PkgConfigDependency): if dep.name == 'glib-2.0' and dep.version_reqs is not None: diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index e2653d4..61b5f18 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -1606,7 +1606,7 @@ rule FORTRAN_DEP_HACK output_args=' '.join(compiler.get_output_args('$out')), compile_only_args=' '.join(compiler.get_compile_only_args()) ) - description = ' description = Compiling %s object $out.\n' % langname.title() + description = ' description = Compiling %s object $out.\n' % compiler.get_display_language() if compiler.get_id() == 'msvc': deps = ' deps = msvc\n' else: diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index c164ccd..cf9d1ee 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -179,7 +179,7 @@ class CCompiler(Compiler): return ['-Wl,--out-implib=' + implibname] def sanity_check_impl(self, work_dir, environment, sname, code): - mlog.debug('Sanity testing ' + self.language + ' compiler:', ' '.join(self.exelist)) + mlog.debug('Sanity testing ' + self.get_display_language() + ' compiler:', ' '.join(self.exelist)) mlog.debug('Is cross compiler: %s.' % str(self.is_cross)) extra_flags = [] diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index ddcaf7a..579988f 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -584,6 +584,9 @@ class Compiler: def get_language(self): return self.language + def get_display_language(self): + return self.language.capitalize() + def get_default_suffix(self): return self.default_suffix @@ -619,28 +622,28 @@ class Compiler: return [] def has_header(self, *args, **kwargs): - raise EnvironmentException('Language %s does not support header checks.' % self.language) + raise EnvironmentException('Language %s does not support header checks.' % self.get_display_language()) def has_header_symbol(self, *args, **kwargs): - raise EnvironmentException('Language %s does not support header symbol checks.' % self.language) + raise EnvironmentException('Language %s does not support header symbol checks.' % self.get_display_language()) def compiles(self, *args, **kwargs): - raise EnvironmentException('Language %s does not support compile checks.' % self.language) + raise EnvironmentException('Language %s does not support compile checks.' % self.get_display_language()) def links(self, *args, **kwargs): - raise EnvironmentException('Language %s does not support link checks.' % self.language) + raise EnvironmentException('Language %s does not support link checks.' % self.get_display_language()) def run(self, *args, **kwargs): - raise EnvironmentException('Language %s does not support run checks.' % self.language) + raise EnvironmentException('Language %s does not support run checks.' % self.get_display_language()) def sizeof(self, *args, **kwargs): - raise EnvironmentException('Language %s does not support sizeof checks.' % self.language) + raise EnvironmentException('Language %s does not support sizeof checks.' % self.get_display_language()) def alignment(self, *args, **kwargs): - raise EnvironmentException('Language %s does not support alignment checks.' % self.language) + raise EnvironmentException('Language %s does not support alignment checks.' % self.get_display_language()) def has_function(self, *args, **kwargs): - raise EnvironmentException('Language %s does not support function checks.' % self.language) + raise EnvironmentException('Language %s does not support function checks.' % self.get_display_language()) @classmethod def unix_args_to_native(cls, args): @@ -648,7 +651,7 @@ class Compiler: return args[:] def find_library(self, *args, **kwargs): - raise EnvironmentException('Language {} does not support library finding.'.format(self.language)) + raise EnvironmentException('Language {} does not support library finding.'.format(self.get_display_language())) def get_library_dirs(self): return [] @@ -659,7 +662,7 @@ class Compiler: def has_multi_arguments(self, args, env): raise EnvironmentException( 'Language {} does not support has_multi_arguments.'.format( - self.language)) + self.get_display_language())) def get_cross_extra_flags(self, environment, link): extra_flags = [] @@ -750,7 +753,7 @@ class Compiler: def get_link_whole_for(self, args): if isinstance(args, list) and not args: return [] - raise EnvironmentException('Language %s does not support linking whole archives.' % self.language) + raise EnvironmentException('Language %s does not support linking whole archives.' % self.get_display_language()) def build_unix_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath): if not rpath_paths and not install_rpath: diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 6d50e57..01525b0 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -32,6 +32,9 @@ class CPPCompiler(CCompiler): self.language = 'cpp' CCompiler.__init__(self, exelist, version, is_cross, exe_wrap) + def get_display_language(self): + return 'C++' + def get_no_stdinc_args(self): return ['-nostdinc++'] diff --git a/mesonbuild/compilers/cs.py b/mesonbuild/compilers/cs.py index c65a539..e6c5b9e 100644 --- a/mesonbuild/compilers/cs.py +++ b/mesonbuild/compilers/cs.py @@ -25,6 +25,9 @@ class MonoCompiler(Compiler): self.id = 'mono' self.monorunner = 'mono' + def get_display_language(self): + return 'C sharp' + def get_output_args(self, fname): return ['-out:' + fname] diff --git a/mesonbuild/compilers/objc.py b/mesonbuild/compilers/objc.py index b011c81..388e83b 100644 --- a/mesonbuild/compilers/objc.py +++ b/mesonbuild/compilers/objc.py @@ -24,6 +24,9 @@ class ObjCCompiler(CCompiler): self.language = 'objc' CCompiler.__init__(self, exelist, version, is_cross, exe_wrap) + def get_display_language(self): + return 'Objective-C' + def sanity_check(self, work_dir, environment): # TODO try to use sanity_check_impl instead of duplicated code source_name = os.path.join(work_dir, 'sanitycheckobjc.m') diff --git a/mesonbuild/compilers/objcpp.py b/mesonbuild/compilers/objcpp.py index b181f9a..c2e4647 100644 --- a/mesonbuild/compilers/objcpp.py +++ b/mesonbuild/compilers/objcpp.py @@ -24,6 +24,9 @@ class ObjCPPCompiler(CPPCompiler): self.language = 'objcpp' CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap) + def get_display_language(self): + return 'Objective-C++' + def sanity_check(self, work_dir, environment): # TODO try to use sanity_check_impl instead of duplicated code source_name = os.path.join(work_dir, 'sanitycheckobjcpp.mm') diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index c24acf0..99df587 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -35,7 +35,7 @@ class BoostDependency(ExternalDependency): def __init__(self, environment, kwargs): super().__init__('boost', environment, 'cpp', kwargs) - self.libdir = '' + self.libdir = None try: self.boost_root = os.environ['BOOST_ROOT'] if not os.path.isabs(self.boost_root): @@ -56,6 +56,9 @@ class BoostDependency(ExternalDependency): self.incdir = os.environ['BOOST_INCLUDEDIR'] else: self.incdir = '/usr/include' + + if 'BOOST_LIBRARYDIR' in os.environ: + self.libdir = os.environ['BOOST_LIBRARYDIR'] else: self.incdir = os.path.join(self.boost_root, 'include') self.boost_inc_subdir = os.path.join(self.incdir, 'boost') @@ -183,7 +186,9 @@ class BoostDependency(ExternalDependency): if not libdir: return libdir = libdir[0] - self.libdir = libdir + # Don't override what was set in the environment + if self.libdir: + self.libdir = libdir globber = 'libboost_*-gd-*.lib' if self.static else 'boost_*-gd-*.lib' # FIXME for entry in glob.glob(os.path.join(libdir, globber)): (_, fname) = os.path.split(entry) @@ -200,8 +205,8 @@ class BoostDependency(ExternalDependency): libsuffix = 'so' globber = 'libboost_*.{}'.format(libsuffix) - if 'BOOST_LIBRARYDIR' in os.environ: - libdirs = [os.environ['BOOST_LIBRARYDIR']] + if self.libdir: + libdirs = [self.libdir] elif self.boost_root is None: libdirs = mesonlib.get_library_dirs() else: @@ -219,6 +224,7 @@ class BoostDependency(ExternalDependency): def get_win_link_args(self): args = [] + # TODO: should this check self.libdir? if self.boost_root: args.append('-L' + self.libdir) for module in self.requested_modules: @@ -233,8 +239,8 @@ class BoostDependency(ExternalDependency): args = [] if self.boost_root: args.append('-L' + os.path.join(self.boost_root, 'lib')) - elif 'BOOST_LIBRARYDIR' in os.environ: - args.append('-L' + os.environ['BOOST_LIBRARYDIR']) + elif self.libdir: + args.append('-L' + self.libdir) for module in self.requested_modules: module = BoostDependency.name2lib.get(module, module) libname = 'boost_' + module diff --git a/mesonbuild/dependencies/ui.py b/mesonbuild/dependencies/ui.py index 7cc8bb4..f1ee7a6 100644 --- a/mesonbuild/dependencies/ui.py +++ b/mesonbuild/dependencies/ui.py @@ -291,10 +291,16 @@ class QtBaseDependency(ExternalDependency): mincdir = os.path.join(incdir, 'Qt' + module) self.compile_args.append('-I' + mincdir) if for_windows(self.env.is_cross_build(), self.env): - libfile = os.path.join(libdir, self.qtpkgname + module + '.lib') + is_debug = self.env.cmd_line_options.buildtype.startswith('debug') + dbg = 'd' if is_debug else '' + if self.qtver == '4': + base_name = 'Qt' + module + dbg + '4' + else: + base_name = 'Qt5' + module + dbg + libfile = os.path.join(libdir, base_name + '.lib') if not os.path.isfile(libfile): # MinGW can link directly to .dll - libfile = os.path.join(self.bindir, self.qtpkgname + module + '.dll') + libfile = os.path.join(self.bindir, base_name + '.dll') if not os.path.isfile(libfile): self.is_found = False break diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index 3be068a..1e4e04b 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -514,7 +514,7 @@ class Environment: if 'Free Software Foundation' in out: defines = self.get_gnu_compiler_defines(compiler) if not defines: - popen_exceptions[compiler] = 'no pre-processor defines' + popen_exceptions[' '.join(compiler)] = 'no pre-processor defines' continue gtype = self.get_gnu_compiler_type(defines) version = self.get_gnu_version_from_defines(defines) @@ -566,7 +566,7 @@ class Environment: if 'GNU Fortran' in out: defines = self.get_gnu_compiler_defines(compiler) if not defines: - popen_exceptions[compiler] = 'no pre-processor defines' + popen_exceptions[' '.join(compiler)] = 'no pre-processor defines' continue gtype = self.get_gnu_compiler_type(defines) version = self.get_gnu_version_from_defines(defines) @@ -617,7 +617,7 @@ class Environment: if 'Free Software Foundation' in out: defines = self.get_gnu_compiler_defines(compiler) if not defines: - popen_exceptions[compiler] = 'no pre-processor defines' + popen_exceptions[' '.join(compiler)] = 'no pre-processor defines' continue gtype = self.get_gnu_compiler_type(defines) version = self.get_gnu_version_from_defines(defines) @@ -643,7 +643,7 @@ class Environment: if 'Free Software Foundation' in out: defines = self.get_gnu_compiler_defines(compiler) if not defines: - popen_exceptions[compiler] = 'no pre-processor defines' + popen_exceptions[' '.join(compiler)] = 'no pre-processor defines' continue gtype = self.get_gnu_compiler_type(defines) version = self.get_gnu_version_from_defines(defines) diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index 7f279c1..916529f 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -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 @@ -741,7 +740,7 @@ class CompilerHolder(InterpreterObject): def unittest_args_method(self, args, kwargs): # At time, only D compilers have this feature. if not hasattr(self.compiler, 'get_unittest_args'): - raise InterpreterException('This {} compiler has no unittest arguments.'.format(self.compiler.language)) + raise InterpreterException('This {} compiler has no unittest arguments.'.format(self.compiler.get_display_language())) return self.compiler.get_unittest_args() def has_member_method(self, args, kwargs): @@ -971,8 +970,7 @@ class CompilerHolder(InterpreterObject): raise InvalidCode('Search directory %s is not an absolute path.' % i) linkargs = self.compiler.find_library(libname, self.environment, search_dirs) if required and not linkargs: - l = self.compiler.language.capitalize() - raise InterpreterException('{} library {!r} not found'.format(l, libname)) + raise InterpreterException('{} library {!r} not found'.format(self.compiler.get_display_language(), libname)) lib = dependencies.ExternalLibrary(libname, linkargs, self.environment, self.compiler.language) return ExternalLibraryHolder(lib) @@ -986,7 +984,7 @@ class CompilerHolder(InterpreterObject): h = mlog.green('YES') else: h = mlog.red('NO') - mlog.log('Compiler for {} supports argument {}:'.format(self.compiler.language, args[0]), h) + mlog.log('Compiler for {} supports argument {}:'.format(self.compiler.get_display_language(), args[0]), h) return result def has_multi_arguments_method(self, args, kwargs): @@ -998,7 +996,7 @@ class CompilerHolder(InterpreterObject): h = mlog.red('NO') mlog.log( 'Compiler for {} supports arguments {}:'.format( - self.compiler.language, ' '.join(args)), + self.compiler.get_display_language(), ' '.join(args)), h) return result @@ -1214,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', @@ -1255,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): @@ -1402,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) @@ -1458,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] @@ -1491,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) @@ -1504,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: @@ -1632,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.') @@ -1678,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)) @@ -1794,7 +1886,7 @@ class Interpreter(InterpreterBase): continue else: raise - mlog.log('Native %s compiler: ' % lang, mlog.bold(' '.join(comp.get_exelist())), ' (%s %s)' % (comp.id, comp.version), sep='') + mlog.log('Native %s compiler: ' % comp.get_display_language(), mlog.bold(' '.join(comp.get_exelist())), ' (%s %s)' % (comp.id, comp.version), sep='') if not comp.get_language() in self.coredata.external_args: (preproc_args, compile_args, link_args) = environment.get_args_from_envvars(comp) self.coredata.external_preprocess_args[comp.get_language()] = preproc_args @@ -1802,7 +1894,7 @@ class Interpreter(InterpreterBase): self.coredata.external_link_args[comp.get_language()] = link_args self.build.add_compiler(comp) if need_cross_compiler: - mlog.log('Cross %s compiler: ' % lang, mlog.bold(' '.join(cross_comp.get_exelist())), ' (%s %s)' % (cross_comp.id, cross_comp.version), sep='') + mlog.log('Cross %s compiler: ' % cross_comp.get_display_language(), mlog.bold(' '.join(cross_comp.get_exelist())), ' (%s %s)' % (cross_comp.id, cross_comp.version), sep='') self.build.add_cross_compiler(cross_comp) if self.environment.is_cross_build() and not need_cross_compiler: self.build.add_cross_compiler(comp) @@ -1821,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.') @@ -2001,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) @@ -2018,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') @@ -2038,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') @@ -2076,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') @@ -2084,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: @@ -2134,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) @@ -2211,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) @@ -2280,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 @@ -2299,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: @@ -2313,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.") @@ -2388,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)) @@ -2407,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() @@ -2443,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: @@ -2484,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) @@ -2532,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() @@ -2685,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 diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py index fb87ea2..d44f71b 100644 --- a/mesonbuild/interpreterbase.py +++ b/mesonbuild/interpreterbase.py @@ -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)) diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py index fde3b91..9d75525 100644 --- a/mesonbuild/modules/__init__.py +++ b/mesonbuild/modules/__init__.py @@ -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. diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index 06a1fad..de66ef9 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -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') diff --git a/mesonbuild/modules/i18n.py b/mesonbuild/modules/i18n.py index c4e29cf..d35c7f1 100644 --- a/mesonbuild/modules/i18n.py +++ b/mesonbuild/modules/i18n.py @@ -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).') diff --git a/mesonbuild/modules/modtest.py b/mesonbuild/modules/modtest.py index 3e11b70..dd2f215 100644 --- a/mesonbuild/modules/modtest.py +++ b/mesonbuild/modules/modtest.py @@ -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, []) diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py index 09c615a..7b0bb83 100644 --- a/mesonbuild/modules/pkgconfig.py +++ b/mesonbuild/modules/pkgconfig.py @@ -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.') diff --git a/mesonbuild/modules/python3.py b/mesonbuild/modules/python3.py index 9f01043..6431047 100644 --- a/mesonbuild/modules/python3.py +++ b/mesonbuild/modules/python3.py @@ -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: diff --git a/mesonbuild/modules/qt4.py b/mesonbuild/modules/qt4.py index 0386291..4056b6d 100644 --- a/mesonbuild/modules/qt4.py +++ b/mesonbuild/modules/qt4.py @@ -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): diff --git a/mesonbuild/modules/qt5.py b/mesonbuild/modules/qt5.py index 6497694..6194a23 100644 --- a/mesonbuild/modules/qt5.py +++ b/mesonbuild/modules/qt5.py @@ -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): diff --git a/mesonbuild/modules/rpm.py b/mesonbuild/modules/rpm.py index 17396ae..b0a8db9 100644 --- a/mesonbuild/modules/rpm.py +++ b/mesonbuild/modules/rpm.py @@ -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(): diff --git a/mesonbuild/modules/windows.py b/mesonbuild/modules/windows.py index 3fb0107..6fef5bb 100644 --- a/mesonbuild/modules/windows.py +++ b/mesonbuild/modules/windows.py @@ -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) diff --git a/mesonbuild/mparser.py b/mesonbuild/mparser.py index 75985c3..8400a1a 100644 --- a/mesonbuild/mparser.py +++ b/mesonbuild/mparser.py @@ -475,12 +475,18 @@ class Parser: def e2(self): left = self.e3() while self.accept('or'): + if isinstance(left, EmptyNode): + raise ParseException('Invalid or clause.', + self.getline(), left.lineno, left.colno) left = OrNode(left, self.e3()) return left def e3(self): left = self.e4() while self.accept('and'): + if isinstance(left, EmptyNode): + raise ParseException('Invalid and clause.', + self.getline(), left.lineno, left.colno) left = AndNode(left, self.e4()) return left @@ -633,6 +639,7 @@ class Parser: def ifblock(self): condition = self.statement() clause = IfClauseNode(condition.lineno, condition.colno) + self.expect('eol') block = self.codeblock() clause.ifs.append(IfNode(clause.lineno, clause.colno, condition, block)) self.elseifblock(clause) |