diff options
-rw-r--r-- | mesonbuild/backend/backends.py | 13 | ||||
-rw-r--r-- | mesonbuild/compilers.py | 11 | ||||
-rw-r--r-- | mesonbuild/environment.py | 11 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 26 | ||||
-rwxr-xr-x | mesonbuild/scripts/gtkdochelper.py | 9 | ||||
-rw-r--r-- | test cases/common/121 interpreter copy mutable var on assignment/meson.build | 20 | ||||
-rw-r--r-- | test cases/common/37 has header/meson.build | 20 | ||||
-rw-r--r-- | test cases/common/48 test args/env2vars.c | 23 | ||||
-rw-r--r-- | test cases/common/48 test args/meson.build | 7 | ||||
-rw-r--r-- | test cases/frameworks/7 gnome/gir/meson.build | 2 | ||||
-rw-r--r-- | test cases/frameworks/7 gnome/installed_files.txt | 2 | ||||
-rw-r--r-- | test cases/vala/6 static library/installed_files.txt | 1 | ||||
-rw-r--r-- | test cases/vala/6 static library/meson.build | 6 |
13 files changed, 127 insertions, 24 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 2861bb6..45d946f 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -271,6 +271,9 @@ class Backend(): def object_filename_from_source(self, target, source): if isinstance(source, mesonlib.File): source = source.fname + # foo.vala files compile down to foo.c and then foo.c.o, not foo.vala.o + if source.endswith('.vala'): + source = os.path.join(self.get_target_private_dir(target), source[:-5] + '.c') return source.replace('/', '_').replace('\\', '_') + '.' + self.environment.get_object_suffix() def determine_ext_objs(self, extobj, proj_dir_to_build_root): @@ -598,11 +601,17 @@ class Backend(): i = i.replace('@OUTDIR@', outdir) elif '@DEPFILE@' in i: if target.depfile is None: - raise MesonException('Custom target %s has @DEPFILE@ but no depfile keyword argument.' % target.name) + msg = 'Custom target {!r} has @DEPFILE@ but no depfile ' \ + 'keyword argument.'.format(target.name) + raise MesonException(msg) dfilename = os.path.join(outdir, target.depfile) i = i.replace('@DEPFILE@', dfilename) elif '@PRIVATE_OUTDIR_' in i: - match = re.search('@PRIVATE_OUTDIR_(ABS_)?([-a-zA-Z0-9.@:]*)@', i) + match = re.search('@PRIVATE_OUTDIR_(ABS_)?([^\/\s*]*)@', i) + if not match: + msg = 'Custom target {!r} has an invalid argument {!r}' \ + ''.format(target.name, i) + raise MesonException(msg) source = match.group(0) if match.group(1) is None and not absolute_paths: lead_dir = '' diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py index bbe6a72..9b76f29 100644 --- a/mesonbuild/compilers.py +++ b/mesonbuild/compilers.py @@ -638,13 +638,11 @@ class CCompiler(Compiler): code = 'int main(int argc, char **argv) { int class=0; return class; }\n' return self.sanity_check_impl(work_dir, environment, 'sanitycheckc.c', code) - def has_header(self, hname, env, extra_args=None, dependencies=None): + def has_header(self, hname, prefix, env, extra_args=None, dependencies=None): if extra_args is None: extra_args = [] - templ = '''#include<%s> -int someSymbolHereJustForFun; -''' - return self.compiles(templ % hname, env, extra_args, dependencies) + code = '{}\n#include<{}>\nint someUselessSymbol;'.format(prefix, hname) + return self.compiles(code, env, extra_args, dependencies) def has_header_symbol(self, hname, symbol, prefix, env, extra_args=None, dependencies=None): if extra_args is None: @@ -1854,6 +1852,9 @@ class VisualStudioCCompiler(CCompiler): result.append(i) return result + def get_werror_args(self): + return ['/WX'] + def get_include_args(self, path, is_system): if path == '': path = '.' diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index f7045f4..405685c 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -331,6 +331,13 @@ class Environment(): if len(rest) == 2: defines[rest[0]] = rest[1] return defines + @staticmethod + def get_gnu_version_from_defines(defines): + dot = '.' + major = defines.get('__GNUC__', '0') + minor = defines.get('__GNUC_MINOR__', '0') + patch = defines.get('__GNUC_PATCHLEVEL__', '0') + return dot.join((major, minor, patch)) @staticmethod def get_gnu_compiler_type(defines): @@ -385,6 +392,7 @@ class Environment(): popen_exceptions[compiler] = 'no pre-processor defines' continue gtype = self.get_gnu_compiler_type(defines) + version = self.get_gnu_version_from_defines(defines) return GnuCCompiler(ccache + [compiler], version, gtype, is_cross, exe_wrap, defines) if 'clang' in out: if 'Apple' in out: @@ -443,6 +451,7 @@ class Environment(): popen_exceptions[compiler] = 'no pre-processor defines' continue gtype = self.get_gnu_compiler_type(defines) + version = self.get_gnu_version_from_defines(defines) return GnuFortranCompiler([compiler], version, gtype, is_cross, exe_wrap, defines) if 'G95' in out: @@ -524,6 +533,7 @@ class Environment(): popen_exceptions[compiler] = 'no pre-processor defines' continue gtype = self.get_gnu_compiler_type(defines) + version = self.get_gnu_version_from_defines(defines) return GnuCPPCompiler(ccache + [compiler], version, gtype, is_cross, exe_wrap, defines) if 'clang' in out: if 'Apple' in out: @@ -563,6 +573,7 @@ class Environment(): version = search_version(out) if 'Free Software Foundation' in out: defines = self.get_gnu_compiler_defines(exelist) + version = self.get_gnu_version_from_defines(defines) return GnuObjCCompiler(exelist, version, is_cross, exe_wrap, defines) if out.startswith('Apple LLVM'): return ClangObjCCompiler(exelist, version, CLANG_OSX, is_cross, exe_wrap) diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index 0030660..33587a4 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -92,6 +92,10 @@ class InterpreterObject(): return self.methods[method_name](args, kwargs) raise InvalidCode('Unknown method "%s" in object.' % method_name) +class MutableInterpreterObject(InterpreterObject): + def __init__(self): + super().__init__() + class TryRunResultHolder(InterpreterObject): def __init__(self, res): super().__init__() @@ -182,14 +186,13 @@ class ConfigureFileHolder(InterpreterObject): self.held_object = build.ConfigureFile(subdir, sourcename, targetname, configuration_data) -class EnvironmentVariablesHolder(InterpreterObject): +class EnvironmentVariablesHolder(MutableInterpreterObject): def __init__(self): super().__init__() self.held_object = build.EnvironmentVariables() self.methods.update({'set': self.set_method, 'append': self.append_method, 'prepend' : self.prepend_method, - 'copy' : self.copy_method, }) @stringArgs @@ -212,11 +215,8 @@ class EnvironmentVariablesHolder(InterpreterObject): def prepend_method(self, args, kwargs): self.add_var(self.held_object.prepend, args, kwargs) - def copy_method(self, args, kwargs): - return copy.deepcopy(self) - -class ConfigurationDataHolder(InterpreterObject): +class ConfigurationDataHolder(MutableInterpreterObject): def __init__(self): super().__init__() self.used = False # These objects become immutable after use in configure_file. @@ -896,15 +896,18 @@ class CompilerHolder(InterpreterObject): if len(args) != 1: raise InterpreterException('has_header method takes exactly one argument.') check_stringlist(args) - string = args[0] + hname = args[0] + prefix = kwargs.get('prefix', '') + if not isinstance(prefix, str): + raise InterpreterException('Prefix argument of has_header must be a string.') extra_args = self.determine_args(kwargs) deps = self.determine_dependencies(kwargs, allowed_dep_types=(dependencies.Dependency,)) - haz = self.compiler.has_header(string, self.environment, extra_args, deps) + haz = self.compiler.has_header(hname, prefix, self.environment, extra_args, deps) if haz: h = mlog.green('YES') else: h = mlog.red('NO') - mlog.log('Has header "%s":' % string, h) + mlog.log('Has header "%s":' % hname, h) return haz def has_header_symbol_method(self, args, kwargs): @@ -915,7 +918,7 @@ class CompilerHolder(InterpreterObject): symbol = args[1] prefix = kwargs.get('prefix', '') if not isinstance(prefix, str): - raise InterpreterException('Prefix argument of has_function must be a string.') + raise InterpreterException('Prefix argument of has_header_symbol must be a string.') extra_args = self.determine_args(kwargs) deps = self.determine_dependencies(kwargs, allowed_dep_types=(dependencies.Dependency,)) haz = self.compiler.has_header_symbol(hname, symbol, prefix, self.environment, extra_args, deps) @@ -2461,6 +2464,9 @@ requirements use the version keyword argument instead.''') value = self.to_native(value) if not self.is_assignable(value): raise InvalidCode('Tried to assign an invalid value to variable.') + # For mutable objects we need to make a copy on assignment + if isinstance(value, MutableInterpreterObject): + value = copy.deepcopy(value) self.set_variable(var_name, value) return value diff --git a/mesonbuild/scripts/gtkdochelper.py b/mesonbuild/scripts/gtkdochelper.py index 220801d..e34b541 100755 --- a/mesonbuild/scripts/gtkdochelper.py +++ b/mesonbuild/scripts/gtkdochelper.py @@ -90,10 +90,11 @@ def build_gtkdoc(source_root, build_root, doc_subdir, src_subdir, f_abs = os.path.join(doc_src, f) shutil.copyfile(f_abs, os.path.join(htmldir, os.path.basename(f_abs))) - scan_cmd = ['gtkdoc-scan', - '--module=' + module, - '--source-dir=' + abs_src, - '--ignore-headers=' + ignore_headers] + scan_args + scan_cmd = ['gtkdoc-scan', '--module=' + module, '--source-dir=' + abs_src] + if ignore_headers: + scan_cmd.append('--ignore-headers=' + ' '.join(ignore_headers)) + # Add user-specified arguments + scan_cmd += scan_args gtkdoc_run_check(scan_cmd, abs_out) if gobject_typesfile: diff --git a/test cases/common/121 interpreter copy mutable var on assignment/meson.build b/test cases/common/121 interpreter copy mutable var on assignment/meson.build new file mode 100644 index 0000000..8b15357 --- /dev/null +++ b/test cases/common/121 interpreter copy mutable var on assignment/meson.build @@ -0,0 +1,20 @@ +project('foo', 'c') + +a = configuration_data() +a.set('HELLO', 1) + +b = a + +assert(a.has('HELLO'), 'Original config data should be set on a') +assert(b.has('HELLO'), 'Original config data should be set on copy') + +configure_file(output : 'b.h', configuration : b) + +# This should still work, as we didn't use the original above but a copy! +a.set('WORLD', 1) + +assert(a.has('WORLD'), 'New config data should have been set') +assert(not b.has('WORLD'), 'New config data set should not affect var copied earlier') + +configure_file(output : 'a.h', configuration : a) + diff --git a/test cases/common/37 has header/meson.build b/test cases/common/37 has header/meson.build index ce6e71a..4f9b94f 100644 --- a/test cases/common/37 has header/meson.build +++ b/test cases/common/37 has header/meson.build @@ -1,10 +1,28 @@ project('has header', 'c', 'cpp') foreach comp : [meson.get_compiler('c'), meson.get_compiler('cpp')] - if comp.has_header('stdio.h') == false + if not comp.has_header('stdio.h') error('Stdio missing.') endif + # stdio.h doesn't actually need stdlib.h, but I don't know any headers on + # UNIX/Linux that need other headers defined beforehand + if not comp.has_header('stdio.h', prefix : '#include <stdlib.h>') + error('Stdio missing.') + endif + + # XInput.h needs windows.h included beforehand. We only do this check on MSVC + # because MinGW often defines its own wrappers that pre-include windows.h + if comp.get_id() == 'msvc' + if not comp.has_header('XInput.h', prefix : '#include <windows.h>') + error('XInput.h is missing on Windows') + endif + if comp.has_header('XInput.h') + error('XInput.h needs windows.h') + endif + endif + + if comp.has_header('ouagadougou.h') error('Found non-existant header.') endif diff --git a/test cases/common/48 test args/env2vars.c b/test cases/common/48 test args/env2vars.c new file mode 100644 index 0000000..19250a8 --- /dev/null +++ b/test cases/common/48 test args/env2vars.c @@ -0,0 +1,23 @@ +#include<stdio.h> +#include<string.h> +#include<stdlib.h> + +int main(int argc, char **argv) { + if(strcmp(getenv("first"), "something-else") != 0) { + fprintf(stderr, "First envvar is wrong. %s\n", getenv("first")); + return 1; + } + if(strcmp(getenv("second"), "val2") != 0) { + fprintf(stderr, "Second envvar is wrong.\n"); + return 1; + } + if(strcmp(getenv("third"), "val3:and_more") != 0) { + fprintf(stderr, "Third envvar is wrong.\n"); + return 1; + } + if(strstr(getenv("PATH"), "fakepath:") != NULL) { + fprintf(stderr, "Third envvar is wrong.\n"); + return 1; + } + return 0; +} diff --git a/test cases/common/48 test args/meson.build b/test cases/common/48 test args/meson.build index 6400198..f599bf7 100644 --- a/test cases/common/48 test args/meson.build +++ b/test cases/common/48 test args/meson.build @@ -2,6 +2,7 @@ project('test features', 'c') e1 = executable('cmd_args', 'cmd_args.c') e2 = executable('envvars', 'envvars.c') +e3 = executable('env2vars', 'env2vars.c') env = environment() env.set('first', 'val1') @@ -9,6 +10,12 @@ env.set('second', 'val2') env.set('third', 'val3', 'and_more', separator: ':') env.append('PATH', 'fakepath', separator: ':') +# Make sure environment objects are copied on assignment and we can +# change the copy without affecting the original environment object. +env2 = env +env2.set('first', 'something-else') + test('command line arguments', e1, args : ['first', 'second']) test('environment variables', e2, env : env) +test('environment variables 2', e3, env : env2) test('file arg', find_program('tester.py'), args : files('testfile.txt')) diff --git a/test cases/frameworks/7 gnome/gir/meson.build b/test cases/frameworks/7 gnome/gir/meson.build index a513062..51bbbab 100644 --- a/test cases/frameworks/7 gnome/gir/meson.build +++ b/test cases/frameworks/7 gnome/gir/meson.build @@ -1,7 +1,7 @@ libsources = ['meson-sample.c', 'meson-sample.h'] girlib = shared_library( - 'girlib', + 'gir_lib', sources : libsources, dependencies : gobj, install : true diff --git a/test cases/frameworks/7 gnome/installed_files.txt b/test cases/frameworks/7 gnome/installed_files.txt index c922f8b..a18e445 100644 --- a/test cases/frameworks/7 gnome/installed_files.txt +++ b/test cases/frameworks/7 gnome/installed_files.txt @@ -3,6 +3,6 @@ usr/include/enums2.h usr/include/enums3.h usr/include/marshaller.h usr/lib/girepository-1.0/Meson-1.0.typelib -usr/lib/libgirlib.so +usr/lib/libgir_lib.so usr/share/gir-1.0/Meson-1.0.gir usr/share/glib-2.0/schemas/com.github.meson.gschema.xml diff --git a/test cases/vala/6 static library/installed_files.txt b/test cases/vala/6 static library/installed_files.txt new file mode 100644 index 0000000..f464bc0 --- /dev/null +++ b/test cases/vala/6 static library/installed_files.txt @@ -0,0 +1 @@ +usr/lib/libextractedlib.a diff --git a/test cases/vala/6 static library/meson.build b/test cases/vala/6 static library/meson.build index ae8eeb9..c74bdf8 100644 --- a/test cases/vala/6 static library/meson.build +++ b/test cases/vala/6 static library/meson.build @@ -3,6 +3,12 @@ project('valastatic', 'vala', 'c') valadeps = [dependency('glib-2.0'), dependency('gobject-2.0')] l = static_library('valalib', 'mylib.vala', dependencies : valadeps) +# NOTE: This static library is not usable from Vala because it does not carry +# forward the .vapi and .h files generated by Valac to the next BuildTarget. +# Will have to be fixed with https://github.com/mesonbuild/meson/issues/891 +m = static_library('extractedlib', + objects : l.extract_all_objects(), + install : true) e = executable('valaprog', 'prog.vala', link_with : l, |