Merge pull request #1194 from centricular/critical-bugfixes-vala

A bunch of bugfixes for Vala
pull/1191/merge
Jussi Pakkanen 8 years ago committed by GitHub
commit 21e475b64b
  1. 44
      mesonbuild/backend/backends.py
  2. 8
      mesonbuild/backend/ninjabackend.py
  3. 3
      mesonbuild/backend/vs2010backend.py
  4. 4
      mesonbuild/build.py
  5. 7
      mesonbuild/dependencies.py
  6. 34
      mesonbuild/modules/__init__.py
  7. 36
      mesonbuild/modules/gnome.py
  8. 2
      mesonbuild/modules/qt4.py
  9. 6
      mesonbuild/modules/rpm.py
  10. 3
      test cases/vala/14 target glib version and gresources/gres/meson.build
  11. 6
      test cases/vala/14 target glib version and gresources/gres/test-resources.xml
  12. 19
      test cases/vala/14 target glib version and gresources/gres/test.ui
  13. 12
      test cases/vala/14 target glib version and gresources/meson.build
  14. 37
      test cases/vala/14 target glib version and gresources/test.vala
  15. 13
      test cases/vala/15 static vapi in source tree/meson.build
  16. 6
      test cases/vala/15 static vapi in source tree/test.vala
  17. 4
      test cases/vala/15 static vapi in source tree/vapi/config.vapi
  18. 43
      test cases/vala/8 generated sources/dependency-generated/enum-types.c.template
  19. 26
      test cases/vala/8 generated sources/dependency-generated/enum-types.h.template
  20. 15
      test cases/vala/8 generated sources/dependency-generated/enums.h
  21. 3
      test cases/vala/8 generated sources/dependency-generated/lib.vala
  22. 3
      test cases/vala/8 generated sources/dependency-generated/main.vala
  23. 44
      test cases/vala/8 generated sources/dependency-generated/meson.build
  24. 1
      test cases/vala/8 generated sources/dependency-generated/null.c
  25. 1
      test cases/vala/8 generated sources/meson.build

@ -504,19 +504,13 @@ class Backend():
libs.append(os.path.join(self.get_target_dir(t), f))
return libs
def eval_custom_target_command(self, target, absolute_paths=False):
if not absolute_paths:
ofilenames = [os.path.join(self.get_target_dir(target), i) for i in target.output]
else:
ofilenames = [os.path.join(self.environment.get_build_dir(), self.get_target_dir(target), i) \
for i in target.output]
def get_custom_target_sources(self, target):
'''
Custom target sources can be of various object types; strings, File,
BuildTarget, even other CustomTargets.
Returns the path to them relative to the build root directory.
'''
srcs = []
outdir = self.get_target_dir(target)
# Many external programs fail on empty arguments.
if outdir == '':
outdir = '.'
if absolute_paths:
outdir = os.path.join(self.environment.get_build_dir(), outdir)
for i in target.get_sources():
if hasattr(i, 'held_object'):
i = i.held_object
@ -530,9 +524,25 @@ class Backend():
fname = [os.path.join(self.get_target_private_dir(target), p) for p in i.get_outputs()]
else:
fname = [i.rel_to_builddir(self.build_to_src)]
if absolute_paths:
fname =[os.path.join(self.environment.get_build_dir(), f) for f in fname]
if target.absolute_paths:
fname = [os.path.join(self.environment.get_build_dir(), f) for f in fname]
srcs += fname
return srcs
def eval_custom_target_command(self, target, absolute_outputs=False):
# We only want the outputs to be absolute when using the VS backend
if not absolute_outputs:
ofilenames = [os.path.join(self.get_target_dir(target), i) for i in target.output]
else:
ofilenames = [os.path.join(self.environment.get_build_dir(), self.get_target_dir(target), i) \
for i in target.output]
srcs = self.get_custom_target_sources(target)
outdir = self.get_target_dir(target)
# Many external programs fail on empty arguments.
if outdir == '':
outdir = '.'
if target.absolute_paths:
outdir = os.path.join(self.environment.get_build_dir(), outdir)
cmd = []
for i in target.command:
if isinstance(i, build.Executable):
@ -545,9 +555,9 @@ class Backend():
i = os.path.join(self.get_target_dir(i), tmp)
elif isinstance(i, mesonlib.File):
i = i.rel_to_builddir(self.build_to_src)
if absolute_paths:
if target.absolute_paths:
i = os.path.join(self.environment.get_build_dir(), i)
# FIXME: str types are blindly added and ignore the 'absolute_paths' argument
# FIXME: str types are blindly added ignoring 'target.absolute_paths'
elif not isinstance(i, str):
err_msg = 'Argument {0} is of unknown type {1}'
raise RuntimeError(err_msg.format(str(i), str(type(i))))
@ -593,7 +603,7 @@ class Backend():
''.format(target.name, i)
raise MesonException(msg)
source = match.group(0)
if match.group(1) is None and not absolute_paths:
if match.group(1) is None and not target.absolute_paths:
lead_dir = ''
else:
lead_dir = self.environment.get_build_dir()

