aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/backend/backends.py2
-rw-r--r--mesonbuild/backend/ninjabackend.py5
-rw-r--r--mesonbuild/build.py2
-rw-r--r--mesonbuild/compilers.py100
-rw-r--r--mesonbuild/interpreter.py87
-rw-r--r--mesonbuild/mesonlib.py8
-rw-r--r--mesonbuild/modules/gnome.py3
-rw-r--r--mesonbuild/scripts/gettext.py6
-rwxr-xr-xtest cases/common/118 allgenerate/converter.py8
-rw-r--r--test cases/common/118 allgenerate/foobar.cpp.in6
-rw-r--r--test cases/common/118 allgenerate/meson.build20
-rw-r--r--test cases/common/16 configure file/meson.build4
-rw-r--r--test cases/common/94 default options/meson.build10
-rw-r--r--test cases/linuxlike/9 compiler checks with dependencies/meson.build31
14 files changed, 227 insertions, 65 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index c726668..4139ace 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -481,7 +481,7 @@ class Backend():
if self.environment.is_cross_build() and \
self.environment.cross_info.need_exe_wrapper() and \
isinstance(exe, build.BuildTarget) and exe.is_cross:
- if 'exe_wrapper' not in self.environment.cross_info.config:
+ if 'exe_wrapper' not in self.environment.cross_info.config['binaries']:
s = 'Can not use target %s as a generator because it is cross-built\n'
s += 'and no exe wrapper is defined. You might want to set it to native instead.'
s = s % exe.name
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index db9e1b0..251f7ee 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -264,10 +264,12 @@ int dummy;
unity_src = []
unity_deps = [] # Generated sources that must be built before compiling a Unity target.
header_deps += self.get_generated_headers(target)
+ generator_output_sources = [] # Needed to determine the linker
for gensource in target.get_generated_sources():
if isinstance(gensource, build.CustomTarget):
for src in gensource.output:
src = os.path.join(self.get_target_dir(gensource), src)
+ generator_output_sources.append(src)
if self.environment.is_source(src) and not self.environment.is_header(src):
if is_unity:
unity_deps.append(os.path.join(self.environment.get_build_dir(), RawFilename(src)))
@@ -285,6 +287,7 @@ int dummy;
header_deps.append(RawFilename(src))
else:
for src in gensource.get_outfilelist():
+ generator_output_sources.append(src)
if self.environment.is_object(src):
obj_list.append(os.path.join(self.get_target_private_dir(target), src))
elif not self.environment.is_header(src):
@@ -330,7 +333,7 @@ int dummy;
if is_unity:
for src in self.generate_unity_files(target, unity_src):
obj_list.append(self.generate_single_compile(target, outfile, src, True, unity_deps + header_deps))
- linker = self.determine_linker(target, src_list)
+ linker = self.determine_linker(target, src_list + generator_output_sources)
elem = self.generate_link(target, outfile, outname, obj_list, linker, pch_objects)
self.generate_shlib_aliases(target, self.get_target_dir(target))
elem.write(outfile)
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 7605b46..dce0236 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -1271,7 +1271,7 @@ class ConfigurationData():
return repr(self.values)
def get(self, name):
- return self.values[name]
+ return self.values[name] # (val, desc)
def keys(self):
return self.values.keys()
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py
index fb2a81a..c5b932c 100644
--- a/mesonbuild/compilers.py
+++ b/mesonbuild/compilers.py
@@ -173,6 +173,9 @@ base_options = {
'b_colorout' : coredata.UserComboOption('b_colorout', 'Use colored output',
['auto', 'always', 'never'],
'always'),
+ 'b_ndebug' : coredata.UserBooleanOption('b_ndebug',
+ 'Disable asserts',
+ False)
}
def sanitizer_compile_args(value):
@@ -218,6 +221,11 @@ def get_base_compile_args(options, compiler):
args += compiler.get_coverage_args()
except KeyError:
pass
+ try:
+ if options['b_ndebug'].value:
+ args += ['-DNDEBUG']
+ except KeyError:
+ pass
return args
def get_base_link_args(options, linker):
@@ -580,15 +588,15 @@ 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):
+ def has_header(self, hname, 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)
+ return self.compiles(templ % hname, env, extra_args, dependencies)
- def has_header_symbol(self, hname, symbol, prefix, env, extra_args=None):
+ def has_header_symbol(self, hname, symbol, prefix, env, extra_args=None, dependencies=None):
if extra_args is None:
extra_args = []
templ = '''{2}
@@ -596,7 +604,7 @@ int someSymbolHereJustForFun;
int main () {{ {1}; }}'''
# Pass -O0 to ensure that the symbol isn't optimized away
args = extra_args + self.get_no_optimization_args()
- return self.compiles(templ.format(hname, symbol, prefix), env, args)
+ return self.compiles(templ.format(hname, symbol, prefix), env, args, dependencies)
def compile(self, code, srcname, extra_args=None):
if extra_args is None:
@@ -616,18 +624,23 @@ int main () {{ {1}; }}'''
os.remove(srcname)
return p
- def compiles(self, code, env, extra_args=None):
+ def compiles(self, code, env, extra_args=None, dependencies=None):
if extra_args is None:
extra_args = []
if isinstance(extra_args, str):
extra_args = [extra_args]
+ if dependencies is None:
+ dependencies = []
+ elif not isinstance(dependencies, list):
+ dependencies = [dependencies]
suflen = len(self.default_suffix)
(fd, srcname) = tempfile.mkstemp(suffix='.'+self.default_suffix)
os.close(fd)
with open(srcname, 'w') as ofile:
ofile.write(code)
+ cargs = [a for d in dependencies for a in d.get_compile_args()]
# Convert flags to the native type of the selected compiler
- args = self.unix_link_flags_to_native(extra_args)
+ args = self.unix_link_flags_to_native(cargs + extra_args)
# Read c_args/cpp_args/etc from the cross-info file (if needed)
args += self.get_cross_extra_flags(env, compile=True, link=False)
# We only want to compile; not link
@@ -644,19 +657,25 @@ int main () {{ {1}; }}'''
pass
return p.returncode == 0
- def links(self, code, env, extra_args=None):
+ def links(self, code, env, extra_args=None, dependencies=None):
if extra_args is None:
extra_args = []
elif isinstance(extra_args, str):
extra_args = [extra_args]
+ if dependencies is None:
+ dependencies = []
+ elif not isinstance(dependencies, list):
+ dependencies = [dependencies]
(fd, srcname) = tempfile.mkstemp(suffix='.'+self.default_suffix)
os.close(fd)
(fd, dstname) = tempfile.mkstemp()
os.close(fd)
with open(srcname, 'w') as ofile:
ofile.write(code)
+ cargs = [a for d in dependencies for a in d.get_compile_args()]
+ link_args = [a for d in dependencies for a in d.get_link_args()]
# Convert flags to the native type of the selected compiler
- args = self.unix_link_flags_to_native(extra_args)
+ args = self.unix_link_flags_to_native(cargs + link_args + extra_args)
# Select a CRT if needed since we're linking
args += self.get_linker_debug_crt_args()
# Read c_args/c_link_args/cpp_args/cpp_link_args/etc from the cross-info file (if needed)
@@ -670,17 +689,23 @@ int main () {{ {1}; }}'''
pass
return p.returncode == 0
- def run(self, code, env, extra_args=None):
+ def run(self, code, env, extra_args=None, dependencies=None):
if extra_args is None:
extra_args = []
+ if dependencies is None:
+ dependencies = []
+ elif not isinstance(dependencies, list):
+ dependencies = [dependencies]
if self.is_cross and self.exe_wrapper is None:
raise CrossNoRunException('Can not run test applications in this cross environment.')
(fd, srcname) = tempfile.mkstemp(suffix='.'+self.default_suffix)
os.close(fd)
with open(srcname, 'w') as ofile:
ofile.write(code)
+ cargs = [a for d in dependencies for a in d.get_compile_args()]
+ link_args = [a for d in dependencies for a in d.get_link_args()]
# Convert flags to the native type of the selected compiler
- args = self.unix_link_flags_to_native(extra_args)
+ args = self.unix_link_flags_to_native(cargs + link_args + extra_args)
# Select a CRT if needed since we're linking
args += self.get_linker_debug_crt_args()
# Read c_link_args/cpp_link_args/etc from the cross-info file
@@ -729,7 +754,7 @@ int main () {{ {1}; }}'''
pass
return RunResult(True, pe.returncode, so, se)
- def cross_sizeof(self, element, prefix, env, extra_args=None):
+ def cross_sizeof(self, element, prefix, env, extra_args=None, dependencies=None):
if extra_args is None:
extra_args = []
element_exists_templ = '''#include <stdio.h>
@@ -743,11 +768,11 @@ int main(int argc, char **argv) {{
int temparray[%d-sizeof(%s)];
'''
args = extra_args + self.get_no_optimization_args()
- if not self.compiles(element_exists_templ.format(prefix, element), env, args):
+ if not self.compiles(element_exists_templ.format(prefix, element), env, args, dependencies):
return -1
for i in range(1, 1024):
code = templ % (prefix, i, element)
- if self.compiles(code, env, args):
+ if self.compiles(code, env, 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
@@ -755,11 +780,11 @@ int temparray[%d-sizeof(%s)];
return i
raise EnvironmentException('Cross checking sizeof overflowed.')
- def sizeof(self, element, prefix, env, extra_args=None):
+ def sizeof(self, element, prefix, env, extra_args=None, dependencies=None):
if extra_args is None:
extra_args = []
if self.is_cross:
- return self.cross_sizeof(element, prefix, env, extra_args)
+ return self.cross_sizeof(element, prefix, env, extra_args, dependencies)
templ = '''#include<stdio.h>
%s
@@ -768,14 +793,14 @@ int main(int argc, char **argv) {
return 0;
};
'''
- res = self.run(templ % (prefix, element), env, extra_args)
+ res = self.run(templ % (prefix, element), env, extra_args, dependencies)
if not res.compiled:
return -1
if res.returncode != 0:
raise EnvironmentException('Could not run sizeof test binary.')
return int(res.stdout)
- def cross_alignment(self, typename, env, extra_args=None):
+ def cross_alignment(self, typename, env, extra_args=None, dependencies=None):
if extra_args is None:
extra_args = []
type_exists_templ = '''#include <stdio.h>
@@ -792,11 +817,11 @@ struct tmp {
int testarray[%d-offsetof(struct tmp, target)];
'''
args = extra_args + self.get_no_optimization_args()
- if not self.compiles(type_exists_templ.format(typename), env, args):
+ if not self.compiles(type_exists_templ.format(typename), env, args, dependencies):
return -1
for i in range(1, 1024):
code = templ % (typename, i)
- if self.compiles(code, env, args):
+ if self.compiles(code, env, 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
@@ -804,11 +829,11 @@ int testarray[%d-offsetof(struct tmp, target)];
return i
raise EnvironmentException('Cross checking offsetof overflowed.')
- def alignment(self, typename, env, extra_args=None):
+ def alignment(self, typename, 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)
+ return self.cross_alignment(typename, env, extra_args, dependencies)
templ = '''#include<stdio.h>
#include<stddef.h>
@@ -822,7 +847,7 @@ int main(int argc, char **argv) {
return 0;
}
'''
- res = self.run(templ % typename, env, extra_args)
+ res = self.run(templ % typename, env, extra_args, dependencies)
if not res.compiled:
raise EnvironmentException('Could not compile alignment test.')
if res.returncode != 0:
@@ -832,7 +857,7 @@ int main(int argc, char **argv) {
raise EnvironmentException('Could not determine alignment of %s. Sorry. You might want to file a bug.' % typename)
return align
- def has_function(self, funcname, prefix, env, extra_args=None):
+ def has_function(self, funcname, prefix, env, extra_args=None, dependencies=None):
"""
First, this function looks for the symbol in the default libraries
provided by the compiler (stdlib + a few others usually). If that
@@ -889,7 +914,7 @@ int main(int argc, char **argv) {
if isinstance(val, bool):
return val
raise EnvironmentException('Cross variable {0} is not a boolean.'.format(varname))
- if self.links(templ.format(prefix, funcname), env, extra_args):
+ if self.links(templ.format(prefix, funcname), env, extra_args, dependencies):
return True
# Add -O0 to ensure that the symbol isn't optimized away by the compiler
args = extra_args + self.get_no_optimization_args()
@@ -898,15 +923,15 @@ int main(int argc, char **argv) {
# still detect the function. We still want to fail if __stub_foo or
# _stub_foo are defined, of course.
header_templ = '#include <limits.h>\n{0}\n' + stubs_fail + '\nint main() {{ {1}; }}'
- if self.links(header_templ.format(prefix, funcname), env, args):
+ if self.links(header_templ.format(prefix, funcname), env, args, dependencies):
return True
# Some functions like alloca() are defined as compiler built-ins which
# are inlined by the compiler, so test for that instead. Built-ins are
# special functions that ignore all includes and defines, so we just
# directly try to link via main().
- return self.links('int main() {{ {0}; }}'.format('__builtin_' + funcname), env, args)
+ return self.links('int main() {{ {0}; }}'.format('__builtin_' + funcname), env, args, dependencies)
- def has_members(self, typename, membernames, prefix, env, extra_args=None):
+ def has_members(self, typename, membernames, prefix, env, extra_args=None, dependencies=None):
if extra_args is None:
extra_args = []
templ = '''{0}
@@ -920,15 +945,15 @@ void bar() {{
for m in membernames:
members += 'foo.{};\n'.format(m)
code = templ.format(prefix, typename, 'foo', members)
- return self.compiles(code, env, extra_args)
+ return self.compiles(code, env, extra_args, dependencies)
- def has_type(self, typename, prefix, env, extra_args):
+ def has_type(self, typename, prefix, env, extra_args, dependencies=None):
templ = '''%s
void bar() {
sizeof(%s);
};
'''
- return self.compiles(templ % (prefix, typename), env, extra_args)
+ return self.compiles(templ % (prefix, typename), env, extra_args, dependencies)
def find_library(self, libname, env, extra_dirs):
# First try if we can just add the library as -l.
@@ -1723,7 +1748,7 @@ class VisualStudioCCompiler(CCompiler):
self.always_args = ['/nologo', '/showIncludes']
self.warn_args = {'1': ['/W2'],
'2': ['/W3'],
- '3': ['/w4']}
+ '3': ['/W4']}
self.base_options = ['b_pch'] # FIXME add lto, pgo and the like
def get_always_args(self):
@@ -1953,7 +1978,7 @@ class GnuCompiler:
self.id = 'gcc'
self.gcc_type = gcc_type
self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage',
- 'b_colorout']
+ 'b_colorout', 'b_ndebug']
if self.gcc_type != GCC_OSX:
self.base_options.append('b_lundef')
self.base_options.append('b_asneeded')
@@ -1963,6 +1988,14 @@ class GnuCompiler:
return gnu_color_args[colortype][:]
return []
+ def get_warn_args(self, level):
+ args = super().get_warn_args(level)
+ if mesonlib.version_compare(self.version, '<4.8.0') and '-Wpedantic' in args:
+ # -Wpedantic was added in 4.8.0
+ # https://gcc.gnu.org/gcc-4.8/changes.html
+ args[args.index('-Wpedantic')] = '-pedantic'
+ return args
+
def get_pic_args(self):
if self.gcc_type == GCC_MINGW:
return [] # On Window gcc defaults to fpic being always on.
@@ -2084,7 +2117,8 @@ class ClangCompiler():
def __init__(self, clang_type):
self.id = 'clang'
self.clang_type = clang_type
- self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage']
+ self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage',
+ 'b_ndebug']
if self.clang_type != CLANG_OSX:
self.base_options.append('b_lundef')
self.base_options.append('b_asneeded')
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 80617dd..385e07a 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -228,40 +228,44 @@ class ConfigurationDataHolder(InterpreterObject):
def mark_used(self):
self.used = True
- def validate_args(self, args):
+ def validate_args(self, args, kwargs):
if len(args) != 2:
raise InterpreterException("Configuration set requires 2 arguments.")
if self.used:
raise InterpreterException("Can not set values on configuration object that has been used.")
name = args[0]
val = args[1]
+ desc = kwargs.get('description', None)
if not isinstance(name, str):
raise InterpreterException("First argument to set must be a string.")
- return (name, val)
+ if desc is not None and not isinstance(desc, str):
+ raise InterpreterException('Description must be a string.')
+
+ return (name, val, desc)
def set_method(self, args, kwargs):
- (name, val) = self.validate_args(args)
- self.held_object.values[name] = val
+ (name, val, desc) = self.validate_args(args, kwargs)
+ self.held_object.values[name] = (val, desc)
def set_quoted_method(self, args, kwargs):
- (name, val) = self.validate_args(args)
+ (name, val, desc) = self.validate_args(args, kwargs)
if not isinstance(val, str):
raise InterpreterException("Second argument to set_quoted must be a string.")
escaped_val = '\\"'.join(val.split('"'))
- self.held_object.values[name] = '"' + escaped_val + '"'
+ self.held_object.values[name] = ('"' + escaped_val + '"', desc)
def set10_method(self, args, kwargs):
- (name, val) = self.validate_args(args)
+ (name, val, desc) = self.validate_args(args, kwargs)
if val:
- self.held_object.values[name] = 1
+ self.held_object.values[name] = (1, desc)
else:
- self.held_object.values[name] = 0
+ self.held_object.values[name] = (0, desc)
def has_method(self, args, kwargs):
return args[0] in self.held_object.values
def get(self, name):
- return self.held_object.values[name]
+ return self.held_object.values[name] # (val, desc)
def keys(self):
return self.held_object.values.keys()
@@ -662,6 +666,25 @@ class CompilerHolder(InterpreterObject):
args += mesonlib.stringlistify(kwargs.get('args', []))
return args
+ def determine_dependencies(self, kwargs, allowed_dep_types=None):
+ deps = kwargs.get('dependencies', None)
+ if allowed_dep_types is None:
+ allowed_dep_types = (dependencies.Dependency, dependencies.ExternalLibrary)
+ if deps is not None:
+ if not isinstance(deps, list):
+ deps = [deps]
+ final_deps = []
+ for d in deps:
+ try:
+ d = d.held_object
+ except Exception:
+ pass
+ if not isinstance(d, allowed_dep_types):
+ raise InterpreterException('Dependencies must be external deps')
+ final_deps.append(d)
+ deps = final_deps
+ return deps
+
def alignment_method(self, args, kwargs):
if len(args) != 1:
raise InterpreterException('Alignment method takes exactly one positional argument.')
@@ -681,7 +704,8 @@ class CompilerHolder(InterpreterObject):
if not isinstance(testname, str):
raise InterpreterException('Testname argument must be a string.')
extra_args = self.determine_args(kwargs)
- result = self.compiler.run(code, self.environment, extra_args)
+ deps = self.determine_dependencies(kwargs)
+ result = self.compiler.run(code, self.environment, extra_args, deps)
if len(testname) > 0:
if not result.compiled:
h = mlog.red('DID NOT COMPILE')
@@ -711,8 +735,9 @@ class CompilerHolder(InterpreterObject):
if not isinstance(prefix, str):
raise InterpreterException('Prefix argument of has_member must be a string.')
extra_args = self.determine_args(kwargs)
+ deps = self.determine_dependencies(kwargs, allowed_dep_types=(dependencies.Dependency,))
had = self.compiler.has_members(typename, [membername], prefix,
- self.environment, extra_args)
+ self.environment, extra_args, deps)
if had:
hadtxt = mlog.green('YES')
else:
@@ -729,8 +754,9 @@ class CompilerHolder(InterpreterObject):
if not isinstance(prefix, str):
raise InterpreterException('Prefix argument of has_members must be a string.')
extra_args = self.determine_args(kwargs)
+ deps = self.determine_dependencies(kwargs, allowed_dep_types=(dependencies.Dependency,))
had = self.compiler.has_members(typename, membernames, prefix,
- self.environment, extra_args)
+ self.environment, extra_args, deps)
if had:
hadtxt = mlog.green('YES')
else:
@@ -749,7 +775,8 @@ class CompilerHolder(InterpreterObject):
if not isinstance(prefix, str):
raise InterpreterException('Prefix argument of has_function must be a string.')
extra_args = self.determine_args(kwargs)
- had = self.compiler.has_function(funcname, prefix, self.environment, extra_args)
+ deps = self.determine_dependencies(kwargs)
+ had = self.compiler.has_function(funcname, prefix, self.environment, extra_args, deps)
if had:
hadtxt = mlog.green('YES')
else:
@@ -766,7 +793,8 @@ class CompilerHolder(InterpreterObject):
if not isinstance(prefix, str):
raise InterpreterException('Prefix argument of has_type must be a string.')
extra_args = self.determine_args(kwargs)
- had = self.compiler.has_type(typename, prefix, self.environment, extra_args)
+ deps = self.determine_dependencies(kwargs)
+ had = self.compiler.has_type(typename, prefix, self.environment, extra_args, deps)
if had:
hadtxt = mlog.green('YES')
else:
@@ -783,7 +811,8 @@ class CompilerHolder(InterpreterObject):
if not isinstance(prefix, str):
raise InterpreterException('Prefix argument of sizeof must be a string.')
extra_args = self.determine_args(kwargs)
- esize = self.compiler.sizeof(element, prefix, self.environment, extra_args)
+ deps = self.determine_dependencies(kwargs, allowed_dep_types=(dependencies.Dependency,))
+ esize = self.compiler.sizeof(element, prefix, self.environment, extra_args, deps)
mlog.log('Checking for size of "%s": %d' % (element, esize))
return esize
@@ -796,7 +825,8 @@ class CompilerHolder(InterpreterObject):
if not isinstance(testname, str):
raise InterpreterException('Testname argument must be a string.')
extra_args = self.determine_args(kwargs)
- result = self.compiler.compiles(code, self.environment, extra_args)
+ deps = self.determine_dependencies(kwargs, allowed_dep_types=(dependencies.Dependency,))
+ result = self.compiler.compiles(code, self.environment, extra_args, deps)
if len(testname) > 0:
if result:
h = mlog.green('YES')
@@ -814,7 +844,8 @@ class CompilerHolder(InterpreterObject):
if not isinstance(testname, str):
raise InterpreterException('Testname argument must be a string.')
extra_args = self.determine_args(kwargs)
- result = self.compiler.links(code, self.environment, extra_args)
+ deps = self.determine_dependencies(kwargs)
+ result = self.compiler.links(code, self.environment, extra_args, deps)
if len(testname) > 0:
if result:
h = mlog.green('YES')
@@ -829,7 +860,8 @@ class CompilerHolder(InterpreterObject):
check_stringlist(args)
string = args[0]
extra_args = self.determine_args(kwargs)
- haz = self.compiler.has_header(string, self.environment, extra_args)
+ deps = self.determine_dependencies(kwargs, allowed_dep_types=(dependencies.Dependency,))
+ haz = self.compiler.has_header(string, self.environment, extra_args, deps)
if haz:
h = mlog.green('YES')
else:
@@ -847,7 +879,8 @@ class CompilerHolder(InterpreterObject):
if not isinstance(prefix, str):
raise InterpreterException('Prefix argument of has_function must be a string.')
extra_args = self.determine_args(kwargs)
- haz = self.compiler.has_header_symbol(hname, symbol, prefix, self.environment, extra_args)
+ deps = self.determine_dependencies(kwargs, allowed_dep_types=(dependencies.Dependency,))
+ haz = self.compiler.has_header_symbol(hname, symbol, prefix, self.environment, extra_args, deps)
if haz:
h = mlog.green('YES')
else:
@@ -856,6 +889,7 @@ class CompilerHolder(InterpreterObject):
return haz
def find_library_method(self, args, kwargs):
+ # TODO add dependencies support?
if len(args) != 1:
raise InterpreterException('find_library method takes one argument.')
libname = args[0]
@@ -942,6 +976,7 @@ class MesonMain(InterpreterObject):
'add_postconf_script' : self.add_postconf_script_method,
'install_dependency_manifest': self.install_dependency_manifest_method,
'project_version': self.project_version_method,
+ 'version': self.version_method,
'project_name' : self.project_name_method,
'get_cross_property': self.get_cross_property_method,
})
@@ -1040,6 +1075,9 @@ class MesonMain(InterpreterObject):
def project_version_method(self, args, kwargs):
return self.build.dep_manifest[self.interpreter.active_projectname]['version']
+ def version_method(self, args, kwargs):
+ return coredata.version
+
def project_name_method(self, args, kwargs):
return self.interpreter.active_projectname
@@ -1810,9 +1848,12 @@ class Interpreter():
raise
else:
return None
- dep = self.subprojects[dirname].get_variable_method([varname], {})
+ try:
+ dep = self.subprojects[dirname].get_variable_method([varname], {})
+ except KeyError:
+ raise InterpreterException('Fallback variable {!r} in the subproject {!r} does not exist'.format(varname, dirname))
if not isinstance(dep, (DependencyHolder, InternalDependencyHolder)):
- raise InterpreterException('Fallback variable is not a dependency object.')
+ raise InterpreterException('Fallback variable {!r} in the subproject {!r} is not a dependency object.'.format(varname, dirname))
# Check if the version of the declared dependency matches what we want
if 'version' in kwargs:
wanted = kwargs['version']
@@ -2231,6 +2272,8 @@ class Interpreter():
self.coredata.target_guids[idname] = str(uuid.uuid4()).upper()
def build_target(self, node, args, kwargs, targetholder):
+ if len(args) == 0:
+ raise InterpreterException('Target does not have a name.')
name = args[0]
sources = args[1:]
if self.environment.is_cross_build():
diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py
index d06e4eb..7294a54 100644
--- a/mesonbuild/mesonlib.py
+++ b/mesonbuild/mesonlib.py
@@ -221,7 +221,7 @@ def do_replacement(regex, line, confdata):
while match:
varname = match.group(1)
if varname in confdata.keys():
- var = confdata.get(varname)
+ (var, desc) = confdata.get(varname)
if isinstance(var, str):
pass
elif isinstance(var, int):
@@ -240,7 +240,7 @@ def do_mesondefine(line, confdata):
raise MesonException('#mesondefine does not contain exactly two tokens: %s', line.strip())
varname = arr[1]
try:
- v = confdata.get(varname)
+ (v, desc) = confdata.get(varname)
except KeyError:
return '/* #undef %s */\n' % varname
if isinstance(v, bool):
@@ -289,7 +289,9 @@ def dump_conf_header(ofilename, cdata):
''')
for k in sorted(cdata.keys()):
- v = cdata.get(k)
+ (v, desc) = cdata.get(k)
+ if desc:
+ ofile.write('/* %s */\n' % desc)
if isinstance(v, bool):
if v:
ofile.write('#define %s\n\n' % k)
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
index 3609d2f..4f72d2f 100644
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -45,6 +45,9 @@ class GnomeModule:
if not isinstance(source_dirs, list):
source_dirs = [source_dirs]
+ if len(args) < 2:
+ raise MesonException('Not enough arguments; The name of the resource and the path to the XML file are required')
+
ifile = args[1]
if isinstance(ifile, mesonlib.File):
ifile = os.path.join(ifile.subdir, ifile.fname)
diff --git a/mesonbuild/scripts/gettext.py b/mesonbuild/scripts/gettext.py
index 4677d5f..1f0a391 100644
--- a/mesonbuild/scripts/gettext.py
+++ b/mesonbuild/scripts/gettext.py
@@ -19,6 +19,12 @@ from mesonbuild.scripts import destdir_join
def run_potgen(src_sub, pkgname, args):
listfile = os.path.join(src_sub, 'POTFILES')
+ if not os.path.exists(listfile):
+ listfile = os.path.join(src_sub, 'POTFILES.in')
+ if not os.path.exists(listfile):
+ print('Could not find file POTFILES in %s' % src_sub)
+ return 1
+
ofile = os.path.join(src_sub, pkgname + '.pot')
return subprocess.call(['xgettext', '--package-name=' + pkgname, '-p', src_sub, '-f', listfile,
'-D', os.environ['MESON_SOURCE_ROOT'], '-k_', '-o', ofile] + args)
diff --git a/test cases/common/118 allgenerate/converter.py b/test cases/common/118 allgenerate/converter.py
new file mode 100755
index 0000000..f8e2ca0
--- /dev/null
+++ b/test cases/common/118 allgenerate/converter.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python3
+
+import sys
+
+ifile = sys.argv[1]
+ofile = sys.argv[2]
+
+open(ofile, 'w').write(open(ifile).read())
diff --git a/test cases/common/118 allgenerate/foobar.cpp.in b/test cases/common/118 allgenerate/foobar.cpp.in
new file mode 100644
index 0000000..c64f3b5
--- /dev/null
+++ b/test cases/common/118 allgenerate/foobar.cpp.in
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ printf("I am a program.\n");
+ return 0;
+}
diff --git a/test cases/common/118 allgenerate/meson.build b/test cases/common/118 allgenerate/meson.build
new file mode 100644
index 0000000..1ec93e6
--- /dev/null
+++ b/test cases/common/118 allgenerate/meson.build
@@ -0,0 +1,20 @@
+# Must have two languages here to exercise linker language
+# selection bug
+project('all sources generated', 'c', 'cpp')
+
+comp = find_program('converter.py')
+
+g = generator(comp,
+ output : '@BASENAME@.cpp',
+ arguments : ['@INPUT@', '@OUTPUT@'])
+
+c = g.process('foobar.cpp.in')
+
+prog = executable('genexe', c)
+
+c2 = custom_target('c2gen',
+ output : 'c2gen.cpp',
+ input : 'foobar.cpp.in',
+ command : [comp, '@INPUT@', '@OUTPUT@'])
+
+prog2 = executable('genexe2', c2) \ No newline at end of file
diff --git a/test cases/common/16 configure file/meson.build b/test cases/common/16 configure file/meson.build
index c00af40..ae3ad27 100644
--- a/test cases/common/16 configure file/meson.build
+++ b/test cases/common/16 configure file/meson.build
@@ -34,7 +34,7 @@ test('inctest2', executable('prog2', 'prog2.c'))
# Generate a conf file without an input file.
dump = configuration_data()
-dump.set_quoted('SHOULD_BE_STRING', 'string')
+dump.set_quoted('SHOULD_BE_STRING', 'string', description : 'A string')
dump.set_quoted('SHOULD_BE_STRING2', 'A "B" C')
dump.set_quoted('SHOULD_BE_STRING3', 'A "" C')
dump.set_quoted('SHOULD_BE_STRING4', 'A " C')
@@ -42,7 +42,7 @@ dump.set('SHOULD_BE_RETURN', 'return')
dump.set('SHOULD_BE_DEFINED', true)
dump.set('SHOULD_BE_UNDEFINED', false)
dump.set('SHOULD_BE_ONE', 1)
-dump.set('SHOULD_BE_ZERO', 0)
+dump.set('SHOULD_BE_ZERO', 0, description : 'Absolutely zero')
dump.set('SHOULD_BE_QUOTED_ONE', '"1"')
configure_file(output : 'config3.h',
configuration : dump)
diff --git a/test cases/common/94 default options/meson.build b/test cases/common/94 default options/meson.build
index 6299106..a718bcc 100644
--- a/test cases/common/94 default options/meson.build
+++ b/test cases/common/94 default options/meson.build
@@ -2,6 +2,7 @@ project('default options', 'cpp', 'c', default_options : [
'buildtype=debugoptimized',
'cpp_std=c++03',
'cpp_eh=none',
+ 'warning_level=3',
])
cpp = meson.get_compiler('cpp')
@@ -9,11 +10,16 @@ cpp = meson.get_compiler('cpp')
assert(get_option('buildtype') == 'debugoptimized', 'Build type default value wrong.')
if cpp.get_id() == 'msvc'
- assert(get_option('cpp_eh') == 'none', 'MSVC eh value wrong.')
+ cpp_eh = get_option('cpp_eh')
+ assert(cpp_eh == 'none', 'MSVC eh value is "' + cpp_eh + '" instead of "none"')
else
- assert(get_option('cpp_std') == 'c++03', 'C++ std value wrong.')
+ cpp_std = get_option('cpp_std')
+ assert(cpp_std == 'c++03', 'C++ std value is "' + cpp_std + '" instead of c++03.')
endif
+w_level = get_option('warning_level')
+assert(w_level == '3', 'warning level "' + w_level + '" instead of "3"')
+
# FIXME. Since we no longer accept invalid options to c_std etc,
# there is no simple way to test this. Gcc does not seem to expose
# the C std used in a preprocessor token so we can't check for it.
diff --git a/test cases/linuxlike/9 compiler checks with dependencies/meson.build b/test cases/linuxlike/9 compiler checks with dependencies/meson.build
new file mode 100644
index 0000000..2aa9015
--- /dev/null
+++ b/test cases/linuxlike/9 compiler checks with dependencies/meson.build
@@ -0,0 +1,31 @@
+project('compiler checks with dependencies', 'c')
+
+cc = meson.get_compiler('c')
+
+glib = dependency ('glib-2.0')
+if glib.found()
+ assert (cc.has_header('glib.h', dependencies : glib), 'glib.h not found')
+ assert (cc.has_type('gint32', prefix : '#include <glib.h>', dependencies : glib), 'gint32 not found')
+ assert (cc.has_function('g_print', dependencies : glib), 'g_print not found')
+ assert (cc.has_member('GError', 'message', prefix : '#include <glib.h>', dependencies : glib), 'GError::message not found')
+ assert (cc.has_header_symbol('glib.h', 'gint32', dependencies : glib), 'gint32 symbol not found')
+ linkcode = '''#include <glib.h>
+int main (int argc, char *argv[]) {
+ GError *error = g_error_new_literal (0, 0, NULL);
+ return error == NULL;
+}
+ '''
+ assert (cc.links(linkcode, dependencies : glib, name : 'Test link against glib'), 'Linking test against glib failed')
+endif
+
+zlib = cc.find_library ('z')
+if zlib.found()
+ linkcode = '''#include<zlib.h>
+int main(int argc, char *argv[]) {
+ void *ptr = (void*)(deflate);
+ return ptr == 0;
+}
+'''
+ assert (cc.has_function('deflate', prefix : '#include<zlib.h>', dependencies : zlib, name : 'Test for function in zlib'), 'has_function test failed.')
+ assert (cc.links(linkcode, dependencies : zlib, name : 'Test link against zlib'), 'Linking test failed against zlib.')
+endif