diff options
-rw-r--r-- | mesonbuild/backend/vs2010backend.py | 11 | ||||
-rw-r--r-- | mesonbuild/compilers.py | 91 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 30 | ||||
-rw-r--r-- | mesonbuild/modules/gnome.py | 18 | ||||
-rw-r--r-- | mesonbuild/mparser.py | 9 | ||||
-rw-r--r-- | test cases/common/117 custom target capture/meson.build | 4 | ||||
-rw-r--r-- | test cases/common/139 compute int/config.h.in | 2 | ||||
-rw-r--r-- | test cases/common/139 compute int/foobar.h | 6 | ||||
-rw-r--r-- | test cases/common/139 compute int/meson.build | 35 | ||||
-rw-r--r-- | test cases/common/139 compute int/prog.c.in | 16 | ||||
-rw-r--r-- | test cases/common/40 logic ops/meson.build | 6 | ||||
-rw-r--r-- | test cases/windows/8 msvc dll versioning/copyfile.py | 6 | ||||
-rw-r--r-- | test cases/windows/8 msvc dll versioning/meson.build | 3 |
13 files changed, 196 insertions, 41 deletions
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index a3af95f..07306aa 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -429,7 +429,16 @@ class Vs2010Backend(backends.Backend): # from the target dir, not the build root. target.absolute_paths = True (srcs, ofilenames, cmd) = self.eval_custom_target_command(target, True) - ET.SubElement(customstep, 'Command').text = ' '.join(self.quote_arguments(cmd)) + # Always use a wrapper because MSBuild eats random characters when + # there are many arguments. + tdir_abs = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target)) + exe_data = self.serialise_executable(target.command[0], cmd[1:], + # All targets run from the target dir + tdir_abs, + capture=ofilenames[0] if target.capture else None) + wrapper_cmd = [sys.executable, self.environment.get_build_command(), + '--internal', 'exe', exe_data] + ET.SubElement(customstep, 'Command').text = ' '.join(self.quote_arguments(wrapper_cmd)) ET.SubElement(customstep, 'Outputs').text = ';'.join(ofilenames) ET.SubElement(customstep, 'Inputs').text = ';'.join(srcs) ET.SubElement(root, 'Import', Project='$(VCTargetsPath)\Microsoft.Cpp.targets') diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py index f8c3f6b..519a7d5 100644 --- a/mesonbuild/compilers.py +++ b/mesonbuild/compilers.py @@ -1001,44 +1001,75 @@ class CCompiler(Compiler): mlog.debug(se) return RunResult(True, pe.returncode, so, se) - def _bisect_compiles(self, t, fargs, env, extra_args, dependencies): - # FIXME: Does not actually do bisection right now - for i in range(1, 1024): - fargs['size'] = i - if self.compiles(t.format(**fargs), env, extra_args, dependencies): - if self.id == 'msvc': - # MSVC refuses to construct an array of zero size, so - # the test only succeeds when i is sizeof(element) + 1 - return i - 1 - return i + def _compile_int(self, expression, prefix, env, extra_args, dependencies): + fargs = {'prefix': prefix, 'expression': expression} + t = '''#include <stdio.h> + {prefix} + int main() {{ static int a[1-2*!({expression})]; a[0]=0; return 0; }}''' + return self.compiles(t.format(**fargs), env, extra_args, dependencies) + + def cross_compute_int(self, expression, l, h, guess, prefix, env, extra_args, dependencies): + if isinstance(guess, int): + if self._compile_int('%s == %d' % (expression, guess), prefix, env, extra_args, dependencies): + return guess + + cur = l + while l < h: + cur = int((l + h) / 2) + if cur == l: + break + + if self._compile_int('%s >= %d' % (expression, cur), prefix, env, extra_args, dependencies): + l = cur + else: + h = cur + + if self._compile_int('%s == %d' % (expression, cur), prefix, env, extra_args, dependencies): + return cur raise EnvironmentException('Cross-compile check overflowed') - def cross_sizeof(self, element, prefix, env, extra_args=None, dependencies=None): + def compute_int(self, expression, l, h, guess, prefix, env, extra_args=None, dependencies=None): + if extra_args is None: + extra_args = [] + if self.is_cross: + return self.cross_compute_int(expression, l, h, guess, prefix, env, extra_args, dependencies) + fargs = {'prefix': prefix, 'expression': expression} + t = '''#include<stdio.h> + {prefix} + int main(int argc, char **argv) {{ + printf("%ld\\n", (long)({expression})); + return 0; + }};''' + res = self.run(t.format(**fargs), env, extra_args, dependencies) + if not res.compiled: + return -1 + if res.returncode != 0: + raise EnvironmentException('Could not run compute_int test binary.') + return int(res.stdout) + + def cross_sizeof(self, typename, prefix, env, extra_args=None, dependencies=None): if extra_args is None: extra_args = [] - fargs = {'prefix': prefix, 'name': element} + fargs = {'prefix': prefix, 'type': typename} t = '''#include <stdio.h> {prefix} int main(int argc, char **argv) {{ - {name} something; + {type} something; }}''' if not self.compiles(t.format(**fargs), env, extra_args, dependencies): return -1 - t = '''#include <stdio.h> - {prefix} - int temparray[{size}-sizeof({name})];''' - return self._bisect_compiles(t, fargs, env, extra_args, dependencies) + return self.cross_compute_int('sizeof(%s)' % typename, 1, 128, None, prefix, env, extra_args, dependencies) - def sizeof(self, element, prefix, env, extra_args=None, dependencies=None): + def sizeof(self, typename, prefix, env, extra_args=None, dependencies=None): if extra_args is None: extra_args = [] - fargs = {'prefix': prefix, 'name': element} + fargs = {'prefix': prefix, 'type': typename} if self.is_cross: - return self.cross_sizeof(element, prefix, env, extra_args, dependencies) + return self.cross_sizeof(typename, prefix, env, extra_args, dependencies) t = '''#include<stdio.h> {prefix} int main(int argc, char **argv) {{ - printf("%ld\\n", (long)(sizeof({name}))); + printf("%ld\\n", (long)(sizeof({type}))); return 0; }};''' res = self.run(t.format(**fargs), env, extra_args, dependencies) @@ -1048,32 +1079,34 @@ class CCompiler(Compiler): raise EnvironmentException('Could not run sizeof test binary.') return int(res.stdout) - def cross_alignment(self, typename, env, extra_args=None, dependencies=None): + def cross_alignment(self, typename, prefix, env, extra_args=None, dependencies=None): if extra_args is None: extra_args = [] - fargs = {'type': typename} + fargs = {'prefix': prefix, 'type': typename} t = '''#include <stdio.h> + {prefix} int main(int argc, char **argv) {{ {type} something; }}''' if not self.compiles(t.format(**fargs), env, extra_args, dependencies): return -1 t = '''#include <stddef.h> + {prefix} struct tmp {{ char c; {type} target; - }}; - int testarray[{size}-offsetof(struct tmp, target)];''' - return self._bisect_compiles(t, fargs, env, extra_args, dependencies) + }};''' + return self.cross_compute_int('offsetof(struct tmp, target)', 1, 1024, None, t.format(**fargs), env, extra_args, dependencies) - def alignment(self, typename, env, extra_args=None, dependencies=None): + def alignment(self, typename, prefix, env, extra_args=None, dependencies=None): if extra_args is None: extra_args = [] if self.is_cross: - return self.cross_alignment(typename, env, extra_args, dependencies) - fargs = {'type': typename} + return self.cross_alignment(typename, prefix, env, extra_args, dependencies) + fargs = {'prefix': prefix, 'type': typename} t = '''#include <stdio.h> #include <stddef.h> + {prefix} struct tmp {{ char c; {type} target; diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index c16b668..79a531d 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -632,6 +632,7 @@ class CompilerHolder(InterpreterObject): self.methods.update({'compiles': self.compiles_method, 'links': self.links_method, 'get_id': self.get_id_method, + 'compute_int': self.compute_int_method, 'sizeof': self.sizeof_method, 'has_header': self.has_header_method, 'has_header_symbol': self.has_header_symbol_method, @@ -700,8 +701,12 @@ class CompilerHolder(InterpreterObject): raise InterpreterException('Alignment method takes exactly one positional argument.') check_stringlist(args) typename = args[0] + prefix = kwargs.get('prefix', '') + if not isinstance(prefix, str): + raise InterpreterException('Prefix argument of sizeof must be a string.') extra_args = mesonlib.stringlistify(kwargs.get('args', [])) - result = self.compiler.alignment(typename, self.environment, extra_args) + deps = self.determine_dependencies(kwargs) + result = self.compiler.alignment(typename, prefix, self.environment, extra_args, deps) mlog.log('Checking for alignment of "', mlog.bold(typename), '": ', result, sep='') return result @@ -823,6 +828,29 @@ class CompilerHolder(InterpreterObject): mlog.log('Checking for type "', mlog.bold(typename), '": ', hadtxt, sep='') return had + def compute_int_method(self, args, kwargs): + if len(args) != 1: + raise InterpreterException('Compute_int takes exactly one argument.') + check_stringlist(args) + expression = args[0] + prefix = kwargs.get('prefix', '') + l = kwargs.get('low', -1024) + h = kwargs.get('high', 1024) + guess = kwargs.get('guess', None) + if not isinstance(prefix, str): + raise InterpreterException('Prefix argument of compute_int must be a string.') + if not isinstance(l, int): + raise InterpreterException('Low argument of compute_int must be an int.') + if not isinstance(h, int): + raise InterpreterException('High argument of compute_int must be an int.') + if guess is not None and not isinstance(guess, int): + raise InterpreterException('Guess argument of compute_int must be an int.') + extra_args = self.determine_args(kwargs) + deps = self.determine_dependencies(kwargs) + res = self.compiler.compute_int(expression, l, h, guess, prefix, self.environment, extra_args, deps) + mlog.log('Computing int of "%s": %d' % (expression, res)) + return res + def sizeof_method(self, args, kwargs): if len(args) != 1: raise InterpreterException('Sizeof takes exactly one argument.') diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index 49270a0..423031d 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -41,6 +41,7 @@ gresource_dep_needed_version = '>= 2.51.1' native_glib_version = None girwarning_printed = False +gdbuswarning_printed = False gresource_warning_printed = False _gir_has_extra_lib_arg = None @@ -80,6 +81,15 @@ class GnomeModule(ExtensionModule): gresource_warning_printed = True return [] + @staticmethod + def _print_gdbus_warning(): + global gdbuswarning_printed + if not gdbuswarning_printed: + mlog.warning('Code generated with gdbus_codegen() requires the root directory be added to\n' + ' include_directories of targets with GLib < 2.51.3:', + mlog.bold('https://github.com/mesonbuild/meson/issues/1387')) + gdbuswarning_printed = True + def compile_resources(self, state, args, kwargs): self.__print_gresources_warning(state) glib_version = self._get_native_glib_version(state) @@ -758,7 +768,13 @@ class GnomeModule(ExtensionModule): cmd += ['--interface-prefix', kwargs.pop('interface_prefix')] if 'namespace' in kwargs: cmd += ['--c-namespace', kwargs.pop('namespace')] - cmd += ['--generate-c-code', '@OUTDIR@/' + namebase, '@INPUT@'] + + # https://git.gnome.org/browse/glib/commit/?id=ee09bb704fe9ccb24d92dd86696a0e6bb8f0dc1a + if mesonlib.version_compare(self._get_native_glib_version(state), '>= 2.51.3'): + cmd += ['--output-directory', '@OUTDIR@', '--generate-c-code', namebase, '@INPUT@'] + else: + self._print_gdbus_warning() + cmd += ['--generate-c-code', '@OUTDIR@/' + namebase, '@INPUT@'] outputs = [namebase + '.c', namebase + '.h'] custom_kwargs = {'input': xml_file, 'output': outputs, diff --git a/mesonbuild/mparser.py b/mesonbuild/mparser.py index 6e1e398..fe5ccc5 100644 --- a/mesonbuild/mparser.py +++ b/mesonbuild/mparser.py @@ -193,9 +193,10 @@ class OrNode: self.right = right class AndNode: - def __init__(self, lineno, colno, left, right): - self.lineno = lineno - self.colno = colno + def __init__(self, left, right): + self.subdir = left.subdir + self.lineno = left.lineno + self.colno = left.colno self.left = left self.right = right @@ -436,7 +437,7 @@ class Parser: def e3(self): left = self.e4() while self.accept('and'): - left = AndNode(left.lineno, left.colno, left, self.e4()) + left = AndNode(left, self.e4()) return left def e4(self): diff --git a/test cases/common/117 custom target capture/meson.build b/test cases/common/117 custom target capture/meson.build index 16b6ac9..58a69ca 100644 --- a/test cases/common/117 custom target capture/meson.build +++ b/test cases/common/117 custom target capture/meson.build @@ -2,10 +2,6 @@ project('custom target', 'c') python3 = import('python3').find_python() -if meson.backend().startswith('vs') - error('MESON_SKIP_TEST: capturing of custom target output is broken with the VS backends') -endif - # Note that this will not add a dependency to the compiler executable. # Code will not be rebuilt if it changes. comp = '@0@/@1@'.format(meson.current_source_dir(), 'my_compiler.py') diff --git a/test cases/common/139 compute int/config.h.in b/test cases/common/139 compute int/config.h.in new file mode 100644 index 0000000..ad8d077 --- /dev/null +++ b/test cases/common/139 compute int/config.h.in @@ -0,0 +1,2 @@ +#define INTSIZE @INTSIZE@ +#define FOOBAR_IN_CONFIG_H @FOOBAR@ diff --git a/test cases/common/139 compute int/foobar.h b/test cases/common/139 compute int/foobar.h new file mode 100644 index 0000000..fd3cb5e --- /dev/null +++ b/test cases/common/139 compute int/foobar.h @@ -0,0 +1,6 @@ +#ifndef __FOOBAR_H__ +#define __FOOBAR_H__ + +#define FOOBAR_IN_FOOBAR_H 10 + +#endif /*__FOOBAR_H__*/ diff --git a/test cases/common/139 compute int/meson.build b/test cases/common/139 compute int/meson.build new file mode 100644 index 0000000..43553fe --- /dev/null +++ b/test cases/common/139 compute int/meson.build @@ -0,0 +1,35 @@ +project('compute int', 'c', 'cpp') + +inc = include_directories('.') + +# Test with C +cc = meson.get_compiler('c') + +intsize = cc.compute_int('sizeof(int)', low : 1, high : 16, guess : 4) +foobar = cc.compute_int('FOOBAR_IN_FOOBAR_H', prefix : '#include "foobar.h"', include_directories : inc) + +cd = configuration_data() +cd.set('INTSIZE', intsize) +cd.set('FOOBAR', foobar) +cd.set('CONFIG', 'config.h') +configure_file(input : 'config.h.in', output : 'config.h', configuration : cd) +s = configure_file(input : 'prog.c.in', output : 'prog.c', configuration : cd) + +e = executable('prog', s) +test('compute int test', e) + +# Test with C++ +cpp = meson.get_compiler('cpp') + +intsize = cpp.compute_int('sizeof(int)') +foobar = cpp.compute_int('FOOBAR_IN_FOOBAR_H', prefix : '#include "foobar.h"', include_directories : inc) + +cdpp = configuration_data() +cdpp.set('INTSIZE', intsize) +cdpp.set('FOOBAR', foobar) +cdpp.set('CONFIG', 'config.hpp') +configure_file(input : 'config.h.in', output : 'config.hpp', configuration : cdpp) +spp = configure_file(input : 'prog.c.in', output : 'prog.cc', configuration : cdpp) + +epp = executable('progpp', spp) +test('compute int test c++', epp) diff --git a/test cases/common/139 compute int/prog.c.in b/test cases/common/139 compute int/prog.c.in new file mode 100644 index 0000000..3ff1463 --- /dev/null +++ b/test cases/common/139 compute int/prog.c.in @@ -0,0 +1,16 @@ +#include "@CONFIG@" +#include <stdio.h> +#include <wchar.h> +#include "foobar.h" + +int main(int argc, char **argv) { + if(INTSIZE != sizeof(int)) { + fprintf(stderr, "Mismatch: computed int size %d, actual size %d.\n", INTSIZE, (int)sizeof(int)); + return 1; + } + if(FOOBAR_IN_CONFIG_H != FOOBAR_IN_FOOBAR_H) { + fprintf(stderr, "Mismatch: computed int %d, should be %d.\n", FOOBAR_IN_CONFIG_H, FOOBAR_IN_FOOBAR_H); + return 1; + } + return 0; +} diff --git a/test cases/common/40 logic ops/meson.build b/test cases/common/40 logic ops/meson.build index e975c7e..897054e 100644 --- a/test cases/common/40 logic ops/meson.build +++ b/test cases/common/40 logic ops/meson.build @@ -87,3 +87,9 @@ if t and t and t and t and t and t and t and t and f else message('Ok.') endif + +if t and t or t + message('Ok.') +else + error('Combination of and-or failed.') +endif diff --git a/test cases/windows/8 msvc dll versioning/copyfile.py b/test cases/windows/8 msvc dll versioning/copyfile.py new file mode 100644 index 0000000..ff42ac3 --- /dev/null +++ b/test cases/windows/8 msvc dll versioning/copyfile.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 + +import sys +import shutil + +shutil.copyfile(sys.argv[1], sys.argv[2]) diff --git a/test cases/windows/8 msvc dll versioning/meson.build b/test cases/windows/8 msvc dll versioning/meson.build index 3f15e76..b72c5ec 100644 --- a/test cases/windows/8 msvc dll versioning/meson.build +++ b/test cases/windows/8 msvc dll versioning/meson.build @@ -28,11 +28,12 @@ onlysoversion = shared_library('onlysoversion', 'lib.c', # Hack to make the executables below depend on the shared libraries above # without actually adding them as `link_with` dependencies since we want to try # linking to them with -lfoo linker arguments. +cp = find_program('copyfile.py') out = custom_target('library-dependency-hack', input : 'exe.orig.c', output : 'exe.c', depends : [some, noversion, onlyversion, onlysoversion], - command : ['cp', '@INPUT@', '@OUTPUT@']) + command : [cp, '@INPUT@', '@OUTPUT@']) # Manually test if the linker can find the above libraries # i.e., whether they were generated with the right naming scheme |