@ -13,6 +13,7 @@
# limitations under the License.
from . import backends
from .. import modules
from .. import environment, mesonlib
from .. import build
from .. import mlog
@ -951,7 +952,7 @@ int dummy;
else:
srctype = othersgen
# Duplicate outputs are disastrous
if f in srctype:
if f in srctype and srctype[f] is not gensrc:
msg = 'Duplicate output {0!r} from {1!r} {2!r}; ' \
'conflicts with {0!r} from {4!r} {3!r}' \
''.format(f, type(gensrc).__name__, gensrc.name,
@ -1032,6 +1033,11 @@ int dummy;
args += ['--pkg', d.name]
elif isinstance(d, dependencies.ExternalLibrary):
args += d.get_lang_args('vala')
# Detect gresources and add --gresources arguments for each
for (gres, gensrc) in other_src[1].items():
if isinstance(gensrc, modules.GResourceTarget):
gres_xml, = self.get_custom_target_sources(gensrc)
args += ['--gresources=' + gres_xml]
extra_args = []
for a in target.extra_args.get('vala', []):

@ -392,6 +392,9 @@ class Vs2010Backend(backends.Backend):
root = self.create_basic_crap(target)
action = ET.SubElement(root, 'ItemDefinitionGroup')
customstep = ET.SubElement(action, 'CustomBuildStep')
# We need to always use absolute paths because our invocation is always
# from the target dir, not the build root.
target.absolute_paths = True
(srcs, ofilenames, cmd) = self.eval_custom_target_command(target, True)
cmd_templ = '''"%s" '''*len(cmd)
ET.SubElement(customstep, 'Command').text = cmd_templ % tuple(cmd)

@ -1218,7 +1218,7 @@ class CustomTarget:
'depfile' : True,
}
def __init__(self, name, subdir, kwargs):
def __init__(self, name, subdir, kwargs, absolute_paths=False):
self.name = name
self.subdir = subdir
self.dependencies = []
@ -1227,6 +1227,8 @@ class CustomTarget:
self.depfile = None
self.process_kwargs(kwargs)
self.extra_files = []
# Whether to use absolute paths for all files on the commandline
self.absolute_paths = absolute_paths
unknowns = []
for k in kwargs:
if k not in CustomTarget.known_kwargs:

@ -145,6 +145,8 @@ class PkgConfigDependency(Dependency):
else:
if not isinstance(self.version_reqs, (str, list)):
raise DependencyException('Version argument must be string or list.')
if isinstance(self.version_reqs, str):
self.version_reqs = [self.version_reqs]
(self.is_found, not_found, found) = \
version_compare_many(self.modversion, self.version_reqs)
if not self.is_found:
@ -169,6 +171,11 @@ class PkgConfigDependency(Dependency):
# Fetch the libraries and library paths needed for using this
self._set_libs()
def __repr__(self):
s = '<{0} {1}: {2} {3}>'
return s.format(self.__class__.__name__, self.name, self.is_found,
self.version_reqs)
def _call_pkgbin(self, args):
p, out = Popen_safe([self.pkgbin] + args, env=os.environ)[0:2]
return (p.returncode, out.strip())

