diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index 19e73de61..82aca6079 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -972,7 +972,9 @@ class ModuleHolder(InterpreterObject): raise InvalidArguments('Module %s does not have method %s.' % (self.modname, method_name)) if method_name.startswith('_'): raise InvalidArguments('Function {!r} in module {!r} is private.'.format(method_name, self.modname)) - build_hash = hash(self.interpreter.build) + # This is not 100% reliable but we can't use hash() + # because the Build object contains dicts and lists. + num_targets = len(self.interpreter.build.targets) state = ModuleState() state.build_to_src = os.path.relpath(self.interpreter.environment.get_source_dir(), self.interpreter.environment.get_build_dir()) @@ -988,7 +990,7 @@ class ModuleHolder(InterpreterObject): state.global_args = self.interpreter.build.global_args state.project_args = self.interpreter.build.projects_args.get(self.interpreter.subproject, {}) value = fn(state, args, kwargs) - if hash(self.interpreter.build) != build_hash: + if num_targets != len(self.interpreter.build.targets): raise InterpreterException('Extension module altered internal state illegally.') return self.interpreter.module_method_callback(value) @@ -1252,32 +1254,16 @@ class Interpreter(InterpreterBase): print(item) raise InterpreterException('Module returned a value of unknown type.') - def module_method_callback(self, return_object): - if not isinstance(return_object, ModuleReturnValue): - raise InterpreterException('Bug in module, it returned an invalid object') - invalues = return_object.new_objects - unwrap_single = False - if invalues is None: - return + def process_new_values(self, invalues): if not isinstance(invalues, list): - unwrap_single = True invalues = [invalues] - outvalues = [] for v in invalues: - if isinstance(v, build.CustomTarget): - self.add_target(v.name, v) - outvalues.append(CustomTargetHolder(v, self)) - elif isinstance(v, (int, str)): - outvalues.append(v) - elif isinstance(v, build.Executable): + if isinstance(v, (build.BuildTarget, build.CustomTarget, build.RunTarget)): self.add_target(v.name, v) - outvalues.append(ExecutableHolder(v, self)) elif isinstance(v, list): - outvalues.append(self.module_method_callback(v)) + self.module_method_callback(v) elif isinstance(v, build.GeneratedList): - outvalues.append(GeneratedListHolder(v)) - elif isinstance(v, build.RunTarget): - self.add_target(v.name, v) + pass elif isinstance(v, build.RunScript): self.build.install_scripts.append(v) elif isinstance(v, build.Data): @@ -1285,13 +1271,17 @@ class Interpreter(InterpreterBase): elif isinstance(v, dependencies.InternalDependency): # FIXME: This is special cased and not ideal: # The first source is our new VapiTarget, the rest are deps - self.module_method_callback(v.sources[0]) - outvalues.append(InternalDependencyHolder(v)) + self.process_new_values(v.sources[0]) else: - print(v) raise InterpreterException('Module returned a value of unknown type.') - if len(outvalues) == 1 and unwrap_single: - return outvalues[0] + + def module_method_callback(self, return_object): + if not isinstance(return_object, ModuleReturnValue): + print(return_object) + assert(False) + raise InterpreterException('Bug in module, it returned an invalid object') + invalues = return_object.new_objects + self.process_new_values(invalues) return self.holderify(return_object.return_value) def get_build_def_files(self): diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index f7aa0f222..ad3464074 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -20,6 +20,7 @@ import os import sys import copy import subprocess +from . import ModuleReturnValue from ..mesonlib import MesonException, Popen_safe from ..dependencies import Dependency, PkgConfigDependency, InternalDependency from .. import mlog @@ -163,7 +164,7 @@ can not be used with the current version of glib-compiled-resources, due to target_c = GResourceTarget(name, state.subdir, kwargs) if gresource: # Only one target for .gresource files - return [target_c] + return ModuleReturnValue(target_c, [target_c]) h_kwargs = { 'command': cmd, @@ -177,7 +178,8 @@ can not be used with the current version of glib-compiled-resources, due to h_kwargs['install_dir'] = kwargs.get('install_dir', state.environment.coredata.get_builtin_option('includedir')) target_h = GResourceHeaderTarget(args[0] + '_h', state.subdir, h_kwargs) - return [target_c, target_h] + rv = [target_c, target_h] + return ModuleReturnValue(rv, rv) def _get_gresource_dependencies(self, state, input_file, source_dirs, dependencies): for dep in dependencies: @@ -352,7 +354,7 @@ can not be used with the current version of glib-compiled-resources, due to if not girwarning_printed: mlog.warning('gobject-introspection dependency was not found, disabling gir generation.') girwarning_printed = True - return [] + return ModuleReturnValue(None, []) ns = kwargs.pop('namespace') nsversion = kwargs.pop('nsversion') libsources = kwargs.pop('sources') @@ -529,7 +531,8 @@ can not be used with the current version of glib-compiled-resources, due to typelib_kwargs['install_dir'] = kwargs.get('install_dir_typelib', os.path.join(state.environment.get_libdir(), 'girepository-1.0')) typelib_target = TypelibTarget(typelib_output, state.subdir, typelib_kwargs) - return [scan_target, typelib_target] + rv = [scan_target, typelib_target] + return ModuleReturnValue(rv, rv) def compile_schemas(self, state, args, kwargs): if len(args) != 0: @@ -547,7 +550,7 @@ can not be used with the current version of glib-compiled-resources, due to else: targetname = 'gsettings-compile-' + state.subdir target_g = build.CustomTarget(targetname, state.subdir, kwargs) - return target_g + return ModuleReturnValue(target_g, [target_g]) def yelp(self, state, args, kwargs): if len(args) < 1: @@ -603,7 +606,8 @@ can not be used with the current version of glib-compiled-resources, due to potarget = build.RunTarget('help-' + project_id + '-update-po', sys.executable, poargs, [], state.subdir) - return [inscript, pottarget, potarget] + rv = [inscript, pottarget, potarget] + return ModuleReturnValue(None, rv) def gtkdoc(self, state, args, kwargs): if len(args) != 1: @@ -671,7 +675,7 @@ can not be used with the current version of glib-compiled-resources, due to res = [build.RunTarget(targetname, command[0], command[1:] + args, [], state.subdir)] if kwargs.get('install', True): res.append(build.RunScript(command, args)) - return res + return ModuleReturnValue(None, res) def _get_build_args(self, kwargs, state): args = [] @@ -701,7 +705,7 @@ can not be used with the current version of glib-compiled-resources, due to modulename = args[0] if not isinstance(modulename, str): raise MesonException('Argument must be a string') - return os.path.join('share/gtkdoc/html', modulename) + return ModuleReturnValue(os.path.join('share/gtkdoc/html', modulename), []) @staticmethod def _unpack_args(arg, kwarg_name, kwargs, expend_file_state=None): @@ -741,7 +745,8 @@ can not be used with the current version of glib-compiled-resources, due to 'output': outputs, 'command': cmd } - return build.CustomTarget(target_name, state.subdir, custom_kwargs) + ct = build.CustomTarget(target_name, state.subdir, custom_kwargs) + return ModuleReturnValue(ct, [ct]) def mkenums(self, state, args, kwargs): if len(args) != 1: @@ -836,11 +841,11 @@ can not be used with the current version of glib-compiled-resources, due to state.environment.coredata.get_builtin_option('includedir') target = self._make_mkenum_custom_target(state, sources, basename, generic_cmd, custom_kwargs) - return target + return ModuleReturnValue(target, [target]) elif len(targets) == 1: - return targets[0] + return ModuleReturnValue(targets[0], [targets[0]]) else: - return targets + return ModuleReturnValue(targets, targets) @staticmethod def _make_mkenum_custom_target(state, sources, output, cmd, kwargs): @@ -907,7 +912,8 @@ can not be used with the current version of glib-compiled-resources, due to custom_kwargs['output'] = output + '.h' header = build.CustomTarget(output + '_h', state.subdir, custom_kwargs) - return [body, header] + rv = [body, header] + return ModuleReturnValue(rv, rv) @staticmethod def _vapi_args_to_command(prefix, variable, kwargs, accept_vapi=False): @@ -991,6 +997,7 @@ can not be used with the current version of glib-compiled-resources, due to if not isinstance(args[0], str): raise MesonException('The first argument must be the name of the library') + created_values = [] library = args[0] build_dir = os.path.join(state.environment.get_build_dir(), state.subdir) @@ -1040,8 +1047,7 @@ can not be used with the current version of glib-compiled-resources, due to # We shouldn't need this locally but we install it deps_target = self._generate_deps(state, library, vapi_packages, install_dir) - # XXX WRONG, state objects must not be modified! Fix this! - state.data.append(deps_target) + created_values.append(deps_target) vapi_target = VapiTarget(vapi_output, state.subdir, custom_kwargs) # So to try our best to get this to just work we need: @@ -1050,7 +1056,9 @@ can not be used with the current version of glib-compiled-resources, due to # - add relevant directories to include dirs incs = [build.IncludeDirs(state.subdir, ['.'] + vapi_includes, False)] sources = [vapi_target] + vapi_depends - return InternalDependency(None, incs, [], [], link_with, sources, []) + rv = InternalDependency(None, incs, [], [], link_with, sources, []) + created_values.append(rv) + return ModuleReturnValue(rv, created_values) def initialize(): return GnomeModule() diff --git a/mesonbuild/modules/rpm.py b/mesonbuild/modules/rpm.py index ece16102d..a696db94e 100644 --- a/mesonbuild/modules/rpm.py +++ b/mesonbuild/modules/rpm.py @@ -20,6 +20,7 @@ from .. import compilers import datetime from .. import mlog from . import GirTarget, TypelibTarget +from . import ModuleReturnValue import os @@ -153,6 +154,7 @@ class RPMModule: fn.write('- \n') fn.write('\n') mlog.log('RPM spec template written to %s.spec.\n' % proj) + return ModuleReturnValue(None, []) def initialize(): return RPMModule() diff --git a/mesonbuild/modules/windows.py b/mesonbuild/modules/windows.py index 56bad2d33..8574dbec5 100644 --- a/mesonbuild/modules/windows.py +++ b/mesonbuild/modules/windows.py @@ -15,6 +15,8 @@ from .. import mesonlib, dependencies, build from ..mesonlib import MesonException from . import get_include_args +from . import ModuleReturnValue + import os class WindowsModule: @@ -54,7 +56,7 @@ class WindowsModule: 'arguments': res_args} res_gen = build.Generator([rescomp], res_kwargs) res_output = res_gen.process_files('Windows resource', args, state) - return res_output + return ModuleReturnValue(res_output, [res_output]) def initialize(): return WindowsModule() diff --git a/test cases/frameworks/7 gnome/gdbus/meson.build b/test cases/frameworks/7 gnome/gdbus/meson.build index 6aa284916..7f7c97b58 100644 --- a/test cases/frameworks/7 gnome/gdbus/meson.build +++ b/test cases/frameworks/7 gnome/gdbus/meson.build @@ -1,9 +1,10 @@ gdbus_src = gnome.gdbus_codegen('generated-gdbus', 'com.example.Sample.xml', -interface_prefix : 'com.example.', -namespace : 'Sample') + interface_prefix : 'com.example.', + namespace : 'Sample') gdbus_exe = executable('gdbus-test', 'gdbusprog.c', -gdbus_src, -include_directories : include_directories('..'), -dependencies : giounix) + gdbus_src, + include_directories : include_directories('..'), + dependencies : giounix) + test('gdbus', gdbus_exe)