diff options
-rw-r--r-- | mesonbuild/interpreter.py | 76 | ||||
-rw-r--r-- | mesonbuild/modules/__init__.py | 5 | ||||
-rw-r--r-- | mesonbuild/modules/gnome.py | 40 | ||||
-rw-r--r-- | mesonbuild/modules/i18n.py | 7 | ||||
-rw-r--r-- | mesonbuild/modules/modtest.py | 4 | ||||
-rw-r--r-- | mesonbuild/modules/pkgconfig.py | 5 | ||||
-rw-r--r-- | mesonbuild/modules/qt4.py | 3 | ||||
-rw-r--r-- | mesonbuild/modules/qt5.py | 3 | ||||
-rw-r--r-- | mesonbuild/modules/rpm.py | 2 | ||||
-rw-r--r-- | mesonbuild/modules/windows.py | 4 | ||||
-rw-r--r-- | test cases/frameworks/7 gnome/gdbus/meson.build | 11 |
11 files changed, 104 insertions, 56 deletions
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index 67ee658..382c04c 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -28,6 +28,7 @@ from .interpreterbase import InterpreterBase from .interpreterbase import check_stringlist, noPosargs, noKwargs, stringArgs from .interpreterbase import InterpreterException, InvalidArguments, InvalidCode from .interpreterbase import InterpreterObject, MutableInterpreterObject +from .modules import ModuleReturnValue import os, sys, shutil, uuid import re @@ -430,11 +431,9 @@ class Headers(InterpreterObject): return self.custom_install_dir class DataHolder(InterpreterObject): - def __init__(self, sources, install_dir): + def __init__(self, data): super().__init__() - if not isinstance(install_dir, str): - raise InterpreterException('Custom_install_dir must be a string.') - self.held_object = build.Data(sources, install_dir) + self.held_object = data def get_source_subdir(self): return self.held_object.source_subdir @@ -984,6 +983,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)) + # 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()) @@ -999,6 +1001,8 @@ 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 num_targets != len(self.interpreter.build.targets): + raise InterpreterException('Extension module altered internal state illegally.') return self.interpreter.module_method_callback(value) class MesonMain(InterpreterObject): @@ -1238,29 +1242,39 @@ class Interpreter(InterpreterBase): 'join_paths': self.func_join_paths, }) - def module_method_callback(self, invalues): - unwrap_single = False - if invalues is None: - return + def holderify(self, item): + if isinstance(item, list): + return [self.holderify(x) for x in item] + if isinstance(item, build.CustomTarget): + return CustomTargetHolder(item, self) + elif isinstance(item, (int, str)) or item is None: + return item + elif isinstance(item, build.Executable): + return ExecutableHolder(item, self) + elif isinstance(item, build.GeneratedList): + return GeneratedListHolder(item) + elif isinstance(item, build.RunTarget): + raise RuntimeError('This is not a pipe.') + elif isinstance(item, build.RunScript): + raise RuntimeError('Do not do this.') + elif isinstance(item, build.Data): + return DataHolder(item) + elif isinstance(item, dependencies.InternalDependency): + return InternalDependencyHolder(item) + else: + print(item) + raise InterpreterException('Module returned a value of unknown type.') + + 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): + if isinstance(v, (build.BuildTarget, build.CustomTarget, build.RunTarget)): self.add_target(v.name, v) - outvalues.append(CustomTargetHolder(v, self)) - elif isinstance(v, (int, str)): - outvalues.append(v) - elif isinstance(v, build.Executable): - 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): @@ -1268,14 +1282,18 @@ 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] - return outvalues + + 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): return self.build_def_files @@ -2113,7 +2131,7 @@ requirements use the version keyword argument instead.''') source_strings.append(s) sources += self.source_strings_to_files(source_strings) install_dir = kwargs.get('install_dir', None) - data = DataHolder(sources, install_dir) + data = DataHolder(build.Data(sources, install_dir)) self.build.data.append(data.held_object) return data @@ -2173,7 +2191,7 @@ requirements use the version keyword argument instead.''') idir = kwargs.get('install_dir', None) if isinstance(idir, str): cfile = mesonlib.File.from_built_file(ofile_path, ofile_fname) - self.build.data.append(DataHolder([cfile], idir).held_object) + self.build.data.append(build.Data([cfile], idir)) return mesonlib.File.from_built_file(self.subdir, output) @stringArgs diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py index 184d85a..16cada0 100644 --- a/mesonbuild/modules/__init__.py +++ b/mesonbuild/modules/__init__.py @@ -45,6 +45,11 @@ def get_include_args(environment, include_dirs, prefix='-I'): return dirs_str +class ModuleReturnValue: + def __init__(self, return_value, new_objects): + self.return_value = return_value + assert(isinstance(new_objects, list)) + self.new_objects = new_objects class GResourceTarget(build.CustomTarget): def __init__(self, name, subdir, kwargs): diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index f7aa0f2..ad34640 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/i18n.py b/mesonbuild/modules/i18n.py index 4b4ae3d..fa52463 100644 --- a/mesonbuild/modules/i18n.py +++ b/mesonbuild/modules/i18n.py @@ -15,6 +15,8 @@ from os import path from .. import coredata, mesonlib, build from ..mesonlib import MesonException +from . import ModuleReturnValue + import sys import shutil @@ -59,7 +61,8 @@ class I18nModule: kwargs['command'] = ['msgfmt', '--' + file_type, '--template', '@INPUT@', '-d', podir, '-o', '@OUTPUT@'] - return build.CustomTarget(kwargs['output'] + '_merge', state.subdir, kwargs) + ct = build.CustomTarget(kwargs['output'] + '_merge', state.subdir, kwargs) + return ModuleReturnValue(ct, [ct]) def gettext(self, state, args, kwargs): if len(args) != 1: @@ -114,7 +117,7 @@ class I18nModule: args.append(lang_arg) iscript = build.RunScript(script, args) - return [pottarget, gmotarget, iscript, updatepotarget] + return ModuleReturnValue(None, [pottarget, gmotarget, iscript, updatepotarget]) def initialize(): return I18nModule() diff --git a/mesonbuild/modules/modtest.py b/mesonbuild/modules/modtest.py index c9247e6..dc347e2 100644 --- a/mesonbuild/modules/modtest.py +++ b/mesonbuild/modules/modtest.py @@ -12,10 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +from . import ModuleReturnValue + class TestModule: def print_hello(self, state, args, kwargs): print('Hello from a Meson module') + rv = ModuleReturnValue(None, []) + return rv def initialize(): return TestModule() diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py index aaf0746..38358f3 100644 --- a/mesonbuild/modules/pkgconfig.py +++ b/mesonbuild/modules/pkgconfig.py @@ -15,6 +15,8 @@ from .. import build from .. import mesonlib from .. import mlog +from . import ModuleReturnValue + import os class PkgConfigModule: @@ -138,7 +140,8 @@ class PkgConfigModule: self.generate_pkgconfig_file(state, libs, subdirs, name, description, url, version, pcfile, pub_reqs, priv_reqs, conflicts, priv_libs) - return build.Data(mesonlib.File(True, state.environment.get_scratch_dir(), pcfile), pkgroot) + res = build.Data(mesonlib.File(True, state.environment.get_scratch_dir(), pcfile), pkgroot) + return ModuleReturnValue(res, [res]) def initialize(): return PkgConfigModule() diff --git a/mesonbuild/modules/qt4.py b/mesonbuild/modules/qt4.py index beb7ca5..6759270 100644 --- a/mesonbuild/modules/qt4.py +++ b/mesonbuild/modules/qt4.py @@ -18,6 +18,7 @@ from .. import build from ..mesonlib import MesonException, Popen_safe from ..dependencies import Qt4Dependency import xml.etree.ElementTree as ET +from . import ModuleReturnValue class Qt4Module(): tools_detected = False @@ -153,7 +154,7 @@ class Qt4Module(): moc_gen = build.Generator([self.moc], moc_kwargs) moc_output = moc_gen.process_files('Qt4 moc source', moc_sources, state) sources.append(moc_output) - return sources + return ModuleReturnValue(sources, sources) def initialize(): mlog.warning('rcc dependencies will not work properly until this upstream issue is fixed:', diff --git a/mesonbuild/modules/qt5.py b/mesonbuild/modules/qt5.py index 2e348db..53f1cb5 100644 --- a/mesonbuild/modules/qt5.py +++ b/mesonbuild/modules/qt5.py @@ -18,6 +18,7 @@ from .. import build from ..mesonlib import MesonException, Popen_safe from ..dependencies import Qt5Dependency import xml.etree.ElementTree as ET +from . import ModuleReturnValue class Qt5Module(): tools_detected = False @@ -159,7 +160,7 @@ class Qt5Module(): moc_gen = build.Generator([self.moc], moc_kwargs) moc_output = moc_gen.process_files('Qt5 moc source', moc_sources, state) sources.append(moc_output) - return sources + return ModuleReturnValue(sources, sources) def initialize(): mlog.warning('rcc dependencies will not work reliably until this upstream issue is fixed:', diff --git a/mesonbuild/modules/rpm.py b/mesonbuild/modules/rpm.py index ece1610..a696db9 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 56bad2d..8574dbe 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 6aa2849..7f7c97b 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) |