@ -0,0 +1,34 @@
from .. import build
from .. import dependencies
_found_programs = {}
def find_program(program_name, target_name):
if program_name in _found_programs:
return _found_programs[program_name]
program = dependencies.ExternalProgram(program_name)
if not program.found():
m = "Target {!r} can't be generated as {!r} could not be found"
raise MesonException(m.format(target_name, program_name))
_found_programs[program_name] = program
return program
class GResourceTarget(build.CustomTarget):
def __init__(self, name, subdir, kwargs):
super().__init__(name, subdir, kwargs)
class GResourceHeaderTarget(build.CustomTarget):
def __init__(self, name, subdir, kwargs):
super().__init__(name, subdir, kwargs)
class GirTarget(build.CustomTarget):
def __init__(self, name, subdir, kwargs):
super().__init__(name, subdir, kwargs)
class TypelibTarget(build.CustomTarget):
def __init__(self, name, subdir, kwargs):
super().__init__(name, subdir, kwargs)
class VapiTarget(build.CustomTarget):
def __init__(self, name, subdir, kwargs):
super().__init__(name, subdir, kwargs)

@ -25,6 +25,7 @@ from .. import dependencies
from .. import mlog
from .. import mesonlib
from .. import interpreter
from . import find_program, GResourceTarget, GResourceHeaderTarget, GirTarget, TypelibTarget, VapiTarget
# gresource compilation is broken due to the way
# the resource compiler and Ninja clash about it
@ -45,19 +46,13 @@ def gir_has_extra_lib_arg():
_gir_has_extra_lib_arg = False
try:
scanner_options = subprocess.check_output(['g-ir-scanner', '--help']).decode()
_gir_has_extra_lib_arg = '--extra-library' in scanner_options
except (FileNotFound, subprocess.CalledProcessError):
g_ir_scanner = find_program('g-ir-scanner', '').get_command()
opts = Popen_safe(g_ir_scanner + ['--help'], stderr=subprocess.STDOUT)[1]
_gir_has_extra_lib_arg = '--extra-library' in opts
except (MesonException, FileNotFoundError, subprocess.CalledProcessError):
pass
return _gir_has_extra_lib_arg
def find_program(program_name, target_name):
program = dependencies.ExternalProgram(program_name)
if not program.found():
raise MesonException('%s can\'t be generated as %s could not be found' % (
target_name, program_name))
return program
class GnomeModule:
@staticmethod
@ -161,7 +156,7 @@ can not be used with the current version of glib-compiled-resources, due to
depfile = kwargs['output'] + '.d'
kwargs['depfile'] = depfile
kwargs['command'] = copy.copy(cmd) + ['--dependency-file', '@DEPFILE@']
target_c = build.CustomTarget(name, state.subdir, kwargs)
target_c = GResourceTarget(name, state.subdir, kwargs)
if gresource: # Only one target for .gresource files
return [target_c]
@ -177,7 +172,7 @@ can not be used with the current version of glib-compiled-resources, due to
h_kwargs['install'] = install_header
h_kwargs['install_dir'] = kwargs.get('install_dir',
state.environment.coredata.get_builtin_option('includedir'))
target_h = build.CustomTarget(args[0] + '_h', state.subdir, h_kwargs)
target_h = GResourceHeaderTarget(args[0] + '_h', state.subdir, h_kwargs)
return [target_c, target_h]
def _get_gresource_dependencies(self, state, input_file, source_dirs, dependencies):
@ -798,7 +793,7 @@ can not be used with the current version of glib-compiled-resources, due to
install_header = False
for arg, value in kwargs.items():
if arg == 'sources':
sources = [value] + sources
raise AssertionError("sources should've already been handled")
elif arg == 'c_template':
c_template = value
if 'template' in kwargs:
@ -882,7 +877,8 @@ can not be used with the current version of glib-compiled-resources, due to
'command': cmd
}
custom_kwargs.update(kwargs)
return build.CustomTarget(output, state.subdir, custom_kwargs)
return build.CustomTarget(output, state.subdir, custom_kwargs,
absolute_paths=True)
def genmarshal(self, state, args, kwargs):
if len(args) != 1:
@ -1087,15 +1083,3 @@ can not be used with the current version of glib-compiled-resources, due to
def initialize():
return GnomeModule()
class GirTarget(build.CustomTarget):
def __init__(self, name, subdir, kwargs):
super().__init__(name, subdir, kwargs)
class TypelibTarget(build.CustomTarget):
def __init__(self, name, subdir, kwargs):
super().__init__(name, subdir, kwargs)
class VapiTarget(build.CustomTarget):
def __init__(self, name, subdir, kwargs):
super().__init__(name, subdir, kwargs)

