aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/interpreter.py76
-rw-r--r--mesonbuild/modules/__init__.py5
-rw-r--r--mesonbuild/modules/gnome.py40
-rw-r--r--mesonbuild/modules/i18n.py7
-rw-r--r--mesonbuild/modules/modtest.py4
-rw-r--r--mesonbuild/modules/pkgconfig.py5
-rw-r--r--mesonbuild/modules/qt4.py3
-rw-r--r--mesonbuild/modules/qt5.py3
-rw-r--r--mesonbuild/modules/rpm.py2
-rw-r--r--mesonbuild/modules/windows.py4
-rw-r--r--test cases/frameworks/7 gnome/gdbus/meson.build11
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)