@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import os, subprocess
import os
from .. import mlog
from .. import build
from ..mesonlib import MesonException, Popen_safe

@ -19,7 +19,7 @@ from .. import build
from .. import compilers
import datetime
from .. import mlog
from ..modules import gnome
from . import GirTarget, TypelibTarget
import os
@ -65,9 +65,9 @@ class RPMModule:
to_delete.add('%%{buildroot}%%{_libdir}/%s' % target.get_filename())
mlog.warning('removing', mlog.bold(target.get_filename()),
'from package because packaging static libs not recommended')
elif isinstance(target, gnome.GirTarget) and target.should_install():
elif isinstance(target, GirTarget) and target.should_install():
files_devel.add('%%{_datadir}/gir-1.0/%s' % target.get_filename()[0])
elif isinstance(target, gnome.TypelibTarget) and target.should_install():
elif isinstance(target, TypelibTarget) and target.should_install():
files.add('%%{_libdir}/girepository-1.0/%s' % target.get_filename()[0])
for header in state.headers:
if len(header.get_install_subdir()) > 0:

@ -0,0 +1,3 @@
res = gnome.compile_resources('testui',
'test-resources.xml',
source_dir : '.')

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/Meson">
<file compressed="true" preprocess="xml-stripblanks">test.ui</file>
</gresource>
</gresources>

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.8 -->
<template class="TestWidget" parent="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">4</property>
<child>
<object class="GtkEntry" id="entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
</template>
</interface>

@ -0,0 +1,12 @@
project('test glib target version and gresources', 'c', 'vala')
gnome = import('gnome')
glib = dependency('glib-2.0', version : '>=2.38')
gtk = dependency('gtk+-3.0')
subdir('gres')
e = executable('gtktemplate', 'test.vala', res, dependencies : [glib, gtk])
# No X on the CI, so disable this for now
#test('test-target-glib', e)

@ -0,0 +1,37 @@
using Gtk;
using GLib;
[GtkTemplate (ui = "/org/Meson/test.ui")]
public class TestWidget : Box {
public string text {
get { return entry.text; }
set { entry.text = value; }
}
[GtkChild]
private Entry entry;
public TestWidget (string text) {
this.text = text;
}
}
void main(string[] args) {
Gtk.init (ref args);
var win = new Window();
win.destroy.connect (Gtk.main_quit);
var widget = new TestWidget ("SOME TEXT HERE");
win.add (widget);
win.show_all ();
/* Exit immediately */
Timeout.add_full (Priority.DEFAULT_IDLE, 1, () =>
{
Gtk.main_quit();
return false;
});
Gtk.main ();
}

@ -0,0 +1,13 @@
project('static vapi', 'c', 'vala')
glib = dependency('glib-2.0')
conf = configuration_data()
conf.set_quoted('VERSION', '1.0.0')
config_h = configure_file(output : 'config.h',
configuration : conf)
e = executable('static-vapi', 'vapi/config.vapi', 'test.vala',
dependencies : glib)
test('test-config', e)

@ -0,0 +1,6 @@
using GLib;
using Config;
public int main (string[] args) {
return GLib.strcmp(VERSION, "1.0.0");
}

@ -0,0 +1,4 @@
[CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "config.h")]
namespace Config {
public const string VERSION;
}

@ -0,0 +1,43 @@
/*** BEGIN file-header ***/
#include "enum-types.h"
/*** END file-header ***/
/*** BEGIN file-production ***/
/* enumerations from "@filename@" */
#include "@filename@"
/*** END file-production ***/
/*** BEGIN value-header ***/
GType
@enum_name@_get_type (void)
{
static volatile gsize g_define_type_id__volatile = 0;
if (g_once_init_enter (&g_define_type_id__volatile)) {
static const G@Type@Value values[] = {
/*** END value-header ***/
/*** BEGIN value-production ***/
{ @VALUENAME@, "@VALUENAME@", "@valuenick@" },
/*** END value-production ***/
/*** BEGIN value-tail ***/
{ 0, NULL, NULL }
};
GType g_define_type_id =
g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
}
return g_define_type_id__volatile;
}
/*** END value-tail ***/
/*** BEGIN file-tail ***/
/*** END file-tail ***/

@ -0,0 +1,26 @@
/*** BEGIN file-header ***/
#ifndef __EXAMPLE_ENUMS_TYPES_H__
#define __EXAMPLE_ENUMS_TYPES_H__
#include <glib-object.h>
#include "enums.h"
G_BEGIN_DECLS
/*** END file-header ***/
/*** BEGIN file-production ***/
/* enumerations from "@filename@" */
/*** END file-production ***/
/*** BEGIN value-header ***/
GType @enum_name@_get_type (void) G_GNUC_CONST;
#define EXAMPLE_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
/*** END value-header ***/
/*** BEGIN file-tail ***/
G_END_DECLS
#endif /* __EXAMPLE_ENUMS_TYPES_H__ */
/*** END file-tail ***/

@ -0,0 +1,15 @@
#ifndef __EXAMPLE_ENUMS_H__
#define __EXAMPLE_ENUMS_H__
G_BEGIN_DECLS
typedef enum {
EXAMPLE_VERBOSITY_ERRORS,
EXAMPLE_VERBOSITY_MINIMAL,
EXAMPLE_VERBOSITY_DETAILED,
EXAMPLE_VERBOSITY_DEBUG,
} ExampleVerbosity;
G_END_DECLS
#endif /* __EXAMPLE_ENUMS_H__ */

@ -0,0 +1,44 @@
# Test that dependencies with their own generated sources don't
# confuse the Vala build instruction generator.
# Test case for https://github.com/mesonbuild/meson/issues/1084
gnome = import('gnome')
gobject = dependency('gobject-2.0')
enums = gnome.mkenums('enum-types',
sources: 'enums.h',
c_template: 'enum-types.c.template',
h_template: 'enum-types.h.template',
)
libcommon = library('common',
enums[0], enums[1],
dependencies: gobject)
common_dep = declare_dependency(
# This is required so that whoever depends on this also depends
# on the generated header; that won't happen implicitly.
# See: https://github.com/mesonbuild/meson/issues/1084
sources: enums[1],
link_with: libcommon,
)
libplover_vala = library('plover',
'lib.vala',
dependencies: [common_dep, gobject]
)
plover_dep = declare_dependency(
link_with: libplover_vala,
dependencies: common_dep
)
vala_prog = executable('hello',
'main.vala',
link_with: libplover_vala,
# There's no need to specify common_dep here since plover_dep pulls it
# in, but it should be harmless to do so.
dependencies: [common_dep, plover_dep, gobject]
)

@ -6,3 +6,4 @@ cd.set('x', 'y')
subdir('src')
subdir('tools')
subdir('onlygen')
subdir('dependency-generated')

Loading…
Cancel
Save